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(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 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 clazz = (Class) 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 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 272e5db67d4e4cb290c8cf6b5e0d7b429a45a90f Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sat, 26 Aug 2017 11:51:52 +0200 Subject: [PATCH 061/175] inventory size --- 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 0defd473ed..415b54196e 100644 --- a/src/main/java/cn/nukkit/inventory/PlayerInventory.java +++ b/src/main/java/cn/nukkit/inventory/PlayerInventory.java @@ -392,7 +392,7 @@ public void sendContents(Collection players) { @Override public void sendContents(Player[] players) { InventoryContentPacket pk = new InventoryContentPacket(); - pk.slots = new Item[this.getSize()]; + pk.slots = new Item[this.getSize() + this.getHotbarSize()]; for (int i = 0; i < this.getSize(); ++i) { pk.slots[i] = this.getItem(i); } From 9172b11cfcdab96a7b26a77600d33cf0a7e0cae9 Mon Sep 17 00:00:00 2001 From: Creeperface01 Date: Sun, 27 Aug 2017 12:52:03 +0200 Subject: [PATCH 062/175] fast fix for crafting (#1882) --- src/main/java/cn/nukkit/Player.java | 65 ++++++++++++++++++- .../cn/nukkit/inventory/BaseInventory.java | 4 +- src/main/java/cn/nukkit/item/Item.java | 2 +- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 4b0a4b136a..abe36f9fda 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -3165,7 +3165,7 @@ public void handleDataPacket(DataPacket packet) { } ingredientz.add(ingredient); - this.inventory.removeItem(ingredient); + this.inventory.removeItem(ingredient); //TODO: improve this, or wait for mojang's fix :D } } } @@ -3192,8 +3192,69 @@ public void handleDataPacket(DataPacket packet) { this.inventory.sendContents(this); } } else { + 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) { + r.count += ingredient.getCount(); + 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; + } + + System.out.println("craft"); + CraftItemEvent craftItemEvent = new CraftItemEvent(this, serialized.values().stream().toArray(Item[]::new), recipe); + getServer().getPluginManager().callEvent(craftItemEvent); + + if (craftItemEvent.isCancelled()) { + this.inventory.sendContents(this); + break; + } + + for (Item ingredient : serialized.values()) { + this.inventory.removeItem(ingredient); + } + + this.inventory.addItem(recipe.getResult()); + + /*if (recipe instanceof ShapedRecipe) { int offsetX = 0; int offsetY = 0; @@ -3389,7 +3450,7 @@ public void handleDataPacket(DataPacket packet) { for (Item i : extraItem) { this.level.dropItem(this, i); } - } + }*/ } switch (recipe.getResult().getId()) { 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/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; From 283abaa5ef5eb893a21a86562735cfad843f4984 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 27 Aug 2017 15:47:20 +0200 Subject: [PATCH 063/175] fixed form windows a bit --- .../java/cn/nukkit/form/window/FormWindowCustom.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java index cb36d7c788..6b0de4b4bd 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java @@ -1,9 +1,9 @@ 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 cn.nukkit.form.response.FormResponseData; +import com.google.gson.Gson; import java.util.ArrayList; import java.util.HashMap; @@ -65,6 +65,10 @@ public void setResponse(String data) { HashMap responses = new HashMap<>(); for (String elementData : elementResponses){ + if (i >= content.size()) { + break; + } + Element e = content.get(i); if (e == null) break; if (e instanceof ElementLabel) { @@ -77,7 +81,7 @@ public void setResponse(String data) { responses.put(i, answer); } else if (e instanceof ElementInput){ - String answer = elementData.substring(0, elementData.length()-1); + String answer = elementData.substring(1, elementData.length() - 1); inputResponses.put(i, answer); responses.put(i, answer); } From 2edcd53bc0df4c9c180cabe6cf15d1bd81565b8f Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 27 Aug 2017 15:48:37 +0200 Subject: [PATCH 064/175] let's make it protected --- 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 ca8173bac0..5ec606eff0 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -199,8 +199,8 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde public int pickedXPOrb = 0; - private int formWindowCount = 0; - private HashMap formWindows = new HashMap<>(); + protected int formWindowCount = 0; + protected HashMap formWindows = new HashMap<>(); public int getStartActionTick() { return startAction; From 8ea0a44c1409caadda4e45fde32bc5db69a203c1 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 27 Aug 2017 16:29:03 +0200 Subject: [PATCH 065/175] Use Gson parsing --- .../cn/nukkit/form/window/FormWindowCustom.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java index 6b0de4b4bd..c55081a6e9 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java @@ -4,9 +4,11 @@ import cn.nukkit.form.response.FormResponseCustom; import cn.nukkit.form.response.FormResponseData; import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; public class FormWindowCustom extends FormWindow { @@ -53,8 +55,11 @@ public void setResponse(String data) { this.closed = true; return; } - String[] elementResponses = data.replace("[", "").replace("]", - "").split(","); + + List elementResponses = new Gson().fromJson(data, new TypeToken>() { + }.getType()); + elementResponses.remove(elementResponses.size() - 1); //submit button + int i = 0; HashMap dropdownResponses = new HashMap<>(); @@ -81,9 +86,8 @@ public void setResponse(String data) { responses.put(i, answer); } else if (e instanceof ElementInput){ - String answer = elementData.substring(1, elementData.length() - 1); - inputResponses.put(i, answer); - responses.put(i, answer); + inputResponses.put(i, elementData); + responses.put(i, elementData); } else if (e instanceof ElementSlider){ Float answer = Float.parseFloat(elementData); From 6030b3078a12f0c683fcbaf5982d6392d3442f02 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Mon, 28 Aug 2017 08:46:36 +0200 Subject: [PATCH 066/175] crafting fix --- src/main/java/cn/nukkit/Player.java | 149 ++++++++++++++++------------ 1 file changed, 83 insertions(+), 66 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 5ec606eff0..584c3737c0 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2719,7 +2719,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; } @@ -2742,62 +2742,19 @@ public void handleDataPacket(DataPacket packet) { boolean canCraft = true; - if (true) { - //System.out.println("output: "+craftingEventPacket.output[0]); - //Recipe[] recipes = getServer().getCraftingManager().getRecipesByResult(craftingEventPacket.output[0]); + if (craftingEventPacket.input.length == 0) { + Recipe[] recipes = getServer().getCraftingManager().getRecipesByResult(craftingEventPacket.output[0]); - recipe = this.getServer().getCraftingManager().getRecipe(craftingEventPacket.id); + recipe = null; - /*ArrayList ingredientz = new ArrayList<>(); + ArrayList ingredientz = new ArrayList<>(); - for (Recipe r : recipes) { - if (r instanceof ShapedRecipe) { - Map> ingredients = ((ShapedRecipe) r).getIngredientMap(); - for (Map map : ingredients.values()) { - for (Item ingredient : map.values()) { - 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; - } - } 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; - } + recipeloop: + for (Recipe rec : recipes) { + ingredientz.clear(); - ingredientz.add(ingredient); - this.inventory.removeItem(ingredient); - } - } - - if (canCraft) { - recipe = r; - break; - } - } - }*/ - - if (recipe != null) { - ArrayList ingredientz = new ArrayList<>(); - - if (recipe instanceof ShapedRecipe) { - Map> ingredients = ((ShapedRecipe) recipe).getIngredientMap(); + if (rec instanceof ShapedRecipe) { + Map> ingredients = ((ShapedRecipe) rec).getIngredientMap(); for (Map map : ingredients.values()) { for (Item ingredient : map.values()) { if (ingredient != null && ingredient.getId() != Item.AIR) { @@ -2805,8 +2762,8 @@ public void handleDataPacket(DataPacket packet) { } } } - } else if (recipe instanceof ShapelessRecipe) { - ShapelessRecipe recipe0 = (ShapelessRecipe) recipe; + } else if (rec instanceof ShapelessRecipe) { + ShapelessRecipe recipe0 = (ShapelessRecipe) rec; for (Item ingredient : recipe0.getIngredientList()) { if (ingredient != null && ingredient.getId() != Item.AIR) { @@ -2822,6 +2779,7 @@ public void handleDataPacket(DataPacket packet) { Item r = serialized.get(hash); if (r != null) { + r.count += ingredient.getCount(); continue; } @@ -2830,22 +2788,18 @@ public void handleDataPacket(DataPacket packet) { for (Item ingredient : serialized.values()) { if (!this.inventory.contains(ingredient)) { - canCraft = false; - break; + continue recipeloop; } } - if (!canCraft) { - this.server.getLogger().debug("(1) Unmatched recipe " + craftingEventPacket.id + " from player " + this.getName() + " not anough ingredients"); - return; - } + recipe = rec; CraftItemEvent craftItemEvent = new CraftItemEvent(this, serialized.values().stream().toArray(Item[]::new), recipe); getServer().getPluginManager().callEvent(craftItemEvent); if (craftItemEvent.isCancelled()) { this.inventory.sendContents(this); - break; + break packetswitch; } for (Item ingredient : serialized.values()) { @@ -2853,13 +2807,77 @@ public void handleDataPacket(DataPacket packet) { } this.inventory.addItem(recipe.getResult()); - } else { - this.server.getLogger().debug("(1) Unmatched recipe " + craftingEventPacket.id + " from player " + this.getName()); + break; + } + + if (recipe == null) { + this.server.getLogger().debug("(1) Unmatched desktop recipe " + craftingEventPacket.id + " from player " + this.getName()); this.inventory.sendContents(this); } } else { + 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) { + r.count += ingredient.getCount(); + 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()) { + this.inventory.sendContents(this); + break; + } + + for (Item ingredient : serialized.values()) { + this.inventory.removeItem(ingredient); + } + + this.inventory.addItem(recipe.getResult()); + + /*if (recipe instanceof ShapedRecipe) { int offsetX = 0; int offsetY = 0; @@ -3055,7 +3073,7 @@ public void handleDataPacket(DataPacket packet) { for (Item i : extraItem) { this.level.dropItem(this, i); } - } + }*/ } if (recipe != null) { @@ -3096,7 +3114,6 @@ public void handleDataPacket(DataPacket packet) { break; } } - break; case ProtocolInfo.INVENTORY_SLOT_PACKET: if (!this.spawned || !this.isAlive()) { From a1c43f665b4e19c3cef49877481741a37be08b9f Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Mon, 28 Aug 2017 08:49:35 +0200 Subject: [PATCH 067/175] ops --- src/main/java/cn/nukkit/Player.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 584c3737c0..2c9a2aa796 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2719,7 +2719,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; } From 56d553a18f1b941f9b77cb320bb0296efa2d32a4 Mon Sep 17 00:00:00 2001 From: Creeperface01 Date: Wed, 30 Aug 2017 11:48:39 +0200 Subject: [PATCH 068/175] final fix for crafting (#1884) * fixed crafting with classic UI * Final fix --- src/main/java/cn/nukkit/Player.java | 135 +++++++++++------- .../cn/nukkit/inventory/CraftingManager.java | 4 +- 2 files changed, 84 insertions(+), 55 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index abe36f9fda..f22862ca05 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -3153,41 +3153,68 @@ public void handleDataPacket(DataPacket packet) { ArrayList ingredientz = new ArrayList<>(); - for (Recipe r : recipes) { - if (r instanceof ShapedRecipe) { - Map> ingredients = ((ShapedRecipe) r).getIngredientMap(); + recipeloop: + for (Recipe rec : recipes) { + ingredientz.clear(); + + if (rec instanceof ShapedRecipe) { + Map> ingredients = ((ShapedRecipe) rec).getIngredientMap(); for (Map map : ingredients.values()) { for (Item ingredient : map.values()) { if (ingredient != null && ingredient.getId() != Item.AIR) { - if (!this.inventory.contains(ingredient)) { - canCraft = false; - break; - } - ingredientz.add(ingredient); - this.inventory.removeItem(ingredient); //TODO: improve this, or wait for mojang's fix :D } } } + } else if (rec instanceof ShapelessRecipe) { + ShapelessRecipe recipe0 = (ShapelessRecipe) rec; - if (canCraft) { - recipe = r; - break; + for (Item ingredient : recipe0.getIngredientList()) { + if (ingredient != null && ingredient.getId() != Item.AIR) { + ingredientz.add(ingredient); + } } } - } - if (recipe != null) { - CraftItemEvent craftItemEvent = new CraftItemEvent(this, ingredientz.stream().toArray(Item[]::new), recipe); + Map serialized = new HashMap<>(); + + for (Item ingredient : ingredientz) { + String hash = ingredient.getId() + ":" + ingredient.getDamage(); + Item r = serialized.get(hash); + + if (r != null) { + r.count += ingredient.getCount(); + continue; + } + + serialized.put(hash, ingredient); + } + + for (Item ingredient : serialized.values()) { + if (!this.inventory.contains(ingredient)) { + continue recipeloop; + } + } + + recipe = rec; + + CraftItemEvent craftItemEvent = new CraftItemEvent(this, serialized.values().stream().toArray(Item[]::new), recipe); getServer().getPluginManager().callEvent(craftItemEvent); if (craftItemEvent.isCancelled()) { this.inventory.sendContents(this); - break; + break packetswitch; + } + + for (Item ingredient : serialized.values()) { + this.inventory.removeItem(ingredient); } this.inventory.addItem(recipe.getResult()); - } else { + break; + } + + if (recipe == null) { this.server.getLogger().debug("(1) Unmatched desktop recipe " + craftingEventPacket.id + " from player " + this.getName()); this.inventory.sendContents(this); } @@ -3195,6 +3222,7 @@ public void handleDataPacket(DataPacket packet) { ArrayList ingredientz = new ArrayList<>(); if (recipe instanceof ShapedRecipe) { + Map> ingredients = ((ShapedRecipe) recipe).getIngredientMap(); for (Map map : ingredients.values()) { for (Item ingredient : map.values()) { @@ -3239,7 +3267,6 @@ public void handleDataPacket(DataPacket packet) { return; } - System.out.println("craft"); CraftItemEvent craftItemEvent = new CraftItemEvent(this, serialized.values().stream().toArray(Item[]::new), recipe); getServer().getPluginManager().callEvent(craftItemEvent); @@ -3453,41 +3480,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/inventory/CraftingManager.java b/src/main/java/cn/nukkit/inventory/CraftingManager.java index ed0e61f8ff..e5a6e1a7c2 100644 --- a/src/main/java/cn/nukkit/inventory/CraftingManager.java +++ b/src/main/java/cn/nukkit/inventory/CraftingManager.java @@ -47,7 +47,7 @@ public CraftingManager() { 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())); + result.addIngredient(Item.get(Utils.toInt(ingredient.get("id")), Utils.toInt(ingredient.get("damage")), /*Utils.toInt(ingredient.get("count"))*/ 1, ingredient.get("nbt").toString().getBytes())); //ingredient count should be always 1 for now } this.registerRecipe(result); break; @@ -63,7 +63,7 @@ public CraftingManager() { 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())); + shapedRecipe.addIngredient(x, y, Item.get(Utils.toInt(ingredient.get("id")), Utils.toInt(ingredient.get("damage")), /*Utils.toInt(ingredient.get("count"))*/ 1, ingredient.get("nbt").toString().getBytes())); } else { shapedRecipe.addIngredient(x, y, new ItemBlock(new BlockAir())); } From cb574b78fb8e60d95267fc48dd0ae35dd1342b44 Mon Sep 17 00:00:00 2001 From: Creeperface01 Date: Tue, 5 Sep 2017 14:02:28 +0200 Subject: [PATCH 069/175] Fixed entities a bit (#1892) --- src/main/java/cn/nukkit/entity/item/EntityItem.java | 6 +++--- .../java/cn/nukkit/entity/item/EntityMinecartAbstract.java | 2 +- src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java | 2 +- src/main/java/cn/nukkit/entity/item/EntityXPOrb.java | 6 +++--- src/main/java/cn/nukkit/level/Level.java | 1 - 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/cn/nukkit/entity/item/EntityItem.java b/src/main/java/cn/nukkit/entity/item/EntityItem.java index 655536819f..9dbd8a31fc 100644 --- a/src/main/java/cn/nukkit/entity/item/EntityItem.java +++ b/src/main/java/cn/nukkit/entity/item/EntityItem.java @@ -29,12 +29,12 @@ public int getNetworkId() { return NETWORK_ID; } - protected String owner = null; - protected String thrower = null; + protected String owner; + protected String thrower; protected Item item; - protected int pickupDelay = 0; + protected int pickupDelay; @Override public float getWidth() { diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java index f398d3bb7e..93221589a6 100644 --- a/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java +++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartAbstract.java @@ -56,7 +56,7 @@ public abstract class EntityMinecartAbstract extends EntityVehicle { {{0, 0, -1}, {1, 0, 0}} }; private double currentSpeed = 0; - private Block blockInside = null; + private Block blockInside; // Plugins modifiers private boolean slowWhenEmpty = true; private double derailedX = 0.5; diff --git a/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java b/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java index 1c520db7c5..2057d1c47c 100644 --- a/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java +++ b/src/main/java/cn/nukkit/entity/item/EntityMinecartTNT.java @@ -19,7 +19,7 @@ public class EntityMinecartTNT extends EntityMinecartAbstract implements EntityExplosive { public static final int NETWORK_ID = 97; //wtf? - private int fuse = 0; + private int fuse; private boolean activated; public EntityMinecartTNT(FullChunk chunk, CompoundTag nbt) { diff --git a/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java b/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java index fb225ee9be..8779f4ffb3 100644 --- a/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java +++ b/src/main/java/cn/nukkit/entity/item/EntityXPOrb.java @@ -56,9 +56,9 @@ public EntityXPOrb(FullChunk chunk, CompoundTag nbt) { super(chunk, nbt); } - private int age = 0; - private int pickupDelay = 0; - private int exp = 0; + private int age; + private int pickupDelay; + private int exp; public Player closestPlayer = null; diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java index 2f4b95b96b..5a4dcf3ef3 100644 --- a/src/main/java/cn/nukkit/level/Level.java +++ b/src/main/java/cn/nukkit/level/Level.java @@ -1755,7 +1755,6 @@ public void dropItem(Vector3 source, Item item, Vector3 motion, boolean dropArou .putShort("Health", 5).putCompound("Item", itemTag).putShort("PickupDelay", delay)); - itemEntity.setPickupDelay(delay); //TODO: fix this itemEntity.spawnToAll(); } } From 1aeacf431b9ea22fb368cc15326596ea55e6fc50 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 10 Sep 2017 15:12:38 +0200 Subject: [PATCH 070/175] fixed update block packet --- src/main/java/cn/nukkit/level/Level.java | 19 +++++++++++++----- .../ClientboundMapItemDataPacket.java | 7 +++++-- .../network/protocol/UpdateBlockPacket.java | 20 ++++++++++++------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java index de540fd2e1..0cb4bb8a11 100644 --- a/src/main/java/cn/nukkit/level/Level.java +++ b/src/main/java/cn/nukkit/level/Level.java @@ -1014,7 +1014,7 @@ public void sendBlocks(Player[] target, Vector3[] blocks, int flags, boolean opt if (b == null) { continue; } - UpdateBlockPacket packet = new UpdateBlockPacket(); + if (b instanceof Block) { UpdateBlockPacket.Entry entry = new UpdateBlockPacket.Entry( (int) b.x, @@ -1039,10 +1039,19 @@ public void sendBlocks(Player[] target, Vector3[] blocks, int flags, boolean opt } } } - UpdateBlockPacket packet = new UpdateBlockPacket(); - packet.entries = entries.stream().toArray(UpdateBlockPacket.Entry[]::new); - for (Player player : target) { - player.dataPacket(packet); + + for (UpdateBlockPacket.Entry entry : entries) { + UpdateBlockPacket packet = new UpdateBlockPacket(); + packet.x = entry.x; + packet.y = entry.y; + packet.z = entry.z; + + packet.blockId = entry.blockId; + packet.blockData = entry.blockData; + + packet.flags = entry.flags; + + Server.broadcastPacket(target, packet); } } diff --git a/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java b/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java index 0202537527..8a06975959 100644 --- a/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java @@ -51,9 +51,11 @@ public void encode() { if (decorators.length > 0) { update |= DECORATIONS_UPDATE; } + if (image != null || colors.length > 0) { update |= TEXTURE_UPDATE; } + this.putUnsignedVarInt(update); if ((update & 0x08) != 0) { //TODO: find out what these are for @@ -70,8 +72,8 @@ public void encode() { this.putUnsignedVarInt(decorators.length); for (MapDecorator decorator : decorators) { - this.putByte(decorator.icon); this.putByte(decorator.rotation); + this.putByte(decorator.icon); this.putByte(decorator.offsetX); this.putByte(decorator.offsetZ); this.putString(decorator.label); @@ -84,7 +86,8 @@ public void encode() { this.putVarInt(height); this.putVarInt(offsetX); this.putVarInt(offsetZ); - this.putVarInt(width * height); + + this.putUnsignedVarInt(width * height); if (image != null) { for (int y = 0; y < width; y++) { diff --git a/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java b/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java index b153595f66..a9da7dc6b6 100644 --- a/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java @@ -1,5 +1,6 @@ package cn.nukkit.network.protocol; + /** * author: MagicDroidX * Nukkit Project @@ -16,7 +17,14 @@ 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 Entry[] entries = new Entry[0]; + public int x; + public int y; + public int z; + + public int blockId; + public int blockData; + + public int flags; @Override public byte pid() { @@ -31,12 +39,10 @@ public void decode() { @Override public void encode() { this.reset(); - 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); - } + this.putBlockVector3(this.x, this.y, this.z); + + this.putUnsignedVarInt(this.blockId); + this.putUnsignedVarInt((this.flags << 4) | this.blockData); } public static class Entry { From 382c908fcce5034b531b9c689d9b0bb22e9f4f25 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 10 Sep 2017 15:24:56 +0200 Subject: [PATCH 071/175] wtf --- .../vehicle/EntityEnterVehicleEvent.java | 32 ++++++++++++++++ .../event/vehicle/EntityExitVehicleEvent.java | 32 ++++++++++++++++ .../event/vehicle/VehicleCreateEvent.java | 19 ++++++++++ .../event/vehicle/VehicleDamageEvent.java | 37 +++++++++++++++++++ .../event/vehicle/VehicleDestroyEvent.java | 27 ++++++++++++++ 5 files changed, 147 insertions(+) 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 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..a654ec75dc --- /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..39694dd25f --- /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..5956c59c19 --- /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; + } + +} From 2ccf0419d04dd013cf5685da029a1df937d4617e Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sat, 16 Sep 2017 20:38:14 +0200 Subject: [PATCH 072/175] some fixes --- .../java/cn/nukkit/AdventureSettings.java | 23 +-- src/main/java/cn/nukkit/Player.java | 15 +- src/main/java/cn/nukkit/entity/Entity.java | 3 +- .../cn/nukkit/inventory/PlayerInventory.java | 10 +- .../ItemReleaseTransactionGroup.java | 2 +- .../transaction/ItemUseTransactionGroup.java | 56 ++++--- .../transaction/TransactionGroup.java | 46 ++++- src/main/java/cn/nukkit/level/Level.java | 35 ++-- .../protocol/AdventureSettingsPacket.java | 157 +++++++++--------- .../protocol/AvailableCommandsPacket.java | 10 +- .../ClientboundMapItemDataPacket.java | 3 + .../protocol/InventoryTransactionPacket.java | 3 +- .../network/protocol/LevelEventPacket.java | 8 +- .../network/protocol/PlayerActionPacket.java | 38 ++--- .../nukkit/network/protocol/ProtocolInfo.java | 6 +- .../network/protocol/StartGamePacket.java | 3 + 16 files changed, 232 insertions(+), 186 deletions(-) diff --git a/src/main/java/cn/nukkit/AdventureSettings.java b/src/main/java/cn/nukkit/AdventureSettings.java index 9b7d35cf76..ab804cfc9b 100644 --- a/src/main/java/cn/nukkit/AdventureSettings.java +++ b/src/main/java/cn/nukkit/AdventureSettings.java @@ -121,17 +121,18 @@ public boolean isMuted() { public void update() { AdventureSettingsPacket pk = new AdventureSettingsPacket(); - pk.flags = 0; - pk.worldImmutable = !canDestroyBlock; - pk.autoJump = autoJump; - pk.allowFlight = canFly; - pk.noClip = noclip; - pk.isFlying = flying; - pk.noPvp = noPvp; - pk.noPvm = noPvm; - pk.noMvp = noMvp; - pk.muted = muted; - pk.userPermission = (this.player.isOp() ? PERMISSION_OPERATOR : PERMISSION_NORMAL); + pk.setFlag(AdventureSettingsPacket.WORLD_IMMUTABLE, !canDestroyBlock); + pk.setFlag(AdventureSettingsPacket.AUTO_JUMP, autoJump); + pk.setFlag(AdventureSettingsPacket.ALLOW_FLIGHT, canFly); + pk.setFlag(AdventureSettingsPacket.NO_CLIP, noclip); + pk.setFlag(AdventureSettingsPacket.FLYING, flying); + pk.setFlag(AdventureSettingsPacket.NO_PVP, noPvp); + pk.setFlag(AdventureSettingsPacket.MUTED, muted); + + pk.commandPermission = (player.isOp() ? AdventureSettingsPacket.PERMISSION_OPERATOR : AdventureSettingsPacket.PERMISSION_NORMAL); + pk.playerPermission = (player.isOp() ? Player.PERMISSION_OPERATOR : Player.PERMISSION_MEMBER); + pk.entityUniqueId = player.getId(); + player.dataPacket(pk); player.resetInAirTicks(); diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 2c9a2aa796..7be1eae2d3 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -92,6 +92,11 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde public static final float DEFAULT_SPEED = 0.1f; public static final float MAXIMUM_SPEED = 0.5f; + public static final int PERMISSION_CUSTOM = 3; + public static final int PERMISSION_OPERATOR = 2; + public static final int PERMISSION_MEMBER = 1; + public static final int PERMISSION_VISITOR = 0; + protected final SourceInterface interfaz; public boolean playedBefore; @@ -2125,11 +2130,11 @@ public void handleDataPacket(DataPacket packet) { case ProtocolInfo.ADVENTURE_SETTINGS_PACKET: //TODO: player abilities, check for other changes AdventureSettingsPacket adventureSettingsPacket = (AdventureSettingsPacket) packet; - if (adventureSettingsPacket.isFlying && !this.getAdventureSettings().canFly()) { + if (adventureSettingsPacket.getFlag(AdventureSettingsPacket.ALLOW_FLIGHT) && !this.getAdventureSettings().canFly()) { this.kick(PlayerKickEvent.Reason.FLYING_DISABLED, "Flying is not enabled on this server"); break; } - PlayerToggleFlightEvent playerToggleFlightEvent = new PlayerToggleFlightEvent(this, adventureSettingsPacket.isFlying); + PlayerToggleFlightEvent playerToggleFlightEvent = new PlayerToggleFlightEvent(this, adventureSettingsPacket.getFlag(AdventureSettingsPacket.ALLOW_FLIGHT)); this.server.getPluginManager().callEvent(playerToggleFlightEvent); if (playerToggleFlightEvent.isCancelled()) { this.getAdventureSettings().update(); @@ -2207,7 +2212,7 @@ public void handleDataPacket(DataPacket packet) { 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)) { + if (!this.spawned || (!this.isAlive() && playerActionPacket.action != PlayerActionPacket.ACTION_RESPAWN && playerActionPacket.action != PlayerActionPacket.ACTION_DIMENSION_CHANGE_REQUEST)) { break; } @@ -2381,16 +2386,12 @@ public void handleDataPacket(DataPacket packet) { this.setGliding(false); } break packetswitch; - case PlayerActionPacket.ACTION_WORLD_IMMUTABLE: - break; //TODO case PlayerActionPacket.ACTION_CONTINUE_BREAK: if (this.isBreakingBlock()) { block = this.level.getBlock(pos); this.level.addParticle(new PunchBlockParticle(pos, block, face)); } break; - case PlayerActionPacket.ACTION_CHANGE_SKIN: - break; //TODO } this.startAction = -1; diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java index 027f19b54a..5723656499 100644 --- a/src/main/java/cn/nukkit/entity/Entity.java +++ b/src/main/java/cn/nukkit/entity/Entity.java @@ -105,6 +105,7 @@ public abstract class Entity extends Location implements Metadatable { /* 45 (byte) container stuff * 46 (int) container stuff * 47 (int) container stuff */ + public static final int DATA_FLAG_FIRE_IMMUNE = 47; public static final int DATA_BLOCK_TARGET = 48; //block coords (ender crystal) public static final int DATA_WITHER_INVULNERABLE_TICKS = 49; //int public static final int DATA_WITHER_TARGET_1 = 50; //long @@ -177,7 +178,7 @@ 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_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; diff --git a/src/main/java/cn/nukkit/inventory/PlayerInventory.java b/src/main/java/cn/nukkit/inventory/PlayerInventory.java index 415b54196e..c7ad5bc9d5 100644 --- a/src/main/java/cn/nukkit/inventory/PlayerInventory.java +++ b/src/main/java/cn/nukkit/inventory/PlayerInventory.java @@ -392,15 +392,15 @@ public void sendContents(Collection players) { @Override public void sendContents(Player[] players) { InventoryContentPacket pk = new InventoryContentPacket(); - pk.slots = new Item[this.getSize() + this.getHotbarSize()]; + 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. + /*//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] = new ItemBlock(new BlockAir()); - } + }*/ for (Player player : players) { int id = player.getWindowId(this); @@ -410,6 +410,10 @@ public void sendContents(Player[] players) { } pk.inventoryId = id; player.dataPacket(pk.clone()); + + if (player.getId() == this.getHolder().getId()) { + this.sendHotbarContents(); + } } } diff --git a/src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java index bbfe7ab038..2adcf1ddaf 100644 --- a/src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java +++ b/src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java @@ -68,7 +68,7 @@ public boolean executeOn(Player player, boolean force) { player.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, false); break; - case ITEM_RELEASE_ACTION_USE: + case ITEM_RELEASE_ACTION_CONSUME: if (player.getStartActionTick() > -1 && player.getDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION)) { if (inventory.getItemInHand().getId() == Item.BOW) { diff --git a/src/main/java/cn/nukkit/inventory/transaction/ItemUseTransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/ItemUseTransactionGroup.java index 7e18bea291..63a2cd79db 100644 --- a/src/main/java/cn/nukkit/inventory/transaction/ItemUseTransactionGroup.java +++ b/src/main/java/cn/nukkit/inventory/transaction/ItemUseTransactionGroup.java @@ -15,6 +15,7 @@ import cn.nukkit.entity.projectile.EntitySnowball; import cn.nukkit.event.entity.ProjectileLaunchEvent; import cn.nukkit.event.player.PlayerInteractEvent; +import cn.nukkit.event.player.PlayerInteractEvent.Action; import cn.nukkit.inventory.PlayerInventory; import cn.nukkit.item.Item; import cn.nukkit.level.sound.LaunchSound; @@ -46,6 +47,8 @@ public ItemUseTransactionGroup(int action, BlockVector3 blockPos, int face, int this.item = item; this.playerPos = playerPos; this.clickPos = clickPos; + + System.out.println("action: " + action); } @Override @@ -63,30 +66,30 @@ public boolean executeOn(Player player, boolean force) { BlockFace face; switch (this.action) { - case ITEM_USE_ACTION_PLACE: + case ITEM_USE_CLICK_AIR: 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; - } - } + Item item; + + if (player.isCreative()) { + item = player.getInventory().getItemInHand(); + } else if (!player.getInventory().getItemInHand().equals(this.item)) { + player.getInventory().sendHeldItem(player); + return true; + } else { + item = player.getInventory().getItemInHand(); + } + PlayerInteractEvent ev = new PlayerInteractEvent(player, item, player.getDirectionVector(), face, Action.RIGHT_CLICK_AIR); + player.getServer().getPluginManager().callEvent(ev); + if (ev.isCancelled()) { + player.getInventory().sendHeldItem(player); + return true; } - return false; - case ITEM_USE_ACTION_USE: + //TODO: handle air click + player.setDataFlag(Entity.DATA_FLAGS, Entity.DATA_FLAG_ACTION, true); + player.startAction(); + return false; + case ITEM_USE_CLICK_BLOCK: 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)) { @@ -95,7 +98,7 @@ public boolean executeOn(Player player, boolean force) { if (player.level.useItemOn(blockVector, i, face, clickPos.x, clickPos.y, clickPos.z, player) != null) { return true; } - } else if (inventory.getItemInHand().deepEquals(item)) { + } else if (inventory.getItemInHand().deepEquals(this.item)) { Item i = inventory.getItemInHand(); Item oldItem = i.clone(); //TODO: Implement adventure mode checks @@ -118,6 +121,8 @@ public boolean executeOn(Player player, boolean force) { Block target = player.level.getBlock(blockVector); Block block = target.getSide(face); + player.level.sendBlocks(new Player[]{player}, new Block[]{target, block}, UpdateBlockPacket.FLAG_ALL_PRIORITY); + if (target instanceof BlockDoor) { BlockDoor door = (BlockDoor) target; @@ -128,9 +133,10 @@ public boolean executeOn(Player player, boolean force) { if (part.getId() == target.getId()) { target = part; + + player.level.sendBlocks(new Player[]{player}, new Block[]{target}, UpdateBlockPacket.FLAG_ALL_PRIORITY); } } - player.level.sendBlocks(new Player[]{player}, new Block[]{target, block}, UpdateBlockPacket.FLAG_ALL_PRIORITY); } } else if (this.face == -1) { Vector3 aimPos = new Vector3( @@ -140,7 +146,7 @@ public boolean executeOn(Player player, boolean force) { ); Item i; - if (player.isCreative() || inventory.getItemInHand().deepEquals(item)) { + if (player.isCreative() || inventory.getItemInHand().deepEquals(this.item)) { i = inventory.getItemInHand(); } else { inventory.sendHeldItem(player); @@ -313,7 +319,7 @@ public boolean executeOn(Player player, boolean force) { } break; - case ITEM_USE_ACTION_DESTROY: + case ITEM_USE_BREAK_BLOCK: Item i = player.getInventory().getItemInHand(); Item oldItem = i.clone(); diff --git a/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java index 5ae20a0f0a..1e42c11f00 100644 --- a/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java +++ b/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java @@ -16,17 +16,47 @@ public interface TransactionGroup { 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_RELEASE_ACTION_RELEASE = 0; //Drop item, bow shoot + int ITEM_RELEASE_ACTION_CONSUME = 1; //eat arrows //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_CLICK_BLOCK = 0; + int ITEM_USE_CLICK_AIR = 1; + int ITEM_USE_BREAK_BLOCK = 2; //-1 - 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; + int SOURCE_CONTAINER = 0; + int SOURCE_WORLD = 2; //drop/pickup item entity + int SOURCE_CREATIVE = 3; + int SOURCE_TODO = 99999; + + int SOURCE_TYPE_CRAFTING_ADD_INGREDIENT = -2; + int SOURCE_TYPE_CRAFTING_REMOVE_INGREDIENT = -3; + int SOURCE_TYPE_CRAFTING_RESULT = -4; + int SOURCE_TYPE_CRAFTING_USE_INGREDIENT = -5; + + int SOURCE_TYPE_ANVIL_INPUT = -10; + int SOURCE_TYPE_ANVIL_MATERIAL = -11; + int SOURCE_TYPE_ANVIL_RESULT = -12; + int SOURCE_TYPE_ANVIL_OUTPUT = -13; + + int SOURCE_TYPE_ENCHANT_INPUT = -15; + int SOURCE_TYPE_ENCHANT_MATERIAL = -16; + int SOURCE_TYPE_ENCHANT_OUTPUT = -17; + + int SOURCE_TYPE_TRADING_INPUT_1 = -20; + int SOURCE_TYPE_TRADING_INPUT_2 = -21; + int SOURCE_TYPE_TRADING_USE_INPUTS = -22; + int SOURCE_TYPE_TRADING_OUTPUT = -23; + + int SOURCE_TYPE_BEACON = -24; + + int SOURCE_TYPE_CONTAINER_DROP_CONTENTS = -100; + + int ACTION_MAGIC_SLOT_DROP_ITEM = 0; + int ACTION_MAGIC_SLOT_PICKUP_ITEM = 1; + + int ACTION_MAGIC_SLOT_CREATIVE_DELETE_ITEM = 0; + int ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM = 1; long getCreationTime(); diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java index 0cb4bb8a11..eb37c5f640 100644 --- a/src/main/java/cn/nukkit/level/Level.java +++ b/src/main/java/cn/nukkit/level/Level.java @@ -1040,6 +1040,8 @@ public void sendBlocks(Player[] target, Vector3[] blocks, int flags, boolean opt } } + List packets = new ArrayList<>(); + for (UpdateBlockPacket.Entry entry : entries) { UpdateBlockPacket packet = new UpdateBlockPacket(); packet.x = entry.x; @@ -1051,8 +1053,10 @@ public void sendBlocks(Player[] target, Vector3[] blocks, int flags, boolean opt packet.flags = entry.flags; - Server.broadcastPacket(target, packet); + packets.add(packet); } + + this.getServer().batchPackets(target, packets.stream().toArray(DataPacket[]::new)); } public void clearCache() { @@ -1969,6 +1973,11 @@ 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); @@ -2014,32 +2023,10 @@ public Item useItemOn(Vector3 vector, Item item, BlockFace face, float fx, float } else { return null; } + } 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/protocol/AdventureSettingsPacket.java b/src/main/java/cn/nukkit/network/protocol/AdventureSettingsPacket.java index 38eae516f7..c46520cf0c 100644 --- a/src/main/java/cn/nukkit/network/protocol/AdventureSettingsPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/AdventureSettingsPacket.java @@ -1,98 +1,95 @@ package cn.nukkit.network.protocol; +import cn.nukkit.Player; + /** * @author Nukkit Project Team */ 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; - public boolean noMvp; - - public boolean autoJump; - public boolean allowFlight; - public boolean noClip; - public boolean worldBuilder; - public boolean isFlying; - public boolean muted; - - /* - bit mask | flag name - 0x00000001 world_immutable - 0x00000002 no_pvp - 0x00000004 no_pvm - 0x00000008 no_mvp - 0x00000010 ? - 0x00000020 auto_jump - 0x00000040 allow_fly - 0x00000080 noclip - 0x00000100 ? - 0x00000200 is_flying - */ - - 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; + public static final int PERMISSION_NORMAL = 0; + public static final int PERMISSION_OPERATOR = 1; + public static final int PERMISSION_HOST = 2; + public static final int PERMISSION_AUTOMATION = 3; + public static final int PERMISSION_ADMIN = 4; + //TODO: check level 3 + /** + * This constant is used to identify flags that should be set on the second field. In a sensible world, these + * flags would all be set on the same packet field, but as of MCPE 1.2, the new abilities flags have for some + * reason been assigned a separate field. + */ + public static final int BITFLAG_SECOND_SET = 1 << 16; + + public static final int WORLD_IMMUTABLE = 0x01; + public static final int NO_PVP = 0x02; + public static final int AUTO_JUMP = 0x20; + public static final int ALLOW_FLIGHT = 0x40; + public static final int NO_CLIP = 0x80; + public static final int WORLD_BUILDER = 0x100; + public static final int FLYING = 0x200; + public static final int MUTED = 0x400; + public static final int BUILD_AND_MINE = 0x01 | BITFLAG_SECOND_SET; + public static final int DOORS_AND_SWITCHES = 0x02 | BITFLAG_SECOND_SET; + public static final int OPEN_CONTAINERS = 0x04 | BITFLAG_SECOND_SET; + public static final int ATTACK_PLAYERS = 0x08 | BITFLAG_SECOND_SET; + public static final int ATTACK_MOBS = 0x10 | BITFLAG_SECOND_SET; + public static final int OPERATOR = 0x20 | BITFLAG_SECOND_SET; + public static final int TELEPORT = 0x80 | BITFLAG_SECOND_SET; + + public long flags = 0; + + public long commandPermission = PERMISSION_NORMAL; + + public long flags2 = -1; + + public long playerPermission = Player.PERMISSION_MEMBER; + + public long customFlags; //... + + public long entityUniqueId; //This is a little-endian long, NOT a var-long. (WTF Mojang) - @Override public void decode() { - this.flags = (int) this.getUnsignedVarInt(); - this.userPermission = (int) this.getUnsignedVarInt(); - this.worldImmutable = (this.flags & 1) != 0; - this.noPvp = (this.flags & (1 << 1)) != 0; - this.noPvm = (this.flags & (1 << 2)) != 0; - this.noMvp = (this.flags & (1 << 3)) != 0; - - this.autoJump = (this.flags & (1 << 5)) != 0; - this.allowFlight = (this.flags & (1 << 6)) != 0; - this.noClip = (this.flags & (1 << 7)) != 0; - this.worldBuilder = (this.flags & (1 << 8)) != 0; - this.isFlying = (this.flags & (1 << 9)) != 0; - this.muted = (this.flags & (1 << 10)) != 0; + this.flags = getUnsignedVarInt(); + this.commandPermission = getUnsignedVarInt(); + this.flags2 = getUnsignedVarInt(); + this.playerPermission = getUnsignedVarInt(); + this.customFlags = getUnsignedVarInt(); + this.entityUniqueId = getLLong(); } - @Override public void encode() { - this.reset(); - if (this.worldImmutable) this.flags |= 1; - if (this.noPvp) this.flags |= 1 << 1; - if (this.noPvm) this.flags |= 1 << 2; - if (this.noMvp) this.flags |= 1 << 3; - - if (this.autoJump) this.flags |= 1 << 5; - if (this.allowFlight) this.flags |= 1 << 6; - if (this.noClip) this.flags |= 1 << 7; - if (this.worldBuilder) this.flags |= 1 << 8; - if (this.isFlying) this.flags |= 1 << 9; - 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)); + this.putUnsignedVarInt(this.commandPermission); + this.putUnsignedVarInt(this.flags2); + this.putUnsignedVarInt(this.playerPermission); + this.putUnsignedVarInt(this.customFlags); + this.putLLong(this.entityUniqueId); + } + + public boolean getFlag(int flag) { + if ((flag & BITFLAG_SECOND_SET) != 0) { + return (this.flags2 & flag) != 0; + } + return (this.flags & flag) != 0; + } + + public void setFlag(int flag, boolean value) { + boolean flags = (flag & BITFLAG_SECOND_SET) != 0; + + if (value) { + if (flags) { + this.flags2 |= flag; + } else { + this.flags |= flag; + } } else { - this.putLLong(this.userId >> 1); + if (flags) { + this.flags2 &= ~flag; + } else { + this.flags &= ~flag; + } } } diff --git a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java index 9241bc45ee..7e3685cb67 100644 --- a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java @@ -7,8 +7,6 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.List; import java.util.Map; /** @@ -25,11 +23,19 @@ public class AvailableCommandsPacket extends DataPacket { 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; + public static final int ARG_TYPE_JSON = 0x15; + public static final int ARG_TYPE_COMMAND = 0x1c; + + public static final int ARG_FLAG_ENUM = 0x200000; + public static final int ARG_FLAG_TEMPLATE = 0x01000000; + @Override public byte pid() { return NETWORK_ID; diff --git a/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java b/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java index 8a06975959..1090e36ba6 100644 --- a/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java @@ -20,6 +20,8 @@ public class ClientboundMapItemDataPacket extends DataPacket { public int offsetX; public int offsetZ; + public byte dimensionId; + public MapDecorator[] decorators = new MapDecorator[0]; public int[] colors = new int[0]; public BufferedImage image = null; @@ -57,6 +59,7 @@ public void encode() { } this.putUnsignedVarInt(update); + this.putByte(this.dimensionId); if ((update & 0x08) != 0) { //TODO: find out what these are for this.putUnsignedVarInt(eids.length); diff --git a/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java b/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java index 61551a034b..c42ae1312e 100644 --- a/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java @@ -1,7 +1,6 @@ package cn.nukkit.network.protocol; import cn.nukkit.inventory.transaction.*; -import cn.nukkit.math.BlockFace; import java.util.ArrayList; import java.util.List; @@ -92,6 +91,7 @@ public void decode() { } list.add(ts); } + switch (type) { case TransactionGroup.TYPE_NORMAL: transaction = new NormalTransactionGroup(); @@ -109,6 +109,7 @@ public void decode() { this.getVector3f(), this.getVector3f() ); + break; case TransactionGroup.TYPE_ITEM_USE_ON_ENTITY: transaction = new ItemUseOnEntityTransactionGroup( diff --git a/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java b/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java index 17063445e5..c5a35f44fb 100644 --- a/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java @@ -41,7 +41,12 @@ public class LevelEventPacket extends DataPacket { public static final int EVENT_SOUND_CAMERA_TAKE_PICTURE = 1050; public static final int EVENT_SOUND_EXPERIENCE_ORB = 1051; - public static final int EVENT_SOUND_BLOCK_PLACE = 1052; + public static final int EVENT_SOUND_TOTEM = 1052; + + public static final int EVENT_SOUND_ARMOR_STAND_BREAK = 1060; + public static final int EVENT_SOUND_ARMOR_STAND_HIT = 1061; + public static final int EVENT_SOUND_ARMOR_STAND_FALL = 1062; + public static final int EVENT_SOUND_ARMOR_STAND_PLACE = 1063; public static final int EVENT_GUARDIAN_CURSE = 2006; @@ -58,6 +63,7 @@ public class LevelEventPacket extends DataPacket { public static final int EVENT_SOUND_SPLASH = 3506; public static final int EVENT_CAULDRON_TAKE_WATER = 3507; public static final int EVENT_CAULDRON_ADD_DYE = 3508; + public static final int EVENT_CAULDRON_CLEAN_BANNER = 3509; public static final int EVENT_PARTICLE_SHOOT = 2000; public static final int EVENT_PARTICLE_DESTROY = 2001; diff --git a/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java b/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java index b40fb480e5..d70e47b7c2 100644 --- a/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java @@ -9,25 +9,25 @@ public class PlayerActionPacket extends DataPacket { public static final byte NETWORK_ID = ProtocolInfo.PLAYER_ACTION_PACKET; - 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_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 static final int ACTION_START_BREAK = 0; + public static final int ACTION_ABORT_BREAK = 1; + public static final int ACTION_STOP_BREAK = 2; + public static final int ACTION_GET_UPDATED_BLOCK = 3; + public static final int ACTION_DROP_ITEM = 4; + public static final int ACTION_START_SLEEPING = 5; + public static final int ACTION_STOP_SLEEPING = 6; + public static final int ACTION_RESPAWN = 7; + public static final int ACTION_JUMP = 8; + public static final int ACTION_START_SPRINT = 9; + public static final int ACTION_STOP_SPRINT = 10; + public static final int ACTION_START_SNEAK = 11; + public static final int ACTION_STOP_SNEAK = 12; + public static final int ACTION_DIMENSION_CHANGE_REQUEST = 13; //sent when dying in different dimension + public static final int ACTION_DIMENSION_CHANGE_ACK = 14; //sent when spawning in a different dimension to tell the server we spawned + public static final int ACTION_START_GLIDE = 15; + public static final int ACTION_STOP_GLIDE = 16; + public static final int ACTION_BUILD_DENIED = 17; + public static final int ACTION_CONTINUE_BREAK = 18; public long entityId; public int action; diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java index 977bc6734b..80ebd9f5ea 100644 --- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java +++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java @@ -9,10 +9,10 @@ public interface ProtocolInfo { /** * Actual Minecraft: PE protocol version */ - byte CURRENT_PROTOCOL = Integer.valueOf("131").byteValue(); //plugins can change it + byte CURRENT_PROTOCOL = Integer.valueOf("136").byteValue(); //plugins can change it - String MINECRAFT_VERSION = "v1.2.0.7 beta"; - String MINECRAFT_VERSION_NETWORK = "1.2.0.7"; + String MINECRAFT_VERSION = "v1.2.0.31 beta"; + String MINECRAFT_VERSION_NETWORK = "1.2.0.31"; byte LOGIN_PACKET = 0x01; byte PLAY_STATUS_PACKET = 0x02; diff --git a/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java b/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java index 24c8aa0921..bb334a0520 100644 --- a/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java +++ b/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java @@ -51,6 +51,8 @@ public byte pid() { public boolean unknown = false; public long currentTick; + public int enchantmentSeed; + @Override public void decode() { @@ -94,6 +96,7 @@ public void encode() { this.putString(this.premiumWorldTemplateId); this.putBoolean(this.unknown); this.putLLong(this.currentTick); + this.putVarInt(this.enchantmentSeed); } } From 39de211241f464ecb257b6609a7c355052d805d2 Mon Sep 17 00:00:00 2001 From: Adam Matthew Date: Sun, 17 Sep 2017 08:57:18 +0800 Subject: [PATCH 073/175] Fix issue when attempt to register block entity by plugin (#1897) --- src/main/java/cn/nukkit/level/Level.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java index 5a4dcf3ef3..2952bb29f6 100644 --- a/src/main/java/cn/nukkit/level/Level.java +++ b/src/main/java/cn/nukkit/level/Level.java @@ -2367,14 +2367,18 @@ public void setChunk(int chunkX, int chunkZ, BaseFullChunk chunk, boolean unload for (Entity entity : oldEntities.values()) { chunk.addEntity(entity); - oldChunk.removeEntity(entity); - entity.chunk = chunk; + if (oldChunk != null) { + oldChunk.removeEntity(entity); + entity.chunk = chunk; + } } for (BlockEntity blockEntity : oldBlockEntities.values()) { chunk.addBlockEntity(blockEntity); - oldChunk.removeBlockEntity(blockEntity); - blockEntity.chunk = chunk; + if (oldChunk != null) { + oldChunk.removeBlockEntity(blockEntity); + blockEntity.chunk = chunk; + } } this.provider.setChunk(chunkX, chunkZ, chunk); From 235dd4306f5b350363311f0b9272268451255a88 Mon Sep 17 00:00:00 2001 From: leNic Date: Sun, 17 Sep 2017 02:57:54 +0200 Subject: [PATCH 074/175] Make Angle region independent (#1896) --- src/main/java/cn/nukkit/math/Angle.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/math/Angle.java b/src/main/java/cn/nukkit/math/Angle.java index 33a7fd61f9..3b3c781f1f 100644 --- a/src/main/java/cn/nukkit/math/Angle.java +++ b/src/main/java/cn/nukkit/math/Angle.java @@ -1,5 +1,7 @@ package cn.nukkit.math; +import java.util.Locale; + import static java.lang.Math.*; /** @@ -96,7 +98,8 @@ public static int compare(Angle a, Angle b) { @Override public String toString() { - return String.format("Angle[%s, %f%s = %f%s] [%d]", + return String.format(Locale.ROOT, + "Angle[%s, %f%s = %f%s] [%d]", isOriginDouble ? "Double" : "Float", isOriginDouble ? doubleValue : floatValue, isDegree ? "deg" : "rad", From e90105175a054afa438f0b2cdce1f107a85dac11 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 17 Sep 2017 18:44:57 +0200 Subject: [PATCH 075/175] rewrote transaction packet handling (from PMMP) --- src/main/java/cn/nukkit/Player.java | 784 ++++++++++++------ src/main/java/cn/nukkit/block/Block.java | 2 +- ...Workbench.java => BlockCraftingTable.java} | 8 +- .../nukkit/blockentity/BlockEntityChest.java | 2 +- .../defaults/SetWorldSpawnCommand.java | 2 +- .../command/defaults/SpawnpointCommand.java | 2 +- .../command/defaults/TeleportCommand.java | 4 +- .../java/cn/nukkit/entity/EntityHuman.java | 4 - .../inventory/InventoryTransactionEvent.java | 9 +- .../cn/nukkit/inventory/AnvilInventory.java | 1 + .../cn/nukkit/inventory/BaseInventory.java | 22 +- .../cn/nukkit/inventory/BigCraftingGrid.java | 16 + .../cn/nukkit/inventory/BrewingInventory.java | 4 +- .../cn/nukkit/inventory/CraftingGrid.java | 34 + .../nukkit/inventory/CraftingInventory.java | 27 - .../cn/nukkit/inventory/EnchantInventory.java | 4 +- .../cn/nukkit/inventory/FurnaceInventory.java | 4 +- .../java/cn/nukkit/inventory/Inventory.java | 24 +- .../cn/nukkit/inventory/InventoryType.java | 5 +- .../inventory/PlayerCursorInventory.java | 58 ++ .../cn/nukkit/inventory/PlayerInventory.java | 113 ++- .../transaction/BaseTransaction.java | 44 - .../transaction/BaseTransactionGroup.java | 47 -- .../transaction/ContainerTransaction.java | 28 - .../transaction/CraftTransaction.java | 22 - .../transaction/CreativeTransaction.java | 15 - .../transaction/GlobalTransaction.java | 15 - .../InventoryMismatchTransactionGroup.java | 21 - .../transaction/InventoryTransaction.java | 26 + .../ItemReleaseTransactionGroup.java | 193 ----- .../ItemUseOnEntityTransactionGroup.java | 57 -- .../transaction/ItemUseTransactionGroup.java | 391 --------- .../transaction/NormalTransactionGroup.java | 120 --- .../SimpleInventoryTransaction.java | 233 ++++++ .../inventory/transaction/Transaction.java | 26 - .../transaction/TransactionGroup.java | 76 -- .../WorldInteractionTransaction.java | 22 - .../action/CreativeInventoryAction.java | 54 ++ .../transaction/action/DropItemAction.java | 37 + .../transaction/action/InventoryAction.java | 66 ++ .../transaction/action/SlotChangeAction.java | 68 ++ .../transaction/data/ReleaseItemData.java | 15 + .../transaction/data/TransactionData.java | 7 + .../transaction/data/UseItemData.java | 22 + .../transaction/data/UseItemOnEntityData.java | 18 + src/main/java/cn/nukkit/item/Item.java | 28 + src/main/java/cn/nukkit/item/ItemBow.java | 103 +++ .../java/cn/nukkit/item/ItemSnowball.java | 12 +- .../java/cn/nukkit/item/ProjectileItem.java | 62 ++ .../java/cn/nukkit/math/BlockVector3.java | 8 + src/main/java/cn/nukkit/math/Vector3.java | 8 + src/main/java/cn/nukkit/math/Vector3f.java | 8 + .../network/protocol/InteractPacket.java | 2 - .../protocol/InventoryTransactionPacket.java | 215 ++--- .../network/protocol/MobEquipmentPacket.java | 12 +- .../network/protocol/PlayerHotbarPacket.java | 33 +- .../network/protocol/types/ContainerIds.java | 18 + .../types/NetworkInventoryAction.java | 175 ++++ src/main/java/cn/nukkit/utils/Binary.java | 24 + .../java/cn/nukkit/utils/BinaryStream.java | 12 +- 60 files changed, 1915 insertions(+), 1557 deletions(-) rename src/main/java/cn/nukkit/block/{BlockWorkbench.java => BlockCraftingTable.java} (81%) create mode 100644 src/main/java/cn/nukkit/inventory/BigCraftingGrid.java create mode 100644 src/main/java/cn/nukkit/inventory/CraftingGrid.java delete mode 100644 src/main/java/cn/nukkit/inventory/CraftingInventory.java create mode 100644 src/main/java/cn/nukkit/inventory/PlayerCursorInventory.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/BaseTransaction.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/BaseTransactionGroup.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/ContainerTransaction.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/CraftTransaction.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/CreativeTransaction.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/GlobalTransaction.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/InventoryMismatchTransactionGroup.java create mode 100644 src/main/java/cn/nukkit/inventory/transaction/InventoryTransaction.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/ItemUseOnEntityTransactionGroup.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/ItemUseTransactionGroup.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/NormalTransactionGroup.java create mode 100644 src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/Transaction.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java delete mode 100644 src/main/java/cn/nukkit/inventory/transaction/WorldInteractionTransaction.java create mode 100644 src/main/java/cn/nukkit/inventory/transaction/action/CreativeInventoryAction.java create mode 100644 src/main/java/cn/nukkit/inventory/transaction/action/DropItemAction.java create mode 100644 src/main/java/cn/nukkit/inventory/transaction/action/InventoryAction.java create mode 100644 src/main/java/cn/nukkit/inventory/transaction/action/SlotChangeAction.java create mode 100644 src/main/java/cn/nukkit/inventory/transaction/data/ReleaseItemData.java create mode 100644 src/main/java/cn/nukkit/inventory/transaction/data/TransactionData.java create mode 100644 src/main/java/cn/nukkit/inventory/transaction/data/UseItemData.java create mode 100644 src/main/java/cn/nukkit/inventory/transaction/data/UseItemOnEntityData.java create mode 100644 src/main/java/cn/nukkit/item/ProjectileItem.java create mode 100644 src/main/java/cn/nukkit/network/protocol/types/ContainerIds.java create mode 100644 src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 7be1eae2d3..50a9ef25d7 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -1,12 +1,10 @@ package cn.nukkit; -import cn.nukkit.block.Block; -import cn.nukkit.block.BlockAir; -import cn.nukkit.block.BlockEnderChest; -import cn.nukkit.block.BlockNoteblock; +import cn.nukkit.block.*; 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; @@ -21,7 +19,10 @@ 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.*; +import cn.nukkit.event.inventory.CraftItemEvent; +import cn.nukkit.event.inventory.InventoryCloseEvent; +import cn.nukkit.event.inventory.InventoryPickupArrowEvent; +import cn.nukkit.event.inventory.InventoryPickupItemEvent; import cn.nukkit.event.player.*; import cn.nukkit.event.player.PlayerInteractEvent.Action; import cn.nukkit.event.player.PlayerTeleportEvent.TeleportCause; @@ -29,7 +30,12 @@ import cn.nukkit.event.server.DataPacketSendEvent; import cn.nukkit.form.window.FormWindow; import cn.nukkit.inventory.*; -import cn.nukkit.inventory.transaction.*; +import cn.nukkit.inventory.transaction.InventoryTransaction; +import cn.nukkit.inventory.transaction.SimpleInventoryTransaction; +import cn.nukkit.inventory.transaction.action.InventoryAction; +import cn.nukkit.inventory.transaction.data.ReleaseItemData; +import cn.nukkit.inventory.transaction.data.UseItemData; +import cn.nukkit.inventory.transaction.data.UseItemOnEntityData; import cn.nukkit.item.*; import cn.nukkit.item.enchantment.Enchantment; import cn.nukkit.item.food.Food; @@ -51,6 +57,8 @@ import cn.nukkit.nbt.tag.*; import cn.nukkit.network.SourceInterface; import cn.nukkit.network.protocol.*; +import cn.nukkit.network.protocol.types.ContainerIds; +import cn.nukkit.network.protocol.types.NetworkInventoryAction; import cn.nukkit.permission.PermissibleBase; import cn.nukkit.permission.Permission; import cn.nukkit.permission.PermissionAttachment; @@ -62,11 +70,13 @@ import cn.nukkit.utils.*; import co.aikar.timings.Timing; import co.aikar.timings.Timings; +import com.google.gson.Gson; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteOrder; import java.util.*; +import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicReference; /** @@ -110,6 +120,7 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde protected Map windows; protected Map windowIndex = new HashMap<>(); + protected Set permanentWindows = new HashSet<>(); protected int messageCounter = 2; @@ -119,10 +130,11 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde public final HashSet achievements = new HashSet<>(); - protected BaseTransactionGroup currentTransaction = null; - public int craftingType = CRAFTING_SMALL; + protected PlayerCursorInventory cursorInventory; + protected CraftingGrid craftingGrid; + public long creationTime = 0; protected long randomClientId; @@ -427,6 +439,7 @@ public void setOp(boolean value) { this.recalculatePermissions(); this.getAdventureSettings().update(); this.sendCommandData(); + this.inventory.sendCreativeContents(); } @Override @@ -569,6 +582,12 @@ public Player(SourceInterface interfaz, Long clientID, String ip, int port) { this.creationTime = System.currentTimeMillis(); } + @Override + protected void initEntity() { + super.initEntity(); + this.addDefaultWindows(); + } + public boolean isPlayer() { return true; } @@ -624,6 +643,20 @@ public int getInAirTicks() { return this.inAirTicks; } + /** + * Returns whether the player is currently using an item (right-click and hold). + * + * @return bool + */ + public boolean isUsingItem() { + return this.getDataFlag(DATA_FLAGS, DATA_FLAG_ACTION) && this.startAction > -1; + } + + public void setUsingItem(boolean value) { + this.startAction = value ? this.server.getTick() : -1; + this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION, value); + } + public String getButtonText() { return this.buttonText; } @@ -1175,6 +1208,7 @@ public boolean setGamemode(int gamemode, boolean clientSide, AdventureSettings n this.inventory.sendContents(this.getViewers().values()); this.inventory.sendHeldItem(this.hasSpawned.values()); + this.inventory.sendCreativeContents(); return true; } @@ -2149,64 +2183,26 @@ public void handleDataPacket(DataPacket packet) { MobEquipmentPacket mobEquipmentPacket = (MobEquipmentPacket) packet; - if (mobEquipmentPacket.slot == 0x28 || mobEquipmentPacket.slot == 0 || mobEquipmentPacket.slot == 255) { - mobEquipmentPacket.slot = -1; - } else { - mobEquipmentPacket.slot -= 9; - } - - Item item; - int slot; - if (this.isCreative()) { - item = mobEquipmentPacket.item; - slot = Item.getCreativeItemIndex(item); + if (mobEquipmentPacket.inventorySlot == 255) { + mobEquipmentPacket.inventorySlot = -1; //Cleared inventorySlot } else { - item = this.inventory.getItem(mobEquipmentPacket.slot); - slot = mobEquipmentPacket.slot; - } + if (mobEquipmentPacket.inventorySlot < 9) { + this.getServer().getLogger().debug("Tried to equip a inventorySlot that does not exist (index " + mobEquipmentPacket.inventorySlot + ")"); + this.inventory.sendContents(this); + return; + } + mobEquipmentPacket.inventorySlot -= 9; //Get real inventory inventorySlot - if (mobEquipmentPacket.slot == -1) { - if (this.isCreative()) { - boolean found = false; - for (int i = 0; i < this.inventory.getHotbarSize(); ++i) { - if (this.inventory.getHotbarSlotIndex(i) == -1) { - this.inventory.setHeldItemIndex(i); - found = true; - break; - } + Item item = this.inventory.getItem(mobEquipmentPacket.inventorySlot); - } - if (!found) { - this.inventory.sendContents(this); - break; - } - } else { - if (mobEquipmentPacket.selectedSlot >= 0 && mobEquipmentPacket.selectedSlot < 9) { - this.inventory.setHeldItemIndex(mobEquipmentPacket.selectedSlot); - this.inventory.setHeldItemSlot(mobEquipmentPacket.slot); - } else { - this.inventory.sendContents(this); - break; - } - } - } else if (item == null || slot == -1 || !item.deepEquals(mobEquipmentPacket.item, true, false)) { - this.inventory.sendContents(this); - break; - } else if (this.isCreative()) { - this.inventory.setHeldItemIndex(mobEquipmentPacket.selectedSlot); - this.inventory.setItem(mobEquipmentPacket.selectedSlot, item); - this.inventory.setHeldItemSlot(mobEquipmentPacket.selectedSlot); - } else { - if (mobEquipmentPacket.selectedSlot >= 0 && mobEquipmentPacket.selectedSlot < this.inventory.getHotbarSize()) { - this.inventory.setHeldItemIndex(mobEquipmentPacket.selectedSlot); - this.inventory.setHeldItemSlot(slot); - } else { + if (!item.equals(mobEquipmentPacket.item)) { + this.server.getLogger().debug("Tried to equip " + mobEquipmentPacket.item + " but have " + item + " in target inventorySlot"); this.inventory.sendContents(this); - break; + return; } } - this.inventory.sendHeldItem(this.hasSpawned.values()); + this.inventory.equipItem(mobEquipmentPacket.hotbarSlot, mobEquipmentPacket.inventorySlot); this.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, false); break; @@ -2291,6 +2287,7 @@ public void handleDataPacket(DataPacket packet) { } this.craftingType = CRAFTING_SMALL; + this.resetCraftingGridType(); PlayerRespawnEvent playerRespawnEvent = new PlayerRespawnEvent(this, this.getSpawn()); this.server.getPluginManager().callEvent(playerRespawnEvent); @@ -2424,6 +2421,9 @@ public void handleDataPacket(DataPacket packet) { break; } + this.craftingType = CRAFTING_SMALL; + this.resetCraftingGridType(); + InteractPacket interactPacket = (InteractPacket) packet; Entity targetEntity = this.level.getEntity(interactPacket.target); @@ -2432,88 +2432,18 @@ public void handleDataPacket(DataPacket packet) { break; } - this.craftingType = CRAFTING_SMALL; - if (targetEntity instanceof EntityItem || targetEntity instanceof EntityArrow || targetEntity instanceof EntityXPOrb) { - this.kick(PlayerKickEvent.Reason.INVALID_PVE, "Attempting to attack an invalid entity"); + this.kick(PlayerKickEvent.Reason.INVALID_PVE, "Attempting to interact with an invalid entity"); this.server.getLogger().warning(this.getServer().getLanguage().translateString("nukkit.player.invalidEntity", this.getName())); break; } - - item = this.inventory.getItemInHand(); + + Item item = this.inventory.getItemInHand(); switch (interactPacket.action) { case InteractPacket.ACTION_MOUSEOVER: this.getServer().getPluginManager().callEvent(new PlayerMouseOverEntityEvent(this, targetEntity)); break; - case InteractPacket.ACTION_LEFT_CLICK: - if (this.getGamemode() == Player.VIEW) { - break; - } - - float itemDamage = item.getAttackDamage(); - - for (Enchantment enchantment : item.getEnchantments()) { - itemDamage += enchantment.getDamageBonus(targetEntity); - } - - Map damage = new EnumMap<>(DamageModifier.class); - damage.put(DamageModifier.BASE, itemDamage); - - if (!this.canInteract(targetEntity, isCreative() ? 8 : 5)) { - break; - } else if (targetEntity instanceof Player) { - if ((((Player) targetEntity).getGamemode() & 0x01) > 0) { - break; - } else if (!this.server.getPropertyBoolean("pvp") || this.server.getDifficulty() == 0) { - break; - } - } - - if (!targetEntity.attack(new EntityDamageByEntityEvent(this, targetEntity, DamageCause.ENTITY_ATTACK, damage))) { - if (item.isTool() && this.isSurvival()) { - this.inventory.sendContents(this); - } - break; - } - - for (Enchantment enchantment : item.getEnchantments()) { - enchantment.doPostAttack(this, targetEntity); - } - - if (item.isTool() && this.isSurvival()) { - if (item.useOn(targetEntity) && item.getDamage() >= item.getMaxDurability()) { - this.inventory.setItemInHand(new ItemBlock(new BlockAir())); - } else { - this.inventory.setItemInHand(item); - } - } - - break; - case InteractPacket.ACTION_RIGHT_CLICK: - PlayerInteractEntityEvent playerInteractEntityEvent = new PlayerInteractEntityEvent(this, targetEntity, item); - getServer().getPluginManager().callEvent(playerInteractEntityEvent); - - if (playerInteractEntityEvent.isCancelled()) { - break; - } - - if (targetEntity.onInteract(this, item) && this.isSurvival()) { - if (item.isTool()) { - if (item.useOn(targetEntity) && item.getDamage() >= item.getMaxDurability()) { - item = new ItemBlock(new BlockAir()); - } - } else { - if (item.count > 1) { - item.count--; - } else { - item = new ItemBlock(new BlockAir()); - } - } - - this.inventory.setItemInHand(item); - } - break; case InteractPacket.ACTION_VEHICLE_EXIT: if (!(targetEntity instanceof EntityVehicle) || this.riding == null) { break; @@ -2563,6 +2493,7 @@ public void handleDataPacket(DataPacket packet) { break; } this.craftingType = CRAFTING_SMALL; + this.resetCraftingGridType(); EntityEventPacket entityEventPacket = (EntityEventPacket) packet; @@ -2646,6 +2577,7 @@ public void handleDataPacket(DataPacket packet) { } this.craftingType = CRAFTING_SMALL; + this.resetCraftingGridType(); TextPacket textPacket = (TextPacket) packet; if (textPacket.type == TextPacket.TYPE_CHAT) { @@ -2667,7 +2599,7 @@ public void handleDataPacket(DataPacket packet) { break; } this.craftingType = CRAFTING_SMALL; - this.currentTransaction = null; + this.resetCraftingGridType(); 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)); @@ -2746,6 +2678,10 @@ public void handleDataPacket(DataPacket packet) { if (craftingEventPacket.input.length == 0) { Recipe[] recipes = getServer().getCraftingManager().getRecipesByResult(craftingEventPacket.output[0]); + if (recipes == null || recipes.length == 0) { + this.getServer().getLogger().debug("Uknown recipe for output (" + craftingEventPacket.output[0] + ")"); + } + recipe = null; ArrayList ingredientz = new ArrayList<>(); @@ -3021,17 +2957,17 @@ public void handleDataPacket(DataPacket packet) { int[] used = new int[this.inventory.getSize()]; for (Item ingredient : ingredients) { - slot = -1; + inventorySlot = -1; for (int index : this.inventory.getContents().keySet()) { Item i = this.inventory.getContents().get(index); if (ingredient.getId() != 0 && ingredient.deepEquals(i, ingredient.hasMeta()) && (i.getCount() - used[index]) >= 1) { - slot = index; + inventorySlot = index; used[index]++; break; } } - if (ingredient.getId() != 0 && slot == -1) { + if (ingredient.getId() != 0 && inventorySlot == -1) { canCraft = false; break; } @@ -3115,121 +3051,6 @@ public void handleDataPacket(DataPacket packet) { break; } } - break; - case ProtocolInfo.INVENTORY_SLOT_PACKET: - if (!this.spawned || !this.isAlive()) { - break; - } - - InventorySlotPacket inventorySlotPacket = (InventorySlotPacket) packet; - if (inventorySlotPacket.slot < 0) { - break; - } - - Inventory inv; - BaseTransaction transaction; - if (inventorySlotPacket.inventoryId == 0) { //Our inventory - inv = this.inventory; - if (inventorySlotPacket.slot >= this.inventory.getSize()) { - break; - } - if (this.isCreative()) { - 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 ContainerTransaction(0, inventorySlotPacket.slot, this.inventory.getItem(inventorySlotPacket.slot), inventorySlotPacket.item); - } else if (inventorySlotPacket.inventoryId == InventoryContentPacket.SPECIAL_ARMOR) { //Our armor - inv = this.inventory; - if (inventorySlotPacket.slot >= 4) { - break; - } - 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 && inventorySlotPacket.item.hasEnchantments()) { - ((EnchantInventory) inv).onEnchant(this, inv.getItem(inventorySlotPacket.slot), inventorySlotPacket.item); - } - - transaction = new ContainerTransaction(inventorySlotPacket.inventoryId, inventorySlotPacket.slot, inv.getItem(inventorySlotPacket.slot), inventorySlotPacket.item); - } else { - break; - } - - if (inv != null) { - Item sourceItem = inv.getItem(inventorySlotPacket.slot); - Item heldItem = sourceItem.clone(); - heldItem.setCount(sourceItem.getCount() - inventorySlotPacket.item.getCount()); - if (heldItem.getCount() > 0) { //In win10, click mouse and hold on 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 - } - } - - if (transaction.getSourceItem().deepEquals(transaction.getTargetItem()) && transaction.getTargetItem().getCount() == transaction.getSourceItem().getCount()) { //No changes! - //No changes, just a local inventory update sent by the server - break; - } - - - if (this.currentTransaction == null || this.currentTransaction.getCreationTime() < (System.currentTimeMillis() - 8 * 1000)) { - if (this.currentTransaction != null) { - 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); - } - } - } - } - this.currentTransaction = new NormalTransactionGroup(); - } - - this.currentTransaction.addTransaction(transaction); - - if (this.currentTransaction.canExecute(this) || this.isCreative()) { - HashSet achievements = new HashSet<>(); - - for (Transaction tr : this.currentTransaction.getTransactions()) { - 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.executeOn(this, this.isCreative())) { - for (String achievement : achievements) { - this.awardAchievement(achievement); - } - } - - this.currentTransaction = null; - } else { - if (inventorySlotPacket.item.getId() != 0) { - inventory.sendSlot(inventorySlotPacket.slot, this); - } - } - break; case ProtocolInfo.BLOCK_ENTITY_DATA_PACKET: if (!this.spawned || !this.isAlive()) { @@ -3237,6 +3058,7 @@ public void handleDataPacket(DataPacket packet) { } BlockEntityDataPacket blockEntityDataPacket = (BlockEntityDataPacket) packet; this.craftingType = CRAFTING_SMALL; + this.resetCraftingGridType(); pos = new Vector3(blockEntityDataPacket.x, blockEntityDataPacket.y, blockEntityDataPacket.z); if (pos.distanceSquared(this) > 10000) { @@ -3370,14 +3192,353 @@ public void handleDataPacket(DataPacket packet) { } break; case ProtocolInfo.INVENTORY_TRANSACTION_PACKET: - ((InventoryTransactionPacket) packet).transaction.executeOn(this, this.isCreative()); + if (this.isSpectator()) { + this.sendAllInventories(); + break; + } + + InventoryTransactionPacket transactionPacket = (InventoryTransactionPacket) packet; + + + List actions = new ArrayList<>(); + for (NetworkInventoryAction networkInventoryAction : transactionPacket.actions) { + try { + actions.add(networkInventoryAction.createInventoryAction(this)); + } catch (Throwable e) { + MainLogger.getLogger().debug("Unhandled inventory action from " + this.getName() + ": " + e.getMessage()); + this.sendAllInventories(); + break packetswitch; + } + } + + switch (transactionPacket.transactionType) { + case InventoryTransactionPacket.TYPE_NORMAL: + InventoryTransaction transaction = new SimpleInventoryTransaction(this, actions); + + if (!transaction.execute()) { + for (Inventory inventory : transaction.getInventories()) { + inventory.sendContents(this); + if (inventory instanceof PlayerInventory) { + ((PlayerInventory) inventory).sendArmorContents(this); + } + } + + MainLogger.getLogger().debug("Failed to execute inventory transaction from " + this.getName() + " with actions: " + new Gson().toJson(transactionPacket.actions)); + + //TODO: check more stuff that might need reversion + break packetswitch; //oops! + } + + //TODO: fix achievement for getting iron from furnace + + break packetswitch; + case InventoryTransactionPacket.TYPE_MISMATCH: + if (transactionPacket.actions.length > 0) { + this.server.getLogger().debug("Expected 0 actions for mismatch, got " + transactionPacket.actions.length + ", " + new Gson().toJson(transactionPacket.actions)); + } + this.sendAllInventories(); + + break packetswitch; + case InventoryTransactionPacket.TYPE_USE_ITEM: + UseItemData useItemData = (UseItemData) transactionPacket.transactionData; + + BlockVector3 blockVector = useItemData.blockPos; + face = useItemData.face; + + int type = useItemData.actionType; + switch (type) { + case InventoryTransactionPacket.USE_ITEM_ACTION_CLICK_BLOCK: + this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION, false); + + if (this.canInteract(blockVector.add(0.5, 0.5, 0.5), this.isCreative() ? 13 : 7)) { + if (this.isCreative()) { + Item i = inventory.getItemInHand(); + if (this.level.useItemOn(blockVector.asVector3(), i, face, useItemData.clickPos.x, useItemData.clickPos.y, useItemData.clickPos.z, this) != null) { + break packetswitch; + } + } else if (inventory.getItemInHand().deepEquals(useItemData.itemInHand)) { + Item i = inventory.getItemInHand(); + Item oldItem = i.clone(); + //TODO: Implement adventure mode checks + if ((i = this.level.useItemOn(blockVector.asVector3(), i, face, useItemData.clickPos.x, useItemData.clickPos.y, useItemData.clickPos.z, this)) != null) { + if (!i.deepEquals(oldItem) || i.getCount() != oldItem.getCount()) { + inventory.setItemInHand(i); + inventory.sendHeldItem(this.getViewers().values()); + } + break packetswitch; + } + } + } + + inventory.sendHeldItem(this); + + if (blockVector.distanceSquared(this) > 10000) { + break packetswitch; + } + + Block target = this.level.getBlock(blockVector.asVector3()); + Block block = target.getSide(face); + + this.level.sendBlocks(new Player[]{this}, new Block[]{target, block}, UpdateBlockPacket.FLAG_ALL_PRIORITY); + + 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}, UpdateBlockPacket.FLAG_ALL_PRIORITY); + } + } + } + break packetswitch; + case InventoryTransactionPacket.USE_ITEM_ACTION_BREAK_BLOCK: + if (!this.spawned || !this.isAlive()) { + break packetswitch; + } + + this.resetCraftingGridType(); + + Item i = this.getInventory().getItemInHand(); + + Item oldItem = i.clone(); + + if (this.canInteract(blockVector.add(0.5, 0.5, 0.5), this.isCreative() ? 13 : 7) && (i = this.level.useBreakOn(blockVector.asVector3(), i, this, true)) != null) { + if (this.isSurvival()) { + this.getFoodData().updateFoodExpLevel(0.025); + if (!i.deepEquals(oldItem) || i.getCount() != oldItem.getCount()) { + inventory.setItemInHand(i); + inventory.sendHeldItem(this.getViewers().values()); + } + } + break packetswitch; + } + + inventory.sendContents(this); + target = this.level.getBlock(blockVector.asVector3()); + BlockEntity blockEntity = this.level.getBlockEntity(blockVector.asVector3()); + + this.level.sendBlocks(new Player[]{this}, new Block[]{target}, UpdateBlockPacket.FLAG_ALL_PRIORITY); + + inventory.sendHeldItem(this); + + if (blockEntity instanceof BlockEntitySpawnable) { + ((BlockEntitySpawnable) blockEntity).spawnTo(this); + } + + break packetswitch; + case InventoryTransactionPacket.USE_ITEM_ACTION_CLICK_AIR: + Vector3 directionVector = this.getDirectionVector(); + + if (this.isCreative()) { + item = this.inventory.getItemInHand(); + } else if (!this.inventory.getItemInHand().equals(useItemData.itemInHand)) { + this.inventory.sendHeldItem(this); + break packetswitch; + } else { + item = this.inventory.getItemInHand(); + } + + PlayerInteractEvent interactEvent = new PlayerInteractEvent(this, item, directionVector, face, Action.RIGHT_CLICK_AIR); + + this.server.getPluginManager().callEvent(interactEvent); + + if (interactEvent.isCancelled()) { + this.inventory.sendHeldItem(this); + break packetswitch; + } + + if (item.onClickAir(this, directionVector) && this.isSurvival()) { + this.inventory.setItemInHand(item); + } + + this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION, true); + this.startAction = this.server.getTick(); + + break packetswitch; + default: + //unknown + break; + } + break; + case InventoryTransactionPacket.TYPE_USE_ITEM_ON_ENTITY: + UseItemOnEntityData useItemOnEntityData = (UseItemOnEntityData) transactionPacket.transactionData; + + Entity target = this.level.getEntity(useItemOnEntityData.entityRuntimeId); + if (target == null) { + return; + } + + type = useItemOnEntityData.actionType; + + if (!useItemOnEntityData.itemInHand.equalsExact(this.inventory.getItemInHand())) { + this.inventory.sendHeldItem(this); + } + + item = this.inventory.getItemInHand(); + + switch (type) { + case InventoryTransactionPacket.USE_ITEM_ON_ENTITY_ACTION_INTERACT: + PlayerInteractEntityEvent playerInteractEntityEvent = new PlayerInteractEntityEvent(this, target, item); + getServer().getPluginManager().callEvent(playerInteractEntityEvent); + + if (playerInteractEntityEvent.isCancelled()) { + break; + } + + if (target.onInteract(this, item) && this.isSurvival()) { + if (item.isTool()) { + if (item.useOn(target) && item.getDamage() >= item.getMaxDurability()) { + item = new ItemBlock(new BlockAir()); + } + } else { + if (item.count > 1) { + item.count--; + } else { + item = new ItemBlock(new BlockAir()); + } + } + + this.inventory.setItemInHand(item); + } + break; + case InventoryTransactionPacket.USE_ITEM_ON_ENTITY_ACTION_ATTACK: + if (this.getGamemode() == Player.VIEW) { + break; + } + + float itemDamage = item.getAttackDamage(); + + for (Enchantment enchantment : item.getEnchantments()) { + itemDamage += enchantment.getDamageBonus(target); + } + + Map damage = new EnumMap<>(DamageModifier.class); + damage.put(DamageModifier.BASE, itemDamage); + + if (!this.canInteract(target, isCreative() ? 8 : 5)) { + break; + } else if (target instanceof Player) { + if ((((Player) target).getGamemode() & 0x01) > 0) { + break; + } else if (!this.server.getPropertyBoolean("pvp") || this.server.getDifficulty() == 0) { + break; + } + } + + if (!target.attack(new EntityDamageByEntityEvent(this, target, DamageCause.ENTITY_ATTACK, damage))) { + if (item.isTool() && this.isSurvival()) { + this.inventory.sendContents(this); + } + break; + } + + for (Enchantment enchantment : item.getEnchantments()) { + enchantment.doPostAttack(this, target); + } + + if (item.isTool() && this.isSurvival()) { + if (item.useOn(target) && item.getDamage() >= item.getMaxDurability()) { + this.inventory.setItemInHand(new ItemBlock(new BlockAir())); + } else { + this.inventory.setItemInHand(item); + } + } + return; + default: + break; //unknown + } + + break; + case InventoryTransactionPacket.TYPE_RELEASE_ITEM: + ReleaseItemData releaseItemData = (ReleaseItemData) transactionPacket.transactionData; + + type = releaseItemData.actionType; + switch (type) { + case InventoryTransactionPacket.RELEASE_ITEM_ACTION_RELEASE: + if (this.isUsingItem()) { + item = this.inventory.getItemInHand(); + if (item.onReleaseUsing(this)) { + this.inventory.setItemInHand(item); + } + } else { + this.inventory.sendContents(this); + } + + this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION, false); + return; + case InventoryTransactionPacket.RELEASE_ITEM_ACTION_CONSUME: + this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION, false); + Item itemInHand = this.inventory.getItemInHand(); + PlayerItemConsumeEvent consumeEvent = new PlayerItemConsumeEvent(this, itemInHand); + this.server.getPluginManager().callEvent(consumeEvent); + if (consumeEvent.isCancelled()) { + this.inventory.sendContents(this); + break; + } + + if (itemInHand.getId() == Item.POTION) { + Potion potion = Potion.getPotion(itemInHand.getDamage()).setSplash(false); + + if (this.getGamemode() == SURVIVAL) { + if (itemInHand.getCount() > 1) { + ItemGlassBottle bottle = new ItemGlassBottle(); + if (this.inventory.canAddItem(bottle)) { + this.inventory.addItem(bottle); + } + --itemInHand.count; + } else { + itemInHand = new ItemGlassBottle(); + } + } + + if (potion != null) { + potion.applyPotion(this); + } + + } else { + EntityEventPacket eventPacket = new EntityEventPacket(); + eventPacket.eid = this.getId(); + eventPacket.event = EntityEventPacket.USE_ITEM; + this.dataPacket(eventPacket); + Server.broadcastPacket(this.getViewers().values(), eventPacket); + + Food food = Food.getByRelative(itemInHand); + if (food != null) if (food.eatenBy(this)) --itemInHand.count; + } + + this.inventory.setItemInHand(itemInHand); + this.inventory.sendHeldItem(this); + + return; + default: + break; + } + break; + default: + this.inventory.sendContents(this); + break; + } 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]); + PlayerHotbarPacket hotbarPacket = (PlayerHotbarPacket) packet; + + if (hotbarPacket.windowId != ContainerIds.INVENTORY) { + return; //In PE this should never happen } - this.inventory.setHeldItemSlot(playerHotbarPacket.selectedSlot); + + for (int hotbarSlot = 0; hotbarSlot < hotbarPacket.slots.length; hotbarSlot++) { + int slotLink = hotbarPacket.slots[hotbarSlot]; + + this.inventory.setHotbarSlotIndex(hotbarSlot, slotLink == -1 ? slotLink : slotLink - 9); + } + + this.inventory.equipItem(hotbarPacket.selectedHotbarSlot); break; default: break; @@ -3604,9 +3765,7 @@ public void close(TextContainer message, String reason, boolean notify) { this.hiddenPlayers = new HashMap<>(); - for (Inventory window : new ArrayList<>(this.windowIndex.values())) { - this.removeWindow(window); - } + this.removeAllWindows(true); for (long index : new ArrayList<>(this.usedChunks.keySet())) { int chunkX = Level.getHashX(index); @@ -3657,7 +3816,6 @@ public void close(TextContainer message, String reason, boolean notify) { if (this.inventory != null) { this.inventory = null; - this.currentTransaction = null; } this.chunk = null; @@ -4047,6 +4205,35 @@ public boolean attack(EntityDamageEvent source) { } } + /** + * Drops an item on the ground in front of the player. Returns if the item drop was successful. + * + * @return bool if the item was dropped or if the item was null + */ + public boolean dropItem(Item item) { + if (!this.spawned || this.isAlive()) { + return false; + } + + if (item.isNull()) { + this.server.getLogger().debug(this.getName() + " attempted to drop a null item (" + item + ")"); + return true; + } + + PlayerDropItemEvent ev; + this.server.getPluginManager().callEvent(ev = new PlayerDropItemEvent(this, item)); + if (ev.isCancelled()) { + return false; + } + + 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); + return true; + } + public void sendPosition(Vector3 pos) { this.sendPosition(pos, this.yaw); } @@ -4183,13 +4370,7 @@ public boolean teleport(Location location, TeleportCause cause) { } if (super.teleport(to, null)) { // null to prevent fire of duplicate EntityTeleportEvent - - for (Inventory window : new ArrayList<>(this.windowIndex.values())) { - if (window == this.inventory) { - continue; - } - this.removeWindow(window); - } + this.removeAllWindows(); this.teleportPosition = new Vector3(this.x, this.y, this.z); this.forceMovement = this.teleportPosition; @@ -4430,6 +4611,10 @@ public int addWindow(Inventory inventory) { } public int addWindow(Inventory inventory, Integer forceId) { + return addWindow(inventory, forceId, false); + } + + public int addWindow(Inventory inventory, Integer forceId, boolean isPermanent) { if (this.windows.containsKey(inventory)) { return this.windows.get(inventory); } @@ -4441,6 +4626,11 @@ public int addWindow(Inventory inventory, Integer forceId) { } this.windowIndex.put(cnt, inventory); this.windows.put(inventory, cnt); + + if (isPermanent) { + this.permanentWindows.add(cnt); + } + if (inventory.open(this)) { return cnt; } else { @@ -4459,6 +4649,66 @@ public void removeWindow(Inventory inventory) { } } + public void sendAllInventories() { + for (Inventory inv : this.windowIndex.values()) { + inv.sendContents(this); + + if (inv instanceof PlayerInventory) { + ((PlayerInventory) inv).sendArmorContents(this); + ((PlayerInventory) inv).sendHotbarContents(); + } + } + } + + protected void addDefaultWindows() { + this.addWindow(this.getInventory(), ContainerIds.INVENTORY, true); + + this.cursorInventory = new PlayerCursorInventory(this); + this.addWindow(this.cursorInventory, ContainerIds.CURSOR, true); + + this.craftingGrid = new CraftingGrid(this); + + //TODO: more windows + } + + public PlayerCursorInventory getCursorInventory() { + return this.cursorInventory; + } + + public CraftingGrid getCraftingGrid() { + return this.craftingGrid; + } + + public void setCraftingGrid(CraftingGrid grid) { + this.craftingGrid = grid; + } + + public void resetCraftingGridType() { + if (this.craftingGrid instanceof BigCraftingGrid) { + Item[] drops = this.inventory.addItem(this.craftingGrid.getContents().values().stream().toArray(Item[]::new)); + for (Item drop : drops) { + this.dropItem(drop); + } + + this.craftingGrid = new CraftingGrid(this); + this.craftingType = 0; + } + } + + public void removeAllWindows() { + removeAllWindows(false); + } + + public void removeAllWindows(boolean permanent) { + for (Entry entry : new ArrayList<>(this.windowIndex.entrySet())) { + if (!permanent && this.permanentWindows.contains(entry.getKey())) { + continue; + } + + this.removeWindow(entry.getValue()); + } + } + @Override public void setMetadata(String metadataKey, MetadataValue newMetadataValue) { this.server.getPlayerMetadata().setMetadata(this, metadataKey, newMetadataValue); diff --git a/src/main/java/cn/nukkit/block/Block.java b/src/main/java/cn/nukkit/block/Block.java index 06cdf2b431..db0a0427bd 100644 --- a/src/main/java/cn/nukkit/block/Block.java +++ b/src/main/java/cn/nukkit/block/Block.java @@ -410,7 +410,7 @@ public static void init() { list[REDSTONE_WIRE] = BlockRedstoneWire.class; //55 list[DIAMOND_ORE] = BlockOreDiamond.class; //56 list[DIAMOND_BLOCK] = BlockDiamond.class; //57 - list[WORKBENCH] = BlockWorkbench.class; //58 + list[WORKBENCH] = BlockCraftingTable.class; //58 list[WHEAT_BLOCK] = BlockWheat.class; //59 list[FARMLAND] = BlockFarmland.class; //60 list[FURNACE] = BlockFurnace.class; //61 diff --git a/src/main/java/cn/nukkit/block/BlockWorkbench.java b/src/main/java/cn/nukkit/block/BlockCraftingTable.java similarity index 81% rename from src/main/java/cn/nukkit/block/BlockWorkbench.java rename to src/main/java/cn/nukkit/block/BlockCraftingTable.java index b5129f79f4..c94c41ca39 100644 --- a/src/main/java/cn/nukkit/block/BlockWorkbench.java +++ b/src/main/java/cn/nukkit/block/BlockCraftingTable.java @@ -1,6 +1,7 @@ package cn.nukkit.block; import cn.nukkit.Player; +import cn.nukkit.inventory.BigCraftingGrid; import cn.nukkit.item.Item; import cn.nukkit.item.ItemTool; import cn.nukkit.utils.BlockColor; @@ -9,12 +10,12 @@ * Created on 2015/12/5 by xtypr. * Package cn.nukkit.block in project Nukkit . */ -public class BlockWorkbench extends BlockSolid { - public BlockWorkbench() { +public class BlockCraftingTable extends BlockSolid { + public BlockCraftingTable() { this(0); } - public BlockWorkbench(int meta) { + public BlockCraftingTable(int meta) { super(meta); } @@ -51,6 +52,7 @@ public int getToolType() { @Override public boolean onActivate(Item item, Player player) { if (player != null) { + player.setCraftingGrid(new BigCraftingGrid(player)); player.craftingType = Player.CRAFTING_BIG; } return true; diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java b/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java index c4f2df249a..09ead3e371 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java @@ -116,7 +116,7 @@ public void setItem(int index, Item item) { // If it is less than i, then it is a new item, so we are going to add it at the end of the list (this.namedTag.getList("Items", CompoundTag.class)).add(d); } else { - // If it is more than i, then it is an update on a slot, so we are going to overwrite the item in the list + // If it is more than i, then it is an update on a inventorySlot, so we are going to overwrite the item in the list (this.namedTag.getList("Items", CompoundTag.class)).add(i, d); } } diff --git a/src/main/java/cn/nukkit/command/defaults/SetWorldSpawnCommand.java b/src/main/java/cn/nukkit/command/defaults/SetWorldSpawnCommand.java index ade4f51260..879e38371d 100644 --- a/src/main/java/cn/nukkit/command/defaults/SetWorldSpawnCommand.java +++ b/src/main/java/cn/nukkit/command/defaults/SetWorldSpawnCommand.java @@ -20,7 +20,7 @@ public SetWorldSpawnCommand(String name) { this.setPermission("nukkit.command.setworldspawn"); this.commandParameters.clear(); this.commandParameters.put("default", new CommandParameter[]{ - new CommandParameter("pos", CommandParameter.ARG_TYPE_BLOCK_POS, true) + new CommandParameter("blockPos", CommandParameter.ARG_TYPE_BLOCK_POS, true) }); } diff --git a/src/main/java/cn/nukkit/command/defaults/SpawnpointCommand.java b/src/main/java/cn/nukkit/command/defaults/SpawnpointCommand.java index 04fdaaab6c..ca97b11d6c 100644 --- a/src/main/java/cn/nukkit/command/defaults/SpawnpointCommand.java +++ b/src/main/java/cn/nukkit/command/defaults/SpawnpointCommand.java @@ -21,7 +21,7 @@ public SpawnpointCommand(String name) { this.setPermission("nukkit.command.spawnpoint"); this.commandParameters.clear(); this.commandParameters.put("default", new CommandParameter[]{ - new CommandParameter("pos", CommandParameter.ARG_TYPE_BLOCK_POS, true), + new CommandParameter("blockPos", CommandParameter.ARG_TYPE_BLOCK_POS, true), }); } diff --git a/src/main/java/cn/nukkit/command/defaults/TeleportCommand.java b/src/main/java/cn/nukkit/command/defaults/TeleportCommand.java index 4bbcb30d84..5fba764991 100644 --- a/src/main/java/cn/nukkit/command/defaults/TeleportCommand.java +++ b/src/main/java/cn/nukkit/command/defaults/TeleportCommand.java @@ -28,10 +28,10 @@ public TeleportCommand(String name) { }); this.commandParameters.put("Player->Pos", new CommandParameter[]{ new CommandParameter("player", CommandParameter.ARG_TYPE_TARGET, false), - new CommandParameter("pos", CommandParameter.ARG_TYPE_BLOCK_POS, false), + new CommandParameter("blockPos", CommandParameter.ARG_TYPE_BLOCK_POS, false), }); this.commandParameters.put("->Pos", new CommandParameter[]{ - new CommandParameter("pos", CommandParameter.ARG_TYPE_BLOCK_POS, false), + new CommandParameter("blockPos", CommandParameter.ARG_TYPE_BLOCK_POS, false), }); } diff --git a/src/main/java/cn/nukkit/entity/EntityHuman.java b/src/main/java/cn/nukkit/entity/EntityHuman.java index 8dd9921a38..372caf882b 100644 --- a/src/main/java/cn/nukkit/entity/EntityHuman.java +++ b/src/main/java/cn/nukkit/entity/EntityHuman.java @@ -104,10 +104,6 @@ protected void initEntity() { } super.initEntity(); - - if (this instanceof Player) { - ((Player) this).addWindow(this.inventory, 0); - } } @Override diff --git a/src/main/java/cn/nukkit/event/inventory/InventoryTransactionEvent.java b/src/main/java/cn/nukkit/event/inventory/InventoryTransactionEvent.java index 836fc3196b..c416b726e6 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.transaction.TransactionGroup; +import cn.nukkit.inventory.transaction.InventoryTransaction; /** * author: MagicDroidX @@ -17,14 +17,13 @@ public static HandlerList getHandlers() { return handlers; } - private final TransactionGroup transaction; + private final InventoryTransaction transaction; - public InventoryTransactionEvent(TransactionGroup transaction) { + public InventoryTransactionEvent(InventoryTransaction transaction) { this.transaction = transaction; } - public TransactionGroup getTransaction() { + public InventoryTransaction getTransaction() { return transaction; } - } \ No newline at end of file diff --git a/src/main/java/cn/nukkit/inventory/AnvilInventory.java b/src/main/java/cn/nukkit/inventory/AnvilInventory.java index 05340c1303..a51e3affa4 100644 --- a/src/main/java/cn/nukkit/inventory/AnvilInventory.java +++ b/src/main/java/cn/nukkit/inventory/AnvilInventory.java @@ -130,6 +130,7 @@ public boolean onRename(Player player, Item resultItem) { public void onClose(Player who) { super.onClose(who); who.craftingType = Player.CRAFTING_SMALL; + who.resetCraftingGridType(); for (int i = 0; i < 2; ++i) { this.getHolder().getLevel().dropItem(this.getHolder().add(0.5, 0.5, 0.5), this.getItem(i)); diff --git a/src/main/java/cn/nukkit/inventory/BaseInventory.java b/src/main/java/cn/nukkit/inventory/BaseInventory.java index be8951619a..dbbf73ac10 100644 --- a/src/main/java/cn/nukkit/inventory/BaseInventory.java +++ b/src/main/java/cn/nukkit/inventory/BaseInventory.java @@ -139,7 +139,7 @@ public void setContents(Map items) { } @Override - public boolean setItem(int index, Item item) { + public boolean setItem(int index, Item item, boolean send) { item = item.clone(); if (index < 0 || index >= this.size) { return false; @@ -161,7 +161,7 @@ public boolean setItem(int index, Item item) { Item old = this.getItem(index); this.slots.put(index, item.clone()); - this.onSlotChange(index, old); + this.onSlotChange(index, old, send); return true; } @@ -209,12 +209,12 @@ public void remove(Item item) { } @Override - public int first(Item item) { + public int first(Item item, boolean exact) { int count = Math.max(1, item.getCount()); boolean checkDamage = item.hasMeta(); boolean checkTag = item.getCompoundTag() != null; for (Map.Entry entry : this.getContents().entrySet()) { - if (item.equals(entry.getValue(), checkDamage, checkTag) && entry.getValue().getCount() >= count) { + if (item.equals(entry.getValue(), checkDamage, checkTag) && (entry.getValue().getCount() == count || (!exact && entry.getValue().getCount() > count))) { return entry.getKey(); } } @@ -350,7 +350,7 @@ public Item[] removeItem(Item... slots) { } @Override - public boolean clear(int index) { + public boolean clear(int index, boolean send) { if (this.slots.containsKey(index)) { Item item = new ItemBlock(new BlockAir(), null, 0); Item old = this.slots.get(index); @@ -371,7 +371,7 @@ public boolean clear(int index) { this.slots.remove(index); } - this.onSlotChange(index, old); + this.onSlotChange(index, old, send); } return true; @@ -427,8 +427,10 @@ public void onClose(Player who) { } @Override - public void onSlotChange(int index, Item before) { - this.sendSlot(index, this.getViewers()); + public void onSlotChange(int index, Item before, boolean send) { + if (send) { + this.sendSlot(index, this.getViewers()); + } } @Override @@ -437,7 +439,7 @@ public void sendContents(Player player) { } @Override - public void sendContents(Player[] players) { + public void sendContents(Player... players) { InventoryContentPacket pk = new InventoryContentPacket(); pk.slots = new Item[this.getSize()]; for (int i = 0; i < this.getSize(); ++i) { @@ -514,7 +516,7 @@ public void sendSlot(int index, Player player) { } @Override - public void sendSlot(int index, Player[] players) { + public void sendSlot(int index, Player... players) { InventorySlotPacket pk = new InventorySlotPacket(); pk.slot = index; pk.item = this.getItem(index).clone(); diff --git a/src/main/java/cn/nukkit/inventory/BigCraftingGrid.java b/src/main/java/cn/nukkit/inventory/BigCraftingGrid.java new file mode 100644 index 0000000000..adb8f7175d --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/BigCraftingGrid.java @@ -0,0 +1,16 @@ +package cn.nukkit.inventory; + +/** + * @author CreeperFace + */ +public class BigCraftingGrid extends CraftingGrid { + + public BigCraftingGrid(InventoryHolder holder) { + super(holder); + } + + @Override + public int getSize() { + return 9; + } +} diff --git a/src/main/java/cn/nukkit/inventory/BrewingInventory.java b/src/main/java/cn/nukkit/inventory/BrewingInventory.java index e488581656..baa960d852 100644 --- a/src/main/java/cn/nukkit/inventory/BrewingInventory.java +++ b/src/main/java/cn/nukkit/inventory/BrewingInventory.java @@ -23,8 +23,8 @@ public void setIngredient(Item item) { } @Override - public void onSlotChange(int index, Item before) { - super.onSlotChange(index, before); + public void onSlotChange(int index, Item before, boolean send) { + super.onSlotChange(index, before, send); this.getHolder().scheduleUpdate(); } diff --git a/src/main/java/cn/nukkit/inventory/CraftingGrid.java b/src/main/java/cn/nukkit/inventory/CraftingGrid.java new file mode 100644 index 0000000000..651225745a --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/CraftingGrid.java @@ -0,0 +1,34 @@ +package cn.nukkit.inventory; + +import cn.nukkit.Player; + +/** + * author: MagicDroidX + * Nukkit Project + */ +public class CraftingGrid extends BaseInventory { + + public CraftingGrid(InventoryHolder holder) { + super(holder, InventoryType.CRAFTING); + } + + public int getDefaultSize() { + return 4; + } + + public void setSize(int size) { + throw new RuntimeException("Cannot change the size of a crafting grid"); + } + + public String getName() { + return "Crafting"; + } + + public void sendSlot(int index, Player... target) { + //we can't send a inventorySlot of a client-sided inventory window + } + + public void sendContents(Player... target) { + //we can't send the contents of a client-sided inventory window + } +} diff --git a/src/main/java/cn/nukkit/inventory/CraftingInventory.java b/src/main/java/cn/nukkit/inventory/CraftingInventory.java deleted file mode 100644 index 005903c6a3..0000000000 --- a/src/main/java/cn/nukkit/inventory/CraftingInventory.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.nukkit.inventory; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public class CraftingInventory extends BaseInventory { - - private Inventory resultInventory; - - public CraftingInventory(InventoryHolder holder, Inventory resultInventory, InventoryType type) { - super(holder, type); - if (!type.getDefaultTitle().equals("Crafting")) { - throw new IllegalStateException("Invalid Inventory type, expected CRAFTING or WORKBENCH"); - } - this.resultInventory = resultInventory; - } - - public Inventory getResultInventory() { - return resultInventory; - } - - @Override - public int getSize() { - return this.getResultInventory().getSize() + super.getSize(); - } -} diff --git a/src/main/java/cn/nukkit/inventory/EnchantInventory.java b/src/main/java/cn/nukkit/inventory/EnchantInventory.java index 38476755dc..9ec1103c28 100644 --- a/src/main/java/cn/nukkit/inventory/EnchantInventory.java +++ b/src/main/java/cn/nukkit/inventory/EnchantInventory.java @@ -67,8 +67,8 @@ public void onOpen(Player who) { } @Override - public void onSlotChange(int index, Item before) { - super.onSlotChange(index, before); + public void onSlotChange(int index, Item before, boolean send) { + super.onSlotChange(index, before, send); if (index == 0) { Item item = this.getItem(0); diff --git a/src/main/java/cn/nukkit/inventory/FurnaceInventory.java b/src/main/java/cn/nukkit/inventory/FurnaceInventory.java index ad45f761a0..34cef28646 100644 --- a/src/main/java/cn/nukkit/inventory/FurnaceInventory.java +++ b/src/main/java/cn/nukkit/inventory/FurnaceInventory.java @@ -43,8 +43,8 @@ public boolean setSmelting(Item item) { } @Override - public void onSlotChange(int index, Item before) { - super.onSlotChange(index, before); + public void onSlotChange(int index, Item before, boolean send) { + super.onSlotChange(index, before, send); this.getHolder().scheduleUpdate(); } diff --git a/src/main/java/cn/nukkit/inventory/Inventory.java b/src/main/java/cn/nukkit/inventory/Inventory.java index 8074ffc57a..ba7e4cdf6e 100644 --- a/src/main/java/cn/nukkit/inventory/Inventory.java +++ b/src/main/java/cn/nukkit/inventory/Inventory.java @@ -27,7 +27,11 @@ public interface Inventory { Item getItem(int index); - boolean setItem(int index, Item item); + default boolean setItem(int index, Item item) { + return setItem(index, item, true); + } + + boolean setItem(int index, Item item, boolean send); Item[] addItem(Item... slots); @@ -41,13 +45,13 @@ public interface Inventory { void sendContents(Player player); - void sendContents(Player[] players); + void sendContents(Player... players); void sendContents(Collection players); void sendSlot(int index, Player player); - void sendSlot(int index, Player[] players); + void sendSlot(int index, Player... players); void sendSlot(int index, Collection players); @@ -55,13 +59,21 @@ public interface Inventory { Map all(Item item); - int first(Item item); + default int first(Item item) { + return first(item, false); + } + + int first(Item item, boolean exact); int firstEmpty(Item item); void remove(Item item); - boolean clear(int index); + default boolean clear(int index) { + return clear(index, true); + } + + boolean clear(int index, boolean send); void clearAll(); @@ -83,5 +95,5 @@ public interface Inventory { void onClose(Player who); - void onSlotChange(int index, Item before); + void onSlotChange(int index, Item before, boolean send); } diff --git a/src/main/java/cn/nukkit/inventory/InventoryType.java b/src/main/java/cn/nukkit/inventory/InventoryType.java index bac09d0e96..949440e708 100644 --- a/src/main/java/cn/nukkit/inventory/InventoryType.java +++ b/src/main/java/cn/nukkit/inventory/InventoryType.java @@ -8,7 +8,7 @@ public enum InventoryType { CHEST(27, "Chest", 0), ENDER_CHEST(27, "Ender Chest", 0), DOUBLE_CHEST(27 + 27, "Double Chest", 0), - PLAYER(40, "Player", 0), //36 CONTAINER, 4 ARMOR + PLAYER(40, "Player", -1), //36 CONTAINER, 4 ARMOR FURNACE(3, "Furnace", 2), CRAFTING(5, "Crafting", 1), //4 CRAFTING slots, 1 RESULT WORKBENCH(10, "Crafting", 1), //9 CRAFTING slots, 1 RESULT @@ -17,7 +17,8 @@ public enum InventoryType { ENCHANT_TABLE(2, "Enchant", 3), //1 INPUT/OUTPUT, 1 LAPIS DISPENSER(0, "Dispenser", 6), //9 CONTAINER DROPPER(9, "Dropper", 7), //9 CONTAINER - HOPPER(5, "Hopper", 8); //5 CONTAINER + HOPPER(5, "Hopper", 8), //5 CONTAINER + CURSOR(1, "Cursor", -1); private final int size; private final String title; diff --git a/src/main/java/cn/nukkit/inventory/PlayerCursorInventory.java b/src/main/java/cn/nukkit/inventory/PlayerCursorInventory.java new file mode 100644 index 0000000000..5d94813115 --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/PlayerCursorInventory.java @@ -0,0 +1,58 @@ +package cn.nukkit.inventory; + +import cn.nukkit.Player; +import cn.nukkit.network.protocol.InventorySlotPacket; +import cn.nukkit.network.protocol.types.ContainerIds; + +/** + * @author CreeperFace + */ +public class PlayerCursorInventory extends BaseInventory { + + public PlayerCursorInventory(Player holder) { + super(holder, InventoryType.CURSOR); + } + + public String getName() { + return "Cursor"; + } + + public int getSize() { + return 1; + } + + public void setSize(int size) { + throw new RuntimeException("Cursor can only carry one item at a time"); + } + + public void sendSlot(int index, Player... target) { + InventorySlotPacket pk = new InventorySlotPacket(); + pk.slot = index; + pk.item = this.getItem(index); + + for (Player p : target) { + if (p == this.getHolder()) { + pk.inventoryId = ContainerIds.CURSOR; + p.dataPacket(pk); + } else { + int id; + + if ((id = p.getWindowId(this)) == ContainerIds.NONE) { + this.close(p); + continue; + } + pk.inventoryId = id; + p.dataPacket(pk); + } + } + } + + /** + * This override is here for documentation and code completion purposes only. + * + * @return Player + */ + public Player getHolder() { + return (Player) this.holder; + } +} diff --git a/src/main/java/cn/nukkit/inventory/PlayerInventory.java b/src/main/java/cn/nukkit/inventory/PlayerInventory.java index c7ad5bc9d5..cfb0802a61 100644 --- a/src/main/java/cn/nukkit/inventory/PlayerInventory.java +++ b/src/main/java/cn/nukkit/inventory/PlayerInventory.java @@ -11,6 +11,7 @@ import cn.nukkit.item.Item; import cn.nukkit.item.ItemBlock; import cn.nukkit.network.protocol.*; +import cn.nukkit.network.protocol.types.ContainerIds; import java.util.Collection; @@ -43,6 +44,52 @@ public void setSize(int size) { this.sendContents(this.getViewers()); } + public boolean equipItem(int hotbarSlot) { + return equipItem(hotbarSlot, null); + } + + /** + * Called when a client equips a hotbar inventorySlot. This method should not be used by plugins. + * This method will call PlayerItemHeldEvent. + * + * @param hotbarSlot Number of the hotbar inventorySlot to equip. + * @param inventorySlot Inventory inventorySlot to map to the specified hotbar inventorySlot. Supply null to make no change to the link. + * @return bool if the equipment change was successful, false if not. + */ + public boolean equipItem(int hotbarSlot, Integer inventorySlot) { + if (inventorySlot == null) { + inventorySlot = this.getHotbarSlotIndex(hotbarSlot); + } + + if (hotbarSlot < 0 || hotbarSlot >= this.getHotbarSize() || inventorySlot < -1 || inventorySlot >= this.getSize()) { + this.sendContents(this.getViewers()); + return false; + } + + Item item; + + if (inventorySlot == -1) { + item = Item.get(Item.AIR, 0, 0); + } else { + item = this.getItem(inventorySlot); + } + + if (this.getHolder() instanceof Player) { + PlayerItemHeldEvent ev = new PlayerItemHeldEvent((Player) this.getHolder(), item, inventorySlot, hotbarSlot); + this.getHolder().getLevel().getServer().getPluginManager().callEvent(ev); + + if (ev.isCancelled()) { + this.sendContents(this.getViewers()); + return false; + } + } + + this.setHotbarSlotIndex(hotbarSlot, inventorySlot); + this.setHeldItemIndex(hotbarSlot, false); + + return true; + } + public int getHotbarSlotIndex(int index) { return (index >= 0 && index < this.getHotbarSize()) ? this.hotbar[index] : -1; } @@ -58,9 +105,17 @@ public int getHeldItemIndex() { } public void setHeldItemIndex(int index) { + setHeldItemIndex(index, true); + } + + public void setHeldItemIndex(int index, boolean send) { if (index >= 0 && index < this.getHotbarSize()) { this.itemInHandIndex = index; + if (this.getHolder() instanceof Player && send) { + this.sendHeldItem((Player) this.getHolder()); + } + this.sendHeldItem(this.getHolder().getViewers().values()); } } @@ -107,8 +162,8 @@ public void sendHeldItem(Player player) { MobEquipmentPacket pk = new MobEquipmentPacket(); pk.eid = this.getHolder().getId(); pk.item = item; - pk.slot = (byte) this.getHeldItemSlot(); - pk.selectedSlot = (byte) this.getHeldItemIndex(); + pk.inventorySlot = (byte) this.getHeldItemSlot(); + pk.hotbarSlot = (byte) this.getHeldItemIndex(); player.dataPacket(pk); if (player.equals(this.getHolder())) { @@ -121,8 +176,8 @@ public void sendHeldItem(Player[] players) { MobEquipmentPacket pk = new MobEquipmentPacket(); pk.item = item; - pk.slot = (byte) this.getHeldItemSlot(); - pk.selectedSlot = (byte) this.getHeldItemIndex(); + pk.inventorySlot = (byte) this.getHeldItemSlot(); + pk.hotbarSlot = (byte) this.getHeldItemIndex(); for (Player player : players) { pk.eid = this.getHolder().getId(); @@ -140,13 +195,13 @@ public void sendHeldItem(Collection players) { } @Override - public void onSlotChange(int index, Item before) { + public void onSlotChange(int index, Item before, boolean send) { EntityHuman holder = this.getHolder(); if (holder instanceof Player && !((Player) holder).spawned) { return; } - super.onSlotChange(index, before); + super.onSlotChange(index, before, send); if (index >= this.getSize()) { this.sendArmorSlot(index, this.getViewers()); @@ -204,10 +259,10 @@ public boolean setBoots(Item boots) { @Override public boolean setItem(int index, Item item) { - return setItem(index, item, false); + return setItem(index, item, false, true); } - private boolean setItem(int index, Item item, boolean ignoreArmorEvents) { + private boolean setItem(int index, Item item, boolean send, boolean ignoreArmorEvents) { if (index < 0 || index >= this.size) { return false; } else if (item.getId() == 0 || item.getCount() <= 0) { @@ -235,13 +290,13 @@ private boolean setItem(int index, Item item, boolean ignoreArmorEvents) { Item old = this.getItem(index); this.slots.put(index, item.clone()); - this.onSlotChange(index, old); + this.onSlotChange(index, old, send); return true; } @Override - public boolean clear(int index) { + public boolean clear(int index, boolean send) { if (this.slots.containsKey(index)) { Item item = new ItemBlock(new BlockAir(), null, 0); Item old = this.slots.get(index); @@ -277,7 +332,7 @@ public boolean clear(int index) { this.slots.remove(index); } - this.onSlotChange(index, old); + this.onSlotChange(index, old, send); } return true; @@ -419,13 +474,19 @@ public void sendContents(Player[] players) { 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; + PlayerHotbarPacket pk = new PlayerHotbarPacket(); + pk.windowId = ContainerIds.INVENTORY; + pk.selectedHotbarSlot = this.getHeldItemIndex(); + pk.slots = new int[this.getHotbarSize()]; + + System.arraycopy(this.hotbar, 0, pk.slots, 0, pk.slots.length); + + for (int i = 0; i < pk.slots.length; i++) { + pk.slots[i] = pk.slots[i] + 9; } - ((Player) holder).dataPacket(playerHotbarPacket); + + ((Player) holder).dataPacket(pk); + } } @@ -440,7 +501,7 @@ public void sendSlot(int index, Collection players) { } @Override - public void sendSlot(int index, Player[] players) { + public void sendSlot(int index, Player... players) { InventorySlotPacket pk = new InventorySlotPacket(); pk.slot = index; pk.item = this.getItem(index).clone(); @@ -461,6 +522,22 @@ public void sendSlot(int index, Player[] players) { } } + public void sendCreativeContents() { + if (!(this.getHolder() instanceof Player)) { + return; + } + Player p = (Player) this.getHolder(); + + InventoryContentPacket pk = new InventoryContentPacket(); + pk.inventoryId = ContainerIds.CREATIVE; + + if (!p.isSpectator()) { //fill it for all gamemodes except spectator + pk.slots = Item.getCreativeItems().stream().toArray(Item[]::new); + } + + p.dataPacket(pk); + } + @Override public EntityHuman getHolder() { return (EntityHuman) super.getHolder(); diff --git a/src/main/java/cn/nukkit/inventory/transaction/BaseTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/BaseTransaction.java deleted file mode 100644 index 181f94e209..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/BaseTransaction.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.nukkit.inventory.transaction; - -import cn.nukkit.item.Item; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public abstract class BaseTransaction implements Transaction { - - protected final int slot; - - protected final Item sourceItem; - - protected final Item targetItem; - - protected final long creationTime = System.currentTimeMillis(); - - BaseTransaction(int slot, Item sourceItem, Item targetItem) { - this.slot = slot; - this.sourceItem = sourceItem.clone(); - this.targetItem = targetItem.clone(); - } - - @Override - public long getCreationTime() { - return creationTime; - } - - @Override - public int getSlot() { - return slot; - } - - @Override - public Item getSourceItem() { - return sourceItem.clone(); - } - - @Override - public Item getTargetItem() { - return targetItem.clone(); - } -} diff --git a/src/main/java/cn/nukkit/inventory/transaction/BaseTransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/BaseTransactionGroup.java deleted file mode 100644 index 763c83c804..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/BaseTransactionGroup.java +++ /dev/null @@ -1,47 +0,0 @@ -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 deleted file mode 100644 index c869918f3d..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/ContainerTransaction.java +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index 6c88bd4bf3..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/CraftTransaction.java +++ /dev/null @@ -1,22 +0,0 @@ -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 deleted file mode 100644 index 63d2ab97bb..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/CreativeTransaction.java +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index 7df1f6912d..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/GlobalTransaction.java +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index b0c687b574..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/InventoryMismatchTransactionGroup.java +++ /dev/null @@ -1,21 +0,0 @@ -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/InventoryTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/InventoryTransaction.java new file mode 100644 index 0000000000..4496afc5b3 --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/transaction/InventoryTransaction.java @@ -0,0 +1,26 @@ +package cn.nukkit.inventory.transaction; + +import cn.nukkit.inventory.Inventory; +import cn.nukkit.inventory.transaction.action.InventoryAction; + +import java.util.Set; + +/** + * @author CreeperFace + */ +public interface InventoryTransaction { + + long getCreationTime(); + + Set getActions(); + + Set getInventories(); + + void addAction(InventoryAction action); + + boolean canExecute(); + + boolean execute(); + + boolean hasExecuted(); +} diff --git a/src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java deleted file mode 100644 index 2adcf1ddaf..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/ItemReleaseTransactionGroup.java +++ /dev/null @@ -1,193 +0,0 @@ -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_CONSUME: - 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 deleted file mode 100644 index f5ac454492..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/ItemUseOnEntityTransactionGroup.java +++ /dev/null @@ -1,57 +0,0 @@ -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 deleted file mode 100644 index 63a2cd79db..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/ItemUseTransactionGroup.java +++ /dev/null @@ -1,391 +0,0 @@ -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.event.player.PlayerInteractEvent.Action; -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; - - System.out.println("action: " + action); - } - - @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_CLICK_AIR: - face = BlockFace.fromIndex(this.face); - Item item; - - if (player.isCreative()) { - item = player.getInventory().getItemInHand(); - } else if (!player.getInventory().getItemInHand().equals(this.item)) { - player.getInventory().sendHeldItem(player); - return true; - } else { - item = player.getInventory().getItemInHand(); - } - PlayerInteractEvent ev = new PlayerInteractEvent(player, item, player.getDirectionVector(), face, Action.RIGHT_CLICK_AIR); - player.getServer().getPluginManager().callEvent(ev); - if (ev.isCancelled()) { - player.getInventory().sendHeldItem(player); - return true; - } - - //TODO: handle air click - player.setDataFlag(Entity.DATA_FLAGS, Entity.DATA_FLAG_ACTION, true); - player.startAction(); - return false; - case ITEM_USE_CLICK_BLOCK: - 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(this.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); - - player.level.sendBlocks(new Player[]{player}, new Block[]{target, block}, UpdateBlockPacket.FLAG_ALL_PRIORITY); - - 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}, 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(this.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_BREAK_BLOCK: - 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/transaction/NormalTransactionGroup.java b/src/main/java/cn/nukkit/inventory/transaction/NormalTransactionGroup.java deleted file mode 100644 index 9b8a0e6a27..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/NormalTransactionGroup.java +++ /dev/null @@ -1,120 +0,0 @@ -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; - -public class NormalTransactionGroup extends BaseTransactionGroup { - - @Override - public void addTransaction(Transaction transaction) { - if (this.transactions.contains(transaction)) { - return; - } - - for (Transaction tx : new HashSet<>(this.transactions)) { - 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 { - return; - } - } - } - - this.transactions.add(transaction); - } - - 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 sourceItem = ts.getSourceItem(); - 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); - } - } - - for (Item needItem : new ArrayList<>(needItems)) { - for (Item haveItem : new ArrayList<>(haveItems)) { - if (needItem.deepEquals(haveItem)) { - int amount = Math.min(haveItem.getCount(), needItem.getCount()); - needItem.setCount(needItem.getCount() - amount); - haveItem.setCount(haveItem.getCount() - amount); - if (haveItem.getCount() == 0) { - haveItems.remove(haveItem); - } - if (needItem.getCount() == 0) { - needItems.remove(needItem); - break; - } - } - } - } - - return haveItems.isEmpty() && needItems.isEmpty(); - } - - @Override - public boolean canExecute(Player player) { - return !this.transactions.isEmpty() && this.matchItems(player); - } - - @Override - 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 (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); - } - } - return false; - } - - 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; - - return true; - } - - @Override - public int getType() { - return TYPE_NORMAL; - } -} diff --git a/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java new file mode 100644 index 0000000000..158779053d --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java @@ -0,0 +1,233 @@ +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.transaction.action.InventoryAction; +import cn.nukkit.inventory.transaction.action.SlotChangeAction; +import cn.nukkit.item.Item; +import cn.nukkit.utils.MainLogger; + +import java.util.*; +import java.util.Map.Entry; + +/** + * @author CreeperFace + */ +public class SimpleInventoryTransaction implements InventoryTransaction { + + private long creationTime; + protected boolean hasExecuted; + + protected Player source; + + protected Set inventories = new HashSet<>(); + + protected Set actions = new HashSet<>(); + + public SimpleInventoryTransaction(Player source, List actions) { + creationTime = System.currentTimeMillis(); + this.source = source; + + for (InventoryAction action : actions) { + this.addAction(action); + } + } + + public Player getSource() { + return source; + } + + @Override + public long getCreationTime() { + return creationTime; + } + + @Override + public Set getInventories() { + return inventories; + } + + @Override + public Set getActions() { + return actions; + } + + public void addAction(InventoryAction action) { + if (this.actions.contains(action)) { + return; + } + + if (action instanceof SlotChangeAction) { + this.inventories.add(((SlotChangeAction) action).getInventory()); + } + + this.actions.add(action); + } + + protected boolean matchItems(List needItems, List haveItems) { + for (InventoryAction action : this.actions) { + if (action.getTargetItem().getId() != Item.AIR) { + needItems.add(action.getTargetItem()); + } + + if (!action.isValid(this.source)) { + return false; + } + + if (action.getSourceItem().getId() != Item.AIR) { + haveItems.add(action.getSourceItem()); + } + } + + for (Item needItem : new ArrayList<>(needItems)) { + for (Item haveItem : new ArrayList<>(haveItems)) { + if (needItem.deepEquals(haveItem)) { + int amount = Math.min(haveItem.getCount(), needItem.getCount()); + needItem.setCount(needItem.getCount() - amount); + haveItem.setCount(haveItem.getCount() - amount); + if (haveItem.getCount() == 0) { + haveItems.remove(haveItem); + } + if (needItem.getCount() == 0) { + needItems.remove(needItem); + break; + } + } + } + } + + return haveItems.isEmpty() && needItems.isEmpty(); + } + + /** + * Iterates over SlotChangeActions in this transaction and compacts any which refer to the same inventorySlot in the same + * inventory so they can be correctly handled. + *

+ * Under normal circumstances, the same inventorySlot would never be changed more than once in a single transaction. However, + * due to the way things like the crafting grid are "implemented" in MCPE 1.2 (a.k.a. hacked-in), we may get + * multiple inventorySlot changes referring to the same inventorySlot in a single transaction. These multiples are not even guaranteed + * to be in the correct order (inventorySlot splitting in the crafting grid for example, causes the actions to be sent in the + * wrong order), so this method also tries to chain them into order. + * + * @return bool + */ + protected boolean squashDuplicateSlotChanges() { + Map> slotChanges = new HashMap<>(); + + for (InventoryAction action : this.actions) { + if (action instanceof SlotChangeAction) { + int hash = Objects.hash(((SlotChangeAction) action).getInventory(), ((SlotChangeAction) action).getSlot()); + + List list = slotChanges.get(hash); + if (list == null) { + list = new ArrayList<>(); + } + + list.add((SlotChangeAction) action); + + slotChanges.put(hash, list); + } + } + + for (Entry> entry : new ArrayList<>(slotChanges.entrySet())) { + int hash = entry.getKey(); + List list = entry.getValue(); + + if (list.size() == 1) { //No need to compact inventorySlot changes if there is only one on this inventorySlot + slotChanges.remove(hash); + continue; + } + + List originalList = new ArrayList<>(list); + + SlotChangeAction originalAction = null; + Item lastTargetItem = null; + + for (int i = 0; i < list.size(); i++) { + SlotChangeAction action = list.get(i); + + if (action.isValid(this.source)) { + originalAction = action; + lastTargetItem = action.getTargetItem(); + list.remove(i); + break; + } + } + + if (originalAction == null) { + return false; //Couldn't find any actions that had a source-item matching the current inventory inventorySlot + } + + int sortedThisLoop; + + do { + sortedThisLoop = 0; + for (int i = 0; i < list.size(); i++) { + SlotChangeAction action = list.get(i); + + Item actionSource = action.getSourceItem(); + if (actionSource.equalsExact(lastTargetItem)) { + lastTargetItem = action.getTargetItem(); + list.remove(i); + sortedThisLoop++; + } + } + } while (sortedThisLoop > 0); + + if (list.size() > 0) { //couldn't chain all the actions together + MainLogger.getLogger().debug("Failed to compact " + originalList.size() + " actions for " + this.source.getName()); + return false; + } + + for (SlotChangeAction action : originalList) { + this.actions.remove(action); + } + + this.addAction(new SlotChangeAction(originalAction.getInventory(), originalAction.getSlot(), originalAction.getSourceItem(), lastTargetItem)); + + MainLogger.getLogger().debug("Successfully compacted " + originalList.size() + " actions for " + this.source.getName()); + } + + return true; + } + + public boolean canExecute() { + this.squashDuplicateSlotChanges(); + + List haveItems = new ArrayList<>(); + List needItems = new ArrayList<>(); + return matchItems(needItems, haveItems) && this.actions.size() > 0 && haveItems.size() == 0 && needItems.size() == 0; + } + + /** + * @return bool + */ + public boolean execute() { + if (this.hasExecuted() || !this.canExecute()) { + return false; + } + + InventoryTransactionEvent ev = new InventoryTransactionEvent(this); + Server.getInstance().getPluginManager().callEvent(ev); + if (ev.isCancelled()) { + return false; + } + + for (InventoryAction action : this.actions) { + if (action.execute(this.source)) { + action.onExecuteSuccess(this.source); + } else { + action.onExecuteFail(this.source); + } + } + + this.hasExecuted = true; + return true; + } + + public boolean hasExecuted() { + return this.hasExecuted; + } +} diff --git a/src/main/java/cn/nukkit/inventory/transaction/Transaction.java b/src/main/java/cn/nukkit/inventory/transaction/Transaction.java deleted file mode 100644 index fa0c05b3ab..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/Transaction.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.nukkit.inventory.transaction; - -import cn.nukkit.item.Item; - -/** - * author: MagicDroidX - * Nukkit Project - */ -public interface Transaction { - - int TYPE_CONTAINER = 0; - int TYPE_GLOBAL = 1; - int TYPE_WORLD_INTERACTON = 2; - int TYPE_CREATIVE = 3; - int TYPE_CRAFT = 99999; - - int getSlot(); - - Item getSourceItem(); - - 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 deleted file mode 100644 index 1e42c11f00..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/TransactionGroup.java +++ /dev/null @@ -1,76 +0,0 @@ -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_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, bow shoot - int ITEM_RELEASE_ACTION_CONSUME = 1; //eat arrows - - //Checked, this values should be like this - int ITEM_USE_CLICK_BLOCK = 0; - int ITEM_USE_CLICK_AIR = 1; - int ITEM_USE_BREAK_BLOCK = 2; //-1 - - int SOURCE_CONTAINER = 0; - int SOURCE_WORLD = 2; //drop/pickup item entity - int SOURCE_CREATIVE = 3; - int SOURCE_TODO = 99999; - - int SOURCE_TYPE_CRAFTING_ADD_INGREDIENT = -2; - int SOURCE_TYPE_CRAFTING_REMOVE_INGREDIENT = -3; - int SOURCE_TYPE_CRAFTING_RESULT = -4; - int SOURCE_TYPE_CRAFTING_USE_INGREDIENT = -5; - - int SOURCE_TYPE_ANVIL_INPUT = -10; - int SOURCE_TYPE_ANVIL_MATERIAL = -11; - int SOURCE_TYPE_ANVIL_RESULT = -12; - int SOURCE_TYPE_ANVIL_OUTPUT = -13; - - int SOURCE_TYPE_ENCHANT_INPUT = -15; - int SOURCE_TYPE_ENCHANT_MATERIAL = -16; - int SOURCE_TYPE_ENCHANT_OUTPUT = -17; - - int SOURCE_TYPE_TRADING_INPUT_1 = -20; - int SOURCE_TYPE_TRADING_INPUT_2 = -21; - int SOURCE_TYPE_TRADING_USE_INPUTS = -22; - int SOURCE_TYPE_TRADING_OUTPUT = -23; - - int SOURCE_TYPE_BEACON = -24; - - int SOURCE_TYPE_CONTAINER_DROP_CONTENTS = -100; - - int ACTION_MAGIC_SLOT_DROP_ITEM = 0; - int ACTION_MAGIC_SLOT_PICKUP_ITEM = 1; - - int ACTION_MAGIC_SLOT_CREATIVE_DELETE_ITEM = 0; - int ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM = 1; - - 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 deleted file mode 100644 index 5c25262951..0000000000 --- a/src/main/java/cn/nukkit/inventory/transaction/WorldInteractionTransaction.java +++ /dev/null @@ -1,22 +0,0 @@ -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/inventory/transaction/action/CreativeInventoryAction.java b/src/main/java/cn/nukkit/inventory/transaction/action/CreativeInventoryAction.java new file mode 100644 index 0000000000..eaa94eec75 --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/transaction/action/CreativeInventoryAction.java @@ -0,0 +1,54 @@ +package cn.nukkit.inventory.transaction.action; + +import cn.nukkit.Player; +import cn.nukkit.item.Item; + +/** + * @author CreeperFace + */ +public class CreativeInventoryAction extends InventoryAction { + /** + * Player put an item into the creative window to destroy it. + */ + public static final int TYPE_DELETE_ITEM = 0; + /** + * Player took an item from the creative window. + */ + public static final int TYPE_CREATE_ITEM = 1; + + protected int actionType; + + public CreativeInventoryAction(Item source, Item target, int action) { + super(source, target); + } + + /** + * Checks that the player is in creative, and (if creating an item) that the item exists in the creative inventory. + */ + public boolean isValid(Player source) { + return source.isCreative() && + (this.actionType == TYPE_DELETE_ITEM || Item.getCreativeItemIndex(this.sourceItem) != -1); + } + + /** + * Returns the type of the action. + */ + public int getActionType() { + return actionType; + } + + /** + * No need to do anything extra here: this type just provides a place for items to disappear or appear from. + */ + public boolean execute(Player source) { + return true; + } + + public void onExecuteSuccess(Player source) { + + } + + public void onExecuteFail(Player source) { + + } +} diff --git a/src/main/java/cn/nukkit/inventory/transaction/action/DropItemAction.java b/src/main/java/cn/nukkit/inventory/transaction/action/DropItemAction.java new file mode 100644 index 0000000000..cd641e43b1 --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/transaction/action/DropItemAction.java @@ -0,0 +1,37 @@ +package cn.nukkit.inventory.transaction.action; + +import cn.nukkit.Player; +import cn.nukkit.item.Item; + +/** + * @author CreeperFace + */ +public class DropItemAction extends InventoryAction { + + public DropItemAction(Item source, Item target) { + super(source, target); + } + + /** + * Verifies that the source item of a drop-item action must be air. This is not strictly necessary, just a sanity + * check. + */ + public boolean isValid(Player source) { + return this.sourceItem.isNull(); + } + + /** + * Drops the target item in front of the player. + */ + public boolean execute(Player source) { + return source.dropItem(this.targetItem); + } + + public void onExecuteSuccess(Player source) { + + } + + public void onExecuteFail(Player source) { + + } +} diff --git a/src/main/java/cn/nukkit/inventory/transaction/action/InventoryAction.java b/src/main/java/cn/nukkit/inventory/transaction/action/InventoryAction.java new file mode 100644 index 0000000000..2760a1e841 --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/transaction/action/InventoryAction.java @@ -0,0 +1,66 @@ +package cn.nukkit.inventory.transaction.action; + +import cn.nukkit.Player; +import cn.nukkit.item.Item; + +/** + * @author CreeperFace + */ +public abstract class InventoryAction { + + + private long creationTime; + + protected Item sourceItem; + + protected Item targetItem; + + public InventoryAction(Item sourceItem, Item targetItem) { + this.sourceItem = sourceItem; + this.targetItem = targetItem; + + this.creationTime = System.currentTimeMillis(); + } + + public long getCreationTime() { + return creationTime; + } + + /** + * Returns the item that was present before the action took place. + * + * @return Item + */ + public Item getSourceItem() { + return sourceItem.clone(); + } + + /** + * Returns the item that the action attempted to replace the source item with. + */ + public Item getTargetItem() { + return targetItem.clone(); + } + + /** + * Returns whether this action is currently valid. This should perform any necessary sanity checks. + */ + abstract public boolean isValid(Player source); + + /** + * Performs actions needed to complete the inventory-action server-side. Returns if it was successful. Will return + * false if plugins cancelled events. This will only be called if the transaction which it is part of is considered + * valid. + */ + abstract public boolean execute(Player source); + + /** + * Performs additional actions when this inventory-action completed successfully. + */ + abstract public void onExecuteSuccess(Player $source); + + /** + * Performs additional actions when this inventory-action did not complete successfully. + */ + abstract public void onExecuteFail(Player source); +} diff --git a/src/main/java/cn/nukkit/inventory/transaction/action/SlotChangeAction.java b/src/main/java/cn/nukkit/inventory/transaction/action/SlotChangeAction.java new file mode 100644 index 0000000000..3b91ada7ae --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/transaction/action/SlotChangeAction.java @@ -0,0 +1,68 @@ +package cn.nukkit.inventory.transaction.action; + +import cn.nukkit.Player; +import cn.nukkit.inventory.Inventory; +import cn.nukkit.item.Item; + +import java.util.Set; + +/** + * @author CreeperFace + */ +public class SlotChangeAction extends InventoryAction { + + protected Inventory inventory; + private int inventorySlot; + + public SlotChangeAction(Inventory inventory, int inventorySlot, Item sourceItem, Item targetItem) { + super(sourceItem, targetItem); + this.inventory = inventory; + this.inventorySlot = inventorySlot; + } + + /** + * Returns the inventory involved in this action. + */ + public Inventory getInventory() { + return this.inventory; + } + + /** + * Returns the inventorySlot in the inventory which this action modified. + */ + public int getSlot() { + return inventorySlot; + } + + /** + * Checks if the item in the inventory at the specified inventorySlot is the same as this action's source item. + */ + public boolean isValid(Player source) { + Item check = inventory.getItem(this.inventorySlot); + return check.equalsExact(this.sourceItem); + } + + /** + * Sets the item into the target inventory. + */ + public boolean execute(Player source) { + return this.inventory.setItem(this.inventorySlot, this.targetItem, false); + } + + /** + * Sends inventorySlot changes to other viewers of the inventory. This will not send any change back to the source Player. + */ + public void onExecuteSuccess(Player source) { + Set viewers = this.inventory.getViewers(); + viewers.remove(source); + + this.inventory.sendSlot(this.inventorySlot, viewers); + } + + /** + * Sends the original inventorySlot contents to the source player to revert the action. + */ + public void onExecuteFail(Player source) { + this.inventory.sendSlot(this.inventorySlot, source); + } +} diff --git a/src/main/java/cn/nukkit/inventory/transaction/data/ReleaseItemData.java b/src/main/java/cn/nukkit/inventory/transaction/data/ReleaseItemData.java new file mode 100644 index 0000000000..9ad8db1038 --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/transaction/data/ReleaseItemData.java @@ -0,0 +1,15 @@ +package cn.nukkit.inventory.transaction.data; + +import cn.nukkit.item.Item; +import cn.nukkit.math.Vector3; + +/** + * @author CreeperFace + */ +public class ReleaseItemData implements TransactionData { + + public int actionType; + public int hotbarSlot; + public Item itemInHand; + public Vector3 headRot; +} diff --git a/src/main/java/cn/nukkit/inventory/transaction/data/TransactionData.java b/src/main/java/cn/nukkit/inventory/transaction/data/TransactionData.java new file mode 100644 index 0000000000..f594453b90 --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/transaction/data/TransactionData.java @@ -0,0 +1,7 @@ +package cn.nukkit.inventory.transaction.data; + +/** + * @author CreeperFace + */ +public interface TransactionData { +} diff --git a/src/main/java/cn/nukkit/inventory/transaction/data/UseItemData.java b/src/main/java/cn/nukkit/inventory/transaction/data/UseItemData.java new file mode 100644 index 0000000000..00c5cae5e3 --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/transaction/data/UseItemData.java @@ -0,0 +1,22 @@ +package cn.nukkit.inventory.transaction.data; + +import cn.nukkit.item.Item; +import cn.nukkit.math.BlockFace; +import cn.nukkit.math.BlockVector3; +import cn.nukkit.math.Vector3; +import cn.nukkit.math.Vector3f; + +/** + * @author CreeperFace + */ +public class UseItemData implements TransactionData { + + public int actionType; + public BlockVector3 blockPos; + public BlockFace face; + public int hotbarSlot; + public Item itemInHand; + public Vector3 playerPos; + public Vector3f clickPos; + +} diff --git a/src/main/java/cn/nukkit/inventory/transaction/data/UseItemOnEntityData.java b/src/main/java/cn/nukkit/inventory/transaction/data/UseItemOnEntityData.java new file mode 100644 index 0000000000..ca09c09d0d --- /dev/null +++ b/src/main/java/cn/nukkit/inventory/transaction/data/UseItemOnEntityData.java @@ -0,0 +1,18 @@ +package cn.nukkit.inventory.transaction.data; + +import cn.nukkit.item.Item; +import cn.nukkit.math.Vector3; + +/** + * @author CreeperFace + */ +public class UseItemOnEntityData implements TransactionData { + + public long entityRuntimeId; + public int actionType; + public int hotbarSlot; + public Item itemInHand; + public Vector3 vector1; + public Vector3 vector2; + +} diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java index 5aef57ef90..a786793591 100644 --- a/src/main/java/cn/nukkit/item/Item.java +++ b/src/main/java/cn/nukkit/item/Item.java @@ -10,6 +10,7 @@ import cn.nukkit.item.enchantment.Enchantment; import cn.nukkit.level.Level; import cn.nukkit.math.BlockFace; +import cn.nukkit.math.Vector3; import cn.nukkit.nbt.NBTIO; import cn.nukkit.nbt.tag.CompoundTag; import cn.nukkit.nbt.tag.ListTag; @@ -1912,6 +1913,10 @@ public void setCount(int count) { this.count = count; } + public boolean isNull() { + return this.count <= 0 || this.id == AIR; + } + final public String getName() { return this.hasCustomName() ? this.getCustomName() : this.name; } @@ -2055,6 +2060,22 @@ public boolean onActivate(Level level, Player player, Block block, Block target, return false; } + /** + * Called when a player uses the item on air, for example throwing a projectile. + * Returns whether the item was changed, for example count decrease or durability change. + */ + public boolean onClickAir(Player player, Vector3 directionVector) { + return false; + } + + /** + * Called when a player is using this item and releases it. Used to handle bow shoot actions. + * Returns whether the item was changed, for example count decrease or durability change. + */ + public boolean onReleaseUsing(Player player) { + return false; + } + @Override public final boolean equals(Object item) { return item instanceof Item && this.equals((Item) item, true); @@ -2068,6 +2089,13 @@ public final boolean equals(Item item, boolean checkDamage, boolean checkCompoun return this.getId() == item.getId() && (!checkDamage || this.getDamage() == item.getDamage()) && (!checkCompound || Arrays.equals(this.getCompoundTag(), item.getCompoundTag())); } + /** + * Returns whether the specified item stack has the same ID, damage, NBT and count as this item stack. + */ + public final boolean equalsExact(Item other) { + return this.equals(other, true, true) && this.count == other.count; + } + public final boolean deepEquals(Item item) { return deepEquals(item, true); } diff --git a/src/main/java/cn/nukkit/item/ItemBow.java b/src/main/java/cn/nukkit/item/ItemBow.java index ada68422ad..1a4e23dab1 100644 --- a/src/main/java/cn/nukkit/item/ItemBow.java +++ b/src/main/java/cn/nukkit/item/ItemBow.java @@ -1,5 +1,21 @@ package cn.nukkit.item; +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.item.enchantment.Enchantment; +import cn.nukkit.level.sound.LaunchSound; +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; + /** * author: MagicDroidX * Nukkit Project @@ -27,4 +43,91 @@ public int getMaxDurability() { public int getEnchantAbility() { return 1; } + + public boolean onReleaseUsing(Player player) { + Item itemArrow = Item.get(Item.ARROW, 0, 1); + + if (player.isSurvival() && !player.getInventory().contains(itemArrow)) { + player.getInventory().sendContents(player); + return false; + } + + double damage = 2; + boolean flame = false; + + if (this.hasEnchantments()) { + Enchantment bowDamage = this.getEnchantment(Enchantment.ID_BOW_POWER); + + if (bowDamage != null && bowDamage.getLevel() > 0) { + damage += 0.25 * (bowDamage.getLevel() + 1); + } + + Enchantment flameEnchant = this.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, this, 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(); + player.getInventory().sendContents(player); + } else { + entityShootBowEvent.getProjectile().setMotion(entityShootBowEvent.getProjectile().getMotion().multiply(entityShootBowEvent.getForce())); + if (player.isSurvival()) { + Enchantment infinity; + + if (!this.hasEnchantments() || (infinity = this.getEnchantment(Enchantment.ID_BOW_INFINITY)) == null || infinity.getLevel() <= 0) + player.getInventory().removeItem(itemArrow); + if (!this.isUnbreakable()) { + Enchantment durability = this.getEnchantment(Enchantment.ID_DURABILITY); + if (!(durability != null && durability.getLevel() > 0 && (100 / (durability.getLevel() + 1)) <= new Random().nextInt(100))) { + this.setDamage(this.getDamage() + 1); + if (this.getDamage() >= 385) { + player.getInventory().setItemInHand(new ItemBlock(new BlockAir(), 0, 0)); + } else { + player.getInventory().setItemInHand(this); + } + } + } + } + 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(); + } + } + + return true; + } } diff --git a/src/main/java/cn/nukkit/item/ItemSnowball.java b/src/main/java/cn/nukkit/item/ItemSnowball.java index 47bf2dc6e5..ae6a5a2740 100644 --- a/src/main/java/cn/nukkit/item/ItemSnowball.java +++ b/src/main/java/cn/nukkit/item/ItemSnowball.java @@ -4,7 +4,7 @@ * author: MagicDroidX * Nukkit Project */ -public class ItemSnowball extends Item { +public class ItemSnowball extends ProjectileItem { public ItemSnowball() { this(0, 1); @@ -22,4 +22,14 @@ public ItemSnowball(Integer meta, int count) { public int getMaxStackSize() { return 16; } + + @Override + public String getProjectileEntityType() { + return "Snowball"; + } + + @Override + public float getThrowForce() { + return 1.5f; + } } diff --git a/src/main/java/cn/nukkit/item/ProjectileItem.java b/src/main/java/cn/nukkit/item/ProjectileItem.java new file mode 100644 index 0000000000..3443f1f317 --- /dev/null +++ b/src/main/java/cn/nukkit/item/ProjectileItem.java @@ -0,0 +1,62 @@ +package cn.nukkit.item; + +import cn.nukkit.Player; +import cn.nukkit.entity.Entity; +import cn.nukkit.entity.projectile.EntityProjectile; +import cn.nukkit.event.entity.ProjectileLaunchEvent; +import cn.nukkit.level.sound.LaunchSound; +import cn.nukkit.math.Vector3; +import cn.nukkit.nbt.tag.CompoundTag; +import cn.nukkit.nbt.tag.DoubleTag; +import cn.nukkit.nbt.tag.FloatTag; +import cn.nukkit.nbt.tag.ListTag; + +/** + * @author CreeperFace + */ +public abstract class ProjectileItem extends Item { + + public ProjectileItem(int id, Integer meta, int count, String name) { + super(id, meta, count, name); + } + + abstract public String getProjectileEntityType(); + + abstract public float getThrowForce(); + + public boolean onClickAir(Player player, Vector3 directionVector) { + 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("", directionVector.x)) + .add(new DoubleTag("", directionVector.y)) + .add(new DoubleTag("", directionVector.z))) + .putList(new ListTag("Rotation") + .add(new FloatTag("", (float) player.yaw)) + .add(new FloatTag("", (float) player.pitch))); + + Entity snowball = Entity.createEntity(this.getProjectileEntityType(), player.getLevel().getChunk(player.getFloorX() >> 4, player.getFloorZ() >> 4), nbt, player); + snowball.setMotion(snowball.getMotion().multiply(this.getThrowForce())); + + this.count--; + + if (snowball instanceof EntityProjectile) { + ProjectileLaunchEvent ev = new ProjectileLaunchEvent((EntityProjectile) snowball); + + player.getServer().getPluginManager().callEvent(ev); + if (ev.isCancelled()) { + snowball.kill(); + } else { + snowball.spawnToAll(); + player.getLevel().addSound(new LaunchSound(player), player.getViewers().values()); + } + } else { + snowball.spawnToAll(); + } + + return true; + } +} diff --git a/src/main/java/cn/nukkit/math/BlockVector3.java b/src/main/java/cn/nukkit/math/BlockVector3.java index 379dd35c29..98d2d4544b 100644 --- a/src/main/java/cn/nukkit/math/BlockVector3.java +++ b/src/main/java/cn/nukkit/math/BlockVector3.java @@ -216,4 +216,12 @@ public BlockVector3 clone() { return null; } } + + public Vector3 asVector3() { + return new Vector3(this.x, this.y, this.z); + } + + public Vector3f asVector3f() { + return new Vector3f(this.x, this.y, this.z); + } } diff --git a/src/main/java/cn/nukkit/math/Vector3.java b/src/main/java/cn/nukkit/math/Vector3.java index e80a3ddbcd..75c7695e6f 100644 --- a/src/main/java/cn/nukkit/math/Vector3.java +++ b/src/main/java/cn/nukkit/math/Vector3.java @@ -346,4 +346,12 @@ public Vector3 clone() { return null; } } + + public Vector3f asVector3f() { + return new Vector3f((float) this.x, (float) this.y, (float) this.z); + } + + public BlockVector3 asBlockVector3() { + return new BlockVector3(this.getFloorX(), this.getFloorY(), this.getFloorZ()); + } } diff --git a/src/main/java/cn/nukkit/math/Vector3f.java b/src/main/java/cn/nukkit/math/Vector3f.java index 3f1eba2461..d77200a278 100644 --- a/src/main/java/cn/nukkit/math/Vector3f.java +++ b/src/main/java/cn/nukkit/math/Vector3f.java @@ -324,4 +324,12 @@ public Vector3f clone() { return null; } } + + public Vector3 asVector3() { + return new Vector3(this.x, this.y, this.z); + } + + public BlockVector3 asBlockVector3() { + return new BlockVector3(getFloorX(), getFloorY(), getFloorZ()); + } } \ No newline at end of file diff --git a/src/main/java/cn/nukkit/network/protocol/InteractPacket.java b/src/main/java/cn/nukkit/network/protocol/InteractPacket.java index ccce4ddd5b..62572dbc6e 100644 --- a/src/main/java/cn/nukkit/network/protocol/InteractPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/InteractPacket.java @@ -7,8 +7,6 @@ public class InteractPacket extends DataPacket { public static final byte NETWORK_ID = ProtocolInfo.INTERACT_PACKET; - 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; diff --git a/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java b/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java index c42ae1312e..56bb403c24 100644 --- a/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java @@ -1,13 +1,39 @@ package cn.nukkit.network.protocol; -import cn.nukkit.inventory.transaction.*; - -import java.util.ArrayList; -import java.util.List; +import cn.nukkit.inventory.transaction.data.ReleaseItemData; +import cn.nukkit.inventory.transaction.data.TransactionData; +import cn.nukkit.inventory.transaction.data.UseItemData; +import cn.nukkit.inventory.transaction.data.UseItemOnEntityData; +import cn.nukkit.network.protocol.types.NetworkInventoryAction; public class InventoryTransactionPacket extends DataPacket { - public TransactionGroup transaction; + public static final int TYPE_NORMAL = 0; + public static final int TYPE_MISMATCH = 1; + public static final int TYPE_USE_ITEM = 2; + public static final int TYPE_USE_ITEM_ON_ENTITY = 3; + public static final int TYPE_RELEASE_ITEM = 4; + + public static final int USE_ITEM_ACTION_CLICK_BLOCK = 0; + public static final int USE_ITEM_ACTION_CLICK_AIR = 1; + public static final int USE_ITEM_ACTION_BREAK_BLOCK = 2; + + public static final int RELEASE_ITEM_ACTION_RELEASE = 0; //bow shoot + public static final int RELEASE_ITEM_ACTION_CONSUME = 1; //eat food, drink potion + + public static final int USE_ITEM_ON_ENTITY_ACTION_INTERACT = 0; + public static final int USE_ITEM_ON_ENTITY_ACTION_ATTACK = 1; + + + public static final int ACTION_MAGIC_SLOT_DROP_ITEM = 0; + public static final int ACTION_MAGIC_SLOT_PICKUP_ITEM = 1; + + public static final int ACTION_MAGIC_SLOT_CREATIVE_DELETE_ITEM = 0; + public static final int ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM = 1; + + public int transactionType; + public NetworkInventoryAction[] actions; + public TransactionData transactionData; @Override public byte pid() { @@ -16,121 +42,102 @@ public byte pid() { @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()); + this.putUnsignedVarInt(this.transactionType); + + this.putUnsignedVarInt(this.actions.length); + for (NetworkInventoryAction action : this.actions) { + action.write(this); } - 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()); + + switch (this.transactionType) { + case TYPE_NORMAL: + case TYPE_MISMATCH: 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()); + case TYPE_USE_ITEM: + UseItemData useItemData = (UseItemData) this.transactionData; + + this.putUnsignedVarInt(useItemData.actionType); + this.putBlockVector3(useItemData.blockPos); + this.putBlockFace(useItemData.face); + this.putVarInt(useItemData.hotbarSlot); + this.putSlot(useItemData.itemInHand); + this.putVector3f(useItemData.playerPos.asVector3f()); + this.putVector3f(useItemData.clickPos); 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()); + case TYPE_USE_ITEM_ON_ENTITY: + UseItemOnEntityData useItemOnEntityData = (UseItemOnEntityData) this.transactionData; + + this.putUnsignedVarInt(useItemOnEntityData.entityRuntimeId); + this.putUnsignedVarInt(useItemOnEntityData.actionType); + this.putVarInt(useItemOnEntityData.hotbarSlot); + this.putSlot(useItemOnEntityData.itemInHand); + this.putVector3f(useItemOnEntityData.vector1.asVector3f()); + this.putVector3f(useItemOnEntityData.vector2.asVector3f()); + break; + case TYPE_RELEASE_ITEM: + ReleaseItemData releaseItemData = (ReleaseItemData) this.transactionData; + + this.putUnsignedVarInt(releaseItemData.actionType); + this.putVarInt(releaseItemData.hotbarSlot); + this.putSlot(releaseItemData.itemInHand); + this.putVector3f(releaseItemData.headRot.asVector3f()); + break; + default: + throw new RuntimeException("Unknown transaction type $this->transactionType"); } } @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); + this.transactionType = (int) this.getUnsignedVarInt(); + + this.actions = new NetworkInventoryAction[(int) this.getUnsignedVarInt()]; + for (int i = 0; i < this.actions.length; i++) { + this.actions[i] = new NetworkInventoryAction().read(this); } - switch (type) { - case TransactionGroup.TYPE_NORMAL: - transaction = new NormalTransactionGroup(); - break; - case TransactionGroup.TYPE_INVENTORY_MISMATCH: - transaction = new InventoryMismatchTransactionGroup(); + switch (this.transactionType) { + case TYPE_NORMAL: + case TYPE_MISMATCH: + //Regular ComplexInventoryTransaction doesn't read any extra data break; - case TransactionGroup.TYPE_ITEM_USE: - transaction = new ItemUseTransactionGroup( - this.getVarInt(), - this.getBlockVector3(), - this.getVarInt(), - this.getVarInt(), - this.getSlot(), - this.getVector3f(), - this.getVector3f() - ); + case TYPE_USE_ITEM: + UseItemData itemData = new UseItemData(); + itemData.actionType = (int) this.getUnsignedVarInt(); + itemData.blockPos = this.getBlockVector3(); + itemData.face = this.getBlockFace(); + itemData.hotbarSlot = this.getVarInt(); + itemData.itemInHand = this.getSlot(); + itemData.playerPos = this.getVector3f().asVector3(); + itemData.clickPos = this.getVector3f(); + + this.transactionData = itemData; break; - case TransactionGroup.TYPE_ITEM_USE_ON_ENTITY: - transaction = new ItemUseOnEntityTransactionGroup( - this.getVarLong(), - this.getVarInt(), - this.getVarInt(), - this.getSlot(), - this.getVector3f() - ); + case TYPE_USE_ITEM_ON_ENTITY: + UseItemOnEntityData useItemOnEntityData = new UseItemOnEntityData(); + + useItemOnEntityData.entityRuntimeId = this.getUnsignedVarLong(); + useItemOnEntityData.actionType = (int) this.getUnsignedVarInt(); + useItemOnEntityData.hotbarSlot = this.getVarInt(); + useItemOnEntityData.itemInHand = this.getSlot(); + useItemOnEntityData.vector1 = this.getVector3f().asVector3(); + useItemOnEntityData.vector2 = this.getVector3f().asVector3(); + + this.transactionData = useItemOnEntityData; break; - case TransactionGroup.TYPE_ITEM_RELEASE: - transaction = new ItemReleaseTransactionGroup( - this.getVarInt(), - this.getVarInt(), - this.getSlot(), - this.getVector3f() - ); + case TYPE_RELEASE_ITEM: + ReleaseItemData releaseItemData = new ReleaseItemData(); + + releaseItemData.actionType = (int) getUnsignedVarInt(); + releaseItemData.hotbarSlot = getVarInt(); + releaseItemData.itemInHand = getSlot(); + releaseItemData.headRot = this.getVector3f().asVector3(); + + this.transactionData = releaseItemData; break; default: - return; + throw new RuntimeException("Unknown transaction type $this->transactionType"); } - list.forEach(transaction::addTransaction); } } diff --git a/src/main/java/cn/nukkit/network/protocol/MobEquipmentPacket.java b/src/main/java/cn/nukkit/network/protocol/MobEquipmentPacket.java index f1ea1ebd50..90380470e8 100644 --- a/src/main/java/cn/nukkit/network/protocol/MobEquipmentPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/MobEquipmentPacket.java @@ -16,16 +16,16 @@ public byte pid() { public long eid; public Item item; - public int slot; - public int selectedSlot; + public int inventorySlot; + public int hotbarSlot; public int windowId; @Override public void decode() { this.eid = this.getVarLong(); //EntityRuntimeID this.item = this.getSlot(); - this.slot = this.getByte(); - this.selectedSlot = this.getByte(); + this.inventorySlot = this.getByte(); + this.hotbarSlot = this.getByte(); this.windowId = this.getByte(); } @@ -34,8 +34,8 @@ public void encode() { this.reset(); this.putVarLong(this.eid); //EntityRuntimeID this.putSlot(this.item); - this.putByte((byte) this.slot); - this.putByte((byte) this.selectedSlot); + this.putByte((byte) this.inventorySlot); + this.putByte((byte) this.hotbarSlot); this.putByte((byte) this.windowId); } } diff --git a/src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java b/src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java index 63078c2fac..6bd53cab3f 100644 --- a/src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java @@ -1,9 +1,16 @@ package cn.nukkit.network.protocol; +import cn.nukkit.network.protocol.types.ContainerIds; +import cn.nukkit.utils.Binary; + public class PlayerHotbarPacket extends DataPacket { - public int selectedSlot; - public int[] data = new int[0]; + public int selectedHotbarSlot; + public int windowId = ContainerIds.INVENTORY; + + public int[] slots; + + public boolean selectHotbarSlot = true; @Override public byte pid() { @@ -12,20 +19,26 @@ public byte pid() { @Override public void decode() { - this.selectedSlot = this.getByte(); + this.selectedHotbarSlot = (int) this.getUnsignedVarInt(); + this.windowId = 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(); + slots = new int[count]; + + for (int i = 0; i < count; ++i) { + this.slots[i] = Binary.signInt((int) this.getUnsignedVarInt()); } + this.selectHotbarSlot = this.getBoolean(); } @Override public void encode() { - this.putByte((byte) selectedSlot); - this.putUnsignedVarInt(this.data.length); - for (int slot : this.data) { - this.putVarInt(slot); + this.putUnsignedVarInt(this.selectedHotbarSlot); + this.putByte((byte) this.windowId); + this.putUnsignedVarInt(this.slots.length); + for (int i : slots) { + this.putUnsignedVarInt(i); } + + this.putBoolean(this.selectHotbarSlot); } } diff --git a/src/main/java/cn/nukkit/network/protocol/types/ContainerIds.java b/src/main/java/cn/nukkit/network/protocol/types/ContainerIds.java new file mode 100644 index 0000000000..539b8098ca --- /dev/null +++ b/src/main/java/cn/nukkit/network/protocol/types/ContainerIds.java @@ -0,0 +1,18 @@ +package cn.nukkit.network.protocol.types; + +/** + * @author CreeperFace + */ +public interface ContainerIds { + + int NONE = -1; + int INVENTORY = 0; + int FIRST = 1; + int LAST = 100; + int OFFHAND = 119; + int ARMOR = 120; + int CREATIVE = 121; + int HOTBAR = 122; + int FIXED_INVENTORY = 123; + int CURSOR = 124; +} diff --git a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java new file mode 100644 index 0000000000..d1da6718d5 --- /dev/null +++ b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java @@ -0,0 +1,175 @@ +package cn.nukkit.network.protocol.types; + +import cn.nukkit.Player; +import cn.nukkit.inventory.Inventory; +import cn.nukkit.inventory.transaction.action.CreativeInventoryAction; +import cn.nukkit.inventory.transaction.action.DropItemAction; +import cn.nukkit.inventory.transaction.action.InventoryAction; +import cn.nukkit.inventory.transaction.action.SlotChangeAction; +import cn.nukkit.item.Item; +import cn.nukkit.network.protocol.InventoryTransactionPacket; + +/** + * @author CreeperFace + */ +public class NetworkInventoryAction { + + public static final int SOURCE_CONTAINER = 0; + + public static final int SOURCE_WORLD = 2; //drop/pickup item entity + public static final int SOURCE_CREATIVE = 3; + public static final int SOURCE_TODO = 99999; + + /** + * Fake window IDs for the SOURCE_TODO type (99999) + *

+ * These identifiers are used for inventory source types which are not currently implemented server-side in MCPE. + * As a general rule of thumb, anything that doesn't have a permanent inventory is client-side. These types are + * to allow servers to track what is going on in client-side windows. + *

+ * Expect these to change in the future. + */ + public static final int SOURCE_TYPE_CRAFTING_ADD_INGREDIENT = -2; + public static final int SOURCE_TYPE_CRAFTING_REMOVE_INGREDIENT = -3; + public static final int SOURCE_TYPE_CRAFTING_RESULT = -4; + public static final int SOURCE_TYPE_CRAFTING_USE_INGREDIENT = -5; + + public static final int SOURCE_TYPE_ANVIL_INPUT = -10; + public static final int SOURCE_TYPE_ANVIL_MATERIAL = -11; + public static final int SOURCE_TYPE_ANVIL_RESULT = -12; + public static final int SOURCE_TYPE_ANVIL_OUTPUT = -13; + + public static final int SOURCE_TYPE_ENCHANT_INPUT = -15; + public static final int SOURCE_TYPE_ENCHANT_MATERIAL = -16; + public static final int SOURCE_TYPE_ENCHANT_OUTPUT = -17; + + public static final int SOURCE_TYPE_TRADING_INPUT_1 = -20; + public static final int SOURCE_TYPE_TRADING_INPUT_2 = -21; + public static final int SOURCE_TYPE_TRADING_USE_INPUTS = -22; + public static final int SOURCE_TYPE_TRADING_OUTPUT = -23; + + public static final int SOURCE_TYPE_BEACON = -24; + + /** + * Any client-side window dropping its contents when the player closes it + */ + public static final int SOURCE_TYPE_CONTAINER_DROP_CONTENTS = -100; + + + public int sourceType; + public int windowId; + public long unknown; + public int inventorySlot; + public Item oldItem; + public Item newItem; + + public NetworkInventoryAction read(InventoryTransactionPacket packet) { + this.sourceType = (int) packet.getUnsignedVarInt(); + + switch (this.sourceType) { + case SOURCE_CONTAINER: + this.windowId = packet.getVarInt(); + break; + case SOURCE_WORLD: + this.unknown = packet.getUnsignedVarInt(); + break; + case SOURCE_CREATIVE: + break; + case SOURCE_TODO: + this.windowId = packet.getVarInt(); + break; + } + + this.inventorySlot = (int) packet.getUnsignedVarInt(); + this.oldItem = packet.getSlot(); + this.newItem = packet.getSlot(); + + return this; + } + + public void write(InventoryTransactionPacket packet) { + packet.putUnsignedVarInt(this.sourceType); + + switch (this.sourceType) { + case SOURCE_CONTAINER: + packet.putVarInt(this.windowId); + break; + case SOURCE_WORLD: + packet.putUnsignedVarInt(this.unknown); + break; + case SOURCE_CREATIVE: + break; + case SOURCE_TODO: + packet.putVarInt(this.windowId); + break; + } + + packet.putUnsignedVarInt(this.inventorySlot); + packet.putSlot(this.oldItem); + packet.putSlot(this.newItem); + } + + public InventoryAction createInventoryAction(Player player) { + switch (this.sourceType) { + case SOURCE_CONTAINER: + if (this.windowId == ContainerIds.ARMOR) { + //TODO: HACK! + this.inventorySlot += 36; + this.windowId = ContainerIds.INVENTORY; + } + + Inventory window = player.getWindowById(this.windowId); + if (window != null) { + return new SlotChangeAction(window, this.inventorySlot, this.oldItem, this.newItem); + } + + throw new RuntimeException("Player " + player.getName() + " has no open container with window ID " + this.windowId); + case SOURCE_WORLD: + if (this.inventorySlot != InventoryTransactionPacket.ACTION_MAGIC_SLOT_DROP_ITEM) { + throw new RuntimeException("Only expecting drop-item world actions from the client!"); + } + + return new DropItemAction(this.oldItem, this.newItem); + case SOURCE_CREATIVE: + int type; + + switch (this.inventorySlot) { + case InventoryTransactionPacket.ACTION_MAGIC_SLOT_CREATIVE_DELETE_ITEM: + type = CreativeInventoryAction.TYPE_DELETE_ITEM; + break; + case InventoryTransactionPacket.ACTION_MAGIC_SLOT_CREATIVE_CREATE_ITEM: + type = CreativeInventoryAction.TYPE_CREATE_ITEM; + break; + default: + throw new RuntimeException("Unexpected creative action type " + this.inventorySlot); + + } + + return new CreativeInventoryAction(this.oldItem, this.newItem, type); + case SOURCE_TODO: + //These types need special handling. + switch (this.windowId) { + case SOURCE_TYPE_CRAFTING_ADD_INGREDIENT: + case SOURCE_TYPE_CRAFTING_REMOVE_INGREDIENT: + window = player.getCraftingGrid(); + return new SlotChangeAction(window, this.inventorySlot, this.oldItem, this.newItem); + + case SOURCE_TYPE_CONTAINER_DROP_CONTENTS: + //TODO: this type applies to all fake windows, not just crafting + window = player.getCraftingGrid(); + + //DROP_CONTENTS doesn't bother telling us what inventorySlot the item is in, so we find it ourselves + inventorySlot = window.first(this.oldItem, true); + if (inventorySlot == -1) { + throw new RuntimeException("Fake container " + window.getClass().getName() + " for " + player.getName() + " does not contain $this->oldItem"); + } + return new SlotChangeAction(window, inventorySlot, this.oldItem, this.newItem); + } + + //TODO: more stuff + throw new RuntimeException("Player " + player.getName() + " has no open container with window ID $this->windowId"); + default: + throw new RuntimeException("Unknown inventory source type $this->sourceType"); + } + } +} diff --git a/src/main/java/cn/nukkit/utils/Binary.java b/src/main/java/cn/nukkit/utils/Binary.java index b66111d825..b50344000f 100644 --- a/src/main/java/cn/nukkit/utils/Binary.java +++ b/src/main/java/cn/nukkit/utils/Binary.java @@ -18,6 +18,30 @@ */ public class Binary { + public static int signByte(int value) { + return value << 56 >> 56; + } + + public static int unsignByte(int value) { + return value & 0xff; + } + + public static int signShort(int value) { + return value << 48 >> 48; + } + + public int unsignShort(int value) { + return value & 0xffff; + } + + public static int signInt(int value) { + return value << 32 >> 32; + } + + public static int unsignInt(int value) { + return value; + } + //Triad: {0x00,0x00,0x01}<=>1 public static int readTriad(byte[] bytes) { return readInt(new byte[]{ diff --git a/src/main/java/cn/nukkit/utils/BinaryStream.java b/src/main/java/cn/nukkit/utils/BinaryStream.java index 44a42df741..a175edeb9a 100644 --- a/src/main/java/cn/nukkit/utils/BinaryStream.java +++ b/src/main/java/cn/nukkit/utils/BinaryStream.java @@ -1,14 +1,12 @@ 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.BlockFace; import cn.nukkit.math.BlockVector3; -import cn.nukkit.math.Vector3; import cn.nukkit.math.Vector3f; -import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; @@ -408,6 +406,14 @@ public void putRuleData(RuleData rule) { this.putBoolean(rule.unknown2); } + public BlockFace getBlockFace() { + return BlockFace.fromIndex(this.getVarInt()); + } + + public void putBlockFace(BlockFace face) { + this.putVarInt(face.getIndex()); + } + public boolean feof() { return this.offset < 0 || this.offset >= this.buffer.length; } From a63ba397ee575773463a5a6ff0146eaf84a14176 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Tue, 19 Sep 2017 19:46:18 +0200 Subject: [PATCH 076/175] Fixed inventory --- src/main/java/cn/nukkit/Player.java | 6 +++--- .../cn/nukkit/inventory/PlayerInventory.java | 21 +++++++++++-------- .../transaction/action/SlotChangeAction.java | 4 +++- src/main/java/cn/nukkit/level/Level.java | 1 + .../protocol/InventoryContentPacket.java | 4 ++-- .../network/protocol/InventorySlotPacket.java | 8 +++---- 6 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 50a9ef25d7..663a4a092e 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -70,7 +70,6 @@ import cn.nukkit.utils.*; import co.aikar.timings.Timing; import co.aikar.timings.Timings; -import com.google.gson.Gson; import java.io.IOException; import java.net.InetSocketAddress; @@ -585,6 +584,7 @@ public Player(SourceInterface interfaz, Long clientID, String ip, int port) { @Override protected void initEntity() { super.initEntity(); + this.addDefaultWindows(); } @@ -3223,7 +3223,7 @@ public void handleDataPacket(DataPacket packet) { } } - MainLogger.getLogger().debug("Failed to execute inventory transaction from " + this.getName() + " with actions: " + new Gson().toJson(transactionPacket.actions)); + MainLogger.getLogger().debug("Failed to execute inventory transaction from " + this.getName() + " with actions: " + Arrays.toString(transactionPacket.actions)); //TODO: check more stuff that might need reversion break packetswitch; //oops! @@ -3234,7 +3234,7 @@ public void handleDataPacket(DataPacket packet) { break packetswitch; case InventoryTransactionPacket.TYPE_MISMATCH: if (transactionPacket.actions.length > 0) { - this.server.getLogger().debug("Expected 0 actions for mismatch, got " + transactionPacket.actions.length + ", " + new Gson().toJson(transactionPacket.actions)); + this.server.getLogger().debug("Expected 0 actions for mismatch, got " + transactionPacket.actions.length + ", " + Arrays.toString(transactionPacket.actions)); } this.sendAllInventories(); diff --git a/src/main/java/cn/nukkit/inventory/PlayerInventory.java b/src/main/java/cn/nukkit/inventory/PlayerInventory.java index cfb0802a61..48a93a7017 100644 --- a/src/main/java/cn/nukkit/inventory/PlayerInventory.java +++ b/src/main/java/cn/nukkit/inventory/PlayerInventory.java @@ -94,10 +94,10 @@ public int getHotbarSlotIndex(int index) { return (index >= 0 && index < this.getHotbarSize()) ? this.hotbar[index] : -1; } - public void setHotbarSlotIndex(int index, int slot) { - if (index >= 0 && index < this.getHotbarSize() && slot >= -1 && slot < this.getSize()) { + public void setHotbarSlotIndex(int index, int slot) { //all slots are now linked to its ID + /*if (index >= 0 && index < this.getHotbarSize() && slot >= -1 && slot < this.getSize()) { this.hotbar[index] = slot; - } + }*/ } public int getHeldItemIndex() { @@ -201,11 +201,11 @@ public void onSlotChange(int index, Item before, boolean send) { return; } - super.onSlotChange(index, before, send); - if (index >= this.getSize()) { this.sendArmorSlot(index, this.getViewers()); this.sendArmorSlot(index, this.getHolder().getViewers().values()); + } else { + super.onSlotChange(index, before, send); } } @@ -259,7 +259,7 @@ public boolean setBoots(Item boots) { @Override public boolean setItem(int index, Item item) { - return setItem(index, item, false, true); + return setItem(index, item, true, false); } private boolean setItem(int index, Item item, boolean send, boolean ignoreArmorEvents) { @@ -287,11 +287,9 @@ private boolean setItem(int index, Item item, boolean send, boolean ignoreArmorE } item = ev.getNewItem(); } - Item old = this.getItem(index); this.slots.put(index, item.clone()); this.onSlotChange(index, old, send); - return true; } @@ -478,6 +476,7 @@ public void sendHotbarContents() { pk.windowId = ContainerIds.INVENTORY; pk.selectedHotbarSlot = this.getHeldItemIndex(); pk.slots = new int[this.getHotbarSize()]; + //pk.slots = this.hotbar; System.arraycopy(this.hotbar, 0, pk.slots, 0, pk.slots.length); @@ -508,8 +507,12 @@ public void sendSlot(int index, Player... players) { for (Player player : players) { if (player.equals(this.getHolder())) { - pk.inventoryId = 0; + pk.inventoryId = ContainerIds.INVENTORY; player.dataPacket(pk); + + if (index >= 0 && index <= 9) { //send hotbar always + this.sendHotbarContents(); + } } else { int id = player.getWindowId(this); if (id == -1) { diff --git a/src/main/java/cn/nukkit/inventory/transaction/action/SlotChangeAction.java b/src/main/java/cn/nukkit/inventory/transaction/action/SlotChangeAction.java index 3b91ada7ae..e1e77987eb 100644 --- a/src/main/java/cn/nukkit/inventory/transaction/action/SlotChangeAction.java +++ b/src/main/java/cn/nukkit/inventory/transaction/action/SlotChangeAction.java @@ -4,6 +4,7 @@ import cn.nukkit.inventory.Inventory; import cn.nukkit.item.Item; +import java.util.HashSet; import java.util.Set; /** @@ -39,6 +40,7 @@ public int getSlot() { */ public boolean isValid(Player source) { Item check = inventory.getItem(this.inventorySlot); + return check.equalsExact(this.sourceItem); } @@ -53,7 +55,7 @@ public boolean execute(Player source) { * Sends inventorySlot changes to other viewers of the inventory. This will not send any change back to the source Player. */ public void onExecuteSuccess(Player source) { - Set viewers = this.inventory.getViewers(); + Set viewers = new HashSet<>(this.inventory.getViewers()); viewers.remove(source); this.inventory.sendSlot(this.inventorySlot, viewers); diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java index eb37c5f640..479daf7b50 100644 --- a/src/main/java/cn/nukkit/level/Level.java +++ b/src/main/java/cn/nukkit/level/Level.java @@ -1830,6 +1830,7 @@ public Item useBreakOn(Vector3 vector, Item item, Player player, boolean createP BlockBreakEvent ev = new BlockBreakEvent(player, target, item, player.isCreative(), (player.lastBreak + breakTime * 1000) > System.currentTimeMillis()); + double distance; if (player.isSurvival() && !target.isBreakable(item)) { ev.setCancelled(); diff --git a/src/main/java/cn/nukkit/network/protocol/InventoryContentPacket.java b/src/main/java/cn/nukkit/network/protocol/InventoryContentPacket.java index f588211dc1..18b831866e 100644 --- a/src/main/java/cn/nukkit/network/protocol/InventoryContentPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/InventoryContentPacket.java @@ -32,7 +32,7 @@ public DataPacket clean() { @Override public void decode() { - this.inventoryId = this.getVarInt(); + this.inventoryId = (int) this.getUnsignedVarInt(); int count = (int) this.getUnsignedVarInt(); this.slots = new Item[count]; @@ -44,7 +44,7 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarInt(this.inventoryId); + this.putUnsignedVarInt(this.inventoryId); this.putUnsignedVarInt(this.slots.length); for (Item slot : this.slots) { this.putSlot(slot); diff --git a/src/main/java/cn/nukkit/network/protocol/InventorySlotPacket.java b/src/main/java/cn/nukkit/network/protocol/InventorySlotPacket.java index bf30c74567..ae8a9d6e0a 100644 --- a/src/main/java/cn/nukkit/network/protocol/InventorySlotPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/InventorySlotPacket.java @@ -20,16 +20,16 @@ public byte pid() { @Override public void decode() { - this.inventoryId = this.getVarInt(); - this.slot = this.getVarInt(); + this.inventoryId = (int) this.getUnsignedVarInt(); + this.slot = (int) this.getUnsignedVarInt(); this.item = this.getSlot(); } @Override public void encode() { this.reset(); - this.putVarInt((byte) this.inventoryId); - this.putVarInt(this.slot); + this.putUnsignedVarInt((byte) this.inventoryId); + this.putUnsignedVarInt(this.slot); this.putSlot(this.item); } } From 81cfc37d5df3d446cdd4670c39c817f7573215f7 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Tue, 19 Sep 2017 20:14:39 +0200 Subject: [PATCH 077/175] fixed update block packet! (idk how :D ) --- src/main/java/cn/nukkit/level/Level.java | 92 ++++++++----------- .../network/protocol/UpdateBlockPacket.java | 11 +-- 2 files changed, 40 insertions(+), 63 deletions(-) diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java index 479daf7b50..6ee49302ee 100644 --- a/src/main/java/cn/nukkit/level/Level.java +++ b/src/main/java/cn/nukkit/level/Level.java @@ -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 entries = new ArrayList<>(); + List packets = new ArrayList<>(); if (optimizeRebuilds) { Map chunks = new HashMap<>(); for (Vector3 b : blocks) { @@ -987,26 +987,24 @@ public void sendBlocks(Player[] target, Vector3[] blocks, int flags, boolean opt } if (b instanceof Block) { - 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); + 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); } else { int fullBlock = this.getFullBlock((int) b.x, (int) b.y, (int) b.z); - 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); + 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); } } } else { @@ -1014,49 +1012,31 @@ public void sendBlocks(Player[] target, Vector3[] blocks, int flags, boolean opt if (b == null) { continue; } - + UpdateBlockPacket packet = new UpdateBlockPacket(); if (b instanceof Block) { - 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); + 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); } else { int fullBlock = this.getFullBlock((int) b.x, (int) b.y, (int) b.z); - UpdateBlockPacket.Entry entry = new UpdateBlockPacket.Entry( - (int) b.x, - (int) b.y, - (int) b.z, - fullBlock >> 4, - fullBlock & 0xf, - flags - ); - entries.add(entry); + 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); } + packets.add(packet); } } - - List packets = new ArrayList<>(); - - for (UpdateBlockPacket.Entry entry : entries) { - UpdateBlockPacket packet = new UpdateBlockPacket(); - packet.x = entry.x; - packet.y = entry.y; - packet.z = entry.z; - - packet.blockId = entry.blockId; - packet.blockData = entry.blockData; - - packet.flags = entry.flags; - - packets.add(packet); - } - - this.getServer().batchPackets(target, packets.stream().toArray(DataPacket[]::new)); + this.server.batchPackets(target, packets.toArray(new DataPacket[packets.size()])); } public void clearCache() { diff --git a/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java b/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java index a9da7dc6b6..debadf376e 100644 --- a/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/UpdateBlockPacket.java @@ -18,12 +18,10 @@ public class UpdateBlockPacket extends DataPacket { public static final int FLAG_ALL_PRIORITY = (FLAG_ALL | FLAG_PRIORITY); public int x; - public int y; public int z; - + public int y; public int blockId; public int blockData; - public int flags; @Override @@ -39,10 +37,9 @@ public void decode() { @Override public void encode() { this.reset(); - this.putBlockVector3(this.x, this.y, this.z); - - this.putUnsignedVarInt(this.blockId); - this.putUnsignedVarInt((this.flags << 4) | this.blockData); + this.putBlockVector3(x, y, z); + this.putUnsignedVarInt(blockId); + this.putUnsignedVarInt((0xb << 4) | blockData & 0xf); } public static class Entry { From d7ee38b2f184b4729c3bf501ec66db81f1b59d15 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Tue, 19 Sep 2017 21:01:40 +0200 Subject: [PATCH 078/175] fixed buttons image, formatting --- src/main/java/cn/nukkit/Player.java | 20 +- src/main/java/cn/nukkit/PlayerFood.java | 62 ++-- src/main/java/cn/nukkit/Server.java | 3 +- src/main/java/cn/nukkit/api/API.java | 184 +++++----- src/main/java/cn/nukkit/block/Block.java | 28 +- src/main/java/cn/nukkit/block/BlockAnvil.java | 4 +- .../java/cn/nukkit/block/BlockEndGateway.java | 1 - .../nukkit/block/BlockGlassPaneStained.java | 2 +- .../cn/nukkit/block/BlockGlassStained.java | 2 +- src/main/java/cn/nukkit/block/BlockRail.java | 1 - .../cn/nukkit/block/BlockRailActivator.java | 8 +- .../cn/nukkit/block/BlockRailDetector.java | 2 +- .../cn/nukkit/block/BlockRailPowered.java | 26 +- .../cn/nukkit/blockentity/BlockEntity.java | 6 +- .../nukkit/blockentity/BlockEntityChest.java | 4 +- .../blockentity/BlockEntityFurnace.java | 3 +- .../nukkit/blockentity/BlockEntityHopper.java | 2 +- .../blockentity/BlockEntityItemFrame.java | 4 +- .../java/cn/nukkit/command/CommandReader.java | 6 +- .../nukkit/command/data/CommandParameter.java | 8 +- .../command/defaults/DifficultyCommand.java | 2 +- .../command/defaults/EnchantCommand.java | 2 +- .../nukkit/command/defaults/TitleCommand.java | 2 +- src/main/java/cn/nukkit/entity/Entity.java | 2 +- .../cn/nukkit/entity/item/EntityBoat.java | 6 +- .../event/entity/EntityVehicleEnterEvent.java | 2 +- .../player/PlayerFormRespondedEvent.java | 5 +- .../cn/nukkit/form/element/ElementButton.java | 13 +- .../form/element/ElementButtonImageData.java | 2 +- .../nukkit/form/element/ElementDropdown.java | 22 +- .../cn/nukkit/form/element/ElementInput.java | 12 +- .../cn/nukkit/form/element/ElementLabel.java | 2 +- .../cn/nukkit/form/element/ElementSlider.java | 12 +- .../form/element/ElementStepSlider.java | 22 +- .../cn/nukkit/form/element/ElementToggle.java | 5 +- .../form/response/FormResponseCustom.java | 26 +- .../form/response/FormResponseData.java | 3 +- .../form/response/FormResponseModal.java | 3 +- .../form/response/FormResponseSimple.java | 3 +- .../cn/nukkit/form/window/FormWindow.java | 2 + .../nukkit/form/window/FormWindowCustom.java | 42 +-- .../nukkit/form/window/FormWindowModal.java | 11 +- .../nukkit/form/window/FormWindowSimple.java | 25 +- src/main/java/cn/nukkit/item/Item.java | 6 +- .../cn/nukkit/level/format/anvil/Anvil.java | 2 +- .../format/generic/EmptyChunkSection.java | 1 - .../nukkit/level/format/leveldb/LevelDB.java | 4 +- .../level/particle/FloatingTextParticle.java | 4 +- src/main/java/cn/nukkit/math/Angle.java | 264 +++++++-------- src/main/java/cn/nukkit/math/NukkitMath.java | 2 +- src/main/java/cn/nukkit/network/Network.java | 2 +- .../protocol/AvailableCommandsPacket.java | 33 +- .../network/protocol/BossEventPacket.java | 4 +- .../protocol/CommandRequestPacket.java | 3 - .../network/protocol/ContainerOpenPacket.java | 2 +- .../protocol/ContainerSetDataPacket.java | 2 +- .../network/protocol/LevelEventPacket.java | 8 +- .../nukkit/network/protocol/LoginPacket.java | 5 +- .../network/protocol/MovePlayerPacket.java | 4 +- .../network/protocol/TransferPacket.java | 4 +- .../protocol/UpdateEquipmentPacket.java | 1 - .../resourcepacks/AbstractResourcePack.java | 2 +- .../cn/nukkit/scheduler/NukkitRunnable.java | 10 +- .../cn/nukkit/scheduler/ServerScheduler.java | 18 +- .../java/cn/nukkit/utils/BinaryStream.java | 19 +- .../java/cn/nukkit/utils/ClientChainData.java | 318 +++++++++--------- .../java/cn/nukkit/utils/MinecartType.java | 5 +- src/main/java/cn/nukkit/utils/Rail.java | 25 +- src/main/java/cn/nukkit/utils/VarInt.java | 84 ++--- .../utils/completers/CommandsCompleter.java | 11 +- .../utils/completers/PlayersCompleter.java | 11 +- 71 files changed, 740 insertions(+), 716 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 663a4a092e..60c4ca6e9f 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -1640,11 +1640,11 @@ public boolean onUpdate(int currentTick) { } return true; } - - public void checkInteractNearby(){ + + public void checkInteractNearby() { int interactDistance = isCreative() ? 5 : 3; - if(canInteract(this, interactDistance)){ - if(getEntityPlayerLookingAt(interactDistance) != null){ + if (canInteract(this, interactDistance)) { + if (getEntityPlayerLookingAt(interactDistance) != null) { EntityInteractable onInteract = getEntityPlayerLookingAt(interactDistance); setButtonText(onInteract.getInteractButtonText()); } else { @@ -1655,7 +1655,7 @@ public void checkInteractNearby(){ } } - /** + /** * Returns the Entity the player is looking at currently * * @param maxDistance the maximum distance to check for entities @@ -1663,7 +1663,7 @@ public void checkInteractNearby(){ */ public EntityInteractable getEntityPlayerLookingAt(int maxDistance) { timing.startTiming(); - + EntityInteractable entity = null; // just a fix because player MAY not be fully initialized @@ -1692,7 +1692,7 @@ public EntityInteractable getEntityPlayerLookingAt(int maxDistance) { 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 @@ -1703,7 +1703,7 @@ private EntityInteractable getEntityAtPosition(Entity[] nearbyEntities, int x, i } return null; } - + private ArrayList messageQueue = new ArrayList<>(); public void checkNetwork() { @@ -2112,11 +2112,11 @@ public void handleDataPacket(DataPacket packet) { this.dataPacket(dataPacket); break; case ProtocolInfo.PLAYER_INPUT_PACKET: - if(!this.isAlive() || !this.spawned){ + if (!this.isAlive() || !this.spawned) { break; } PlayerInputPacket ipk = (PlayerInputPacket) packet; - if(riding instanceof EntityMinecartAbstract){ + if (riding instanceof EntityMinecartAbstract) { ((EntityMinecartEmpty) riding).setCurrentSpeed(ipk.motionY); } break; diff --git a/src/main/java/cn/nukkit/PlayerFood.java b/src/main/java/cn/nukkit/PlayerFood.java index 9ab78ac94e..166ba513b4 100644 --- a/src/main/java/cn/nukkit/PlayerFood.java +++ b/src/main/java/cn/nukkit/PlayerFood.java @@ -136,37 +136,37 @@ public void sendFoodLevel(int foodLevel) { public void update(int tickDiff) { if (!this.getPlayer().isFoodEnabled()) return; - if (this.getPlayer().isAlive()) { - int diff = Server.getInstance().getDifficulty(); - if (this.getLevel() > 17) { - this.foodTickTimer += tickDiff; - if (this.foodTickTimer >= 80) { - if (this.getPlayer().getHealth() < this.getPlayer().getMaxHealth()) { - EntityRegainHealthEvent ev = new EntityRegainHealthEvent(this.getPlayer(), 1, EntityRegainHealthEvent.CAUSE_EATING); - this.getPlayer().heal(ev); - //this.updateFoodExpLevel(3); - } - this.foodTickTimer = 0; - } - } else if (this.getLevel() == 0) { - this.foodTickTimer += tickDiff; - if (this.foodTickTimer >= 80) { - EntityDamageEvent ev = new EntityDamageEvent(this.getPlayer(), DamageCause.VOID, 1); - float now = this.getPlayer().getHealth(); - if (diff == 1) { - if (now > 10) this.getPlayer().attack(ev); - } else if (diff == 2) { - if (now > 1) this.getPlayer().attack(ev); - } else { - this.getPlayer().attack(ev); - } - - this.foodTickTimer = 0; - } - } - if (this.getPlayer().hasEffect(Effect.HUNGER)) { - this.updateFoodExpLevel(0.025); - } + if (this.getPlayer().isAlive()) { + int diff = Server.getInstance().getDifficulty(); + if (this.getLevel() > 17) { + this.foodTickTimer += tickDiff; + if (this.foodTickTimer >= 80) { + if (this.getPlayer().getHealth() < this.getPlayer().getMaxHealth()) { + EntityRegainHealthEvent ev = new EntityRegainHealthEvent(this.getPlayer(), 1, EntityRegainHealthEvent.CAUSE_EATING); + this.getPlayer().heal(ev); + //this.updateFoodExpLevel(3); + } + this.foodTickTimer = 0; + } + } else if (this.getLevel() == 0) { + this.foodTickTimer += tickDiff; + if (this.foodTickTimer >= 80) { + EntityDamageEvent ev = new EntityDamageEvent(this.getPlayer(), DamageCause.VOID, 1); + float now = this.getPlayer().getHealth(); + if (diff == 1) { + if (now > 10) this.getPlayer().attack(ev); + } else if (diff == 2) { + if (now > 1) this.getPlayer().attack(ev); + } else { + this.getPlayer().attack(ev); + } + + this.foodTickTimer = 0; + } + } + if (this.getPlayer().hasEffect(Effect.HUNGER)) { + this.updateFoodExpLevel(0.025); + } } } diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index 81add9a976..04f3e9c828 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -1891,8 +1891,9 @@ public boolean shouldSavePlayerData() { /** * Checks the current thread against the expected primary thread for the server. - * + *

* Note: this method should not be used to indicate the current synchronized state of the runtime. A current thread matching the main thread indicates that it is synchronized, but a mismatch does not preclude the same assumption. + * * @return true if the current thread matches the expected primary thread, false otherwise */ public boolean isPrimaryThread() { diff --git a/src/main/java/cn/nukkit/api/API.java b/src/main/java/cn/nukkit/api/API.java index e906d2b0b0..70f7369ecc 100644 --- a/src/main/java/cn/nukkit/api/API.java +++ b/src/main/java/cn/nukkit/api/API.java @@ -11,9 +11,9 @@ /** * Describes an API element. * + * @author Lin Mulan, Nukkit Project * @see Usage * @see Definition - * @author Lin Mulan, Nukkit Project */ @Retention(RetentionPolicy.SOURCE) @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE}) @@ -21,110 +21,110 @@ @SuppressWarnings("unused") public @interface API { - /** - * Indicates the level of stability of an API element. - * The stability also describes when to use this API element. - * - * @return The stability - * @see Usage - */ - Usage usage(); - - /** - * Indicates definition or the platforms this API element supports. - * - * @return The definition - * @see Definition - */ - Definition definition(); - - /** - * Enum constant for API usage. Indicates when to use this API element. - * - * @see #DEPRECATED - * @see #INCUBATING - * @see #BLEEDING - * @see #EXPERIMENTAL - * @see #MAINTAINED - * @see #STABLE - */ - enum Usage{ - - /** - * Should no longer be used, might disappear in the next minor release. - */ - DEPRECATED, - /** - * Intended for features in drafts. Should only be used for tests. + * Indicates the level of stability of an API element. + * The stability also describes when to use this API element. * - *

Might contains notable new features, but will be moved to a new package before remarking to {@link #BLEEDING}. - * Could be unsafe, might be removed without prior notice. Warnings will be send if used. + * @return The stability + * @see Usage */ - INCUBATING, + Usage usage(); /** - * Intended for features in early development. Should only be used for tests. + * Indicates definition or the platforms this API element supports. * - *

Might be unwrapped, unsafe or have unchecked parameters. - * Further contribution was demanded to enhance, strengthen or simplify before remarking to {@link #EXPERIMENTAL}. - * Might be removed or modified without prior notice. - */ - BLEEDING, - - /** - * Intended for new, experimental features where we are looking for feedback. - * At least stable for development. - * - *

Use with caution, might be remarked to {@link #MAINTAINED} or {@link #STABLE} in the future, - * but also might be removed without prior notice. - */ - EXPERIMENTAL, - - /** - * Intended for features that was tested, documented and at least stable for production use. - * - *

These features will not be modified in a backwards-incompatible way for at least next minor release - * of the current major version. Will be remarked to {@link #DEPRECATED} first if scheduled for removal. - */ - MAINTAINED, - - /** - * Intended for features that was tested, documented and is preferred in production use. - * - *

Will not be changed in a backwards-incompatible way in the current version. - */ - STABLE - } - - /** - * Enum constant for API definition. Indicates which client platform this API element supports. - * - * @see #INTERNAL - * @see #PLATFORM_NATIVE - * @see #UNIVERSAL - */ - enum Definition{ - - /** - * Intended for features should only be used by Nukkit itself. - * Should not be used in production. + * @return The definition + * @see Definition */ - INTERNAL, + Definition definition(); /** - * Intended for features only available on one or several client platforms. + * Enum constant for API usage. Indicates when to use this API element. * - *

By using {@code PLATFORM_NATIVE} features, program will lose some cross-platform features provided. - * Might not available in some client platforms. Read the documents carefully before using this API element. + * @see #DEPRECATED + * @see #INCUBATING + * @see #BLEEDING + * @see #EXPERIMENTAL + * @see #MAINTAINED + * @see #STABLE */ - PLATFORM_NATIVE, + enum Usage { + + /** + * Should no longer be used, might disappear in the next minor release. + */ + DEPRECATED, + + /** + * Intended for features in drafts. Should only be used for tests. + *

+ *

Might contains notable new features, but will be moved to a new package before remarking to {@link #BLEEDING}. + * Could be unsafe, might be removed without prior notice. Warnings will be send if used. + */ + INCUBATING, + + /** + * Intended for features in early development. Should only be used for tests. + *

+ *

Might be unwrapped, unsafe or have unchecked parameters. + * Further contribution was demanded to enhance, strengthen or simplify before remarking to {@link #EXPERIMENTAL}. + * Might be removed or modified without prior notice. + */ + BLEEDING, + + /** + * Intended for new, experimental features where we are looking for feedback. + * At least stable for development. + *

+ *

Use with caution, might be remarked to {@link #MAINTAINED} or {@link #STABLE} in the future, + * but also might be removed without prior notice. + */ + EXPERIMENTAL, + + /** + * Intended for features that was tested, documented and at least stable for production use. + *

+ *

These features will not be modified in a backwards-incompatible way for at least next minor release + * of the current major version. Will be remarked to {@link #DEPRECATED} first if scheduled for removal. + */ + MAINTAINED, + + /** + * Intended for features that was tested, documented and is preferred in production use. + *

+ *

Will not be changed in a backwards-incompatible way in the current version. + */ + STABLE + } /** - * Intended for features implemented in all client platforms. + * Enum constant for API definition. Indicates which client platform this API element supports. * - *

Preferred to use for production use, but sometimes be lack of platform-native features. + * @see #INTERNAL + * @see #PLATFORM_NATIVE + * @see #UNIVERSAL */ - UNIVERSAL - } + enum Definition { + + /** + * Intended for features should only be used by Nukkit itself. + * Should not be used in production. + */ + INTERNAL, + + /** + * Intended for features only available on one or several client platforms. + *

+ *

By using {@code PLATFORM_NATIVE} features, program will lose some cross-platform features provided. + * Might not available in some client platforms. Read the documents carefully before using this API element. + */ + PLATFORM_NATIVE, + + /** + * Intended for features implemented in all client platforms. + *

+ *

Preferred to use for production use, but sometimes be lack of platform-native features. + */ + UNIVERSAL + } } diff --git a/src/main/java/cn/nukkit/block/Block.java b/src/main/java/cn/nukkit/block/Block.java index db0a0427bd..d81954935f 100644 --- a/src/main/java/cn/nukkit/block/Block.java +++ b/src/main/java/cn/nukkit/block/Block.java @@ -843,7 +843,7 @@ private static double toolBreakTimeBonus0( } private static double speedBonusByEfficiencyLore0(int efficiencyLoreLevel) { - if(efficiencyLoreLevel == 0) return 0; + if (efficiencyLoreLevel == 0) return 0; return efficiencyLoreLevel * efficiencyLoreLevel + 1; } @@ -852,20 +852,20 @@ private static double speedRateByHasteLore0(int hasteLoreLevel) { } private static int toolType0(Item item) { - if(item.isSword()) return ItemTool.TYPE_SWORD ; - if(item.isShovel()) return ItemTool.TYPE_SHOVEL ; - if(item.isPickaxe()) return ItemTool.TYPE_PICKAXE ; - if(item.isAxe()) return ItemTool.TYPE_AXE ; - if(item.isShears()) return ItemTool.TYPE_SHEARS ; + if (item.isSword()) return ItemTool.TYPE_SWORD; + if (item.isShovel()) return ItemTool.TYPE_SHOVEL; + if (item.isPickaxe()) return ItemTool.TYPE_PICKAXE; + if (item.isAxe()) return ItemTool.TYPE_AXE; + if (item.isShears()) return ItemTool.TYPE_SHEARS; return ItemTool.TYPE_NONE; } private static boolean correctTool0(int blockToolType, Item item) { - return (blockToolType == ItemTool.TYPE_SWORD && item.isSword() ) || - (blockToolType == ItemTool.TYPE_SHOVEL && item.isShovel() ) || - (blockToolType == ItemTool.TYPE_PICKAXE && item.isPickaxe() ) || - (blockToolType == ItemTool.TYPE_AXE && item.isAxe() ) || - (blockToolType == ItemTool.TYPE_SHEARS && item.isShears() ) || + return (blockToolType == ItemTool.TYPE_SWORD && item.isSword()) || + (blockToolType == ItemTool.TYPE_SHOVEL && item.isShovel()) || + (blockToolType == ItemTool.TYPE_PICKAXE && item.isPickaxe()) || + (blockToolType == ItemTool.TYPE_AXE && item.isAxe()) || + (blockToolType == ItemTool.TYPE_SHEARS && item.isShears()) || blockToolType == ItemTool.TYPE_NONE; } @@ -876,11 +876,11 @@ private static double breakTime0(double blockHardness, boolean correctTool, bool double baseTime = ((correctTool || canHarvestWithHand) ? 1.5 : 5.0) * blockHardness; double speed = 1.0 / baseTime; boolean isWoolBlock = blockId == Block.WOOL, isCobweb = blockId == Block.COBWEB; - if(correctTool) speed *= toolBreakTimeBonus0(toolType, toolTier, isWoolBlock, isCobweb); + if (correctTool) speed *= toolBreakTimeBonus0(toolType, toolTier, isWoolBlock, isCobweb); speed += speedBonusByEfficiencyLore0(efficiencyLoreLevel); speed *= speedRateByHasteLore0(hasteEffectLevel); - if(insideOfWaterWithoutAquaAffinity) speed *= 0.2; - if(outOfWaterButNotOnGround) speed *= 0.2; + if (insideOfWaterWithoutAquaAffinity) speed *= 0.2; + if (outOfWaterButNotOnGround) speed *= 0.2; return 1.0 / speed; } diff --git a/src/main/java/cn/nukkit/block/BlockAnvil.java b/src/main/java/cn/nukkit/block/BlockAnvil.java index 7759da99e6..a33ed35f50 100644 --- a/src/main/java/cn/nukkit/block/BlockAnvil.java +++ b/src/main/java/cn/nukkit/block/BlockAnvil.java @@ -76,9 +76,9 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl int[] faces = {1, 2, 3, 0}; this.meta = faces[player != null ? player.getDirection().getHorizontalIndex() : 0]; if (damage >= 4 && damage <= 7) { - this.meta |= 0x04; + this.meta |= 0x04; } else if (damage >= 8 && damage <= 11) { - this.meta |= 0x08; + this.meta |= 0x08; } this.getLevel().setBlock(block, this, true); return true; diff --git a/src/main/java/cn/nukkit/block/BlockEndGateway.java b/src/main/java/cn/nukkit/block/BlockEndGateway.java index 87038f41d7..c87a0ade38 100644 --- a/src/main/java/cn/nukkit/block/BlockEndGateway.java +++ b/src/main/java/cn/nukkit/block/BlockEndGateway.java @@ -4,7 +4,6 @@ import cn.nukkit.utils.BlockColor; /** - * * @author PikyCZ */ public class BlockEndGateway extends BlockSolid { diff --git a/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java b/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java index 184cec0bcd..7bc6c771cc 100644 --- a/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java +++ b/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java @@ -14,7 +14,7 @@ public BlockGlassPaneStained() { public BlockGlassPaneStained(int meta) { super(meta); } - + @Override public int getId() { return STAINED_GLASS_PANE; diff --git a/src/main/java/cn/nukkit/block/BlockGlassStained.java b/src/main/java/cn/nukkit/block/BlockGlassStained.java index 113f094994..a00e545cd1 100644 --- a/src/main/java/cn/nukkit/block/BlockGlassStained.java +++ b/src/main/java/cn/nukkit/block/BlockGlassStained.java @@ -7,7 +7,7 @@ * Created by CreeperFace on 7.8.2017. */ public class BlockGlassStained extends BlockGlass { - + public BlockGlassStained() { this(0); } diff --git a/src/main/java/cn/nukkit/block/BlockRail.java b/src/main/java/cn/nukkit/block/BlockRail.java index debed246f1..54119ae2e6 100644 --- a/src/main/java/cn/nukkit/block/BlockRail.java +++ b/src/main/java/cn/nukkit/block/BlockRail.java @@ -1,7 +1,6 @@ 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; diff --git a/src/main/java/cn/nukkit/block/BlockRailActivator.java b/src/main/java/cn/nukkit/block/BlockRailActivator.java index c7c33339a9..e0e91bf35f 100644 --- a/src/main/java/cn/nukkit/block/BlockRailActivator.java +++ b/src/main/java/cn/nukkit/block/BlockRailActivator.java @@ -57,9 +57,9 @@ public int onUpdate(int type) { /** * Check the surrounding of the rail * - * @param pos The rail position + * @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 + * @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) { @@ -69,7 +69,7 @@ protected boolean checkSurrounding(Vector3 pos, boolean relative, int power) { int dx = pos.getFloorX(); int dy = pos.getFloorY(); int dz = pos.getFloorZ(); - + BlockRail block; Block block2 = level.getBlock(new Vector3(dx, dy, dz)); @@ -153,7 +153,7 @@ protected boolean canPowered(Vector3 pos, Rail.Orientation state, int power, boo } Rail.Orientation base = ((BlockRailActivator) block).getOrientation(); - + return (state != Rail.Orientation.STRAIGHT_EAST_WEST || base != Rail.Orientation.STRAIGHT_NORTH_SOUTH && base != Rail.Orientation.ASCENDING_NORTH diff --git a/src/main/java/cn/nukkit/block/BlockRailDetector.java b/src/main/java/cn/nukkit/block/BlockRailDetector.java index 563821914c..83818621d2 100644 --- a/src/main/java/cn/nukkit/block/BlockRailDetector.java +++ b/src/main/java/cn/nukkit/block/BlockRailDetector.java @@ -52,7 +52,7 @@ public int getStrongPower(BlockFace side) { @Override public int onUpdate(int type) { - if (type == Level.BLOCK_UPDATE_SCHEDULED) { + if (type == Level.BLOCK_UPDATE_SCHEDULED) { updateState(); return type; } diff --git a/src/main/java/cn/nukkit/block/BlockRailPowered.java b/src/main/java/cn/nukkit/block/BlockRailPowered.java index bdd3966779..3350d60728 100644 --- a/src/main/java/cn/nukkit/block/BlockRailPowered.java +++ b/src/main/java/cn/nukkit/block/BlockRailPowered.java @@ -5,7 +5,7 @@ import cn.nukkit.utils.Rail; /** - * Created by Snake1999 on 2016/1/11. + * Created by Snake1999 on 2016/1/11. * Contributed by: larryTheCoder on 2017/7/18. *

* Nukkit Project, @@ -62,9 +62,9 @@ public int onUpdate(int type) { /** * Check the surrounding of the rail * - * @param pos The rail position + * @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 + * @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) { @@ -86,7 +86,7 @@ protected boolean checkSurrounding(Vector3 pos, boolean relative, int power) { } else { return false; } - + // Used to check if the next ascending rail should be what Rail.Orientation base = null; boolean onStraight = true; @@ -150,7 +150,7 @@ protected boolean checkSurrounding(Vector3 pos, boolean relative, int power) { // 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); @@ -168,14 +168,14 @@ protected boolean canPowered(Vector3 pos, Rail.Orientation state, int power, boo // 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) + 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/blockentity/BlockEntity.java b/src/main/java/cn/nukkit/blockentity/BlockEntity.java index 58c72dbf91..5d188805e7 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntity.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntity.java @@ -143,13 +143,13 @@ public void saveNBT() { this.namedTag.putInt("z", (int) this.getZ()); } - public CompoundTag getCleanedNBT(){ + public CompoundTag getCleanedNBT() { this.saveNBT(); CompoundTag tag = this.namedTag.clone(); tag.remove("x").remove("y").remove("z").remove("id"); - if(tag.getTags().size() > 0){ + if (tag.getTags().size() > 0) { return tag; - }else{ + } else { return null; } } diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java b/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java index 09ead3e371..8f5bb96edc 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java @@ -38,7 +38,7 @@ public BlockEntityChest(FullChunk chunk, CompoundTag nbt) { /* for (int i = 0; i < this.getSize(); i++) { this.inventory.setItem(i, this.getItem(i)); } */ - + ListTag list = (ListTag) this.namedTag.getList("Items"); for (CompoundTag compound : list.getAll()) { Item item = NBTIO.getItemHelper(compound); @@ -104,7 +104,7 @@ public Item getItem(int index) { @Override public void setItem(int index, Item item) { int i = this.getSlotIndex(index); - + CompoundTag d = NBTIO.putItemHelper(item, index); // If item is air or count less than 0, remove the item from the "Items" list diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java b/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java index ecb974051e..6e3265c627 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntityFurnace.java @@ -263,7 +263,8 @@ public boolean onUpdate() { if (windowId > 0) { ContainerSetDataPacket pk = new ContainerSetDataPacket(); pk.windowId = windowId; - pk.property = ContainerSetDataPacket.PROPERTY_FURNACE_TICK_COUNT;; + pk.property = ContainerSetDataPacket.PROPERTY_FURNACE_TICK_COUNT; + ; pk.value = cookTime; player.dataPacket(pk); diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java b/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java index 9bdc5fd129..000a378045 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntityHopper.java @@ -146,7 +146,7 @@ public boolean onUpdate() { if (this.closed) { return false; } - + this.transferCooldown--; if (!this.isOnTransferCooldown()) { diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityItemFrame.java b/src/main/java/cn/nukkit/blockentity/BlockEntityItemFrame.java index ef5aad0f82..222a1b0490 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntityItemFrame.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntityItemFrame.java @@ -96,8 +96,8 @@ public CompoundTag getSpawnCompound() { .putInt("z", (int) this.z) .putCompound("Item", item ? NBTIO.putItemHelper(new ItemBlock(new BlockAir())) : NBTItem) .putByte("ItemRotation", item ? 0 : this.getItemRotation()); - // TODO: This crashes the client, why? - // .putFloat("ItemDropChance", this.getItemDropChance()); + // TODO: This crashes the client, why? + // .putFloat("ItemDropChance", this.getItemDropChance()); } public int getAnalogOutput() { diff --git a/src/main/java/cn/nukkit/command/CommandReader.java b/src/main/java/cn/nukkit/command/CommandReader.java index 037750dbee..4586c6ce5c 100644 --- a/src/main/java/cn/nukkit/command/CommandReader.java +++ b/src/main/java/cn/nukkit/command/CommandReader.java @@ -37,7 +37,7 @@ public CommandReader() { this.reader = new ConsoleReader(); reader.setPrompt("> "); instance = this; - + reader.addCompleter(new PlayersCompleter()); // Add player TAB completer reader.addCompleter(new CommandsCompleter()); // Add command TAB completer } catch (IOException e) { @@ -54,11 +54,11 @@ public String readLine() { } return null; } - + public void run() { Long lastLine = System.currentTimeMillis(); String line; - + try { while ((line = reader.readLine()) != null) { if (Server.getInstance().getConsoleSender() == null || Server.getInstance().getPluginManager() == null) { diff --git a/src/main/java/cn/nukkit/command/data/CommandParameter.java b/src/main/java/cn/nukkit/command/data/CommandParameter.java index 281115bab6..a3fe91c979 100644 --- a/src/main/java/cn/nukkit/command/data/CommandParameter.java +++ b/src/main/java/cn/nukkit/command/data/CommandParameter.java @@ -41,25 +41,25 @@ public CommandParameter(String name) { this(name, false); } - public CommandParameter(String name, boolean optional, String enumType){ + public CommandParameter(String name, boolean optional, String enumType) { this.name = name; this.type = ARG_TYPE_STRING_ENUM; this.optional = optional; this.enum_type = enumType; } - public CommandParameter(String name, boolean optional, String[] enumValues){ + public CommandParameter(String name, boolean optional, String[] enumValues) { this.name = name; this.type = ARG_TYPE_STRING_ENUM; this.optional = optional; this.enum_values = enumValues; } - public CommandParameter(String name, String enumType){ + public CommandParameter(String name, String enumType) { this(name, false, enumType); } - public CommandParameter(String name, String[] enumValues){ + public CommandParameter(String name, String[] enumValues) { this(name, false, enumValues); } diff --git a/src/main/java/cn/nukkit/command/defaults/DifficultyCommand.java b/src/main/java/cn/nukkit/command/defaults/DifficultyCommand.java index d2c75f1d6d..40d6800748 100644 --- a/src/main/java/cn/nukkit/command/defaults/DifficultyCommand.java +++ b/src/main/java/cn/nukkit/command/defaults/DifficultyCommand.java @@ -24,7 +24,7 @@ public DifficultyCommand(String name) { }); this.commandParameters.put("byString", new CommandParameter[]{ new CommandParameter("difficulty", new String[]{"peaceful", "p", "easy", "e", - "normal", "n", "hard", "h"}) + "normal", "n", "hard", "h"}) }); } diff --git a/src/main/java/cn/nukkit/command/defaults/EnchantCommand.java b/src/main/java/cn/nukkit/command/defaults/EnchantCommand.java index 0ae775b8de..868f23c44c 100644 --- a/src/main/java/cn/nukkit/command/defaults/EnchantCommand.java +++ b/src/main/java/cn/nukkit/command/defaults/EnchantCommand.java @@ -71,7 +71,7 @@ public boolean execute(CommandSender sender, String commandLabel, String[] args) } public int getIdByName(String value) throws NumberFormatException { - switch (value){ + switch (value) { case "protection": return 0; case "fire_protection": diff --git a/src/main/java/cn/nukkit/command/defaults/TitleCommand.java b/src/main/java/cn/nukkit/command/defaults/TitleCommand.java index c0b91ccd1c..ab09ce5d13 100644 --- a/src/main/java/cn/nukkit/command/defaults/TitleCommand.java +++ b/src/main/java/cn/nukkit/command/defaults/TitleCommand.java @@ -78,7 +78,7 @@ public boolean execute(CommandSender sender, String commandLabel, String[] args) sender.sendMessage(new TranslationContainer("commands.generic.usage", this.usageMessage)); return false; } - } else if (args.length == 3){ + } else if (args.length == 3) { switch (args[1].toLowerCase()) { case "title": player.sendTitle(args[2]); diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java index 5723656499..482cf4c52b 100644 --- a/src/main/java/cn/nukkit/entity/Entity.java +++ b/src/main/java/cn/nukkit/entity/Entity.java @@ -1097,7 +1097,7 @@ public boolean entityBaseTick(int tickDiff) { if (this.inPortalTicks == 80) { EntityPortalEnterEvent ev = new EntityPortalEnterEvent(this, PortalType.NETHER); getServer().getPluginManager().callEvent(ev); - + //TODO: teleport } diff --git a/src/main/java/cn/nukkit/entity/item/EntityBoat.java b/src/main/java/cn/nukkit/entity/item/EntityBoat.java index 8ec0a0685c..8c940db809 100644 --- a/src/main/java/cn/nukkit/entity/item/EntityBoat.java +++ b/src/main/java/cn/nukkit/entity/item/EntityBoat.java @@ -64,7 +64,7 @@ protected float getGravity() { public float getBaseOffset() { return 0.35F; } - + @Override public int getNetworkId() { return NETWORK_ID; @@ -133,7 +133,7 @@ public boolean attack(EntityDamageEvent source) { } } } - + return true; } @@ -167,7 +167,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/event/entity/EntityVehicleEnterEvent.java b/src/main/java/cn/nukkit/event/entity/EntityVehicleEnterEvent.java index 12dfe408b7..0a3b505cc4 100644 --- a/src/main/java/cn/nukkit/event/entity/EntityVehicleEnterEvent.java +++ b/src/main/java/cn/nukkit/event/entity/EntityVehicleEnterEvent.java @@ -12,7 +12,7 @@ public class EntityVehicleEnterEvent extends EntityEvent implements Cancellable public static HandlerList getHandlers() { return handlers; } - + private final EntityVehicle vehicle; public EntityVehicleEnterEvent(Entity entity, EntityVehicle vehicle) { diff --git a/src/main/java/cn/nukkit/event/player/PlayerFormRespondedEvent.java b/src/main/java/cn/nukkit/event/player/PlayerFormRespondedEvent.java index c34d4a8ad1..d3eee72225 100644 --- a/src/main/java/cn/nukkit/event/player/PlayerFormRespondedEvent.java +++ b/src/main/java/cn/nukkit/event/player/PlayerFormRespondedEvent.java @@ -8,6 +8,7 @@ public class PlayerFormRespondedEvent extends PlayerEvent { private static final HandlerList handlers = new HandlerList(); + public static HandlerList getHandlers() { return handlers; } @@ -23,7 +24,7 @@ public PlayerFormRespondedEvent(Player player, int formID, FormWindow window) { this.window = window; } - public int getFormID(){ + public int getFormID() { return this.formID; } @@ -41,7 +42,7 @@ public FormResponse getResponse() { /** * Defines if player closed the window or submitted it */ - public boolean wasClosed(){ + public boolean wasClosed() { return window.wasClosed(); } diff --git a/src/main/java/cn/nukkit/form/element/ElementButton.java b/src/main/java/cn/nukkit/form/element/ElementButton.java index c896f39d87..b1e05692d4 100644 --- a/src/main/java/cn/nukkit/form/element/ElementButton.java +++ b/src/main/java/cn/nukkit/form/element/ElementButton.java @@ -3,18 +3,19 @@ public class ElementButton { public String text = ""; - public ElementButtonImageData data; + public ElementButtonImageData image; - public ElementButton(String text){ + public ElementButton(String text) { this.text = text; } - public ElementButton(String text, ElementButtonImageData data){ + + public ElementButton(String text, ElementButtonImageData image) { this.text = text; - if (!data.data.isEmpty() && !data.type.isEmpty()) this.data = data; + if (!image.data.isEmpty() && !image.type.isEmpty()) this.image = image; } - public void addImage(ElementButtonImageData data){ - if (!data.data.isEmpty() && !data.type.isEmpty()) this.data = data; + public void addImage(ElementButtonImageData image) { + if (!image.data.isEmpty() && !image.type.isEmpty()) this.image = image; } } diff --git a/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java b/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java index a39de15286..fec2ad006e 100644 --- a/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java +++ b/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java @@ -8,7 +8,7 @@ public class ElementButtonImageData { public String type; public String data; - public ElementButtonImageData(String type, 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 index 2cf8623149..647e15c07e 100644 --- a/src/main/java/cn/nukkit/form/element/ElementDropdown.java +++ b/src/main/java/cn/nukkit/form/element/ElementDropdown.java @@ -9,28 +9,32 @@ public class ElementDropdown extends Element { public ArrayList options; public int defaultOptionIndex = 0; - public ElementDropdown(String text){ - this (text, new ArrayList<>()); + public ElementDropdown(String text) { + this(text, new ArrayList<>()); } - public ElementDropdown(String text, ArrayList options){ - this (text, options, 0); + + public ElementDropdown(String text, ArrayList options) { + this(text, options, 0); } - public ElementDropdown(String text, ArrayList options, int defaultOption){ + + public ElementDropdown(String text, ArrayList options, int defaultOption) { this.text = text; this.options = options; this.defaultOptionIndex = defaultOption; } - public void setDefaultOptionIndex(int index){ + public void setDefaultOptionIndex(int index) { if (index >= options.size()) return; this.defaultOptionIndex = index; } - public void addOption(String option){ + + public void addOption(String option) { addOption(option, false); } - public void addOption(String option, boolean isDefault){ + + public void addOption(String option, boolean isDefault) { options.add(option); - if (isDefault) this.defaultOptionIndex = options.size()-1; + 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 index aa36d17345..ad8407ace8 100644 --- a/src/main/java/cn/nukkit/form/element/ElementInput.java +++ b/src/main/java/cn/nukkit/form/element/ElementInput.java @@ -7,13 +7,15 @@ public class ElementInput extends Element { public String placeholder = ""; public String defaultText = ""; - public ElementInput (String text){ - this (text, ""); + public ElementInput(String text) { + this(text, ""); } - public ElementInput (String text, String placeholder){ - this (text, placeholder, ""); + + public ElementInput(String text, String placeholder) { + this(text, placeholder, ""); } - public ElementInput (String text, String placeholder, String defaultText){ + + 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 index 10725d3274..a69e58c233 100644 --- a/src/main/java/cn/nukkit/form/element/ElementLabel.java +++ b/src/main/java/cn/nukkit/form/element/ElementLabel.java @@ -5,7 +5,7 @@ public class ElementLabel extends Element { public String type = "label"; public String text = ""; - public ElementLabel (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 index 8336707e7b..1513ec424f 100644 --- a/src/main/java/cn/nukkit/form/element/ElementSlider.java +++ b/src/main/java/cn/nukkit/form/element/ElementSlider.java @@ -9,13 +9,15 @@ public class ElementSlider extends Element { 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) { + 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) { + this(text, min, max, step, -1f); } - public ElementSlider (String text, float min, float max, float step, float defaultValue){ + + 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; diff --git a/src/main/java/cn/nukkit/form/element/ElementStepSlider.java b/src/main/java/cn/nukkit/form/element/ElementStepSlider.java index ceeea63815..aeb72b5bcb 100644 --- a/src/main/java/cn/nukkit/form/element/ElementStepSlider.java +++ b/src/main/java/cn/nukkit/form/element/ElementStepSlider.java @@ -9,28 +9,32 @@ public class ElementStepSlider extends Element { public ArrayList steps; public int defaultStepIndex = 0; - public ElementStepSlider(String text){ - this (text, new ArrayList<>()); + public ElementStepSlider(String text) { + this(text, new ArrayList<>()); } - public ElementStepSlider(String text, ArrayList steps){ - this (text, steps, 0); + + public ElementStepSlider(String text, ArrayList steps) { + this(text, steps, 0); } - public ElementStepSlider(String text, ArrayList steps, int defaultStep){ + + public ElementStepSlider(String text, ArrayList steps, int defaultStep) { this.text = text; this.steps = steps; this.defaultStepIndex = defaultStep; } - public void setDefaultOptionIndex(int index){ + public void setDefaultOptionIndex(int index) { if (index >= steps.size()) return; this.defaultStepIndex = index; } - public void addStep(String step){ + + public void addStep(String step) { addStep(step, false); } - public void addStep(String step, boolean isDefault){ + + public void addStep(String step, boolean isDefault) { steps.add(step); - if (isDefault) this.defaultStepIndex = steps.size()-1; + 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 index e9dffe6b7f..c9f12ba843 100644 --- a/src/main/java/cn/nukkit/form/element/ElementToggle.java +++ b/src/main/java/cn/nukkit/form/element/ElementToggle.java @@ -7,9 +7,10 @@ public class ElementToggle extends Element { public boolean defaultValue = false; public ElementToggle(String text) { - this (text, false); + this(text, false); } - public ElementToggle(String text, boolean defaultValue){ + + public ElementToggle(String text, boolean defaultValue) { this.text = text; this.defaultValue = defaultValue; } diff --git a/src/main/java/cn/nukkit/form/response/FormResponseCustom.java b/src/main/java/cn/nukkit/form/response/FormResponseCustom.java index 1d29f41cec..a905ec9648 100644 --- a/src/main/java/cn/nukkit/form/response/FormResponseCustom.java +++ b/src/main/java/cn/nukkit/form/response/FormResponseCustom.java @@ -1,6 +1,5 @@ package cn.nukkit.form.response; -import java.util.ArrayList; import java.util.HashMap; public class FormResponseCustom extends FormResponse { @@ -12,10 +11,10 @@ public class FormResponseCustom extends FormResponse { private HashMap stepSliderResponses = new HashMap<>(); private HashMap toggleResponses = new HashMap<>(); - public FormResponseCustom (HashMap responses, HashMap dropdownResponses, - HashMap inputResponses, HashMap sliderResponses, - HashMap stepSliderResponses, - HashMap toggleResponses){ + public FormResponseCustom(HashMap responses, HashMap dropdownResponses, + HashMap inputResponses, HashMap sliderResponses, + HashMap stepSliderResponses, + HashMap toggleResponses) { this.responses = responses; this.dropdownResponses = dropdownResponses; this.inputResponses = inputResponses; @@ -24,22 +23,27 @@ public FormResponseCustom (HashMap responses, HashMap content; + public List content; private FormResponseCustom response; - public FormWindowCustom(String title){ - this (title, new ArrayList<>()); + public FormWindowCustom(String title) { + this(title, new ArrayList<>()); } - public FormWindowCustom(String title, ArrayList contents){ - this (title, contents, ""); + + public FormWindowCustom(String title, List contents) { + this(title, contents, ""); } - public FormWindowCustom(String title, ArrayList contents, String icon){ + + public FormWindowCustom(String title, List 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){ + public void addElement(Element element) { content.add(element); } - public void setIcon(String icon){ + + public void setIcon(String icon) { if (!icon.isEmpty()) this.icon = new ElementButtonImageData(ElementButtonImageData.IMAGE_DATA_TYPE_URL, icon); } - public String getJSONData(){ + 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") @@ -47,11 +50,12 @@ public String getJSONData(){ .replace("defaultStepIndex", "default"); } - public FormResponseCustom getResponse(){ + public FormResponseCustom getResponse() { return response; } + public void setResponse(String data) { - if (data.equals("null")){ + if (data.equals("null")) { this.closed = true; return; } @@ -69,7 +73,7 @@ public void setResponse(String data) { HashMap toggleResponses = new HashMap<>(); HashMap responses = new HashMap<>(); - for (String elementData : elementResponses){ + for (String elementData : elementResponses) { if (i >= content.size()) { break; } @@ -80,26 +84,22 @@ public void setResponse(String data) { i++; continue; } - if (e instanceof ElementDropdown){ + 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){ + } else if (e instanceof ElementInput) { inputResponses.put(i, elementData); responses.put(i, elementData); - } - else if (e instanceof ElementSlider){ + } else if (e instanceof ElementSlider) { Float answer = Float.parseFloat(elementData); sliderResponses.put(i, answer); responses.put(i, answer); - } - else if (e instanceof ElementStepSlider){ + } 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){ + } else if (e instanceof ElementToggle) { Boolean answer = Boolean.parseBoolean(elementData); toggleResponses.put(i, answer); responses.put(i, answer); diff --git a/src/main/java/cn/nukkit/form/window/FormWindowModal.java b/src/main/java/cn/nukkit/form/window/FormWindowModal.java index fc72a60155..6e3cfc872c 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowModal.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowModal.java @@ -1,7 +1,7 @@ package cn.nukkit.form.window; -import com.google.gson.Gson; import cn.nukkit.form.response.FormResponseModal; +import com.google.gson.Gson; public class FormWindowModal extends FormWindow { @@ -13,22 +13,23 @@ public class FormWindowModal extends FormWindow { private FormResponseModal response = null; - public FormWindowModal(String title, String content, String trueButonText, String falseButtonText){ + 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(){ + public String getJSONData() { return new Gson().toJson(this); } public FormResponseModal getResponse() { return response; } - public void setResponse(String data){ - if (data.equals("null")){ + + public void setResponse(String data) { + if (data.equals("null")) { closed = true; return; } diff --git a/src/main/java/cn/nukkit/form/window/FormWindowSimple.java b/src/main/java/cn/nukkit/form/window/FormWindowSimple.java index 6410ee1810..58bcdbb704 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowSimple.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowSimple.java @@ -1,54 +1,55 @@ 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 com.google.gson.Gson; import java.util.ArrayList; +import java.util.List; public class FormWindowSimple extends FormWindow { public String type = "form"; public String title = ""; public String content = ""; - public ArrayList buttons; + public List buttons; private FormResponseSimple response = null; - public FormWindowSimple(String title, String content){ - this (title, content, new ArrayList<>()); + public FormWindowSimple(String title, String content) { + this(title, content, new ArrayList<>()); } - public FormWindowSimple(String title, String content, ArrayList buttons){ + + public FormWindowSimple(String title, String content, List buttons) { this.title = title; this.content = content; this.buttons = buttons; } - public void addButton(ElementButton button){ + public void addButton(ElementButton button) { this.buttons.add(button); } - public String getJSONData(){ + public String getJSONData() { return new Gson().toJson(this); } public FormResponseSimple getResponse() { return response; } + public void setResponse(String data) { - if (data.equals("null")){ + if (data.equals("null")) { this.closed = true; return; } int buttonID; try { buttonID = Integer.parseInt(data); - } - catch (Exception e) { + } catch (Exception e) { return; } - if (buttonID >= this.buttons.size()){ + if (buttonID >= this.buttons.size()) { this.response = new FormResponseSimple(buttonID, null); return; } diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java index a786793591..1b41e5a34d 100644 --- a/src/main/java/cn/nukkit/item/Item.java +++ b/src/main/java/cn/nukkit/item/Item.java @@ -1160,7 +1160,7 @@ private static void initCreativeItems() { addCreativeItem(Item.get(Item.IRON_HORSE_ARMOR, 0)); addCreativeItem(Item.get(Item.GOLD_HORSE_ARMOR, 0)); addCreativeItem(Item.get(Item.DIAMOND_HORSE_ARMOR, 0)); - + addCreativeItem(Item.get(Item.SPAWN_EGG, 10)); //Chicken addCreativeItem(Item.get(Item.SPAWN_EGG, 11)); //Cow addCreativeItem(Item.get(Item.SPAWN_EGG, 12)); //Pig @@ -1169,7 +1169,7 @@ private static void initCreativeItems() { addCreativeItem(Item.get(Item.SPAWN_EGG, 16)); //Mooshroom addCreativeItem(Item.get(Item.SPAWN_EGG, 17)); //Squid addCreativeItem(Item.get(Item.SPAWN_EGG, 19)); //Bat - //addCreativeItem(Item.get(Item.SPAWN_EGG, 20)); //Iron Golem + //addCreativeItem(Item.get(Item.SPAWN_EGG, 20)); //Iron Golem //addCreativeItem(Item.get(Item.SPAWN_EGG, 21)); //Snow Golem addCreativeItem(Item.get(Item.SPAWN_EGG, 22)); //Ocelot addCreativeItem(Item.get(Item.SPAWN_EGG, 23)); //Horse @@ -1197,7 +1197,7 @@ private static void initCreativeItems() { addCreativeItem(Item.get(Item.SPAWN_EGG, 49)); //Guardian addCreativeItem(Item.get(Item.SPAWN_EGG, 50)); //ElderGuardian addCreativeItem(Item.get(Item.SPAWN_EGG, 54)); //Shulker - + addCreativeItem(Item.get(Item.FIRE_CHARGE, 0)); addCreativeItem(Item.get(Item.WOODEN_SWORD)); addCreativeItem(Item.get(Item.WOODEN_HOE)); 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 8b54b1b2d9..6ab251d841 100644 --- a/src/main/java/cn/nukkit/level/format/anvil/Anvil.java +++ b/src/main/java/cn/nukkit/level/format/anvil/Anvil.java @@ -342,7 +342,7 @@ 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("SkyLight", sl); nbt.putByteArray("BlockLight", new byte[2048]); return new ChunkSection(nbt); } 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 f7eb1072e2..c8be638548 100644 --- a/src/main/java/cn/nukkit/level/format/generic/EmptyChunkSection.java +++ b/src/main/java/cn/nukkit/level/format/generic/EmptyChunkSection.java @@ -3,7 +3,6 @@ import cn.nukkit.level.format.ChunkSection; import cn.nukkit.utils.ChunkException; -import java.nio.ByteBuffer; import java.util.Arrays; /** diff --git a/src/main/java/cn/nukkit/level/format/leveldb/LevelDB.java b/src/main/java/cn/nukkit/level/format/leveldb/LevelDB.java index a3e0c50e53..dce975c0fe 100644 --- a/src/main/java/cn/nukkit/level/format/leveldb/LevelDB.java +++ b/src/main/java/cn/nukkit/level/format/leveldb/LevelDB.java @@ -3,8 +3,8 @@ import cn.nukkit.Server; import cn.nukkit.blockentity.BlockEntity; import cn.nukkit.blockentity.BlockEntitySpawnable; -import cn.nukkit.level.Level; import cn.nukkit.level.GameRules; +import cn.nukkit.level.Level; import cn.nukkit.level.format.ChunkSection; import cn.nukkit.level.format.FullChunk; import cn.nukkit.level.format.LevelProvider; @@ -507,7 +507,7 @@ public void setSpawn(Vector3 pos) { this.levelData.putInt("SpawnY", (int) pos.y); this.levelData.putInt("SpawnZ", (int) pos.z); } - + @Override public GameRules getGamerules() { GameRules rules = new GameRules(); diff --git a/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java b/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java index dc1688b019..aa133b8f3f 100644 --- a/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java +++ b/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java @@ -80,8 +80,8 @@ public DataPacket[] encode() { pk.pitch = 0; long flags = ( (1L << Entity.DATA_FLAG_CAN_SHOW_NAMETAG) | - (1L << Entity.DATA_FLAG_ALWAYS_SHOW_NAMETAG) | - (1L << Entity.DATA_FLAG_IMMOBILE) + (1L << Entity.DATA_FLAG_ALWAYS_SHOW_NAMETAG) | + (1L << Entity.DATA_FLAG_IMMOBILE) ); pk.metadata = new EntityMetadata() .putLong(Entity.DATA_FLAGS, flags) diff --git a/src/main/java/cn/nukkit/math/Angle.java b/src/main/java/cn/nukkit/math/Angle.java index 33a7fd61f9..8f9a17535f 100644 --- a/src/main/java/cn/nukkit/math/Angle.java +++ b/src/main/java/cn/nukkit/math/Angle.java @@ -1,6 +1,6 @@ package cn.nukkit.math; -import static java.lang.Math.*; +import static java.lang.Math.PI; /** * Copyright 2017 lmlstarqaq @@ -8,142 +8,142 @@ */ public final class Angle implements Comparable { - public static Angle fromDegree(float floatDegree) { - return new Angle(floatDegree, true); - } - - public static Angle fromDegree(double doubleDegree) { - return new Angle(doubleDegree, true); - } - - public static Angle fromRadian(float floatRadian) { - return new Angle(floatRadian, false); - } - - public static Angle fromRadian(double doubleRadian) { - return new Angle(doubleRadian, false); - } - - public static Angle asin(double v) { - return fromRadian(Math.asin(v)); - } - - public static Angle acos(double v) { - return fromRadian(Math.acos(v)); - } - - public static Angle atan(double v) { - return fromRadian(Math.atan(v)); - } - - public double sin() { - return Math.sin(asDoubleRadian()); - } - - public double cos() { - return Math.cos(asDoubleRadian()); - } - - public double tan() { - return Math.tan(asDoubleRadian()); - } - - public float asFloatRadian() { - if (isOriginDouble) { - if (isDegree) return (float) (doubleValue * PI / 180.0); - else return (float) doubleValue; - } else { - if (isDegree) return floatValue * (float) PI / 180.0f; - else return floatValue; - } - } - - public double asDoubleRadian() { - if (isOriginDouble) { - if (isDegree) return doubleValue * PI / 180.0; - else return doubleValue; - } else { - if (isDegree) return floatValue * PI / 180.0; - else return floatValue; - } - } - - public float asFloatDegree() { - if (isOriginDouble) { - if (isDegree) return (float) doubleValue; - else return (float) (doubleValue * 180.0 / PI); - } else { - if (isDegree) return floatValue; - else return floatValue * 180.0f / (float) PI; - } - } - - public double asDoubleDegree() { - if (isOriginDouble) { - if (isDegree) return doubleValue; - else return doubleValue * 180.0 / PI; - } else { - if (isDegree) return floatValue ; - else return floatValue * 180.0 / PI; - } - } - - public static int compare(Angle a, Angle b) { - return a.compareTo(b); - } + public static Angle fromDegree(float floatDegree) { + return new Angle(floatDegree, true); + } + + public static Angle fromDegree(double doubleDegree) { + return new Angle(doubleDegree, true); + } + + public static Angle fromRadian(float floatRadian) { + return new Angle(floatRadian, false); + } + + public static Angle fromRadian(double doubleRadian) { + return new Angle(doubleRadian, false); + } + + public static Angle asin(double v) { + return fromRadian(Math.asin(v)); + } + + public static Angle acos(double v) { + return fromRadian(Math.acos(v)); + } + + public static Angle atan(double v) { + return fromRadian(Math.atan(v)); + } + + public double sin() { + return Math.sin(asDoubleRadian()); + } + + public double cos() { + return Math.cos(asDoubleRadian()); + } + + public double tan() { + return Math.tan(asDoubleRadian()); + } + + public float asFloatRadian() { + if (isOriginDouble) { + if (isDegree) return (float) (doubleValue * PI / 180.0); + else return (float) doubleValue; + } else { + if (isDegree) return floatValue * (float) PI / 180.0f; + else return floatValue; + } + } + + public double asDoubleRadian() { + if (isOriginDouble) { + if (isDegree) return doubleValue * PI / 180.0; + else return doubleValue; + } else { + if (isDegree) return floatValue * PI / 180.0; + else return floatValue; + } + } + + public float asFloatDegree() { + if (isOriginDouble) { + if (isDegree) return (float) doubleValue; + else return (float) (doubleValue * 180.0 / PI); + } else { + if (isDegree) return floatValue; + else return floatValue * 180.0f / (float) PI; + } + } + + public double asDoubleDegree() { + if (isOriginDouble) { + if (isDegree) return doubleValue; + else return doubleValue * 180.0 / PI; + } else { + if (isDegree) return floatValue; + else return floatValue * 180.0 / PI; + } + } + + public static int compare(Angle a, Angle b) { + return a.compareTo(b); + } /* -- Override -- */ - @Override - public String toString() { - return String.format("Angle[%s, %f%s = %f%s] [%d]", - isOriginDouble ? "Double" : "Float", - isOriginDouble ? doubleValue : floatValue, - isDegree ? "deg" : "rad", - isDegree ? (isOriginDouble ? asDoubleRadian() : asFloatRadian()) : - (isOriginDouble ? asDoubleDegree() : asFloatDegree()) , - isDegree ? "rad" : "deg", - hashCode() - ); - } - - @Override - public int compareTo(Angle o) { - return Double.compare(asDoubleRadian(), o.asDoubleRadian()); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Angle && this.compareTo((Angle) obj) == 0; - } - - @Override - public int hashCode() { - int hash; - if (isOriginDouble) hash = Double.hashCode(doubleValue); - else hash = Float.hashCode(floatValue); - if (isDegree) hash = hash ^ 0xABCD1234; - return hash; - } + @Override + public String toString() { + return String.format("Angle[%s, %f%s = %f%s] [%d]", + isOriginDouble ? "Double" : "Float", + isOriginDouble ? doubleValue : floatValue, + isDegree ? "deg" : "rad", + isDegree ? (isOriginDouble ? asDoubleRadian() : asFloatRadian()) : + (isOriginDouble ? asDoubleDegree() : asFloatDegree()), + isDegree ? "rad" : "deg", + hashCode() + ); + } + + @Override + public int compareTo(Angle o) { + return Double.compare(asDoubleRadian(), o.asDoubleRadian()); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Angle && this.compareTo((Angle) obj) == 0; + } + + @Override + public int hashCode() { + int hash; + if (isOriginDouble) hash = Double.hashCode(doubleValue); + else hash = Float.hashCode(floatValue); + if (isDegree) hash = hash ^ 0xABCD1234; + return hash; + } /* -- Internal Part -- */ - private final float floatValue; - private final double doubleValue; - private final boolean isDegree, isOriginDouble; - - private Angle(float floatValue, boolean isDegree) { - this.isOriginDouble = false; - this.floatValue = floatValue; - this.doubleValue = 0.0; - this.isDegree = isDegree; - } - - private Angle(double doubleValue, boolean isDegree) { - this.isOriginDouble = true; - this.floatValue = 0.0f; - this.doubleValue = doubleValue; - this.isDegree = isDegree; - } + private final float floatValue; + private final double doubleValue; + private final boolean isDegree, isOriginDouble; + + private Angle(float floatValue, boolean isDegree) { + this.isOriginDouble = false; + this.floatValue = floatValue; + this.doubleValue = 0.0; + this.isDegree = isDegree; + } + + private Angle(double doubleValue, boolean isDegree) { + this.isOriginDouble = true; + this.floatValue = 0.0f; + this.doubleValue = doubleValue; + this.isDegree = isDegree; + } } diff --git a/src/main/java/cn/nukkit/math/NukkitMath.java b/src/main/java/cn/nukkit/math/NukkitMath.java index 32368a2ca7..1858b57937 100644 --- a/src/main/java/cn/nukkit/math/NukkitMath.java +++ b/src/main/java/cn/nukkit/math/NukkitMath.java @@ -45,7 +45,7 @@ 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); } diff --git a/src/main/java/cn/nukkit/network/Network.java b/src/main/java/cn/nukkit/network/Network.java index 91fac322b0..2058ca7c10 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, 3); //skip 2 more bytes + pk.setBuffer(buf, 3); //skip 2 more bytes pk.decode(); diff --git a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java index 7e3685cb67..2af6355473 100644 --- a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java @@ -17,18 +17,18 @@ 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_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_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; + public static final int ARG_TYPE_RAWTEXT = 0x10; + public static final int ARG_TYPE_TEXT = 0x12; public static final int ARG_TYPE_JSON = 0x15; public static final int ARG_TYPE_COMMAND = 0x1c; @@ -46,6 +46,7 @@ public void decode() { } int aliasCommands = 0; + @Override public void encode() { this.reset(); @@ -55,34 +56,34 @@ public void encode() { ArrayList aliases = new ArrayList<>(); aliases.addAll(Arrays.asList(versions.versions.get(0).aliases)); aliases.add(name); - for (String alias : aliases){ + 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()){ + for (CommandOverload overload : versions.versions.get(0).overloads.values()) { commandsStream.putUnsignedVarInt(overload.input.parameters.length); - for (CommandParameter parameter : overload.input.parameters){ + for (CommandParameter parameter : overload.input.parameters) { commandsStream.putString(parameter.name); commandsStream.putLInt(ARG_FLAG_VALID | getFlag(parameter.type)); commandsStream.putBoolean(parameter.optional); } } } - aliasCommands += (aliases.size()-1); + aliasCommands += (aliases.size() - 1); }); this.putUnsignedVarInt(0); this.putUnsignedVarInt(0); this.putUnsignedVarInt(0); - this.putUnsignedVarInt(this.commands.size()+aliasCommands); + this.putUnsignedVarInt(this.commands.size() + aliasCommands); this.put(commandsStream.getBuffer()); } - int getFlag(String type){ - switch (type){ + int getFlag(String type) { + switch (type) { case CommandParameter.ARG_TYPE_BLOCK_POS: return ARG_TYPE_POSITION; case CommandParameter.ARG_TYPE_INT: diff --git a/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java b/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java index 0595d991b1..5d1de53edf 100644 --- a/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java @@ -32,7 +32,7 @@ public class BossEventPacket extends DataPacket { public short unknown; public int color; public int overlay; - + @Override public byte pid() { return NETWORK_ID; @@ -61,7 +61,7 @@ public void decode() { break; case TYPE_TITLE: this.title = this.getString(); - break; + break; } } diff --git a/src/main/java/cn/nukkit/network/protocol/CommandRequestPacket.java b/src/main/java/cn/nukkit/network/protocol/CommandRequestPacket.java index 5da8657009..28673d2ac1 100644 --- a/src/main/java/cn/nukkit/network/protocol/CommandRequestPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/CommandRequestPacket.java @@ -1,8 +1,5 @@ package cn.nukkit.network.protocol; -import cn.nukkit.command.data.CommandArgs; -import com.google.gson.Gson; - /** * author: MagicDroidX * Nukkit Project diff --git a/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java b/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java index 80e7b110af..754f8b6b11 100644 --- a/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java @@ -22,7 +22,7 @@ public byte pid() { @Override public void decode() { this.windowId = this.getByte(); - this.type = this.getByte(); + this.type = this.getByte(); } @Override diff --git a/src/main/java/cn/nukkit/network/protocol/ContainerSetDataPacket.java b/src/main/java/cn/nukkit/network/protocol/ContainerSetDataPacket.java index f39ab27686..97458e3e82 100644 --- a/src/main/java/cn/nukkit/network/protocol/ContainerSetDataPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/ContainerSetDataPacket.java @@ -6,7 +6,7 @@ */ public class ContainerSetDataPacket extends DataPacket { public static final byte NETWORK_ID = ProtocolInfo.CONTAINER_SET_DATA_PACKET; - + public static final int PROPERTY_FURNACE_TICK_COUNT = 0; public static final int PROPERTY_FURNACE_LIT_TIME = 1; public static final int PROPERTY_FURNACE_LIT_DURATION = 2; diff --git a/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java b/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java index c5a35f44fb..421958dcd1 100644 --- a/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/LevelEventPacket.java @@ -32,7 +32,7 @@ public class LevelEventPacket extends DataPacket { public static final int EVENT_SOUND_ITEM_THROWN = 1031; public static final int EVENT_SOUND_PORTAL = 1032; - + public static final int EVENT_SOUND_ITEM_FRAME_ITEM_ADDED = 1040; public static final int EVENT_SOUND_ITEM_FRAME_PLACED = 1041; public static final int EVENT_SOUND_ITEM_FRAME_REMOVED = 1042; @@ -49,11 +49,11 @@ public class LevelEventPacket extends DataPacket { public static final int EVENT_SOUND_ARMOR_STAND_PLACE = 1063; public static final int EVENT_GUARDIAN_CURSE = 2006; - + public static final int EVENT_PARTICLE_BLOCK_FORCE_FIELD = 2008; public static final int EVENT_PARTICLE_PUNCH_BLOCK = 2014; - + public static final int EVENT_SOUND_BUTTON_CLICK = 3500; public static final int EVENT_SOUND_EXPLODE = 3501; public static final int EVENT_CAULDRON_DYE_ARMOR = 3502; @@ -64,7 +64,7 @@ public class LevelEventPacket extends DataPacket { public static final int EVENT_CAULDRON_TAKE_WATER = 3507; public static final int EVENT_CAULDRON_ADD_DYE = 3508; public static final int EVENT_CAULDRON_CLEAN_BANNER = 3509; - + public static final int EVENT_PARTICLE_SHOOT = 2000; public static final int EVENT_PARTICLE_DESTROY = 2001; public static final int EVENT_PARTICLE_SPLASH = 2002; diff --git a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java index 3571abfcec..ffc6c680c5 100644 --- a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java @@ -1,8 +1,6 @@ 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; @@ -76,7 +74,8 @@ private void decodeSkinData() { 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()); + 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/MovePlayerPacket.java b/src/main/java/cn/nukkit/network/protocol/MovePlayerPacket.java index d37234244d..25478aaf61 100644 --- a/src/main/java/cn/nukkit/network/protocol/MovePlayerPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/MovePlayerPacket.java @@ -40,7 +40,7 @@ public void decode() { this.mode = this.getByte(); this.onGround = this.getBoolean(); this.ridingEid = this.getVarLong(); - if (this.mode == MODE_TELEPORT){ + if (this.mode == MODE_TELEPORT) { this.int1 = this.getLInt(); this.int2 = this.getLInt(); } @@ -57,7 +57,7 @@ public void encode() { this.putByte((byte) this.mode); this.putBoolean(this.onGround); this.putVarLong(this.ridingEid); - if (this.mode == MODE_TELEPORT){ + if (this.mode == MODE_TELEPORT) { this.putLInt(this.int1); this.putLInt(this.int2); } diff --git a/src/main/java/cn/nukkit/network/protocol/TransferPacket.java b/src/main/java/cn/nukkit/network/protocol/TransferPacket.java index 2ba3af1e8a..0c15ef2dd8 100644 --- a/src/main/java/cn/nukkit/network/protocol/TransferPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/TransferPacket.java @@ -3,10 +3,10 @@ // A wild TransferPacket appeared! public class TransferPacket extends DataPacket { public static final byte NETWORK_ID = ProtocolInfo.TRANSFER_PACKET; - + public String address; // Server address public int port = 19132; // Server port - + @Override public void decode() { this.address = this.getString(); diff --git a/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java b/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java index 54184041c7..5d45fd2d3f 100644 --- a/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java @@ -9,7 +9,6 @@ public class UpdateEquipmentPacket extends DataPacket { public byte[] namedtag; - @Override public byte pid() { return ProtocolInfo.UPDATE_EQUIPMENT_PACKET; diff --git a/src/main/java/cn/nukkit/resourcepacks/AbstractResourcePack.java b/src/main/java/cn/nukkit/resourcepacks/AbstractResourcePack.java index 440435e0d9..0c6ae3fdb3 100644 --- a/src/main/java/cn/nukkit/resourcepacks/AbstractResourcePack.java +++ b/src/main/java/cn/nukkit/resourcepacks/AbstractResourcePack.java @@ -9,7 +9,7 @@ public abstract class AbstractResourcePack implements ResourcePack { protected boolean verifyManifest() { if (this.manifest.has("format_version") && this.manifest.has("header") && this.manifest.has("modules")) { JsonObject header = this.manifest.getAsJsonObject("header"); - return header.has("description") && + return header.has("description") && header.has("name") && header.has("uuid") && header.has("version") && diff --git a/src/main/java/cn/nukkit/scheduler/NukkitRunnable.java b/src/main/java/cn/nukkit/scheduler/NukkitRunnable.java index ee992d88f5..55db31ab63 100644 --- a/src/main/java/cn/nukkit/scheduler/NukkitRunnable.java +++ b/src/main/java/cn/nukkit/scheduler/NukkitRunnable.java @@ -24,31 +24,31 @@ public synchronized Runnable runTask(Plugin plugin) throws IllegalArgumentExcept return taskHandler.getTask(); } - public synchronized Runnable runTaskAsynchronously(Plugin plugin) throws IllegalArgumentException, IllegalStateException { + public synchronized Runnable runTaskAsynchronously(Plugin plugin) throws IllegalArgumentException, IllegalStateException { checkState(); this.taskHandler = Server.getInstance().getScheduler().scheduleTask(plugin, this, true); return taskHandler.getTask(); } - public synchronized Runnable runTaskLater(Plugin plugin, int delay) throws IllegalArgumentException, IllegalStateException { + public synchronized Runnable runTaskLater(Plugin plugin, int delay) throws IllegalArgumentException, IllegalStateException { checkState(); this.taskHandler = Server.getInstance().getScheduler().scheduleDelayedTask(plugin, this, delay); return taskHandler.getTask(); } - public synchronized Runnable runTaskLaterAsynchronously(Plugin plugin, int delay) throws IllegalArgumentException, IllegalStateException { + public synchronized Runnable runTaskLaterAsynchronously(Plugin plugin, int delay) throws IllegalArgumentException, IllegalStateException { checkState(); this.taskHandler = Server.getInstance().getScheduler().scheduleDelayedTask(plugin, this, delay, true); return taskHandler.getTask(); } - public synchronized Runnable runTaskTimer(Plugin plugin, int delay, int period) throws IllegalArgumentException, IllegalStateException { + public synchronized Runnable runTaskTimer(Plugin plugin, int delay, int period) throws IllegalArgumentException, IllegalStateException { checkState(); this.taskHandler = Server.getInstance().getScheduler().scheduleDelayedRepeatingTask(plugin, this, delay, period); return taskHandler.getTask(); } - public synchronized Runnable runTaskTimerAsynchronously(Plugin plugin, int delay, int period) throws IllegalArgumentException, IllegalStateException { + public synchronized Runnable runTaskTimerAsynchronously(Plugin plugin, int delay, int period) throws IllegalArgumentException, IllegalStateException { checkState(); this.taskHandler = Server.getInstance().getScheduler().scheduleDelayedRepeatingTask(plugin, this, delay, period, true); return taskHandler.getTask(); diff --git a/src/main/java/cn/nukkit/scheduler/ServerScheduler.java b/src/main/java/cn/nukkit/scheduler/ServerScheduler.java index c07e6ef469..ad62bafbd0 100644 --- a/src/main/java/cn/nukkit/scheduler/ServerScheduler.java +++ b/src/main/java/cn/nukkit/scheduler/ServerScheduler.java @@ -57,7 +57,7 @@ public TaskHandler scheduleTask(Runnable task) { public TaskHandler scheduleTask(Plugin plugin, Runnable task) { return addTask(plugin, task, 0, 0, false); } - + /** * @deprecated Use {@link #scheduleTask(Plugin, Runnable, boolean) */ @@ -69,7 +69,7 @@ public TaskHandler scheduleTask(Runnable task, boolean asynchronous) { public TaskHandler scheduleTask(Plugin plugin, Runnable task, boolean asynchronous) { return addTask(plugin, task, 0, 0, asynchronous); } - + /** * @deprecated Use {@link #scheduleAsyncTask(Plugin, AsyncTask) */ @@ -81,7 +81,7 @@ public TaskHandler scheduleAsyncTask(AsyncTask task) { public TaskHandler scheduleAsyncTask(Plugin plugin, AsyncTask task) { return addTask(plugin, task, 0, 0, true); } - + @Deprecated public void scheduleAsyncTaskToWorker(AsyncTask task, int worker) { scheduleAsyncTask(task); @@ -114,7 +114,7 @@ public TaskHandler scheduleDelayedTask(Runnable task, int delay) { public TaskHandler scheduleDelayedTask(Plugin plugin, Runnable task, int delay) { return addTask(plugin, task, delay, 0, false); } - + /** * @deprecated Use {@link #scheduleDelayedTask(Plugin, Runnable, int, boolean) */ @@ -126,7 +126,7 @@ public TaskHandler scheduleDelayedTask(Runnable task, int delay, boolean asynchr public TaskHandler scheduleDelayedTask(Plugin plugin, Runnable task, int delay, boolean asynchronous) { return addTask(plugin, task, delay, 0, asynchronous); } - + /** * @deprecated Use {@link #scheduleRepeatingTask(Plugin, Runnable, int) */ @@ -134,7 +134,7 @@ public TaskHandler scheduleDelayedTask(Plugin plugin, Runnable task, int delay, public TaskHandler scheduleRepeatingTask(Runnable task, int period) { return addTask(null, task, 0, period, false); } - + public TaskHandler scheduleRepeatingTask(Plugin plugin, Runnable task, int period) { return addTask(plugin, task, 0, period, false); } @@ -150,7 +150,7 @@ public TaskHandler scheduleRepeatingTask(Runnable task, int period, boolean asyn public TaskHandler scheduleRepeatingTask(Plugin plugin, Runnable task, int period, boolean asynchronous) { return addTask(plugin, task, 0, period, asynchronous); } - + public TaskHandler scheduleRepeatingTask(Task task, int period) { return addTask(task, 0, period, false); } @@ -174,7 +174,7 @@ public TaskHandler scheduleDelayedRepeatingTask(Task task, int delay, int period public TaskHandler scheduleDelayedRepeatingTask(Runnable task, int delay, int period) { return addTask(null, task, delay, period, false); } - + public TaskHandler scheduleDelayedRepeatingTask(Plugin plugin, Runnable task, int delay, int period) { return addTask(plugin, task, delay, period, false); } @@ -186,7 +186,7 @@ public TaskHandler scheduleDelayedRepeatingTask(Plugin plugin, Runnable task, in public TaskHandler scheduleDelayedRepeatingTask(Runnable task, int delay, int period, boolean asynchronous) { return addTask(null, task, delay, period, asynchronous); } - + public TaskHandler scheduleDelayedRepeatingTask(Plugin plugin, Runnable task, int delay, int period, boolean asynchronous) { return addTask(plugin, task, delay, period, asynchronous); } diff --git a/src/main/java/cn/nukkit/utils/BinaryStream.java b/src/main/java/cn/nukkit/utils/BinaryStream.java index a175edeb9a..a61cc8cb84 100644 --- a/src/main/java/cn/nukkit/utils/BinaryStream.java +++ b/src/main/java/cn/nukkit/utils/BinaryStream.java @@ -204,21 +204,22 @@ public void putByte(byte b) { /** * Reads a list of Attributes from the stream. + * * @return Attribute[] */ public Attribute[] getAttributeList() throws Exception { List list = new ArrayList<>(); long count = this.getUnsignedVarInt(); - for(int i = 0; i < count; ++i){ + for (int i = 0; i < count; ++i) { String name = this.getString(); Attribute attr = Attribute.getAttributeByName(name); - if(attr != null){ + if (attr != null) { attr.setMinValue(this.getLFloat()); attr.setValue(this.getLFloat()); attr.setMaxValue(this.getLFloat()); list.add(attr); - }else{ + } else { throw new Exception("Unknown attribute type \"" + name + "\""); } } @@ -229,9 +230,9 @@ public Attribute[] getAttributeList() throws Exception { /** * Writes a list of Attributes to the packet buffer using the standard format. */ - public void putAttributeList(Attribute[] attributes){ + 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.getValue()); @@ -279,16 +280,16 @@ public Item getSlot() { //TODO int canPlaceOn = this.getVarInt(); - if(canPlaceOn > 0){ - for(int i = 0; i < canPlaceOn; ++i){ + if (canPlaceOn > 0) { + for (int i = 0; i < canPlaceOn; ++i) { this.getString(); } } //TODO int canDestroy = this.getVarInt(); - if(canDestroy > 0){ - for(int i = 0; i < canDestroy; ++i){ + if (canDestroy > 0) { + for (int i = 0; i < canDestroy; ++i) { this.getString(); } } diff --git a/src/main/java/cn/nukkit/utils/ClientChainData.java b/src/main/java/cn/nukkit/utils/ClientChainData.java index 356a57004a..21297693f5 100644 --- a/src/main/java/cn/nukkit/utils/ClientChainData.java +++ b/src/main/java/cn/nukkit/utils/ClientChainData.java @@ -10,12 +10,12 @@ /** * ClientChainData is a container of chain data sent from clients. - * + *

* Device information such as client UUID, xuid and serverAddress, can be * read from instances of this object. - * + *

* To get chain data, you can use player.getLoginChainData() or read(loginPacket) - * + *

* =============== * author: boybook * Nukkit Project @@ -23,164 +23,164 @@ */ public final class ClientChainData { - public static ClientChainData of(byte[] buffer) { - return new ClientChainData(buffer); - } - - public static ClientChainData read(LoginPacket pk) { - return of(pk.getBuffer()); - } + public static ClientChainData of(byte[] buffer) { + return new ClientChainData(buffer); + } + + public static ClientChainData read(LoginPacket pk) { + return of(pk.getBuffer()); + } + + public String getUsername() { + return username; + } + + public UUID getClientUUID() { + return clientUUID; + } + + public String getIdentityPublicKey() { + return identityPublicKey; + } + + public long getClientId() { + return clientId; + } + + public String getServerAddress() { + return serverAddress; + } + + public String getDeviceModel() { + return deviceModel; + } + + public int getDeviceOS() { + return deviceOS; + } + + public String getGameVersion() { + return gameVersion; + } + + public int getGuiScale() { + return guiScale; + } + + public String getLanguageCode() { + return languageCode; + } + + public String getXUID() { + return xuid; + } - public String getUsername() { - return username; - } + public int getCurrentInputMode() { + return currentInputMode; + } + + 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; + + public int getUIProfile() { + return UIProfile; + } + + /////////////////////////////////////////////////////////////////////////// + // Override + /////////////////////////////////////////////////////////////////////////// + + @Override + public boolean equals(Object obj) { + return obj instanceof ClientChainData && Objects.equals(bs, ((ClientChainData) obj).bs); + } + + @Override + public int hashCode() { + return bs.hashCode(); + } - public UUID getClientUUID() { - return clientUUID; - } + /////////////////////////////////////////////////////////////////////////// + // Internal + /////////////////////////////////////////////////////////////////////////// - public String getIdentityPublicKey() { - return identityPublicKey; - } - - public long getClientId() { - return clientId; - } - - public String getServerAddress() { - return serverAddress; - } - - public String getDeviceModel() { - return deviceModel; - } - - public int getDeviceOS() { - return deviceOS; - } - - public String getGameVersion() { - return gameVersion; - } - - public int getGuiScale() { - return guiScale; - } - - public String getLanguageCode() { - return languageCode; - } - - public String getXUID() { - return xuid; - } - - public int getCurrentInputMode() { - return currentInputMode; - } - - 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; - - public int getUIProfile() { - return UIProfile; - } - - /////////////////////////////////////////////////////////////////////////// - // Override - /////////////////////////////////////////////////////////////////////////// - - @Override - public boolean equals(Object obj) { - return obj instanceof ClientChainData && Objects.equals(bs, ((ClientChainData) obj).bs); - } - - @Override - public int hashCode() { - return bs.hashCode(); - } - - /////////////////////////////////////////////////////////////////////////// - // Internal - /////////////////////////////////////////////////////////////////////////// - - private String username; - private UUID clientUUID; - private String xuid; - private String identityPublicKey; - - private long clientId; - private String serverAddress; - private String deviceModel; - private int deviceOS; - private String gameVersion; - private int guiScale; - private String languageCode; - private int currentInputMode; - private int defaultInputMode; - - private int UIProfile; - - private String capeData; - - private BinaryStream bs = new BinaryStream(); - - private ClientChainData(byte[] buffer) { - bs.setBuffer(buffer, 0); - decodeChainData(); - decodeSkinData(); - } - - private void decodeChainData() { - Map> map = new Gson().fromJson(new String(bs.get(bs.getLInt()), StandardCharsets.UTF_8), - new TypeToken>>() { - }.getType()); - if (map.isEmpty() || !map.containsKey("chain") || map.get("chain").isEmpty()) return; - List chains = map.get("chain"); - for (String c : chains) { - JsonObject chainMap = decodeToken(c); - if (chainMap == null) continue; - if (chainMap.has("extraData")) { - JsonObject extra = chainMap.get("extraData").getAsJsonObject(); - if (extra.has("displayName")) this.username = extra.get("displayName").getAsString(); - if (extra.has("identity")) this.clientUUID = UUID.fromString(extra.get("identity").getAsString()); - if (extra.has("XUID")) this.xuid = extra.get("XUID").getAsString(); - } - if (chainMap.has("identityPublicKey")) - this.identityPublicKey = chainMap.get("identityPublicKey").getAsString(); - } - } - - private void decodeSkinData() { - JsonObject skinToken = decodeToken(new String(bs.get(bs.getLInt()))); - if(skinToken == null) return; - if (skinToken.has("ClientRandomId")) this.clientId = skinToken.get("ClientRandomId").getAsLong(); - if (skinToken.has("ServerAddress")) this.serverAddress = skinToken.get("ServerAddress").getAsString(); - if (skinToken.has("DeviceModel")) this.deviceModel = skinToken.get("DeviceModel").getAsString(); - if (skinToken.has("DeviceOS")) this.deviceOS = skinToken.get("DeviceOS").getAsInt(); - if (skinToken.has("GameVersion")) this.gameVersion = skinToken.get("GameVersion").getAsString(); - if (skinToken.has("GuiScale")) this.guiScale = skinToken.get("GuiScale").getAsInt(); - 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("UIProfile")) this.UIProfile = skinToken.get("UIProfile").getAsInt(); - if (skinToken.has("CapeData")) this.capeData = skinToken.get("CapeData").getAsString(); - } - - private JsonObject decodeToken(String token) { - String[] base = token.split("\\."); - if (base.length < 2) return null; - String json = new String(Base64.getDecoder().decode(base[1]), StandardCharsets.UTF_8); - //Server.getInstance().getLogger().debug(json); - return new Gson().fromJson(json, JsonObject.class); - } + private String username; + private UUID clientUUID; + private String xuid; + private String identityPublicKey; + + private long clientId; + private String serverAddress; + private String deviceModel; + private int deviceOS; + private String gameVersion; + private int guiScale; + private String languageCode; + private int currentInputMode; + private int defaultInputMode; + + private int UIProfile; + + private String capeData; + + private BinaryStream bs = new BinaryStream(); + + private ClientChainData(byte[] buffer) { + bs.setBuffer(buffer, 0); + decodeChainData(); + decodeSkinData(); + } + + private void decodeChainData() { + Map> map = new Gson().fromJson(new String(bs.get(bs.getLInt()), StandardCharsets.UTF_8), + new TypeToken>>() { + }.getType()); + if (map.isEmpty() || !map.containsKey("chain") || map.get("chain").isEmpty()) return; + List chains = map.get("chain"); + for (String c : chains) { + JsonObject chainMap = decodeToken(c); + if (chainMap == null) continue; + if (chainMap.has("extraData")) { + JsonObject extra = chainMap.get("extraData").getAsJsonObject(); + if (extra.has("displayName")) this.username = extra.get("displayName").getAsString(); + if (extra.has("identity")) this.clientUUID = UUID.fromString(extra.get("identity").getAsString()); + if (extra.has("XUID")) this.xuid = extra.get("XUID").getAsString(); + } + if (chainMap.has("identityPublicKey")) + this.identityPublicKey = chainMap.get("identityPublicKey").getAsString(); + } + } + + private void decodeSkinData() { + JsonObject skinToken = decodeToken(new String(bs.get(bs.getLInt()))); + if (skinToken == null) return; + if (skinToken.has("ClientRandomId")) this.clientId = skinToken.get("ClientRandomId").getAsLong(); + if (skinToken.has("ServerAddress")) this.serverAddress = skinToken.get("ServerAddress").getAsString(); + if (skinToken.has("DeviceModel")) this.deviceModel = skinToken.get("DeviceModel").getAsString(); + if (skinToken.has("DeviceOS")) this.deviceOS = skinToken.get("DeviceOS").getAsInt(); + if (skinToken.has("GameVersion")) this.gameVersion = skinToken.get("GameVersion").getAsString(); + if (skinToken.has("GuiScale")) this.guiScale = skinToken.get("GuiScale").getAsInt(); + 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("UIProfile")) this.UIProfile = skinToken.get("UIProfile").getAsInt(); + if (skinToken.has("CapeData")) this.capeData = skinToken.get("CapeData").getAsString(); + } + + private JsonObject decodeToken(String token) { + String[] base = token.split("\\."); + if (base.length < 2) return null; + String json = new String(Base64.getDecoder().decode(base[1]), StandardCharsets.UTF_8); + //Server.getInstance().getLogger().debug(json); + return new Gson().fromJson(json, JsonObject.class); + } } diff --git a/src/main/java/cn/nukkit/utils/MinecartType.java b/src/main/java/cn/nukkit/utils/MinecartType.java index e369644629..1bf3fb21de 100644 --- a/src/main/java/cn/nukkit/utils/MinecartType.java +++ b/src/main/java/cn/nukkit/utils/MinecartType.java @@ -1,13 +1,14 @@ 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 + * By Adam Matthew * Creation time: 2017/7/17 19:55. */ @API(usage = API.Usage.STABLE, definition = API.Definition.INTERNAL) @@ -82,7 +83,7 @@ public int getId() { public String getName() { return realName; } - + /** * Gets if the minecart contains block * diff --git a/src/main/java/cn/nukkit/utils/Rail.java b/src/main/java/cn/nukkit/utils/Rail.java index 504d1d769d..7cb9d958e2 100644 --- a/src/main/java/cn/nukkit/utils/Rail.java +++ b/src/main/java/cn/nukkit/utils/Rail.java @@ -4,7 +4,10 @@ import cn.nukkit.block.Block; import cn.nukkit.math.BlockFace; -import java.util.*; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.stream.Stream; import static cn.nukkit.math.BlockFace.*; @@ -25,16 +28,16 @@ public static boolean isRailBlock(Block block) { } 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); + 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; diff --git a/src/main/java/cn/nukkit/utils/VarInt.java b/src/main/java/cn/nukkit/utils/VarInt.java index 373b3b07ea..e80f6fbbe4 100644 --- a/src/main/java/cn/nukkit/utils/VarInt.java +++ b/src/main/java/cn/nukkit/utils/VarInt.java @@ -20,9 +20,9 @@ @API(usage = EXPERIMENTAL, definition = UNIVERSAL) public final class VarInt { - private VarInt() { - //no instance - } + private VarInt() { + //no instance + } /** * @param v Signed int @@ -46,7 +46,7 @@ public static int decodeZigZag32(long v) { * @return Unsigned encoded long */ public static long encodeZigZag64(long v) { - return (v << 1) ^ (v >> 63); + return (v << 1) ^ (v >> 63); } /** @@ -58,31 +58,31 @@ public static long decodeZigZag64(long v) { } private static long read(BinaryStream stream, int maxSize) { - long value = 0; - int size = 0; - int b; - while (((b = stream.getByte()) & 0x80) == 0x80) { - value |= (long) (b & 0x7F) << (size++ * 7); - if (size >= maxSize) { - throw new IllegalArgumentException("VarLong too big"); - } - } + long value = 0; + int size = 0; + int b; + while (((b = stream.getByte()) & 0x80) == 0x80) { + value |= (long) (b & 0x7F) << (size++ * 7); + if (size >= maxSize) { + throw new IllegalArgumentException("VarLong too big"); + } + } - return value | ((long) (b & 0x7F) << (size * 7)); + return value | ((long) (b & 0x7F) << (size * 7)); } private static long read(InputStream stream, int maxSize) throws IOException { - long value = 0; - int size = 0; - int b; - while (((b = stream.read()) & 0x80) == 0x80) { - value |= (long) (b & 0x7F) << (size++ * 7); - if (size >= maxSize) { - throw new IllegalArgumentException("VarLong too big"); - } - } + long value = 0; + int size = 0; + int b; + while (((b = stream.read()) & 0x80) == 0x80) { + value |= (long) (b & 0x7F) << (size++ * 7); + if (size >= maxSize) { + throw new IllegalArgumentException("VarLong too big"); + } + } - return value | ((long) (b & 0x7F) << (size * 7)); + return value | ((long) (b & 0x7F) << (size * 7)); } /** @@ -150,27 +150,27 @@ public static long readUnsignedVarLong(InputStream stream) throws IOException { } private static void write(BinaryStream stream, long value) { - do { - byte temp = (byte)(value & 0b01111111); - // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone - value >>>= 7; - if (value != 0) { - temp |= 0b10000000; - } - stream.putByte(temp); - } while (value != 0); + do { + byte temp = (byte) (value & 0b01111111); + // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone + value >>>= 7; + if (value != 0) { + temp |= 0b10000000; + } + stream.putByte(temp); + } while (value != 0); } private static void write(OutputStream stream, long value) throws IOException { - do { - byte temp = (byte)(value & 0b01111111); - // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone - value >>>= 7; - if (value != 0) { - temp |= 0b10000000; - } - stream.write(temp); - } while (value != 0); + do { + byte temp = (byte) (value & 0b01111111); + // Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone + value >>>= 7; + if (value != 0) { + temp |= 0b10000000; + } + stream.write(temp); + } while (value != 0); } /** diff --git a/src/main/java/cn/nukkit/utils/completers/CommandsCompleter.java b/src/main/java/cn/nukkit/utils/completers/CommandsCompleter.java index 41e77e5ac1..30248759e4 100644 --- a/src/main/java/cn/nukkit/utils/completers/CommandsCompleter.java +++ b/src/main/java/cn/nukkit/utils/completers/CommandsCompleter.java @@ -1,13 +1,13 @@ package cn.nukkit.utils.completers; -import static jline.internal.Preconditions.checkNotNull; +import cn.nukkit.Server; +import jline.console.completer.Completer; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; -import cn.nukkit.Server; -import jline.console.completer.Completer; +import static jline.internal.Preconditions.checkNotNull; public class CommandsCompleter implements Completer { @@ -18,15 +18,14 @@ public int complete(String buffer, int cursor, List candidates) { if (buffer == null) { Server.getInstance().getCommandMap().getCommands().keySet().forEach((cmd) -> candidates.add(cmd)); - } - else { + } else { SortedSet names = new TreeSet(); Server.getInstance().getCommandMap().getCommands().keySet().forEach((cmd) -> names.add(cmd)); for (String match : names) { if (!match.toLowerCase().startsWith(buffer.toLowerCase())) { continue; } - + candidates.add(match); } } diff --git a/src/main/java/cn/nukkit/utils/completers/PlayersCompleter.java b/src/main/java/cn/nukkit/utils/completers/PlayersCompleter.java index 10930903b1..0c057dd91d 100644 --- a/src/main/java/cn/nukkit/utils/completers/PlayersCompleter.java +++ b/src/main/java/cn/nukkit/utils/completers/PlayersCompleter.java @@ -1,13 +1,13 @@ package cn.nukkit.utils.completers; -import static jline.internal.Preconditions.checkNotNull; +import cn.nukkit.Server; +import jline.console.completer.Completer; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; -import cn.nukkit.Server; -import jline.console.completer.Completer; +import static jline.internal.Preconditions.checkNotNull; public class PlayersCompleter implements Completer { @@ -18,8 +18,7 @@ public int complete(String buffer, int cursor, List candidates) { if (buffer == null) { Server.getInstance().getOnlinePlayers().values().forEach((p) -> candidates.add(p.getName())); - } - else { + } else { // We are auto completing player names, so 99% of the times we are doing this, it will be something like // "say John*TAB*" // however the buffer will be "say John", but we don't want that, the buffer must be the player's name @@ -33,7 +32,7 @@ public int complete(String buffer, int cursor, List candidates) { if (!match.toLowerCase().startsWith(buffer.toLowerCase())) { continue; } - + candidates.add(cmd + match); } } From cc29bc0af384a0ea8c62dfeec652f10690a68aed Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Tue, 19 Sep 2017 21:05:31 +0200 Subject: [PATCH 079/175] fix example config --- .../java/cn/nukkit/utils/ConfigSection.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/cn/nukkit/utils/ConfigSection.java b/src/main/java/cn/nukkit/utils/ConfigSection.java index bdab8c57d3..05bb97b2fd 100644 --- a/src/main/java/cn/nukkit/utils/ConfigSection.java +++ b/src/main/java/cn/nukkit/utils/ConfigSection.java @@ -133,17 +133,17 @@ public ConfigSection getSection(String key) { /** * Get all ConfigSections in root path. * Example config: - * a1: - * b1: - * c1: - * c2: - * a2: - * b2: - * c3: - * c4: - * a3: true - * a4: "hello" - * a5: 100 + * a1: + * b1: + * c1: + * c2: + * a2: + * b2: + * c3: + * c4: + * a3: true + * a4: "hello" + * a5: 100 *

* getSections() will return new ConfigSection, that contains sections a1 and a2 only. * From 860315a110e2bee0cc0cbded4f058fb72bdec0ec Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Wed, 20 Sep 2017 16:13:42 +0200 Subject: [PATCH 080/175] fix example config --- src/main/java/cn/nukkit/form/window/FormWindowCustom.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java index a23aa7a18f..f52f81c572 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java @@ -62,7 +62,7 @@ public void setResponse(String data) { List elementResponses = new Gson().fromJson(data, new TypeToken>() { }.getType()); - elementResponses.remove(elementResponses.size() - 1); //submit button + //elementResponses.remove(elementResponses.size() - 1); //submit button //maybe mojang removed that? int i = 0; From fb912acbe43d5b1ba4ec5172e085fb88fa099427 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Wed, 20 Sep 2017 17:23:49 +0200 Subject: [PATCH 081/175] fix item dropping --- src/main/java/cn/nukkit/Player.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 60c4ca6e9f..33d7664c74 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -4211,7 +4211,7 @@ public boolean attack(EntityDamageEvent source) { * @return bool if the item was dropped or if the item was null */ public boolean dropItem(Item item) { - if (!this.spawned || this.isAlive()) { + if (!this.spawned || !this.isAlive()) { return false; } From c818d6a8fbcb9dd6c1d2be67c47849ad19e4eec8 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Wed, 20 Sep 2017 18:56:01 +0200 Subject: [PATCH 082/175] some improvements from PMMP --- src/main/java/cn/nukkit/Player.java | 9 ++------- .../java/cn/nukkit/inventory/CraftingGrid.java | 3 ++- src/main/java/cn/nukkit/inventory/Recipe.java | 4 ++++ .../java/cn/nukkit/inventory/ShapedRecipe.java | 5 +++++ .../cn/nukkit/inventory/ShapelessRecipe.java | 5 +++++ .../transaction/SimpleInventoryTransaction.java | 16 +++++++++++++++- .../transaction/action/DropItemAction.java | 12 ++++++++++++ .../transaction/action/InventoryAction.java | 8 ++++++++ .../protocol/types/NetworkInventoryAction.java | 15 ++++++++++++--- 9 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 33d7664c74..30b1eaf703 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2680,6 +2680,7 @@ public void handleDataPacket(DataPacket packet) { if (recipes == null || recipes.length == 0) { this.getServer().getLogger().debug("Uknown recipe for output (" + craftingEventPacket.output[0] + ")"); + return; } recipe = null; @@ -3223,7 +3224,7 @@ public void handleDataPacket(DataPacket packet) { } } - MainLogger.getLogger().debug("Failed to execute inventory transaction from " + this.getName() + " with actions: " + Arrays.toString(transactionPacket.actions)); + MainLogger.getLogger().debug("Failed to execute inventory transaction from " + this.getName() + " with actions: " + Arrays.toString(actions.stream().toArray())); //TODO: check more stuff that might need reversion break packetswitch; //oops! @@ -4220,12 +4221,6 @@ public boolean dropItem(Item item) { return true; } - PlayerDropItemEvent ev; - this.server.getPluginManager().callEvent(ev = new PlayerDropItemEvent(this, item)); - if (ev.isCancelled()) { - return false; - } - Vector3 motion = this.getDirectionVector().multiply(0.4); this.level.dropItem(this.add(0, 1.3, 0), item, motion, 40); diff --git a/src/main/java/cn/nukkit/inventory/CraftingGrid.java b/src/main/java/cn/nukkit/inventory/CraftingGrid.java index 651225745a..60351996f8 100644 --- a/src/main/java/cn/nukkit/inventory/CraftingGrid.java +++ b/src/main/java/cn/nukkit/inventory/CraftingGrid.java @@ -12,7 +12,8 @@ public CraftingGrid(InventoryHolder holder) { super(holder, InventoryType.CRAFTING); } - public int getDefaultSize() { + @Override + public int getSize() { return 4; } diff --git a/src/main/java/cn/nukkit/inventory/Recipe.java b/src/main/java/cn/nukkit/inventory/Recipe.java index 5fcaa90a11..a5c0a42973 100644 --- a/src/main/java/cn/nukkit/inventory/Recipe.java +++ b/src/main/java/cn/nukkit/inventory/Recipe.java @@ -17,4 +17,8 @@ public interface Recipe { UUID getId(); void setId(UUID id); + + default boolean requiresCraftingTable() { + return false; + } } diff --git a/src/main/java/cn/nukkit/inventory/ShapedRecipe.java b/src/main/java/cn/nukkit/inventory/ShapedRecipe.java index 38b454a227..f479015760 100644 --- a/src/main/java/cn/nukkit/inventory/ShapedRecipe.java +++ b/src/main/java/cn/nukkit/inventory/ShapedRecipe.java @@ -134,6 +134,11 @@ public void registerToCraftingManager() { Server.getInstance().getCraftingManager().registerShapedRecipe(this); } + @Override + public boolean requiresCraftingTable() { + return this.getHeight() > 2 || this.getWidth() > 2; + } + public static class Entry { public final int x; public final int y; diff --git a/src/main/java/cn/nukkit/inventory/ShapelessRecipe.java b/src/main/java/cn/nukkit/inventory/ShapelessRecipe.java index cb813a04aa..8892a80ecd 100644 --- a/src/main/java/cn/nukkit/inventory/ShapelessRecipe.java +++ b/src/main/java/cn/nukkit/inventory/ShapelessRecipe.java @@ -94,4 +94,9 @@ public int getIngredientCount() { public void registerToCraftingManager() { Server.getInstance().getCraftingManager().registerShapelessRecipe(this); } + + @Override + public boolean requiresCraftingTable() { + return this.ingredients.size() > 4; + } } diff --git a/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java index 158779053d..0da5910ed3 100644 --- a/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java +++ b/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java @@ -212,7 +212,15 @@ public boolean execute() { InventoryTransactionEvent ev = new InventoryTransactionEvent(this); Server.getInstance().getPluginManager().callEvent(ev); if (ev.isCancelled()) { - return false; + this.handleFailed(); + return true; + } + + for (InventoryAction action : this.actions) { + if (!action.onPreExecute(this.source)) { + this.handleFailed(); + return true; + } } for (InventoryAction action : this.actions) { @@ -227,6 +235,12 @@ public boolean execute() { return true; } + protected void handleFailed() { + for (InventoryAction action : this.actions) { + action.onExecuteFail(this.source); + } + } + public boolean hasExecuted() { return this.hasExecuted; } diff --git a/src/main/java/cn/nukkit/inventory/transaction/action/DropItemAction.java b/src/main/java/cn/nukkit/inventory/transaction/action/DropItemAction.java index cd641e43b1..b2cdea9ddf 100644 --- a/src/main/java/cn/nukkit/inventory/transaction/action/DropItemAction.java +++ b/src/main/java/cn/nukkit/inventory/transaction/action/DropItemAction.java @@ -1,6 +1,7 @@ package cn.nukkit.inventory.transaction.action; import cn.nukkit.Player; +import cn.nukkit.event.player.PlayerDropItemEvent; import cn.nukkit.item.Item; /** @@ -20,6 +21,17 @@ public boolean isValid(Player source) { return this.sourceItem.isNull(); } + @Override + public boolean onPreExecute(Player source) { + PlayerDropItemEvent ev; + source.getServer().getPluginManager().callEvent(ev = new PlayerDropItemEvent(source, this.targetItem)); + if (ev.isCancelled()) { + return false; + } + + return true; + } + /** * Drops the target item in front of the player. */ diff --git a/src/main/java/cn/nukkit/inventory/transaction/action/InventoryAction.java b/src/main/java/cn/nukkit/inventory/transaction/action/InventoryAction.java index 2760a1e841..e853cbe085 100644 --- a/src/main/java/cn/nukkit/inventory/transaction/action/InventoryAction.java +++ b/src/main/java/cn/nukkit/inventory/transaction/action/InventoryAction.java @@ -42,6 +42,14 @@ public Item getTargetItem() { return targetItem.clone(); } + /** + * Called by inventory transactions before any actions are processed. If this returns false, the transaction will + * be cancelled. + */ + public boolean onPreExecute(Player source) { + return true; + } + /** * Returns whether this action is currently valid. This should perform any necessary sanity checks. */ diff --git a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java index d1da6718d5..e71095e997 100644 --- a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java +++ b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java @@ -151,9 +151,18 @@ public InventoryAction createInventoryAction(Player player) { switch (this.windowId) { case SOURCE_TYPE_CRAFTING_ADD_INGREDIENT: case SOURCE_TYPE_CRAFTING_REMOVE_INGREDIENT: + System.out.println("crafting change ingredient, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); window = player.getCraftingGrid(); return new SlotChangeAction(window, this.inventorySlot, this.oldItem, this.newItem); + case SOURCE_TYPE_CRAFTING_RESULT: + window = player.getCraftingGrid(); + //return new SlotChangeAction(window, this.inventorySlot, this.); + System.out.println("crafting result, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); + break; + case SOURCE_TYPE_CRAFTING_USE_INGREDIENT: + System.out.println("crafting use ingredient, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); + break; case SOURCE_TYPE_CONTAINER_DROP_CONTENTS: //TODO: this type applies to all fake windows, not just crafting window = player.getCraftingGrid(); @@ -161,15 +170,15 @@ public InventoryAction createInventoryAction(Player player) { //DROP_CONTENTS doesn't bother telling us what inventorySlot the item is in, so we find it ourselves inventorySlot = window.first(this.oldItem, true); if (inventorySlot == -1) { - throw new RuntimeException("Fake container " + window.getClass().getName() + " for " + player.getName() + " does not contain $this->oldItem"); + throw new RuntimeException("Fake container " + window.getClass().getName() + " for " + player.getName() + " does not contain " + this.oldItem); } return new SlotChangeAction(window, inventorySlot, this.oldItem, this.newItem); } //TODO: more stuff - throw new RuntimeException("Player " + player.getName() + " has no open container with window ID $this->windowId"); + throw new RuntimeException("Player " + player.getName() + " has no open container with window ID " + this.windowId); default: - throw new RuntimeException("Unknown inventory source type $this->sourceType"); + throw new RuntimeException("Unknown inventory source type " + this.sourceType); } } } From ba62ada1f1d1b7cbc299a11b83c681b74acdf0e8 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 21 Sep 2017 21:32:43 +0200 Subject: [PATCH 083/175] fixed entity IDs --- src/main/java/cn/nukkit/Player.java | 14 ++++----- .../network/protocol/AddEntityPacket.java | 4 +-- .../network/protocol/AddItemEntityPacket.java | 4 +-- .../network/protocol/AddPaintingPacket.java | 4 +-- .../network/protocol/AddPlayerPacket.java | 4 +-- .../network/protocol/AnimatePacket.java | 4 +-- .../network/protocol/BossEventPacket.java | 8 ++--- .../nukkit/network/protocol/CameraPacket.java | 4 +-- .../ClientboundMapItemDataPacket.java | 6 ++-- .../protocol/CommandBlockUpdatePacket.java | 4 +-- .../network/protocol/ContainerOpenPacket.java | 11 +++++-- .../network/protocol/EntityEventPacket.java | 8 ++--- .../network/protocol/EntityFallPacket.java | 2 +- .../protocol/GUIDataPickItemPacket.java | 7 +++-- .../network/protocol/InteractPacket.java | 4 +-- .../protocol/InventoryTransactionPacket.java | 8 ++--- .../protocol/MapInfoRequestPacket.java | 2 +- .../protocol/MobArmorEquipmentPacket.java | 4 +-- .../network/protocol/MobEffectPacket.java | 2 +- .../network/protocol/MobEquipmentPacket.java | 4 +-- .../network/protocol/MoveEntityPacket.java | 4 +-- .../network/protocol/MovePlayerPacket.java | 8 ++--- .../network/protocol/PlayerActionPacket.java | 4 +-- .../network/protocol/PlayerListPacket.java | 8 +++++ .../network/protocol/RemoveEntityPacket.java | 2 +- .../network/protocol/SetEntityDataPacket.java | 2 +- .../network/protocol/SetEntityLinkPacket.java | 4 +-- .../protocol/SetEntityMotionPacket.java | 2 +- .../network/protocol/ShowCreditsPacket.java | 2 +- .../network/protocol/StartGamePacket.java | 8 ++--- .../protocol/UpdateAttributesPacket.java | 2 +- .../protocol/UpdateEquipmentPacket.java | 2 +- .../network/protocol/UpdateTradePacket.java | 12 ++++---- .../types/NetworkInventoryAction.java | 8 ++--- .../java/cn/nukkit/utils/BinaryStream.java | 30 +++++++++++++++++++ 35 files changed, 127 insertions(+), 79 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 30b1eaf703..26ade9d074 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -438,7 +438,6 @@ public void setOp(boolean value) { this.recalculatePermissions(); this.getAdventureSettings().update(); this.sendCommandData(); - this.inventory.sendCreativeContents(); } @Override @@ -1888,7 +1887,7 @@ protected void processLogin() { startGamePacket.pitch = (float) this.pitch; startGamePacket.seed = -1; startGamePacket.dimension = (byte) (this.level.getDimension() & 0xff); - startGamePacket.gamemode = getClientFriendlyGamemode(this.gamemode); + startGamePacket.worldGamemode = getClientFriendlyGamemode(this.gamemode); startGamePacket.difficulty = this.server.getDifficulty(); startGamePacket.spawnX = (int) spawnPosition.x; startGamePacket.spawnY = (int) spawnPosition.y; @@ -1930,13 +1929,10 @@ protected void processLogin() { if (this.gamemode == Player.SPECTATOR) { InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); - inventoryContentPacket.inventoryId = InventoryContentPacket.SPECIAL_CREATIVE; + inventoryContentPacket.inventoryId = ContainerIds.CREATIVE; this.dataPacket(inventoryContentPacket); } else { - InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); - inventoryContentPacket.inventoryId = InventoryContentPacket.SPECIAL_CREATIVE; - inventoryContentPacket.slots = Item.getCreativeItems().stream().toArray(Item[]::new); - this.dataPacket(inventoryContentPacket); + this.inventory.sendCreativeContents(); } this.setEnableClientCommand(true); @@ -3370,6 +3366,10 @@ public void handleDataPacket(DataPacket packet) { case InventoryTransactionPacket.TYPE_USE_ITEM_ON_ENTITY: UseItemOnEntityData useItemOnEntityData = (UseItemOnEntityData) transactionPacket.transactionData; + if (useItemOnEntityData.entityRuntimeId % 2 == 0) { + useItemOnEntityData.entityRuntimeId /= 2; //wtf is that + } + Entity target = this.level.getEntity(useItemOnEntityData.entityRuntimeId); if (target == null) { return; diff --git a/src/main/java/cn/nukkit/network/protocol/AddEntityPacket.java b/src/main/java/cn/nukkit/network/protocol/AddEntityPacket.java index 98ec3b0f3e..c0df2caf39 100644 --- a/src/main/java/cn/nukkit/network/protocol/AddEntityPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/AddEntityPacket.java @@ -39,8 +39,8 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.entityUniqueId); - this.putVarLong(this.entityRuntimeId); + this.putEntityUniqueId(this.entityUniqueId); + this.putEntityRuntimeId(this.entityRuntimeId); this.putUnsignedVarInt(this.type); this.putVector3f(this.x, this.y, this.z); this.putVector3f(this.speedX, this.speedY, this.speedZ); diff --git a/src/main/java/cn/nukkit/network/protocol/AddItemEntityPacket.java b/src/main/java/cn/nukkit/network/protocol/AddItemEntityPacket.java index c22085541c..9a6904e7f5 100644 --- a/src/main/java/cn/nukkit/network/protocol/AddItemEntityPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/AddItemEntityPacket.java @@ -35,8 +35,8 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.entityUniqueId); - this.putVarLong(this.entityRuntimeId); + this.putEntityUniqueId(this.entityUniqueId); + this.putEntityRuntimeId(this.entityRuntimeId); this.putSlot(this.item); this.putVector3f(this.x, this.y, this.z); this.putVector3f(this.speedX, this.speedY, this.speedZ); diff --git a/src/main/java/cn/nukkit/network/protocol/AddPaintingPacket.java b/src/main/java/cn/nukkit/network/protocol/AddPaintingPacket.java index 8b4e03c247..3c07331314 100644 --- a/src/main/java/cn/nukkit/network/protocol/AddPaintingPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/AddPaintingPacket.java @@ -23,8 +23,8 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.entityUniqueId); - this.putVarLong(this.entityRuntimeId); + this.putEntityUniqueId(this.entityUniqueId); + this.putEntityRuntimeId(this.entityRuntimeId); 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/AddPlayerPacket.java b/src/main/java/cn/nukkit/network/protocol/AddPlayerPacket.java index 3accf53984..6c211d3db6 100644 --- a/src/main/java/cn/nukkit/network/protocol/AddPlayerPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/AddPlayerPacket.java @@ -43,8 +43,8 @@ public void encode() { this.reset(); this.putUUID(this.uuid); this.putString(this.username); - this.putVarLong(this.entityUniqueId); - this.putVarLong(this.entityRuntimeId); + this.putEntityUniqueId(this.entityUniqueId); + this.putEntityRuntimeId(this.entityRuntimeId); this.putVector3f(this.x, this.y, this.z); this.putVector3f(this.speedX, this.speedY, this.speedZ); this.putLFloat(this.pitch); diff --git a/src/main/java/cn/nukkit/network/protocol/AnimatePacket.java b/src/main/java/cn/nukkit/network/protocol/AnimatePacket.java index 562b378827..87abc99036 100644 --- a/src/main/java/cn/nukkit/network/protocol/AnimatePacket.java +++ b/src/main/java/cn/nukkit/network/protocol/AnimatePacket.java @@ -14,7 +14,7 @@ public class AnimatePacket extends DataPacket { @Override public void decode() { this.action = this.getVarInt(); - this.eid = getVarLong(); + this.eid = getEntityRuntimeId(); if ((this.action & 0x80) != 0) { this.unknown = this.getLFloat(); } @@ -24,7 +24,7 @@ public void decode() { public void encode() { this.reset(); this.putVarInt(this.action); - this.putVarLong(this.eid); + this.putEntityRuntimeId(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 5d1de53edf..1b52ddc078 100644 --- a/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java @@ -40,12 +40,12 @@ public byte pid() { @Override public void decode() { - this.bossEid = this.getVarLong(); + this.bossEid = this.getEntityUniqueId(); this.type = (int) this.getUnsignedVarInt(); switch (this.type) { case TYPE_REGISTER_PLAYER: case TYPE_UNREGISTER_PLAYER: - this.playerEid = this.getLong(); + this.playerEid = this.getEntityUniqueId(); break; case TYPE_SHOW: this.title = this.getString(); @@ -68,12 +68,12 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.bossEid); + this.putEntityUniqueId(this.bossEid); this.putUnsignedVarInt(this.type); switch (this.type) { case TYPE_REGISTER_PLAYER: case TYPE_UNREGISTER_PLAYER: - this.putLong(this.playerEid); + this.putEntityUniqueId(this.playerEid); break; case TYPE_SHOW: this.putString(this.title); diff --git a/src/main/java/cn/nukkit/network/protocol/CameraPacket.java b/src/main/java/cn/nukkit/network/protocol/CameraPacket.java index 98ddcf8629..7f0c092dc3 100644 --- a/src/main/java/cn/nukkit/network/protocol/CameraPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/CameraPacket.java @@ -19,7 +19,7 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.cameraUniqueId); - this.putVarLong(this.playerUniqueId); + this.putEntityUniqueId(this.cameraUniqueId); + this.putEntityUniqueId(this.playerUniqueId); } } diff --git a/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java b/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java index 1090e36ba6..5e8b531477 100644 --- a/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/ClientboundMapItemDataPacket.java @@ -8,7 +8,7 @@ /** * Created by CreeperFace on 5.3.2017. */ -public class ClientboundMapItemDataPacket extends DataPacket { +public class ClientboundMapItemDataPacket extends DataPacket { //TODO: update to 1.2 public int[] eids = new int[0]; @@ -44,7 +44,7 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(mapId); + this.putEntityUniqueId(mapId); int update = 0; if (eids.length > 0) { @@ -64,7 +64,7 @@ public void encode() { if ((update & 0x08) != 0) { //TODO: find out what these are for this.putUnsignedVarInt(eids.length); for (int eid : eids) { - this.putVarInt(eid); + this.putEntityUniqueId(eid); } } if ((update & (TEXTURE_UPDATE | DECORATIONS_UPDATE)) != 0) { diff --git a/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java b/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java index fbd9ef3236..c8784d1fb7 100644 --- a/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java +++ b/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java @@ -34,7 +34,7 @@ public void decode() { this.isRedstoneMode = this.getBoolean(); this.isConditional = this.getBoolean(); } else { - this.minecartEid = this.getVarLong(); + this.minecartEid = this.getEntityRuntimeId(); } this.command = this.getString(); this.lastOutput = this.getString(); @@ -51,7 +51,7 @@ public void encode() { this.putBoolean(this.isRedstoneMode); this.putBoolean(this.isConditional); } else { - this.putVarLong(this.minecartEid); + this.putEntityRuntimeId(this.minecartEid); } this.putString(this.command); this.putString(this.lastOutput); diff --git a/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java b/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java index 754f8b6b11..9ba871c569 100644 --- a/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/ContainerOpenPacket.java @@ -1,5 +1,7 @@ package cn.nukkit.network.protocol; +import cn.nukkit.math.BlockVector3; + /** * author: MagicDroidX * Nukkit Project @@ -17,12 +19,17 @@ public byte pid() { public int x; public int y; public int z; - public final long entityId = -1; + public long entityId = -1; @Override public void decode() { this.windowId = this.getByte(); this.type = this.getByte(); + BlockVector3 v = this.getBlockVector3(); + this.x = v.x; + this.y = v.y; + this.z = v.z; + this.entityId = this.getEntityUniqueId(); } @Override @@ -31,6 +38,6 @@ public void encode() { this.putByte((byte) this.windowId); this.putByte((byte) this.type); this.putBlockVector3(this.x, this.y, this.z); - this.putVarLong(this.entityId); + this.putEntityUniqueId(this.entityId); } } diff --git a/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java b/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java index 1e9dbfde96..6fdd0bf9c5 100644 --- a/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java @@ -44,16 +44,16 @@ public byte pid() { @Override public void decode() { - this.eid = this.getVarLong(); + this.eid = this.getEntityRuntimeId(); this.event = this.getByte(); - this.type = this.getByte(); + this.type = this.getVarInt(); } @Override public void encode() { this.reset(); - this.putVarLong(this.eid); + this.putEntityRuntimeId(this.eid); this.putByte((byte) this.event); - this.putByte((byte) this.type); + this.putVarInt((byte) this.type); } } diff --git a/src/main/java/cn/nukkit/network/protocol/EntityFallPacket.java b/src/main/java/cn/nukkit/network/protocol/EntityFallPacket.java index ae876b029d..086fc56a6b 100644 --- a/src/main/java/cn/nukkit/network/protocol/EntityFallPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/EntityFallPacket.java @@ -9,7 +9,7 @@ public class EntityFallPacket extends DataPacket { @Override public void decode() { - this.eid = this.getVarLong(); + this.eid = this.getEntityRuntimeId(); this.fallDistance = this.getLFloat(); this.unknown = this.getBoolean(); } diff --git a/src/main/java/cn/nukkit/network/protocol/GUIDataPickItemPacket.java b/src/main/java/cn/nukkit/network/protocol/GUIDataPickItemPacket.java index 6f33b7ac7b..6cbc80ca1f 100644 --- a/src/main/java/cn/nukkit/network/protocol/GUIDataPickItemPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/GUIDataPickItemPacket.java @@ -2,6 +2,8 @@ public class GUIDataPickItemPacket extends DataPacket { + public int hotbarSlot; + @Override public byte pid() { return ProtocolInfo.GUI_DATA_PICK_ITEM_PACKET; @@ -9,11 +11,12 @@ public byte pid() { @Override public void encode() { - //TODO + this.reset(); + this.putLInt(this.hotbarSlot); } @Override public void decode() { - + this.hotbarSlot = this.getLInt(); } } diff --git a/src/main/java/cn/nukkit/network/protocol/InteractPacket.java b/src/main/java/cn/nukkit/network/protocol/InteractPacket.java index 62572dbc6e..e909160c28 100644 --- a/src/main/java/cn/nukkit/network/protocol/InteractPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/InteractPacket.java @@ -18,14 +18,14 @@ public class InteractPacket extends DataPacket { @Override public void decode() { this.action = this.getByte(); - this.target = this.getVarLong(); + this.target = this.getEntityRuntimeId(); } @Override public void encode() { this.reset(); this.putByte((byte) this.action); - this.putVarLong(this.target); + this.putEntityRuntimeId(this.target); } @Override diff --git a/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java b/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java index 56bb403c24..0d27e02a92 100644 --- a/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java @@ -67,7 +67,7 @@ public void encode() { case TYPE_USE_ITEM_ON_ENTITY: UseItemOnEntityData useItemOnEntityData = (UseItemOnEntityData) this.transactionData; - this.putUnsignedVarInt(useItemOnEntityData.entityRuntimeId); + this.putEntityRuntimeId(useItemOnEntityData.entityRuntimeId); this.putUnsignedVarInt(useItemOnEntityData.actionType); this.putVarInt(useItemOnEntityData.hotbarSlot); this.putSlot(useItemOnEntityData.itemInHand); @@ -83,7 +83,7 @@ public void encode() { this.putVector3f(releaseItemData.headRot.asVector3f()); break; default: - throw new RuntimeException("Unknown transaction type $this->transactionType"); + throw new RuntimeException("Unknown transaction type " + this.transactionType); } } @@ -117,7 +117,7 @@ public void decode() { case TYPE_USE_ITEM_ON_ENTITY: UseItemOnEntityData useItemOnEntityData = new UseItemOnEntityData(); - useItemOnEntityData.entityRuntimeId = this.getUnsignedVarLong(); + useItemOnEntityData.entityRuntimeId = this.getEntityRuntimeId(); useItemOnEntityData.actionType = (int) this.getUnsignedVarInt(); useItemOnEntityData.hotbarSlot = this.getVarInt(); useItemOnEntityData.itemInHand = this.getSlot(); @@ -137,7 +137,7 @@ public void decode() { this.transactionData = releaseItemData; break; default: - throw new RuntimeException("Unknown transaction type $this->transactionType"); + throw new RuntimeException("Unknown transaction type " + this.transactionType); } } } diff --git a/src/main/java/cn/nukkit/network/protocol/MapInfoRequestPacket.java b/src/main/java/cn/nukkit/network/protocol/MapInfoRequestPacket.java index 0edf1e43f8..f28d1a46c6 100644 --- a/src/main/java/cn/nukkit/network/protocol/MapInfoRequestPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/MapInfoRequestPacket.java @@ -13,7 +13,7 @@ public byte pid() { @Override public void decode() { - mapId = this.getVarLong(); + mapId = this.getEntityUniqueId(); } @Override diff --git a/src/main/java/cn/nukkit/network/protocol/MobArmorEquipmentPacket.java b/src/main/java/cn/nukkit/network/protocol/MobArmorEquipmentPacket.java index fa26b06c87..b34c6fc013 100644 --- a/src/main/java/cn/nukkit/network/protocol/MobArmorEquipmentPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/MobArmorEquipmentPacket.java @@ -19,7 +19,7 @@ public byte pid() { @Override public void decode() { - this.eid = this.getVarLong(); + this.eid = this.getEntityRuntimeId(); this.slots = new Item[4]; this.slots[0] = this.getSlot(); this.slots[1] = this.getSlot(); @@ -30,7 +30,7 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.eid); + this.putEntityRuntimeId(this.eid); this.putSlot(this.slots[0]); this.putSlot(this.slots[1]); this.putSlot(this.slots[2]); diff --git a/src/main/java/cn/nukkit/network/protocol/MobEffectPacket.java b/src/main/java/cn/nukkit/network/protocol/MobEffectPacket.java index afa89f0f5d..c04a3f23ef 100644 --- a/src/main/java/cn/nukkit/network/protocol/MobEffectPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/MobEffectPacket.java @@ -32,7 +32,7 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.eid); + this.putEntityRuntimeId(this.eid); this.putByte((byte) this.eventId); this.putVarInt(this.effectId); this.putVarInt(this.amplifier); diff --git a/src/main/java/cn/nukkit/network/protocol/MobEquipmentPacket.java b/src/main/java/cn/nukkit/network/protocol/MobEquipmentPacket.java index 90380470e8..22c0033d1e 100644 --- a/src/main/java/cn/nukkit/network/protocol/MobEquipmentPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/MobEquipmentPacket.java @@ -22,7 +22,7 @@ public byte pid() { @Override public void decode() { - this.eid = this.getVarLong(); //EntityRuntimeID + this.eid = this.getEntityRuntimeId(); //EntityRuntimeID this.item = this.getSlot(); this.inventorySlot = this.getByte(); this.hotbarSlot = this.getByte(); @@ -32,7 +32,7 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.eid); //EntityRuntimeID + this.putEntityRuntimeId(this.eid); //EntityRuntimeID this.putSlot(this.item); this.putByte((byte) this.inventorySlot); this.putByte((byte) this.hotbarSlot); diff --git a/src/main/java/cn/nukkit/network/protocol/MoveEntityPacket.java b/src/main/java/cn/nukkit/network/protocol/MoveEntityPacket.java index 5ff8ba1f0d..9fef170c0f 100644 --- a/src/main/java/cn/nukkit/network/protocol/MoveEntityPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/MoveEntityPacket.java @@ -26,7 +26,7 @@ public byte pid() { @Override public void decode() { - this.eid = this.getVarLong(); + this.eid = this.getEntityRuntimeId(); Vector3f v = this.getVector3f(); this.x = v.x; this.y = v.y; @@ -41,7 +41,7 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.eid); + this.putEntityRuntimeId(this.eid); this.putVector3f((float) this.x, (float) this.y, (float) this.z); this.putByte((byte) (this.pitch / (360d / 256d))); this.putByte((byte) (this.headYaw / (360d / 256d))); diff --git a/src/main/java/cn/nukkit/network/protocol/MovePlayerPacket.java b/src/main/java/cn/nukkit/network/protocol/MovePlayerPacket.java index 25478aaf61..41e11ec247 100644 --- a/src/main/java/cn/nukkit/network/protocol/MovePlayerPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/MovePlayerPacket.java @@ -29,7 +29,7 @@ public class MovePlayerPacket extends DataPacket { @Override public void decode() { - this.eid = this.getVarLong(); + this.eid = this.getEntityRuntimeId(); Vector3f v = this.getVector3f(); this.x = v.x; this.y = v.y; @@ -39,7 +39,7 @@ public void decode() { this.yaw = this.getLFloat(); this.mode = this.getByte(); this.onGround = this.getBoolean(); - this.ridingEid = this.getVarLong(); + this.ridingEid = this.getEntityRuntimeId(); if (this.mode == MODE_TELEPORT) { this.int1 = this.getLInt(); this.int2 = this.getLInt(); @@ -49,14 +49,14 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.eid); + this.putEntityRuntimeId(this.eid); this.putVector3f(this.x, this.y, this.z); this.putLFloat(this.pitch); this.putLFloat(this.yaw); this.putLFloat(this.headYaw); this.putByte((byte) this.mode); this.putBoolean(this.onGround); - this.putVarLong(this.ridingEid); + this.putEntityRuntimeId(this.ridingEid); if (this.mode == MODE_TELEPORT) { this.putLInt(this.int1); this.putLInt(this.int2); diff --git a/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java b/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java index d70e47b7c2..cab869e93b 100644 --- a/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/PlayerActionPacket.java @@ -39,7 +39,7 @@ public class PlayerActionPacket extends DataPacket { @Override public void decode() { - this.entityId = this.getVarLong(); + this.entityId = this.getEntityRuntimeId(); this.action = this.getVarInt(); BlockVector3 v = this.getBlockVector3(); this.x = v.x; @@ -51,7 +51,7 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.entityId); + this.putEntityRuntimeId(this.entityId); this.putVarInt(this.action); this.putBlockVector3(this.x, this.y, this.z); this.putVarInt(this.face); diff --git a/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java b/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java index 09bb760ce8..b071951a88 100644 --- a/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java @@ -33,6 +33,10 @@ public void encode() { this.putVarLong(entry.entityId); this.putString(entry.name); this.putSkin(entry.skin); + this.putByteArray(entry.capeData); + this.putString(entry.geometryModel); + this.putByteArray(entry.geometryData); + this.putString(entry.xboxUserId); } else { this.putUUID(entry.uuid); } @@ -51,6 +55,10 @@ public static class Entry { public long entityId = 0; public String name = ""; public Skin skin; + public byte[] capeData = new byte[0]; //TODO + public String geometryModel = ""; + public byte[] geometryData = new byte[0]; //TODO + public String xboxUserId = ""; //TODO public Entry(UUID uuid) { this.uuid = uuid; diff --git a/src/main/java/cn/nukkit/network/protocol/RemoveEntityPacket.java b/src/main/java/cn/nukkit/network/protocol/RemoveEntityPacket.java index 46cba714f1..1d5ac0dded 100644 --- a/src/main/java/cn/nukkit/network/protocol/RemoveEntityPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/RemoveEntityPacket.java @@ -22,6 +22,6 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.eid); + this.putEntityUniqueId(this.eid); } } diff --git a/src/main/java/cn/nukkit/network/protocol/SetEntityDataPacket.java b/src/main/java/cn/nukkit/network/protocol/SetEntityDataPacket.java index f15027cdb7..49e90f1b0e 100644 --- a/src/main/java/cn/nukkit/network/protocol/SetEntityDataPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/SetEntityDataPacket.java @@ -26,7 +26,7 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.eid); + this.putEntityRuntimeId(this.eid); this.put(Binary.writeMetadata(this.metadata)); } } diff --git a/src/main/java/cn/nukkit/network/protocol/SetEntityLinkPacket.java b/src/main/java/cn/nukkit/network/protocol/SetEntityLinkPacket.java index da60c96b78..2a6218dc86 100644 --- a/src/main/java/cn/nukkit/network/protocol/SetEntityLinkPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/SetEntityLinkPacket.java @@ -23,8 +23,8 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.rider); - this.putVarLong(this.riding); + this.putEntityRuntimeId(this.rider); + this.putEntityRuntimeId(this.riding); this.putByte(this.type); } diff --git a/src/main/java/cn/nukkit/network/protocol/SetEntityMotionPacket.java b/src/main/java/cn/nukkit/network/protocol/SetEntityMotionPacket.java index 7ee5d898ed..7aa9ae9f09 100644 --- a/src/main/java/cn/nukkit/network/protocol/SetEntityMotionPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/SetEntityMotionPacket.java @@ -25,7 +25,7 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.eid); + this.putEntityRuntimeId(this.eid); this.putVector3f(this.motionX, this.motionY, this.motionZ); } } diff --git a/src/main/java/cn/nukkit/network/protocol/ShowCreditsPacket.java b/src/main/java/cn/nukkit/network/protocol/ShowCreditsPacket.java index 113cb11f0a..500ab9099b 100644 --- a/src/main/java/cn/nukkit/network/protocol/ShowCreditsPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/ShowCreditsPacket.java @@ -22,7 +22,7 @@ public void decode() { @Override public void encode() { - this.putVarLong(this.eid); + this.putEntityRuntimeId(this.eid); this.putVarInt(this.status); } } diff --git a/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java b/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java index bb334a0520..a376b6abe1 100644 --- a/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java +++ b/src/main/java/cn/nukkit/network/protocol/StartGamePacket.java @@ -25,7 +25,7 @@ public byte pid() { public int seed; public byte dimension; public int generator = 1; - public int gamemode; + public int worldGamemode; public int difficulty; public int spawnX; public int spawnY; @@ -61,8 +61,8 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.entityUniqueId); - this.putVarLong(this.entityRuntimeId); + this.putEntityUniqueId(this.entityUniqueId); + this.putEntityRuntimeId(this.entityRuntimeId); this.putVarInt(this.playerGamemode); this.putVector3f(this.x, this.y, this.z); this.putLFloat(this.yaw); @@ -70,7 +70,7 @@ public void encode() { this.putVarInt(this.seed); this.putVarInt(this.dimension); this.putVarInt(this.generator); - this.putVarInt(this.gamemode); + this.putVarInt(this.worldGamemode); this.putVarInt(this.difficulty); this.putBlockVector3(this.spawnX, this.spawnY, this.spawnZ); this.putBoolean(this.hasAchievementsDisabled); diff --git a/src/main/java/cn/nukkit/network/protocol/UpdateAttributesPacket.java b/src/main/java/cn/nukkit/network/protocol/UpdateAttributesPacket.java index eef6281ac6..d720f86e5f 100644 --- a/src/main/java/cn/nukkit/network/protocol/UpdateAttributesPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/UpdateAttributesPacket.java @@ -24,7 +24,7 @@ public void decode() { public void encode() { this.reset(); - this.putVarLong(this.entityId); + this.putEntityRuntimeId(this.entityId); if (this.entries == null) { this.putUnsignedVarInt(0); diff --git a/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java b/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java index 5d45fd2d3f..bbd9125d16 100644 --- a/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java @@ -23,7 +23,7 @@ public void decode() { public void encode() { this.putByte((byte) this.windowId); this.putByte((byte) this.windowType); - this.putVarLong(this.eid); + this.putEntityUniqueId(this.eid); this.put(this.namedtag); } } diff --git a/src/main/java/cn/nukkit/network/protocol/UpdateTradePacket.java b/src/main/java/cn/nukkit/network/protocol/UpdateTradePacket.java index 129ed4605e..c1d61d1bbc 100644 --- a/src/main/java/cn/nukkit/network/protocol/UpdateTradePacket.java +++ b/src/main/java/cn/nukkit/network/protocol/UpdateTradePacket.java @@ -4,8 +4,8 @@ public class UpdateTradePacket extends DataPacket { public static final byte NETWORK_ID = ProtocolInfo.UPDATE_TRADE_PACKET; - public byte unknownByte1; - public byte unknownByte2; + public byte windowId; + public byte windowType = 15; //trading id public int unknownVarInt1; public int unknownVarInt2; public boolean isWilling; @@ -26,13 +26,13 @@ public void decode() { @Override public void encode() { - this.putByte(unknownByte1); - this.putByte(unknownByte2); + this.putByte(windowId); + this.putByte(windowType); this.putVarInt(unknownVarInt1); this.putVarInt(unknownVarInt2); this.putBoolean(isWilling); - this.putVarLong(player); - this.putVarLong(trader); + this.putEntityUniqueId(player); + this.putEntityUniqueId(trader); this.putString(displayName); this.put(this.offers); } diff --git a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java index e71095e997..7dc339c0b7 100644 --- a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java +++ b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java @@ -150,18 +150,18 @@ public InventoryAction createInventoryAction(Player player) { //These types need special handling. switch (this.windowId) { case SOURCE_TYPE_CRAFTING_ADD_INGREDIENT: - case SOURCE_TYPE_CRAFTING_REMOVE_INGREDIENT: - System.out.println("crafting change ingredient, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); + case SOURCE_TYPE_CRAFTING_REMOVE_INGREDIENT: //TODO: a lot + //System.out.println("crafting change ingredient, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); window = player.getCraftingGrid(); return new SlotChangeAction(window, this.inventorySlot, this.oldItem, this.newItem); case SOURCE_TYPE_CRAFTING_RESULT: window = player.getCraftingGrid(); //return new SlotChangeAction(window, this.inventorySlot, this.); - System.out.println("crafting result, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); + //System.out.println("crafting result, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); break; case SOURCE_TYPE_CRAFTING_USE_INGREDIENT: - System.out.println("crafting use ingredient, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); + //System.out.println("crafting use ingredient, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); break; case SOURCE_TYPE_CONTAINER_DROP_CONTENTS: //TODO: this type applies to all fake windows, not just crafting diff --git a/src/main/java/cn/nukkit/utils/BinaryStream.java b/src/main/java/cn/nukkit/utils/BinaryStream.java index a61cc8cb84..e0f7df845f 100644 --- a/src/main/java/cn/nukkit/utils/BinaryStream.java +++ b/src/main/java/cn/nukkit/utils/BinaryStream.java @@ -407,6 +407,36 @@ public void putRuleData(RuleData rule) { this.putBoolean(rule.unknown2); } + /** + * Reads and returns an EntityUniqueID + * + * @return int + */ + public long getEntityUniqueId() { + return this.getVarLong(); + } + + /** + * Writes an EntityUniqueID + */ + public void putEntityUniqueId(long eid) { + this.putVarLong(eid); + } + + /** + * Reads and returns an EntityRuntimeID + */ + public long getEntityRuntimeId() { + return this.getUnsignedVarLong(); + } + + /** + * Writes an EntityUniqueID + */ + public void putEntityRuntimeId(long eid) { + this.putUnsignedVarLong(eid); + } + public BlockFace getBlockFace() { return BlockFace.fromIndex(this.getVarInt()); } From 3d4e6c6099e77d9ff080294fecf6c31cf38e38c8 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 21 Sep 2017 22:02:13 +0200 Subject: [PATCH 084/175] more adventure settings --- .../java/cn/nukkit/AdventureSettings.java | 163 +++++------------- src/main/java/cn/nukkit/Player.java | 41 ++--- 2 files changed, 61 insertions(+), 143 deletions(-) diff --git a/src/main/java/cn/nukkit/AdventureSettings.java b/src/main/java/cn/nukkit/AdventureSettings.java index ab804cfc9b..0ac5b80eca 100644 --- a/src/main/java/cn/nukkit/AdventureSettings.java +++ b/src/main/java/cn/nukkit/AdventureSettings.java @@ -2,6 +2,10 @@ import cn.nukkit.network.protocol.AdventureSettingsPacket; +import java.util.EnumMap; +import java.util.Map; +import java.util.Map.Entry; + /** * Nukkit Project * Author: MagicDroidX @@ -14,29 +18,10 @@ public class AdventureSettings implements Cloneable { public static final int PERMISSION_AUTOMATION = 3; public static final int PERMISSION_ADMIN = 4; - private boolean canDestroyBlock = true; - - private boolean autoJump = true; - - private boolean canFly = false; - - private boolean flying = false; - - private boolean noclip = false; - - private boolean noPvp = false; - - private boolean noPvm = false; - - private boolean noMvp = false; - - private boolean muted = false; + private Map values = new EnumMap<>(Type.class); private Player player; - private AdventureSettings() { - } - public AdventureSettings clone(Player newPlayer) { try { AdventureSettings settings = (AdventureSettings) super.clone(); @@ -47,87 +32,22 @@ public AdventureSettings clone(Player newPlayer) { } } - public void setCanDestroyBlock(boolean canDestroyBlock) { - this.canDestroyBlock = canDestroyBlock; - } - - public void setAutoJump(boolean autoJump) { - this.autoJump = autoJump; + public AdventureSettings set(Type type, boolean value) { + this.values.put(type, value); + return this; } - public void setCanFly(boolean canFly) { - this.canFly = canFly; - } - - public void setFlying(boolean flying) { - this.flying = flying; - } - - public void setNoclip(boolean noclip) { - this.noclip = noclip; - } - - public void setNoPvp(boolean noPvp) { - this.noPvp = noPvp; - } - - public void setNoPvm(boolean noPvm) { - this.noPvm = noPvm; - } - - public void setNoMvp(boolean noMvp) { - this.noMvp = noMvp; - } - - public void setMuted(boolean muted) { - this.muted = muted; - } + public boolean get(Type type) { + Boolean value = this.values.get(type); - public boolean canDestroyBlock() { - return canDestroyBlock; - } - - public boolean isAutoJumpEnabled() { - return autoJump; - } - - public boolean canFly() { - return canFly; - } - - public boolean isFlying() { - return flying; - } - - public boolean isNoclipEnabled() { - return noclip; - } - - public boolean isNoPvp() { - return noPvp; - } - - public boolean isNoPvm() { - return noPvm; - } - - public boolean isNoMvp() { - return noMvp; - } - - public boolean isMuted() { - return muted; + return value == null ? type.getDefaultValue() : value; } public void update() { AdventureSettingsPacket pk = new AdventureSettingsPacket(); - pk.setFlag(AdventureSettingsPacket.WORLD_IMMUTABLE, !canDestroyBlock); - pk.setFlag(AdventureSettingsPacket.AUTO_JUMP, autoJump); - pk.setFlag(AdventureSettingsPacket.ALLOW_FLIGHT, canFly); - pk.setFlag(AdventureSettingsPacket.NO_CLIP, noclip); - pk.setFlag(AdventureSettingsPacket.FLYING, flying); - pk.setFlag(AdventureSettingsPacket.NO_PVP, noPvp); - pk.setFlag(AdventureSettingsPacket.MUTED, muted); + for (Entry entry : this.values.entrySet()) { + pk.setFlag(entry.getKey().getId(), entry.getValue()); + } pk.commandPermission = (player.isOp() ? AdventureSettingsPacket.PERMISSION_OPERATOR : AdventureSettingsPacket.PERMISSION_NORMAL); pk.playerPermission = (player.isOp() ? Player.PERMISSION_OPERATOR : Player.PERMISSION_MEMBER); @@ -138,39 +58,36 @@ public void update() { player.resetInAirTicks(); } - public static class Builder { - private final AdventureSettings settings = new AdventureSettings(); - - public Builder(Player player) { - if (player == null) { - throw new IllegalArgumentException("Player can not be null."); - } - - settings.player = player; - } - - public Builder canFly(boolean can) { - settings.canFly = can; - return this; - } - - public Builder noclip(boolean noclip) { - settings.noclip = noclip; - return this; - } - - public Builder canDestroyBlock(boolean can) { - settings.canDestroyBlock = can; - return this; + public enum Type { + WORLD_IMMUTABLE(AdventureSettingsPacket.WORLD_IMMUTABLE, false), + AUTO_JUMP(AdventureSettingsPacket.AUTO_JUMP, true), + ALLOW_FLIGHT(AdventureSettingsPacket.ALLOW_FLIGHT, false), + NO_CLIP(AdventureSettingsPacket.NO_CLIP, false), + WORLD_BUILDER(AdventureSettingsPacket.WORLD_BUILDER, true), + FLYING(AdventureSettingsPacket.FLYING, false), + MUTED(AdventureSettingsPacket.MUTED, false), + BUILD_AND_MINE(AdventureSettingsPacket.BUILD_AND_MINE, true), + DOORS_AND_SWITCHED(AdventureSettingsPacket.DOORS_AND_SWITCHES, true), + OPEN_CONTAINERS(AdventureSettingsPacket.OPEN_CONTAINERS, true), + ATTACK_PLAYERS(AdventureSettingsPacket.ATTACK_PLAYERS, true), + ATTACK_MOBS(AdventureSettingsPacket.ATTACK_MOBS, true), + OPERATOR(AdventureSettingsPacket.OPERATOR, false), + TELEPORT(AdventureSettingsPacket.TELEPORT, false); + + private final int id; + private final boolean defaultValue; + + Type(int id, boolean defaultValue) { + this.id = id; + this.defaultValue = defaultValue; } - public Builder autoJump(boolean autoJump) { - settings.autoJump = autoJump; - return this; + public int getId() { + return id; } - public AdventureSettings build() { - return this.settings; + public boolean getDefaultValue() { + return this.defaultValue; } } } diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 26ade9d074..659b8e5926 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -1,5 +1,6 @@ package cn.nukkit; +import cn.nukkit.AdventureSettings.Type; import cn.nukkit.block.*; import cn.nukkit.blockentity.BlockEntity; import cn.nukkit.blockentity.BlockEntityItemFrame; @@ -332,24 +333,24 @@ public void resetInAirTicks() { @Deprecated public void setAllowFlight(boolean value) { - this.getAdventureSettings().setCanFly(value); + this.getAdventureSettings().set(Type.ALLOW_FLIGHT, value); this.getAdventureSettings().update(); } @Deprecated public boolean getAllowFlight() { - return this.getAdventureSettings().canFly(); + return this.getAdventureSettings().get(Type.ALLOW_FLIGHT); } @Deprecated public void setAutoJump(boolean value) { - this.getAdventureSettings().setAutoJump(value); + this.getAdventureSettings().set(Type.AUTO_JUMP, value); this.getAdventureSettings().update(); } @Deprecated public boolean hasAutoJump() { - return this.getAdventureSettings().isAutoJumpEnabled(); + return this.getAdventureSettings().get(Type.AUTO_JUMP); } @Override @@ -1151,10 +1152,11 @@ public boolean setGamemode(int gamemode, boolean clientSide, AdventureSettings n if (newSettings == null) { newSettings = this.getAdventureSettings().clone(this); - newSettings.setCanDestroyBlock(gamemode != 3); - newSettings.setCanFly((gamemode & 0x01) > 0); - newSettings.setNoclip(gamemode == 0x03); - newSettings.setFlying(gamemode == 0x03); + newSettings.set(Type.WORLD_IMMUTABLE, gamemode != 3); + newSettings.set(Type.BUILD_AND_MINE, gamemode != 3); + newSettings.set(Type.ALLOW_FLIGHT, (gamemode & 0x01) > 0); + newSettings.set(Type.NO_CLIP, gamemode == 0x03); + newSettings.set(Type.FLYING, gamemode == 0x03); } PlayerGameModeChangeEvent ev; @@ -1185,7 +1187,7 @@ public boolean setGamemode(int gamemode, boolean clientSide, AdventureSettings n this.setAdventureSettings(ev.getNewAdventureSettings()); if (this.isSpectator()) { - this.getAdventureSettings().setFlying(true); + this.getAdventureSettings().set(Type.FLYING, true); this.teleport(this.temporalVector.setComponents(this.x, this.y + 0.1, this.z)); InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); @@ -1193,7 +1195,7 @@ public boolean setGamemode(int gamemode, boolean clientSide, AdventureSettings n this.dataPacket(inventoryContentPacket); } else { if (this.isSurvival()) { - this.getAdventureSettings().setFlying(false); + this.getAdventureSettings().set(Type.FLYING, false); } InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); inventoryContentPacket.inventoryId = InventoryContentPacket.SPECIAL_CREATIVE; @@ -1596,7 +1598,7 @@ public boolean onUpdate(int currentTick) { this.inAirTicks = 0; this.highestPosition = this.y; } else { - if (!this.isGliding() && !server.getAllowFlight() && !this.getAdventureSettings().canFly() && this.inAirTicks > 10 && !this.isSleeping() && !this.isImmobile()) { + if (!this.isGliding() && !server.getAllowFlight() && !this.getAdventureSettings().get(Type.ALLOW_FLIGHT) && this.inAirTicks > 10 && !this.isSleeping() && !this.isImmobile()) { double expectedVelocity = (-this.getGravity()) / ((double) this.getDrag()) - ((-this.getGravity()) / ((double) this.getDrag())) * Math.exp(-((double) this.getDrag()) * ((double) (this.inAirTicks - this.startAirTicks))); double diff = (this.speed.y - expectedVelocity) * (this.speed.y - expectedVelocity); @@ -1803,12 +1805,11 @@ protected void processLogin() { nbt.putInt("playerGameType", this.gamemode); } - this.adventureSettings = new AdventureSettings.Builder(this) - .canDestroyBlock(!isAdventure()) - .autoJump(true) - .canFly(isCreative()) - .noclip(isSpectator()) - .build(); + this.adventureSettings = new AdventureSettings() + .set(Type.WORLD_IMMUTABLE, !isAdventure()) + .set(Type.AUTO_JUMP, true) + .set(Type.ALLOW_FLIGHT, isCreative()) + .set(Type.NO_CLIP, isSpectator()); Level level; if ((level = this.server.getLevelByName(nbt.getString("Level"))) == null || !alive) { @@ -2160,7 +2161,7 @@ public void handleDataPacket(DataPacket packet) { case ProtocolInfo.ADVENTURE_SETTINGS_PACKET: //TODO: player abilities, check for other changes AdventureSettingsPacket adventureSettingsPacket = (AdventureSettingsPacket) packet; - if (adventureSettingsPacket.getFlag(AdventureSettingsPacket.ALLOW_FLIGHT) && !this.getAdventureSettings().canFly()) { + if (adventureSettingsPacket.getFlag(AdventureSettingsPacket.ALLOW_FLIGHT) && !this.getAdventureSettings().get(Type.ALLOW_FLIGHT)) { this.kick(PlayerKickEvent.Reason.FLYING_DISABLED, "Flying is not enabled on this server"); break; } @@ -2169,7 +2170,7 @@ public void handleDataPacket(DataPacket packet) { if (playerToggleFlightEvent.isCancelled()) { this.getAdventureSettings().update(); } else { - this.getAdventureSettings().setFlying(playerToggleFlightEvent.isFlying()); + this.getAdventureSettings().set(Type.FLYING, playerToggleFlightEvent.isFlying()); } break; case ProtocolInfo.MOB_EQUIPMENT_PACKET: @@ -4160,7 +4161,7 @@ public boolean attack(EntityDamageEvent source) { ) { //source.setCancelled(); return false; - } else if (this.getAdventureSettings().canFly() && source.getCause() == DamageCause.FALL) { + } else if (this.getAdventureSettings().get(Type.ALLOW_FLIGHT) && source.getCause() == DamageCause.FALL) { //source.setCancelled(); return false; } else if (source.getCause() == DamageCause.FALL) { From 5b96f59eff20a0f617f5016587e9039cdef1e2d9 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Fri, 22 Sep 2017 19:57:35 +0200 Subject: [PATCH 085/175] Merge remote-tracking branch 'remotes/origin/master1.2' into GT1.2 # Conflicts: # src/main/java/cn/nukkit/Player.java # src/main/java/cn/nukkit/inventory/CraftingManager.java # src/main/java/cn/nukkit/inventory/PlayerInventory.java # src/main/java/cn/nukkit/math/Angle.java # src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java # src/main/java/cn/nukkit/utils/Utils.java --- .../java/cn/nukkit/AdventureSettings.java | 4 + src/main/java/cn/nukkit/Player.java | 197 ++----------- src/main/java/cn/nukkit/entity/Entity.java | 2 +- .../cn/nukkit/inventory/CraftingManager.java | 23 +- src/main/java/cn/nukkit/math/Angle.java | 266 +++++++++--------- 5 files changed, 187 insertions(+), 305 deletions(-) diff --git a/src/main/java/cn/nukkit/AdventureSettings.java b/src/main/java/cn/nukkit/AdventureSettings.java index 0ac5b80eca..a101853c91 100644 --- a/src/main/java/cn/nukkit/AdventureSettings.java +++ b/src/main/java/cn/nukkit/AdventureSettings.java @@ -22,6 +22,10 @@ public class AdventureSettings implements Cloneable { private Player player; + public AdventureSettings(Player player) { + this.player = player; + } + public AdventureSettings clone(Player newPlayer) { try { AdventureSettings settings = (AdventureSettings) super.clone(); diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 789a685eb1..9c3bea3496 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -212,8 +212,6 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde private ClientChainData loginChainData; - public int pickedXPOrb = 0; - public Block breakingBlock = null; public int pickedXPOrb = 0; @@ -1807,7 +1805,7 @@ protected void processLogin() { nbt.putInt("playerGameType", this.gamemode); } - this.adventureSettings = new AdventureSettings() + this.adventureSettings = new AdventureSettings(this) .set(Type.WORLD_IMMUTABLE, !isAdventure()) .set(Type.AUTO_JUMP, true) .set(Type.ALLOW_FLIGHT, isCreative()) @@ -2575,21 +2573,10 @@ public void handleDataPacket(DataPacket packet) { break; } - this.craftingType = CRAFTING_SMALL; - this.resetCraftingGridType(); TextPacket textPacket = (TextPacket) packet; if (textPacket.type == TextPacket.TYPE_CHAT) { - textPacket.message = this.removeFormat ? TextFormat.clean(textPacket.message) : textPacket.message; - for (String msg : textPacket.message.split("\n")) { - if (!"".equals(msg.trim()) && msg.length() <= 255 && this.messageCounter-- > 0) { - PlayerChatEvent chatEvent = new PlayerChatEvent(this, msg); - this.server.getPluginManager().callEvent(chatEvent); - if (!chatEvent.isCancelled()) { - this.server.broadcastMessage(this.getServer().getLanguage().translateString(chatEvent.getFormat(), new String[]{chatEvent.getPlayer().getDisplayName(), chatEvent.getMessage()}), chatEvent.getRecipients()); - } - } - } + this.chat(textPacket.message); } break; case ProtocolInfo.CONTAINER_CLOSE_PACKET: @@ -3052,153 +3039,6 @@ public void handleDataPacket(DataPacket packet) { } } - break; - case ProtocolInfo.CONTAINER_SET_SLOT_PACKET: - if (!this.spawned || !this.isAlive()) { - break; - } - - ContainerSetSlotPacket containerSetSlotPacket = (ContainerSetSlotPacket) packet; - if (containerSetSlotPacket.slot < 0) { - break; - } - - Inventory inv; - BaseTransaction transaction; - if (containerSetSlotPacket.windowid == 0) { //Our inventory - inv = this.inventory; - if (containerSetSlotPacket.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] - } - } - transaction = new BaseTransaction(this.inventory, containerSetSlotPacket.slot, this.inventory.getItem(containerSetSlotPacket.slot), containerSetSlotPacket.item); - } else if (containerSetSlotPacket.windowid == ContainerSetContentPacket.SPECIAL_ARMOR) { //Our armor - inv = this.inventory; - if (containerSetSlotPacket.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); - - 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); - } - - transaction = new BaseTransaction(inv, containerSetSlotPacket.slot, inv.getItem(containerSetSlotPacket.slot), containerSetSlotPacket.item); - } else { - break; - } - - if (inv != null) { - Item sourceItem = inv.getItem(containerSetSlotPacket.slot); - Item heldItem = sourceItem.clone(); - heldItem.setCount(sourceItem.getCount() - containerSetSlotPacket.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); - this.getServer().getPluginManager().callEvent(inventoryClickEvent); - //TODO Fix hold on bug and support Cancellable - } - } - - if (transaction.getSourceItem().deepEquals(transaction.getTargetItem()) && transaction.getTargetItem().getCount() == transaction.getSourceItem().getCount()) { //No changes! - //No changes, just a local inventory update sent by the server - break; - } - - - 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); - } - inventory.sendContents(this); - } - } - this.currentTransaction = new SimpleTransactionGroup(this); - } - - this.currentTransaction.addTransaction(transaction); - - if (this.currentTransaction.canExecute() || 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 (this.currentTransaction.execute(this.isCreative())) { - for (String achievement : achievements) { - this.awardAchievement(achievement); - } - } - - this.currentTransaction = null; - } else { - if (containerSetSlotPacket.item.getId() != 0) { - inventory.sendSlot(containerSetSlotPacket.hotbarSlot, this); - inventory.sendSlot(containerSetSlotPacket.slot, this); - } - } - - 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; case ProtocolInfo.BLOCK_ENTITY_DATA_PACKET: if (!this.spawned || !this.isAlive()) { @@ -3517,10 +3357,6 @@ public void handleDataPacket(DataPacket packet) { case InventoryTransactionPacket.TYPE_USE_ITEM_ON_ENTITY: UseItemOnEntityData useItemOnEntityData = (UseItemOnEntityData) transactionPacket.transactionData; - if (useItemOnEntityData.entityRuntimeId % 2 == 0) { - useItemOnEntityData.entityRuntimeId /= 2; //wtf is that - } - Entity target = this.level.getEntity(useItemOnEntityData.entityRuntimeId); if (target == null) { return; @@ -3698,6 +3534,35 @@ public void handleDataPacket(DataPacket packet) { } } + /** + * Sends a chat message as this player. If the message begins with a / (forward-slash) it will be treated + * as a command. + */ + public boolean chat(String message) { + if (!this.spawned || !this.isAlive()) { + return false; + } + + this.resetCraftingGridType(); + this.craftingType = CRAFTING_SMALL; + + if (this.removeFormat) { + message = TextFormat.clean(message); + } + + for (String msg : message.split("\n")) { + if (!"".equals(msg.trim()) && msg.length() <= 255 && this.messageCounter-- > 0) { + PlayerChatEvent chatEvent = new PlayerChatEvent(this, msg); + this.server.getPluginManager().callEvent(chatEvent); + if (!chatEvent.isCancelled()) { + this.server.broadcastMessage(this.getServer().getLanguage().translateString(chatEvent.getFormat(), new String[]{chatEvent.getPlayer().getDisplayName(), chatEvent.getMessage()}), chatEvent.getRecipients()); + } + } + } + + return true; + } + public boolean kick() { return this.kick(""); } diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java index e5e6b9ad7d..2d2a4293bc 100644 --- a/src/main/java/cn/nukkit/entity/Entity.java +++ b/src/main/java/cn/nukkit/entity/Entity.java @@ -1097,7 +1097,7 @@ public boolean entityBaseTick(int tickDiff) { if (this.inPortalTicks == 80) { EntityPortalEnterEvent ev = new EntityPortalEnterEvent(this, PortalType.NETHER); getServer().getPluginManager().callEvent(ev); - + //TODO: teleport } diff --git a/src/main/java/cn/nukkit/inventory/CraftingManager.java b/src/main/java/cn/nukkit/inventory/CraftingManager.java index b3ba2d7ced..5db22d1e45 100644 --- a/src/main/java/cn/nukkit/inventory/CraftingManager.java +++ b/src/main/java/cn/nukkit/inventory/CraftingManager.java @@ -47,9 +47,15 @@ public CraftingManager() { 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"))*/ 1, ingredient.get("nbt").toString().getBytes())); //ingredient count should be always 1 for now + result.addIngredient(Item.get(Utils.toInt(ingredient.get("id")), Utils.toInt(ingredient.get("damage")), Utils.toInt(ingredient.get("count")), ingredient.get("nbt").toString().getBytes())); + } + + String id = (String) recipe.get("uuid"); + if (id != null && !id.isEmpty()) { + UUID uuid = UUID.fromString(id); + result.setId(uuid); + this.recipes.put(uuid, result); } - this.registerRecipe(result); break; case 1: // TODO: handle multiple result items @@ -63,19 +69,26 @@ public CraftingManager() { 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"))*/ 1, ingredient.get("nbt").toString().getBytes())); + 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); + + 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; diff --git a/src/main/java/cn/nukkit/math/Angle.java b/src/main/java/cn/nukkit/math/Angle.java index 3b3c781f1f..549284a74a 100644 --- a/src/main/java/cn/nukkit/math/Angle.java +++ b/src/main/java/cn/nukkit/math/Angle.java @@ -2,7 +2,7 @@ import java.util.Locale; -import static java.lang.Math.*; +import static java.lang.Math.PI; /** * Copyright 2017 lmlstarqaq @@ -10,143 +10,143 @@ */ public final class Angle implements Comparable { - public static Angle fromDegree(float floatDegree) { - return new Angle(floatDegree, true); - } - - public static Angle fromDegree(double doubleDegree) { - return new Angle(doubleDegree, true); - } - - public static Angle fromRadian(float floatRadian) { - return new Angle(floatRadian, false); - } - - public static Angle fromRadian(double doubleRadian) { - return new Angle(doubleRadian, false); - } - - public static Angle asin(double v) { - return fromRadian(Math.asin(v)); - } - - public static Angle acos(double v) { - return fromRadian(Math.acos(v)); - } - - public static Angle atan(double v) { - return fromRadian(Math.atan(v)); - } - - public double sin() { - return Math.sin(asDoubleRadian()); - } - - public double cos() { - return Math.cos(asDoubleRadian()); - } - - public double tan() { - return Math.tan(asDoubleRadian()); - } - - public float asFloatRadian() { - if (isOriginDouble) { - if (isDegree) return (float) (doubleValue * PI / 180.0); - else return (float) doubleValue; - } else { - if (isDegree) return floatValue * (float) PI / 180.0f; - else return floatValue; - } - } - - public double asDoubleRadian() { - if (isOriginDouble) { - if (isDegree) return doubleValue * PI / 180.0; - else return doubleValue; - } else { - if (isDegree) return floatValue * PI / 180.0; - else return floatValue; - } - } - - public float asFloatDegree() { - if (isOriginDouble) { - if (isDegree) return (float) doubleValue; - else return (float) (doubleValue * 180.0 / PI); - } else { - if (isDegree) return floatValue; - else return floatValue * 180.0f / (float) PI; - } - } - - public double asDoubleDegree() { - if (isOriginDouble) { - if (isDegree) return doubleValue; - else return doubleValue * 180.0 / PI; - } else { - if (isDegree) return floatValue ; - else return floatValue * 180.0 / PI; - } - } - - public static int compare(Angle a, Angle b) { - return a.compareTo(b); - } + public static Angle fromDegree(float floatDegree) { + return new Angle(floatDegree, true); + } + + public static Angle fromDegree(double doubleDegree) { + return new Angle(doubleDegree, true); + } + + public static Angle fromRadian(float floatRadian) { + return new Angle(floatRadian, false); + } + + public static Angle fromRadian(double doubleRadian) { + return new Angle(doubleRadian, false); + } + + public static Angle asin(double v) { + return fromRadian(Math.asin(v)); + } + + public static Angle acos(double v) { + return fromRadian(Math.acos(v)); + } + + public static Angle atan(double v) { + return fromRadian(Math.atan(v)); + } + + public double sin() { + return Math.sin(asDoubleRadian()); + } + + public double cos() { + return Math.cos(asDoubleRadian()); + } + + public double tan() { + return Math.tan(asDoubleRadian()); + } + + public float asFloatRadian() { + if (isOriginDouble) { + if (isDegree) return (float) (doubleValue * PI / 180.0); + else return (float) doubleValue; + } else { + if (isDegree) return floatValue * (float) PI / 180.0f; + else return floatValue; + } + } + + public double asDoubleRadian() { + if (isOriginDouble) { + if (isDegree) return doubleValue * PI / 180.0; + else return doubleValue; + } else { + if (isDegree) return floatValue * PI / 180.0; + else return floatValue; + } + } + + public float asFloatDegree() { + if (isOriginDouble) { + if (isDegree) return (float) doubleValue; + else return (float) (doubleValue * 180.0 / PI); + } else { + if (isDegree) return floatValue; + else return floatValue * 180.0f / (float) PI; + } + } + + public double asDoubleDegree() { + if (isOriginDouble) { + if (isDegree) return doubleValue; + else return doubleValue * 180.0 / PI; + } else { + if (isDegree) return floatValue; + else return floatValue * 180.0 / PI; + } + } + + public static int compare(Angle a, Angle b) { + return a.compareTo(b); + } /* -- Override -- */ - @Override - public String toString() { - return String.format(Locale.ROOT, - "Angle[%s, %f%s = %f%s] [%d]", - isOriginDouble ? "Double" : "Float", - isOriginDouble ? doubleValue : floatValue, - isDegree ? "deg" : "rad", - isDegree ? (isOriginDouble ? asDoubleRadian() : asFloatRadian()) : - (isOriginDouble ? asDoubleDegree() : asFloatDegree()) , - isDegree ? "rad" : "deg", - hashCode() - ); - } - - @Override - public int compareTo(Angle o) { - return Double.compare(asDoubleRadian(), o.asDoubleRadian()); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof Angle && this.compareTo((Angle) obj) == 0; - } - - @Override - public int hashCode() { - int hash; - if (isOriginDouble) hash = Double.hashCode(doubleValue); - else hash = Float.hashCode(floatValue); - if (isDegree) hash = hash ^ 0xABCD1234; - return hash; - } + @Override + public String toString() { + return String.format(Locale.ROOT, + "Angle[%s, %f%s = %f%s] [%d]", + isOriginDouble ? "Double" : "Float", + isOriginDouble ? doubleValue : floatValue, + isDegree ? "deg" : "rad", + isDegree ? (isOriginDouble ? asDoubleRadian() : asFloatRadian()) : + (isOriginDouble ? asDoubleDegree() : asFloatDegree()), + isDegree ? "rad" : "deg", + hashCode() + ); + } + + @Override + public int compareTo(Angle o) { + return Double.compare(asDoubleRadian(), o.asDoubleRadian()); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Angle && this.compareTo((Angle) obj) == 0; + } + + @Override + public int hashCode() { + int hash; + if (isOriginDouble) hash = Double.hashCode(doubleValue); + else hash = Float.hashCode(floatValue); + if (isDegree) hash = hash ^ 0xABCD1234; + return hash; + } /* -- Internal Part -- */ - private final float floatValue; - private final double doubleValue; - private final boolean isDegree, isOriginDouble; - - private Angle(float floatValue, boolean isDegree) { - this.isOriginDouble = false; - this.floatValue = floatValue; - this.doubleValue = 0.0; - this.isDegree = isDegree; - } - - private Angle(double doubleValue, boolean isDegree) { - this.isOriginDouble = true; - this.floatValue = 0.0f; - this.doubleValue = doubleValue; - this.isDegree = isDegree; - } + private final float floatValue; + private final double doubleValue; + private final boolean isDegree, isOriginDouble; + + private Angle(float floatValue, boolean isDegree) { + this.isOriginDouble = false; + this.floatValue = floatValue; + this.doubleValue = 0.0; + this.isDegree = isDegree; + } + + private Angle(double doubleValue, boolean isDegree) { + this.isOriginDouble = true; + this.floatValue = 0.0f; + this.doubleValue = doubleValue; + this.isDegree = isDegree; + } } From 8b5f54c7d5f3a1ebe20b8b8475f710a9ece39a1b Mon Sep 17 00:00:00 2001 From: Goodstuff4UonYT Date: Fri, 22 Sep 2017 22:35:52 +0200 Subject: [PATCH 086/175] Fix Floating Text Particle --- .../level/particle/FloatingTextParticle.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java b/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java index aa133b8f3f..776bfa396e 100644 --- a/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java +++ b/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java @@ -2,13 +2,14 @@ import cn.nukkit.entity.Entity; import cn.nukkit.entity.data.EntityMetadata; -import cn.nukkit.entity.item.EntityItem; +import cn.nukkit.item.Item; import cn.nukkit.math.Vector3; -import cn.nukkit.network.protocol.AddEntityPacket; +import cn.nukkit.network.protocol.AddPlayerPacket; import cn.nukkit.network.protocol.DataPacket; import cn.nukkit.network.protocol.RemoveEntityPacket; import java.util.ArrayList; +import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; /** @@ -16,6 +17,8 @@ * Package cn.nukkit.level.particle in project Nukkit . */ public class FloatingTextParticle extends Particle { + + protected String text; protected String title; protected long entityId = -1; @@ -32,10 +35,18 @@ public FloatingTextParticle(Vector3 pos, String text, String title) { this.title = title; } + public String getText() { + return text; + } + public void setText(String text) { this.text = text; } + public String getTitle() { + return title; + } + public void setTitle(String title) { this.title = title; } @@ -66,10 +77,11 @@ public DataPacket[] encode() { } if (!this.invisible) { - AddEntityPacket pk = new AddEntityPacket(); + AddPlayerPacket pk = new AddPlayerPacket(); + pk.uuid = UUID.randomUUID(); + pk.username = ""; pk.entityUniqueId = this.entityId; pk.entityRuntimeId = this.entityId; - pk.type = EntityItem.NETWORK_ID; pk.x = (float) this.x; pk.y = (float) (this.y - 0.75); pk.z = (float) this.z; @@ -85,10 +97,14 @@ public DataPacket[] encode() { ); pk.metadata = new EntityMetadata() .putLong(Entity.DATA_FLAGS, flags) - .putString(Entity.DATA_NAMETAG, this.title + (!this.text.isEmpty() ? "\n" + this.text : "")); + .putString(Entity.DATA_NAMETAG, this.title + (!this.text.isEmpty() ? "\n" + this.text : "")) + .putFloat(Entity.DATA_TYPE_FLOAT, 0.01f) //zero causes problems on debug builds? + .putLong(Entity.DATA_LEAD_HOLDER_EID,-1) + .putFloat(Entity.DATA_SCALE, 0.01f); + pk.item = Item.get(Item.AIR); packets.add(pk); } return packets.stream().toArray(DataPacket[]::new); } -} +} \ No newline at end of file From 7ea255d59e48303bd516c7c829048208b1af05fa Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sat, 23 Sep 2017 10:43:54 +0200 Subject: [PATCH 087/175] still crashes --- src/main/java/cn/nukkit/Player.java | 116 +++++++++--------- src/main/java/cn/nukkit/Server.java | 5 + src/main/java/cn/nukkit/level/Level.java | 19 +-- .../level/particle/FloatingTextParticle.java | 3 +- .../ServerSettingsResponsePacket.java | 1 + 5 files changed, 69 insertions(+), 75 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 9c3bea3496..af4e02f161 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -810,7 +810,6 @@ protected void sendNextChunk() { protected void doFirstSpawn() { this.spawned = true; - this.server.sendRecipeList(this); this.getAdventureSettings().update(); this.sendPotionEffects(this); @@ -837,9 +836,7 @@ protected void doFirstSpawn() { respawnPacket.z = (float) pos.z; this.dataPacket(respawnPacket); - PlayStatusPacket playStatusPacket = new PlayStatusPacket(); - playStatusPacket.status = PlayStatusPacket.PLAYER_SPAWN; - this.dataPacket(playStatusPacket); + this.sendPlayStatus(PlayStatusPacket.PLAYER_SPAWN); PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(this, new TranslationContainer(TextFormat.YELLOW + "%multiplayer.player.joined", new String[]{ @@ -1839,6 +1836,9 @@ protected void processLogin() { this.server.saveOfflinePlayerData(this.username, nbt, true); } + this.sendPlayStatus(PlayStatusPacket.LOGIN_SUCCESS); + this.server.onPlayerLogin(this); + ListTag posList = nbt.getList("Pos", DoubleTag.class); super.init(this.level.getChunk((int) posList.get(0).data >> 4, (int) posList.get(2).data >> 4, true), nbt); @@ -1853,17 +1853,6 @@ protected void processLogin() { float foodSaturationLevel = this.namedTag.getFloat("foodSaturationLevel"); this.foodData = new PlayerFood(this, foodLevel, foodSaturationLevel); - PlayerLoginEvent ev; - this.server.getPluginManager().callEvent(ev = new PlayerLoginEvent(this, "Plugin reason")); - if (ev.isCancelled()) { - this.close(this.getLeaveMessage(), ev.getKickMessage()); - - return; - } - - this.server.addOnlinePlayer(this); - this.loggedIn = true; - if (this.isCreative()) { this.inventory.setHeldItemSlot(0); } else { @@ -1872,6 +1861,17 @@ protected void processLogin() { if (this.isSpectator()) this.keepMovement = true; + this.setEnableClientCommand(true); + + this.forceMovement = this.teleportPosition = this.getPosition(); + + ResourcePacksInfoPacket infoPacket = new ResourcePacksInfoPacket(); + infoPacket.resourcePackEntries = this.server.getResourcePackManager().getResourceStack(); + infoPacket.mustAccept = this.server.getForceResources(); + this.dataPacket(infoPacket); + } + + protected void completeLoginSequence() { if (this.spawnPosition == null && this.namedTag.contains("SpawnLevel") && (level = this.server.getLevelByName(this.namedTag.getString("SpawnLevel"))) != null) { this.spawnPosition = new Position(this.namedTag.getInt("SpawnX"), this.namedTag.getInt("SpawnY"), this.namedTag.getInt("SpawnZ"), level); } @@ -1904,9 +1904,16 @@ protected void processLogin() { startGamePacket.generator = 1; //0 old, 1 infinite, 2 flat this.dataPacket(startGamePacket); - SetTimePacket setTimePacket = new SetTimePacket(); - setTimePacket.time = this.level.getTime(); - this.dataPacket(setTimePacket); + PlayerLoginEvent ev; + this.server.getPluginManager().callEvent(ev = new PlayerLoginEvent(this, "Plugin reason")); + if (ev.isCancelled()) { + this.close(this.getLeaveMessage(), ev.getKickMessage()); + return; + } + + this.loggedIn = true; + + this.level.sendTime(this); this.setMovementSpeed(DEFAULT_SPEED); this.sendAttributes(); @@ -1928,6 +1935,8 @@ protected void processLogin() { this.setRemoveFormat(false); } + this.sendCommandData(); + if (this.gamemode == Player.SPECTATOR) { InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); inventoryContentPacket.inventoryId = ContainerIds.CREATIVE; @@ -1936,13 +1945,8 @@ protected void processLogin() { this.inventory.sendCreativeContents(); } - this.setEnableClientCommand(true); - - this.server.sendFullPlayerListData(this); - - this.forceMovement = this.teleportPosition = this.getPosition(); - - this.server.onPlayerLogin(this); + this.server.addOnlinePlayer(this); + this.server.onPlayerCompleteLoginSequence(this); } public void handleDataPacket(DataPacket packet) { @@ -1978,15 +1982,11 @@ public void handleDataPacket(DataPacket packet) { if (loginPacket.getProtocol() < ProtocolInfo.CURRENT_PROTOCOL) { message = "disconnectionScreen.outdatedClient"; - PlayStatusPacket pk = new PlayStatusPacket(); - pk.status = PlayStatusPacket.LOGIN_FAILED_CLIENT; - this.directDataPacket(pk); + this.sendPlayStatus(PlayStatusPacket.LOGIN_FAILED_CLIENT); } else { message = "disconnectionScreen.outdatedServer"; - PlayStatusPacket pk = new PlayStatusPacket(); - pk.status = PlayStatusPacket.LOGIN_FAILED_SERVER; - this.directDataPacket(pk); + this.sendPlayStatus(PlayStatusPacket.LOGIN_FAILED_SERVER); } this.close("", message, false); break; @@ -2049,15 +2049,7 @@ public void handleDataPacket(DataPacket packet) { break; } - PlayStatusPacket statusPacket = new PlayStatusPacket(); - statusPacket.status = PlayStatusPacket.LOGIN_SUCCESS; - this.dataPacket(statusPacket); - - ResourcePacksInfoPacket infoPacket = new ResourcePacksInfoPacket(); - infoPacket.resourcePackEntries = this.server.getResourcePackManager().getResourceStack(); - infoPacket.mustAccept = this.server.getForceResources(); - this.dataPacket(infoPacket); - + this.processLogin(); break; case ProtocolInfo.RESOURCE_PACK_CLIENT_RESPONSE_PACKET: ResourcePackClientResponsePacket responsePacket = (ResourcePackClientResponsePacket) packet; @@ -2089,7 +2081,7 @@ public void handleDataPacket(DataPacket packet) { this.dataPacket(stackPacket); break; case ResourcePackClientResponsePacket.STATUS_COMPLETED: - this.processLogin(); + this.completeLoginSequence(); break; } break; @@ -2180,28 +2172,19 @@ public void handleDataPacket(DataPacket packet) { MobEquipmentPacket mobEquipmentPacket = (MobEquipmentPacket) packet; - if (mobEquipmentPacket.inventorySlot == 255) { - mobEquipmentPacket.inventorySlot = -1; //Cleared inventorySlot - } else { - if (mobEquipmentPacket.inventorySlot < 9) { - this.getServer().getLogger().debug("Tried to equip a inventorySlot that does not exist (index " + mobEquipmentPacket.inventorySlot + ")"); - this.inventory.sendContents(this); - return; - } - mobEquipmentPacket.inventorySlot -= 9; //Get real inventory inventorySlot - - Item item = this.inventory.getItem(mobEquipmentPacket.inventorySlot); + Item item = this.inventory.getItem(mobEquipmentPacket.hotbarSlot); - if (!item.equals(mobEquipmentPacket.item)) { - this.server.getLogger().debug("Tried to equip " + mobEquipmentPacket.item + " but have " + item + " in target inventorySlot"); - this.inventory.sendContents(this); - return; - } + if (!item.equals(mobEquipmentPacket.item)) { + this.server.getLogger().debug("Tried to equip " + mobEquipmentPacket.item + " but have " + item + " in target slot"); + this.inventory.sendContents(this); + return; } - this.inventory.equipItem(mobEquipmentPacket.hotbarSlot, mobEquipmentPacket.inventorySlot); + this.inventory.equipItem(mobEquipmentPacket.hotbarSlot); this.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, false); + + this.inventory.equipItem(mobEquipmentPacket.hotbarSlot, mobEquipmentPacket.inventorySlot); break; case ProtocolInfo.PLAYER_ACTION_PACKET: PlayerActionPacket playerActionPacket = (PlayerActionPacket) packet; @@ -2435,7 +2418,7 @@ public void handleDataPacket(DataPacket packet) { break; } - Item item = this.inventory.getItemInHand(); + item = this.inventory.getItemInHand(); switch (interactPacket.action) { case InteractPacket.ACTION_MOUSEOVER: @@ -4353,6 +4336,21 @@ protected boolean checkTeleportPosition() { return false; } + protected void sendPlayStatus(int status) { + sendPlayStatus(status, false); + } + + protected void sendPlayStatus(int status, boolean immediate) { + PlayStatusPacket pk = new PlayStatusPacket(); + pk.status = status; + + if (immediate) { + this.directDataPacket(pk); + } else { + this.dataPacket(pk); + } + } + private boolean isLevelChange = false; @Override diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index 04f3e9c828..38c2f8ae9f 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -814,6 +814,11 @@ public void tickProcessor() { } } + public void onPlayerCompleteLoginSequence(Player player) { + this.sendFullPlayerListData(player); + this.sendRecipeList(player); + } + public void onPlayerLogin(Player player) { if (this.sendUsageTicker > 0) { this.uniquePlayers.add(player.getUniqueId()); diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java index f820a4cee0..f64649681e 100644 --- a/src/main/java/cn/nukkit/level/Level.java +++ b/src/main/java/cn/nukkit/level/Level.java @@ -676,30 +676,21 @@ public void checkTime() { } } - public void sendTime(Player player) { - if (this.stopTime) { + public void sendTime(Player... players) { + /*if (this.stopTime) { //TODO SetTimePacket pk0 = new SetTimePacket(); pk0.time = (int) this.time; player.dataPacket(pk0); - } + }*/ SetTimePacket pk = new SetTimePacket(); pk.time = (int) this.time; - player.dataPacket(pk); + Server.broadcastPacket(players, pk); } public void sendTime() { - if (this.stopTime) { - SetTimePacket pk0 = new SetTimePacket(); - pk0.time = (int) this.time; - Server.broadcastPacket(this.players.values().stream().toArray(Player[]::new), pk0); - } - - SetTimePacket pk = new SetTimePacket(); - pk.time = (int) this.time; - - Server.broadcastPacket(this.players.values().stream().toArray(Player[]::new), pk); + sendTime(this.players.values().stream().toArray(Player[]::new)); } public GameRules getGameRules() { diff --git a/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java b/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java index 776bfa396e..9e5566f414 100644 --- a/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java +++ b/src/main/java/cn/nukkit/level/particle/FloatingTextParticle.java @@ -98,9 +98,8 @@ public DataPacket[] encode() { pk.metadata = new EntityMetadata() .putLong(Entity.DATA_FLAGS, flags) .putString(Entity.DATA_NAMETAG, this.title + (!this.text.isEmpty() ? "\n" + this.text : "")) - .putFloat(Entity.DATA_TYPE_FLOAT, 0.01f) //zero causes problems on debug builds? .putLong(Entity.DATA_LEAD_HOLDER_EID,-1) - .putFloat(Entity.DATA_SCALE, 0.01f); + .putFloat(Entity.DATA_SCALE, 0.01f); //zero causes problems on debug builds? pk.item = Item.get(Item.AIR); packets.add(pk); } diff --git a/src/main/java/cn/nukkit/network/protocol/ServerSettingsResponsePacket.java b/src/main/java/cn/nukkit/network/protocol/ServerSettingsResponsePacket.java index cfe42c455c..f7efce36dd 100644 --- a/src/main/java/cn/nukkit/network/protocol/ServerSettingsResponsePacket.java +++ b/src/main/java/cn/nukkit/network/protocol/ServerSettingsResponsePacket.java @@ -17,6 +17,7 @@ public void decode() { @Override public void encode() { + this.reset(); this.putVarInt(this.formId); this.putString(this.data); } From 731b8824e9c2a3404e9089227925917395b9aa18 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sat, 23 Sep 2017 15:54:25 +0200 Subject: [PATCH 088/175] random fixes and additions from PMMP --- src/main/java/cn/nukkit/Player.java | 35 +++-- .../cn/nukkit/entity/EntityHumanType.java | 13 +- src/main/java/cn/nukkit/entity/data/Skin.java | 90 ++++++++++++ .../event/player/PlayerItemHeldEvent.java | 13 +- .../cn/nukkit/inventory/PlayerInventory.java | 133 +++++------------- .../nukkit/network/protocol/LoginPacket.java | 10 +- .../network/protocol/PlayerListPacket.java | 2 +- .../network/protocol/PlayerSkinPacket.java | 32 ++++- 8 files changed, 195 insertions(+), 133 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index af4e02f161..0a70a0e673 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -217,7 +217,8 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde public int pickedXPOrb = 0; protected int formWindowCount = 0; - protected HashMap formWindows = new HashMap<>(); + protected Map formWindows = new HashMap<>(); + protected Map serverSettings = new HashMap<>(); public int getStartActionTick() { return startAction; @@ -815,7 +816,6 @@ protected void doFirstSpawn() { this.sendPotionEffects(this); this.sendData(this); this.inventory.sendContents(this); - this.inventory.sendHotbarContents(); this.inventory.sendArmorContents(this); SetTimePacket setTimePacket = new SetTimePacket(); @@ -1853,12 +1853,6 @@ protected void processLogin() { float foodSaturationLevel = this.namedTag.getFloat("foodSaturationLevel"); this.foodData = new PlayerFood(this, foodLevel, foodSaturationLevel); - if (this.isCreative()) { - this.inventory.setHeldItemSlot(0); - } else { - this.inventory.setHeldItemSlot(this.inventory.getHotbarSlotIndex(0)); - } - if (this.isSpectator()) this.keepMovement = true; this.setEnableClientCommand(true); @@ -2184,7 +2178,7 @@ public void handleDataPacket(DataPacket packet) { this.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, false); - this.inventory.equipItem(mobEquipmentPacket.hotbarSlot, mobEquipmentPacket.inventorySlot); + this.inventory.equipItem(mobEquipmentPacket.hotbarSlot); break; case ProtocolInfo.PLAYER_ACTION_PACKET: PlayerActionPacket playerActionPacket = (PlayerActionPacket) packet; @@ -2614,8 +2608,6 @@ public void handleDataPacket(DataPacket packet) { this.getServer().getLogger().debug(this.getName() + " failed to rename an item in an anvil"); this.inventory.sendContents(this); } - } else { - //TODO: Anvil crafting recipes } break; } else if (!this.windowIndex.containsKey(craftingEventPacket.windowId)) { @@ -3503,13 +3495,10 @@ public void handleDataPacket(DataPacket packet) { return; //In PE this should never happen } - for (int hotbarSlot = 0; hotbarSlot < hotbarPacket.slots.length; hotbarSlot++) { - int slotLink = hotbarPacket.slots[hotbarSlot]; - - this.inventory.setHotbarSlotIndex(hotbarSlot, slotLink == -1 ? slotLink : slotLink - 9); - } - this.inventory.equipItem(hotbarPacket.selectedHotbarSlot); + break; + case ProtocolInfo.SERVER_SETTINGS_REQUEST_PACKET: + break; default: break; @@ -4503,6 +4492,17 @@ public int showFormWindow(FormWindow window) { return id; } + /** + * Shows a new setting page in game settings + * You can find out settings result by listening to PlayerFormRespondedEvent + */ + public int addServerSettings(FormWindow window) { + int id = this.formWindowCount++; + + this.serverSettings.put(id, window); + return id; + } + /** * Creates and sends a BossBar to the player * @@ -4664,7 +4664,6 @@ public void sendAllInventories() { if (inv instanceof PlayerInventory) { ((PlayerInventory) inv).sendArmorContents(this); - ((PlayerInventory) inv).sendHotbarContents(); } } } diff --git a/src/main/java/cn/nukkit/entity/EntityHumanType.java b/src/main/java/cn/nukkit/entity/EntityHumanType.java index 215a7d5e04..a85d2cc764 100644 --- a/src/main/java/cn/nukkit/entity/EntityHumanType.java +++ b/src/main/java/cn/nukkit/entity/EntityHumanType.java @@ -45,8 +45,9 @@ protected void initEntity() { ListTag inventoryList = this.namedTag.getList("Inventory", CompoundTag.class); for (CompoundTag item : inventoryList.getAll()) { int slot = item.getByte("Slot"); - if (slot >= 0 && slot < 9) { - this.inventory.setHotbarSlotIndex(slot, item.contains("TrueSlot") ? item.getByte("TrueSlot") : -1); + if (slot >= 0 && slot < 9) { //hotbar + //Old hotbar saving stuff, remove it (useless now) + inventoryList.remove(item); } else if (slot >= 100 && slot < 104) { this.inventory.setItem(this.inventory.getSize() + slot - 100, NBTIO.getItemHelper(item)); } else { @@ -74,14 +75,6 @@ public void saveNBT() { this.namedTag.putList(new ListTag("Inventory")); if (this.inventory != null) { for (int slot = 0; slot < 9; ++slot) { - int hotbarSlot = this.inventory.getHotbarSlotIndex(slot); - if (hotbarSlot != -1) { - Item item = this.inventory.getItem(hotbarSlot); - if (item.getId() != 0 && item.getCount() > 0) { - this.namedTag.getList("Inventory", CompoundTag.class).add(NBTIO.putItemHelper(item, slot).putByte("TrueSlot", hotbarSlot)); - continue; - } - } this.namedTag.getList("Inventory", CompoundTag.class).add(new CompoundTag() .putByte("Count", 0) .putShort("Damage", 0) diff --git a/src/main/java/cn/nukkit/entity/data/Skin.java b/src/main/java/cn/nukkit/entity/data/Skin.java index c2ba8dfd0f..1619d06406 100644 --- a/src/main/java/cn/nukkit/entity/data/Skin.java +++ b/src/main/java/cn/nukkit/entity/data/Skin.java @@ -25,6 +25,7 @@ public class Skin { private byte[] data = new byte[SINGLE_SKIN_SIZE]; private String model; + private Cape cape; public Skin(byte[] data) { this(data, MODEL_STEVE); @@ -150,7 +151,96 @@ public void setModel(String model) { this.model = model; } + public Cape getCape() { + return cape; + } + + public void setCape(Cape cape) { + this.cape = cape; + } + public boolean isValid() { return this.data.length == SINGLE_SKIN_SIZE || this.data.length == DOUBLE_SKIN_SIZE; } + + public class Cape { + + public byte[] data; + + public Cape(byte[] data) { + this.setData(data); + } + + public Cape(InputStream inputStream) { + BufferedImage image; + try { + image = ImageIO.read(inputStream); + } catch (IOException e) { + throw new RuntimeException(e); + } + + this.parseBufferedImage(image); + } + + public Cape(ImageInputStream inputStream) { + BufferedImage image; + try { + image = ImageIO.read(inputStream); + } catch (IOException e) { + throw new RuntimeException(e); + } + this.parseBufferedImage(image); + } + + public Cape(File file, String model) { + BufferedImage image; + try { + image = ImageIO.read(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + this.parseBufferedImage(image); + } + + public Cape(URL url) { + BufferedImage image; + try { + image = ImageIO.read(url); + } catch (IOException e) { + throw new RuntimeException(e); + } + this.parseBufferedImage(image); + } + + public Cape(BufferedImage image) { + this.parseBufferedImage(image); + } + + public Cape(String base64) { + this(Base64.getDecoder().decode(base64)); + } + + public void setData(byte[] data) { + this.data = data; + } + + public byte[] getData() { + return data; + } + + public void parseBufferedImage(BufferedImage image) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + for (int y = 0; y < image.getHeight(); y++) { + for (int x = 0; x < image.getWidth(); x++) { + Color color = new Color(image.getRGB(x, y), true); + outputStream.write(color.getRed()); + outputStream.write(color.getGreen()); + outputStream.write(color.getBlue()); + outputStream.write(color.getAlpha()); + } + } + image.flush(); + this.setData(outputStream.toByteArray()); + } + } } diff --git a/src/main/java/cn/nukkit/event/player/PlayerItemHeldEvent.java b/src/main/java/cn/nukkit/event/player/PlayerItemHeldEvent.java index b64cc57286..c38a17e63b 100644 --- a/src/main/java/cn/nukkit/event/player/PlayerItemHeldEvent.java +++ b/src/main/java/cn/nukkit/event/player/PlayerItemHeldEvent.java @@ -18,22 +18,21 @@ public static HandlerList getHandlers() { } private final Item item; - private final int slot; - private final int inventorySlot; + private final int hotbarSlot; - public PlayerItemHeldEvent(Player player, Item item, int inventorySlot, int slot) { + public PlayerItemHeldEvent(Player player, Item item, int hotbarSlot) { this.player = player; this.item = item; - this.inventorySlot = inventorySlot; - this.slot = slot; + this.hotbarSlot = hotbarSlot; } public int getSlot() { - return slot; + return this.hotbarSlot; } + @Deprecated public int getInventorySlot() { - return inventorySlot; + return hotbarSlot; } public Item getItem() { diff --git a/src/main/java/cn/nukkit/inventory/PlayerInventory.java b/src/main/java/cn/nukkit/inventory/PlayerInventory.java index a5e2be4897..dde668532b 100644 --- a/src/main/java/cn/nukkit/inventory/PlayerInventory.java +++ b/src/main/java/cn/nukkit/inventory/PlayerInventory.java @@ -10,7 +10,10 @@ import cn.nukkit.event.player.PlayerItemHeldEvent; import cn.nukkit.item.Item; import cn.nukkit.item.ItemBlock; -import cn.nukkit.network.protocol.*; +import cn.nukkit.network.protocol.InventoryContentPacket; +import cn.nukkit.network.protocol.InventorySlotPacket; +import cn.nukkit.network.protocol.MobArmorEquipmentPacket; +import cn.nukkit.network.protocol.MobEquipmentPacket; import cn.nukkit.network.protocol.types.ContainerIds; import java.util.Collection; @@ -22,15 +25,16 @@ public class PlayerInventory extends BaseInventory { protected int itemInHandIndex = 0; - - protected final int[] hotbar; + private int[] hotbar; public PlayerInventory(EntityHumanType player) { super(player, InventoryType.PLAYER); this.hotbar = new int[this.getHotbarSize()]; + for (int i = 0; i < this.hotbar.length; i++) { this.hotbar[i] = i; } + } @Override @@ -44,38 +48,21 @@ public void setSize(int size) { this.sendContents(this.getViewers()); } - public boolean equipItem(int hotbarSlot) { - return equipItem(hotbarSlot, null); - } - /** * Called when a client equips a hotbar inventorySlot. This method should not be used by plugins. * This method will call PlayerItemHeldEvent. * - * @param hotbarSlot Number of the hotbar inventorySlot to equip. - * @param inventorySlot Inventory inventorySlot to map to the specified hotbar inventorySlot. Supply null to make no change to the link. - * @return bool if the equipment change was successful, false if not. + * @param slot hotbar slot Number of the hotbar slot to equip. + * @return boolean if the equipment change was successful, false if not. */ - public boolean equipItem(int hotbarSlot, Integer inventorySlot) { - if (inventorySlot == null) { - inventorySlot = this.getHotbarSlotIndex(hotbarSlot); - } - - if (hotbarSlot < 0 || hotbarSlot >= this.getHotbarSize() || inventorySlot < -1 || inventorySlot >= this.getSize()) { - this.sendContents(this.getViewers()); + public boolean equipItem(int slot) { + if (!isHotbarSlot(slot)) { + this.sendContents((Player) this.getHolder()); return false; } - Item item; - - if (inventorySlot == -1) { - item = Item.get(Item.AIR, 0, 0); - } else { - item = this.getItem(inventorySlot); - } - if (this.getHolder() instanceof Player) { - PlayerItemHeldEvent ev = new PlayerItemHeldEvent((Player) this.getHolder(), item, inventorySlot, hotbarSlot); + PlayerItemHeldEvent ev = new PlayerItemHeldEvent((Player) this.getHolder(), this.getItem(slot), slot); this.getHolder().getLevel().getServer().getPluginManager().callEvent(ev); if (ev.isCancelled()) { @@ -84,24 +71,26 @@ public boolean equipItem(int hotbarSlot, Integer inventorySlot) { } } - this.setHotbarSlotIndex(hotbarSlot, inventorySlot); - this.setHeldItemIndex(hotbarSlot, false); - + this.setHeldItemIndex(slot, false); return true; } + private boolean isHotbarSlot(int slot) { + return slot >= 0 && slot <= this.getHotbarSize(); + } + + @Deprecated public int getHotbarSlotIndex(int index) { - return (index >= 0 && index < this.getHotbarSize()) ? this.hotbar[index] : -1; + return index; } - public void setHotbarSlotIndex(int index, int slot) { //all slots are now linked to its ID - /*if (index >= 0 && index < this.getHotbarSize() && slot >= -1 && slot < this.getSize()) { - this.hotbar[index] = slot; - }*/ + @Deprecated + public void setHotbarSlotIndex(int index, int slot) { + } public int getHeldItemIndex() { - return itemInHandIndex; + return this.itemInHandIndex; } public void setHeldItemIndex(int index) { @@ -121,7 +110,7 @@ public void setHeldItemIndex(int index, boolean send) { } public Item getItemInHand() { - Item item = this.getItem(this.getHeldItemSlot()); + Item item = this.getItem(this.getHeldItemIndex()); if (item != null) { return item; } else { @@ -130,60 +119,40 @@ public Item getItemInHand() { } public boolean setItemInHand(Item item) { - return this.setItem(this.getHeldItemSlot(), item); + return this.setItem(this.getHeldItemIndex(), item); } + @Deprecated public int getHeldItemSlot() { - return this.getHotbarSlotIndex(this.itemInHandIndex); + return this.itemInHandIndex; } public void setHeldItemSlot(int slot) { - if (slot >= -1 && slot < this.getSize()) { - Item item = this.getItem(slot); - - int itemIndex = this.getHeldItemIndex(); - - if (this.getHolder() instanceof Player) { - PlayerItemHeldEvent ev = new PlayerItemHeldEvent((Player) this.getHolder(), item, slot, itemIndex); - Server.getInstance().getPluginManager().callEvent(ev); - if (ev.isCancelled()) { - this.sendHotbarContents(); - return; - } - } - - this.setHotbarSlotIndex(itemIndex, slot); + if (!isHotbarSlot(slot)) { + return; } - } - public void sendHeldItem(Player player) { - Item item = this.getItemInHand(); + this.itemInHandIndex = slot; - MobEquipmentPacket pk = new MobEquipmentPacket(); - pk.eid = this.getHolder().getId(); - pk.item = item; - pk.inventorySlot = (byte) this.getHeldItemSlot(); - pk.hotbarSlot = (byte) this.getHeldItemIndex(); - - player.dataPacket(pk); - if (player.equals(this.getHolder())) { - this.sendSlot(this.getHeldItemSlot(), player); + if (this.getHolder() instanceof Player) { + this.sendHeldItem((Player) this.getHolder()); } + + this.sendHeldItem(this.getViewers()); } - public void sendHeldItem(Player[] players) { + public void sendHeldItem(Player... players) { Item item = this.getItemInHand(); MobEquipmentPacket pk = new MobEquipmentPacket(); pk.item = item; - pk.inventorySlot = (byte) this.getHeldItemSlot(); - pk.hotbarSlot = (byte) this.getHeldItemIndex(); + pk.inventorySlot = pk.hotbarSlot = this.getHeldItemIndex(); for (Player player : players) { pk.eid = this.getHolder().getId(); if (player.equals(this.getHolder())) { pk.eid = player.getId(); - this.sendSlot(this.getHeldItemSlot(), player); + this.sendSlot(this.getHeldItemIndex(), player); } player.dataPacket(pk); @@ -466,28 +435,6 @@ public void sendContents(Player[] players) { pk.inventoryId = id; player.dataPacket(pk.clone()); - if (player.getId() == this.getHolder().getId()) { - this.sendHotbarContents(); - } - } - } - - public void sendHotbarContents() { - if (this.getHolder() instanceof Player) { - PlayerHotbarPacket pk = new PlayerHotbarPacket(); - pk.windowId = ContainerIds.INVENTORY; - pk.selectedHotbarSlot = this.getHeldItemIndex(); - pk.slots = new int[this.getHotbarSize()]; - //pk.slots = this.hotbar; - - System.arraycopy(this.hotbar, 0, pk.slots, 0, pk.slots.length); - - for (int i = 0; i < pk.slots.length; i++) { - pk.slots[i] = pk.slots[i] + 9; - } - - ((Player) holder).dataPacket(pk); - } } @@ -511,10 +458,6 @@ public void sendSlot(int index, Player... players) { if (player.equals(this.getHolder())) { pk.inventoryId = ContainerIds.INVENTORY; player.dataPacket(pk); - - if (index >= 0 && index <= 9) { //send hotbar always - this.sendHotbarContents(); - } } else { int id = player.getWindowId(this); if (id == -1) { diff --git a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java index ffc6c680c5..c1fab370b2 100644 --- a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java @@ -28,6 +28,8 @@ public class LoginPacket extends DataPacket { public String skinGeometryName; public byte[] skinGeometry; + public byte[] capeData; + @Override public byte pid() { return NETWORK_ID; @@ -72,7 +74,13 @@ private void decodeSkinData() { String skinId = null; 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("SkinData")) { + this.skin = new Skin(skinToken.get("SkinData").getAsString(), skinId); + + if (skinToken.has("CapeData")) + this.skin.setCape(this.skin.new Cape(Base64.getDecoder().decode(skinToken.get("CapeData").getAsString()))); + } + if (skinToken.has("SkinGeometryName")) this.skinGeometryName = skinToken.get("SkinGeometryName").getAsString(); if (skinToken.has("SkinGeometry")) this.skinGeometry = Base64.getDecoder().decode(skinToken.get("SkinGeometry").getAsString()); diff --git a/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java b/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java index b071951a88..37465f892e 100644 --- a/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java @@ -33,7 +33,7 @@ public void encode() { this.putVarLong(entry.entityId); this.putString(entry.name); this.putSkin(entry.skin); - this.putByteArray(entry.capeData); + this.putByteArray(entry.skin.getCape().getData()); this.putString(entry.geometryModel); this.putByteArray(entry.geometryData); this.putString(entry.xboxUserId); diff --git a/src/main/java/cn/nukkit/network/protocol/PlayerSkinPacket.java b/src/main/java/cn/nukkit/network/protocol/PlayerSkinPacket.java index ea8e22d710..b7de833ab5 100644 --- a/src/main/java/cn/nukkit/network/protocol/PlayerSkinPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/PlayerSkinPacket.java @@ -1,7 +1,18 @@ package cn.nukkit.network.protocol; +import cn.nukkit.entity.data.Skin; + +import java.util.UUID; + public class PlayerSkinPacket extends DataPacket { + public UUID uuid; + public Skin skin; + public String skinName; + public String serializeName; + public String geometryModel; + public String geometryData; + @Override public byte pid() { return ProtocolInfo.PLAYER_SKIN_PACKET; @@ -9,11 +20,30 @@ public byte pid() { @Override public void decode() { + this.uuid = this.getUUID(); + String skinId = this.getString(); + this.skinName = this.getString(); + this.serializeName = this.getString(); + byte[] data = this.getByteArray(); + byte[] cape = this.getByteArray(); + + this.skin = new Skin(data, skinId); + this.skin.setCape(this.skin.new Cape(cape)); + this.geometryModel = this.getString(); + this.geometryData = this.getString(); } @Override public void encode() { - //TODO + this.reset(); + this.putUUID(this.uuid); + this.putString(this.skin.getModel()); + this.putString(this.skinName); + this.putString(this.serializeName); + this.putByteArray(this.skin.getData()); + this.putByteArray(this.skin.getCape().getData()); + this.putString(this.geometryModel); + this.putString(this.geometryData); } } From c967d7f27dcde11f32ef4ca9ffba59d420df5272 Mon Sep 17 00:00:00 2001 From: boybook Date: Sun, 24 Sep 2017 14:18:19 +0800 Subject: [PATCH 089/175] Small fix of String.equals in ElementButtonImageData. --- .../java/cn/nukkit/form/element/ElementButtonImageData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java b/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java index fec2ad006e..1bc5a48b9b 100644 --- a/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java +++ b/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java @@ -9,7 +9,7 @@ public class ElementButtonImageData { public String data; public ElementButtonImageData(String type, String data) { - if (type != IMAGE_DATA_TYPE_URL && type != IMAGE_DATA_TYPE_PATH) return; + if (!type.equals(IMAGE_DATA_TYPE_URL) && !type.equals(IMAGE_DATA_TYPE_PATH)) return; this.type = type; this.data = data; } From c4dbe971ceea69ec38ed37bfa47c55000d945c32 Mon Sep 17 00:00:00 2001 From: boybook Date: Sun, 24 Sep 2017 15:57:55 +0800 Subject: [PATCH 090/175] Maybe fix Joining server crashed and "Disconnecting from Server" --- src/main/java/cn/nukkit/Player.java | 22 +++++++++++----------- src/main/java/cn/nukkit/Server.java | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 0a70a0e673..e6ada31172 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -852,6 +852,16 @@ protected void doFirstSpawn() { this.noDamageTicks = 60; + this.getServer().sendRecipeList(this); + + if (this.gamemode == Player.SPECTATOR) { + InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); + inventoryContentPacket.inventoryId = ContainerIds.CREATIVE; + this.dataPacket(inventoryContentPacket); + } else { + inventory.sendCreativeContents(); + } + for (long index : this.usedChunks.keySet()) { int chunkX = Level.getHashX(index); int chunkZ = Level.getHashZ(index); @@ -1855,8 +1865,6 @@ protected void processLogin() { if (this.isSpectator()) this.keepMovement = true; - this.setEnableClientCommand(true); - this.forceMovement = this.teleportPosition = this.getPosition(); ResourcePacksInfoPacket infoPacket = new ResourcePacksInfoPacket(); @@ -1929,15 +1937,7 @@ protected void completeLoginSequence() { this.setRemoveFormat(false); } - this.sendCommandData(); - - if (this.gamemode == Player.SPECTATOR) { - InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); - inventoryContentPacket.inventoryId = ContainerIds.CREATIVE; - this.dataPacket(inventoryContentPacket); - } else { - this.inventory.sendCreativeContents(); - } + this.setEnableClientCommand(true); this.server.addOnlinePlayer(this); this.server.onPlayerCompleteLoginSequence(this); diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index 38c2f8ae9f..a9d4065d24 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -70,6 +70,7 @@ import cn.nukkit.resourcepacks.ResourcePackManager; import cn.nukkit.scheduler.FileWriteTask; import cn.nukkit.scheduler.ServerScheduler; +import cn.nukkit.scheduler.Task; import cn.nukkit.utils.*; import cn.nukkit.utils.bugreport.ExceptionHandler; import co.aikar.timings.Timings; @@ -816,7 +817,6 @@ public void tickProcessor() { public void onPlayerCompleteLoginSequence(Player player) { this.sendFullPlayerListData(player); - this.sendRecipeList(player); } public void onPlayerLogin(Player player) { From 27797dcca31511f0e8e20b79a6e6ee8872b3216a Mon Sep 17 00:00:00 2001 From: boybook Date: Sun, 24 Sep 2017 15:59:13 +0800 Subject: [PATCH 091/175] Oops.. --- src/main/java/cn/nukkit/Server.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index a9d4065d24..80e5591353 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -70,7 +70,6 @@ import cn.nukkit.resourcepacks.ResourcePackManager; import cn.nukkit.scheduler.FileWriteTask; import cn.nukkit.scheduler.ServerScheduler; -import cn.nukkit.scheduler.Task; import cn.nukkit.utils.*; import cn.nukkit.utils.bugreport.ExceptionHandler; import co.aikar.timings.Timings; From a73e67197da40cdb08f203d55522e3aa3e084e58 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 24 Sep 2017 10:24:40 +0200 Subject: [PATCH 092/175] Improved brewing and added fuel --- src/main/java/cn/nukkit/Player.java | 38 ++--- .../cn/nukkit/blockentity/BlockEntity.java | 10 +- .../blockentity/BlockEntityBrewingStand.java | 146 ++++++++++++++---- .../cn/nukkit/event/inventory/BrewEvent.java | 59 +++++++ .../event/inventory/StartBrewEvent.java | 53 +++++++ .../cn/nukkit/inventory/BrewingInventory.java | 12 ++ .../cn/nukkit/inventory/InventoryType.java | 2 +- 7 files changed, 272 insertions(+), 48 deletions(-) create mode 100644 src/main/java/cn/nukkit/event/inventory/BrewEvent.java create mode 100644 src/main/java/cn/nukkit/event/inventory/StartBrewEvent.java diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index e6ada31172..15558e89d5 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -852,16 +852,6 @@ protected void doFirstSpawn() { this.noDamageTicks = 60; - this.getServer().sendRecipeList(this); - - if (this.gamemode == Player.SPECTATOR) { - InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); - inventoryContentPacket.inventoryId = ContainerIds.CREATIVE; - this.dataPacket(inventoryContentPacket); - } else { - inventory.sendCreativeContents(); - } - for (long index : this.usedChunks.keySet()) { int chunkX = Level.getHashX(index); int chunkZ = Level.getHashZ(index); @@ -1381,7 +1371,7 @@ protected void processMovement(int tickDiff) { if (diffX != 0 || diffY != 0 || diffZ != 0) { if (this.checkMovement && !server.getAllowFlight() && this.isSurvival()) { - // Some say: I cant move my head when riding because the server + // 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)); @@ -1865,6 +1855,8 @@ protected void processLogin() { if (this.isSpectator()) this.keepMovement = true; + this.setEnableClientCommand(true); + this.forceMovement = this.teleportPosition = this.getPosition(); ResourcePacksInfoPacket infoPacket = new ResourcePacksInfoPacket(); @@ -1874,6 +1866,13 @@ protected void processLogin() { } protected void completeLoginSequence() { + PlayerLoginEvent ev; + this.server.getPluginManager().callEvent(ev = new PlayerLoginEvent(this, "Plugin reason")); + if (ev.isCancelled()) { + this.close(this.getLeaveMessage(), ev.getKickMessage()); + return; + } + if (this.spawnPosition == null && this.namedTag.contains("SpawnLevel") && (level = this.server.getLevelByName(this.namedTag.getString("SpawnLevel"))) != null) { this.spawnPosition = new Position(this.namedTag.getInt("SpawnX"), this.namedTag.getInt("SpawnY"), this.namedTag.getInt("SpawnZ"), level); } @@ -1906,13 +1905,6 @@ protected void completeLoginSequence() { startGamePacket.generator = 1; //0 old, 1 infinite, 2 flat this.dataPacket(startGamePacket); - PlayerLoginEvent ev; - this.server.getPluginManager().callEvent(ev = new PlayerLoginEvent(this, "Plugin reason")); - if (ev.isCancelled()) { - this.close(this.getLeaveMessage(), ev.getKickMessage()); - return; - } - this.loggedIn = true; this.level.sendTime(this); @@ -1937,7 +1929,15 @@ protected void completeLoginSequence() { this.setRemoveFormat(false); } - this.setEnableClientCommand(true); + this.sendCommandData(); + + if (this.gamemode == Player.SPECTATOR) { + InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); + inventoryContentPacket.inventoryId = ContainerIds.CREATIVE; + this.dataPacket(inventoryContentPacket); + } else { + this.inventory.sendCreativeContents(); + } this.server.addOnlinePlayer(this); this.server.onPlayerCompleteLoginSequence(this); diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntity.java b/src/main/java/cn/nukkit/blockentity/BlockEntity.java index 5d188805e7..ce054acb6d 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntity.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntity.java @@ -49,6 +49,8 @@ public abstract class BlockEntity extends Position { public String name; public long id; + public boolean movable = true; + public boolean closed = false; public CompoundTag namedTag; protected long lastUpdate; @@ -71,6 +73,7 @@ public BlockEntity(FullChunk chunk, CompoundTag nbt) { this.x = this.namedTag.getInt("x"); this.y = this.namedTag.getInt("y"); this.z = this.namedTag.getInt("z"); + this.movable = this.namedTag.getBoolean("isMovable"); this.chunk.addBlockEntity(this); this.getLevel().addBlockEntity(this); @@ -141,6 +144,7 @@ public void saveNBT() { this.namedTag.putInt("x", (int) this.getX()); this.namedTag.putInt("y", (int) this.getY()); this.namedTag.putInt("z", (int) this.getZ()); + this.namedTag.putBoolean("isMovable", this.movable); } public CompoundTag getCleanedNBT() { @@ -155,7 +159,7 @@ public CompoundTag getCleanedNBT() { } public Block getBlock() { - return this.level.getBlock(this); + return this.getLevelBlock(); } public abstract boolean isBlockEntityValid(); @@ -186,6 +190,10 @@ public String getName() { return name; } + public boolean isMovable() { + return movable; + } + public static CompoundTag getDefaultCompound(Vector3 pos, String id) { return new CompoundTag("") .putString("id", id) diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java b/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java index 133c4cd2dd..2d3118fde1 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java @@ -1,10 +1,12 @@ package cn.nukkit.blockentity; - import cn.nukkit.Player; import cn.nukkit.Server; import cn.nukkit.block.Block; import cn.nukkit.block.BlockAir; +import cn.nukkit.block.BlockBrewingStand; +import cn.nukkit.event.inventory.BrewEvent; +import cn.nukkit.event.inventory.StartBrewEvent; import cn.nukkit.inventory.BrewingInventory; import cn.nukkit.inventory.BrewingRecipe; import cn.nukkit.inventory.InventoryHolder; @@ -28,6 +30,8 @@ public class BlockEntityBrewingStand extends BlockEntitySpawnable implements Inv public static final int MAX_BREW_TIME = 400; public int brewTime = MAX_BREW_TIME; + public int fuelTotal; + public int fuelAmount; public static final List ingredients = new ArrayList() { { @@ -53,6 +57,9 @@ public BlockEntityBrewingStand(FullChunk chunk, CompoundTag nbt) { this.brewTime = namedTag.getShort("CookTime"); } + this.fuelAmount = namedTag.getShort("FuelAmount"); + this.fuelTotal = namedTag.getShort("FuelTotal"); + if (brewTime < MAX_BREW_TIME) { this.scheduleUpdate(); } @@ -96,6 +103,8 @@ public void saveNBT() { } namedTag.putShort("CookTime", brewTime); + namedTag.putShort("FuelAmount", this.fuelAmount); + namedTag.putShort("FuelTotal", this.fuelTotal); } @Override @@ -167,46 +176,65 @@ public boolean onUpdate() { Item ingredient = this.inventory.getIngredient(); boolean canBrew = false; - for (int i = 1; i <= 3; i++) { - if (this.inventory.getItem(i).getId() == Item.POTION) { - canBrew = true; - } + Item fuel = this.getInventory().getFuel(); + if (this.fuelAmount <= 0 && fuel.getId() == Item.BLAZE_POWDER && fuel.getCount() > 0) { + fuel.count--; + this.fuelAmount = 20; + this.fuelTotal = 20; + + this.inventory.setFuel(fuel); + this.sendFuel(); } - if (this.brewTime <= MAX_BREW_TIME && canBrew && ingredient.getCount() > 0) { - if (!this.checkIngredient(ingredient)) { + if (this.fuelAmount > 0) { + for (int i = 1; i <= 3; i++) { + if (this.inventory.getItem(i).getId() == Item.POTION) { + canBrew = true; + } + } + + if (this.brewTime <= MAX_BREW_TIME && canBrew && ingredient.getCount() > 0) { + if (!this.checkIngredient(ingredient)) { + canBrew = false; + } + } else { canBrew = false; } - } else { - canBrew = false; } if (canBrew) { - this.brewTime--; + if (this.brewTime == MAX_BREW_TIME) { + this.sendBrewTime(); + StartBrewEvent e = new StartBrewEvent(this); + this.server.getPluginManager().callEvent(e); - for (Player player : this.inventory.getViewers()) { - int windowId = player.getWindowId(this.inventory); - if (windowId > 0) { - ContainerSetDataPacket pk = new ContainerSetDataPacket(); - pk.windowId = windowId; - pk.property = 0; - pk.value = this.brewTime; - player.dataPacket(pk); + if (e.isCancelled()) { + return false; } } + this.brewTime--; + if (this.brewTime <= 0) { //20 seconds - for (int i = 1; i <= 3; i++) { - Item potion = this.inventory.getItem(i); - BrewingRecipe recipe = Server.getInstance().getCraftingManager().matchBrewingRecipe(ingredient, potion); + BrewEvent e = new BrewEvent(this); + this.server.getPluginManager().callEvent(e); + + if (!e.isCancelled()) { + for (int i = 1; i <= 3; i++) { + Item potion = this.inventory.getItem(i); + BrewingRecipe recipe = Server.getInstance().getCraftingManager().matchBrewingRecipe(ingredient, potion); - if (recipe != null) { - this.inventory.setItem(i, recipe.getResult()); + if (recipe != null) { + this.inventory.setItem(i, recipe.getResult()); + } } - } - ingredient.count--; - this.inventory.setIngredient(ingredient); + ingredient.count--; + this.inventory.setIngredient(ingredient); + + this.fuelAmount--; + this.sendFuel(); + } this.brewTime = MAX_BREW_TIME; } @@ -216,11 +244,75 @@ public boolean onUpdate() { this.brewTime = MAX_BREW_TIME; } + //this.sendBrewTime(); lastUpdate = System.currentTimeMillis(); return ret; } + protected void sendFuel() { + ContainerSetDataPacket pk = new ContainerSetDataPacket(); + + for (Player p : this.inventory.getViewers()) { + int windowId = p.getWindowId(this.inventory); + if (windowId > 0) { + pk.windowId = windowId; + + pk.property = ContainerSetDataPacket.PROPERTY_BREWING_STAND_FUEL_AMOUNT; + pk.value = this.fuelAmount; + p.dataPacket(pk); + + pk.property = ContainerSetDataPacket.PROPERTY_BREWING_STAND_FUEL_TOTAL; + pk.value = this.fuelTotal; + p.dataPacket(pk); + } + } + } + + protected void sendBrewTime() { + ContainerSetDataPacket pk = new ContainerSetDataPacket(); + pk.property = ContainerSetDataPacket.PROPERTY_BREWING_STAND_BREW_TIME; + pk.value = this.brewTime; + + for (Player p : this.inventory.getViewers()) { + int windowId = p.getWindowId(this.inventory); + if (windowId > 0) { + pk.windowId = windowId; + + p.dataPacket(pk); + } + } + } + + public void updateBlock() { + Block block = this.getLevelBlock(); + + if (!(block instanceof BlockBrewingStand)) { + return; + } + + int meta = 0; + + for (int i = 1; i <= 3; ++i) { + Item potion = this.inventory.getItem(i); + + if (potion.getId() == Item.POTION && potion.getCount() > 0) { + meta |= 1 << i; + } + } + + block.setDamage(meta); + this.level.setBlock(block, block, false, false); + } + + public int getFuel() { + return fuelAmount; + } + + public void setFuel(int fuel) { + this.fuelAmount = fuel; + } + @Override public CompoundTag getSpawnCompound() { CompoundTag nbt = new CompoundTag() @@ -228,7 +320,7 @@ public CompoundTag getSpawnCompound() { .putInt("x", (int) this.x) .putInt("y", (int) this.y) .putInt("z", (int) this.z) - .putShort("CookTime", 0); + .putShort("CookTime", this.brewTime); if (this.hasName()) { nbt.put("CustomName", namedTag.get("CustomName")); diff --git a/src/main/java/cn/nukkit/event/inventory/BrewEvent.java b/src/main/java/cn/nukkit/event/inventory/BrewEvent.java new file mode 100644 index 0000000000..e00a225aaa --- /dev/null +++ b/src/main/java/cn/nukkit/event/inventory/BrewEvent.java @@ -0,0 +1,59 @@ +package cn.nukkit.event.inventory; + +import cn.nukkit.blockentity.BlockEntityBrewingStand; +import cn.nukkit.event.Cancellable; +import cn.nukkit.event.HandlerList; +import cn.nukkit.item.Item; + +/** + * @author CreeperFace + */ +public class BrewEvent extends InventoryEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlers() { + return handlers; + } + + private final BlockEntityBrewingStand brewingStand; + private final Item ingredient; + private final Item[] potions; + private final int fuel; + + public BrewEvent(BlockEntityBrewingStand blockEntity) { + super(blockEntity.getInventory()); + this.brewingStand = blockEntity; + this.fuel = blockEntity.fuelAmount; + + this.ingredient = blockEntity.getInventory().getIngredient(); + + this.potions = new Item[3]; + for (int i = 0; i < 3; i++) { + this.potions[i] = blockEntity.getInventory().getItem(i); + } + } + + public BlockEntityBrewingStand getBrewingStand() { + return brewingStand; + } + + public Item getIngredient() { + return ingredient; + } + + public Item[] getPotions() { + return potions; + } + + /** + * @param index Potion index in range 0 - 2 + */ + public Item getPotion(int index) { + return this.potions[index]; + } + + public int getFuel() { + return fuel; + } +} diff --git a/src/main/java/cn/nukkit/event/inventory/StartBrewEvent.java b/src/main/java/cn/nukkit/event/inventory/StartBrewEvent.java new file mode 100644 index 0000000000..5ad96b160e --- /dev/null +++ b/src/main/java/cn/nukkit/event/inventory/StartBrewEvent.java @@ -0,0 +1,53 @@ +package cn.nukkit.event.inventory; + +import cn.nukkit.blockentity.BlockEntityBrewingStand; +import cn.nukkit.event.Cancellable; +import cn.nukkit.event.HandlerList; +import cn.nukkit.item.Item; + +/** + * @author CreeperFace + */ +public class StartBrewEvent extends InventoryEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlers() { + return handlers; + } + + private final BlockEntityBrewingStand brewingStand; + private final Item ingredient; + private final Item[] potions; + + public StartBrewEvent(BlockEntityBrewingStand blockEntity) { + super(blockEntity.getInventory()); + this.brewingStand = blockEntity; + + this.ingredient = blockEntity.getInventory().getIngredient(); + + this.potions = new Item[3]; + for (int i = 0; i < 3; i++) { + this.potions[i] = blockEntity.getInventory().getItem(i); + } + } + + public BlockEntityBrewingStand getBrewingStand() { + return brewingStand; + } + + public Item getIngredient() { + return ingredient; + } + + public Item[] getPotions() { + return potions; + } + + /** + * @param index Potion index in range 0 - 2 + */ + public Item getPotion(int index) { + return this.potions[index]; + } +} diff --git a/src/main/java/cn/nukkit/inventory/BrewingInventory.java b/src/main/java/cn/nukkit/inventory/BrewingInventory.java index baa960d852..dd276f878a 100644 --- a/src/main/java/cn/nukkit/inventory/BrewingInventory.java +++ b/src/main/java/cn/nukkit/inventory/BrewingInventory.java @@ -22,10 +22,22 @@ public void setIngredient(Item item) { setItem(0, item); } + public void setFuel(Item fuel) { + setItem(4, fuel); + } + + public Item getFuel() { + return getItem(4); + } + @Override public void onSlotChange(int index, Item before, boolean send) { super.onSlotChange(index, before, send); + if (index >= 0 && index <= 2) { + this.getHolder().updateBlock(); + } + this.getHolder().scheduleUpdate(); } } \ No newline at end of file diff --git a/src/main/java/cn/nukkit/inventory/InventoryType.java b/src/main/java/cn/nukkit/inventory/InventoryType.java index 949440e708..f6ac77f11c 100644 --- a/src/main/java/cn/nukkit/inventory/InventoryType.java +++ b/src/main/java/cn/nukkit/inventory/InventoryType.java @@ -12,7 +12,7 @@ public enum InventoryType { FURNACE(3, "Furnace", 2), CRAFTING(5, "Crafting", 1), //4 CRAFTING slots, 1 RESULT WORKBENCH(10, "Crafting", 1), //9 CRAFTING slots, 1 RESULT - BREWING_STAND(4, "Brewing", 4), //1 INPUT, 3 POTION + BREWING_STAND(5, "Brewing", 4), //1 INPUT, 3 POTION, 1 fuel ANVIL(3, "Anvil", 5), //2 INPUT, 1 OUTPUT ENCHANT_TABLE(2, "Enchant", 3), //1 INPUT/OUTPUT, 1 LAPIS DISPENSER(0, "Dispenser", 6), //9 CONTAINER From be0ee5bc225971c382edeaef104b22bd41b26cf2 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 24 Sep 2017 10:31:55 +0200 Subject: [PATCH 093/175] Ops --- src/main/java/cn/nukkit/Player.java | 30 +++++++++++------------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 15558e89d5..037c1c2bfb 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -852,6 +852,16 @@ protected void doFirstSpawn() { this.noDamageTicks = 60; + this.getServer().sendRecipeList(this); + + if (this.gamemode == Player.SPECTATOR) { + InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); + inventoryContentPacket.inventoryId = ContainerIds.CREATIVE; + this.dataPacket(inventoryContentPacket); + } else { + inventory.sendCreativeContents(); + } + for (long index : this.usedChunks.keySet()) { int chunkX = Level.getHashX(index); int chunkZ = Level.getHashZ(index); @@ -1855,8 +1865,6 @@ protected void processLogin() { if (this.isSpectator()) this.keepMovement = true; - this.setEnableClientCommand(true); - this.forceMovement = this.teleportPosition = this.getPosition(); ResourcePacksInfoPacket infoPacket = new ResourcePacksInfoPacket(); @@ -1929,15 +1937,7 @@ protected void completeLoginSequence() { this.setRemoveFormat(false); } - this.sendCommandData(); - - if (this.gamemode == Player.SPECTATOR) { - InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); - inventoryContentPacket.inventoryId = ContainerIds.CREATIVE; - this.dataPacket(inventoryContentPacket); - } else { - this.inventory.sendCreativeContents(); - } + this.setEnableClientCommand(true); this.server.addOnlinePlayer(this); this.server.onPlayerCompleteLoginSequence(this); @@ -4877,10 +4877,6 @@ public boolean pickupEntity(Entity entity, boolean near) { 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()); @@ -4923,10 +4919,6 @@ public boolean pickupEntity(Entity entity, boolean near) { 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()); From e76717a5d43cbf644c8c3b480843cbfbfd4b42ef Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 24 Sep 2017 10:35:36 +0200 Subject: [PATCH 094/175] Add fuel to spawn nbt --- .../cn/nukkit/blockentity/BlockEntityBrewingStand.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java b/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java index 2d3118fde1..ec033ad95e 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntityBrewingStand.java @@ -320,7 +320,12 @@ public CompoundTag getSpawnCompound() { .putInt("x", (int) this.x) .putInt("y", (int) this.y) .putInt("z", (int) this.z) - .putShort("CookTime", this.brewTime); + .putShort("FuelTotal", this.fuelTotal) + .putShort("FuelAmount", this.fuelAmount); + + if (this.brewTime < MAX_BREW_TIME) { + nbt.putShort("CookTime", this.brewTime); + } if (this.hasName()) { nbt.put("CustomName", namedTag.get("CustomName")); From cd3ae729330d79e31648126a9a6b19cfaa06f3f3 Mon Sep 17 00:00:00 2001 From: boybook Date: Sun, 24 Sep 2017 21:38:46 +0800 Subject: [PATCH 095/175] Support PlayerSettings FormWindow --- src/main/java/cn/nukkit/Player.java | 17 +++++- .../player/PlayerSettingsRespondedEvent.java | 55 +++++++++++++++++++ .../nukkit/form/window/FormWindowCustom.java | 25 +++++++++ src/main/java/cn/nukkit/network/Network.java | 2 + 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 src/main/java/cn/nukkit/event/player/PlayerSettingsRespondedEvent.java diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index e6ada31172..c09190af81 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -30,6 +30,7 @@ import cn.nukkit.event.server.DataPacketReceiveEvent; import cn.nukkit.event.server.DataPacketSendEvent; import cn.nukkit.form.window.FormWindow; +import cn.nukkit.form.window.FormWindowCustom; import cn.nukkit.inventory.*; import cn.nukkit.inventory.transaction.InventoryTransaction; import cn.nukkit.inventory.transaction.SimpleInventoryTransaction; @@ -2386,6 +2387,15 @@ public void handleDataPacket(DataPacket packet) { getServer().getPluginManager().callEvent(event); formWindows.remove(modalFormPacket.formId); + } else if (serverSettings.containsKey(modalFormPacket.formId)) { + FormWindow window = serverSettings.get(modalFormPacket.formId); + window.setResponse(modalFormPacket.data.trim()); + + PlayerSettingsRespondedEvent event = new PlayerSettingsRespondedEvent(this, modalFormPacket.formId, window); + getServer().getPluginManager().callEvent(event); + + //Set back new settings if not been cancelled + if (!event.isCancelled() && window instanceof FormWindowCustom) ((FormWindowCustom) window).setElementsFromResponse(); } break; @@ -3498,7 +3508,12 @@ public void handleDataPacket(DataPacket packet) { this.inventory.equipItem(hotbarPacket.selectedHotbarSlot); break; case ProtocolInfo.SERVER_SETTINGS_REQUEST_PACKET: - + this.serverSettings.forEach((id, window) -> { + ServerSettingsResponsePacket re = new ServerSettingsResponsePacket(); + re.formId = id; + re.data = window.getJSONData(); + this.dataPacket(re); + }); break; default: break; diff --git a/src/main/java/cn/nukkit/event/player/PlayerSettingsRespondedEvent.java b/src/main/java/cn/nukkit/event/player/PlayerSettingsRespondedEvent.java new file mode 100644 index 0000000000..5743436543 --- /dev/null +++ b/src/main/java/cn/nukkit/event/player/PlayerSettingsRespondedEvent.java @@ -0,0 +1,55 @@ +package cn.nukkit.event.player; + +import cn.nukkit.Player; +import cn.nukkit.event.Cancellable; +import cn.nukkit.event.HandlerList; +import cn.nukkit.form.response.FormResponse; +import cn.nukkit.form.window.FormWindow; + +public class PlayerSettingsRespondedEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlers() { + return handlers; + } + + protected int formID; + protected FormWindow window; + + protected boolean closed = false; + + public PlayerSettingsRespondedEvent(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(); + } + + @Override + public void setCancelled() { + super.setCancelled(); + } + +} diff --git a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java index f52f81c572..cd4c70eddd 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java @@ -111,4 +111,29 @@ public void setResponse(String data) { sliderResponses, stepSliderResponses, toggleResponses); } + /** + * Set Elements from Response + * Used on ServerSettings Form Response. After players set settings, we need to sync these settings to the server. + */ + public void setElementsFromResponse() { + if (this.response != null) { + this.response.responses.forEach((i, response) -> { + Element e = content.get(i); + if (e != null) { + if (e instanceof ElementDropdown) { + ((ElementDropdown) e).defaultOptionIndex = ((ElementDropdown) e).options.indexOf(response); + } else if (e instanceof ElementInput) { + ((ElementInput) e).defaultText = (String)response; + } else if (e instanceof ElementSlider) { + ((ElementSlider) e).defaultValue = (Float)response; + } else if (e instanceof ElementStepSlider) { + ((ElementStepSlider) e).defaultStepIndex = ((ElementStepSlider) e).steps.indexOf(response); + } else if (e instanceof ElementToggle) { + ((ElementToggle) e).defaultValue = (Boolean)response; + } + } + }); + } + } + } diff --git a/src/main/java/cn/nukkit/network/Network.java b/src/main/java/cn/nukkit/network/Network.java index bf1c50b119..25185c798a 100644 --- a/src/main/java/cn/nukkit/network/Network.java +++ b/src/main/java/cn/nukkit/network/Network.java @@ -276,6 +276,8 @@ private void registerPackets() { this.registerPacket(ProtocolInfo.SET_SPAWN_POSITION_PACKET, SetSpawnPositionPacket.class); this.registerPacket(ProtocolInfo.SET_TITLE_PACKET, SetTitlePacket.class); this.registerPacket(ProtocolInfo.SET_TIME_PACKET, SetTimePacket.class); + this.registerPacket(ProtocolInfo.SERVER_SETTINGS_REQUEST_PACKET, ServerSettingsRequestPacket.class); + this.registerPacket(ProtocolInfo.SERVER_SETTINGS_RESPONSE_PACKET, ServerSettingsResponsePacket.class); this.registerPacket(ProtocolInfo.SHOW_CREDITS_PACKET, ShowCreditsPacket.class); this.registerPacket(ProtocolInfo.SPAWN_EXPERIENCE_ORB_PACKET, SpawnExperienceOrbPacket.class); this.registerPacket(ProtocolInfo.START_GAME_PACKET, StartGamePacket.class); From 8b118137bc0db42d63380bc83c519d3161479ac0 Mon Sep 17 00:00:00 2001 From: boybook Date: Mon, 25 Sep 2017 16:17:56 +0800 Subject: [PATCH 096/175] Fix Projectile Items. --- src/main/java/cn/nukkit/Server.java | 2 ++ src/main/java/cn/nukkit/item/ItemEgg.java | 12 +++++++- .../java/cn/nukkit/item/ItemEnderPearl.java | 12 +++++++- .../java/cn/nukkit/item/ItemExpBottle.java | 12 +++++++- .../java/cn/nukkit/item/ItemPotionSplash.java | 12 +++++++- .../java/cn/nukkit/item/ProjectileItem.java | 28 ++++++++++--------- 6 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index 80e5591353..87ee947c35 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -11,6 +11,7 @@ import cn.nukkit.entity.mob.*; import cn.nukkit.entity.passive.*; import cn.nukkit.entity.projectile.EntityArrow; +import cn.nukkit.entity.projectile.EntityEgg; import cn.nukkit.entity.projectile.EntityEnderPearl; import cn.nukkit.entity.projectile.EntitySnowball; import cn.nukkit.event.HandlerList; @@ -1954,6 +1955,7 @@ private void registerEntities() { Entity.registerEntity("ThrownExpBottle", EntityExpBottle.class); Entity.registerEntity("XpOrb", EntityXPOrb.class); Entity.registerEntity("ThrownPotion", EntityPotion.class); + Entity.registerEntity("Egg", EntityEgg.class); Entity.registerEntity("Human", EntityHuman.class, true); diff --git a/src/main/java/cn/nukkit/item/ItemEgg.java b/src/main/java/cn/nukkit/item/ItemEgg.java index 139071cf4f..38eb3f062f 100644 --- a/src/main/java/cn/nukkit/item/ItemEgg.java +++ b/src/main/java/cn/nukkit/item/ItemEgg.java @@ -4,7 +4,7 @@ * author: MagicDroidX * Nukkit Project */ -public class ItemEgg extends Item { +public class ItemEgg extends ProjectileItem { public ItemEgg() { this(0, 1); @@ -17,4 +17,14 @@ public ItemEgg(Integer meta) { public ItemEgg(Integer meta, int count) { super(EGG, meta, count, "Egg"); } + + @Override + public String getProjectileEntityType() { + return "Egg"; + } + + @Override + public float getThrowForce() { + return 1.5f; + } } diff --git a/src/main/java/cn/nukkit/item/ItemEnderPearl.java b/src/main/java/cn/nukkit/item/ItemEnderPearl.java index b2895fdd3a..138de386ae 100644 --- a/src/main/java/cn/nukkit/item/ItemEnderPearl.java +++ b/src/main/java/cn/nukkit/item/ItemEnderPearl.java @@ -1,6 +1,6 @@ package cn.nukkit.item; -public class ItemEnderPearl extends Item { +public class ItemEnderPearl extends ProjectileItem { public ItemEnderPearl() { this(0, 1); @@ -18,4 +18,14 @@ public ItemEnderPearl(Integer meta, int count) { public int getMaxStackSize() { return 16; } + + @Override + public String getProjectileEntityType() { + return "EnderPearl"; + } + + @Override + public float getThrowForce() { + return 1.5f; + } } diff --git a/src/main/java/cn/nukkit/item/ItemExpBottle.java b/src/main/java/cn/nukkit/item/ItemExpBottle.java index 04c288b5f4..247e282431 100644 --- a/src/main/java/cn/nukkit/item/ItemExpBottle.java +++ b/src/main/java/cn/nukkit/item/ItemExpBottle.java @@ -4,7 +4,7 @@ * Created on 2015/12/25 by xtypr. * Package cn.nukkit.item in project Nukkit . */ -public class ItemExpBottle extends Item { +public class ItemExpBottle extends ProjectileItem { public ItemExpBottle() { this(0, 1); @@ -18,4 +18,14 @@ public ItemExpBottle(Integer meta, int count) { super(EXPERIENCE_BOTTLE, meta, count, "Bottle o' Enchanting"); } + @Override + public String getProjectileEntityType() { + return "ThrownExpBottle"; + } + + @Override + public float getThrowForce() { + return 1f; + } + } diff --git a/src/main/java/cn/nukkit/item/ItemPotionSplash.java b/src/main/java/cn/nukkit/item/ItemPotionSplash.java index d337540f0c..38c7504738 100644 --- a/src/main/java/cn/nukkit/item/ItemPotionSplash.java +++ b/src/main/java/cn/nukkit/item/ItemPotionSplash.java @@ -4,7 +4,7 @@ * Created on 2015/12/27 by xtypr. * Package cn.nukkit.item in project Nukkit . */ -public class ItemPotionSplash extends Item { +public class ItemPotionSplash extends ProjectileItem { public ItemPotionSplash(Integer meta) { this(meta, 1); @@ -23,4 +23,14 @@ public int getMaxStackSize() { public boolean canBeActivated() { return true; } + + @Override + public String getProjectileEntityType() { + return "ThrownPotion"; + } + + @Override + public float getThrowForce() { + return 1f; + } } diff --git a/src/main/java/cn/nukkit/item/ProjectileItem.java b/src/main/java/cn/nukkit/item/ProjectileItem.java index 3443f1f317..a4e2a1385b 100644 --- a/src/main/java/cn/nukkit/item/ProjectileItem.java +++ b/src/main/java/cn/nukkit/item/ProjectileItem.java @@ -38,25 +38,27 @@ public boolean onClickAir(Player player, Vector3 directionVector) { .add(new FloatTag("", (float) player.yaw)) .add(new FloatTag("", (float) player.pitch))); - Entity snowball = Entity.createEntity(this.getProjectileEntityType(), player.getLevel().getChunk(player.getFloorX() >> 4, player.getFloorZ() >> 4), nbt, player); - snowball.setMotion(snowball.getMotion().multiply(this.getThrowForce())); + Entity projectile = Entity.createEntity(this.getProjectileEntityType(), player.getLevel().getChunk(player.getFloorX() >> 4, player.getFloorZ() >> 4), nbt, player); + if (projectile != null) { + projectile.setMotion(projectile.getMotion().multiply(this.getThrowForce())); + this.count--; - this.count--; + if (projectile instanceof EntityProjectile) { + ProjectileLaunchEvent ev = new ProjectileLaunchEvent((EntityProjectile) projectile); - if (snowball instanceof EntityProjectile) { - ProjectileLaunchEvent ev = new ProjectileLaunchEvent((EntityProjectile) snowball); - - player.getServer().getPluginManager().callEvent(ev); - if (ev.isCancelled()) { - snowball.kill(); + player.getServer().getPluginManager().callEvent(ev); + if (ev.isCancelled()) { + projectile.kill(); + } else { + projectile.spawnToAll(); + player.getLevel().addSound(new LaunchSound(player), player.getViewers().values()); + } } else { - snowball.spawnToAll(); - player.getLevel().addSound(new LaunchSound(player), player.getViewers().values()); + projectile.spawnToAll(); } } else { - snowball.spawnToAll(); + return false; } - return true; } } From 164b57edda57b0adc37649fba5ce27395bb961e8 Mon Sep 17 00:00:00 2001 From: boybook Date: Mon, 25 Sep 2017 16:19:40 +0800 Subject: [PATCH 097/175] Broadcast LevelSoundEventPacket, More sounds! --- src/main/java/cn/nukkit/Player.java | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index ef18bfa415..7a2d96b4c2 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -3150,19 +3150,9 @@ public void handleDataPacket(DataPacket packet) { 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); - } + //LevelSoundEventPacket levelSoundEventPacket = (LevelSoundEventPacket) packet; + //We just need to broadcast this packet to all viewers. + this.level.addChunkPacket(this.getFloorX() >> 4, this.getFloorZ() >> 4, packet); break; case ProtocolInfo.INVENTORY_TRANSACTION_PACKET: if (this.isSpectator()) { From 5da1e7149653bf0e6c340af52fe079745f90c845 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Mon, 25 Sep 2017 14:20:55 +0200 Subject: [PATCH 098/175] Add PlayerBlockPickEvent + eating sounds --- src/main/java/cn/nukkit/Player.java | 82 ++++++------------- .../event/player/PlayerBlockPickEvent.java | 40 +++++++++ .../protocol/BlockPickRequestPacket.java | 2 + .../network/protocol/EntityEventPacket.java | 10 +-- 4 files changed, 71 insertions(+), 63 deletions(-) create mode 100644 src/main/java/cn/nukkit/event/player/PlayerBlockPickEvent.java diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 037c1c2bfb..246cf007b4 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2429,10 +2429,13 @@ public void handleDataPacket(DataPacket packet) { break; case ProtocolInfo.BLOCK_PICK_REQUEST_PACKET: BlockPickRequestPacket pickRequestPacket = (BlockPickRequestPacket) packet; - if (this.isCreative()) { - BlockEntity be = this.getLevel().getBlockEntity(new Vector3(pickRequestPacket.x, pickRequestPacket.y, pickRequestPacket.z)); - if (be != null) { - CompoundTag nbt = be.getCleanedNBT(); + Block block = this.level.getBlock(this.temporalVector.setComponents(pickRequestPacket.x, pickRequestPacket.y, pickRequestPacket.z)); + item = block.toItem(); + + if (pickRequestPacket.addUserData) { + BlockEntity blockEntity = this.getLevel().getBlockEntity(new Vector3(pickRequestPacket.x, pickRequestPacket.y, pickRequestPacket.z)); + if (blockEntity != null) { + CompoundTag nbt = blockEntity.getCleanedNBT(); if (nbt != null) { Item item1 = this.getInventory().getItemInHand(); item1.setCustomBlockData(nbt); @@ -2441,6 +2444,18 @@ public void handleDataPacket(DataPacket packet) { } } } + + PlayerBlockPickEvent pickEvent = new PlayerBlockPickEvent(this, block, item); + if (!this.isCreative()) { + this.server.getLogger().debug("Got block-pick request from " + this.getName() + " when not in creative mode (gamemode " + this.getGamemode() + ")"); + pickEvent.setCancelled(); + } + + this.server.getPluginManager().callEvent(pickEvent); + + if (!pickEvent.isCancelled()) { + this.inventory.setItemInHand(pickEvent.getItem()); + } break; case ProtocolInfo.ANIMATE_PACKET: if (!this.spawned || !this.isAlive()) { @@ -2472,61 +2487,14 @@ public void handleDataPacket(DataPacket packet) { 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); - if (consumeEvent.isCancelled()) { - this.inventory.sendContents(this); + case EntityEventPacket.EATING_ITEM: + if (entityEventPacket.data == 0) { break; } - if (itemInHand.getId() == Item.POTION) { - Potion potion = Potion.getPotion(itemInHand.getDamage()).setSplash(false); - - if (this.getGamemode() == SURVIVAL) { - if (itemInHand.getCount() > 1) { - ItemGlassBottle bottle = new ItemGlassBottle(); - if (this.inventory.canAddItem(bottle)) { - this.inventory.addItem(bottle); - } - --itemInHand.count; - } else { - itemInHand = new ItemGlassBottle(); - } - } - - if (potion != null) { - potion.applyPotion(this); - } - - } else { - EntityEventPacket pk = new EntityEventPacket(); - pk.eid = this.getId(); - pk.event = EntityEventPacket.USE_ITEM; - this.dataPacket(pk); - Server.broadcastPacket(this.getViewers().values(), pk); - - Food food = Food.getByRelative(itemInHand); - if (food != null) if (food.eatenBy(this)) --itemInHand.count; - } - - this.inventory.setItemInHand(itemInHand); - this.inventory.sendHeldItem(this); - + this.dataPacket(packet); + Server.broadcastPacket(this.getViewers().values(), packet); break; - /*case EntityEventPacket.CONSUME_ITEM: - EntityEventPacket pk = new EntityEventPacket(); - pk.eid = this.getId(); - pk.event = EntityEventPacket.CONSUME_ITEM; - pk.itemId = this.inventory.getItemInHand().getId(); - - if (pk.itemId != Item.POTION) { //idk what's wrong - Server.broadcastPacket(this.getViewers().values(), pk); - this.dataPacket(pk); - } - break;*/ } break; case ProtocolInfo.COMMAND_REQUEST_PACKET: @@ -3089,7 +3057,7 @@ public void handleDataPacket(DataPacket packet) { BlockEntity blockEntityItemFrame = this.level.getBlockEntity(vector3); BlockEntityItemFrame itemFrame = (BlockEntityItemFrame) blockEntityItemFrame; if (itemFrame != null) { - Block block = itemFrame.getBlock(); + block = itemFrame.getBlock(); Item itemDrop = itemFrame.getItem(); ItemFrameDropItemEvent itemFrameDropItemEvent = new ItemFrameDropItemEvent(this, block, itemFrame, itemDrop); this.server.getPluginManager().callEvent(itemFrameDropItemEvent); @@ -3240,7 +3208,7 @@ public void handleDataPacket(DataPacket packet) { } Block target = this.level.getBlock(blockVector.asVector3()); - Block block = target.getSide(face); + block = target.getSide(face); this.level.sendBlocks(new Player[]{this}, new Block[]{target, block}, UpdateBlockPacket.FLAG_ALL_PRIORITY); diff --git a/src/main/java/cn/nukkit/event/player/PlayerBlockPickEvent.java b/src/main/java/cn/nukkit/event/player/PlayerBlockPickEvent.java new file mode 100644 index 0000000000..bbca5b106e --- /dev/null +++ b/src/main/java/cn/nukkit/event/player/PlayerBlockPickEvent.java @@ -0,0 +1,40 @@ +package cn.nukkit.event.player; + +import cn.nukkit.Player; +import cn.nukkit.block.Block; +import cn.nukkit.event.Cancellable; +import cn.nukkit.event.HandlerList; +import cn.nukkit.item.Item; + +/** + * @author CreeperFace + */ +public class PlayerBlockPickEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlers() { + return handlers; + } + + private final Block blockClicked; + private Item item; + + public PlayerBlockPickEvent(Player player, Block blockClicked, Item item) { + this.blockClicked = blockClicked; + this.item = item; + this.player = player; + } + + public Item getItem() { + return item; + } + + public void setItem(Item item) { + this.item = item; + } + + public Block getBlockClicked() { + return blockClicked; + } +} diff --git a/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java b/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java index cd6f4701c6..d0da9beaf5 100644 --- a/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java @@ -9,6 +9,7 @@ public class BlockPickRequestPacket extends DataPacket { public int x; public int y; public int z; + public boolean addUserData; public int selectedSlot; @Override @@ -22,6 +23,7 @@ public void decode() { this.x = v.x; this.y = v.y; this.z = v.z; + this.putBoolean(this.addUserData); this.selectedSlot = this.getByte(); } diff --git a/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java b/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java index 6fdd0bf9c5..2ad19b9e17 100644 --- a/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/EntityEventPacket.java @@ -27,9 +27,7 @@ public class EntityEventPacket extends DataPacket { public static final int ENCHANT = 34; - public static final int FEED = 57; - - public static final byte CONSUME_ITEM = 57; + public static final byte EATING_ITEM = 57; public static final byte UNKNOWN1 = 66; @@ -40,13 +38,13 @@ public byte pid() { public long eid; public int event; - public int type; + public int data; @Override public void decode() { this.eid = this.getEntityRuntimeId(); this.event = this.getByte(); - this.type = this.getVarInt(); + this.data = this.getVarInt(); } @Override @@ -54,6 +52,6 @@ public void encode() { this.reset(); this.putEntityRuntimeId(this.eid); this.putByte((byte) this.event); - this.putVarInt((byte) this.type); + this.putVarInt((byte) this.data); } } From 28db22d4e49a27567ce82dd6cd1e578a07d6dbc8 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Mon, 25 Sep 2017 16:22:47 +0200 Subject: [PATCH 099/175] Fix splash potion type --- src/main/java/cn/nukkit/item/ItemPotionSplash.java | 8 ++++++++ src/main/java/cn/nukkit/item/ProjectileItem.java | 13 +++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/cn/nukkit/item/ItemPotionSplash.java b/src/main/java/cn/nukkit/item/ItemPotionSplash.java index 38c7504738..77ff8c8d9f 100644 --- a/src/main/java/cn/nukkit/item/ItemPotionSplash.java +++ b/src/main/java/cn/nukkit/item/ItemPotionSplash.java @@ -1,5 +1,8 @@ package cn.nukkit.item; +import cn.nukkit.nbt.tag.IntTag; +import cn.nukkit.nbt.tag.Tag; + /** * Created on 2015/12/27 by xtypr. * Package cn.nukkit.item in project Nukkit . @@ -33,4 +36,9 @@ public String getProjectileEntityType() { public float getThrowForce() { return 1f; } + + @Override + protected Tag[] getAdditionalNBT() { + return new Tag[]{new IntTag("PotionId", this.meta)}; + } } diff --git a/src/main/java/cn/nukkit/item/ProjectileItem.java b/src/main/java/cn/nukkit/item/ProjectileItem.java index a4e2a1385b..0096415a62 100644 --- a/src/main/java/cn/nukkit/item/ProjectileItem.java +++ b/src/main/java/cn/nukkit/item/ProjectileItem.java @@ -6,10 +6,7 @@ import cn.nukkit.event.entity.ProjectileLaunchEvent; import cn.nukkit.level.sound.LaunchSound; import cn.nukkit.math.Vector3; -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.nbt.tag.*; /** * @author CreeperFace @@ -38,6 +35,10 @@ public boolean onClickAir(Player player, Vector3 directionVector) { .add(new FloatTag("", (float) player.yaw)) .add(new FloatTag("", (float) player.pitch))); + for (Tag tag : getAdditionalNBT()) { + nbt.put(tag.getName(), tag); + } + Entity projectile = Entity.createEntity(this.getProjectileEntityType(), player.getLevel().getChunk(player.getFloorX() >> 4, player.getFloorZ() >> 4), nbt, player); if (projectile != null) { projectile.setMotion(projectile.getMotion().multiply(this.getThrowForce())); @@ -61,4 +62,8 @@ public boolean onClickAir(Player player, Vector3 directionVector) { } return true; } + + protected Tag[] getAdditionalNBT() { + return new Tag[0]; + } } From 0c39fe61e6d8d837d8aec90af6644325e53da59c Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Mon, 25 Sep 2017 16:24:41 +0200 Subject: [PATCH 100/175] Better method --- src/main/java/cn/nukkit/item/ItemPotionSplash.java | 7 +++---- src/main/java/cn/nukkit/item/ProjectileItem.java | 13 +++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/cn/nukkit/item/ItemPotionSplash.java b/src/main/java/cn/nukkit/item/ItemPotionSplash.java index 77ff8c8d9f..fa4bcc38f6 100644 --- a/src/main/java/cn/nukkit/item/ItemPotionSplash.java +++ b/src/main/java/cn/nukkit/item/ItemPotionSplash.java @@ -1,7 +1,6 @@ package cn.nukkit.item; -import cn.nukkit.nbt.tag.IntTag; -import cn.nukkit.nbt.tag.Tag; +import cn.nukkit.nbt.tag.CompoundTag; /** * Created on 2015/12/27 by xtypr. @@ -38,7 +37,7 @@ public float getThrowForce() { } @Override - protected Tag[] getAdditionalNBT() { - return new Tag[]{new IntTag("PotionId", this.meta)}; + protected void correctNBT(CompoundTag nbt) { + nbt.putInt("PotionId", this.meta); } } diff --git a/src/main/java/cn/nukkit/item/ProjectileItem.java b/src/main/java/cn/nukkit/item/ProjectileItem.java index 0096415a62..2af398a52a 100644 --- a/src/main/java/cn/nukkit/item/ProjectileItem.java +++ b/src/main/java/cn/nukkit/item/ProjectileItem.java @@ -6,7 +6,10 @@ import cn.nukkit.event.entity.ProjectileLaunchEvent; import cn.nukkit.level.sound.LaunchSound; import cn.nukkit.math.Vector3; -import cn.nukkit.nbt.tag.*; +import cn.nukkit.nbt.tag.CompoundTag; +import cn.nukkit.nbt.tag.DoubleTag; +import cn.nukkit.nbt.tag.FloatTag; +import cn.nukkit.nbt.tag.ListTag; /** * @author CreeperFace @@ -35,9 +38,7 @@ public boolean onClickAir(Player player, Vector3 directionVector) { .add(new FloatTag("", (float) player.yaw)) .add(new FloatTag("", (float) player.pitch))); - for (Tag tag : getAdditionalNBT()) { - nbt.put(tag.getName(), tag); - } + this.correctNBT(nbt); Entity projectile = Entity.createEntity(this.getProjectileEntityType(), player.getLevel().getChunk(player.getFloorX() >> 4, player.getFloorZ() >> 4), nbt, player); if (projectile != null) { @@ -63,7 +64,7 @@ public boolean onClickAir(Player player, Vector3 directionVector) { return true; } - protected Tag[] getAdditionalNBT() { - return new Tag[0]; + protected void correctNBT(CompoundTag nbt) { + } } From 5e5f6ce1c6c6954cc939639954680cfef479c8d8 Mon Sep 17 00:00:00 2001 From: kvetinac97 Date: Tue, 26 Sep 2017 07:17:33 +0200 Subject: [PATCH 101/175] Repair BossBar, add old title methods for better compatibility (#19) * Make old plugins working on this Nukkit * Forgot these imports * Who did invent this? * Back to how this should be * Forgot this --- src/main/java/cn/nukkit/Player.java | 36 +++++++--- .../network/protocol/BossEventPacket.java | 67 +------------------ 2 files changed, 29 insertions(+), 74 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 1d5c57e528..b38ab1b39a 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -12,6 +12,7 @@ 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.EntityArrow; import cn.nukkit.event.block.ItemFrameDropItemEvent; import cn.nukkit.event.block.SignChangeEvent; @@ -79,6 +80,7 @@ import java.util.*; import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.ThreadLocalRandom; /** * author: MagicDroidX & Box @@ -3635,6 +3637,22 @@ public void resetTitleSettings() { pk.type = SetTitlePacket.TYPE_RESET; this.dataPacket(pk); } + + public void setSubtitle(String subtitle){ + SetTitlePacket pk = new SetTitlePacket(); + pk.type = SetTitlePacket.TYPE_SUBTITLE; + pk.text = subtitle; + this.dataPacket(pk); + } + + public void setTitleAnimationTimes(int fadein, int duration, int fadeout){ + SetTitlePacket pk = new SetTitlePacket(); + pk.type = SetTitlePacket.TYPE_ANIMATION_TIMES; + pk.fadeInTime = fadein; + pk.stayTime = duration; + pk.fadeOutTime = fadeout; + this.dataPacket(pk); + } public void sendTitle(String title) { this.sendTitle(title, "", 20, 20, 5); @@ -4484,7 +4502,7 @@ public int addServerSettings(FormWindow window) { * @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(); @@ -4521,11 +4539,11 @@ public int addServerSettings(FormWindow window) { // And now we send the bossbar packet BossEventPacket pkBoss = new BossEventPacket(); - pkBoss.eid = bossBarId; - pkBoss.type = BossEventPacket.ADD; + pkBoss.bossEid = bossBarId; + pkBoss.type = BossEventPacket.TYPE_SHOW; this.dataPacket(pkBoss); return bossBarId; - }*/ + } /** * Updates a BossBar @@ -4534,7 +4552,7 @@ public int addServerSettings(FormWindow window) { * @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; @@ -4559,11 +4577,11 @@ public int addServerSettings(FormWindow window) { // And now we send the bossbar packet BossEventPacket pkBoss = new BossEventPacket(); - pkBoss.eid = bossBarId; - pkBoss.type = BossEventPacket.UPDATE; + pkBoss.bossEid = bossBarId; + pkBoss.type = BossEventPacket.TYPE_UPDATE; this.dataPacket(pkBoss); return; - }*/ + } /** * Removes a BossBar @@ -4948,4 +4966,4 @@ public void notifyACK(int identification) { public boolean isBreakingBlock() { return this.breakingBlock != null; } -} \ No newline at end of file +} diff --git a/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java b/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java index 1b52ddc078..ef0675f1a3 100644 --- a/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java @@ -7,32 +7,13 @@ public class BossEventPacket extends DataPacket { public static final byte NETWORK_ID = ProtocolInfo.BOSS_EVENT_PACKET; - /* 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_UPDATE = 1; 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 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() { return NETWORK_ID; @@ -40,29 +21,6 @@ public byte pid() { @Override public void decode() { - this.bossEid = this.getEntityUniqueId(); - this.type = (int) this.getUnsignedVarInt(); - switch (this.type) { - case TYPE_REGISTER_PLAYER: - case TYPE_UNREGISTER_PLAYER: - this.playerEid = this.getEntityUniqueId(); - 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 @@ -70,26 +28,5 @@ public void encode() { this.reset(); this.putEntityUniqueId(this.bossEid); this.putUnsignedVarInt(this.type); - switch (this.type) { - case TYPE_REGISTER_PLAYER: - case TYPE_UNREGISTER_PLAYER: - this.putEntityUniqueId(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; - } } } From 940421109a1473c4d71bc87c274df3c0af7c6d01 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Tue, 26 Sep 2017 17:52:54 +0200 Subject: [PATCH 102/175] add fortune --- src/main/java/cn/nukkit/Player.java | 114 ++++++++++-------- .../java/cn/nukkit/block/BlockGlowstone.java | 14 ++- src/main/java/cn/nukkit/block/BlockMelon.java | 11 +- .../java/cn/nukkit/block/BlockOreCoal.java | 17 ++- .../java/cn/nukkit/block/BlockOreDiamond.java | 17 ++- .../java/cn/nukkit/block/BlockOreEmerald.java | 17 ++- .../java/cn/nukkit/block/BlockOreGold.java | 2 +- .../java/cn/nukkit/block/BlockOreIron.java | 2 +- .../java/cn/nukkit/block/BlockOreLapis.java | 14 +++ .../java/cn/nukkit/block/BlockOreQuartz.java | 17 ++- .../cn/nukkit/block/BlockOreRedstone.java | 10 +- .../java/cn/nukkit/item/ProjectileItem.java | 2 +- 12 files changed, 176 insertions(+), 61 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 1d5c57e528..2350187b95 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -3389,66 +3389,78 @@ public void handleDataPacket(DataPacket packet) { case InventoryTransactionPacket.TYPE_RELEASE_ITEM: ReleaseItemData releaseItemData = (ReleaseItemData) transactionPacket.transactionData; - type = releaseItemData.actionType; - switch (type) { - case InventoryTransactionPacket.RELEASE_ITEM_ACTION_RELEASE: - if (this.isUsingItem()) { - item = this.inventory.getItemInHand(); - if (item.onReleaseUsing(this)) { - this.inventory.setItemInHand(item); + try { + type = releaseItemData.actionType; + switch (type) { + case InventoryTransactionPacket.RELEASE_ITEM_ACTION_RELEASE: + if (this.isUsingItem()) { + item = this.inventory.getItemInHand(); + if (item.onReleaseUsing(this)) { + this.inventory.setItemInHand(item); + } + } else { + this.inventory.sendContents(this); } - } else { - this.inventory.sendContents(this); - } + return; + case InventoryTransactionPacket.RELEASE_ITEM_ACTION_CONSUME: + Item itemInHand = this.inventory.getItemInHand(); + PlayerItemConsumeEvent consumeEvent = new PlayerItemConsumeEvent(this, itemInHand); + + if (itemInHand.getId() == Item.POTION) { + this.server.getPluginManager().callEvent(consumeEvent); + if (consumeEvent.isCancelled()) { + this.inventory.sendContents(this); + break; + } + Potion potion = Potion.getPotion(itemInHand.getDamage()).setSplash(false); - this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION, false); - return; - case InventoryTransactionPacket.RELEASE_ITEM_ACTION_CONSUME: - this.setDataFlag(DATA_FLAGS, DATA_FLAG_ACTION, false); - Item itemInHand = this.inventory.getItemInHand(); - PlayerItemConsumeEvent consumeEvent = new PlayerItemConsumeEvent(this, itemInHand); - this.server.getPluginManager().callEvent(consumeEvent); - if (consumeEvent.isCancelled()) { - this.inventory.sendContents(this); - break; - } + if (this.getGamemode() == SURVIVAL) { + --itemInHand.count; + this.inventory.setItemInHand(itemInHand); + this.inventory.addItem(new ItemGlassBottle()); + } - if (itemInHand.getId() == Item.POTION) { - Potion potion = Potion.getPotion(itemInHand.getDamage()).setSplash(false); + if (potion != null) { + potion.applyPotion(this); + } - if (this.getGamemode() == SURVIVAL) { - if (itemInHand.getCount() > 1) { - ItemGlassBottle bottle = new ItemGlassBottle(); - if (this.inventory.canAddItem(bottle)) { - this.inventory.addItem(bottle); - } - --itemInHand.count; - } else { - itemInHand = new ItemGlassBottle(); + } else if (itemInHand.getId() == Item.BUCKET && itemInHand.getDamage() == 1) { //milk + this.server.getPluginManager().callEvent(consumeEvent); + if (consumeEvent.isCancelled()) { + this.inventory.sendContents(this); + break; } - } - if (potion != null) { - potion.applyPotion(this); - } + EntityEventPacket eventPacket = new EntityEventPacket(); + eventPacket.eid = this.getId(); + eventPacket.event = EntityEventPacket.USE_ITEM; + this.dataPacket(eventPacket); + Server.broadcastPacket(this.getViewers().values(), eventPacket); - } else { - EntityEventPacket eventPacket = new EntityEventPacket(); - eventPacket.eid = this.getId(); - eventPacket.event = EntityEventPacket.USE_ITEM; - this.dataPacket(eventPacket); - Server.broadcastPacket(this.getViewers().values(), eventPacket); - - Food food = Food.getByRelative(itemInHand); - if (food != null) if (food.eatenBy(this)) --itemInHand.count; - } + if (this.isSurvival()) { + itemInHand.count--; + this.inventory.setItemInHand(itemInHand); + this.inventory.addItem(new ItemBucket()); + } - this.inventory.setItemInHand(itemInHand); - this.inventory.sendHeldItem(this); + this.removeAllEffects(); + } else { + this.server.getPluginManager().callEvent(consumeEvent); + if (consumeEvent.isCancelled()) { + this.inventory.sendContents(this); + break; + } - return; - default: - break; + Food food = Food.getByRelative(itemInHand); + if (food != null && food.eatenBy(this)) --itemInHand.count; + this.inventory.setItemInHand(itemInHand); + } + return; + default: + break; + } + } finally { + this.setUsingItem(false); } break; default: diff --git a/src/main/java/cn/nukkit/block/BlockGlowstone.java b/src/main/java/cn/nukkit/block/BlockGlowstone.java index b0b623553f..b19c80069a 100644 --- a/src/main/java/cn/nukkit/block/BlockGlowstone.java +++ b/src/main/java/cn/nukkit/block/BlockGlowstone.java @@ -2,8 +2,12 @@ import cn.nukkit.item.Item; import cn.nukkit.item.ItemGlowstoneDust; +import cn.nukkit.item.enchantment.Enchantment; +import cn.nukkit.math.MathHelper; import cn.nukkit.utils.BlockColor; +import java.util.Random; + /** * Created on 2015/12/6 by xtypr. * Package cn.nukkit.block in project Nukkit . @@ -44,8 +48,16 @@ public int getLightLevel() { @Override public Item[] getDrops(Item item) { + Random random = new Random(); + int count = 2 + random.nextInt(3); + + Enchantment fortune = item.getEnchantment(Enchantment.ID_FORTUNE_DIGGING); + if (fortune != null && fortune.getLevel() >= 1) { + count += random.nextInt(fortune.getLevel() + 1); + } + return new Item[]{ - new ItemGlowstoneDust(0, ((int) (2d * Math.random()) + 2)) + new ItemGlowstoneDust(0, MathHelper.clamp(count, 1, 4)) }; } diff --git a/src/main/java/cn/nukkit/block/BlockMelon.java b/src/main/java/cn/nukkit/block/BlockMelon.java index 0f8e41c513..8b227cdb9f 100644 --- a/src/main/java/cn/nukkit/block/BlockMelon.java +++ b/src/main/java/cn/nukkit/block/BlockMelon.java @@ -3,6 +3,7 @@ import cn.nukkit.item.Item; import cn.nukkit.item.ItemMelon; import cn.nukkit.item.ItemTool; +import cn.nukkit.item.enchantment.Enchantment; import cn.nukkit.utils.BlockColor; import java.util.Random; @@ -42,8 +43,16 @@ public double getResistance() { @Override public Item[] getDrops(Item item) { + Random random = new Random(); + int count = 3 + random.nextInt(5); + + Enchantment fortune = item.getEnchantment(Enchantment.ID_FORTUNE_DIGGING); + if (fortune != null && fortune.getLevel() >= 1) { + count += random.nextInt(fortune.getLevel() + 1); + } + return new Item[]{ - new ItemMelon(0, new Random().nextInt(4) + 3) + new ItemMelon(0, Math.min(9, count)) }; } diff --git a/src/main/java/cn/nukkit/block/BlockOreCoal.java b/src/main/java/cn/nukkit/block/BlockOreCoal.java index c03f69ba62..56012c2d25 100644 --- a/src/main/java/cn/nukkit/block/BlockOreCoal.java +++ b/src/main/java/cn/nukkit/block/BlockOreCoal.java @@ -3,8 +3,11 @@ import cn.nukkit.item.Item; import cn.nukkit.item.ItemCoal; import cn.nukkit.item.ItemTool; +import cn.nukkit.item.enchantment.Enchantment; import cn.nukkit.math.NukkitRandom; +import java.util.concurrent.ThreadLocalRandom; + /** * author: MagicDroidX * Nukkit Project @@ -47,8 +50,20 @@ public String getName() { @Override public Item[] getDrops(Item item) { if (item.isPickaxe() && item.getTier() >= ItemTool.TIER_WOODEN) { + int count = 1; + Enchantment fortune = item.getEnchantment(Enchantment.ID_FORTUNE_DIGGING); + if (fortune != null && fortune.getLevel() >= 1) { + int i = ThreadLocalRandom.current().nextInt(fortune.getLevel() + 2) - 1; + + if (i < 0) { + i = 0; + } + + count = i + 1; + } + return new Item[]{ - new ItemCoal() + new ItemCoal(0, count) }; } else { return new Item[0]; diff --git a/src/main/java/cn/nukkit/block/BlockOreDiamond.java b/src/main/java/cn/nukkit/block/BlockOreDiamond.java index ec06031fef..31dcaf22b4 100644 --- a/src/main/java/cn/nukkit/block/BlockOreDiamond.java +++ b/src/main/java/cn/nukkit/block/BlockOreDiamond.java @@ -3,8 +3,11 @@ import cn.nukkit.item.Item; import cn.nukkit.item.ItemDiamond; import cn.nukkit.item.ItemTool; +import cn.nukkit.item.enchantment.Enchantment; import cn.nukkit.math.NukkitRandom; +import java.util.concurrent.ThreadLocalRandom; + /** * author: MagicDroidX * Nukkit Project @@ -48,8 +51,20 @@ public String getName() { @Override public Item[] getDrops(Item item) { if (item.isPickaxe() && item.getTier() >= ItemTool.TIER_IRON) { + int count = 1; + Enchantment fortune = item.getEnchantment(Enchantment.ID_FORTUNE_DIGGING); + if (fortune != null && fortune.getLevel() >= 1) { + int i = ThreadLocalRandom.current().nextInt(fortune.getLevel() + 2) - 1; + + if (i < 0) { + i = 0; + } + + count = i + 1; + } + return new Item[]{ - new ItemDiamond() + new ItemDiamond(0, count) }; } else { return new Item[0]; diff --git a/src/main/java/cn/nukkit/block/BlockOreEmerald.java b/src/main/java/cn/nukkit/block/BlockOreEmerald.java index c0afbd0d9e..1e81d7d144 100644 --- a/src/main/java/cn/nukkit/block/BlockOreEmerald.java +++ b/src/main/java/cn/nukkit/block/BlockOreEmerald.java @@ -3,8 +3,11 @@ import cn.nukkit.item.Item; import cn.nukkit.item.ItemEmerald; import cn.nukkit.item.ItemTool; +import cn.nukkit.item.enchantment.Enchantment; import cn.nukkit.math.NukkitRandom; +import java.util.concurrent.ThreadLocalRandom; + /** * Created on 2015/12/1 by xtypr. * Package cn.nukkit.block in project Nukkit . @@ -47,8 +50,20 @@ public double getResistance() { @Override public Item[] getDrops(Item item) { if (item.isPickaxe() && item.getTier() >= ItemTool.TIER_IRON) { + int count = 1; + Enchantment fortune = item.getEnchantment(Enchantment.ID_FORTUNE_DIGGING); + if (fortune != null && fortune.getLevel() >= 1) { + int i = ThreadLocalRandom.current().nextInt(fortune.getLevel() + 2) - 1; + + if (i < 0) { + i = 0; + } + + count = i + 1; + } + return new Item[]{ - new ItemEmerald() + new ItemEmerald(0, count) }; } else { return new Item[0]; diff --git a/src/main/java/cn/nukkit/block/BlockOreGold.java b/src/main/java/cn/nukkit/block/BlockOreGold.java index e46c15d5ea..c3d1d47a8a 100644 --- a/src/main/java/cn/nukkit/block/BlockOreGold.java +++ b/src/main/java/cn/nukkit/block/BlockOreGold.java @@ -46,7 +46,7 @@ public String getName() { public Item[] getDrops(Item item) { if (item.isPickaxe() && item.getTier() >= ItemTool.TIER_IRON) { return new Item[]{ - toItem() + Item.get(GOLD_ORE) }; } else { return new Item[0]; diff --git a/src/main/java/cn/nukkit/block/BlockOreIron.java b/src/main/java/cn/nukkit/block/BlockOreIron.java index 057c632e51..87e62af814 100644 --- a/src/main/java/cn/nukkit/block/BlockOreIron.java +++ b/src/main/java/cn/nukkit/block/BlockOreIron.java @@ -47,7 +47,7 @@ public String getName() { public Item[] getDrops(Item item) { if (item.isPickaxe() && item.getTier() >= ItemTool.TIER_STONE) { return new Item[]{ - toItem() + Item.get(IRON_ORE) }; } else { return new Item[0]; diff --git a/src/main/java/cn/nukkit/block/BlockOreLapis.java b/src/main/java/cn/nukkit/block/BlockOreLapis.java index 6fc943a0de..23b6957d47 100644 --- a/src/main/java/cn/nukkit/block/BlockOreLapis.java +++ b/src/main/java/cn/nukkit/block/BlockOreLapis.java @@ -3,9 +3,11 @@ import cn.nukkit.item.Item; import cn.nukkit.item.ItemDye; import cn.nukkit.item.ItemTool; +import cn.nukkit.item.enchantment.Enchantment; import cn.nukkit.math.NukkitRandom; import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; /** * author: MagicDroidX @@ -50,6 +52,18 @@ public String getName() { @Override public Item[] getDrops(Item item) { if (item.isPickaxe() && item.getTier() >= ItemTool.TIER_STONE) { + int count = 4 + ThreadLocalRandom.current().nextInt(5); + Enchantment fortune = item.getEnchantment(Enchantment.ID_FORTUNE_DIGGING); + if (fortune != null && fortune.getLevel() >= 1) { + int i = ThreadLocalRandom.current().nextInt(fortune.getLevel() + 2) - 1; + + if (i < 0) { + i = 0; + } + + count *= (i + 1); + } + return new Item[]{ new ItemDye(4, new Random().nextInt(4) + 4) }; diff --git a/src/main/java/cn/nukkit/block/BlockOreQuartz.java b/src/main/java/cn/nukkit/block/BlockOreQuartz.java index 2fede06996..135eab5fa1 100644 --- a/src/main/java/cn/nukkit/block/BlockOreQuartz.java +++ b/src/main/java/cn/nukkit/block/BlockOreQuartz.java @@ -3,8 +3,11 @@ import cn.nukkit.item.Item; import cn.nukkit.item.ItemQuartz; import cn.nukkit.item.ItemTool; +import cn.nukkit.item.enchantment.Enchantment; import cn.nukkit.math.NukkitRandom; +import java.util.concurrent.ThreadLocalRandom; + /** * Created on 2015/12/26 by xtypr. * Package cn.nukkit.block in project Nukkit . @@ -47,8 +50,20 @@ public int getToolType() { @Override public Item[] getDrops(Item item) { if (item.isPickaxe() && item.getTier() >= ItemTool.TIER_WOODEN) { + int count = 1; + Enchantment fortune = item.getEnchantment(Enchantment.ID_FORTUNE_DIGGING); + if (fortune != null && fortune.getLevel() >= 1) { + int i = ThreadLocalRandom.current().nextInt(fortune.getLevel() + 2) - 1; + + if (i < 0) { + i = 0; + } + + count = i + 1; + } + return new Item[]{ - new ItemQuartz() + new ItemQuartz(0, count) }; } else { return new Item[0]; diff --git a/src/main/java/cn/nukkit/block/BlockOreRedstone.java b/src/main/java/cn/nukkit/block/BlockOreRedstone.java index 0c3cd1cbe7..0357dfd6dd 100644 --- a/src/main/java/cn/nukkit/block/BlockOreRedstone.java +++ b/src/main/java/cn/nukkit/block/BlockOreRedstone.java @@ -3,6 +3,7 @@ import cn.nukkit.item.Item; import cn.nukkit.item.ItemRedstone; import cn.nukkit.item.ItemTool; +import cn.nukkit.item.enchantment.Enchantment; import cn.nukkit.level.Level; import cn.nukkit.math.NukkitRandom; @@ -50,8 +51,15 @@ public String getName() { @Override public Item[] getDrops(Item item) { if (item.isPickaxe() && item.getTier() >= ItemTool.TIER_IRON) { + int count = new Random().nextInt(2) + 4; + + Enchantment fortune = item.getEnchantment(Enchantment.ID_FORTUNE_DIGGING); + if (fortune != null && fortune.getLevel() >= 1) { + count += new Random().nextInt(fortune.getLevel() + 1); + } + return new Item[]{ - new ItemRedstone(0, new Random().nextInt(1) + 4) + new ItemRedstone(0, count) }; } else { return new Item[0]; diff --git a/src/main/java/cn/nukkit/item/ProjectileItem.java b/src/main/java/cn/nukkit/item/ProjectileItem.java index 2af398a52a..0ae17e87a0 100644 --- a/src/main/java/cn/nukkit/item/ProjectileItem.java +++ b/src/main/java/cn/nukkit/item/ProjectileItem.java @@ -65,6 +65,6 @@ public boolean onClickAir(Player player, Vector3 directionVector) { } protected void correctNBT(CompoundTag nbt) { - + } } From cc7a520a553131456ce0a409f9dfe7d5c3d29492 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Tue, 26 Sep 2017 19:36:01 +0200 Subject: [PATCH 103/175] Fixed sounds, signs, block picking --- src/main/java/cn/nukkit/Player.java | 30 +- src/main/java/cn/nukkit/block/Block.java | 7 + src/main/java/cn/nukkit/block/BlockBone.java | 53 ++++ .../cn/nukkit/block/BlockTripWireHook.java | 8 +- .../nukkit/blockentity/BlockEntitySign.java | 101 ++++--- .../blockentity/BlockEntitySpawnable.java | 10 + .../entity/weather/EntityLightning.java | 4 +- .../cn/nukkit/inventory/ChestInventory.java | 4 +- .../inventory/DoubleChestInventory.java | 5 + src/main/java/cn/nukkit/item/Item.java | 5 + src/main/java/cn/nukkit/level/Level.java | 21 +- .../level/sound/LevelSoundEventSound.java | 8 +- .../protocol/BlockPickRequestPacket.java | 2 +- .../protocol/LevelSoundEventPacket.java | 269 +++++++++++------- .../java/cn/nukkit/utils/BinaryStream.java | 10 + 15 files changed, 333 insertions(+), 204 deletions(-) create mode 100644 src/main/java/cn/nukkit/block/BlockBone.java diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 2556dbf2ab..9967503d6f 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -4,7 +4,6 @@ import cn.nukkit.block.*; 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; @@ -15,7 +14,6 @@ import cn.nukkit.entity.mob.EntityCreeper; import cn.nukkit.entity.projectile.EntityArrow; import cn.nukkit.event.block.ItemFrameDropItemEvent; -import cn.nukkit.event.block.SignChangeEvent; import cn.nukkit.event.entity.EntityDamageByBlockEvent; import cn.nukkit.event.entity.EntityDamageByEntityEvent; import cn.nukkit.event.entity.EntityDamageEvent; @@ -79,8 +77,8 @@ import java.nio.ByteOrder; import java.util.*; import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicReference; /** * author: MagicDroidX & Box @@ -3009,7 +3007,7 @@ public void handleDataPacket(DataPacket packet) { } BlockEntity t = this.level.getBlockEntity(pos); - if (t instanceof BlockEntitySign) { + if (t instanceof BlockEntitySpawnable) { CompoundTag nbt; try { nbt = NBTIO.read(blockEntityDataPacket.namedTag, ByteOrder.LITTLE_ENDIAN, true); @@ -3017,28 +3015,8 @@ public void handleDataPacket(DataPacket packet) { throw new RuntimeException(e); } - if (!BlockEntity.SIGN.equals(nbt.getString("id"))) { - ((BlockEntitySign) t).spawnTo(this); - } else { - SignChangeEvent signChangeEvent = new SignChangeEvent(t.getBlock(), this, new String[]{ - this.removeFormat ? TextFormat.clean(nbt.getString("Text1")) : nbt.getString("Text1"), - this.removeFormat ? TextFormat.clean(nbt.getString("Text2")) : nbt.getString("Text2"), - this.removeFormat ? TextFormat.clean(nbt.getString("Text3")) : nbt.getString("Text3"), - this.removeFormat ? TextFormat.clean(nbt.getString("Text4")) : nbt.getString("Text4") - }); - - if (!t.namedTag.contains("Creator") || !Objects.equals(this.getUniqueId().toString(), t.namedTag.getString("Creator"))) { - signChangeEvent.setCancelled(); - } - - this.server.getPluginManager().callEvent(signChangeEvent); - - if (!signChangeEvent.isCancelled()) { - ((BlockEntitySign) t).setText(signChangeEvent.getLine(0), signChangeEvent.getLine(1), signChangeEvent.getLine(2), signChangeEvent.getLine(3)); - } else { - ((BlockEntitySign) t).spawnTo(this); - } - + if (!((BlockEntitySpawnable) t).updateCompoundTag(nbt, this)) { + ((BlockEntitySpawnable) t).spawnTo(this); } } break; diff --git a/src/main/java/cn/nukkit/block/Block.java b/src/main/java/cn/nukkit/block/Block.java index d81954935f..de6230759d 100644 --- a/src/main/java/cn/nukkit/block/Block.java +++ b/src/main/java/cn/nukkit/block/Block.java @@ -295,6 +295,11 @@ public abstract class Block extends Position implements Metadatable, Cloneable { public static final int END_ROD = 208; public static final int END_GATEWAY = 209; + public static final int MAGMA = 213; + public static final int BLOCK_NETHER_WART_BLOCK = 214; + public static final int RED_NETHER_BRICK = 215; + public static final int BONE_BLOCK = 216; + public static final int SHULKER_BOX = 218; public static final int PURPLE_GLAZED_TERRACOTTA = 219; public static final int WHITE_GLAZED_TERRACOTTA = 220; @@ -558,6 +563,8 @@ public static void init() { list[END_ROD] = BlockEndRod.class; //208 list[END_GATEWAY] = BlockEndGateway.class; //209 + list[BONE_BLOCK] = BlockBone.class; //216 + //TODO: list[SHULKER_BOX] = BlockShulkerBox.class; //218 list[PURPLE_GLAZED_TERRACOTTA] = BlockTerracottaGlazedPurple.class; //219 list[WHITE_GLAZED_TERRACOTTA] = BlockTerracottaGlazedWhite.class; //220 diff --git a/src/main/java/cn/nukkit/block/BlockBone.java b/src/main/java/cn/nukkit/block/BlockBone.java new file mode 100644 index 0000000000..4e28539b40 --- /dev/null +++ b/src/main/java/cn/nukkit/block/BlockBone.java @@ -0,0 +1,53 @@ +package cn.nukkit.block; + +import cn.nukkit.item.Item; +import cn.nukkit.item.ItemBlock; +import cn.nukkit.item.ItemTool; + +/** + * @author CreeperFace + */ +public class BlockBone extends BlockSolid { + + public BlockBone() { + this(0); + } + + public BlockBone(int meta) { + super(meta); + } + + @Override + public int getId() { + return BONE_BLOCK; + } + + @Override + public String getName() { + return "Bone Block"; + } + + @Override + public double getHardness() { + return 2; + } + + @Override + public double getResistance() { + return 10; + } + + @Override + public int getToolType() { + return ItemTool.TYPE_PICKAXE; + } + + @Override + public Item[] getDrops(Item item) { + if (item.isPickaxe() && item.getTier() >= ItemTool.TIER_WOODEN) { + return new Item[]{new ItemBlock(this)}; + } + + return new Item[0]; + } +} diff --git a/src/main/java/cn/nukkit/block/BlockTripWireHook.java b/src/main/java/cn/nukkit/block/BlockTripWireHook.java index aed58677d2..1ed0edc6bc 100644 --- a/src/main/java/cn/nukkit/block/BlockTripWireHook.java +++ b/src/main/java/cn/nukkit/block/BlockTripWireHook.java @@ -177,15 +177,15 @@ public void calculateState(boolean onBreak, boolean updateAround, int pos, Block 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.addLevelSoundEvent(LevelSoundEventPacket.SOUND_POWER_ON, 1, -1, pos); 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.addLevelSoundEvent(LevelSoundEventPacket.SOUND_POWER_OFF, 1, -1, pos); 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); + this.level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_ATTACH, 1, -1, pos); } else if (!canConnect && attached) { - this.level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_DETACH, 1, -1, pos, false, false); + this.level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_DETACH, 1, -1, pos); } } diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntitySign.java b/src/main/java/cn/nukkit/blockentity/BlockEntitySign.java index 23f73a1991..2a3e212fd5 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntitySign.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntitySign.java @@ -1,8 +1,15 @@ package cn.nukkit.blockentity; +import cn.nukkit.Player; import cn.nukkit.block.Block; +import cn.nukkit.event.block.SignChangeEvent; import cn.nukkit.level.format.FullChunk; import cn.nukkit.nbt.tag.CompoundTag; +import cn.nukkit.utils.TextFormat; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; /** * author: MagicDroidX @@ -12,19 +19,24 @@ public class BlockEntitySign extends BlockEntitySpawnable { public BlockEntitySign(FullChunk chunk, CompoundTag nbt) { super(chunk, nbt); - if (!nbt.contains("Text1")) { - nbt.putString("Text1", ""); - } - if (!nbt.contains("Text2")) { - nbt.putString("Text2", ""); - } - if (!nbt.contains("Text3")) { - nbt.putString("Text3", ""); - } - if (!nbt.contains("Text4")) { - nbt.putString("Text4", ""); + + if (!nbt.contains("Text")) { + List lines = new ArrayList<>(); + + for (int i = 1; i <= 4; i++) { + String key = "Text" + i; + + if (nbt.contains(key)) { + String line = nbt.getString(key); + + lines.add(line); + + nbt.remove(key); + } + } + + nbt.putString("Text", String.join("\n", lines)); } - this.namedTag = nbt; } @Override @@ -39,27 +51,8 @@ public boolean isBlockEntityValid() { return blockID == Block.SIGN_POST || blockID == Block.WALL_SIGN; } - public boolean setText() { - return this.setText(""); - } - - public boolean setText(String line1) { - return this.setText(line1, ""); - } - - public boolean setText(String line1, String line2) { - return this.setText(line1, line2, ""); - } - - public boolean setText(String line1, String line2, String line3) { - return this.setText(line1, line2, line3, ""); - } - - public boolean setText(String line1, String line2, String line3, String line4) { - this.namedTag.putString("Text1", line1); - this.namedTag.putString("Text2", line2); - this.namedTag.putString("Text3", line3); - this.namedTag.putString("Text4", line4); + public boolean setText(String... lines) { + this.namedTag.putString("Text", String.join("\n", lines)); this.spawnToAll(); if (this.chunk != null) { @@ -71,26 +64,46 @@ public boolean setText(String line1, String line2, String line3, String line4) { } public String[] getText() { - return new String[]{ - this.namedTag.getString("Text1"), - this.namedTag.getString("Text2"), - this.namedTag.getString("Text3"), - this.namedTag.getString("Text4") - }; + return this.namedTag.getString("Text").split("\n"); + } + + @Override + public boolean updateCompoundTag(CompoundTag nbt, Player player) { + if (!nbt.getString("id").equals(BlockEntity.SIGN)) { + return false; + } + String[] text = nbt.getString("Text").split("\n", 4); + + SignChangeEvent signChangeEvent = new SignChangeEvent(this.getBlock(), player, text); + + if (!this.namedTag.contains("Creator") || !Objects.equals(player.getUniqueId().toString(), this.namedTag.getString("Creator"))) { + signChangeEvent.setCancelled(); + } + + if (player.getRemoveFormat()) { + for (int i = 0; i < text.length; i++) { + text[i] = TextFormat.clean(text[i]); + } + } + + this.server.getPluginManager().callEvent(signChangeEvent); + + if (!signChangeEvent.isCancelled()) { + this.setText(signChangeEvent.getLines()); + return true; + } + + return false; } @Override public CompoundTag getSpawnCompound() { return new CompoundTag() .putString("id", BlockEntity.SIGN) - .putString("Text1", this.namedTag.getString("Text1")) - .putString("Text2", this.namedTag.getString("Text2")) - .putString("Text3", this.namedTag.getString("Text3")) - .putString("Text4", this.namedTag.getString("Text4")) + .putString("Text", this.namedTag.getString("Text")) .putInt("x", (int) this.x) .putInt("y", (int) this.y) .putInt("z", (int) this.z); } - } diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntitySpawnable.java b/src/main/java/cn/nukkit/blockentity/BlockEntitySpawnable.java index 5371b9655d..1f9b7ee3ad 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntitySpawnable.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntitySpawnable.java @@ -50,4 +50,14 @@ public void spawnToAll() { } } } + + /** + * Called when a player updates a block entity's NBT data + * for example when writing on a sign. + * + * @return bool indication of success, will respawn the tile to the player if false. + */ + public boolean updateCompoundTag(CompoundTag nbt, Player player) { + return false; + } } diff --git a/src/main/java/cn/nukkit/entity/weather/EntityLightning.java b/src/main/java/cn/nukkit/entity/weather/EntityLightning.java index 1883f807f3..30fba34e45 100644 --- a/src/main/java/cn/nukkit/entity/weather/EntityLightning.java +++ b/src/main/java/cn/nukkit/entity/weather/EntityLightning.java @@ -119,8 +119,8 @@ public boolean onUpdate(int currentTick) { this.entityBaseTick(tickDiff); 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.level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_THUNDER, 93, -1, this); + this.level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_EXPLODE, 93, -1, this); } this.state--; diff --git a/src/main/java/cn/nukkit/inventory/ChestInventory.java b/src/main/java/cn/nukkit/inventory/ChestInventory.java index b9941dde57..0faf34ba36 100644 --- a/src/main/java/cn/nukkit/inventory/ChestInventory.java +++ b/src/main/java/cn/nukkit/inventory/ChestInventory.java @@ -34,8 +34,8 @@ 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.addLevelSoundEvent(LevelSoundEventPacket.SOUND_CHEST_OPEN, 1, -1, this.getHolder().add(0.5, 0.5, 0.5)); level.addChunkPacket((int) this.getHolder().getX() >> 4, (int) this.getHolder().getZ() >> 4, pk); } } @@ -52,8 +52,8 @@ 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.addLevelSoundEvent(LevelSoundEventPacket.SOUND_CHEST_CLOSED, 1, -1, this.getHolder().add(0.5, 0.5, 0.5)); level.addChunkPacket((int) this.getHolder().getX() >> 4, (int) this.getHolder().getZ() >> 4, pk); } } diff --git a/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java b/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java index a2337ead25..3776ebdedf 100644 --- a/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java +++ b/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java @@ -5,6 +5,7 @@ import cn.nukkit.item.Item; import cn.nukkit.level.Level; import cn.nukkit.network.protocol.BlockEventPacket; +import cn.nukkit.network.protocol.LevelSoundEventPacket; import java.util.HashMap; import java.util.Map; @@ -115,6 +116,7 @@ public void onOpen(Player who) { pk1.case2 = 2; Level level = this.left.getHolder().getLevel(); if (level != null) { + level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_CHEST_OPEN, 1, -1, this.left.getHolder().add(0.5, 0.5, 0.5)); level.addChunkPacket((int) this.left.getHolder().getX() >> 4, (int) this.left.getHolder().getZ() >> 4, pk1); } @@ -127,6 +129,7 @@ public void onOpen(Player who) { level = this.right.getHolder().getLevel(); if (level != null) { + level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_CHEST_OPEN, 1, -1, this.right.getHolder().add(0.5, 0.5, 0.5)); level.addChunkPacket((int) this.right.getHolder().getX() >> 4, (int) this.right.getHolder().getZ() >> 4, pk2); } } @@ -144,6 +147,7 @@ public void onClose(Player who) { Level level = this.right.getHolder().getLevel(); if (level != null) { + level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_CHEST_CLOSED, 1, -1, this.right.getHolder().add(0.5, 0.5, 0.5)); level.addChunkPacket((int) this.right.getHolder().getX() >> 4, (int) this.right.getHolder().getZ() >> 4, pk1); } @@ -156,6 +160,7 @@ public void onClose(Player who) { level = this.left.getHolder().getLevel(); if (level != null) { + level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_CHEST_CLOSED, 1, -1, this.left.getHolder().add(0.5, 0.5, 0.5)); level.addChunkPacket((int) this.left.getHolder().getX() >> 4, (int) this.left.getHolder().getZ() >> 4, pk2); } } diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java index 1b41e5a34d..54b4dcd423 100644 --- a/src/main/java/cn/nukkit/item/Item.java +++ b/src/main/java/cn/nukkit/item/Item.java @@ -312,6 +312,11 @@ private byte[] writeCompoundTag(CompoundTag tag) { public static final int END_ROD = 208; public static final int END_GATEWAY = 209; + public static final int MAGMA = 213; + public static final int BLOCK_NETHER_WART_BLOCK = 214; + public static final int RED_NETHER_BRICK = 215; + public static final int BONE_BLOCK = 216; + public static final int SHULKER_BOX = 218; public static final int PURPLE_GLAZED_TERRACOTTA = 219; public static final int WHITE_GLAZED_TERRACOTTA = 220; diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java index f64649681e..19ac2d6885 100644 --- a/src/main/java/cn/nukkit/level/Level.java +++ b/src/main/java/cn/nukkit/level/Level.java @@ -489,11 +489,11 @@ 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(int type, int pitch, int data, Vector3 pos) { + this.addLevelSoundEvent(type, pitch, data, pos, false); } - public void addLevelSoundEvent(byte type, int pitch, int data, Vector3 pos, Collection players, boolean unknown, boolean disableRelativeVolume) { + public void addLevelSoundEvent(int type, int pitch, int data, Vector3 pos, boolean isGlobal) { LevelSoundEventPacket pk = new LevelSoundEventPacket(); pk.sound = type; pk.pitch = pitch; @@ -501,14 +501,9 @@ 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.isBabyMob = unknown; - pk.isGlobal = disableRelativeVolume; + pk.isGlobal = isGlobal; - if (players == null) { - this.addChunkPacket(pos.getFloorX(), pos.getFloorZ(), pk); - } else { - Server.broadcastPacket(players, pk); - } + this.addChunkPacket(pos.getFloorX() >> 4, pos.getFloorZ() >> 4, pk); } public void addParticle(Particle particle) { @@ -758,8 +753,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); + this.addLevelSoundEvent(LevelSoundEventPacket.SOUND_THUNDER, 93, -1, vector, false); + this.addLevelSoundEvent(LevelSoundEventPacket.SOUND_EXPLODE, 93, -1, vector, false); } } @@ -2090,7 +2085,7 @@ public Item useItemOn(Vector3 vector, Item item, BlockFace face, float fx, float } if (playSound) { - this.addSound(new BlockPlaceSound(hand, hand.getId())); + this.addLevelSoundEvent(LevelSoundEventPacket.SOUND_PLACE, 1, item.getId(), hand, false); } if (item.getCount() <= 0) { diff --git a/src/main/java/cn/nukkit/level/sound/LevelSoundEventSound.java b/src/main/java/cn/nukkit/level/sound/LevelSoundEventSound.java index 8d89a8c3b5..380c32b517 100644 --- a/src/main/java/cn/nukkit/level/sound/LevelSoundEventSound.java +++ b/src/main/java/cn/nukkit/level/sound/LevelSoundEventSound.java @@ -8,19 +8,19 @@ * @author Tee7even */ public class LevelSoundEventSound extends Sound { - protected final byte type; + protected final int type; protected int extraData; protected int pitch; - public LevelSoundEventSound(Vector3 pos, byte type) { + public LevelSoundEventSound(Vector3 pos, int type) { this(pos, type, -1, -1); } - public LevelSoundEventSound(Vector3 pos, byte type, int extraData) { + public LevelSoundEventSound(Vector3 pos, int type, int extraData) { this(pos, type, extraData, -1); } - public LevelSoundEventSound(Vector3 pos, byte type, int extraData, int pitch) { + public LevelSoundEventSound(Vector3 pos, int type, int extraData, int pitch) { super(pos.x, pos.y, pos.z); this.type = type; this.extraData = extraData; diff --git a/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java b/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java index d0da9beaf5..a2cbc823f1 100644 --- a/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/BlockPickRequestPacket.java @@ -19,7 +19,7 @@ public byte pid() { @Override public void decode() { - BlockVector3 v = this.getBlockVector3(); + BlockVector3 v = this.getSignedBlockPosition(); this.x = v.x; this.y = v.y; this.z = v.z; diff --git a/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java b/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java index e4b3fbe2fd..9952f18e46 100644 --- a/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/LevelSoundEventPacket.java @@ -6,114 +6,167 @@ public class LevelSoundEventPacket extends DataPacket { public static final byte NETWORK_ID = ProtocolInfo.LEVEL_SOUND_EVENT_PACKET; - public static final byte SOUND_ITEM_USE_ON = 0; - public static final byte SOUND_HIT = 1; - public static final byte SOUND_STEP = 2; - public static final byte SOUND_JUMP = 3; - public static final byte SOUND_BREAK = 4; - public static final byte SOUND_PLACE = 5; - public static final byte SOUND_HEAVY_STEP = 6; - public static final byte SOUND_GALLOP = 7; - public static final byte SOUND_FALL = 8; - public static final byte SOUND_AMBIENT = 9; - public static final byte SOUND_AMBIENT_BABY = 10; - public static final byte SOUND_AMBIENT_IN_WATER = 11; - public static final byte SOUND_BREATHE = 12; - public static final byte SOUND_DEATH = 13; - public static final byte SOUND_DEATH_IN_WATER = 14; - public static final byte SOUND_DEATH_TO_ZOMBIE = 15; - public static final byte SOUND_HURT = 16; - public static final byte SOUND_HURT_IN_WATER = 17; - public static final byte SOUND_MAD = 18; - public static final byte SOUND_BOOST = 19; - public static final byte SOUND_BOW = 20; - public static final byte SOUND_SQUISH_BIG = 21; - public static final byte SOUND_SQUISH_SMALL = 22; - public static final byte SOUND_FALL_BIG = 23; - public static final byte SOUND_FALL_SMALL = 24; - public static final byte SOUND_SPLASH = 25; - public static final byte SOUND_FIZZ = 26; - public static final byte SOUND_FLAP = 27; - public static final byte SOUND_SWIM = 28; - public static final byte SOUND_DRINK = 29; - public static final byte SOUND_EAT = 30; - public static final byte SOUND_TAKEOFF = 31; - public static final byte SOUND_SHAKE = 32; - public static final byte SOUND_PLOP = 33; - public static final byte SOUND_LAND = 34; - public static final byte SOUND_SADDLE = 35; - public static final byte SOUND_ARMOR = 36; - public static final byte SOUND_ADD_CHEST = 37; - public static final byte SOUND_THROW = 38; - public static final byte SOUND_ATTACK = 39; - public static final byte SOUND_ATTACK_NODAMAGE = 40; - public static final byte SOUND_WARN = 41; - public static final byte SOUND_SHEAR = 42; - public static final byte SOUND_MILK = 43; - public static final byte SOUND_THUNDER = 44; - public static final byte SOUND_EXPLODE = 45; - public static final byte SOUND_FIRE = 46; - public static final byte SOUND_IGNITE = 47; - public static final byte SOUND_FUSE = 48; - public static final byte SOUND_STARE = 49; - public static final byte SOUND_SPAWN = 50; - public static final byte SOUND_SHOOT = 51; - public static final byte SOUND_BREAK_BLOCK = 52; - public static final byte SOUND_REMEDY = 53; - public static final byte SOUND_UNFECT = 54; - public static final byte SOUND_LEVELUP = 55; - public static final byte SOUND_BOW_HIT = 56; - public static final byte SOUND_BULLET_HIT = 57; - public static final byte SOUND_EXTINGUISH_FIRE = 58; - public static final byte SOUND_ITEM_FIZZ = 59; - public static final byte SOUND_CHEST_OPEN = 60; - public static final byte SOUND_CHEST_CLOSED = 61; - public static final byte SOUND_SHULKERBOX_OPEN = 62; - public static final byte SOUND_SHULKERBOX_CLOSED = 63; - public static final byte SOUND_POWER_ON = 64; - public static final byte SOUND_POWER_OFF = 65; - public static final byte SOUND_ATTACH = 66; - public static final byte SOUND_DETACH = 67; - public static final byte SOUND_DENY = 68; - public static final byte SOUND_TRIPOD = 69; - public static final byte SOUND_POP = 70; - public static final byte SOUND_DROP_SLOT = 71; - public static final byte SOUND_NOTE = 72; - public static final byte SOUND_THORNS = 73; - public static final byte SOUND_PISTON_IN = 74; - public static final byte SOUND_PISTON_OUT = 75; - public static final byte SOUND_PORTAL = 76; - public static final byte SOUND_WATER = 77; - public static final byte SOUND_LAVA_POP = 78; - public static final byte SOUND_LAVA = 79; - public static final byte SOUND_BURP = 80; - public static final byte SOUND_BUCKET_FILL_WATER = 81; - public static final byte SOUND_BUCKET_FILL_LAVA = 82; - public static final byte SOUND_BUCKET_EMPTY_WATER = 83; - public static final byte SOUND_BUCKET_EMPTY_LAVA = 84; - public static final byte SOUND_GUARDIAN_FLOP = 85; - public static final byte SOUND_ELDERGUARDIAN_CURSE = 86; - public static final byte SOUND_MOB_WARNING = 87; - public static final byte SOUND_MOB_WARNING_BABY = 88; - public static final byte SOUND_TELEPORT = 89; - public static final byte SOUND_SHULKER_OPEN = 90; - public static final byte SOUND_SHULKER_CLOSE = 91; - public static final byte SOUND_HAGGLE = 92; - public static final byte SOUND_HAGGLE_YES = 93; - public static final byte SOUND_HAGGLE_NO = 94; - public static final byte SOUND_HAGGLE_IDLE = 95; - public static final byte SOUND_CHORUSGROW = 96; - public static final byte SOUND_CHORUSDEATH = 97; - public static final byte SOUND_GLASS = 98; - public static final byte SOUND_CAST_SPELL = 99; - public static final byte SOUND_PREPARE_ATTACK = 100; - public static final byte SOUND_PREPARE_SUMMON = 101; - public static final byte SOUND_PREPARE_WOLOLO = 102; - public static final byte SOUND_FANG = 103; - public static final byte SOUND_CHARGE = 104; - public static final byte SOUND_CAMERA_TAKE_PICTURE = 105; - public static final byte SOUND_DEFAULT = 106; - public static final byte SOUND_UNDEFINED = 107; + public static final int SOUND_ITEM_USE_ON = 0; + public static final int SOUND_HIT = 1; + public static final int SOUND_STEP = 2; + public static final int SOUND_FLY = 3; + public static final int SOUND_JUMP = 4; + public static final int SOUND_BREAK = 5; + public static final int SOUND_PLACE = 6; + public static final int SOUND_HEAVY_STEP = 7; + public static final int SOUND_GALLOP = 8; + public static final int SOUND_FALL = 9; + public static final int SOUND_AMBIENT = 10; + public static final int SOUND_AMBIENT_BABY = 11; + public static final int SOUND_AMBIENT_IN_WATER = 12; + public static final int SOUND_BREATHE = 13; + public static final int SOUND_DEATH = 14; + public static final int SOUND_DEATH_IN_WATER = 15; + public static final int SOUND_DEATH_TO_ZOMBIE = 16; + public static final int SOUND_HURT = 17; + public static final int SOUND_HURT_IN_WATER = 18; + public static final int SOUND_MAD = 19; + public static final int SOUND_BOOST = 20; + public static final int SOUND_BOW = 21; + public static final int SOUND_SQUISH_BIG = 22; + public static final int SOUND_SQUISH_SMALL = 23; + public static final int SOUND_FALL_BIG = 24; + public static final int SOUND_FALL_SMALL = 25; + public static final int SOUND_SPLASH = 26; + public static final int SOUND_FIZZ = 27; + public static final int SOUND_FLAP = 28; + public static final int SOUND_SWIM = 29; + public static final int SOUND_DRINK = 30; + public static final int SOUND_EAT = 31; + public static final int SOUND_TAKEOFF = 32; + public static final int SOUND_SHAKE = 33; + public static final int SOUND_PLOP = 34; + public static final int SOUND_LAND = 35; + public static final int SOUND_SADDLE = 36; + public static final int SOUND_ARMOR = 37; + public static final int SOUND_ADD_CHEST = 38; + public static final int SOUND_THROW = 39; + public static final int SOUND_ATTACK = 40; + public static final int SOUND_ATTACK_NODAMAGE = 41; + public static final int SOUND_WARN = 42; + public static final int SOUND_SHEAR = 43; + public static final int SOUND_MILK = 44; + public static final int SOUND_THUNDER = 45; + public static final int SOUND_EXPLODE = 46; + public static final int SOUND_FIRE = 47; + public static final int SOUND_IGNITE = 48; + public static final int SOUND_FUSE = 49; + public static final int SOUND_STARE = 50; + public static final int SOUND_SPAWN = 51; + public static final int SOUND_SHOOT = 52; + public static final int SOUND_BREAK_BLOCK = 53; + public static final int SOUND_LAUNCH = 54; + public static final int SOUND_BLAST = 55; + public static final int SOUND_LARGE_BLAST = 56; + public static final int SOUND_TWINKLE = 57; + public static final int SOUND_REMEDY = 58; + public static final int SOUND_UNFECT = 59; + public static final int SOUND_LEVELUP = 60; + public static final int SOUND_BOW_HIT = 61; + public static final int SOUND_BULLET_HIT = 62; + public static final int SOUND_EXTINGUISH_FIRE = 63; + public static final int SOUND_ITEM_FIZZ = 64; + public static final int SOUND_CHEST_OPEN = 65; + public static final int SOUND_CHEST_CLOSED = 66; + public static final int SOUND_SHULKERBOX_OPEN = 67; + public static final int SOUND_SHULKERBOX_CLOSED = 68; + public static final int SOUND_POWER_ON = 69; + public static final int SOUND_POWER_OFF = 70; + public static final int SOUND_ATTACH = 71; + public static final int SOUND_DETACH = 72; + public static final int SOUND_DENY = 73; + public static final int SOUND_TRIPOD = 74; + public static final int SOUND_POP = 75; + public static final int SOUND_DROP_SLOT = 76; + public static final int SOUND_NOTE = 77; + public static final int SOUND_THORNS = 78; + public static final int SOUND_PISTON_IN = 79; + public static final int SOUND_PISTON_OUT = 80; + public static final int SOUND_PORTAL = 81; + public static final int SOUND_WATER = 82; + public static final int SOUND_LAVA_POP = 83; + public static final int SOUND_LAVA = 84; + public static final int SOUND_BURP = 85; + public static final int SOUND_BUCKET_FILL_WATER = 86; + public static final int SOUND_BUCKET_FILL_LAVA = 87; + public static final int SOUND_BUCKET_EMPTY_WATER = 88; + public static final int SOUND_BUCKET_EMPTY_LAVA = 89; + public static final int SOUND_RECORD_13 = 90; + public static final int SOUND_RECORD_CAT = 91; + public static final int SOUND_RECORD_BLOCKS = 92; + public static final int SOUND_RECORD_CHIRP = 93; + public static final int SOUND_RECORD_FAR = 94; + public static final int SOUND_RECORD_MALL = 95; + public static final int SOUND_RECORD_MELLOHI = 96; + public static final int SOUND_RECORD_STAL = 97; + public static final int SOUND_RECORD_STRAD = 98; + public static final int SOUND_RECORD_WARD = 99; + public static final int SOUND_RECORD_11 = 100; + public static final int SOUND_RECORD_WAIT = 101; + public static final int SOUND_GUARDIAN_FLOP = 103; + public static final int SOUND_ELDERGUARDIAN_CURSE = 104; + public static final int SOUND_MOB_WARNING = 105; + public static final int SOUND_MOB_WARNING_BABY = 106; + public static final int SOUND_TELEPORT = 107; + public static final int SOUND_SHULKER_OPEN = 108; + public static final int SOUND_SHULKER_CLOSE = 109; + public static final int SOUND_HAGGLE = 110; + public static final int SOUND_HAGGLE_YES = 111; + public static final int SOUND_HAGGLE_NO = 112; + public static final int SOUND_HAGGLE_IDLE = 113; + public static final int SOUND_CHORUSGROW = 114; + public static final int SOUND_CHORUSDEATH = 115; + public static final int SOUND_GLASS = 116; + public static final int SOUND_CAST_SPELL = 117; + public static final int SOUND_PREPARE_ATTACK = 118; + public static final int SOUND_PREPARE_SUMMON = 119; + public static final int SOUND_PREPARE_WOLOLO = 120; + public static final int SOUND_FANG = 121; + public static final int SOUND_CHARGE = 122; + public static final int SOUND_CAMERA_TAKE_PICTURE = 123; + public static final int SOUND_LEASHKNOT_PLACE = 124; + public static final int SOUND_LEASHKNOT_BREAK = 125; + public static final int SOUND_GROWL = 126; + public static final int SOUND_WHINE = 127; + public static final int SOUND_PANT = 128; + public static final int SOUND_PURR = 129; + public static final int SOUND_PURREOW = 130; + public static final int SOUND_DEATH_MIN_VOLUME = 131; + public static final int SOUND_DEATH_MID_VOLUME = 132; + public static final int SOUND_IMITATE_BLAZE = 133; + public static final int SOUND_IMITATE_CAVE_SPIDER = 134; + public static final int SOUND_IMITATE_CREEPER = 135; + public static final int SOUND_IMITATE_ELDER_GUARDIAN = 136; + public static final int SOUND_IMITATE_ENDER_DRAGON = 137; + public static final int SOUND_IMITATE_ENDERMAN = 138; + public static final int SOUND_IMITATE_EVOCATION_ILLAGER = 140; + public static final int SOUND_IMITATE_GHAST = 141; + public static final int SOUND_IMITATE_HUSK = 142; + public static final int SOUND_IMITATE_ILLUSION_ILLAGER = 143; + public static final int SOUND_IMITATE_MAGMA_CUBE = 144; + public static final int SOUND_IMITATE_POLAR_BEAR = 145; + public static final int SOUND_IMITATE_SHULKER = 146; + public static final int SOUND_IMITATE_SILVERFISH = 147; + public static final int SOUND_IMITATE_SKELETON = 148; + public static final int SOUND_IMITATE_SLIME = 149; + public static final int SOUND_IMITATE_SPIDER = 150; + public static final int SOUND_IMITATE_STRAY = 151; + public static final int SOUND_IMITATE_VEX = 152; + public static final int SOUND_IMITATE_VINDICATION_ILLAGER = 153; + public static final int SOUND_IMITATE_WITCH = 154; + public static final int SOUND_IMITATE_WITHER = 155; + public static final int SOUND_IMITATE_WITHER_SKELETON = 156; + public static final int SOUND_IMITATE_WOLF = 157; + public static final int SOUND_IMITATE_ZOMBIE = 158; + public static final int SOUND_IMITATE_ZOMBIE_PIGMAN = 159; + public static final int SOUND_IMITATE_ZOMBIE_VILLAGER = 160; + public static final int SOUND_DEFAULT = 161; + public static final int SOUND_UNDEFINED = 162; public int sound; public float x; diff --git a/src/main/java/cn/nukkit/utils/BinaryStream.java b/src/main/java/cn/nukkit/utils/BinaryStream.java index e0f7df845f..170bfee573 100644 --- a/src/main/java/cn/nukkit/utils/BinaryStream.java +++ b/src/main/java/cn/nukkit/utils/BinaryStream.java @@ -369,6 +369,16 @@ public BlockVector3 getBlockVector3() { return new BlockVector3(this.getVarInt(), (int) this.getUnsignedVarInt(), this.getVarInt()); } + public BlockVector3 getSignedBlockPosition() { + return new BlockVector3(getVarInt(), getVarInt(), getVarInt()); + } + + public void putSignedBlockPosition(BlockVector3 v) { + putVarInt(v.x); + putVarInt(v.y); + putVarInt(v.z); + } + public void putBlockVector3(BlockVector3 v) { this.putBlockVector3(v.x, v.y, v.z); } From 46bca0d6ef5d5b2efb8ad401f0a4327865d0e017 Mon Sep 17 00:00:00 2001 From: boybook Date: Wed, 27 Sep 2017 23:31:07 +0800 Subject: [PATCH 104/175] New DummyBossBar API! And it's compatible with the old API. --- src/main/java/cn/nukkit/Player.java | 131 +++++----- .../network/protocol/BossEventPacket.java | 64 +++++ .../java/cn/nukkit/utils/DummyBossBar.java | 234 ++++++++++++++++++ 3 files changed, 355 insertions(+), 74 deletions(-) create mode 100644 src/main/java/cn/nukkit/utils/DummyBossBar.java diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 9967503d6f..f4d7156b57 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -11,7 +11,6 @@ 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.EntityArrow; import cn.nukkit.event.block.ItemFrameDropItemEvent; import cn.nukkit.event.entity.EntityDamageByBlockEvent; @@ -72,12 +71,13 @@ import co.aikar.timings.Timing; import co.aikar.timings.Timings; +import java.awt.*; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteOrder; import java.util.*; +import java.util.List; import java.util.Map.Entry; -import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.atomic.AtomicReference; /** @@ -221,6 +221,8 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde protected Map formWindows = new HashMap<>(); protected Map serverSettings = new HashMap<>(); + protected Map dummyBossBars = new HashMap<>(); + public int getStartActionTick() { return startAction; } @@ -1647,6 +1649,11 @@ public boolean onUpdate(int currentTick) { this.dataPacket(pk); messageQueue.clear(); } + + if (this.spawned && this.dummyBossBars.size() > 0 && currentTick % 100 == 0) { + this.dummyBossBars.values().forEach(DummyBossBar::updateBossEntityPosition); + } + return true; } @@ -4361,6 +4368,8 @@ public boolean teleport(Location location, TeleportCause cause) { this.nextChunkOrderRun = 0; this.newPosition = null; + //DummyBossBar + this.getDummyBossBars().values().forEach(DummyBossBar::reshow); //Weather this.getLevel().sendWeather(this); //Update time @@ -4491,48 +4500,43 @@ public int addServerSettings(FormWindow window) { * @param length The BossBar percentage * @return bossBarId The BossBar ID, you should store it if you want to remove or update the BossBar later */ - + @Deprecated public long createBossBar(String text, int length) { - // First we spawn a entity - long bossBarId = 1095216660480L + ThreadLocalRandom.current().nextLong(0, 0x7fffffffL); - AddEntityPacket pkAdd = new AddEntityPacket(); - pkAdd.type = EntityCreeper.NETWORK_ID; - pkAdd.entityUniqueId = bossBarId; - pkAdd.entityRuntimeId = bossBarId; - pkAdd.x = (float) this.x; - pkAdd.y = (float) -10; // Below the bedrock - pkAdd.z = (float) this.z; - pkAdd.speedX = (float) this.motionX; - pkAdd.speedY = (float) this.motionY; - pkAdd.speedZ = (float) this.motionZ; - EntityMetadata metadata = new EntityMetadata() - // Default Metadata tags - .putLong(DATA_FLAGS, 0) - .putShort(DATA_AIR, 400) - .putShort(DATA_MAX_AIR, 400) - .putLong(DATA_LEAD_HOLDER_EID, -1) - .putFloat(DATA_SCALE, 1f) - .putString(Entity.DATA_NAMETAG, text) // Set the entity name - .putInt(Entity.DATA_SCALE, 0); // And make it invisible - pkAdd.metadata = metadata; - this.dataPacket(pkAdd); - - // Now we send the entity attributes - // TODO: Attributes should be sent on AddEntityPacket, however it doesn't work (client bug?) - UpdateAttributesPacket pkAttributes = new UpdateAttributesPacket(); - pkAttributes.entityId = 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}; - this.dataPacket(pkAttributes); - - // And now we send the bossbar packet - BossEventPacket pkBoss = new BossEventPacket(); - pkBoss.bossEid = bossBarId; - pkBoss.type = BossEventPacket.TYPE_SHOW; - this.dataPacket(pkBoss); - return bossBarId; + DummyBossBar bossBar = new DummyBossBar.Builder(this).text(text).length(length).build(); + return this.createBossBar(bossBar); + } + + /** + * Creates and sends a BossBar to the player + * + * @param dummyBossBar DummyBossBar Object (Instantiate it by the Class Builder) + * @see DummyBossBar.Builder + * @return bossBarId The BossBar ID, you should store it if you want to remove or update the BossBar later + */ + public long createBossBar(DummyBossBar dummyBossBar) { + this.dummyBossBars.put(dummyBossBar.getBossBarId(), dummyBossBar); + dummyBossBar.create(); + return dummyBossBar.getBossBarId(); + } + + /** + * Get a DummyBossBar object + * @param bossBarId The BossBar ID + * @return DummyBossBar object + * @see DummyBossBar#setText(String) Set BossBar text + * @see DummyBossBar#setLength(float) Set BossBar length + * @see DummyBossBar#setColor(Color) Set BossBar color + */ + public DummyBossBar getDummyBossBar(long bossBarId) { + return this.dummyBossBars.getOrDefault(bossBarId, null); + } + + /** + * Get all DummyBossBar objects + * @return DummyBossBars Map + */ + public Map getDummyBossBars() { + return dummyBossBars; } /** @@ -4542,35 +4546,13 @@ public long createBossBar(String text, int length) { * @param length The new BossBar length * @param bossBarId The BossBar ID */ + @Deprecated public void updateBossBar(String text, int length, long bossBarId) { - // First we update the boss bar length - UpdateAttributesPacket pkAttributes = new UpdateAttributesPacket(); - pkAttributes.entityId = 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}; - this.dataPacket(pkAttributes); - // And then the boss bar text - SetEntityDataPacket pkMetadata = new SetEntityDataPacket(); - pkMetadata.eid = bossBarId; - pkMetadata.metadata = new EntityMetadata() - // Default Metadata tags - .putLong(DATA_FLAGS, 0) - .putShort(DATA_AIR, 400) - .putShort(DATA_MAX_AIR, 400) - .putLong(DATA_LEAD_HOLDER_EID, -1) - .putFloat(DATA_SCALE, 1f) - .putString(Entity.DATA_NAMETAG, text) // Set the entity name - .putInt(Entity.DATA_SCALE, 0); // And make it invisible - this.dataPacket(pkMetadata); - - // And now we send the bossbar packet - BossEventPacket pkBoss = new BossEventPacket(); - pkBoss.bossEid = bossBarId; - pkBoss.type = BossEventPacket.TYPE_UPDATE; - this.dataPacket(pkBoss); - return; + if (this.dummyBossBars.containsKey(bossBarId)) { + DummyBossBar bossBar = this.dummyBossBars.get(bossBarId); + bossBar.setText(text); + bossBar.setLength(length); + } } /** @@ -4579,9 +4561,10 @@ public void updateBossBar(String text, int length, long bossBarId) { * @param bossBarId The BossBar ID */ public void removeBossBar(long bossBarId) { - RemoveEntityPacket pkRemove = new RemoveEntityPacket(); - pkRemove.eid = bossBarId; - this.dataPacket(pkRemove); + if (this.dummyBossBars.containsKey(bossBarId)) { + this.dummyBossBars.get(bossBarId).destroy(); + this.dummyBossBars.remove(bossBarId); + } } public int getWindowId(Inventory inventory) { diff --git a/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java b/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java index ef0675f1a3..2e4452776f 100644 --- a/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java @@ -7,12 +7,32 @@ public class BossEventPacket extends DataPacket { public static final byte NETWORK_ID = ProtocolInfo.BOSS_EVENT_PACKET; + /* S2C: Shows the bossbar 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; public static final int TYPE_UPDATE = 1; + /* S2C: Removes the bossbar 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 clientside 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 clientside whatsoever. */ + public static final int TYPE_TEXTURE = 7; 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,6 +41,29 @@ public byte pid() { @Override public void decode() { + this.bossEid = this.getEntityUniqueId(); + this.type = (int) this.getUnsignedVarInt(); + switch (this.type) { + case TYPE_REGISTER_PLAYER: + case TYPE_UNREGISTER_PLAYER: + this.playerEid = this.getEntityUniqueId(); + 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 @@ -28,5 +71,26 @@ public void encode() { this.reset(); this.putEntityUniqueId(this.bossEid); this.putUnsignedVarInt(this.type); + switch (this.type) { + case TYPE_REGISTER_PLAYER: + case TYPE_UNREGISTER_PLAYER: + this.putEntityUniqueId(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/utils/DummyBossBar.java b/src/main/java/cn/nukkit/utils/DummyBossBar.java new file mode 100644 index 0000000000..8f59d91fcb --- /dev/null +++ b/src/main/java/cn/nukkit/utils/DummyBossBar.java @@ -0,0 +1,234 @@ +package cn.nukkit.utils; + +import cn.nukkit.Player; +import cn.nukkit.entity.Attribute; +import cn.nukkit.entity.Entity; +import cn.nukkit.entity.data.EntityMetadata; +import cn.nukkit.entity.mob.EntityCreeper; +import cn.nukkit.network.protocol.*; + +import java.awt.*; +import java.util.concurrent.ThreadLocalRandom; + +/** + * DummyBossBar + * =============== + * author: boybook + * Nukkit Project + * =============== + */ +public class DummyBossBar { + + private final Player player; + private final long bossBarId; + + private String text; + private float length; + private Color color; + + private DummyBossBar(Builder builder) { + this.player = builder.player; + this.bossBarId = builder.bossBarId; + this.text = builder.text; + this.length = builder.length; + this.color = builder.color; + } + + public static class Builder { + private final Player player; + private final long bossBarId; + + private String text = ""; + private float length = 100; + private Color color = null; + + public Builder(Player player) { + this.player = player; + this.bossBarId = 1095216660480L + ThreadLocalRandom.current().nextLong(0, 0x7fffffffL); + } + + public Builder text(String text) { + this.text = text; + return this; + } + + public Builder length(float length) { + if (length >= 0 && length <= 100) this.length = length; + return this; + } + + public Builder color(Color color) { + this.color = color; + return this; + } + + public Builder color(int red, int green, int blue) { + return color(new Color(red, green, blue)); + } + + public DummyBossBar build() { + return new DummyBossBar(this); + } + } + + public Player getPlayer() { + return player; + } + + public long getBossBarId() { + return bossBarId; + } + + public String getText() { + return text; + } + + public void setText(String text) { + if (!this.text.equals(text)) { + this.text = text; + this.updateBossEntityNameTag(); + } + } + + public float getLength() { + return length; + } + + public void setLength(float length) { + if (this.length != length) { + this.length = length; + this.sendAttributes(); + } + } + + /** + * Color is not working in the current version. We are keep waiting for client support. + * @param color the boss bar color + */ + public void setColor(Color color) { + if (this.color == null || !this.color.equals(color)) { + this.color = color; + this.sendSetBossBarTexture(); + } + } + + public void setColor(int red, int green, int blue) { + this.setColor(new Color(red, green, blue)); + } + + public int getMixedColor() { + return this.color.getRGB();//(this.color.getRed() << 16 | this.color.getGreen() << 8 | this.color.getBlue()) & 0xffffff; + } + + public Color getColor() { + return this.color; + } + + private void createBossEntity() { + AddEntityPacket pkAdd = new AddEntityPacket(); + pkAdd.type = EntityCreeper.NETWORK_ID; + pkAdd.entityUniqueId = bossBarId; + pkAdd.entityRuntimeId = bossBarId; + pkAdd.x = (float) player.x; + pkAdd.y = (float) -10; // Below the bedrock + pkAdd.z = (float) player.z; + pkAdd.speedX = 0; + pkAdd.speedY = 0; + pkAdd.speedZ = 0; + pkAdd.metadata = new EntityMetadata() + // Default Metadata tags + .putLong(Entity.DATA_FLAGS, 0) + .putShort(Entity.DATA_AIR, 400) + .putShort(Entity.DATA_MAX_AIR, 400) + .putLong(Entity.DATA_LEAD_HOLDER_EID, -1) + .putFloat(Entity.DATA_SCALE, 1f) + .putString(Entity.DATA_NAMETAG, text) // Set the entity name + .putInt(Entity.DATA_SCALE, 0); // And make it invisible + + player.dataPacket(pkAdd); + } + + private void sendAttributes() { + UpdateAttributesPacket pkAttributes = new UpdateAttributesPacket(); + pkAttributes.entityId = 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}; + player.dataPacket(pkAttributes); + } + + private void sendShowBossBar() { + BossEventPacket pkBoss = new BossEventPacket(); + pkBoss.bossEid = bossBarId; + pkBoss.type = BossEventPacket.TYPE_SHOW; + pkBoss.title = text; + pkBoss.healthPercent = this.length; + player.dataPacket(pkBoss); + } + + private void sendHideBossBar() { + BossEventPacket pkBoss = new BossEventPacket(); + pkBoss.bossEid = bossBarId; + pkBoss.type = BossEventPacket.TYPE_HIDE; + player.dataPacket(pkBoss); + } + + private void sendSetBossBarTexture() { + BossEventPacket pk = new BossEventPacket(); + pk.bossEid = this.bossBarId; + pk.type = BossEventPacket.TYPE_TEXTURE; + pk.color = this.getMixedColor(); + player.dataPacket(pk); + } + + /** + * Don't let the entity go too far from the player, or the BossBar will disappear. + * Update boss entity's position when teleport and each 5s. + */ + public void updateBossEntityPosition() { + MoveEntityPacket pk = new MoveEntityPacket(); + pk.eid = this.bossBarId; + pk.x = this.player.x; + pk.y = -10; + pk.z = this.player.z; + pk.headYaw = 0; + pk.yaw = 0; + pk.pitch = 0; + player.dataPacket(pk); + } + + private void updateBossEntityNameTag() { + SetEntityDataPacket pk = new SetEntityDataPacket(); + pk.eid = this.bossBarId; + pk.metadata = new EntityMetadata().putString(Entity.DATA_NAMETAG, this.text); + player.dataPacket(pk); + } + + private void removeBossEntity() { + RemoveEntityPacket pkRemove = new RemoveEntityPacket(); + pkRemove.eid = bossBarId; + player.dataPacket(pkRemove); + } + + public void create() { + createBossEntity(); + sendAttributes(); + sendShowBossBar(); + if (color != null) this.sendSetBossBarTexture(); + } + + /** + * Once the player has teleported, resend Show BossBar + */ + public void reshow() { + updateBossEntityPosition(); + sendShowBossBar(); + } + + public void destroy() { + sendHideBossBar(); + removeBossEntity(); + } + +} From af4f31167647e714f45fd629daad2ce3403cb9c0 Mon Sep 17 00:00:00 2001 From: boybook Date: Thu, 28 Sep 2017 00:21:35 +0800 Subject: [PATCH 105/175] Oops... --- src/main/java/cn/nukkit/utils/DummyBossBar.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/cn/nukkit/utils/DummyBossBar.java b/src/main/java/cn/nukkit/utils/DummyBossBar.java index 8f59d91fcb..ca434bc6cb 100644 --- a/src/main/java/cn/nukkit/utils/DummyBossBar.java +++ b/src/main/java/cn/nukkit/utils/DummyBossBar.java @@ -141,7 +141,6 @@ private void createBossEntity() { .putShort(Entity.DATA_AIR, 400) .putShort(Entity.DATA_MAX_AIR, 400) .putLong(Entity.DATA_LEAD_HOLDER_EID, -1) - .putFloat(Entity.DATA_SCALE, 1f) .putString(Entity.DATA_NAMETAG, text) // Set the entity name .putInt(Entity.DATA_SCALE, 0); // And make it invisible From 68586dcbf47a44dad82e605f7cc0bd4a66a6f1db Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 28 Sep 2017 09:52:44 +0200 Subject: [PATCH 106/175] fixed items with compound tag, added client side anvil support --- src/main/java/cn/nukkit/Player.java | 14 ++-- src/main/java/cn/nukkit/block/BlockAnvil.java | 2 +- .../cn/nukkit/inventory/AnvilInventory.java | 19 ++++- .../SimpleInventoryTransaction.java | 2 +- src/main/java/cn/nukkit/item/Item.java | 78 +++++++++++-------- .../types/NetworkInventoryAction.java | 31 ++++++++ 6 files changed, 105 insertions(+), 41 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 9967503d6f..23f21f2148 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -108,6 +108,9 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde public static final int PERMISSION_MEMBER = 1; public static final int PERMISSION_VISITOR = 0; + public static final int ANVIL_WINDOW_ID = 2; + public static final int ENCHANT_WINDOW_ID = 3; + protected final SourceInterface interfaz; public boolean playedBefore; @@ -116,7 +119,7 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde public int gamemode; public long lastBreak; - protected int windowCnt = 2; + protected int windowCnt = 4; protected Map windows; @@ -3110,7 +3113,6 @@ public void handleDataPacket(DataPacket packet) { InventoryTransactionPacket transactionPacket = (InventoryTransactionPacket) packet; - List actions = new ArrayList<>(); for (NetworkInventoryAction networkInventoryAction : transactionPacket.actions) { try { @@ -3167,12 +3169,12 @@ public void handleDataPacket(DataPacket packet) { if (this.level.useItemOn(blockVector.asVector3(), i, face, useItemData.clickPos.x, useItemData.clickPos.y, useItemData.clickPos.z, this) != null) { break packetswitch; } - } else if (inventory.getItemInHand().deepEquals(useItemData.itemInHand)) { + } else if (inventory.getItemInHand().equals(useItemData.itemInHand)) { Item i = inventory.getItemInHand(); Item oldItem = i.clone(); //TODO: Implement adventure mode checks if ((i = this.level.useItemOn(blockVector.asVector3(), i, face, useItemData.clickPos.x, useItemData.clickPos.y, useItemData.clickPos.z, this)) != null) { - if (!i.deepEquals(oldItem) || i.getCount() != oldItem.getCount()) { + if (!i.equals(oldItem) || i.getCount() != oldItem.getCount()) { inventory.setItemInHand(i); inventory.sendHeldItem(this.getViewers().values()); } @@ -3222,7 +3224,7 @@ public void handleDataPacket(DataPacket packet) { if (this.canInteract(blockVector.add(0.5, 0.5, 0.5), this.isCreative() ? 13 : 7) && (i = this.level.useBreakOn(blockVector.asVector3(), i, this, true)) != null) { if (this.isSurvival()) { this.getFoodData().updateFoodExpLevel(0.025); - if (!i.deepEquals(oldItem) || i.getCount() != oldItem.getCount()) { + if (!i.equals(oldItem) || i.getCount() != oldItem.getCount()) { inventory.setItemInHand(i); inventory.sendHeldItem(this.getViewers().values()); } @@ -4610,7 +4612,7 @@ public int addWindow(Inventory inventory, Integer forceId, boolean isPermanent) } int cnt; if (forceId == null) { - this.windowCnt = cnt = Math.max(2, ++this.windowCnt % 99); + this.windowCnt = cnt = Math.max(4, ++this.windowCnt % 99); } else { cnt = forceId; } diff --git a/src/main/java/cn/nukkit/block/BlockAnvil.java b/src/main/java/cn/nukkit/block/BlockAnvil.java index a33ed35f50..d8a60a5d5a 100644 --- a/src/main/java/cn/nukkit/block/BlockAnvil.java +++ b/src/main/java/cn/nukkit/block/BlockAnvil.java @@ -89,7 +89,7 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl @Override public boolean onActivate(Item item, Player player) { if (player != null) { - player.addWindow(new AnvilInventory(this)); + player.addWindow(new AnvilInventory(this), Player.ANVIL_WINDOW_ID); } return true; } diff --git a/src/main/java/cn/nukkit/inventory/AnvilInventory.java b/src/main/java/cn/nukkit/inventory/AnvilInventory.java index a51e3affa4..b246c49593 100644 --- a/src/main/java/cn/nukkit/inventory/AnvilInventory.java +++ b/src/main/java/cn/nukkit/inventory/AnvilInventory.java @@ -33,12 +33,12 @@ public boolean onRename(Player player, Item resultItem) { Item local = getItem(TARGET); Item second = getItem(SACRIFICE); - if (!resultItem.deepEquals(local, true, false) || resultItem.getCount() != local.getCount()) { + if (!resultItem.equals(local, true, false) || resultItem.getCount() != local.getCount()) { //Item does not match target item. Everything must match except the tags. return false; } - if (local.deepEquals(resultItem)) { + if (local.equals(resultItem)) { //just item transaction return true; } @@ -143,4 +143,19 @@ public void onOpen(Player who) { super.onOpen(who); who.craftingType = Player.CRAFTING_ANVIL; } + + /*@Override + public boolean setItem(int index, Item item, boolean send) { + return super.setItem(index, item, false); + } + + @Override + public void sendSlot(int index, Player... players) { + + } + + @Override + public void sendContents(Player... player) { + + }*/ } \ No newline at end of file diff --git a/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java index 0da5910ed3..aadf1625d9 100644 --- a/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java +++ b/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java @@ -83,7 +83,7 @@ protected boolean matchItems(List needItems, List haveItems) { for (Item needItem : new ArrayList<>(needItems)) { for (Item haveItem : new ArrayList<>(haveItems)) { - if (needItem.deepEquals(haveItem)) { + if (needItem.equals(haveItem)) { int amount = Math.min(haveItem.getCount(), needItem.getCount()); needItem.setCount(needItem.getCount() - amount); haveItem.setCount(haveItem.getCount() - amount); diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java index 54b4dcd423..65d1bd81fd 100644 --- a/src/main/java/cn/nukkit/item/Item.java +++ b/src/main/java/cn/nukkit/item/Item.java @@ -31,22 +31,6 @@ */ public class Item implements Cloneable { - private static CompoundTag parseCompoundTag(byte[] tag) { - try { - return NBTIO.read(tag, ByteOrder.LITTLE_ENDIAN); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private byte[] writeCompoundTag(CompoundTag tag) { - try { - return NBTIO.write(tag, ByteOrder.LITTLE_ENDIAN); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - //All Block IDs are here too public static final int AIR = 0; public static final int STONE = 1; @@ -1889,16 +1873,24 @@ public Tag getNamedTagEntry(String name) { public CompoundTag getNamedTag() { if (!this.hasCompoundTag()) { return null; - } else if (this.cachedNBT != null) { - return this.cachedNBT; } - return this.cachedNBT = parseCompoundTag(this.tags); + + if (this.cachedNBT == null) { + this.cachedNBT = parseCompoundTag(this.tags); + } + + if (this.cachedNBT != null) { + this.cachedNBT.setName(""); + } + + return this.cachedNBT; } public Item setNamedTag(CompoundTag tag) { if (tag.isEmpty()) { return this.clearNamedTag(); } + tag.setName(null); this.cachedNBT = tag; this.tags = writeCompoundTag(tag); @@ -1910,6 +1902,23 @@ public Item clearNamedTag() { return this.setCompoundTag(new byte[0]); } + public static CompoundTag parseCompoundTag(byte[] tag) { + try { + return NBTIO.read(tag, ByteOrder.LITTLE_ENDIAN); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public byte[] writeCompoundTag(CompoundTag tag) { + try { + tag.setName(""); + return NBTIO.write(tag, ByteOrder.LITTLE_ENDIAN); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public int getCount() { return count; } @@ -2091,7 +2100,19 @@ public final boolean equals(Item item, boolean checkDamage) { } public final boolean equals(Item item, boolean checkDamage, boolean checkCompound) { - return this.getId() == item.getId() && (!checkDamage || this.getDamage() == item.getDamage()) && (!checkCompound || Arrays.equals(this.getCompoundTag(), item.getCompoundTag())); + if (this.getId() == item.getId() && (!checkDamage || this.getDamage() == item.getDamage())) { + if (checkCompound) { + if (Arrays.equals(this.getCompoundTag(), item.getCompoundTag())) { + return true; + } else if (this.hasCompoundTag() && item.hasCompoundTag()) { + return this.getNamedTag().equals(item.getNamedTag()); + } + } else { + return true; + } + } + + return false; } /** @@ -2101,24 +2122,19 @@ public final boolean equalsExact(Item other) { return this.equals(other, true, true) && this.count == other.count; } + @Deprecated public final boolean deepEquals(Item item) { - return deepEquals(item, true); + return equals(item, true); } + @Deprecated public final boolean deepEquals(Item item, boolean checkDamage) { - return deepEquals(item, checkDamage, true); + return equals(item, checkDamage, true); } + @Deprecated public final boolean deepEquals(Item item, boolean checkDamage, boolean checkCompound) { - if (this.equals(item, checkDamage, checkCompound)) { - return true; - } else if (item.hasCompoundTag()) { - return item.getNamedTag().equals(this.getNamedTag()); - } else if (this.hasCompoundTag()) { - return this.getNamedTag().equals(item.getNamedTag()); - } - - return false; + return equals(item, checkDamage, checkCompound); } @Override diff --git a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java index 7dc339c0b7..0e9048b0bb 100644 --- a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java +++ b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java @@ -1,6 +1,7 @@ package cn.nukkit.network.protocol.types; import cn.nukkit.Player; +import cn.nukkit.inventory.AnvilInventory; import cn.nukkit.inventory.Inventory; import cn.nukkit.inventory.transaction.action.CreativeInventoryAction; import cn.nukkit.inventory.transaction.action.DropItemAction; @@ -175,6 +176,36 @@ public InventoryAction createInventoryAction(Player player) { return new SlotChangeAction(window, inventorySlot, this.oldItem, this.newItem); } + if (this.windowId >= SOURCE_TYPE_ANVIL_OUTPUT && this.windowId <= SOURCE_TYPE_ANVIL_INPUT) { //anvil actions + Inventory inv = player.getWindowById(Player.ANVIL_WINDOW_ID); + + if (!(inv instanceof AnvilInventory)) { + throw new RuntimeException("Player " + player.getName() + " has no open anvil inventory"); + } + AnvilInventory anvil = (AnvilInventory) inv; + + switch (this.windowId) { + case SOURCE_TYPE_ANVIL_INPUT: + //System.out.println("action input"); + this.inventorySlot = 0; + return new SlotChangeAction(anvil, this.inventorySlot, this.oldItem, this.newItem); + case SOURCE_TYPE_ANVIL_MATERIAL: + //System.out.println("material"); + this.inventorySlot = 1; + return new SlotChangeAction(anvil, this.inventorySlot, this.oldItem, this.newItem); + case SOURCE_TYPE_ANVIL_OUTPUT: + //System.out.println("action output"); + break; + case SOURCE_TYPE_ANVIL_RESULT: + this.inventorySlot = 2; + anvil.clear(0); + anvil.clear(1); + anvil.setItem(2, this.oldItem); + //System.out.println("action result"); + return new SlotChangeAction(anvil, this.inventorySlot, this.oldItem, this.newItem); + } + } + //TODO: more stuff throw new RuntimeException("Player " + player.getName() + " has no open container with window ID " + this.windowId); default: From 777a5d6ca0693a771fd90ee4917dd6b0852a2644 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Fri, 29 Sep 2017 09:32:45 +0200 Subject: [PATCH 107/175] Client-side enchant support, need add some API --- src/main/java/cn/nukkit/Player.java | 12 +++-- .../cn/nukkit/block/BlockEnchantingTable.java | 2 +- .../cn/nukkit/inventory/EnchantInventory.java | 54 +++++++++++++++++-- .../network/protocol/BossEventPacket.java | 2 +- .../types/NetworkInventoryAction.java | 28 ++++++++++ 5 files changed, 89 insertions(+), 9 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index a6e183e47c..ad4f29a63d 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -1892,11 +1892,13 @@ protected void completeLoginSequence() { return; } + Level level; if (this.spawnPosition == null && this.namedTag.contains("SpawnLevel") && (level = this.server.getLevelByName(this.namedTag.getString("SpawnLevel"))) != null) { this.spawnPosition = new Position(this.namedTag.getInt("SpawnX"), this.namedTag.getInt("SpawnY"), this.namedTag.getInt("SpawnZ"), level); } Position spawnPosition = this.getSpawn(); + StartGamePacket startGamePacket = new StartGamePacket(); startGamePacket.entityUniqueId = this.id; startGamePacket.entityRuntimeId = this.id; @@ -1907,7 +1909,7 @@ protected void completeLoginSequence() { startGamePacket.yaw = (float) this.yaw; startGamePacket.pitch = (float) this.pitch; startGamePacket.seed = -1; - startGamePacket.dimension = (byte) (this.level.getDimension() & 0xff); + startGamePacket.dimension = (byte) (spawnPosition.level.getDimension() & 0xff); startGamePacket.worldGamemode = getClientFriendlyGamemode(this.gamemode); startGamePacket.difficulty = this.server.getDifficulty(); startGamePacket.spawnX = (int) spawnPosition.x; @@ -1926,7 +1928,7 @@ protected void completeLoginSequence() { this.loggedIn = true; - this.level.sendTime(this); + spawnPosition.level.sendTime(this); this.setMovementSpeed(DEFAULT_SPEED); this.sendAttributes(); @@ -3123,7 +3125,11 @@ public void handleDataPacket(DataPacket packet) { List actions = new ArrayList<>(); for (NetworkInventoryAction networkInventoryAction : transactionPacket.actions) { try { - actions.add(networkInventoryAction.createInventoryAction(this)); + InventoryAction a = networkInventoryAction.createInventoryAction(this); + + if (a != null) { + actions.add(a); + } } catch (Throwable e) { MainLogger.getLogger().debug("Unhandled inventory action from " + this.getName() + ": " + e.getMessage()); this.sendAllInventories(); diff --git a/src/main/java/cn/nukkit/block/BlockEnchantingTable.java b/src/main/java/cn/nukkit/block/BlockEnchantingTable.java index 2619966fe5..d29d132b8a 100644 --- a/src/main/java/cn/nukkit/block/BlockEnchantingTable.java +++ b/src/main/java/cn/nukkit/block/BlockEnchantingTable.java @@ -122,7 +122,7 @@ public boolean onActivate(Item item, Player player) { } } - player.addWindow(new EnchantInventory(this.getLocation())); + player.addWindow(new EnchantInventory(this.getLocation()), Player.ENCHANT_WINDOW_ID); } return true; diff --git a/src/main/java/cn/nukkit/inventory/EnchantInventory.java b/src/main/java/cn/nukkit/inventory/EnchantInventory.java index 9ec1103c28..0f74ff60a5 100644 --- a/src/main/java/cn/nukkit/inventory/EnchantInventory.java +++ b/src/main/java/cn/nukkit/inventory/EnchantInventory.java @@ -1,12 +1,14 @@ package cn.nukkit.inventory; import cn.nukkit.Player; -import cn.nukkit.Server; +import cn.nukkit.block.Block; import cn.nukkit.item.Item; import cn.nukkit.item.ItemBookEnchanted; import cn.nukkit.item.enchantment.Enchantment; import cn.nukkit.item.enchantment.EnchantmentEntry; import cn.nukkit.item.enchantment.EnchantmentList; +import cn.nukkit.level.Level; +import cn.nukkit.level.Location; import cn.nukkit.level.Position; import cn.nukkit.math.NukkitRandom; import cn.nukkit.network.protocol.CraftingDataPacket; @@ -218,8 +220,38 @@ public void onEnchant(Player who, Item before, Item after) { } public int countBookshelf() { - return 15; - //todo calculate bookshelf + int count = 0; + Location loc = this.getHolder().getLocation(); + Level level = loc.getLevel(); + + for (int y = 0; y <= 1; y++) { + for (int x = -1; x <= 1; x++) { + for (int z = -1; z <= 1; z++) { + if (z == 0 && x == 0) continue; + if (level.getBlock(loc.add(x, 0, z)).isTransparent()) { + if (level.getBlock(loc.add(0, 1, 0)).isTransparent()) { + //diagonal and straight + if (level.getBlock(loc.add(x << 1, y, z << 1)).getId() == Block.BOOKSHELF) { + count++; + } + + if (x != 0 && z != 0) { + //one block diagonal and one straight + if (level.getBlock(loc.add(x << 1, y, z)).getId() == Block.BOOKSHELF) { + ++count; + } + + if (level.getBlock(loc.add(x, y, z << 1)).getId() == Block.BOOKSHELF) { + ++count; + } + } + } + } + } + } + } + + return count; } public void sendEnchantmentList() { @@ -232,7 +264,21 @@ public void sendEnchantmentList() { pk.addEnchantList(list); } - Server.broadcastPacket(this.getViewers(), pk); + //Server.broadcastPacket(this.getViewers(), pk); //TODO: fix this, causes crash in 1.2 + } + + /*@Override + public void sendSlot(int index, Player... players) { + } + @Override + public void sendContents(Player... players) { + + } + + @Override + public boolean setItem(int index, Item item, boolean send) { + return super.setItem(index, item, false); + }*/ } diff --git a/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java b/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java index 2e4452776f..8bca568b8e 100644 --- a/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/BossEventPacket.java @@ -29,7 +29,7 @@ public class BossEventPacket extends DataPacket { public int type; public long playerEid; public float healthPercent; - public String title; + public String title = ""; public short unknown; public int color; public int overlay; diff --git a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java index 0e9048b0bb..559fb23d07 100644 --- a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java +++ b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java @@ -2,6 +2,7 @@ import cn.nukkit.Player; import cn.nukkit.inventory.AnvilInventory; +import cn.nukkit.inventory.EnchantInventory; import cn.nukkit.inventory.Inventory; import cn.nukkit.inventory.transaction.action.CreativeInventoryAction; import cn.nukkit.inventory.transaction.action.DropItemAction; @@ -206,6 +207,33 @@ public InventoryAction createInventoryAction(Player player) { } } + if (this.windowId >= SOURCE_TYPE_ENCHANT_OUTPUT && this.windowId <= SOURCE_TYPE_ENCHANT_INPUT) { + Inventory inv = player.getWindowById(Player.ENCHANT_WINDOW_ID); + + if (!(inv instanceof EnchantInventory)) { + throw new RuntimeException("Player " + player.getName() + " has no open enchant inventory"); + } + EnchantInventory enchant = (EnchantInventory) inv; + + switch (this.windowId) { + case SOURCE_TYPE_ENCHANT_INPUT: + this.inventorySlot = 0; + Item local = enchant.getItem(0); + if (local.equals(this.newItem, true, false)) { + enchant.setItem(0, this.newItem); + } + break; + case SOURCE_TYPE_ENCHANT_MATERIAL: + this.inventorySlot = 1; + break; + case SOURCE_TYPE_ENCHANT_OUTPUT: + //ignore? + return null; + } + + return new SlotChangeAction(enchant, this.inventorySlot, this.oldItem, this.newItem); + } + //TODO: more stuff throw new RuntimeException("Player " + player.getName() + " has no open container with window ID " + this.windowId); default: From 5ccf768caeddd457e01912a83fe71e43153fecd1 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Fri, 29 Sep 2017 09:37:22 +0200 Subject: [PATCH 108/175] maybe better than nothing --- .../cn/nukkit/network/protocol/types/NetworkInventoryAction.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java index 559fb23d07..1e72c21ad6 100644 --- a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java +++ b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java @@ -227,6 +227,7 @@ public InventoryAction createInventoryAction(Player player) { this.inventorySlot = 1; break; case SOURCE_TYPE_ENCHANT_OUTPUT: + enchant.sendSlot(0, player); //ignore? return null; } From f57399ca01ea90fc2ae0649b81e1e62976291049 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Fri, 29 Sep 2017 13:20:18 +0200 Subject: [PATCH 109/175] Fixed upload/download updating --- src/main/java/cn/nukkit/Server.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index 87ee947c35..301f2ba5fa 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -1006,6 +1006,7 @@ private boolean tick() { if ((this.tickCounter & 0b1111) == 0) { this.titleTick(); + this.network.resetStatistics(); this.maxTick = 20; this.maxUse = 0; @@ -1074,7 +1075,7 @@ private boolean tick() { // TODO: Fix title tick public void titleTick() { - if (true || !Nukkit.ANSI) { + if (!Nukkit.ANSI) { return; } @@ -1094,8 +1095,6 @@ public void titleTick() { " | Load " + this.getTickUsage() + "%" + (char) 0x07; System.out.print(title); - - this.network.resetStatistics(); } public QueryRegenerateEvent getQueryInformation() { From 23c3253cdda4c7951a8e5e88ec709ecf2ae669e1 Mon Sep 17 00:00:00 2001 From: boybook Date: Sat, 30 Sep 2017 01:32:57 +0800 Subject: [PATCH 110/175] Default no cape in a new Skin, fix NPE in PlayerListPacket (NPC). --- src/main/java/cn/nukkit/entity/data/Skin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/entity/data/Skin.java b/src/main/java/cn/nukkit/entity/data/Skin.java index 1619d06406..d6e4b1772d 100644 --- a/src/main/java/cn/nukkit/entity/data/Skin.java +++ b/src/main/java/cn/nukkit/entity/data/Skin.java @@ -25,7 +25,7 @@ public class Skin { private byte[] data = new byte[SINGLE_SKIN_SIZE]; private String model; - private Cape cape; + private Cape cape = new Cape(new byte[0]); //default no cape public Skin(byte[] data) { this(data, MODEL_STEVE); From 49983d0bd99d89d17f990cd8a72f29d1a41d3853 Mon Sep 17 00:00:00 2001 From: kvetinac97 Date: Sat, 30 Sep 2017 08:11:28 +0200 Subject: [PATCH 111/175] Fix Crafting, ArgTypes + ProtocolVersion (#24) * Fix NPE * Fix Arg types * Change byte to int type Because byte can handle values from -127 to 127, so we need now something bigger. * Update it for MCPE 1.2.1 * Debug crafting * Revert Debug * Hmm * Ignore check for Crafting * Fix build * Arrrrrgh * Do pr... se mnou * Step forward * Do not check items * Remove items from where they are * Remove this debug --- src/main/java/cn/nukkit/Player.java | 18 +++++++++++------- .../cn/nukkit/inventory/CraftingManager.java | 2 ++ .../protocol/AvailableCommandsPacket.java | 12 ++++++------ .../nukkit/network/protocol/ProtocolInfo.java | 6 +++--- .../protocol/types/NetworkInventoryAction.java | 17 +++-------------- 5 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index ad4f29a63d..f8028194d3 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -33,6 +33,7 @@ import cn.nukkit.inventory.transaction.InventoryTransaction; import cn.nukkit.inventory.transaction.SimpleInventoryTransaction; import cn.nukkit.inventory.transaction.action.InventoryAction; +import cn.nukkit.inventory.transaction.action.SlotChangeAction; import cn.nukkit.inventory.transaction.data.ReleaseItemData; import cn.nukkit.inventory.transaction.data.UseItemData; import cn.nukkit.inventory.transaction.data.UseItemOnEntityData; @@ -2627,7 +2628,7 @@ public void handleDataPacket(DataPacket packet) { boolean canCraft = true; if (craftingEventPacket.input.length == 0) { - Recipe[] recipes = getServer().getCraftingManager().getRecipesByResult(craftingEventPacket.output[0]); + Recipe[] recipes = new Recipe[]{recipe}; if (recipes == null || recipes.length == 0) { this.getServer().getLogger().debug("Uknown recipe for output (" + craftingEventPacket.output[0] + ")"); @@ -2676,7 +2677,7 @@ public void handleDataPacket(DataPacket packet) { } for (Item ingredient : serialized.values()) { - if (!this.inventory.contains(ingredient)) { + if (!this.craftingGrid.contains(ingredient)) { continue recipeloop; } } @@ -2692,7 +2693,7 @@ public void handleDataPacket(DataPacket packet) { } for (Item ingredient : serialized.values()) { - this.inventory.removeItem(ingredient); + this.craftingGrid.removeItem(ingredient); } this.inventory.addItem(recipe.getResult()); @@ -2741,7 +2742,7 @@ public void handleDataPacket(DataPacket packet) { } for (Item ingredient : serialized.values()) { - if (!this.inventory.contains(ingredient)) { + if (!this.craftingGrid.contains(ingredient)) { canCraft = false; break; } @@ -2761,7 +2762,7 @@ public void handleDataPacket(DataPacket packet) { } for (Item ingredient : serialized.values()) { - this.inventory.removeItem(ingredient); + this.craftingGrid.removeItem(ingredient); } this.inventory.addItem(recipe.getResult()); @@ -3122,12 +3123,15 @@ public void handleDataPacket(DataPacket packet) { InventoryTransactionPacket transactionPacket = (InventoryTransactionPacket) packet; + boolean isCrafting = false; List actions = new ArrayList<>(); for (NetworkInventoryAction networkInventoryAction : transactionPacket.actions) { try { InventoryAction a = networkInventoryAction.createInventoryAction(this); - if (a != null) { + if (a instanceof SlotChangeAction) { + if (((SlotChangeAction) a).getInventory() instanceof CraftingGrid) isCrafting = true; + } actions.add(a); } } catch (Throwable e) { @@ -3141,7 +3145,7 @@ public void handleDataPacket(DataPacket packet) { case InventoryTransactionPacket.TYPE_NORMAL: InventoryTransaction transaction = new SimpleInventoryTransaction(this, actions); - if (!transaction.execute()) { + if (!transaction.execute() && !isCrafting) { for (Inventory inventory : transaction.getInventories()) { inventory.sendContents(this); if (inventory instanceof PlayerInventory) { diff --git a/src/main/java/cn/nukkit/inventory/CraftingManager.java b/src/main/java/cn/nukkit/inventory/CraftingManager.java index 5db22d1e45..a9ee652616 100644 --- a/src/main/java/cn/nukkit/inventory/CraftingManager.java +++ b/src/main/java/cn/nukkit/inventory/CraftingManager.java @@ -327,6 +327,8 @@ public void registerRecipe(Recipe recipe) { } public Recipe[] getRecipesByResult(Item result) { + Map lookup = recipeLookup.get(result.getId() + ":" + result.getDamage()); + if (lookup == null) return new Recipe[0]; return recipeLookup.get(result.getId() + ":" + result.getDamage()).values().stream().toArray(Recipe[]::new); } diff --git a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java index 2af6355473..02db5e03bc 100644 --- a/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/AvailableCommandsPacket.java @@ -24,14 +24,14 @@ public class AvailableCommandsPacket extends DataPacket { 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_STRING = 0x0d; + public static final int ARG_TYPE_POSITION = 0x0e; - public static final int ARG_TYPE_RAWTEXT = 0x10; - public static final int ARG_TYPE_TEXT = 0x12; + public static final int ARG_TYPE_RAWTEXT = 0x11; + public static final int ARG_TYPE_TEXT = 0x13; - public static final int ARG_TYPE_JSON = 0x15; - public static final int ARG_TYPE_COMMAND = 0x1c; + public static final int ARG_TYPE_JSON = 0x16; + public static final int ARG_TYPE_COMMAND = 0x1d; public static final int ARG_FLAG_ENUM = 0x200000; public static final int ARG_FLAG_TEMPLATE = 0x01000000; diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java index 6213cdb333..e0cb2808b1 100644 --- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java +++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java @@ -9,10 +9,10 @@ public interface ProtocolInfo { /** * Actual Minecraft: PE protocol version */ - byte CURRENT_PROTOCOL = Integer.valueOf("136").byteValue(); //plugins can change it + int CURRENT_PROTOCOL = 137; - String MINECRAFT_VERSION = "v1.2.0.31 beta"; - String MINECRAFT_VERSION_NETWORK = "1.2.0.31"; + String MINECRAFT_VERSION = "v1.2.1"; + String MINECRAFT_VERSION_NETWORK = "1.2.1"; byte LOGIN_PACKET = 0x01; byte PLAY_STATUS_PACKET = 0x02; diff --git a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java index 1e72c21ad6..ea76a85ec4 100644 --- a/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java +++ b/src/main/java/cn/nukkit/network/protocol/types/NetworkInventoryAction.java @@ -152,24 +152,13 @@ public InventoryAction createInventoryAction(Player player) { //These types need special handling. switch (this.windowId) { case SOURCE_TYPE_CRAFTING_ADD_INGREDIENT: - case SOURCE_TYPE_CRAFTING_REMOVE_INGREDIENT: //TODO: a lot - //System.out.println("crafting change ingredient, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); - window = player.getCraftingGrid(); - return new SlotChangeAction(window, this.inventorySlot, this.oldItem, this.newItem); + case SOURCE_TYPE_CRAFTING_REMOVE_INGREDIENT: case SOURCE_TYPE_CRAFTING_RESULT: - window = player.getCraftingGrid(); - //return new SlotChangeAction(window, this.inventorySlot, this.); - - //System.out.println("crafting result, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); - break; case SOURCE_TYPE_CRAFTING_USE_INGREDIENT: - //System.out.println("crafting use ingredient, old: " + this.oldItem + " new: " + this.newItem + " slot: " + this.inventorySlot); - break; + window = player.getCraftingGrid(); + return new SlotChangeAction(window, this.inventorySlot, this.oldItem, this.newItem); case SOURCE_TYPE_CONTAINER_DROP_CONTENTS: - //TODO: this type applies to all fake windows, not just crafting window = player.getCraftingGrid(); - - //DROP_CONTENTS doesn't bother telling us what inventorySlot the item is in, so we find it ourselves inventorySlot = window.first(this.oldItem, true); if (inventorySlot == -1) { throw new RuntimeException("Fake container " + window.getClass().getName() + " for " + player.getName() + " does not contain " + this.oldItem); From 3f9bb060f0d03e2ffb4993d27ac58d3011daec7f Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sat, 30 Sep 2017 08:13:05 +0200 Subject: [PATCH 112/175] set chunk changed --- src/main/java/cn/nukkit/block/BlockPistonBase.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/cn/nukkit/block/BlockPistonBase.java b/src/main/java/cn/nukkit/block/BlockPistonBase.java index d4e583fdfc..43212a2cd2 100644 --- a/src/main/java/cn/nukkit/block/BlockPistonBase.java +++ b/src/main/java/cn/nukkit/block/BlockPistonBase.java @@ -99,6 +99,9 @@ public int onUpdate(int type) { if (arm.powered != powered) { this.level.getServer().getPluginManager().callEvent(new BlockPistonChangeEvent(this, powered ? 0 : 15, powered ? 15 : 0)); arm.powered = !arm.powered; + if (arm.chunk != null) { + arm.chunk.setChanged(); + } } } From dfc12757cf5c6f7eb2fc8caf253fb1a08790b42e Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sat, 30 Sep 2017 08:50:00 +0200 Subject: [PATCH 113/175] small changes --- src/main/java/cn/nukkit/Player.java | 481 ++++-------------- .../nukkit/network/protocol/ProtocolInfo.java | 2 +- 2 files changed, 89 insertions(+), 394 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index f8028194d3..f9ec5ea389 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2408,7 +2408,8 @@ public void handleDataPacket(DataPacket packet) { getServer().getPluginManager().callEvent(event); //Set back new settings if not been cancelled - if (!event.isCancelled() && window instanceof FormWindowCustom) ((FormWindowCustom) window).setElementsFromResponse(); + if (!event.isCancelled() && window instanceof FormWindowCustom) + ((FormWindowCustom) window).setElementsFromResponse(); } break; @@ -2571,37 +2572,7 @@ public void handleDataPacket(DataPacket packet) { Recipe recipe = this.server.getCraftingManager().getRecipe(craftingEventPacket.id); - if (this.craftingType == CRAFTING_ANVIL) { - Inventory inv = this.windowIndex.get(craftingEventPacket.windowId); - AnvilInventory anvilInventory = inv instanceof AnvilInventory ? (AnvilInventory) inv : null; - - if (anvilInventory == null) { - anvilInventory = null; - - for (Inventory window : this.windowIndex.values()) { - if (window instanceof AnvilInventory) { - anvilInventory = (AnvilInventory) window; - break; - } - } - - if (anvilInventory == null) { //If it'sf _still_ null, then the player doesn't have a valid anvil window, cannot proceed. - this.getServer().getLogger().debug("Couldn't find an anvil window for " + this.getName() + ", exiting"); - this.inventory.sendContents(this); - break; - } - } - - if (recipe == null) { - //Item renamed - - if (!anvilInventory.onRename(this, craftingEventPacket.output[0])) { - this.getServer().getLogger().debug(this.getName() + " failed to rename an item in an anvil"); - this.inventory.sendContents(this); - } - } - break; - } else if (!this.windowIndex.containsKey(craftingEventPacket.windowId)) { + if (!this.windowIndex.containsKey(craftingEventPacket.windowId)) { this.inventory.sendContents(this); containerClosePacket = new ContainerClosePacket(); containerClosePacket.windowId = craftingEventPacket.windowId; @@ -2609,7 +2580,7 @@ public void handleDataPacket(DataPacket packet) { break; } - if ((recipe == null) || (((recipe instanceof BigShapelessRecipe) || (recipe instanceof BigShapedRecipe)) && this.craftingType == CRAFTING_SMALL)) { + if (recipe == null || (((recipe instanceof BigShapelessRecipe) || (recipe instanceof BigShapedRecipe)) && this.craftingType == CRAFTING_SMALL)) { this.inventory.sendContents(this); break; } @@ -2627,382 +2598,103 @@ public void handleDataPacket(DataPacket packet) { boolean canCraft = true; - if (craftingEventPacket.input.length == 0) { - Recipe[] recipes = new Recipe[]{recipe}; - - if (recipes == null || recipes.length == 0) { - this.getServer().getLogger().debug("Uknown recipe for output (" + craftingEventPacket.output[0] + ")"); - return; - } - - recipe = null; + ArrayList ingredientz = new ArrayList<>(); - ArrayList ingredientz = new ArrayList<>(); + if (recipe instanceof ShapedRecipe) { - recipeloop: - for (Recipe rec : recipes) { - ingredientz.clear(); - - if (rec instanceof ShapedRecipe) { - Map> ingredients = ((ShapedRecipe) rec).getIngredientMap(); - for (Map map : ingredients.values()) { - for (Item ingredient : map.values()) { - if (ingredient != null && ingredient.getId() != Item.AIR) { - ingredientz.add(ingredient); - } - } - } - } else if (rec instanceof ShapelessRecipe) { - ShapelessRecipe recipe0 = (ShapelessRecipe) rec; - - 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) { - r.count += ingredient.getCount(); - continue; - } - - serialized.put(hash, ingredient); - } - - for (Item ingredient : serialized.values()) { - if (!this.craftingGrid.contains(ingredient)) { - continue recipeloop; - } - } - - recipe = rec; - - CraftItemEvent craftItemEvent = new CraftItemEvent(this, serialized.values().stream().toArray(Item[]::new), recipe); - getServer().getPluginManager().callEvent(craftItemEvent); - - if (craftItemEvent.isCancelled()) { - this.inventory.sendContents(this); - break packetswitch; - } - - for (Item ingredient : serialized.values()) { - this.craftingGrid.removeItem(ingredient); - } - - this.inventory.addItem(recipe.getResult()); - break; - } - - if (recipe == null) { - this.server.getLogger().debug("(1) Unmatched desktop recipe " + craftingEventPacket.id + " from player " + this.getName()); - this.inventory.sendContents(this); - } - } else { - 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()) { + 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; - Map serialized = new HashMap<>(); - - for (Item ingredient : ingredientz) { - String hash = ingredient.getId() + ":" + ingredient.getDamage(); - Item r = serialized.get(hash); - - if (r != null) { - r.count += ingredient.getCount(); - continue; - } - - serialized.put(hash, ingredient); - } - - for (Item ingredient : serialized.values()) { - if (!this.craftingGrid.contains(ingredient)) { - canCraft = false; - break; + for (Item ingredient : recipe0.getIngredientList()) { + if (ingredient != null && ingredient.getId() != Item.AIR) { + ingredientz.add(ingredient); } } + } - if (!canCraft) { - this.server.getLogger().debug("(1) Unmatched recipe " + craftingEventPacket.id + " from player " + this.getName() + " not anough ingredients"); - return; - } + Map serialized = new HashMap<>(); - CraftItemEvent craftItemEvent = new CraftItemEvent(this, serialized.values().stream().toArray(Item[]::new), recipe); - getServer().getPluginManager().callEvent(craftItemEvent); + for (Item ingredient : ingredientz) { + String hash = ingredient.getId() + ":" + ingredient.getDamage(); + Item r = serialized.get(hash); - if (craftItemEvent.isCancelled()) { - this.inventory.sendContents(this); - break; - } - - for (Item ingredient : serialized.values()) { - this.craftingGrid.removeItem(ingredient); + if (r != null) { + r.count += ingredient.getCount(); + continue; } - this.inventory.addItem(recipe.getResult()); - - /*if (recipe instanceof ShapedRecipe) { - int offsetX = 0; - int offsetY = 0; - - if (this.craftingType == CRAFTING_BIG) { - int minX = -1, minY = -1, maxX = 0, maxY = 0; - for (int x = 0; x < 3 && canCraft; ++x) { - for (int y = 0; y < 3; ++y) { - Item readItem = craftingEventPacket.input[y * 3 + x]; - if (readItem.getId() != Item.AIR) { - if (minY == -1 || minY > y) { - minY = y; - } - if (maxY < y) { - maxY = y; - } - if (minX == -1) { - minX = x; - } - if (maxX < x) { - maxX = x; - } - } - } - } - if (maxX == minX) { - offsetX = minX; - } - if (maxY == minY) { - offsetY = minY; - } - } - - //To fix some items can't craft - for (int x = 0; x < 3 - offsetX && canCraft; ++x) { - for (int y = 0; y < 3 - offsetY; ++y) { - item = craftingEventPacket.input[(y + offsetY) * 3 + (x + offsetX)]; - Item ingredient = ((ShapedRecipe) recipe).getIngredient(x, y); - //todo: check this https://github.com/PocketMine/PocketMine-MP/commit/58709293cf4eee2e836a94226bbba4aca0f53908 - if (item.getCount() > 0) { - if (ingredient == null || !ingredient.deepEquals(item, ingredient.hasMeta(), ingredient.getCompoundTag() != null)) { - canCraft = false; - break; - } - - } - } - } - - //If can't craft by auto resize, will try to craft this item in another way - if (!canCraft) { - canCraft = true; - for (int x = 0; x < 3 && canCraft; ++x) { - for (int y = 0; y < 3; ++y) { - item = craftingEventPacket.input[y * 3 + x]; - Item ingredient = ((ShapedRecipe) recipe).getIngredient(x, y); - if (item.getCount() > 0) { - if (ingredient == null || !ingredient.deepEquals(item, ingredient.hasMeta(), ingredient.getCompoundTag() != null)) { - canCraft = false; - break; - } - - } - } - } - } - - } else if (recipe instanceof ShapelessRecipe) { - List needed = ((ShapelessRecipe) recipe).getIngredientList(); - - for (int x = 0; x < 3 && canCraft; ++x) { - for (int y = 0; y < 3; ++y) { - item = craftingEventPacket.input[y * 3 + x].clone(); - - for (Item n : new ArrayList<>(needed)) { - if (n.deepEquals(item, n.hasMeta(), n.getCompoundTag() != null)) { - int remove = Math.min(n.getCount(), item.getCount()); - n.setCount(n.getCount() - remove); - item.setCount(item.getCount() - remove); - - if (n.getCount() == 0) { - needed.remove(n); - } - } - } - - if (item.getCount() > 0) { - canCraft = false; - break; - } - } - } + serialized.put(hash, ingredient); + } - if (!needed.isEmpty()) { - canCraft = false; - } - } else { + for (Item ingredient : serialized.values()) { + if (!this.craftingGrid.contains(ingredient)) { canCraft = false; + break; } + } - List ingredientsList = new ArrayList<>(); - if (recipe instanceof ShapedRecipe) { - for (int x = 0; x < 3; x++) { - for (int y = 0; y < 3; y++) { - Item need = ((ShapedRecipe) recipe).getIngredient(x, y); - if (need.getId() == 0) { - continue; - } - for (int count = need.getCount(); count > 0; count--) { - Item needAdd = need.clone(); - //todo: check if there need to set item's count to 1, I'm too tired to check that today =w= - needAdd.setCount(1); - ingredientsList.add(needAdd); - } - } - } - } - if (recipe instanceof ShapelessRecipe) { - List recipeItem = ((ShapelessRecipe) recipe).getIngredientList(); - for (Item need : recipeItem) { - if (need.getId() == 0) { - continue; - } - Item needAdd = need.clone(); - //todo: check if there need to set item's count to 1, I'm too tired to check that today =w= - needAdd.setCount(1); - ingredientsList.add(needAdd); - } - } - - Item[] ingredients = ingredientsList.stream().toArray(Item[]::new); - - Item result = craftingEventPacket.output[0]; + if (!canCraft) { + this.server.getLogger().debug("(1) Unmatched recipe " + craftingEventPacket.id + " from player " + this.getName() + " not anough ingredients"); + return; + } - if (!canCraft || !recipe.getResult().deepEquals(result)) { - this.server.getLogger().debug("(2) Unmatched recipe " + recipe.getId() + " from player " + this.getName() + ": expected " + recipe.getResult() + ", got " + result + ", using: " + Arrays.asList(ingredients).toString()); - this.inventory.sendContents(this); - break; - } + CraftItemEvent craftItemEvent = new CraftItemEvent(this, serialized.values().stream().toArray(Item[]::new), recipe); + getServer().getPluginManager().callEvent(craftItemEvent); - int[] used = new int[this.inventory.getSize()]; + if (craftItemEvent.isCancelled()) { + this.inventory.sendContents(this); + break; + } - for (Item ingredient : ingredients) { - slot = -1; - for (int index : this.inventory.getContents().keySet()) { - Item i = this.inventory.getContents().get(index); - if (ingredient.getId() != 0 && ingredient.deepEquals(i, ingredient.hasMeta()) && (i.getCount() - used[index]) >= 1) { - slot = index; - used[index]++; - break; - } - } + for (Item ingredient : serialized.values()) { + this.craftingGrid.removeItem(ingredient); + } - if (ingredient.getId() != 0 && slot == -1) { - canCraft = false; - break; - } - } + this.inventory.addItem(recipe.getResult()); - if (!canCraft) { - this.server.getLogger().debug("(3) Unmatched recipe " + recipe.getId() + " from player " + this.getName() + ": client does not have enough items, using: " + Arrays.asList(ingredients).toString()); - this.inventory.sendContents(this); + switch (recipe.getResult().getId()) { + case Item.WORKBENCH: + this.awardAchievement("buildWorkBench"); break; - } - CraftItemEvent craftItemEvent; - this.server.getPluginManager().callEvent(craftItemEvent = new CraftItemEvent(this, ingredients, recipe)); - - if (craftItemEvent.isCancelled()) { - this.inventory.sendContents(this); + 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; - } - - for (int i = 0; i < used.length; i++) { - int count = used[i]; - if (count == 0) { - continue; - } - - item = this.inventory.getItem(i); - - Item newItem; - if (item.getCount() > count) { - newItem = item.clone(); - newItem.setCount(item.getCount() - count); - } else { - newItem = new ItemBlock(new BlockAir(), 0, 0); - } - - this.inventory.setItem(i, newItem); - } - - Item[] extraItem = this.inventory.addItem(recipe.getResult()); - if (extraItem.length > 0) { - for (Item i : extraItem) { - this.level.dropItem(this, i); - } - }*/ - } - - 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; @@ -3130,7 +2822,8 @@ public void handleDataPacket(DataPacket packet) { InventoryAction a = networkInventoryAction.createInventoryAction(this); if (a != null) { if (a instanceof SlotChangeAction) { - if (((SlotChangeAction) a).getInventory() instanceof CraftingGrid) isCrafting = true; + if (((SlotChangeAction) a).getInventory() instanceof CraftingGrid) + isCrafting = true; } actions.add(a); } @@ -3646,15 +3339,15 @@ public void resetTitleSettings() { pk.type = SetTitlePacket.TYPE_RESET; this.dataPacket(pk); } - - public void setSubtitle(String subtitle){ - SetTitlePacket pk = new SetTitlePacket(); - pk.type = SetTitlePacket.TYPE_SUBTITLE; - pk.text = subtitle; - this.dataPacket(pk); + + public void setSubtitle(String subtitle) { + SetTitlePacket pk = new SetTitlePacket(); + pk.type = SetTitlePacket.TYPE_SUBTITLE; + pk.text = subtitle; + this.dataPacket(pk); } - - public void setTitleAnimationTimes(int fadein, int duration, int fadeout){ + + public void setTitleAnimationTimes(int fadein, int duration, int fadeout) { SetTitlePacket pk = new SetTitlePacket(); pk.type = SetTitlePacket.TYPE_ANIMATION_TIMES; pk.fadeInTime = fadein; @@ -4522,8 +4215,8 @@ public long createBossBar(String text, int length) { * Creates and sends a BossBar to the player * * @param dummyBossBar DummyBossBar Object (Instantiate it by the Class Builder) - * @see DummyBossBar.Builder * @return bossBarId The BossBar ID, you should store it if you want to remove or update the BossBar later + * @see DummyBossBar.Builder */ public long createBossBar(DummyBossBar dummyBossBar) { this.dummyBossBars.put(dummyBossBar.getBossBarId(), dummyBossBar); @@ -4533,6 +4226,7 @@ public long createBossBar(DummyBossBar dummyBossBar) { /** * Get a DummyBossBar object + * * @param bossBarId The BossBar ID * @return DummyBossBar object * @see DummyBossBar#setText(String) Set BossBar text @@ -4545,6 +4239,7 @@ public DummyBossBar getDummyBossBar(long bossBarId) { /** * Get all DummyBossBar objects + * * @return DummyBossBars Map */ public Map getDummyBossBars() { diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java index e0cb2808b1..1f8ca4c31c 100644 --- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java +++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java @@ -9,7 +9,7 @@ public interface ProtocolInfo { /** * Actual Minecraft: PE protocol version */ - int CURRENT_PROTOCOL = 137; + int CURRENT_PROTOCOL = Integer.valueOf("137"); //plugins can change it String MINECRAFT_VERSION = "v1.2.1"; String MINECRAFT_VERSION_NETWORK = "1.2.1"; From 6d669fb2e6db0d5ded1558f17e1e2c82334969de Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sat, 30 Sep 2017 10:00:15 +0200 Subject: [PATCH 114/175] Big crafting is still buggy, --- src/main/java/cn/nukkit/Player.java | 3 +- .../cn/nukkit/inventory/BigCraftingGrid.java | 2 +- .../cn/nukkit/inventory/CraftingGrid.java | 28 ++++++++++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index f9ec5ea389..2133f576f4 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2555,6 +2555,7 @@ public void handleDataPacket(DataPacket packet) { } this.craftingType = CRAFTING_SMALL; this.resetCraftingGridType(); + 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)); @@ -2655,7 +2656,7 @@ public void handleDataPacket(DataPacket packet) { } for (Item ingredient : serialized.values()) { - this.craftingGrid.removeItem(ingredient); + this.craftingGrid.removeFromAll(ingredient); } this.inventory.addItem(recipe.getResult()); diff --git a/src/main/java/cn/nukkit/inventory/BigCraftingGrid.java b/src/main/java/cn/nukkit/inventory/BigCraftingGrid.java index adb8f7175d..c4aebc8bc1 100644 --- a/src/main/java/cn/nukkit/inventory/BigCraftingGrid.java +++ b/src/main/java/cn/nukkit/inventory/BigCraftingGrid.java @@ -6,7 +6,7 @@ public class BigCraftingGrid extends CraftingGrid { public BigCraftingGrid(InventoryHolder holder) { - super(holder); + super(holder, 9); } @Override diff --git a/src/main/java/cn/nukkit/inventory/CraftingGrid.java b/src/main/java/cn/nukkit/inventory/CraftingGrid.java index 60351996f8..379ad2f8d9 100644 --- a/src/main/java/cn/nukkit/inventory/CraftingGrid.java +++ b/src/main/java/cn/nukkit/inventory/CraftingGrid.java @@ -1,6 +1,10 @@ package cn.nukkit.inventory; import cn.nukkit.Player; +import cn.nukkit.item.Item; +import cn.nukkit.utils.MainLogger; + +import java.util.HashMap; /** * author: MagicDroidX @@ -9,7 +13,11 @@ public class CraftingGrid extends BaseInventory { public CraftingGrid(InventoryHolder holder) { - super(holder, InventoryType.CRAFTING); + this(holder, 4); + } + + public CraftingGrid(InventoryHolder holder, int overrideSize) { + super(holder, InventoryType.CRAFTING, new HashMap<>(), overrideSize); } @Override @@ -25,6 +33,24 @@ public String getName() { return "Crafting"; } + public void removeFromAll(Item item) { + int count = item.getCount(); + + for (int i = 0; i < this.size; i++) { + Item target = this.getItem(i); + + if (target.equals(item, true, false)) { + count--; + target.count--; + this.setItem(i, target); + } + } + + if (count != 0) { + MainLogger.getLogger().debug("Unexpected ingredient count (" + count + ") in crafting grid"); + } + } + public void sendSlot(int index, Player... target) { //we can't send a inventorySlot of a client-sided inventory window } From e4fb61b0d6043a0e0da405ce91d66f1f448cb205 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sat, 30 Sep 2017 11:02:20 +0200 Subject: [PATCH 115/175] add Server settings request event --- src/main/java/cn/nukkit/Player.java | 17 +++++--- .../PlayerServerSettingsRequestEvent.java | 39 +++++++++++++++++++ 2 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 src/main/java/cn/nukkit/event/player/PlayerServerSettingsRequestEvent.java diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 2133f576f4..b64aeb575c 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -3171,12 +3171,17 @@ public void handleDataPacket(DataPacket packet) { this.inventory.equipItem(hotbarPacket.selectedHotbarSlot); break; case ProtocolInfo.SERVER_SETTINGS_REQUEST_PACKET: - this.serverSettings.forEach((id, window) -> { - ServerSettingsResponsePacket re = new ServerSettingsResponsePacket(); - re.formId = id; - re.data = window.getJSONData(); - this.dataPacket(re); - }); + PlayerServerSettingsRequestEvent settingsRequestEvent = new PlayerServerSettingsRequestEvent(this, new HashMap<>(this.serverSettings)) + this.getServer().getPluginManager().callEvent(settingsRequestEvent); + + if (!settingsRequestEvent.isCancelled()) { + settingsRequestEvent.getSettings().forEach((id, window) -> { + ServerSettingsResponsePacket re = new ServerSettingsResponsePacket(); + re.formId = id; + re.data = window.getJSONData(); + this.dataPacket(re); + }); + } break; default: break; diff --git a/src/main/java/cn/nukkit/event/player/PlayerServerSettingsRequestEvent.java b/src/main/java/cn/nukkit/event/player/PlayerServerSettingsRequestEvent.java new file mode 100644 index 0000000000..400dd347ed --- /dev/null +++ b/src/main/java/cn/nukkit/event/player/PlayerServerSettingsRequestEvent.java @@ -0,0 +1,39 @@ +package cn.nukkit.event.player; + +import cn.nukkit.Player; +import cn.nukkit.event.Cancellable; +import cn.nukkit.event.HandlerList; +import cn.nukkit.form.window.FormWindow; + +import java.util.Map; + +/** + * @author CreeperFace + */ +public class PlayerServerSettingsRequestEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + public static HandlerList getHandlers() { + return handlers; + } + + private Map settings; + + public PlayerServerSettingsRequestEvent(Player player, Map settings) { + this.player = player; + this.settings = settings; + } + + public Map getSettings() { + return settings; + } + + public void setSettings(Map settings) { + this.settings = settings; + } + + public void setSettings(int id, FormWindow window) { + this.settings.put(id, window); + } +} From ec4b58d617bac00c07fc3a9c20454f8f3e971925 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sat, 30 Sep 2017 11:04:43 +0200 Subject: [PATCH 116/175] ops --- 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 b64aeb575c..a58008d819 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -3171,9 +3171,9 @@ public void handleDataPacket(DataPacket packet) { this.inventory.equipItem(hotbarPacket.selectedHotbarSlot); break; case ProtocolInfo.SERVER_SETTINGS_REQUEST_PACKET: - PlayerServerSettingsRequestEvent settingsRequestEvent = new PlayerServerSettingsRequestEvent(this, new HashMap<>(this.serverSettings)) + PlayerServerSettingsRequestEvent settingsRequestEvent = new PlayerServerSettingsRequestEvent(this, new HashMap<>(this.serverSettings)); this.getServer().getPluginManager().callEvent(settingsRequestEvent); - + if (!settingsRequestEvent.isCancelled()) { settingsRequestEvent.getSettings().forEach((id, window) -> { ServerSettingsResponsePacket re = new ServerSettingsResponsePacket(); From 32e4e4d145debc91c3525c930c494487d54a0036 Mon Sep 17 00:00:00 2001 From: kvetinac97 Date: Sat, 30 Sep 2017 13:47:04 +0200 Subject: [PATCH 117/175] Fix Nukkit sometimes getting wrong Recipe ID (#28) * Make getResultByOutput working * Ban this from happening * Kind of backup here * Fix * Debug * Hm * Remove it --- src/main/java/cn/nukkit/Player.java | 92 ++++++++++++------- .../cn/nukkit/inventory/CraftingGrid.java | 1 + .../cn/nukkit/inventory/CraftingManager.java | 4 +- .../SimpleInventoryTransaction.java | 5 + 4 files changed, 68 insertions(+), 34 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index a58008d819..5384f155d6 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2572,6 +2572,16 @@ public void handleDataPacket(DataPacket packet) { } Recipe recipe = this.server.getCraftingManager().getRecipe(craftingEventPacket.id); + Recipe[] recipes = this.server.getCraftingManager().getRecipesByResult(craftingEventPacket.output[0]); + + boolean isValid = false; + for (Recipe rec : recipes){ + if (rec.getId().equals(recipe.getId())) { + isValid = true; + break; + } + } + if (isValid) recipes = new Recipe[]{recipe}; if (!this.windowIndex.containsKey(craftingEventPacket.windowId)) { this.inventory.sendContents(this); @@ -2580,8 +2590,8 @@ public void handleDataPacket(DataPacket packet) { this.dataPacket(containerClosePacket); break; } - - if (recipe == null || (((recipe instanceof BigShapelessRecipe) || (recipe instanceof BigShapedRecipe)) && this.craftingType == CRAFTING_SMALL)) { + + if (isValid && (recipe == null || (((recipe instanceof BigShapelessRecipe) || (recipe instanceof BigShapedRecipe)) && this.craftingType == CRAFTING_SMALL))) { this.inventory.sendContents(this); break; } @@ -2598,48 +2608,66 @@ public void handleDataPacket(DataPacket packet) { } boolean canCraft = true; + Map realSerialized = new HashMap<>(); + + for (Recipe rec : recipes) { + ArrayList ingredientz = new ArrayList<>(); + + if (rec == null || (((rec instanceof BigShapelessRecipe) || (rec instanceof BigShapedRecipe)) && this.craftingType == CRAFTING_SMALL)) { + continue; + } - ArrayList ingredientz = new ArrayList<>(); - - if (recipe instanceof ShapedRecipe) { + if (rec instanceof ShapedRecipe) { + Map> ingredients = ((ShapedRecipe) rec).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; - Map> ingredients = ((ShapedRecipe) recipe).getIngredientMap(); - for (Map map : ingredients.values()) { - for (Item ingredient : map.values()) { + for (Item ingredient : recipe0.getIngredientList()) { 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<>(); - Map serialized = new HashMap<>(); + for (Item ingredient : ingredientz) { + String hash = ingredient.getId() + ":" + ingredient.getDamage(); + Item r = serialized.get(hash); - for (Item ingredient : ingredientz) { - String hash = ingredient.getId() + ":" + ingredient.getDamage(); - Item r = serialized.get(hash); + if (r != null) { + r.count += ingredient.getCount(); + continue; + } - if (r != null) { - r.count += ingredient.getCount(); - continue; + serialized.put(hash, ingredient); } - serialized.put(hash, ingredient); - } - - for (Item ingredient : serialized.values()) { - if (!this.craftingGrid.contains(ingredient)) { - canCraft = false; - break; + boolean isPossible = true; + for (Item ingredient : serialized.values()) { + if (!this.craftingGrid.contains(ingredient)) { + if (isValid) { + canCraft = false; + break; + } + else { + isPossible = false; + break; + } + } } + if (!isPossible) continue; + recipe = rec; + realSerialized = serialized; + break; } if (!canCraft) { @@ -2647,7 +2675,7 @@ public void handleDataPacket(DataPacket packet) { return; } - CraftItemEvent craftItemEvent = new CraftItemEvent(this, serialized.values().stream().toArray(Item[]::new), recipe); + CraftItemEvent craftItemEvent = new CraftItemEvent(this, realSerialized.values().stream().toArray(Item[]::new), recipe); getServer().getPluginManager().callEvent(craftItemEvent); if (craftItemEvent.isCancelled()) { @@ -2655,7 +2683,7 @@ public void handleDataPacket(DataPacket packet) { break; } - for (Item ingredient : serialized.values()) { + for (Item ingredient : realSerialized.values()) { this.craftingGrid.removeFromAll(ingredient); } diff --git a/src/main/java/cn/nukkit/inventory/CraftingGrid.java b/src/main/java/cn/nukkit/inventory/CraftingGrid.java index 379ad2f8d9..4183d6b8fe 100644 --- a/src/main/java/cn/nukkit/inventory/CraftingGrid.java +++ b/src/main/java/cn/nukkit/inventory/CraftingGrid.java @@ -43,6 +43,7 @@ public void removeFromAll(Item item) { count--; target.count--; this.setItem(i, target); + if (count <= 0) break; } } diff --git a/src/main/java/cn/nukkit/inventory/CraftingManager.java b/src/main/java/cn/nukkit/inventory/CraftingManager.java index a9ee652616..ce857bef51 100644 --- a/src/main/java/cn/nukkit/inventory/CraftingManager.java +++ b/src/main/java/cn/nukkit/inventory/CraftingManager.java @@ -54,7 +54,7 @@ public CraftingManager() { if (id != null && !id.isEmpty()) { UUID uuid = UUID.fromString(id); result.setId(uuid); - this.recipes.put(uuid, result); + this.registerShapelessRecipe(result); } break; case 1: @@ -81,7 +81,7 @@ public CraftingManager() { if (id != null && !id.isEmpty()) { UUID uuid = UUID.fromString(id); shapedRecipe.setId(uuid); - this.recipes.put(uuid, shapedRecipe); + this.registerShapedRecipe(shapedRecipe); } break; case 2: diff --git a/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java b/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java index aadf1625d9..48df171900 100644 --- a/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java +++ b/src/main/java/cn/nukkit/inventory/transaction/SimpleInventoryTransaction.java @@ -173,6 +173,11 @@ protected boolean squashDuplicateSlotChanges() { list.remove(i); sortedThisLoop++; } + else if (actionSource.equals(lastTargetItem)) { + lastTargetItem.count -= actionSource.count; + list.remove(i); + if (lastTargetItem.count == 0) sortedThisLoop++; + } } } while (sortedThisLoop > 0); From 0818402cab8f48b819e4d36d77f8301356b0b799 Mon Sep 17 00:00:00 2001 From: kvetinac97 Date: Sun, 1 Oct 2017 08:48:40 +0200 Subject: [PATCH 118/175] Add possibility to write books (#29) * Add Book & Quill + WrittenBook Book & Quill and the whole writing of books are TODO * Create ItemBookWritten.java * Better have ItemBookWritten than ItemWrittenBook * More constructors * Add getPages method --- src/main/java/cn/nukkit/item/Item.java | 6 +- .../java/cn/nukkit/item/ItemBookWritten.java | 96 +++++++++++++++++++ 2 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/main/java/cn/nukkit/item/ItemBookWritten.java diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java index 65d1bd81fd..8aa38ec4a9 100644 --- a/src/main/java/cn/nukkit/item/Item.java +++ b/src/main/java/cn/nukkit/item/Item.java @@ -480,7 +480,8 @@ public class Item implements Cloneable { public static final int SPAWN_EGG = 383; public static final int EXPERIENCE_BOTTLE = 384; public static final int FIRE_CHARGE = 385; - + public static final int BOOK_AND_QUILL = 386; + public static final int WRITTEN_BOOK = 387; public static final int EMERALD = 388; public static final int ITEM_FRAME = 389; public static final int FLOWER_POT = 390; @@ -744,7 +745,8 @@ public static void init() { list[SPAWN_EGG] = ItemSpawnEgg.class; //383 list[EXPERIENCE_BOTTLE] = ItemExpBottle.class; //384 //TODO: list[FIRE_CHARGE] = ItemFireCharge.class; //385 - + //TODO: list[BOOK_AND_QUILL] = ItemBookAndQuill.class; //386 + list[WRITTEN_BOOK] = ItemBookWritten.class; //387 list[EMERALD] = ItemEmerald.class; //388 list[ITEM_FRAME] = ItemItemFrame.class; //389 list[FLOWER_POT] = ItemFlowerPot.class; //390 diff --git a/src/main/java/cn/nukkit/item/ItemBookWritten.java b/src/main/java/cn/nukkit/item/ItemBookWritten.java new file mode 100644 index 0000000000..7161892853 --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemBookWritten.java @@ -0,0 +1,96 @@ +package cn.nukkit.item; + +import cn.nukkit.item.Item; +import cn.nukkit.nbt.tag.CompoundTag; +import cn.nukkit.nbt.tag.ListTag; + +import java.util.concurrent.ThreadLocalRandom; + +public class ItemBookWritten extends Item { + + protected boolean isWritten = false; + + public ItemBookWritten() { + this (Integer.valueOf(0), 1); + } + public ItemBookWritten (String author, String title, String[] pages) { + this (Integer.valueOf(0), 1); + this.writeBook(author, title, pages); + } + public ItemBookWritten (String author, String title, ListTag pages) { + this (Integer.valueOf(0), 1); + this.writeBook(author, title, pages); + } + public ItemBookWritten(Integer meta) { + this (meta, 1); + } + public ItemBookWritten (Integer meta, String author, String title, String[] pages) { + this (meta, 1); + this.writeBook(author, title, pages); + } + public ItemBookWritten (Integer meta, String author, String title, ListTag pages) { + this (meta, 1); + this.writeBook(author, title, pages); + } + public ItemBookWritten(Integer meta, int count) { + super (Item.WRITTEN_BOOK, Integer.valueOf(0), count, "Book"); + } + public ItemBookWritten (Integer meta, Integer count, String author, String title, String[] pages) { + this (meta, count); + this.writeBook(author, title, pages); + } + public ItemBookWritten (Integer meta, Integer count, String author, String title, ListTag pages) { + this (meta, count); + this.writeBook(author, title, pages); + } + + public Item writeBook (String author, String title, String[] pages) { + ListTag pageList = new ListTag<>("pages"); + for (String page : pages){ + pageList.add(new CompoundTag().putString("photoname", "").putString("text", page)); + } + return writeBook(author, title, pageList); + } + public Item writeBook (String author, String title, ListTag pages){ + if (pages.size() > 50 || pages.size() <= 0) return this; //Minecraft does not support more than 50 pages + if (this.isWritten) return this; //Book content can only be updated once + CompoundTag tag; + if (!this.hasCompoundTag()){ + tag = new CompoundTag(); + } + else { + tag = this.getNamedTag(); + } + + tag.putString("author", author); + tag.putString("title", title); + tag.putList(pages); + + tag.putInt("generation", 0); + long randomId = 1095216660480L + ThreadLocalRandom.current().nextLong(0L, 2147483647L); + tag.putLong("id", randomId); + + this.isWritten = true; + return this.setNamedTag(tag); + } + public String getAuthor(){ + if (!this.isWritten) return ""; + return this.getNamedTag().getString("author"); + } + public String getTitle(){ + if (!this.isWritten) return "Book"; + return this.getNamedTag().getString("title"); + } + public String[] getPages(){ + if (!this.isWritten) return new String[0]; + ListTag tag = (ListTag) this.getNamedTag().getList("pages"); + String[] pages = new String[tag.size()]; + int i = 0; + for (CompoundTag pageCompound : tag.getAll()) { + pages[i] = pageCompound.getString("text"); + i++; + } + return pages; + } + +} From 354894a2784c8341955fc44b2a6b00afe75dedba Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 1 Oct 2017 09:57:46 +0200 Subject: [PATCH 119/175] Load creative items from json --- .../nukkit/block/BlockGlassPaneStained.java | 6 + .../cn/nukkit/inventory/CraftingManager.java | 17 +- src/main/java/cn/nukkit/item/Item.java | 664 +--- .../java/cn/nukkit/item/ItemBookWritten.java | 57 +- src/main/resources/creativeitems.json | 3352 +++++++++++++++++ 5 files changed, 3413 insertions(+), 683 deletions(-) create mode 100644 src/main/resources/creativeitems.json diff --git a/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java b/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java index 7bc6c771cc..bf3caeba14 100644 --- a/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java +++ b/src/main/java/cn/nukkit/block/BlockGlassPaneStained.java @@ -1,5 +1,6 @@ package cn.nukkit.block; +import cn.nukkit.utils.BlockColor; import cn.nukkit.utils.DyeColor; /** @@ -25,6 +26,11 @@ public String getName() { return getDyeColor().getName() + " stained glass pane"; } + @Override + public BlockColor getColor() { + return getDyeColor().getColor(); + } + public DyeColor getDyeColor() { return DyeColor.getByWoolData(meta); } diff --git a/src/main/java/cn/nukkit/inventory/CraftingManager.java b/src/main/java/cn/nukkit/inventory/CraftingManager.java index ce857bef51..41a7e21497 100644 --- a/src/main/java/cn/nukkit/inventory/CraftingManager.java +++ b/src/main/java/cn/nukkit/inventory/CraftingManager.java @@ -10,6 +10,7 @@ import cn.nukkit.utils.MainLogger; import cn.nukkit.utils.Utils; +import java.io.File; import java.io.IOException; import java.util.*; @@ -32,13 +33,17 @@ public class CraftingManager { public static CraftingDataPacket packet = null; public CraftingManager() { - try { - Utils.writeFile(Server.getInstance().getDataPath() + "recipes.json", Server.class.getClassLoader().getResourceAsStream("recipes.json")); - } catch (IOException e) { - MainLogger.getLogger().logException(e); - //return; + String path = Server.getInstance().getDataPath() + "recipes.json"; + + if (!new File(path).exists()) { + try { + Utils.writeFile(path, Server.class.getClassLoader().getResourceAsStream("recipes.json")); + } catch (IOException e) { + MainLogger.getLogger().logException(e); + } } - List recipes = new Config(Server.getInstance().getDataPath() + "recipes.json", Config.JSON).getMapList("recipes"); + + List recipes = new Config(path, Config.JSON).getMapList("recipes"); MainLogger.getLogger().info("Loading recipes..."); for (Map recipe : recipes) { //TODO: implement this better switch (Utils.toInt(recipe.get("type"))) { diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java index 8aa38ec4a9..6932c11a2b 100644 --- a/src/main/java/cn/nukkit/item/Item.java +++ b/src/main/java/cn/nukkit/item/Item.java @@ -1,10 +1,9 @@ package cn.nukkit.item; import cn.nukkit.Player; +import cn.nukkit.Server; import cn.nukkit.block.Block; import cn.nukkit.block.BlockAir; -import cn.nukkit.block.BlockFence; -import cn.nukkit.block.BlockFlower; import cn.nukkit.entity.Entity; import cn.nukkit.inventory.Fuel; import cn.nukkit.item.enchantment.Enchantment; @@ -17,12 +16,18 @@ import cn.nukkit.nbt.tag.StringTag; import cn.nukkit.nbt.tag.Tag; import cn.nukkit.utils.Binary; +import cn.nukkit.utils.Config; +import cn.nukkit.utils.MainLogger; +import cn.nukkit.utils.Utils; +import javax.xml.bind.DatatypeConverter; +import java.io.File; import java.io.IOException; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.regex.Pattern; /** @@ -825,644 +830,31 @@ public static void init() { private static void initCreativeItems() { clearCreativeItems(); + Server server = Server.getInstance(); - //Building - addCreativeItem(Item.get(Item.COBBLESTONE, 0)); - addCreativeItem(Item.get(Item.STONE_BRICKS, 0)); - addCreativeItem(Item.get(Item.STONE_BRICKS, 1)); - addCreativeItem(Item.get(Item.STONE_BRICKS, 2)); - addCreativeItem(Item.get(Item.STONE_BRICKS, 3)); - addCreativeItem(Item.get(Item.MOSS_STONE, 0)); - addCreativeItem(Item.get(Item.WOODEN_PLANKS, 0)); - addCreativeItem(Item.get(Item.WOODEN_PLANKS, 1)); - addCreativeItem(Item.get(Item.WOODEN_PLANKS, 2)); - addCreativeItem(Item.get(Item.WOODEN_PLANKS, 3)); - addCreativeItem(Item.get(Item.WOODEN_PLANKS, 4)); - addCreativeItem(Item.get(Item.WOODEN_PLANKS, 5)); - addCreativeItem(Item.get(Item.BRICKS, 0)); - - addCreativeItem(Item.get(Item.STONE, 0)); - addCreativeItem(Item.get(Item.STONE, 1)); - addCreativeItem(Item.get(Item.STONE, 2)); - addCreativeItem(Item.get(Item.STONE, 3)); - addCreativeItem(Item.get(Item.STONE, 4)); - addCreativeItem(Item.get(Item.STONE, 5)); - addCreativeItem(Item.get(Item.STONE, 6)); - addCreativeItem(Item.get(Item.DIRT, 0)); - addCreativeItem(Item.get(Item.PODZOL, 0)); - addCreativeItem(Item.get(Item.GRASS, 0)); - addCreativeItem(Item.get(Item.MYCELIUM, 0)); - addCreativeItem(Item.get(Item.CLAY_BLOCK, 0)); - addCreativeItem(Item.get(Item.TERRACOTTA, 0)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 0)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 1)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 2)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 3)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 4)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 5)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 6)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 7)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 8)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 9)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 10)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 11)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 12)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 13)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 14)); - addCreativeItem(Item.get(Item.STAINED_TERRACOTTA, 15)); - addCreativeItem(Item.get(Item.SANDSTONE, 0)); - addCreativeItem(Item.get(Item.SANDSTONE, 1)); - addCreativeItem(Item.get(Item.SANDSTONE, 2)); - addCreativeItem(Item.get(Item.RED_SANDSTONE, 0)); - addCreativeItem(Item.get(Item.RED_SANDSTONE, 1)); - addCreativeItem(Item.get(Item.RED_SANDSTONE, 2)); - addCreativeItem(Item.get(Item.SAND, 0)); - addCreativeItem(Item.get(Item.SAND, 1)); - addCreativeItem(Item.get(Item.GRAVEL, 0)); - addCreativeItem(Item.get(Item.TRUNK, 0)); - addCreativeItem(Item.get(Item.TRUNK, 1)); - addCreativeItem(Item.get(Item.TRUNK, 2)); - addCreativeItem(Item.get(Item.TRUNK, 3)); - addCreativeItem(Item.get(Item.TRUNK2, 0)); - addCreativeItem(Item.get(Item.TRUNK2, 1)); - addCreativeItem(Item.get(Item.NETHER_BRICKS, 0)); - addCreativeItem(Item.get(Item.NETHERRACK, 0)); - addCreativeItem(Item.get(Item.SOUL_SAND, 0)); - addCreativeItem(Item.get(Item.BEDROCK, 0)); - addCreativeItem(Item.get(Item.COBBLESTONE_STAIRS, 0)); - addCreativeItem(Item.get(Item.OAK_WOODEN_STAIRS, 0)); - addCreativeItem(Item.get(Item.SPRUCE_WOODEN_STAIRS, 0)); - addCreativeItem(Item.get(Item.BIRCH_WOODEN_STAIRS, 0)); - addCreativeItem(Item.get(Item.JUNGLE_WOODEN_STAIRS, 0)); - addCreativeItem(Item.get(Item.ACACIA_WOODEN_STAIRS, 0)); - addCreativeItem(Item.get(Item.DARK_OAK_WOODEN_STAIRS, 0)); - addCreativeItem(Item.get(Item.BRICK_STAIRS, 0)); - addCreativeItem(Item.get(Item.SANDSTONE_STAIRS, 0)); - addCreativeItem(Item.get(Item.RED_SANDSTONE_STAIRS, 0)); - addCreativeItem(Item.get(Item.STONE_BRICK_STAIRS, 0)); - addCreativeItem(Item.get(Item.NETHER_BRICKS_STAIRS, 0)); - addCreativeItem(Item.get(Item.QUARTZ_STAIRS, 0)); - addCreativeItem(Item.get(Item.PURPUR_STAIRS, 0)); - addCreativeItem(Item.get(Item.SLAB, 0)); - addCreativeItem(Item.get(Item.SLAB, 3)); - addCreativeItem(Item.get(Item.WOODEN_SLAB, 0)); - addCreativeItem(Item.get(Item.WOODEN_SLAB, 1)); - addCreativeItem(Item.get(Item.WOODEN_SLAB, 2)); - addCreativeItem(Item.get(Item.WOODEN_SLAB, 3)); - addCreativeItem(Item.get(Item.WOODEN_SLAB, 4)); - addCreativeItem(Item.get(Item.WOODEN_SLAB, 5)); - addCreativeItem(Item.get(Item.SLAB, 4)); - addCreativeItem(Item.get(Item.SLAB, 1)); - addCreativeItem(Item.get(Item.RED_SANDSTONE_SLAB)); - addCreativeItem(Item.get(Item.SLAB, 5)); - addCreativeItem(Item.get(Item.SLAB, 7)); - addCreativeItem(Item.get(Item.SLAB, 6)); - addCreativeItem(Item.get(Item.RED_SANDSTONE_SLAB, 1)); - addCreativeItem(Item.get(Item.QUARTZ_BLOCK, 0)); - addCreativeItem(Item.get(Item.QUARTZ_BLOCK, 2)); - addCreativeItem(Item.get(Item.QUARTZ_BLOCK, 1)); - addCreativeItem(Item.get(Item.PRISMARINE, 0)); - addCreativeItem(Item.get(Item.PRISMARINE, 1)); - addCreativeItem(Item.get(Item.PRISMARINE, 2)); - addCreativeItem(Item.get(Item.PURPUR_BLOCK, 0)); - addCreativeItem(Item.get(Item.PURPUR_BLOCK, 2)); - addCreativeItem(Item.get(Item.COAL_ORE, 0)); - addCreativeItem(Item.get(Item.IRON_ORE, 0)); - addCreativeItem(Item.get(Item.GOLD_ORE, 0)); - addCreativeItem(Item.get(Item.DIAMOND_ORE, 0)); - addCreativeItem(Item.get(Item.LAPIS_ORE, 0)); - addCreativeItem(Item.get(Item.REDSTONE_ORE, 0)); - addCreativeItem(Item.get(Item.EMERALD_ORE, 0)); - addCreativeItem(Item.get(Item.QUARTZ_ORE, 0)); - addCreativeItem(Item.get(Item.OBSIDIAN, 0)); - addCreativeItem(Item.get(Item.ICE, 0)); - addCreativeItem(Item.get(Item.PACKED_ICE, 0)); - addCreativeItem(Item.get(Item.SNOW_BLOCK, 0)); - addCreativeItem(Item.get(Item.END_BRICKS, 0)); - addCreativeItem(Item.get(Item.END_STONE, 0)); - - //Decoration - addCreativeItem(Item.get(Item.BEACON, 0)); - addCreativeItem(Item.get(Item.COBBLESTONE_WALL, 0)); - addCreativeItem(Item.get(Item.COBBLESTONE_WALL, 1)); - addCreativeItem(Item.get(Item.WATER_LILY, 0)); - addCreativeItem(Item.get(Item.SEA_LANTERN, 0)); - addCreativeItem(Item.get(Item.CHORUS_PLANT, 0)); - addCreativeItem(Item.get(Item.CHORUS_FLOWER, 0)); - addCreativeItem(Item.get(Item.GOLD_BLOCK, 0)); - addCreativeItem(Item.get(Item.IRON_BLOCK, 0)); - addCreativeItem(Item.get(Item.DIAMOND_BLOCK, 0)); - addCreativeItem(Item.get(Item.LAPIS_BLOCK, 0)); - addCreativeItem(Item.get(Item.COAL_BLOCK, 0)); - addCreativeItem(Item.get(Item.EMERALD_BLOCK, 0)); - addCreativeItem(Item.get(Item.REDSTONE_BLOCK, 0)); - addCreativeItem(Item.get(Item.SNOW_LAYER, 0)); - addCreativeItem(Item.get(Item.GLASS, 0)); - addCreativeItem(Item.get(Item.GLOWSTONE_BLOCK, 0)); - addCreativeItem(Item.get(Item.VINES, 0)); - addCreativeItem(Item.get(Item.LADDER, 0)); - addCreativeItem(Item.get(Item.SPONGE, 0)); - addCreativeItem(Item.get(Item.SPONGE, 1)); - addCreativeItem(Item.get(Item.GLASS_PANE, 0)); - addCreativeItem(Item.get(Item.WOODEN_DOOR, 0)); - addCreativeItem(Item.get(Item.SPRUCE_DOOR, 0)); - addCreativeItem(Item.get(Item.BIRCH_DOOR, 0)); - addCreativeItem(Item.get(Item.JUNGLE_DOOR, 0)); - addCreativeItem(Item.get(Item.ACACIA_DOOR, 0)); - addCreativeItem(Item.get(Item.DARK_OAK_DOOR, 0)); - addCreativeItem(Item.get(Item.IRON_DOOR, 0)); - addCreativeItem(Item.get(Item.TRAPDOOR, 0)); - addCreativeItem(Item.get(Item.IRON_TRAPDOOR, 0)); - addCreativeItem(Item.get(Item.FENCE, BlockFence.FENCE_OAK)); - addCreativeItem(Item.get(Item.FENCE, BlockFence.FENCE_SPRUCE)); - addCreativeItem(Item.get(Item.FENCE, BlockFence.FENCE_BIRCH)); - addCreativeItem(Item.get(Item.FENCE, BlockFence.FENCE_JUNGLE)); - addCreativeItem(Item.get(Item.FENCE, BlockFence.FENCE_ACACIA)); - addCreativeItem(Item.get(Item.FENCE, BlockFence.FENCE_DARK_OAK)); - addCreativeItem(Item.get(Item.NETHER_BRICK_FENCE, 0)); - addCreativeItem(Item.get(Item.FENCE_GATE, 0)); - addCreativeItem(Item.get(Item.FENCE_GATE_SPRUCE, 0)); - addCreativeItem(Item.get(Item.FENCE_GATE_BIRCH, 0)); - addCreativeItem(Item.get(Item.FENCE_GATE_JUNGLE, 0)); - addCreativeItem(Item.get(Item.FENCE_GATE_ACACIA, 0)); - addCreativeItem(Item.get(Item.FENCE_GATE_DARK_OAK, 0)); - addCreativeItem(Item.get(Item.IRON_BARS, 0)); - int[] dyeColors = {0, 8, 7, 15, 12, 14, 1, 4, 5, 13, 9, 3, 11, 10, 2, 6}; - for (int color : dyeColors) { - addCreativeItem(Item.get(Item.BED, color)); - } - addCreativeItem(Item.get(Item.BOOKSHELF, 0)); - addCreativeItem(Item.get(Item.SIGN, 0)); - addCreativeItem(Item.get(Item.PAINTING, 0)); - addCreativeItem(Item.get(Item.ITEM_FRAME, 0)); - addCreativeItem(Item.get(Item.WORKBENCH, 0)); - addCreativeItem(Item.get(Item.STONECUTTER, 0)); - addCreativeItem(Item.get(Item.CHEST, 0)); - addCreativeItem(Item.get(Item.TRAPPED_CHEST, 0)); - addCreativeItem(Item.get(Item.FURNACE, 0)); - addCreativeItem(Item.get(Item.BREWING_STAND, 0)); - addCreativeItem(Item.get(Item.CAULDRON, 0)); - addCreativeItem(Item.get(Item.NOTEBLOCK, 0)); - addCreativeItem(Item.get(Item.END_ROD, 0)); - addCreativeItem(Item.get(Item.END_PORTAL_FRAME, 0)); - addCreativeItem(Item.get(Item.ANVIL, 0)); - addCreativeItem(Item.get(Item.ANVIL, 4)); - addCreativeItem(Item.get(Item.ANVIL, 8)); - addCreativeItem(Item.get(Item.DANDELION, 0)); - addCreativeItem(Item.get(Item.RED_FLOWER, BlockFlower.TYPE_POPPY)); - addCreativeItem(Item.get(Item.RED_FLOWER, BlockFlower.TYPE_BLUE_ORCHID)); - addCreativeItem(Item.get(Item.RED_FLOWER, BlockFlower.TYPE_ALLIUM)); - addCreativeItem(Item.get(Item.RED_FLOWER, BlockFlower.TYPE_AZURE_BLUET)); - addCreativeItem(Item.get(Item.RED_FLOWER, BlockFlower.TYPE_RED_TULIP)); - addCreativeItem(Item.get(Item.RED_FLOWER, BlockFlower.TYPE_ORANGE_TULIP)); - addCreativeItem(Item.get(Item.RED_FLOWER, BlockFlower.TYPE_WHITE_TULIP)); - addCreativeItem(Item.get(Item.RED_FLOWER, BlockFlower.TYPE_PINK_TULIP)); - addCreativeItem(Item.get(Item.RED_FLOWER, BlockFlower.TYPE_OXEYE_DAISY)); - addCreativeItem(Item.get(Item.DOUBLE_PLANT, 0)); // SUNFLOWER - addCreativeItem(Item.get(Item.DOUBLE_PLANT, 1)); // Lilac - addCreativeItem(Item.get(Item.DOUBLE_PLANT, 2)); // Double Tall Grass - addCreativeItem(Item.get(Item.DOUBLE_PLANT, 3)); // Large fern - addCreativeItem(Item.get(Item.DOUBLE_PLANT, 4)); // Rose bush - addCreativeItem(Item.get(Item.DOUBLE_PLANT, 5)); // Peony - addCreativeItem(Item.get(Item.BROWN_MUSHROOM, 0)); - addCreativeItem(Item.get(Item.RED_MUSHROOM, 0)); - addCreativeItem(Item.get(Item.BROWN_MUSHROOM_BLOCK, 14)); - addCreativeItem(Item.get(Item.RED_MUSHROOM_BLOCK, 14)); - addCreativeItem(Item.get(Item.BROWN_MUSHROOM_BLOCK, 0)); - addCreativeItem(Item.get(Item.RED_MUSHROOM_BLOCK, 15)); - addCreativeItem(Item.get(Item.CACTUS, 0)); - addCreativeItem(Item.get(Item.MELON_BLOCK, 0)); - addCreativeItem(Item.get(Item.PUMPKIN, 0)); - addCreativeItem(Item.get(Item.LIT_PUMPKIN, 0)); - addCreativeItem(Item.get(Item.COBWEB, 0)); - addCreativeItem(Item.get(Item.HAY_BALE, 0)); - addCreativeItem(Item.get(Item.TALL_GRASS, 1)); - addCreativeItem(Item.get(Item.TALL_GRASS, 2)); - addCreativeItem(Item.get(Item.DEAD_BUSH, 0)); - addCreativeItem(Item.get(Item.SAPLING, 0)); - addCreativeItem(Item.get(Item.SAPLING, 1)); - addCreativeItem(Item.get(Item.SAPLING, 2)); - addCreativeItem(Item.get(Item.SAPLING, 3)); - addCreativeItem(Item.get(Item.SAPLING, 4)); - addCreativeItem(Item.get(Item.SAPLING, 5)); - addCreativeItem(Item.get(Item.LEAVES, 0)); - addCreativeItem(Item.get(Item.LEAVES, 1)); - addCreativeItem(Item.get(Item.LEAVES, 2)); - addCreativeItem(Item.get(Item.LEAVES, 3)); - addCreativeItem(Item.get(Item.LEAVES2, 0)); - addCreativeItem(Item.get(Item.LEAVES2, 1)); - - addCreativeItem(Item.get(Item.WHITE_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.SILVER_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.GRAY_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.BLACK_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.BROWN_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.RED_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.ORANGE_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.LIME_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.GREEN_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.CYAN_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.LIGHT_BLUE_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.BLUE_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.PURPLE_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.MAGENTA_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.WHITE_GLAZED_TERRACOTTA)); - addCreativeItem(Item.get(Item.PINK_GLAZED_TERRACOTTA)); - - addCreativeItem(Item.get(Item.CAKE, 0)); - - addCreativeItem(Item.get(Item.SKULL, ItemSkull.SKELETON_SKULL)); - addCreativeItem(Item.get(Item.SKULL, ItemSkull.WITHER_SKELETON_SKULL)); - addCreativeItem(Item.get(Item.SKULL, ItemSkull.ZOMBIE_HEAD)); - addCreativeItem(Item.get(Item.SKULL, ItemSkull.HEAD)); - addCreativeItem(Item.get(Item.SKULL, ItemSkull.CREEPER_HEAD)); - addCreativeItem(Item.get(Item.SKULL, ItemSkull.DRAGON_HEAD)); - - addCreativeItem(Item.get(Item.FLOWER_POT, 0)); - - addCreativeItem(Item.get(Item.MONSTER_EGG, 0)); - addCreativeItem(Item.get(Item.MONSTER_EGG, 1)); - addCreativeItem(Item.get(Item.MONSTER_EGG, 2)); - addCreativeItem(Item.get(Item.MONSTER_EGG, 3)); - addCreativeItem(Item.get(Item.MONSTER_EGG, 4)); - addCreativeItem(Item.get(Item.MONSTER_EGG, 5)); - - addCreativeItem(Item.get(Item.DRAGON_EGG, 0)); - addCreativeItem(Item.get(Item.END_CRYSTAL, 0)); - addCreativeItem(Item.get(Item.MONSTER_SPAWNER, 0)); - addCreativeItem(Item.get(Item.ENCHANTMENT_TABLE, 0)); - addCreativeItem(Item.get(Item.SLIME_BLOCK, 0)); - addCreativeItem(Item.get(Item.ENDER_CHEST, 0)); - - for (int color : dyeColors) { - addCreativeItem(Item.get(Item.WOOL, color)); + String path = server.getDataPath() + "creativeitems.json"; + if (!new File(path).exists()) { + try { + Utils.writeFile(path, Server.class.getClassLoader().getResourceAsStream("creativeitems.json")); + } catch (IOException e) { + MainLogger.getLogger().logException(e); + return; + } } + List list = new Config(path, Config.YAML).getMapList("items"); - addCreativeItem(Item.get(Item.CARPET, 0)); - addCreativeItem(Item.get(Item.CARPET, 8)); - addCreativeItem(Item.get(Item.CARPET, 7)); - addCreativeItem(Item.get(Item.CARPET, 15)); - addCreativeItem(Item.get(Item.CARPET, 12)); - addCreativeItem(Item.get(Item.CARPET, 14)); - addCreativeItem(Item.get(Item.CARPET, 1)); - addCreativeItem(Item.get(Item.CARPET, 4)); - addCreativeItem(Item.get(Item.CARPET, 5)); - addCreativeItem(Item.get(Item.CARPET, 13)); - addCreativeItem(Item.get(Item.CARPET, 9)); - addCreativeItem(Item.get(Item.CARPET, 3)); - addCreativeItem(Item.get(Item.CARPET, 11)); - addCreativeItem(Item.get(Item.CARPET, 10)); - addCreativeItem(Item.get(Item.CARPET, 2)); - addCreativeItem(Item.get(Item.CARPET, 6)); - - - //Tools - addCreativeItem(Item.get(Item.RAIL, 0)); - addCreativeItem(Item.get(Item.POWERED_RAIL, 0)); - addCreativeItem(Item.get(Item.DETECTOR_RAIL, 0)); - addCreativeItem(Item.get(Item.ACTIVATOR_RAIL, 0)); - addCreativeItem(Item.get(Item.TORCH, 0)); - addCreativeItem(Item.get(Item.BUCKET, 0)); - addCreativeItem(Item.get(Item.BUCKET, 1)); // milk - addCreativeItem(Item.get(Item.BUCKET, 8)); // water - addCreativeItem(Item.get(Item.BUCKET, 10)); // lava - addCreativeItem(Item.get(Item.TNT, 0)); - addCreativeItem(Item.get(Item.LEAD, 0)); - addCreativeItem(Item.get(Item.NAME_TAG, 0)); - addCreativeItem(Item.get(Item.REDSTONE, 0)); - addCreativeItem(Item.get(Item.BOW, 0)); - addCreativeItem(Item.get(Item.FISHING_ROD, 0)); - addCreativeItem(Item.get(Item.FLINT_AND_STEEL, 0)); - addCreativeItem(Item.get(Item.SHEARS, 0)); - addCreativeItem(Item.get(Item.CLOCK, 0)); - addCreativeItem(Item.get(Item.COMPASS, 0)); - addCreativeItem(Item.get(Item.MINECART, 0)); - addCreativeItem(Item.get(Item.MINECART_WITH_CHEST, 0)); - addCreativeItem(Item.get(Item.MINECART_WITH_HOPPER, 0)); - addCreativeItem(Item.get(Item.MINECART_WITH_TNT, 0)); - addCreativeItem(Item.get(Item.BOAT, 0)); // Oak - addCreativeItem(Item.get(Item.BOAT, 1)); // Spruce - addCreativeItem(Item.get(Item.BOAT, 2)); // Birch - addCreativeItem(Item.get(Item.BOAT, 3)); // Jungle - addCreativeItem(Item.get(Item.BOAT, 4)); // Acacia - addCreativeItem(Item.get(Item.BOAT, 5)); // Dark Oak - addCreativeItem(Item.get(Item.SADDLE, 0)); - addCreativeItem(Item.get(Item.LEATHER_HORSE_ARMOR, 0)); - addCreativeItem(Item.get(Item.IRON_HORSE_ARMOR, 0)); - addCreativeItem(Item.get(Item.GOLD_HORSE_ARMOR, 0)); - addCreativeItem(Item.get(Item.DIAMOND_HORSE_ARMOR, 0)); - - addCreativeItem(Item.get(Item.SPAWN_EGG, 10)); //Chicken - addCreativeItem(Item.get(Item.SPAWN_EGG, 11)); //Cow - addCreativeItem(Item.get(Item.SPAWN_EGG, 12)); //Pig - addCreativeItem(Item.get(Item.SPAWN_EGG, 13)); //Sheep - addCreativeItem(Item.get(Item.SPAWN_EGG, 15)); //Villager - addCreativeItem(Item.get(Item.SPAWN_EGG, 16)); //Mooshroom - addCreativeItem(Item.get(Item.SPAWN_EGG, 17)); //Squid - addCreativeItem(Item.get(Item.SPAWN_EGG, 19)); //Bat - //addCreativeItem(Item.get(Item.SPAWN_EGG, 20)); //Iron Golem - //addCreativeItem(Item.get(Item.SPAWN_EGG, 21)); //Snow Golem - addCreativeItem(Item.get(Item.SPAWN_EGG, 22)); //Ocelot - addCreativeItem(Item.get(Item.SPAWN_EGG, 23)); //Horse - addCreativeItem(Item.get(Item.SPAWN_EGG, 24)); //Donkey - addCreativeItem(Item.get(Item.SPAWN_EGG, 25)); //Mule - addCreativeItem(Item.get(Item.SPAWN_EGG, 26)); //SkeletonHorse - addCreativeItem(Item.get(Item.SPAWN_EGG, 27)); //ZombieHorse - addCreativeItem(Item.get(Item.SPAWN_EGG, 28)); //PolarBear - addCreativeItem(Item.get(Item.SPAWN_EGG, 29)); //Llama - addCreativeItem(Item.get(Item.SPAWN_EGG, 32)); //Zombie - addCreativeItem(Item.get(Item.SPAWN_EGG, 33)); //Creeper - addCreativeItem(Item.get(Item.SPAWN_EGG, 34)); //Skeleton - addCreativeItem(Item.get(Item.SPAWN_EGG, 35)); //Spider - addCreativeItem(Item.get(Item.SPAWN_EGG, 36)); //Zombie Pigman - addCreativeItem(Item.get(Item.SPAWN_EGG, 37)); //Slime - addCreativeItem(Item.get(Item.SPAWN_EGG, 38)); //Enderman - addCreativeItem(Item.get(Item.SPAWN_EGG, 39)); //Silverfish - addCreativeItem(Item.get(Item.SPAWN_EGG, 40)); //Cave spider - addCreativeItem(Item.get(Item.SPAWN_EGG, 41)); //Ghast - addCreativeItem(Item.get(Item.SPAWN_EGG, 42)); //MagmaCube - addCreativeItem(Item.get(Item.SPAWN_EGG, 43)); //Blaze - addCreativeItem(Item.get(Item.SPAWN_EGG, 45)); //Witch - addCreativeItem(Item.get(Item.SPAWN_EGG, 46)); //Stray - addCreativeItem(Item.get(Item.SPAWN_EGG, 47)); //Husk - addCreativeItem(Item.get(Item.SPAWN_EGG, 49)); //Guardian - addCreativeItem(Item.get(Item.SPAWN_EGG, 50)); //ElderGuardian - addCreativeItem(Item.get(Item.SPAWN_EGG, 54)); //Shulker - - addCreativeItem(Item.get(Item.FIRE_CHARGE, 0)); - addCreativeItem(Item.get(Item.WOODEN_SWORD)); - addCreativeItem(Item.get(Item.WOODEN_HOE)); - addCreativeItem(Item.get(Item.WOODEN_SHOVEL)); - addCreativeItem(Item.get(Item.WOODEN_PICKAXE)); - addCreativeItem(Item.get(Item.WOODEN_AXE)); - addCreativeItem(Item.get(Item.STONE_SWORD)); - addCreativeItem(Item.get(Item.STONE_HOE)); - addCreativeItem(Item.get(Item.STONE_SHOVEL)); - addCreativeItem(Item.get(Item.STONE_PICKAXE)); - addCreativeItem(Item.get(Item.STONE_AXE)); - addCreativeItem(Item.get(Item.IRON_SWORD)); - addCreativeItem(Item.get(Item.IRON_HOE)); - addCreativeItem(Item.get(Item.IRON_SHOVEL)); - addCreativeItem(Item.get(Item.IRON_PICKAXE)); - addCreativeItem(Item.get(Item.IRON_AXE)); - addCreativeItem(Item.get(Item.DIAMOND_SWORD)); - addCreativeItem(Item.get(Item.DIAMOND_HOE)); - addCreativeItem(Item.get(Item.DIAMOND_SHOVEL)); - addCreativeItem(Item.get(Item.DIAMOND_PICKAXE)); - addCreativeItem(Item.get(Item.DIAMOND_AXE)); - addCreativeItem(Item.get(Item.GOLD_SWORD)); - addCreativeItem(Item.get(Item.GOLD_HOE)); - addCreativeItem(Item.get(Item.GOLD_SHOVEL)); - addCreativeItem(Item.get(Item.GOLD_PICKAXE)); - addCreativeItem(Item.get(Item.GOLD_AXE)); - addCreativeItem(Item.get(Item.LEATHER_CAP)); - addCreativeItem(Item.get(Item.LEATHER_TUNIC)); - addCreativeItem(Item.get(Item.LEATHER_PANTS)); - addCreativeItem(Item.get(Item.LEATHER_BOOTS)); - addCreativeItem(Item.get(Item.CHAIN_HELMET)); - addCreativeItem(Item.get(Item.CHAIN_CHESTPLATE)); - addCreativeItem(Item.get(Item.CHAIN_LEGGINGS)); - addCreativeItem(Item.get(Item.CHAIN_BOOTS)); - addCreativeItem(Item.get(Item.IRON_HELMET)); - addCreativeItem(Item.get(Item.IRON_CHESTPLATE)); - addCreativeItem(Item.get(Item.IRON_LEGGINGS)); - addCreativeItem(Item.get(Item.IRON_BOOTS)); - addCreativeItem(Item.get(Item.DIAMOND_HELMET)); - addCreativeItem(Item.get(Item.DIAMOND_CHESTPLATE)); - addCreativeItem(Item.get(Item.DIAMOND_LEGGINGS)); - addCreativeItem(Item.get(Item.DIAMOND_BOOTS)); - addCreativeItem(Item.get(Item.GOLD_HELMET)); - addCreativeItem(Item.get(Item.GOLD_CHESTPLATE)); - addCreativeItem(Item.get(Item.GOLD_LEGGINGS)); - addCreativeItem(Item.get(Item.GOLD_BOOTS)); - addCreativeItem(Item.get(Item.ELYTRA)); - addCreativeItem(Item.get(Item.LEVER)); - addCreativeItem(Item.get(Item.REDSTONE_LAMP)); - addCreativeItem(Item.get(Item.REDSTONE_TORCH)); - addCreativeItem(Item.get(Item.WOODEN_PRESSURE_PLATE)); - addCreativeItem(Item.get(Item.STONE_PRESSURE_PLATE)); - addCreativeItem(Item.get(Item.LIGHT_WEIGHTED_PRESSURE_PLATE)); - addCreativeItem(Item.get(Item.HEAVY_WEIGHTED_PRESSURE_PLATE)); - addCreativeItem(Item.get(Item.WOODEN_BUTTON, 5)); - addCreativeItem(Item.get(Item.STONE_BUTTON, 5)); - addCreativeItem(Item.get(Item.DAYLIGHT_DETECTOR)); - addCreativeItem(Item.get(Item.TRIPWIRE_HOOK)); - addCreativeItem(Item.get(Item.REPEATER)); - addCreativeItem(Item.get(Item.COMPARATOR)); - addCreativeItem(Item.get(Item.DISPENSER, 3)); - addCreativeItem(Item.get(Item.DROPPER)); - addCreativeItem(Item.get(Item.PISTON)); - addCreativeItem(Item.get(Item.STICKY_PISTON)); - addCreativeItem(Item.get(Item.OBSERVER)); - addCreativeItem(Item.get(Item.HOPPER)); - addCreativeItem(Item.get(Item.SNOWBALL)); - addCreativeItem(Item.get(Item.ENDER_PEARL)); - addCreativeItem(Item.get(Item.ENDER_EYE)); - - //Seeds - addCreativeItem(Item.get(Item.COAL, 0)); - addCreativeItem(Item.get(Item.COAL, 1)); - addCreativeItem(Item.get(Item.DIAMOND, 0)); - addCreativeItem(Item.get(Item.IRON_INGOT, 0)); - addCreativeItem(Item.get(Item.GOLD_INGOT, 0)); - addCreativeItem(Item.get(Item.EMERALD, 0)); - addCreativeItem(Item.get(Item.STICK, 0)); - addCreativeItem(Item.get(Item.BOWL, 0)); - addCreativeItem(Item.get(Item.STRING, 0)); - addCreativeItem(Item.get(Item.FEATHER, 0)); - addCreativeItem(Item.get(Item.FLINT, 0)); - addCreativeItem(Item.get(Item.LEATHER, 0)); - addCreativeItem(Item.get(Item.RABBIT_HIDE, 0)); - addCreativeItem(Item.get(Item.CLAY, 0)); - addCreativeItem(Item.get(Item.SUGAR, 0)); - addCreativeItem(Item.get(Item.BRICK, 0)); - addCreativeItem(Item.get(Item.NETHER_BRICK, 0)); - addCreativeItem(Item.get(Item.NETHER_QUARTZ, 0)); - addCreativeItem(Item.get(Item.PAPER, 0)); - addCreativeItem(Item.get(Item.BOOK, 0)); - addCreativeItem(Item.get(Item.ARROW, 0)); - addCreativeItem(Item.get(Item.BONE, 0)); - addCreativeItem(Item.get(Item.EMPTY_MAP, 0)); - addCreativeItem(Item.get(Item.SUGARCANE, 0)); - addCreativeItem(Item.get(Item.WHEAT, 0)); - addCreativeItem(Item.get(Item.SEEDS, 0)); - addCreativeItem(Item.get(Item.PUMPKIN_SEEDS, 0)); - addCreativeItem(Item.get(Item.MELON_SEEDS, 0)); - addCreativeItem(Item.get(Item.BEETROOT_SEEDS, 0)); - addCreativeItem(Item.get(Item.EGG, 0)); - addCreativeItem(Item.get(Item.APPLE, 0)); - addCreativeItem(Item.get(Item.GOLDEN_APPLE, 0)); - addCreativeItem(Item.get(Item.GOLDEN_APPLE_ENCHANTED, 0)); - addCreativeItem(Item.get(Item.RAW_FISH, 0)); - addCreativeItem(Item.get(Item.RAW_SALMON, 0)); - addCreativeItem(Item.get(Item.CLOWNFISH, 0)); - addCreativeItem(Item.get(Item.PUFFERFISH, 0)); - addCreativeItem(Item.get(Item.COOKED_FISH, 0)); - addCreativeItem(Item.get(Item.COOKED_SALMON, 0)); - addCreativeItem(Item.get(Item.ROTTEN_FLESH, 0)); - addCreativeItem(Item.get(Item.MUSHROOM_STEW, 0)); - addCreativeItem(Item.get(Item.BREAD, 0)); - addCreativeItem(Item.get(Item.RAW_PORKCHOP, 0)); - addCreativeItem(Item.get(Item.COOKED_PORKCHOP, 0)); - addCreativeItem(Item.get(Item.RAW_CHICKEN, 0)); - addCreativeItem(Item.get(Item.COOKED_CHICKEN, 0)); - addCreativeItem(Item.get(Item.RAW_MUTTON, 0)); - addCreativeItem(Item.get(Item.COOKED_MUTTON, 0)); - addCreativeItem(Item.get(Item.RAW_BEEF, 0)); - addCreativeItem(Item.get(Item.STEAK, 0)); - addCreativeItem(Item.get(Item.MELON, 0)); - addCreativeItem(Item.get(Item.CARROT, 0)); - addCreativeItem(Item.get(Item.POTATO, 0)); - addCreativeItem(Item.get(Item.BAKED_POTATO, 0)); - addCreativeItem(Item.get(Item.POISONOUS_POTATO, 0)); - addCreativeItem(Item.get(Item.BEETROOT, 0)); - addCreativeItem(Item.get(Item.COOKIE, 0)); - addCreativeItem(Item.get(Item.PUMPKIN_PIE, 0)); - addCreativeItem(Item.get(Item.RAW_RABBIT, 0)); - addCreativeItem(Item.get(Item.COOKED_RABBIT, 0)); - addCreativeItem(Item.get(Item.RABBIT_STEW, 0)); - addCreativeItem(Item.get(Item.CHORUS_FRUIT, 0)); - addCreativeItem(Item.get(Item.POPPED_CHORUS_FRUIT, 0)); - addCreativeItem(Item.get(Item.NETHER_STAR, 0)); - addCreativeItem(Item.get(Item.MAGMA_CREAM, 0)); - addCreativeItem(Item.get(Item.BLAZE_ROD, 0)); - addCreativeItem(Item.get(Item.GOLD_NUGGET, 0)); - addCreativeItem(Item.get(Item.GOLDEN_CARROT, 0)); - addCreativeItem(Item.get(Item.GLISTERING_MELON, 0)); - addCreativeItem(Item.get(Item.RABBIT_FOOT, 0)); - addCreativeItem(Item.get(Item.GHAST_TEAR, 0)); - addCreativeItem(Item.get(Item.SLIMEBALL, 0)); - addCreativeItem(Item.get(Item.BLAZE_POWDER, 0)); - addCreativeItem(Item.get(Item.NETHER_WART, 0)); - addCreativeItem(Item.get(Item.GUNPOWDER, 0)); - addCreativeItem(Item.get(Item.GLOWSTONE_DUST, 0)); - addCreativeItem(Item.get(Item.SPIDER_EYE, 0)); - addCreativeItem(Item.get(Item.FERMENTED_SPIDER_EYE, 0)); - addCreativeItem(Item.get(Item.DRAGON_BREATH)); - addCreativeItem(Item.get(Item.CARROT_ON_A_STICK)); - addCreativeItem(Item.get(Item.EXPERIENCE_BOTTLE)); - addCreativeItem(Item.get(Item.SHULKER_SHELL)); - addCreativeItem(Item.get(Item.PRISMARINE_SHARD, 0)); - addCreativeItem(Item.get(Item.PRISMARINE_CRYSTALS, 0)); - for (int color : dyeColors) { - addCreativeItem(Item.get(Item.DYE, color)); + for (Map map : list) { + try { + int id = (int) map.get("id"); + int damage = Utils.toInt(map.getOrDefault("damage", 0D)); + String hex = (String) map.get("nbt_hex"); + byte[] nbt = hex != null ? DatatypeConverter.parseHexBinary(hex) : new byte[0]; + + addCreativeItem(Item.get(id, damage, 1, nbt)); + } catch (Exception e) { + MainLogger.getLogger().logException(e); + } } - - //Potion - addCreativeItem(Item.get(Item.GLASS_BOTTLE, 0)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.NO_EFFECTS)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.MUNDANE)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.MUNDANE_II)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.THICK)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.AWKWARD)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.NIGHT_VISION)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.NIGHT_VISION_LONG)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.INVISIBLE)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.INVISIBLE_LONG)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.LEAPING)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.LEAPING_LONG)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.LEAPING_II)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.FIRE_RESISTANCE)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.FIRE_RESISTANCE_LONG)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.SPEED)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.SPEED_LONG)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.SPEED_II)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.SLOWNESS)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.SLOWNESS_LONG)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.WATER_BREATHING)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.WATER_BREATHING_LONG)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.INSTANT_HEALTH)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.INSTANT_HEALTH_II)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.HARMING)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.HARMING_II)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.POISON)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.POISON_LONG)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.POISON_II)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.REGENERATION)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.REGENERATION_LONG)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.REGENERATION_II)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.STRENGTH)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.STRENGTH_LONG)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.STRENGTH_II)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.WEAKNESS)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.WEAKNESS_LONG)); - addCreativeItem(Item.get(Item.POTION, ItemPotion.DECAY)); - - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.NO_EFFECTS)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.MUNDANE)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.MUNDANE_II)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.THICK)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.AWKWARD)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.NIGHT_VISION)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.NIGHT_VISION_LONG)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.INVISIBLE)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.INVISIBLE_LONG)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.LEAPING)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.LEAPING_LONG)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.LEAPING_II)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.FIRE_RESISTANCE)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.FIRE_RESISTANCE_LONG)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.SPEED)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.SPEED_LONG)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.SPEED_II)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.SLOWNESS)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.SLOWNESS_LONG)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.WATER_BREATHING)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.WATER_BREATHING_LONG)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.INSTANT_HEALTH)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.INSTANT_HEALTH_II)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.HARMING)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.HARMING_II)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.POISON)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.POISON_LONG)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.POISON_II)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.REGENERATION)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.REGENERATION_LONG)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.REGENERATION_II)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.STRENGTH)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.STRENGTH_LONG)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.STRENGTH_II)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.WEAKNESS)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.WEAKNESS_LONG)); - addCreativeItem(Item.get(Item.SPLASH_POTION, ItemPotion.DECAY)); - - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.NO_EFFECTS)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.MUNDANE)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.MUNDANE_II)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.THICK)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.AWKWARD)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.NIGHT_VISION)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.NIGHT_VISION_LONG)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.INVISIBLE)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.INVISIBLE_LONG)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.LEAPING)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.LEAPING_LONG)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.LEAPING_II)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.FIRE_RESISTANCE)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.FIRE_RESISTANCE_LONG)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.SPEED)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.SPEED_LONG)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.SPEED_II)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.SLOWNESS)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.SLOWNESS_LONG)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.WATER_BREATHING)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.WATER_BREATHING_LONG)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.INSTANT_HEALTH)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.INSTANT_HEALTH_II)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.HARMING)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.HARMING_II)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.POISON)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.POISON_LONG)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.POISON_II)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.REGENERATION)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.REGENERATION_LONG)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.REGENERATION_II)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.STRENGTH)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.STRENGTH_LONG)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.STRENGTH_II)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.WEAKNESS)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.WEAKNESS_LONG)); - addCreativeItem(Item.get(Item.LINGERING_POTION, ItemPotion.DECAY)); } public static void clearCreativeItems() { diff --git a/src/main/java/cn/nukkit/item/ItemBookWritten.java b/src/main/java/cn/nukkit/item/ItemBookWritten.java index 7161892853..f4d699b393 100644 --- a/src/main/java/cn/nukkit/item/ItemBookWritten.java +++ b/src/main/java/cn/nukkit/item/ItemBookWritten.java @@ -1,6 +1,5 @@ package cn.nukkit.item; -import cn.nukkit.item.Item; import cn.nukkit.nbt.tag.CompoundTag; import cn.nukkit.nbt.tag.ListTag; @@ -11,54 +10,28 @@ public class ItemBookWritten extends Item { protected boolean isWritten = false; public ItemBookWritten() { - this (Integer.valueOf(0), 1); - } - public ItemBookWritten (String author, String title, String[] pages) { - this (Integer.valueOf(0), 1); - this.writeBook(author, title, pages); - } - public ItemBookWritten (String author, String title, ListTag pages) { - this (Integer.valueOf(0), 1); - this.writeBook(author, title, pages); - } - public ItemBookWritten(Integer meta) { - this (meta, 1); - } - public ItemBookWritten (Integer meta, String author, String title, String[] pages) { - this (meta, 1); - this.writeBook(author, title, pages); - } - public ItemBookWritten (Integer meta, String author, String title, ListTag pages) { - this (meta, 1); - this.writeBook(author, title, pages); + this(0, 1); } + public ItemBookWritten(Integer meta, int count) { - super (Item.WRITTEN_BOOK, Integer.valueOf(0), count, "Book"); - } - public ItemBookWritten (Integer meta, Integer count, String author, String title, String[] pages) { - this (meta, count); - this.writeBook(author, title, pages); - } - public ItemBookWritten (Integer meta, Integer count, String author, String title, ListTag pages) { - this (meta, count); - this.writeBook(author, title, pages); + super(Item.WRITTEN_BOOK, 0, count, "Book"); } - public Item writeBook (String author, String title, String[] pages) { + public Item writeBook(String author, String title, String[] pages) { ListTag pageList = new ListTag<>("pages"); - for (String page : pages){ + for (String page : pages) { pageList.add(new CompoundTag().putString("photoname", "").putString("text", page)); } return writeBook(author, title, pageList); } - public Item writeBook (String author, String title, ListTag pages){ + + public Item writeBook(String author, String title, ListTag pages) { if (pages.size() > 50 || pages.size() <= 0) return this; //Minecraft does not support more than 50 pages if (this.isWritten) return this; //Book content can only be updated once CompoundTag tag; - if (!this.hasCompoundTag()){ + if (!this.hasCompoundTag()) { tag = new CompoundTag(); - } - else { + } else { tag = this.getNamedTag(); } @@ -73,15 +46,18 @@ public Item writeBook (String author, String title, ListTag pages){ this.isWritten = true; return this.setNamedTag(tag); } - public String getAuthor(){ + + public String getAuthor() { if (!this.isWritten) return ""; return this.getNamedTag().getString("author"); } - public String getTitle(){ + + public String getTitle() { if (!this.isWritten) return "Book"; return this.getNamedTag().getString("title"); } - public String[] getPages(){ + + public String[] getPages() { if (!this.isWritten) return new String[0]; ListTag tag = (ListTag) this.getNamedTag().getList("pages"); String[] pages = new String[tag.size()]; @@ -92,5 +68,4 @@ public String[] getPages(){ } return pages; } - -} +} \ No newline at end of file diff --git a/src/main/resources/creativeitems.json b/src/main/resources/creativeitems.json new file mode 100644 index 0000000000..9390ddb4f4 --- /dev/null +++ b/src/main/resources/creativeitems.json @@ -0,0 +1,3352 @@ +{ + "items": [ + { + "id": 5 + }, + { + "id": 5, + "damage": 1 + }, + { + "id": 5, + "damage": 2 + }, + { + "id": 5, + "damage": 3 + }, + { + "id": 5, + "damage": 4 + }, + { + "id": 5, + "damage": 5 + }, + { + "id": 139 + }, + { + "id": 139, + "damage": 1 + }, + { + "id": 85 + }, + { + "id": 85, + "damage": 1 + }, + { + "id": 85, + "damage": 2 + }, + { + "id": 85, + "damage": 3 + }, + { + "id": 85, + "damage": 4 + }, + { + "id": 85, + "damage": 5 + }, + { + "id": 113 + }, + { + "id": 107 + }, + { + "id": 183 + }, + { + "id": 184 + }, + { + "id": 185 + }, + { + "id": 187 + }, + { + "id": 186 + }, + { + "id": 67 + }, + { + "id": 53 + }, + { + "id": 134 + }, + { + "id": 135 + }, + { + "id": 136 + }, + { + "id": 163 + }, + { + "id": 164 + }, + { + "id": 108 + }, + { + "id": 109 + }, + { + "id": 114 + }, + { + "id": 128 + }, + { + "id": 180 + }, + { + "id": 156 + }, + { + "id": 203 + }, + { + "id": 324 + }, + { + "id": 427 + }, + { + "id": 428 + }, + { + "id": 429 + }, + { + "id": 430 + }, + { + "id": 431 + }, + { + "id": 330 + }, + { + "id": 96 + }, + { + "id": 167 + }, + { + "id": 101 + }, + { + "id": 20 + }, + { + "id": 241 + }, + { + "id": 241, + "damage": 8 + }, + { + "id": 241, + "damage": 7 + }, + { + "id": 241, + "damage": 15 + }, + { + "id": 241, + "damage": 12 + }, + { + "id": 241, + "damage": 14 + }, + { + "id": 241, + "damage": 1 + }, + { + "id": 241, + "damage": 4 + }, + { + "id": 241, + "damage": 5 + }, + { + "id": 241, + "damage": 13 + }, + { + "id": 241, + "damage": 9 + }, + { + "id": 241, + "damage": 3 + }, + { + "id": 241, + "damage": 11 + }, + { + "id": 241, + "damage": 10 + }, + { + "id": 241, + "damage": 2 + }, + { + "id": 241, + "damage": 6 + }, + { + "id": 102 + }, + { + "id": 160 + }, + { + "id": 160, + "damage": 8 + }, + { + "id": 160, + "damage": 7 + }, + { + "id": 160, + "damage": 15 + }, + { + "id": 160, + "damage": 12 + }, + { + "id": 160, + "damage": 14 + }, + { + "id": 160, + "damage": 1 + }, + { + "id": 160, + "damage": 4 + }, + { + "id": 160, + "damage": 5 + }, + { + "id": 160, + "damage": 13 + }, + { + "id": 160, + "damage": 9 + }, + { + "id": 160, + "damage": 3 + }, + { + "id": 160, + "damage": 11 + }, + { + "id": 160, + "damage": 10 + }, + { + "id": 160, + "damage": 2 + }, + { + "id": 160, + "damage": 6 + }, + { + "id": 65 + }, + { + "id": 44 + }, + { + "id": 44, + "damage": 3 + }, + { + "id": 158 + }, + { + "id": 158, + "damage": 1 + }, + { + "id": 158, + "damage": 2 + }, + { + "id": 158, + "damage": 3 + }, + { + "id": 158, + "damage": 4 + }, + { + "id": 158, + "damage": 5 + }, + { + "id": 44, + "damage": 4 + }, + { + "id": 44, + "damage": 5 + }, + { + "id": 44, + "damage": 7 + }, + { + "id": 44, + "damage": 1 + }, + { + "id": 182 + }, + { + "id": 44, + "damage": 6 + }, + { + "id": 182, + "damage": 1 + }, + { + "id": 45 + }, + { + "id": 98 + }, + { + "id": 98, + "damage": 1 + }, + { + "id": 98, + "damage": 2 + }, + { + "id": 98, + "damage": 3 + }, + { + "id": 206 + }, + { + "id": 168, + "damage": 2 + }, + { + "id": 112 + }, + { + "id": 215 + }, + { + "id": 4 + }, + { + "id": 48 + }, + { + "id": 406 + }, + { + "id": 24 + }, + { + "id": 24, + "damage": 1 + }, + { + "id": 24, + "damage": 2 + }, + { + "id": 179 + }, + { + "id": 179, + "damage": 1 + }, + { + "id": 179, + "damage": 2 + }, + { + "id": 173 + }, + { + "id": 152 + }, + { + "id": 41 + }, + { + "id": 42 + }, + { + "id": 133 + }, + { + "id": 57 + }, + { + "id": 22 + }, + { + "id": 155 + }, + { + "id": 155, + "damage": 2 + }, + { + "id": 155, + "damage": 1 + }, + { + "id": 168 + }, + { + "id": 168, + "damage": 1 + }, + { + "id": 165 + }, + { + "id": 170 + }, + { + "id": 216 + }, + { + "id": 214 + }, + { + "id": 35 + }, + { + "id": 35, + "damage": 8 + }, + { + "id": 35, + "damage": 7 + }, + { + "id": 35, + "damage": 15 + }, + { + "id": 35, + "damage": 12 + }, + { + "id": 35, + "damage": 14 + }, + { + "id": 35, + "damage": 1 + }, + { + "id": 35, + "damage": 4 + }, + { + "id": 35, + "damage": 5 + }, + { + "id": 35, + "damage": 13 + }, + { + "id": 35, + "damage": 9 + }, + { + "id": 35, + "damage": 3 + }, + { + "id": 35, + "damage": 11 + }, + { + "id": 35, + "damage": 10 + }, + { + "id": 35, + "damage": 2 + }, + { + "id": 35, + "damage": 6 + }, + { + "id": 171 + }, + { + "id": 171, + "damage": 8 + }, + { + "id": 171, + "damage": 7 + }, + { + "id": 171, + "damage": 15 + }, + { + "id": 171, + "damage": 12 + }, + { + "id": 171, + "damage": 14 + }, + { + "id": 171, + "damage": 1 + }, + { + "id": 171, + "damage": 4 + }, + { + "id": 171, + "damage": 5 + }, + { + "id": 171, + "damage": 13 + }, + { + "id": 171, + "damage": 9 + }, + { + "id": 171, + "damage": 3 + }, + { + "id": 171, + "damage": 11 + }, + { + "id": 171, + "damage": 10 + }, + { + "id": 171, + "damage": 2 + }, + { + "id": 171, + "damage": 6 + }, + { + "id": 237 + }, + { + "id": 237, + "damage": 8 + }, + { + "id": 237, + "damage": 7 + }, + { + "id": 237, + "damage": 15 + }, + { + "id": 237, + "damage": 12 + }, + { + "id": 237, + "damage": 14 + }, + { + "id": 237, + "damage": 1 + }, + { + "id": 237, + "damage": 4 + }, + { + "id": 237, + "damage": 5 + }, + { + "id": 237, + "damage": 13 + }, + { + "id": 237, + "damage": 9 + }, + { + "id": 237, + "damage": 3 + }, + { + "id": 237, + "damage": 11 + }, + { + "id": 237, + "damage": 10 + }, + { + "id": 237, + "damage": 2 + }, + { + "id": 237, + "damage": 6 + }, + { + "id": 236 + }, + { + "id": 236, + "damage": 8 + }, + { + "id": 236, + "damage": 7 + }, + { + "id": 236, + "damage": 15 + }, + { + "id": 236, + "damage": 12 + }, + { + "id": 236, + "damage": 14 + }, + { + "id": 236, + "damage": 1 + }, + { + "id": 236, + "damage": 4 + }, + { + "id": 236, + "damage": 5 + }, + { + "id": 236, + "damage": 13 + }, + { + "id": 236, + "damage": 9 + }, + { + "id": 236, + "damage": 3 + }, + { + "id": 236, + "damage": 11 + }, + { + "id": 236, + "damage": 10 + }, + { + "id": 236, + "damage": 2 + }, + { + "id": 236, + "damage": 6 + }, + { + "id": 82 + }, + { + "id": 172 + }, + { + "id": 159 + }, + { + "id": 159, + "damage": 8 + }, + { + "id": 159, + "damage": 7 + }, + { + "id": 159, + "damage": 15 + }, + { + "id": 159, + "damage": 12 + }, + { + "id": 159, + "damage": 14 + }, + { + "id": 159, + "damage": 1 + }, + { + "id": 159, + "damage": 4 + }, + { + "id": 159, + "damage": 5 + }, + { + "id": 159, + "damage": 13 + }, + { + "id": 159, + "damage": 9 + }, + { + "id": 159, + "damage": 3 + }, + { + "id": 159, + "damage": 11 + }, + { + "id": 159, + "damage": 10 + }, + { + "id": 159, + "damage": 2 + }, + { + "id": 159, + "damage": 6 + }, + { + "id": 220 + }, + { + "id": 228 + }, + { + "id": 227 + }, + { + "id": 235 + }, + { + "id": 232 + }, + { + "id": 234 + }, + { + "id": 221 + }, + { + "id": 224 + }, + { + "id": 225 + }, + { + "id": 233 + }, + { + "id": 229 + }, + { + "id": 223 + }, + { + "id": 231 + }, + { + "id": 219 + }, + { + "id": 222 + }, + { + "id": 226 + }, + { + "id": 201 + }, + { + "id": 201, + "damage": 2 + }, + { + "id": 3 + }, + { + "id": 3, + "damage": 1 + }, + { + "id": 2 + }, + { + "id": 243 + }, + { + "id": 110 + }, + { + "id": 1 + }, + { + "id": 15 + }, + { + "id": 14 + }, + { + "id": 56 + }, + { + "id": 21 + }, + { + "id": 73 + }, + { + "id": 16 + }, + { + "id": 129 + }, + { + "id": 153 + }, + { + "id": 13 + }, + { + "id": 1, + "damage": 1 + }, + { + "id": 1, + "damage": 3 + }, + { + "id": 1, + "damage": 5 + }, + { + "id": 1, + "damage": 2 + }, + { + "id": 1, + "damage": 4 + }, + { + "id": 1, + "damage": 6 + }, + { + "id": 12 + }, + { + "id": 12, + "damage": 1 + }, + { + "id": 81 + }, + { + "id": 17 + }, + { + "id": 17, + "damage": 1 + }, + { + "id": 17, + "damage": 2 + }, + { + "id": 17, + "damage": 3 + }, + { + "id": 162 + }, + { + "id": 162, + "damage": 1 + }, + { + "id": 18 + }, + { + "id": 18, + "damage": 1 + }, + { + "id": 18, + "damage": 2 + }, + { + "id": 18, + "damage": 3 + }, + { + "id": 161 + }, + { + "id": 161, + "damage": 1 + }, + { + "id": 6 + }, + { + "id": 6, + "damage": 1 + }, + { + "id": 6, + "damage": 2 + }, + { + "id": 6, + "damage": 3 + }, + { + "id": 6, + "damage": 4 + }, + { + "id": 6, + "damage": 5 + }, + { + "id": 295 + }, + { + "id": 361 + }, + { + "id": 362 + }, + { + "id": 458 + }, + { + "id": 296 + }, + { + "id": 457 + }, + { + "id": 392 + }, + { + "id": 394 + }, + { + "id": 391 + }, + { + "id": 396 + }, + { + "id": 260 + }, + { + "id": 322 + }, + { + "id": 466 + }, + { + "id": 103 + }, + { + "id": 360 + }, + { + "id": 382 + }, + { + "id": 86 + }, + { + "id": 91 + }, + { + "id": 31, + "damage": 2 + }, + { + "id": 175, + "damage": 3 + }, + { + "id": 31, + "damage": 1 + }, + { + "id": 175, + "damage": 2 + }, + { + "id": 37 + }, + { + "id": 38 + }, + { + "id": 38, + "damage": 1 + }, + { + "id": 38, + "damage": 2 + }, + { + "id": 38, + "damage": 3 + }, + { + "id": 38, + "damage": 4 + }, + { + "id": 38, + "damage": 5 + }, + { + "id": 38, + "damage": 6 + }, + { + "id": 38, + "damage": 7 + }, + { + "id": 38, + "damage": 8 + }, + { + "id": 175 + }, + { + "id": 175, + "damage": 1 + }, + { + "id": 175, + "damage": 4 + }, + { + "id": 175, + "damage": 5 + }, + { + "id": 351, + "damage": 7 + }, + { + "id": 351, + "damage": 8 + }, + { + "id": 351 + }, + { + "id": 351, + "damage": 1 + }, + { + "id": 351, + "damage": 14 + }, + { + "id": 351, + "damage": 11 + }, + { + "id": 351, + "damage": 10 + }, + { + "id": 351, + "damage": 2 + }, + { + "id": 351, + "damage": 6 + }, + { + "id": 351, + "damage": 12 + }, + { + "id": 351, + "damage": 4 + }, + { + "id": 351, + "damage": 5 + }, + { + "id": 351, + "damage": 13 + }, + { + "id": 351, + "damage": 9 + }, + { + "id": 351, + "damage": 15 + }, + { + "id": 351, + "damage": 3 + }, + { + "id": 106 + }, + { + "id": 111 + }, + { + "id": 32 + }, + { + "id": 80 + }, + { + "id": 79 + }, + { + "id": 174 + }, + { + "id": 78 + }, + { + "id": 365 + }, + { + "id": 319 + }, + { + "id": 363 + }, + { + "id": 423 + }, + { + "id": 411 + }, + { + "id": 349 + }, + { + "id": 460 + }, + { + "id": 461 + }, + { + "id": 462 + }, + { + "id": 366 + }, + { + "id": 320 + }, + { + "id": 364 + }, + { + "id": 424 + }, + { + "id": 412 + }, + { + "id": 350 + }, + { + "id": 463 + }, + { + "id": 297 + }, + { + "id": 282 + }, + { + "id": 459 + }, + { + "id": 413 + }, + { + "id": 393 + }, + { + "id": 357 + }, + { + "id": 400 + }, + { + "id": 354 + }, + { + "id": 39 + }, + { + "id": 40 + }, + { + "id": 99, + "damage": 14 + }, + { + "id": 100, + "damage": 14 + }, + { + "id": 99, + "damage": 15 + }, + { + "id": 99 + }, + { + "id": 344 + }, + { + "id": 338 + }, + { + "id": 353 + }, + { + "id": 52 + }, + { + "id": 97 + }, + { + "id": 97, + "damage": 1 + }, + { + "id": 97, + "damage": 2 + }, + { + "id": 97, + "damage": 3 + }, + { + "id": 97, + "damage": 4 + }, + { + "id": 97, + "damage": 5 + }, + { + "id": 122 + }, + { + "id": 383, + "damage": 10 + }, + { + "id": 383, + "damage": 11 + }, + { + "id": 383, + "damage": 12 + }, + { + "id": 383, + "damage": 13 + }, + { + "id": 383, + "damage": 14 + }, + { + "id": 383, + "damage": 28 + }, + { + "id": 383, + "damage": 22 + }, + { + "id": 383, + "damage": 16 + }, + { + "id": 383, + "damage": 19 + }, + { + "id": 383, + "damage": 30 + }, + { + "id": 383, + "damage": 18 + }, + { + "id": 383, + "damage": 29 + }, + { + "id": 383, + "damage": 23 + }, + { + "id": 383, + "damage": 24 + }, + { + "id": 383, + "damage": 25 + }, + { + "id": 383, + "damage": 26 + }, + { + "id": 383, + "damage": 27 + }, + { + "id": 383, + "damage": 33 + }, + { + "id": 383, + "damage": 38 + }, + { + "id": 383, + "damage": 39 + }, + { + "id": 383, + "damage": 34 + }, + { + "id": 383, + "damage": 48 + }, + { + "id": 383, + "damage": 46 + }, + { + "id": 383, + "damage": 37 + }, + { + "id": 383, + "damage": 35 + }, + { + "id": 383, + "damage": 32 + }, + { + "id": 383, + "damage": 36 + }, + { + "id": 383, + "damage": 47 + }, + { + "id": 383, + "damage": 17 + }, + { + "id": 383, + "damage": 40 + }, + { + "id": 383, + "damage": 45 + }, + { + "id": 383, + "damage": 49 + }, + { + "id": 383, + "damage": 50 + }, + { + "id": 383, + "damage": 55 + }, + { + "id": 383, + "damage": 42 + }, + { + "id": 383, + "damage": 41 + }, + { + "id": 383, + "damage": 43 + }, + { + "id": 383, + "damage": 54 + }, + { + "id": 383, + "damage": 57 + }, + { + "id": 383, + "damage": 104 + }, + { + "id": 383, + "damage": 105 + }, + { + "id": 383, + "damage": 15 + }, + { + "id": 383, + "damage": 44 + }, + { + "id": 49 + }, + { + "id": 7 + }, + { + "id": 88 + }, + { + "id": 87 + }, + { + "id": 213 + }, + { + "id": 372 + }, + { + "id": 121 + }, + { + "id": 200 + }, + { + "id": 240 + }, + { + "id": 432 + }, + { + "id": 433 + }, + { + "id": 19 + }, + { + "id": 19, + "damage": 1 + }, + { + "id": 367 + }, + { + "id": 352 + }, + { + "id": 30 + }, + { + "id": 298 + }, + { + "id": 302 + }, + { + "id": 306 + }, + { + "id": 314 + }, + { + "id": 310 + }, + { + "id": 299 + }, + { + "id": 303 + }, + { + "id": 307 + }, + { + "id": 315 + }, + { + "id": 311 + }, + { + "id": 300 + }, + { + "id": 304 + }, + { + "id": 308 + }, + { + "id": 316 + }, + { + "id": 312 + }, + { + "id": 301 + }, + { + "id": 305 + }, + { + "id": 309 + }, + { + "id": 317 + }, + { + "id": 313 + }, + { + "id": 329 + }, + { + "id": 416 + }, + { + "id": 417 + }, + { + "id": 418 + }, + { + "id": 419 + }, + { + "id": 444 + }, + { + "id": 268 + }, + { + "id": 272 + }, + { + "id": 267 + }, + { + "id": 283 + }, + { + "id": 276 + }, + { + "id": 271 + }, + { + "id": 275 + }, + { + "id": 258 + }, + { + "id": 286 + }, + { + "id": 279 + }, + { + "id": 270 + }, + { + "id": 274 + }, + { + "id": 257 + }, + { + "id": 285 + }, + { + "id": 278 + }, + { + "id": 269 + }, + { + "id": 273 + }, + { + "id": 256 + }, + { + "id": 284 + }, + { + "id": 277 + }, + { + "id": 290 + }, + { + "id": 291 + }, + { + "id": 292 + }, + { + "id": 294 + }, + { + "id": 293 + }, + { + "id": 261 + }, + { + "id": 262 + }, + { + "id": 262, + "damage": 6 + }, + { + "id": 262, + "damage": 7 + }, + { + "id": 262, + "damage": 8 + }, + { + "id": 262, + "damage": 9 + }, + { + "id": 262, + "damage": 10 + }, + { + "id": 262, + "damage": 11 + }, + { + "id": 262, + "damage": 12 + }, + { + "id": 262, + "damage": 13 + }, + { + "id": 262, + "damage": 14 + }, + { + "id": 262, + "damage": 15 + }, + { + "id": 262, + "damage": 16 + }, + { + "id": 262, + "damage": 17 + }, + { + "id": 262, + "damage": 18 + }, + { + "id": 262, + "damage": 19 + }, + { + "id": 262, + "damage": 20 + }, + { + "id": 262, + "damage": 21 + }, + { + "id": 262, + "damage": 22 + }, + { + "id": 262, + "damage": 23 + }, + { + "id": 262, + "damage": 24 + }, + { + "id": 262, + "damage": 25 + }, + { + "id": 262, + "damage": 26 + }, + { + "id": 262, + "damage": 27 + }, + { + "id": 262, + "damage": 28 + }, + { + "id": 262, + "damage": 29 + }, + { + "id": 262, + "damage": 30 + }, + { + "id": 262, + "damage": 31 + }, + { + "id": 262, + "damage": 32 + }, + { + "id": 262, + "damage": 33 + }, + { + "id": 262, + "damage": 34 + }, + { + "id": 262, + "damage": 35 + }, + { + "id": 262, + "damage": 36 + }, + { + "id": 262, + "damage": 37 + }, + { + "id": 346 + }, + { + "id": 398 + }, + { + "id": 332 + }, + { + "id": 359 + }, + { + "id": 259 + }, + { + "id": 450 + }, + { + "id": 374 + }, + { + "id": 384 + }, + { + "id": 373 + }, + { + "id": 373, + "damage": 1 + }, + { + "id": 373, + "damage": 2 + }, + { + "id": 373, + "damage": 3 + }, + { + "id": 373, + "damage": 4 + }, + { + "id": 373, + "damage": 5 + }, + { + "id": 373, + "damage": 6 + }, + { + "id": 373, + "damage": 7 + }, + { + "id": 373, + "damage": 8 + }, + { + "id": 373, + "damage": 9 + }, + { + "id": 373, + "damage": 10 + }, + { + "id": 373, + "damage": 11 + }, + { + "id": 373, + "damage": 12 + }, + { + "id": 373, + "damage": 13 + }, + { + "id": 373, + "damage": 14 + }, + { + "id": 373, + "damage": 15 + }, + { + "id": 373, + "damage": 16 + }, + { + "id": 373, + "damage": 17 + }, + { + "id": 373, + "damage": 18 + }, + { + "id": 373, + "damage": 19 + }, + { + "id": 373, + "damage": 20 + }, + { + "id": 373, + "damage": 21 + }, + { + "id": 373, + "damage": 22 + }, + { + "id": 373, + "damage": 23 + }, + { + "id": 373, + "damage": 24 + }, + { + "id": 373, + "damage": 25 + }, + { + "id": 373, + "damage": 26 + }, + { + "id": 373, + "damage": 27 + }, + { + "id": 373, + "damage": 28 + }, + { + "id": 373, + "damage": 29 + }, + { + "id": 373, + "damage": 30 + }, + { + "id": 373, + "damage": 31 + }, + { + "id": 373, + "damage": 32 + }, + { + "id": 373, + "damage": 33 + }, + { + "id": 373, + "damage": 34 + }, + { + "id": 373, + "damage": 35 + }, + { + "id": 373, + "damage": 36 + }, + { + "id": 438 + }, + { + "id": 438, + "damage": 1 + }, + { + "id": 438, + "damage": 2 + }, + { + "id": 438, + "damage": 3 + }, + { + "id": 438, + "damage": 4 + }, + { + "id": 438, + "damage": 5 + }, + { + "id": 438, + "damage": 6 + }, + { + "id": 438, + "damage": 7 + }, + { + "id": 438, + "damage": 8 + }, + { + "id": 438, + "damage": 9 + }, + { + "id": 438, + "damage": 10 + }, + { + "id": 438, + "damage": 11 + }, + { + "id": 438, + "damage": 12 + }, + { + "id": 438, + "damage": 13 + }, + { + "id": 438, + "damage": 14 + }, + { + "id": 438, + "damage": 15 + }, + { + "id": 438, + "damage": 16 + }, + { + "id": 438, + "damage": 17 + }, + { + "id": 438, + "damage": 18 + }, + { + "id": 438, + "damage": 19 + }, + { + "id": 438, + "damage": 20 + }, + { + "id": 438, + "damage": 21 + }, + { + "id": 438, + "damage": 22 + }, + { + "id": 438, + "damage": 23 + }, + { + "id": 438, + "damage": 24 + }, + { + "id": 438, + "damage": 25 + }, + { + "id": 438, + "damage": 26 + }, + { + "id": 438, + "damage": 27 + }, + { + "id": 438, + "damage": 28 + }, + { + "id": 438, + "damage": 29 + }, + { + "id": 438, + "damage": 30 + }, + { + "id": 438, + "damage": 31 + }, + { + "id": 438, + "damage": 32 + }, + { + "id": 438, + "damage": 33 + }, + { + "id": 438, + "damage": 34 + }, + { + "id": 438, + "damage": 35 + }, + { + "id": 438, + "damage": 36 + }, + { + "id": 441 + }, + { + "id": 441, + "damage": 1 + }, + { + "id": 441, + "damage": 2 + }, + { + "id": 441, + "damage": 3 + }, + { + "id": 441, + "damage": 4 + }, + { + "id": 441, + "damage": 5 + }, + { + "id": 441, + "damage": 6 + }, + { + "id": 441, + "damage": 7 + }, + { + "id": 441, + "damage": 8 + }, + { + "id": 441, + "damage": 9 + }, + { + "id": 441, + "damage": 10 + }, + { + "id": 441, + "damage": 11 + }, + { + "id": 441, + "damage": 12 + }, + { + "id": 441, + "damage": 13 + }, + { + "id": 441, + "damage": 14 + }, + { + "id": 441, + "damage": 15 + }, + { + "id": 441, + "damage": 16 + }, + { + "id": 441, + "damage": 17 + }, + { + "id": 441, + "damage": 18 + }, + { + "id": 441, + "damage": 19 + }, + { + "id": 441, + "damage": 20 + }, + { + "id": 441, + "damage": 21 + }, + { + "id": 441, + "damage": 22 + }, + { + "id": 441, + "damage": 23 + }, + { + "id": 441, + "damage": 24 + }, + { + "id": 441, + "damage": 25 + }, + { + "id": 441, + "damage": 26 + }, + { + "id": 441, + "damage": 27 + }, + { + "id": 441, + "damage": 28 + }, + { + "id": 441, + "damage": 29 + }, + { + "id": 441, + "damage": 30 + }, + { + "id": 441, + "damage": 31 + }, + { + "id": 441, + "damage": 32 + }, + { + "id": 441, + "damage": 33 + }, + { + "id": 441, + "damage": 34 + }, + { + "id": 441, + "damage": 35 + }, + { + "id": 441, + "damage": 36 + }, + { + "id": 280 + }, + { + "id": 355 + }, + { + "id": 355, + "damage": 8 + }, + { + "id": 355, + "damage": 7 + }, + { + "id": 355, + "damage": 15 + }, + { + "id": 355, + "damage": 12 + }, + { + "id": 355, + "damage": 14 + }, + { + "id": 355, + "damage": 1 + }, + { + "id": 355, + "damage": 4 + }, + { + "id": 355, + "damage": 5 + }, + { + "id": 355, + "damage": 13 + }, + { + "id": 355, + "damage": 9 + }, + { + "id": 355, + "damage": 3 + }, + { + "id": 355, + "damage": 11 + }, + { + "id": 355, + "damage": 10 + }, + { + "id": 355, + "damage": 2 + }, + { + "id": 355, + "damage": 6 + }, + { + "id": 50 + }, + { + "id": 76 + }, + { + "id": 123 + }, + { + "id": 169 + }, + { + "id": 89 + }, + { + "id": 348 + }, + { + "id": 323 + }, + { + "id": 321 + }, + { + "id": 389 + }, + { + "id": 390 + }, + { + "id": 281 + }, + { + "id": 425 + }, + { + "id": 58 + }, + { + "id": 61 + }, + { + "id": 379 + }, + { + "id": 380 + }, + { + "id": 145 + }, + { + "id": 145, + "damage": 1 + }, + { + "id": 145, + "damage": 2 + }, + { + "id": 245 + }, + { + "id": 54 + }, + { + "id": 146 + }, + { + "id": 130 + }, + { + "id": 205, + "damage": 16 + }, + { + "id": 218 + }, + { + "id": 218, + "damage": 8 + }, + { + "id": 218, + "damage": 7 + }, + { + "id": 218, + "damage": 15 + }, + { + "id": 218, + "damage": 12 + }, + { + "id": 218, + "damage": 14 + }, + { + "id": 218, + "damage": 1 + }, + { + "id": 218, + "damage": 4 + }, + { + "id": 218, + "damage": 5 + }, + { + "id": 218, + "damage": 13 + }, + { + "id": 218, + "damage": 9 + }, + { + "id": 218, + "damage": 3 + }, + { + "id": 218, + "damage": 11 + }, + { + "id": 218, + "damage": 10 + }, + { + "id": 218, + "damage": 2 + }, + { + "id": 218, + "damage": 6 + }, + { + "id": 47 + }, + { + "id": 116 + }, + { + "id": 25 + }, + { + "id": 84 + }, + { + "id": 500 + }, + { + "id": 501 + }, + { + "id": 502 + }, + { + "id": 503 + }, + { + "id": 504 + }, + { + "id": 505 + }, + { + "id": 506 + }, + { + "id": 507 + }, + { + "id": 508 + }, + { + "id": 509 + }, + { + "id": 510 + }, + { + "id": 511 + }, + { + "id": 397, + "damage": 3 + }, + { + "id": 397, + "damage": 2 + }, + { + "id": 397, + "damage": 4 + }, + { + "id": 397, + "damage": 5 + }, + { + "id": 397 + }, + { + "id": 397, + "damage": 1 + }, + { + "id": 138 + }, + { + "id": 151 + }, + { + "id": 120 + }, + { + "id": 287 + }, + { + "id": 325 + }, + { + "id": 325, + "damage": 1 + }, + { + "id": 325, + "damage": 8 + }, + { + "id": 325, + "damage": 10 + }, + { + "id": 288 + }, + { + "id": 318 + }, + { + "id": 289 + }, + { + "id": 334 + }, + { + "id": 415 + }, + { + "id": 414 + }, + { + "id": 452 + }, + { + "id": 371 + }, + { + "id": 385 + }, + { + "id": 377 + }, + { + "id": 369 + }, + { + "id": 378 + }, + { + "id": 375 + }, + { + "id": 376 + }, + { + "id": 437 + }, + { + "id": 445 + }, + { + "id": 370 + }, + { + "id": 341 + }, + { + "id": 368 + }, + { + "id": 381 + }, + { + "id": 399 + }, + { + "id": 208 + }, + { + "id": 426 + }, + { + "id": 339 + }, + { + "id": 395 + }, + { + "id": 395, + "damage": 2 + }, + { + "id": 386 + }, + { + "id": 340 + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696400000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696400000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696400000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696400000203006c766c04000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696401000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696401000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696401000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696401000203006c766c04000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696402000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696402000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696402000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696402000203006c766c04000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696403000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696403000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696403000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696403000203006c766c04000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696404000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696404000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696404000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696404000203006c766c04000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696405000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696405000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696405000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696406000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696406000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696406000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696407000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696407000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696407000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696408000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696409000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696409000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696409000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696409000203006c766c04000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696409000203006c766c05000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640a000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640a000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640a000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640a000203006c766c04000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640a000203006c766c05000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640b000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640b000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640b000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640b000203006c766c04000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640b000203006c766c05000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640c000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640c000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640d000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640d000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640e000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640e000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640e000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640f000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640f000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640f000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640f000203006c766c04000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069640f000203006c766c05000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696410000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696411000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696411000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696411000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696412000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696412000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696412000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696413000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696413000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696413000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696413000203006c766c04000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696413000203006c766c05000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696414000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696414000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696415000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696416000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696417000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696417000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696417000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696418000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696418000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696418000203006c766c03000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696419000203006c766c01000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a01000000020200696419000203006c766c02000000" + }, + { + "id": 403, + "nbt_hex": "0a0000090400656e63680a0100000002020069641a000203006c766c01000000" + }, + { + "id": 333 + }, + { + "id": 333, + "damage": 1 + }, + { + "id": 333, + "damage": 2 + }, + { + "id": 333, + "damage": 3 + }, + { + "id": 333, + "damage": 4 + }, + { + "id": 333, + "damage": 5 + }, + { + "id": 66 + }, + { + "id": 27 + }, + { + "id": 28 + }, + { + "id": 126 + }, + { + "id": 328 + }, + { + "id": 342 + }, + { + "id": 408 + }, + { + "id": 407 + }, + { + "id": 69 + }, + { + "id": 143, + "damage": 5 + }, + { + "id": 77, + "damage": 5 + }, + { + "id": 410 + }, + { + "id": 125, + "damage": 3 + }, + { + "id": 23, + "damage": 3 + }, + { + "id": 33, + "damage": 1 + }, + { + "id": 29, + "damage": 1 + }, + { + "id": 251 + }, + { + "id": 356 + }, + { + "id": 404 + }, + { + "id": 131 + }, + { + "id": 72 + }, + { + "id": 70 + }, + { + "id": 147 + }, + { + "id": 148 + }, + { + "id": 331 + }, + { + "id": 263 + }, + { + "id": 263, + "damage": 1 + }, + { + "id": 264 + }, + { + "id": 265 + }, + { + "id": 266 + }, + { + "id": 388 + }, + { + "id": 336 + }, + { + "id": 405 + }, + { + "id": 337 + }, + { + "id": 409 + }, + { + "id": 422 + }, + { + "id": 46 + }, + { + "id": 420 + }, + { + "id": 421 + }, + { + "id": 347 + }, + { + "id": 345 + }, + { + "id": 446 + }, + { + "id": 446, + "damage": 8 + }, + { + "id": 446, + "damage": 7 + }, + { + "id": 446, + "damage": 15 + }, + { + "id": 446, + "damage": 12 + }, + { + "id": 446, + "damage": 14 + }, + { + "id": 446, + "damage": 1 + }, + { + "id": 446, + "damage": 4 + }, + { + "id": 446, + "damage": 5 + }, + { + "id": 446, + "damage": 13 + }, + { + "id": 446, + "damage": 9 + }, + { + "id": 446, + "damage": 3 + }, + { + "id": 446, + "damage": 11 + }, + { + "id": 446, + "damage": 10 + }, + { + "id": 446, + "damage": 2 + }, + { + "id": 446, + "damage": 6 + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730000000000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f720100000000070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f720100000008070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f720100000007070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f72010000000f070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f72010000000c070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f72010000000e070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f720100000001070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f720100000004070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f720100000005070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f72010000000d070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f720100000009070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f720100000003070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f72010000000b070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f72010000000a070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f720100000002070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 401, + "nbt_hex": "0a00000a090046697265776f726b73090a004578706c6f73696f6e730a01000000070d0046697265776f726b436f6c6f720100000006070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000010600466c69676874010000" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f720100000000070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72211d1dff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f720100000008070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72524f47ff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f720100000007070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72979d9dff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f72010000000f070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72f0f0f0ff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f72010000000c070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72dab33aff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f72010000000e070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f721d80f9ff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f720100000001070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72262eb0ff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f720100000004070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72aa443cff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f720100000005070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72b83289ff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f72010000000d070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72bd4ec7ff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f720100000009070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72aa8bf3ff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f720100000003070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72325483ff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f72010000000b070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f723dd8feff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f72010000000a070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f721fc780ff00" + }, + { + "id": 402, + "c": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f720100000002070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f72167c5eff00" + }, + { + "id": 402, + "nbt_hex": "0a00000a0d0046697265776f726b734974656d070d0046697265776f726b436f6c6f720100000006070c0046697265776f726b4661646500000000010f0046697265776f726b466c69636b657200010d0046697265776f726b547261696c00010c0046697265776f726b547970650000030b00637573746f6d436f6c6f729c9c16ff00" + } + ] +} \ No newline at end of file From 75ce3d3ff7d32a43eaf60049f99d7e831267f9e2 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 1 Oct 2017 13:33:59 +0200 Subject: [PATCH 120/175] fix --- src/main/java/cn/nukkit/item/Item.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java index 6932c11a2b..9ebf5b52f3 100644 --- a/src/main/java/cn/nukkit/item/Item.java +++ b/src/main/java/cn/nukkit/item/Item.java @@ -846,7 +846,7 @@ private static void initCreativeItems() { for (Map map : list) { try { int id = (int) map.get("id"); - int damage = Utils.toInt(map.getOrDefault("damage", 0D)); + int damage = (int) map.getOrDefault("damage", 0); String hex = (String) map.get("nbt_hex"); byte[] nbt = hex != null ? DatatypeConverter.parseHexBinary(hex) : new byte[0]; From eb2687f89d40fe5a75568e50cb739e8b2fbe2d94 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 1 Oct 2017 15:03:46 +0200 Subject: [PATCH 121/175] Fixed client-side item movement handling --- README.md | 6 ++++++ src/main/java/cn/nukkit/entity/item/EntityItem.java | 1 + 2 files changed, 7 insertions(+) diff --git a/README.md b/README.md index 220403d2cc..a4a327878b 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,12 @@ It has a few key advantages over other server software: Nukkit is **under improvement** yet, we welcome contributions. +Example servers running Nukkit +-------------------- +- **play.EaseCation.com** +- **play.GameTeam.cz** +- **MultiLabs.net** + Get Nukkit & Plugins -------------------- diff --git a/src/main/java/cn/nukkit/entity/item/EntityItem.java b/src/main/java/cn/nukkit/entity/item/EntityItem.java index c43b88025c..4fbca75fa9 100644 --- a/src/main/java/cn/nukkit/entity/item/EntityItem.java +++ b/src/main/java/cn/nukkit/entity/item/EntityItem.java @@ -100,6 +100,7 @@ protected void initEntity() { } this.item = NBTIO.getItemHelper(this.namedTag.getCompound("Item")); + this.setDataFlag(DATA_FLAGS, DATA_FLAG_IMMOBILE, true); this.server.getPluginManager().callEvent(new ItemSpawnEvent(this)); } From 9d2e220e41bc481abd46b483e732fea4cfd8e05d Mon Sep 17 00:00:00 2001 From: boybook Date: Sun, 1 Oct 2017 22:55:03 +0800 Subject: [PATCH 122/175] EaseCation.net --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a4a327878b..1c2c1410c9 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Nukkit is **under improvement** yet, we welcome contributions. Example servers running Nukkit -------------------- -- **play.EaseCation.com** +- **play.EaseCation.net** - **play.GameTeam.cz** - **MultiLabs.net** From 1b78b3bee516aa568dfdbf87b6fdfc73f18b9d27 Mon Sep 17 00:00:00 2001 From: boybook Date: Mon, 2 Oct 2017 00:39:16 +0800 Subject: [PATCH 123/175] Careless? Multiple equipItem and call event two times. --- src/main/java/cn/nukkit/Player.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 5384f155d6..61bcb349e9 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2192,7 +2192,6 @@ public void handleDataPacket(DataPacket packet) { this.setDataFlag(Player.DATA_FLAGS, Player.DATA_FLAG_ACTION, false); - this.inventory.equipItem(mobEquipmentPacket.hotbarSlot); break; case ProtocolInfo.PLAYER_ACTION_PACKET: PlayerActionPacket playerActionPacket = (PlayerActionPacket) packet; From 9bb3fc58a4acfc42f900b8d91f76884c78f4fc65 Mon Sep 17 00:00:00 2001 From: Sam Ezeh Date: Mon, 2 Oct 2017 04:33:38 +0100 Subject: [PATCH 124/175] Allows for the log level to be changed (#1908) Close #1869 --- src/main/java/cn/nukkit/Nukkit.java | 33 ++++++++++++++- src/main/java/cn/nukkit/utils/LogLevel.java | 10 ++++- src/main/java/cn/nukkit/utils/MainLogger.java | 41 +++++++++++-------- 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/main/java/cn/nukkit/Nukkit.java b/src/main/java/cn/nukkit/Nukkit.java index 435374a0a4..03ec56f906 100644 --- a/src/main/java/cn/nukkit/Nukkit.java +++ b/src/main/java/cn/nukkit/Nukkit.java @@ -2,9 +2,14 @@ import cn.nukkit.command.CommandReader; import cn.nukkit.network.protocol.ProtocolInfo; +import cn.nukkit.utils.LogLevel; import cn.nukkit.utils.MainLogger; import cn.nukkit.utils.ServerKiller; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + /** * `_ _ _ _ _ _ * | \ | | | | | | (_) | @@ -50,16 +55,42 @@ public static void main(String[] args) { } } + LogLevel logLevel = LogLevel.DEFAULT_LEVEL; + int index = -1; + boolean skip = false; //启动参数 for (String arg : args) { + index++; + if (skip) { + skip = false; + continue; + } + switch (arg) { case "disable-ansi": ANSI = false; break; + + case "--verbosity": + case "-v": + skip = true; + try { + String levelName = args[index + 1]; + Set levelNames = Arrays.stream(LogLevel.values()).map(level -> level.name().toLowerCase()).collect(Collectors.toSet()); + if (!levelNames.contains(levelName.toLowerCase())) { + System.out.printf("'%s' is not a valid log level, using the default\n", levelName); + continue; + } + logLevel = Arrays.stream(LogLevel.values()).filter(level -> level.name().equalsIgnoreCase(levelName)).findAny().orElse(LogLevel.DEFAULT_LEVEL); + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println("You must enter the requested log level, using the default\n"); + } + } } - MainLogger logger = new MainLogger(DATA_PATH + "server.log"); + MainLogger logger = new MainLogger(DATA_PATH + "server.log", logLevel); + System.out.printf("Using log level '%s'\n", logLevel); try { if (ANSI) { diff --git a/src/main/java/cn/nukkit/utils/LogLevel.java b/src/main/java/cn/nukkit/utils/LogLevel.java index 9a674f6431..c883031763 100644 --- a/src/main/java/cn/nukkit/utils/LogLevel.java +++ b/src/main/java/cn/nukkit/utils/LogLevel.java @@ -4,7 +4,8 @@ * author: MagicDroidX * Nukkit Project */ -public enum LogLevel { +public enum LogLevel implements Comparable { + NONE, EMERGENCY, ALERT, CRITICAL, @@ -12,5 +13,10 @@ public enum LogLevel { WARNING, NOTICE, INFO, - DEBUG + DEBUG; + public static final LogLevel DEFAULT_LEVEL = INFO; + + int getLevel() { + return ordinal(); + } } diff --git a/src/main/java/cn/nukkit/utils/MainLogger.java b/src/main/java/cn/nukkit/utils/MainLogger.java index 0934f0afe8..0704e489e1 100644 --- a/src/main/java/cn/nukkit/utils/MainLogger.java +++ b/src/main/java/cn/nukkit/utils/MainLogger.java @@ -22,75 +22,84 @@ public class MainLogger extends ThreadedLogger { protected final String logPath; protected final ConcurrentLinkedQueue logBuffer = new ConcurrentLinkedQueue<>(); protected boolean shutdown; - protected boolean logDebug = false; + protected LogLevel logLevel = LogLevel.DEFAULT_LEVEL; private final Map replacements = new EnumMap<>(TextFormat.class); private final TextFormat[] colors = TextFormat.values(); protected static MainLogger logger; public MainLogger(String logFile) { - this(logFile, false); + this(logFile, LogLevel.DEFAULT_LEVEL); } - public MainLogger(String logFile, boolean logDebug) { + public MainLogger(String logFile, LogLevel logLevel) { + if (logger != null) { throw new RuntimeException("MainLogger has been already created"); } logger = this; this.logPath = logFile; - this.logDebug = logDebug; this.start(); } + public MainLogger(String logFile, boolean logDebug) { + this(logFile, logDebug ? LogLevel.DEBUG : LogLevel.INFO); + } + public static MainLogger getLogger() { return logger; } @Override public void emergency(String message) { - this.send(TextFormat.RED + "[EMERGENCY] " + message); + if (logLevel.getLevel() <= LogLevel.EMERGENCY.getLevel()) + this.send(TextFormat.RED + "[EMERGENCY] " + message); } @Override public void alert(String message) { - this.send(TextFormat.RED + "[ALERT] " + message); + if (logLevel.getLevel() <= LogLevel.ALERT.getLevel()) + this.send(TextFormat.RED + "[ALERT] " + message); } @Override public void critical(String message) { - this.send(TextFormat.RED + "[CRITICAL] " + message); + if (logLevel.getLevel() <= LogLevel.CRITICAL.getLevel()) + this.send(TextFormat.RED + "[CRITICAL] " + message); } @Override public void error(String message) { - this.send(TextFormat.DARK_RED + "[ERROR] " + message); + if (logLevel.getLevel() <= LogLevel.ERROR.getLevel()) + this.send(TextFormat.DARK_RED + "[ERROR] " + message); } @Override public void warning(String message) { - this.send(TextFormat.YELLOW + "[WARNING] " + message); + if (logLevel.getLevel() <= LogLevel.WARNING.getLevel()) + this.send(TextFormat.YELLOW + "[WARNING] " + message); } @Override public void notice(String message) { - this.send(TextFormat.AQUA + "[NOTICE] " + message); + if (logLevel.getLevel() <= LogLevel.NOTICE.getLevel()) + this.send(TextFormat.AQUA + "[NOTICE] " + message); } @Override public void info(String message) { - this.send(TextFormat.WHITE + "[INFO] " + message); + if (logLevel.getLevel() <= LogLevel.INFO.getLevel()) + this.send(TextFormat.WHITE + "[INFO] " + message); } @Override public void debug(String message) { - if (!this.logDebug) { - return; - } - this.send(TextFormat.GRAY + "[DEBUG] " + message); + if (logLevel.getLevel() <= LogLevel.DEBUG.getLevel()) + this.send(TextFormat.GRAY + "[DEBUG] " + message); } public void setLogDebug(Boolean logDebug) { - this.logDebug = logDebug; + this.logLevel = logDebug ? LogLevel.INFO : LogLevel.DEBUG; } public void logException(Exception e) { From 99a9e6847b78ae800c5984c78bccc8f28d41ab08 Mon Sep 17 00:00:00 2001 From: boybook Date: Tue, 3 Oct 2017 01:27:32 +0800 Subject: [PATCH 125/175] Fix AdventureSettings not works! WFT we forgot reset() (put packet ID!!!!!!) --- .../java/cn/nukkit/network/protocol/AdventureSettingsPacket.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/cn/nukkit/network/protocol/AdventureSettingsPacket.java b/src/main/java/cn/nukkit/network/protocol/AdventureSettingsPacket.java index c46520cf0c..16c3ff6802 100644 --- a/src/main/java/cn/nukkit/network/protocol/AdventureSettingsPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/AdventureSettingsPacket.java @@ -60,6 +60,7 @@ public void decode() { } public void encode() { + this.reset(); this.putUnsignedVarInt(this.flags); this.putUnsignedVarInt(this.commandPermission); this.putUnsignedVarInt(this.flags2); From 2c239c7107a501f86d6185f2f155d2c055a573eb Mon Sep 17 00:00:00 2001 From: boybook Date: Tue, 3 Oct 2017 03:14:09 +0800 Subject: [PATCH 126/175] Remove old messageQueue, add player.sendChat() --- src/main/java/cn/nukkit/Player.java | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 61bcb349e9..9a93dce52f 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -1645,15 +1645,6 @@ public boolean onUpdate(int currentTick) { this.checkTeleportPosition(); this.checkInteractNearby(); - // TODO: remove this workaround (broken client MCPE 1.0.0) - if (!messageQueue.isEmpty()) { - TextPacket pk = new TextPacket(); - pk.type = TextPacket.TYPE_RAW; - pk.message = String.join("\n", messageQueue); - this.dataPacket(pk); - messageQueue.clear(); - } - if (this.spawned && this.dummyBossBars.size() > 0 && currentTick % 100 == 0) { this.dummyBossBars.values().forEach(DummyBossBar::updateBossEntityPosition); } @@ -1724,8 +1715,6 @@ private EntityInteractable getEntityAtPosition(Entity[] nearbyEntities, int x, i return null; } - private ArrayList messageQueue = new ArrayList<>(); - public void checkNetwork() { if (!this.isOnline()) { return; @@ -3298,15 +3287,10 @@ public boolean kick(PlayerKickEvent.Reason reason, String reasonString, boolean @Override public void sendMessage(String message) { - // TODO: Remove this workaround (broken client MCPE 1.0.0) - messageQueue.add(this.server.getLanguage().translateString(message)); - - /* TextPacket pk = new TextPacket(); pk.type = TextPacket.TYPE_RAW; pk.message = this.server.getLanguage().translateString(message); this.dataPacket(pk); - */ } @Override @@ -3339,6 +3323,18 @@ public void sendTranslation(String message, String[] parameters) { this.dataPacket(pk); } + public void sendChat(String message) { + this.sendChat("", message); + } + + public void sendChat(String source, String message) { + TextPacket pk = new TextPacket(); + pk.type = TextPacket.TYPE_CHAT; + pk.source = source; + pk.message = this.server.getLanguage().translateString(message); + this.dataPacket(pk); + } + public void sendPopup(String message) { this.sendPopup(message, ""); } From 5b8f6a0222b35f45ebc938d508e9b44a51f862ea Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 5 Oct 2017 08:15:51 +0200 Subject: [PATCH 127/175] Changed ArrayList to List --- src/main/java/cn/nukkit/AdventureSettings.java | 5 ++--- src/main/java/cn/nukkit/form/element/ElementDropdown.java | 7 ++++--- .../java/cn/nukkit/form/element/ElementStepSlider.java | 7 ++++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/cn/nukkit/AdventureSettings.java b/src/main/java/cn/nukkit/AdventureSettings.java index a101853c91..39fe46ac43 100644 --- a/src/main/java/cn/nukkit/AdventureSettings.java +++ b/src/main/java/cn/nukkit/AdventureSettings.java @@ -4,7 +4,6 @@ import java.util.EnumMap; import java.util.Map; -import java.util.Map.Entry; /** * Nukkit Project @@ -49,8 +48,8 @@ public boolean get(Type type) { public void update() { AdventureSettingsPacket pk = new AdventureSettingsPacket(); - for (Entry entry : this.values.entrySet()) { - pk.setFlag(entry.getKey().getId(), entry.getValue()); + for (Type t : Type.values()) { + pk.setFlag(t.getId(), get(t)); } pk.commandPermission = (player.isOp() ? AdventureSettingsPacket.PERMISSION_OPERATOR : AdventureSettingsPacket.PERMISSION_NORMAL); diff --git a/src/main/java/cn/nukkit/form/element/ElementDropdown.java b/src/main/java/cn/nukkit/form/element/ElementDropdown.java index 647e15c07e..7bd9cdbc54 100644 --- a/src/main/java/cn/nukkit/form/element/ElementDropdown.java +++ b/src/main/java/cn/nukkit/form/element/ElementDropdown.java @@ -1,23 +1,24 @@ package cn.nukkit.form.element; import java.util.ArrayList; +import java.util.List; public class ElementDropdown extends Element { public String type = "dropdown"; public String text = ""; - public ArrayList options; + public List options; public int defaultOptionIndex = 0; public ElementDropdown(String text) { this(text, new ArrayList<>()); } - public ElementDropdown(String text, ArrayList options) { + public ElementDropdown(String text, List options) { this(text, options, 0); } - public ElementDropdown(String text, ArrayList options, int defaultOption) { + public ElementDropdown(String text, List options, int defaultOption) { this.text = text; this.options = options; this.defaultOptionIndex = defaultOption; diff --git a/src/main/java/cn/nukkit/form/element/ElementStepSlider.java b/src/main/java/cn/nukkit/form/element/ElementStepSlider.java index aeb72b5bcb..3624bcdb19 100644 --- a/src/main/java/cn/nukkit/form/element/ElementStepSlider.java +++ b/src/main/java/cn/nukkit/form/element/ElementStepSlider.java @@ -1,23 +1,24 @@ package cn.nukkit.form.element; import java.util.ArrayList; +import java.util.List; public class ElementStepSlider extends Element { public String type = "step_slider"; public String text = ""; - public ArrayList steps; + public List steps; public int defaultStepIndex = 0; public ElementStepSlider(String text) { this(text, new ArrayList<>()); } - public ElementStepSlider(String text, ArrayList steps) { + public ElementStepSlider(String text, List steps) { this(text, steps, 0); } - public ElementStepSlider(String text, ArrayList steps, int defaultStep) { + public ElementStepSlider(String text, List steps, int defaultStep) { this.text = text; this.steps = steps; this.defaultStepIndex = defaultStep; From eb7d3a5286ff31d3b38f5070176c26d1068a8cad Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 5 Oct 2017 09:39:06 +0200 Subject: [PATCH 128/175] Allow plugins to change players view distance --- src/main/java/cn/nukkit/Player.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 9a93dce52f..54d2986a1c 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2745,7 +2745,7 @@ public void handleDataPacket(DataPacket packet) { case ProtocolInfo.REQUEST_CHUNK_RADIUS_PACKET: RequestChunkRadiusPacket requestChunkRadiusPacket = (RequestChunkRadiusPacket) packet; ChunkRadiusUpdatedPacket chunkRadiusUpdatePacket = new ChunkRadiusUpdatedPacket(); - this.chunkRadius = Math.max(5, Math.min(requestChunkRadiusPacket.radius, this.viewDistance)); + this.chunkRadius = Math.max(3, Math.min(requestChunkRadiusPacket.radius, this.viewDistance)); chunkRadiusUpdatePacket.radius = this.chunkRadius; this.dataPacket(chunkRadiusUpdatePacket); break; @@ -3285,6 +3285,19 @@ public boolean kick(PlayerKickEvent.Reason reason, String reasonString, boolean return false; } + public void setViewDistance(int distance) { + this.chunkRadius = distance; + + ChunkRadiusUpdatedPacket pk = new ChunkRadiusUpdatedPacket(); + pk.radius = distance; + + this.dataPacket(pk); + } + + public int getViewDistance() { + return this.chunkRadius; + } + @Override public void sendMessage(String message) { TextPacket pk = new TextPacket(); From 028d460d015bb84be4d75e15e25a03b096867c8f Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 5 Oct 2017 10:15:49 +0200 Subject: [PATCH 129/175] Fixed stained glass pane --- src/main/java/cn/nukkit/Player.java | 17 +++++++++++++++++ .../java/cn/nukkit/block/BlockGlassPane.java | 3 +-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 54d2986a1c..ab16172455 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -350,6 +350,23 @@ public boolean getAllowFlight() { return this.getAdventureSettings().get(Type.ALLOW_FLIGHT); } + public void setAllowModifyWorld(boolean value) { + this.getAdventureSettings().set(Type.WORLD_IMMUTABLE, !value); + this.getAdventureSettings().set(Type.BUILD_AND_MINE, value); + this.getAdventureSettings().update(); + } + + public void setAllowInteract(boolean value) { + setAllowInteract(value, value); + } + + public void setAllowInteract(boolean value, boolean containers) { + this.getAdventureSettings().set(Type.WORLD_IMMUTABLE, !value); + this.getAdventureSettings().set(Type.DOORS_AND_SWITCHED, value); + this.getAdventureSettings().set(Type.OPEN_CONTAINERS, containers); + this.getAdventureSettings().update(); + } + @Deprecated public void setAutoJump(boolean value) { this.getAdventureSettings().set(Type.AUTO_JUMP, value); diff --git a/src/main/java/cn/nukkit/block/BlockGlassPane.java b/src/main/java/cn/nukkit/block/BlockGlassPane.java index 4da68af165..b2fa9fcd21 100644 --- a/src/main/java/cn/nukkit/block/BlockGlassPane.java +++ b/src/main/java/cn/nukkit/block/BlockGlassPane.java @@ -14,10 +14,9 @@ public BlockGlassPane() { } public BlockGlassPane(int meta) { - super(0); + super(meta); } - @Override public String getName() { return "Glass Pane"; From df1e8af4322ff988b1bd7b8c6106a8cf56a8a644 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 5 Oct 2017 12:25:07 +0200 Subject: [PATCH 130/175] Fixed teleport during process movement --- src/main/java/cn/nukkit/Player.java | 51 ++--------------------------- 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index ab16172455..405dbcf79e 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -937,7 +937,6 @@ protected boolean orderChunks() { int centerX = (int) this.x >> 4; int centerZ = (int) this.z >> 4; - int count = 0; for (int x = -this.chunkRadius; x <= this.chunkRadius; x++) { for (int z = -this.chunkRadius; z <= this.chunkRadius; z++) { @@ -948,7 +947,6 @@ protected boolean orderChunks() { long index; if (!(this.usedChunks.containsKey(index = Level.chunkHash(chunkX, chunkZ))) || !this.usedChunks.get(index)) { newOrder.put(index, distance); - count++; } lastChunk.remove(index); } @@ -1393,6 +1391,9 @@ protected void processMovement(int tickDiff) { double dz = newPos.z - this.z; this.fastMove(dx, dy, dz); + if (this.newPosition == null) { + return; //maybe solve that in better way + } double diffX = this.x - newPos.x; double diffY = this.y - newPos.y; @@ -4053,20 +4054,6 @@ protected boolean checkTeleportPosition() { } } - /*if (this.isLevelChange) { //TODO: remove this - PlayStatusPacket statusPacket0 = new PlayStatusPacket();//Weather - this.getLevel().sendWeather(this); - //Update time - this.getLevel().sendTime(this); - statusPacket0.status = PlayStatusPacket.PLAYER_SPAWN; - this.dataPacket(statusPacket0); - - //Weather - this.getLevel().sendWeather(this); - //Update time - this.getLevel().sendTime(this); - }*/ - this.spawnToAll(); this.isLevelChange = false; this.forceMovement = this.teleportPosition; @@ -4138,38 +4125,6 @@ public boolean teleport(Location location, TeleportCause cause) { this.getLevel().sendWeather(this); //Update time this.getLevel().sendTime(this); - - if (from.getLevel().getId() != to.level.getId()) { - /*if (this.spawned) { //broken - //TODO: remove this in future version - this.isLevelChange = true; - this.nextChunkOrderRun = 10000; - - ChangeDimensionPacket changeDimensionPacket1 = new ChangeDimensionPacket(); - changeDimensionPacket1.dimension = 1; - changeDimensionPacket1.x = (float) this.getX(); - changeDimensionPacket1.y = (float) this.getY(); - changeDimensionPacket1.z = (float) this.getZ(); - this.dataPacket(changeDimensionPacket1); - - this.forceSendEmptyChunks(); - this.getServer().getScheduler().scheduleDelayedTask(() -> { - PlayStatusPacket statusPacket0 = new PlayStatusPacket(); - statusPacket0.status = PlayStatusPacket.PLAYER_SPAWN; - dataPacket(statusPacket0); - }, 8); - - this.getServer().getScheduler().scheduleDelayedTask(() -> { - ChangeDimensionPacket changeDimensionPacket = new ChangeDimensionPacket(); - changeDimensionPacket.dimension = 0; - changeDimensionPacket.x = (float) this.getX(); - changeDimensionPacket.y = (float) this.getY(); - changeDimensionPacket.z = (float) this.getZ(); - dataPacket(changeDimensionPacket); - nextChunkOrderRun = 0; - }, 9); - }*/ - } return true; } From 66ff1ef64f2d31b030cd5b7947c59085107f56d8 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 5 Oct 2017 12:44:10 +0200 Subject: [PATCH 131/175] Fixed double chest inventory --- src/main/java/cn/nukkit/Player.java | 3 --- src/main/java/cn/nukkit/blockentity/BlockEntityChest.java | 2 +- src/main/java/cn/nukkit/inventory/DoubleChestInventory.java | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 405dbcf79e..b461381036 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -4055,7 +4055,6 @@ protected boolean checkTeleportPosition() { } this.spawnToAll(); - this.isLevelChange = false; this.forceMovement = this.teleportPosition; this.teleportPosition = null; return true; @@ -4079,8 +4078,6 @@ protected void sendPlayStatus(int status, boolean immediate) { } } - private boolean isLevelChange = false; - @Override public boolean teleport(Location location, TeleportCause cause) { if (!this.isOnline()) { diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java b/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java index 8f5bb96edc..f4cdeab250 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntityChest.java @@ -123,7 +123,7 @@ public void setItem(int index, Item item) { @Override public BaseInventory getInventory() { - if (this.isPaired() && this.doubleInventory == null) { + if (this.doubleInventory == null && this.isPaired()) { this.checkPairing(); } diff --git a/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java b/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java index 3776ebdedf..38f83cc912 100644 --- a/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java +++ b/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java @@ -58,8 +58,8 @@ public Item getItem(int index) { } @Override - public boolean setItem(int index, Item item) { - return index < this.left.getSize() ? this.left.setItem(index, item) : this.right.setItem(index - this.right.getSize(), item); + public boolean setItem(int index, Item item, boolean send) { + return index < this.left.getSize() ? this.left.setItem(index, item, send) : this.right.setItem(index - this.right.getSize(), item, send); } @Override From a2350178f87e173d9499ef728dd2c37d598d9339 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 5 Oct 2017 13:15:58 +0200 Subject: [PATCH 132/175] Update version --- src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java index 1f8ca4c31c..55cee556ae 100644 --- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java +++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java @@ -11,8 +11,8 @@ public interface ProtocolInfo { */ int CURRENT_PROTOCOL = Integer.valueOf("137"); //plugins can change it - String MINECRAFT_VERSION = "v1.2.1"; - String MINECRAFT_VERSION_NETWORK = "1.2.1"; + String MINECRAFT_VERSION = "v1.2.2"; + String MINECRAFT_VERSION_NETWORK = "1.2.2"; byte LOGIN_PACKET = 0x01; byte PLAY_STATUS_PACKET = 0x02; From 42f5751b49c7824c42d9160ad09df5c42ffdbf32 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 5 Oct 2017 14:01:56 +0200 Subject: [PATCH 133/175] don't pickup items in spectator mode --- src/main/java/cn/nukkit/Player.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index b461381036..ebb3a43b87 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -4538,7 +4538,7 @@ public ClientChainData getLoginChainData() { } public boolean pickupEntity(Entity entity, boolean near) { - if (!this.spawned || !this.isAlive() || !this.isOnline()) { + if (!this.spawned || !this.isAlive() || !this.isOnline() || this.getGamemode() == SPECTATOR) { return false; } From 36a690289a6f1d9ebce1415ea4077bb115018db2 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 5 Oct 2017 15:08:09 +0200 Subject: [PATCH 134/175] reverted eating sounds --- 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 ebb3a43b87..6e2e428010 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2522,8 +2522,8 @@ public void handleDataPacket(DataPacket packet) { break; } - this.dataPacket(packet); - Server.broadcastPacket(this.getViewers().values(), packet); + /*this.dataPacket(packet); //bug? + Server.broadcastPacket(this.getViewers().values(), packet);*/ break; } break; From 6941eb2dca7d5675489241a02df7ff341f92a371 Mon Sep 17 00:00:00 2001 From: boybook Date: Thu, 5 Oct 2017 22:11:12 +0800 Subject: [PATCH 135/175] Support Damage Absorption! --- src/main/java/cn/nukkit/Player.java | 3 ++- src/main/java/cn/nukkit/entity/Entity.java | 18 ++++++++++++++++++ .../nukkit/event/entity/EntityDamageEvent.java | 6 +++++- src/main/java/cn/nukkit/potion/Effect.java | 9 +++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index ebb3a43b87..ebb71a5cb7 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -3792,7 +3792,8 @@ public void setHealth(float health) { } super.setHealth(health); - Attribute attr = Attribute.getAttribute(Attribute.MAX_HEALTH).setMaxValue(this.getMaxHealth()).setValue(health > 0 ? (health < getMaxHealth() ? health : getMaxHealth()) : 0); + //TODO: Remove it in future! This a hack to solve the client-side absorption bug! WFT Mojang (Half a yellow heart cannot be shown, we can test it in local gaming) + Attribute attr = Attribute.getAttribute(Attribute.MAX_HEALTH).setMaxValue(this.getAbsorption() % 2 != 0 ? this.getMaxHealth() + 1 : this.getMaxHealth()).setValue(health > 0 ? (health < getMaxHealth() ? health : getMaxHealth()) : 0); if (this.spawned) { UpdateAttributesPacket pk = new UpdateAttributesPacket(); pk.entries = new Attribute[]{attr}; diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java index 2d2a4293bc..7f8bad05be 100644 --- a/src/main/java/cn/nukkit/entity/Entity.java +++ b/src/main/java/cn/nukkit/entity/Entity.java @@ -246,6 +246,8 @@ public abstract class Entity extends Location implements Metadatable { protected float health = 20; private int maxHealth = 20; + protected float absorption = 0; + protected float ySize = 0; public boolean keepMovement = false; @@ -859,6 +861,11 @@ public boolean attack(EntityDamageEvent source) { if (source.isCancelled()) { return false; } + if (this.absorption > 0) { //Damage Absorption + float absorptionHealth = this.absorption - source.getFinalDamage() > 0 ? source.getFinalDamage() : this.absorption; + this.setAbsorption(this.absorption - absorptionHealth); + source.setDamage(-absorptionHealth, EntityDamageEvent.DamageModifier.ABSORPTION); + } setLastDamageCause(source); setHealth(getHealth() - source.getFinalDamage()); return true; @@ -1256,6 +1263,17 @@ public void setOnFire(int seconds) { } } + public float getAbsorption() { + return absorption; + } + + public void setAbsorption(float absorption) { + if (absorption != this.absorption) { + this.absorption = absorption; + if (this instanceof Player) ((Player) this).setAttribute(Attribute.getAttribute(Attribute.ABSORPTION).setValue(absorption)); + } + } + public BlockFace getDirection() { double rotation = this.yaw % 360; if (rotation < 0) { diff --git a/src/main/java/cn/nukkit/event/entity/EntityDamageEvent.java b/src/main/java/cn/nukkit/event/entity/EntityDamageEvent.java index c2a00e67a3..3652869819 100644 --- a/src/main/java/cn/nukkit/event/entity/EntityDamageEvent.java +++ b/src/main/java/cn/nukkit/event/entity/EntityDamageEvent.java @@ -120,7 +120,11 @@ public enum DamageModifier { /** * Damage reduction caused by the Resistance potion effect */ - RESISTANCE + RESISTANCE, + /** + * Damage reduction caused by the Damage absorption effect + */ + ABSORPTION //ARMOR_ENCHANTMENTS } diff --git a/src/main/java/cn/nukkit/potion/Effect.java b/src/main/java/cn/nukkit/potion/Effect.java index a2fbf92b16..b6d47800a3 100644 --- a/src/main/java/cn/nukkit/potion/Effect.java +++ b/src/main/java/cn/nukkit/potion/Effect.java @@ -261,6 +261,11 @@ public void add(Entity entity, boolean modify) { entity.setDataFlag(Entity.DATA_FLAGS, Entity.DATA_FLAG_INVISIBLE, true); entity.setNameTagVisible(false); } + + if (this.id == Effect.ABSORPTION) { + int add = (this.amplifier + 1) * 4; + if (add > entity.getAbsorption()) entity.setAbsorption(add); + } } public void remove(Entity entity) { @@ -281,6 +286,10 @@ public void remove(Entity entity) { entity.setDataFlag(Entity.DATA_FLAGS, Entity.DATA_FLAG_INVISIBLE, false); entity.setNameTagVisible(true); } + + if (this.id == Effect.ABSORPTION) { + entity.setAbsorption(0); + } } @Override From 5136393fdff38bb3c5591a30bcbccd48506cd2a2 Mon Sep 17 00:00:00 2001 From: boybook Date: Thu, 5 Oct 2017 22:50:29 +0800 Subject: [PATCH 136/175] =?UTF-8?q?Funny=F0=9F=98=82,=20add=20Player.showX?= =?UTF-8?q?boxProfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/cn/nukkit/Player.java | 10 +++++++ .../nukkit/network/protocol/ProtocolInfo.java | 3 ++ .../network/protocol/ShowProfilePacket.java | 28 +++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 src/main/java/cn/nukkit/network/protocol/ShowProfilePacket.java diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 3a3b81fbac..b9147bc755 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -4658,4 +4658,14 @@ public void notifyACK(int identification) { public boolean isBreakingBlock() { return this.breakingBlock != null; } + + /** + * Show a window of a XBOX account's profile + * @param xuid XUID + */ + public void showXboxProfile(String xuid) { + ShowProfilePacket pk = new ShowProfilePacket(); + pk.xuid = getLoginChainData().getXUID(); + this.dataPacket(pk); + } } diff --git a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java index 55cee556ae..1a1238f5e4 100644 --- a/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java +++ b/src/main/java/cn/nukkit/network/protocol/ProtocolInfo.java @@ -92,6 +92,7 @@ public interface ProtocolInfo { byte AVAILABLE_COMMANDS_PACKET = 0x4c; byte COMMAND_REQUEST_PACKET = 0x4d; byte COMMAND_BLOCK_UPDATE_PACKET = 0x4e; + byte COMMAND_OUTPUT_PACKET = 0x4f; byte UPDATE_TRADE_PACKET = 0x50; byte UPDATE_EQUIPMENT_PACKET = 0x51; byte RESOURCE_PACK_DATA_INFO_PACKET = 0x52; @@ -116,5 +117,7 @@ public interface ProtocolInfo { byte MODAL_FORM_RESPONSE_PACKET = 0x65; byte SERVER_SETTINGS_REQUEST_PACKET = 0x66; byte SERVER_SETTINGS_RESPONSE_PACKET = 0x67; + byte SHOW_PROFILE_PACKET = 0x68; + byte SET_DEFAULT_GAME_TYPE_PACKET = 0x69; byte BATCH_PACKET = (byte) 0xff; } diff --git a/src/main/java/cn/nukkit/network/protocol/ShowProfilePacket.java b/src/main/java/cn/nukkit/network/protocol/ShowProfilePacket.java new file mode 100644 index 0000000000..89c85bdf1a --- /dev/null +++ b/src/main/java/cn/nukkit/network/protocol/ShowProfilePacket.java @@ -0,0 +1,28 @@ +package cn.nukkit.network.protocol; + +/** + * author: MagicDroidX + * Nukkit Project + */ +public class ShowProfilePacket extends DataPacket { + public static final byte NETWORK_ID = ProtocolInfo.SHOW_PROFILE_PACKET; + + public String xuid; + + @Override + public byte pid() { + return NETWORK_ID; + } + + @Override + public void decode() { + this.xuid = this.getString(); + } + + @Override + public void encode() { + this.reset(); + this.putString(this.xuid); + } + +} From edf1bc0534a4ee6a1cd331f30f4be510bda80c47 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 8 Oct 2017 08:06:11 +0200 Subject: [PATCH 137/175] Fixed flowerpot item conversion --- src/main/java/cn/nukkit/block/BlockFlowerPot.java | 5 +++++ .../cn/nukkit/network/protocol/SetEntityLinkPacket.java | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/cn/nukkit/block/BlockFlowerPot.java b/src/main/java/cn/nukkit/block/BlockFlowerPot.java index 4c8a6c4fbb..1e7648d085 100644 --- a/src/main/java/cn/nukkit/block/BlockFlowerPot.java +++ b/src/main/java/cn/nukkit/block/BlockFlowerPot.java @@ -157,4 +157,9 @@ protected AxisAlignedBB recalculateBoundingBox() { public boolean canPassThrough() { return false; } + + @Override + public Item toItem() { + return new ItemFlowerPot(); + } } diff --git a/src/main/java/cn/nukkit/network/protocol/SetEntityLinkPacket.java b/src/main/java/cn/nukkit/network/protocol/SetEntityLinkPacket.java index 2a6218dc86..863d8d41e3 100644 --- a/src/main/java/cn/nukkit/network/protocol/SetEntityLinkPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/SetEntityLinkPacket.java @@ -14,6 +14,7 @@ public class SetEntityLinkPacket extends DataPacket { public long rider; public long riding; public byte type; + public byte unknownByte; @Override public void decode() { @@ -23,14 +24,14 @@ public void decode() { @Override public void encode() { this.reset(); - this.putEntityRuntimeId(this.rider); - this.putEntityRuntimeId(this.riding); + this.putEntityUniqueId(this.rider); + this.putEntityUniqueId(this.riding); this.putByte(this.type); + this.putByte(this.unknownByte); } @Override public byte pid() { return NETWORK_ID; } - } From 96fe5d91a9ed02ba1aa92b5236f79cdb58ff3582 Mon Sep 17 00:00:00 2001 From: boybook Date: Mon, 9 Oct 2017 22:00:11 +0800 Subject: [PATCH 138/175] Fix some logical error in ElementSlider. --- .../cn/nukkit/form/element/ElementSlider.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/java/cn/nukkit/form/element/ElementSlider.java b/src/main/java/cn/nukkit/form/element/ElementSlider.java index 1513ec424f..fb03bb5a9f 100644 --- a/src/main/java/cn/nukkit/form/element/ElementSlider.java +++ b/src/main/java/cn/nukkit/form/element/ElementSlider.java @@ -6,24 +6,22 @@ public class ElementSlider extends Element { public String text = ""; public float min = 0f; public float max = 100f; - public float step; + public int step; public float defaultValue; public ElementSlider(String text, float min, float max) { - this(text, min, max, -1f); + this(text, min, max, -1); } - public ElementSlider(String text, float min, float max, float step) { - this(text, min, max, step, -1f); + public ElementSlider(String text, float min, float max, int step) { + this(text, min, max, step, -1); } - public ElementSlider(String text, float min, float max, float step, float defaultValue) { + public ElementSlider(String text, float min, float max, int 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; + this.min = min < 0f ? 0f : min; + this.max = max > this.min ? max : this.min; + if (step != -1f && step > 0) this.step = step; if (defaultValue != -1f) this.defaultValue = defaultValue; } From 5737fce9252a55bf7da79f75c79764b426dc74f8 Mon Sep 17 00:00:00 2001 From: boybook Date: Wed, 11 Oct 2017 23:28:47 +0800 Subject: [PATCH 139/175] Fix no sound when opening ender chest. --- .../java/cn/nukkit/inventory/PlayerEnderChestInventory.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/cn/nukkit/inventory/PlayerEnderChestInventory.java b/src/main/java/cn/nukkit/inventory/PlayerEnderChestInventory.java index 76eec02831..2e10d98a3b 100644 --- a/src/main/java/cn/nukkit/inventory/PlayerEnderChestInventory.java +++ b/src/main/java/cn/nukkit/inventory/PlayerEnderChestInventory.java @@ -8,6 +8,7 @@ import cn.nukkit.network.protocol.BlockEventPacket; import cn.nukkit.network.protocol.ContainerClosePacket; import cn.nukkit.network.protocol.ContainerOpenPacket; +import cn.nukkit.network.protocol.LevelSoundEventPacket; public class PlayerEnderChestInventory extends BaseInventory { @@ -52,6 +53,7 @@ public void onOpen(Player who) { Level level = this.getHolder().getLevel(); if (level != null) { + level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_CHEST_OPEN, 1, -1, this.getHolder().add(0.5, 0.5, 0.5)); level.addChunkPacket((int) this.getHolder().getX() >> 4, (int) this.getHolder().getZ() >> 4, blockEventPacket); } } From fb686af8e885d7925ae15e125a74e322e76223e1 Mon Sep 17 00:00:00 2001 From: boybook Date: Thu, 12 Oct 2017 16:21:26 +0800 Subject: [PATCH 140/175] Fix no any sounds when closing an ender chest. --- src/main/java/cn/nukkit/inventory/PlayerEnderChestInventory.java | 1 + 1 file changed, 1 insertion(+) mode change 100644 => 100755 src/main/java/cn/nukkit/inventory/PlayerEnderChestInventory.java diff --git a/src/main/java/cn/nukkit/inventory/PlayerEnderChestInventory.java b/src/main/java/cn/nukkit/inventory/PlayerEnderChestInventory.java old mode 100644 new mode 100755 index 2e10d98a3b..d72fa0d603 --- a/src/main/java/cn/nukkit/inventory/PlayerEnderChestInventory.java +++ b/src/main/java/cn/nukkit/inventory/PlayerEnderChestInventory.java @@ -77,6 +77,7 @@ public void onClose(Player who) { Level level = this.getHolder().getLevel(); if (level != null) { + level.addLevelSoundEvent(LevelSoundEventPacket.SOUND_CHEST_CLOSED, 1, -1, this.getHolder().add(0.5, 0.5, 0.5)); level.addChunkPacket((int) this.getHolder().getX() >> 4, (int) this.getHolder().getZ() >> 4, blockEventPacket); } From 0ad523a8cecbd64f1c08d2dd8d7e6f6a1219da99 Mon Sep 17 00:00:00 2001 From: boybook Date: Fri, 13 Oct 2017 17:50:27 +0800 Subject: [PATCH 141/175] Daily enhancement on form (GUI) system 2017/10/13 --- .../java/cn/nukkit/form/element/Element.java | 2 +- .../cn/nukkit/form/element/ElementButton.java | 20 ++++++-- .../form/element/ElementButtonImageData.java | 19 ++++++- .../nukkit/form/element/ElementDropdown.java | 24 +++++++-- .../cn/nukkit/form/element/ElementInput.java | 31 +++++++++-- .../cn/nukkit/form/element/ElementLabel.java | 11 +++- .../cn/nukkit/form/element/ElementSlider.java | 51 ++++++++++++++++--- .../form/element/ElementStepSlider.java | 24 +++++++-- .../cn/nukkit/form/element/ElementToggle.java | 21 ++++++-- .../form/response/FormResponseCustom.java | 6 ++- .../nukkit/form/window/FormWindowCustom.java | 40 ++++++++++----- .../nukkit/form/window/FormWindowModal.java | 42 +++++++++++++-- .../nukkit/form/window/FormWindowSimple.java | 28 ++++++++-- 13 files changed, 267 insertions(+), 52 deletions(-) diff --git a/src/main/java/cn/nukkit/form/element/Element.java b/src/main/java/cn/nukkit/form/element/Element.java index 8dda3bf997..fc80c0b7db 100644 --- a/src/main/java/cn/nukkit/form/element/Element.java +++ b/src/main/java/cn/nukkit/form/element/Element.java @@ -1,5 +1,5 @@ package cn.nukkit.form.element; -abstract public class Element { +public abstract class Element { } diff --git a/src/main/java/cn/nukkit/form/element/ElementButton.java b/src/main/java/cn/nukkit/form/element/ElementButton.java index b1e05692d4..a95846582f 100644 --- a/src/main/java/cn/nukkit/form/element/ElementButton.java +++ b/src/main/java/cn/nukkit/form/element/ElementButton.java @@ -2,8 +2,8 @@ public class ElementButton { - public String text = ""; - public ElementButtonImageData image; + private String text = ""; + private ElementButtonImageData image; public ElementButton(String text) { this.text = text; @@ -11,11 +11,23 @@ public ElementButton(String text) { public ElementButton(String text, ElementButtonImageData image) { this.text = text; - if (!image.data.isEmpty() && !image.type.isEmpty()) this.image = image; + if (!image.getData().isEmpty() && !image.getType().isEmpty()) this.image = image; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public ElementButtonImageData getImage() { + return image; } public void addImage(ElementButtonImageData image) { - if (!image.data.isEmpty() && !image.type.isEmpty()) this.image = image; + if (!image.getData().isEmpty() && !image.getType().isEmpty()) this.image = image; } } diff --git a/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java b/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java index 1bc5a48b9b..e3d0fa4e42 100644 --- a/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java +++ b/src/main/java/cn/nukkit/form/element/ElementButtonImageData.java @@ -5,8 +5,8 @@ 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; + private String type; + private String data; public ElementButtonImageData(String type, String data) { if (!type.equals(IMAGE_DATA_TYPE_URL) && !type.equals(IMAGE_DATA_TYPE_PATH)) return; @@ -14,4 +14,19 @@ public ElementButtonImageData(String type, String data) { this.data = data; } + public String getType() { + return type; + } + + public String getData() { + return data; + } + + public void setType(String type) { + this.type = type; + } + + public void setData(String data) { + 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 index 7bd9cdbc54..c335d49c12 100644 --- a/src/main/java/cn/nukkit/form/element/ElementDropdown.java +++ b/src/main/java/cn/nukkit/form/element/ElementDropdown.java @@ -5,10 +5,10 @@ public class ElementDropdown extends Element { - public String type = "dropdown"; - public String text = ""; - public List options; - public int defaultOptionIndex = 0; + private final String type = "dropdown"; + private String text = ""; + private List options; + private int defaultOptionIndex = 0; public ElementDropdown(String text) { this(text, new ArrayList<>()); @@ -24,11 +24,27 @@ public ElementDropdown(String text, List options, int defaultOption) { this.defaultOptionIndex = defaultOption; } + public int getDefaultOptionIndex() { + return defaultOptionIndex; + } + public void setDefaultOptionIndex(int index) { if (index >= options.size()) return; this.defaultOptionIndex = index; } + public List getOptions() { + return options; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + public void addOption(String option) { addOption(option, false); } diff --git a/src/main/java/cn/nukkit/form/element/ElementInput.java b/src/main/java/cn/nukkit/form/element/ElementInput.java index ad8407ace8..c11a1af190 100644 --- a/src/main/java/cn/nukkit/form/element/ElementInput.java +++ b/src/main/java/cn/nukkit/form/element/ElementInput.java @@ -2,10 +2,10 @@ public class ElementInput extends Element { - public String type = "input"; - public String text = ""; - public String placeholder = ""; - public String defaultText = ""; + private final String type = "input"; + private String text = ""; + private String placeholder = ""; + private String defaultText = ""; public ElementInput(String text) { this(text, ""); @@ -21,4 +21,27 @@ public ElementInput(String text, String placeholder, String defaultText) { this.defaultText = defaultText; } + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getPlaceHolder() { + return placeholder; + } + + public void setPlaceHolder(String placeholder) { + this.placeholder = placeholder; + } + + public String getDefaultText() { + return defaultText; + } + + public void setDefaultText(String defaultText) { + 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 index a69e58c233..e965e0e188 100644 --- a/src/main/java/cn/nukkit/form/element/ElementLabel.java +++ b/src/main/java/cn/nukkit/form/element/ElementLabel.java @@ -2,11 +2,18 @@ public class ElementLabel extends Element { - public String type = "label"; - public String text = ""; + private final String type = "label"; + private String text = ""; public ElementLabel(String text) { this.text = text; } + public String getText() { + return text; + } + + public void setText(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 index fb03bb5a9f..021ec14c1a 100644 --- a/src/main/java/cn/nukkit/form/element/ElementSlider.java +++ b/src/main/java/cn/nukkit/form/element/ElementSlider.java @@ -2,12 +2,12 @@ public class ElementSlider extends Element { - public String type = "slider"; - public String text = ""; - public float min = 0f; - public float max = 100f; - public int step; - public float defaultValue; + private final String type = "slider"; + private String text = ""; + private float min = 0f; + private float max = 100f; + private int step; + private float defaultValue; public ElementSlider(String text, float min, float max) { this(text, min, max, -1); @@ -25,4 +25,43 @@ public ElementSlider(String text, float min, float max, int step, float defaultV if (defaultValue != -1f) this.defaultValue = defaultValue; } + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public float getMin() { + return min; + } + + public void setMin(float min) { + this.min = min; + } + + public float getMax() { + return max; + } + + public void setMax(float max) { + this.max = max; + } + + public int getStep() { + return step; + } + + public void setStep(int step) { + this.step = step; + } + + public float getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(float defaultValue) { + 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 index 3624bcdb19..aecee77ff7 100644 --- a/src/main/java/cn/nukkit/form/element/ElementStepSlider.java +++ b/src/main/java/cn/nukkit/form/element/ElementStepSlider.java @@ -5,10 +5,10 @@ public class ElementStepSlider extends Element { - public String type = "step_slider"; - public String text = ""; - public List steps; - public int defaultStepIndex = 0; + private final String type = "step_slider"; + private String text = ""; + private List steps; + private int defaultStepIndex = 0; public ElementStepSlider(String text) { this(text, new ArrayList<>()); @@ -24,11 +24,27 @@ public ElementStepSlider(String text, List steps, int defaultStep) { this.defaultStepIndex = defaultStep; } + public int getDefaultStepIndex() { + return defaultStepIndex; + } + public void setDefaultOptionIndex(int index) { if (index >= steps.size()) return; this.defaultStepIndex = index; } + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public List getSteps() { + return steps; + } + public void addStep(String step) { addStep(step, false); } diff --git a/src/main/java/cn/nukkit/form/element/ElementToggle.java b/src/main/java/cn/nukkit/form/element/ElementToggle.java index c9f12ba843..561f08f570 100644 --- a/src/main/java/cn/nukkit/form/element/ElementToggle.java +++ b/src/main/java/cn/nukkit/form/element/ElementToggle.java @@ -2,9 +2,9 @@ public class ElementToggle extends Element { - public String type = "toggle"; - public String text = ""; - public boolean defaultValue = false; + private final String type = "toggle"; + private String text = ""; + private boolean defaultValue = false; public ElementToggle(String text) { this(text, false); @@ -15,4 +15,19 @@ public ElementToggle(String text, boolean defaultValue) { this.defaultValue = defaultValue; } + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public boolean isDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(boolean defaultValue) { + this.defaultValue = defaultValue; + } } diff --git a/src/main/java/cn/nukkit/form/response/FormResponseCustom.java b/src/main/java/cn/nukkit/form/response/FormResponseCustom.java index a905ec9648..b7d3704c88 100644 --- a/src/main/java/cn/nukkit/form/response/FormResponseCustom.java +++ b/src/main/java/cn/nukkit/form/response/FormResponseCustom.java @@ -4,7 +4,7 @@ public class FormResponseCustom extends FormResponse { - public HashMap responses = new HashMap<>(); + private HashMap responses = new HashMap<>(); private HashMap dropdownResponses = new HashMap<>(); private HashMap inputResponses = new HashMap<>(); private HashMap sliderResponses = new HashMap<>(); @@ -23,6 +23,10 @@ public FormResponseCustom(HashMap responses, HashMap getResponses() { + return responses; + } + public Object getResponse(int id) { return responses.get(id); } diff --git a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java index cd4c70eddd..42db6d327e 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java @@ -12,10 +12,10 @@ public class FormWindowCustom extends FormWindow { - public String type = "custom_form"; - public String title = ""; - public ElementButtonImageData icon; - public List content; + private final String type = "custom_form"; + private String title = ""; + private ElementButtonImageData icon; + private List content; private FormResponseCustom response; @@ -33,10 +33,26 @@ public FormWindowCustom(String title, List contents, String icon) { if (!icon.isEmpty()) this.icon = new ElementButtonImageData(ElementButtonImageData.IMAGE_DATA_TYPE_URL, icon); } + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public List getElements() { + return content; + } + public void addElement(Element element) { content.add(element); } + public ElementButtonImageData getIcon() { + return icon; + } + public void setIcon(String icon) { if (!icon.isEmpty()) this.icon = new ElementButtonImageData(ElementButtonImageData.IMAGE_DATA_TYPE_URL, icon); } @@ -85,7 +101,7 @@ public void setResponse(String data) { continue; } if (e instanceof ElementDropdown) { - String answer = ((ElementDropdown) e).options.get(Integer.parseInt(elementData)); + String answer = ((ElementDropdown) e).getOptions().get(Integer.parseInt(elementData)); dropdownResponses.put(i, new FormResponseData(Integer.parseInt(elementData), answer)); responses.put(i, answer); } else if (e instanceof ElementInput) { @@ -96,7 +112,7 @@ public void setResponse(String data) { sliderResponses.put(i, answer); responses.put(i, answer); } else if (e instanceof ElementStepSlider) { - String answer = ((ElementStepSlider) e).steps.get(Integer.parseInt(elementData)); + String answer = ((ElementStepSlider) e).getSteps().get(Integer.parseInt(elementData)); stepSliderResponses.put(i, new FormResponseData(Integer.parseInt(elementData), answer)); responses.put(i, answer); } else if (e instanceof ElementToggle) { @@ -117,19 +133,19 @@ public void setResponse(String data) { */ public void setElementsFromResponse() { if (this.response != null) { - this.response.responses.forEach((i, response) -> { + this.response.getResponses().forEach((i, response) -> { Element e = content.get(i); if (e != null) { if (e instanceof ElementDropdown) { - ((ElementDropdown) e).defaultOptionIndex = ((ElementDropdown) e).options.indexOf(response); + ((ElementDropdown) e).setDefaultOptionIndex(((ElementDropdown) e).getOptions().indexOf(response)); } else if (e instanceof ElementInput) { - ((ElementInput) e).defaultText = (String)response; + ((ElementInput) e).setDefaultText((String)response); } else if (e instanceof ElementSlider) { - ((ElementSlider) e).defaultValue = (Float)response; + ((ElementSlider) e).setDefaultValue((Float)response); } else if (e instanceof ElementStepSlider) { - ((ElementStepSlider) e).defaultStepIndex = ((ElementStepSlider) e).steps.indexOf(response); + ((ElementStepSlider) e).setDefaultOptionIndex(((ElementStepSlider) e).getSteps().indexOf(response)); } else if (e instanceof ElementToggle) { - ((ElementToggle) e).defaultValue = (Boolean)response; + ((ElementToggle) e).setDefaultValue((Boolean)response); } } }); diff --git a/src/main/java/cn/nukkit/form/window/FormWindowModal.java b/src/main/java/cn/nukkit/form/window/FormWindowModal.java index 6e3cfc872c..da47e1eeaf 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowModal.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowModal.java @@ -5,11 +5,11 @@ public class FormWindowModal extends FormWindow { - private String type = "modal"; - public String title = ""; - public String content = ""; - public String button1 = ""; - public String button2 = ""; + private final String type = "modal"; + private String title = ""; + private String content = ""; + private String button1 = ""; + private String button2 = ""; private FormResponseModal response = null; @@ -20,6 +20,38 @@ public FormWindowModal(String title, String content, String trueButonText, Strin this.button2 = falseButtonText; } + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getButton1() { + return button1; + } + + public void setButton1(String button1) { + this.button1 = button1; + } + + public String getButton2() { + return button2; + } + + public void setButton2(String button2) { + this.button2 = button2; + } + public String getJSONData() { return new Gson().toJson(this); } diff --git a/src/main/java/cn/nukkit/form/window/FormWindowSimple.java b/src/main/java/cn/nukkit/form/window/FormWindowSimple.java index 58bcdbb704..a9f3aaedaf 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowSimple.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowSimple.java @@ -9,10 +9,10 @@ public class FormWindowSimple extends FormWindow { - public String type = "form"; - public String title = ""; - public String content = ""; - public List buttons; + private final String type = "form"; + private String title = ""; + private String content = ""; + private List buttons; private FormResponseSimple response = null; @@ -26,6 +26,26 @@ public FormWindowSimple(String title, String content, List button this.buttons = buttons; } + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public List getButtons() { + return buttons; + } + public void addButton(ElementButton button) { this.buttons.add(button); } From 1ce8a0371828de360e791b9d2102b9dd7b4b55bb Mon Sep 17 00:00:00 2001 From: boybook Date: Fri, 13 Oct 2017 17:59:24 +0800 Subject: [PATCH 142/175] FormWindow interpret: This variable is used for JSON import operations. Do NOT delete :) -- @Snake1999 --- src/main/java/cn/nukkit/form/element/ElementDropdown.java | 2 +- src/main/java/cn/nukkit/form/element/ElementInput.java | 2 +- src/main/java/cn/nukkit/form/element/ElementLabel.java | 2 +- src/main/java/cn/nukkit/form/element/ElementSlider.java | 2 +- src/main/java/cn/nukkit/form/element/ElementStepSlider.java | 2 +- src/main/java/cn/nukkit/form/element/ElementToggle.java | 2 +- src/main/java/cn/nukkit/form/window/FormWindowCustom.java | 2 +- src/main/java/cn/nukkit/form/window/FormWindowModal.java | 2 +- src/main/java/cn/nukkit/form/window/FormWindowSimple.java | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/cn/nukkit/form/element/ElementDropdown.java b/src/main/java/cn/nukkit/form/element/ElementDropdown.java index c335d49c12..b10699759b 100644 --- a/src/main/java/cn/nukkit/form/element/ElementDropdown.java +++ b/src/main/java/cn/nukkit/form/element/ElementDropdown.java @@ -5,7 +5,7 @@ public class ElementDropdown extends Element { - private final String type = "dropdown"; + private final String type = "dropdown"; //This variable is used for JSON import operations. Do NOT delete :) -- @Snake1999 private String text = ""; private List options; private int defaultOptionIndex = 0; diff --git a/src/main/java/cn/nukkit/form/element/ElementInput.java b/src/main/java/cn/nukkit/form/element/ElementInput.java index c11a1af190..e9af69b817 100644 --- a/src/main/java/cn/nukkit/form/element/ElementInput.java +++ b/src/main/java/cn/nukkit/form/element/ElementInput.java @@ -2,7 +2,7 @@ public class ElementInput extends Element { - private final String type = "input"; + private final String type = "input"; //This variable is used for JSON import operations. Do NOT delete :) -- @Snake1999 private String text = ""; private String placeholder = ""; private String defaultText = ""; diff --git a/src/main/java/cn/nukkit/form/element/ElementLabel.java b/src/main/java/cn/nukkit/form/element/ElementLabel.java index e965e0e188..449eae0561 100644 --- a/src/main/java/cn/nukkit/form/element/ElementLabel.java +++ b/src/main/java/cn/nukkit/form/element/ElementLabel.java @@ -2,7 +2,7 @@ public class ElementLabel extends Element { - private final String type = "label"; + private final String type = "label"; //This variable is used for JSON import operations. Do NOT delete :) -- @Snake1999 private String text = ""; public ElementLabel(String text) { diff --git a/src/main/java/cn/nukkit/form/element/ElementSlider.java b/src/main/java/cn/nukkit/form/element/ElementSlider.java index 021ec14c1a..8ed077bb75 100644 --- a/src/main/java/cn/nukkit/form/element/ElementSlider.java +++ b/src/main/java/cn/nukkit/form/element/ElementSlider.java @@ -2,7 +2,7 @@ public class ElementSlider extends Element { - private final String type = "slider"; + private final String type = "slider"; //This variable is used for JSON import operations. Do NOT delete :) -- @Snake1999 private String text = ""; private float min = 0f; private float max = 100f; diff --git a/src/main/java/cn/nukkit/form/element/ElementStepSlider.java b/src/main/java/cn/nukkit/form/element/ElementStepSlider.java index aecee77ff7..443a98596c 100644 --- a/src/main/java/cn/nukkit/form/element/ElementStepSlider.java +++ b/src/main/java/cn/nukkit/form/element/ElementStepSlider.java @@ -5,7 +5,7 @@ public class ElementStepSlider extends Element { - private final String type = "step_slider"; + private final String type = "step_slider"; //This variable is used for JSON import operations. Do NOT delete :) -- @Snake1999 private String text = ""; private List steps; private int defaultStepIndex = 0; diff --git a/src/main/java/cn/nukkit/form/element/ElementToggle.java b/src/main/java/cn/nukkit/form/element/ElementToggle.java index 561f08f570..2da9d7fdf1 100644 --- a/src/main/java/cn/nukkit/form/element/ElementToggle.java +++ b/src/main/java/cn/nukkit/form/element/ElementToggle.java @@ -2,7 +2,7 @@ public class ElementToggle extends Element { - private final String type = "toggle"; + private final String type = "toggle"; //This variable is used for JSON import operations. Do NOT delete :) -- @Snake1999 private String text = ""; private boolean defaultValue = false; diff --git a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java index 42db6d327e..4ce0aaf1fe 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowCustom.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowCustom.java @@ -12,7 +12,7 @@ public class FormWindowCustom extends FormWindow { - private final String type = "custom_form"; + private final String type = "custom_form"; //This variable is used for JSON import operations. Do NOT delete :) -- @Snake1999 private String title = ""; private ElementButtonImageData icon; private List content; diff --git a/src/main/java/cn/nukkit/form/window/FormWindowModal.java b/src/main/java/cn/nukkit/form/window/FormWindowModal.java index da47e1eeaf..f0139942b0 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowModal.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowModal.java @@ -5,7 +5,7 @@ public class FormWindowModal extends FormWindow { - private final String type = "modal"; + private final String type = "modal"; //This variable is used for JSON import operations. Do NOT delete :) -- @Snake1999 private String title = ""; private String content = ""; private String button1 = ""; diff --git a/src/main/java/cn/nukkit/form/window/FormWindowSimple.java b/src/main/java/cn/nukkit/form/window/FormWindowSimple.java index a9f3aaedaf..3df90500c6 100644 --- a/src/main/java/cn/nukkit/form/window/FormWindowSimple.java +++ b/src/main/java/cn/nukkit/form/window/FormWindowSimple.java @@ -9,7 +9,7 @@ public class FormWindowSimple extends FormWindow { - private final String type = "form"; + private final String type = "form"; //This variable is used for JSON import operations. Do NOT delete :) -- @Snake1999 private String title = ""; private String content = ""; private List buttons; From 99d4421d1ae8981aec4fc990c227a5766b5c0149 Mon Sep 17 00:00:00 2001 From: boybook Date: Sat, 14 Oct 2017 22:28:30 +0800 Subject: [PATCH 143/175] Don't forget reset() in DataPacket#encode --- .../cn/nukkit/network/protocol/CommandBlockUpdatePacket.java | 1 + .../cn/nukkit/network/protocol/InventoryTransactionPacket.java | 1 + src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java | 1 + .../java/cn/nukkit/network/protocol/PlayerHotbarPacket.java | 1 + src/main/java/cn/nukkit/network/protocol/RiderJumpPacket.java | 3 ++- .../java/cn/nukkit/network/protocol/ShowCreditsPacket.java | 1 + .../java/cn/nukkit/network/protocol/SimpleEventPacket.java | 1 + src/main/java/cn/nukkit/network/protocol/StopSoundPacket.java | 1 + .../java/cn/nukkit/network/protocol/TelemetryEventPacket.java | 1 + .../java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java | 1 + .../java/cn/nukkit/network/protocol/UpdateTradePacket.java | 1 + 11 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java b/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java index c8784d1fb7..e87893e35c 100644 --- a/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java +++ b/src/main/java/cn/nukkit/network/protocol/CommandBlockUpdatePacket.java @@ -44,6 +44,7 @@ public void decode() { @Override public void encode() { + this.reset(); this.putBoolean(this.isBlock); if (this.isBlock) { this.putBlockVector3(this.x, this.y, this.z); diff --git a/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java b/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java index 0d27e02a92..88ae0646de 100644 --- a/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/InventoryTransactionPacket.java @@ -42,6 +42,7 @@ public byte pid() { @Override public void encode() { + this.reset(); this.putUnsignedVarInt(this.transactionType); this.putUnsignedVarInt(this.actions.length); diff --git a/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java b/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java index 5e0ea6dc1d..081179ccb4 100644 --- a/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java @@ -23,6 +23,7 @@ public void decode() { @Override public void encode() { + this.reset(); this.putString(this.name); this.putBlockVector3(this.x, this.y, this.z); this.putLFloat(this.volume); diff --git a/src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java b/src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java index 6bd53cab3f..0dc249f454 100644 --- a/src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/PlayerHotbarPacket.java @@ -32,6 +32,7 @@ public void decode() { @Override public void encode() { + this.reset(); this.putUnsignedVarInt(this.selectedHotbarSlot); this.putByte((byte) this.windowId); this.putUnsignedVarInt(this.slots.length); diff --git a/src/main/java/cn/nukkit/network/protocol/RiderJumpPacket.java b/src/main/java/cn/nukkit/network/protocol/RiderJumpPacket.java index 3ef8d1e88c..86b11887c0 100644 --- a/src/main/java/cn/nukkit/network/protocol/RiderJumpPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/RiderJumpPacket.java @@ -13,11 +13,12 @@ public byte pid() { @Override public void decode() { - + this.unknown = this.getVarInt(); } @Override public void encode() { + this.reset(); this.putVarInt(this.unknown); } } diff --git a/src/main/java/cn/nukkit/network/protocol/ShowCreditsPacket.java b/src/main/java/cn/nukkit/network/protocol/ShowCreditsPacket.java index 500ab9099b..8089289499 100644 --- a/src/main/java/cn/nukkit/network/protocol/ShowCreditsPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/ShowCreditsPacket.java @@ -22,6 +22,7 @@ public void decode() { @Override public void encode() { + this.reset(); this.putEntityRuntimeId(this.eid); this.putVarInt(this.status); } diff --git a/src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java b/src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java index 04d26e6ac2..a045ff1243 100644 --- a/src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/SimpleEventPacket.java @@ -16,6 +16,7 @@ public void decode() { @Override public void encode() { + this.reset(); this.putShort(this.unknown); } } diff --git a/src/main/java/cn/nukkit/network/protocol/StopSoundPacket.java b/src/main/java/cn/nukkit/network/protocol/StopSoundPacket.java index 0c9d45acfa..32cf956b50 100644 --- a/src/main/java/cn/nukkit/network/protocol/StopSoundPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/StopSoundPacket.java @@ -19,6 +19,7 @@ public void decode() { @Override public void encode() { + this.reset(); this.putString(this.name); this.putBoolean(this.stopAll); } diff --git a/src/main/java/cn/nukkit/network/protocol/TelemetryEventPacket.java b/src/main/java/cn/nukkit/network/protocol/TelemetryEventPacket.java index b73bb35919..d429d6ab8c 100644 --- a/src/main/java/cn/nukkit/network/protocol/TelemetryEventPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/TelemetryEventPacket.java @@ -18,6 +18,7 @@ public void decode() { @Override public void encode() { + this.reset(); this.putVarLong(this.eid); this.putVarInt(this.unknown1); this.putByte(this.unknown2); diff --git a/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java b/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java index bbd9125d16..5a6f37ae42 100644 --- a/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/UpdateEquipmentPacket.java @@ -21,6 +21,7 @@ public void decode() { @Override public void encode() { + this.reset(); this.putByte((byte) this.windowId); this.putByte((byte) this.windowType); this.putEntityUniqueId(this.eid); diff --git a/src/main/java/cn/nukkit/network/protocol/UpdateTradePacket.java b/src/main/java/cn/nukkit/network/protocol/UpdateTradePacket.java index c1d61d1bbc..28502ba3db 100644 --- a/src/main/java/cn/nukkit/network/protocol/UpdateTradePacket.java +++ b/src/main/java/cn/nukkit/network/protocol/UpdateTradePacket.java @@ -26,6 +26,7 @@ public void decode() { @Override public void encode() { + this.reset(); this.putByte(windowId); this.putByte(windowType); this.putVarInt(unknownVarInt1); From be944b2cd31580d0d3026b41d661c752cd9aa162 Mon Sep 17 00:00:00 2001 From: boybook Date: Sat, 14 Oct 2017 22:30:47 +0800 Subject: [PATCH 144/175] Change EntityInteractable from extends to interface. --- .../java/cn/nukkit/entity/EntityInteractable.java | 13 +++---------- .../java/cn/nukkit/entity/item/EntityVehicle.java | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/main/java/cn/nukkit/entity/EntityInteractable.java b/src/main/java/cn/nukkit/entity/EntityInteractable.java index 22a44e01e4..49c9515a1a 100644 --- a/src/main/java/cn/nukkit/entity/EntityInteractable.java +++ b/src/main/java/cn/nukkit/entity/EntityInteractable.java @@ -1,20 +1,13 @@ 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); - } +public interface EntityInteractable { // Todo: Passive entity?? i18n and boat leaving text - public abstract String getInteractButtonText(); + String getInteractButtonText(); - public abstract boolean canDoInteraction(); + boolean canDoInteraction(); } diff --git a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java index 74ab837635..5a6a672a0f 100644 --- a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java +++ b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java @@ -18,7 +18,7 @@ * author: MagicDroidX * Nukkit Project */ -public abstract class EntityVehicle extends EntityInteractable implements EntityRideable { +public abstract class EntityVehicle extends Entity implements EntityRideable, EntityInteractable { public EntityVehicle(FullChunk chunk, CompoundTag nbt) { super(chunk, nbt); From e605fa516a7a858b7ee505def47043ce5adf76e4 Mon Sep 17 00:00:00 2001 From: boybook Date: Mon, 16 Oct 2017 22:36:07 +0800 Subject: [PATCH 145/175] Move EntityVehicle#collidingWith to interface to solve the problem of some custom entities. --- src/main/java/cn/nukkit/Player.java | 8 ++++---- src/main/java/cn/nukkit/entity/Entity.java | 4 ++-- src/main/java/cn/nukkit/entity/EntityLiving.java | 6 +++--- src/main/java/cn/nukkit/entity/EntityRideable.java | 9 +++++++++ src/main/java/cn/nukkit/entity/item/EntityVehicle.java | 1 + 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index b9147bc755..6a0375b749 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2449,11 +2449,11 @@ public void handleDataPacket(DataPacket packet) { this.getServer().getPluginManager().callEvent(new PlayerMouseOverEntityEvent(this, targetEntity)); break; case InteractPacket.ACTION_VEHICLE_EXIT: - if (!(targetEntity instanceof EntityVehicle) || this.riding == null) { + if (!(targetEntity instanceof EntityRideable) || this.riding == null) { break; } - ((EntityVehicle) riding).mountEntity(this); + ((EntityRideable) riding).mountEntity(this); break; } break; @@ -3544,8 +3544,8 @@ public void close(TextContainer message, String reason, boolean notify) { this.hasSpawned = new HashMap<>(); this.spawnPosition = null; - if (this.riding instanceof EntityVehicle) { - ((EntityVehicle) this.riding).linkedEntity = null; + if (this.riding instanceof EntityRideable) { + this.riding.linkedEntity = null; } this.riding = null; diff --git a/src/main/java/cn/nukkit/entity/Entity.java b/src/main/java/cn/nukkit/entity/Entity.java index 7f8bad05be..ac6a907f99 100644 --- a/src/main/java/cn/nukkit/entity/Entity.java +++ b/src/main/java/cn/nukkit/entity/Entity.java @@ -1048,8 +1048,8 @@ public boolean entityBaseTick(int tickDiff) { Timings.entityBaseTickTimer.stopTiming(); return false; } - if (riding != null && !riding.isAlive()) { - ((EntityVehicle) riding).mountEntity(this); + if (riding != null && !riding.isAlive() && riding instanceof EntityRideable) { + ((EntityRideable) riding).mountEntity(this); } if (!this.effects.isEmpty()) { diff --git a/src/main/java/cn/nukkit/entity/EntityLiving.java b/src/main/java/cn/nukkit/entity/EntityLiving.java index 6074ac9c74..5f30e58155 100644 --- a/src/main/java/cn/nukkit/entity/EntityLiving.java +++ b/src/main/java/cn/nukkit/entity/EntityLiving.java @@ -88,7 +88,7 @@ public boolean hasLineOfSight(Entity entity) { return true; } - public void collidingWith(EntityVehicle ent) { // can override (IronGolem|Bats) + public void collidingWith(Entity ent) { // can override (IronGolem|Bats) ent.applyEntityCollision(this); } @@ -239,8 +239,8 @@ public boolean entityBaseTick(int 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); + if (entity instanceof EntityRideable) { + this.collidingWith(entity); } } } diff --git a/src/main/java/cn/nukkit/entity/EntityRideable.java b/src/main/java/cn/nukkit/entity/EntityRideable.java index 70b5b8f20d..91441f8dea 100644 --- a/src/main/java/cn/nukkit/entity/EntityRideable.java +++ b/src/main/java/cn/nukkit/entity/EntityRideable.java @@ -5,4 +5,13 @@ * Nukkit Project */ public interface EntityRideable { + + /** + * Mount or Dismounts an Entity from a rideable entity + * + * @param entity The target Entity + * @return {@code true} if the mounting successful + */ + boolean mountEntity(Entity entity); + } diff --git a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java index 5a6a672a0f..1edfe83d18 100644 --- a/src/main/java/cn/nukkit/entity/item/EntityVehicle.java +++ b/src/main/java/cn/nukkit/entity/item/EntityVehicle.java @@ -64,6 +64,7 @@ public boolean canDoInteraction() { * @param entity The target Entity * @return {@code true} if the mounting successful */ + @Override public boolean mountEntity(Entity entity) { Objects.requireNonNull(entity, "The target of the mounting entity can't be null"); this.PitchDelta = 0.0D; From c33e3ef5fc94523703206a1c07ab714cad14590d Mon Sep 17 00:00:00 2001 From: boybook Date: Tue, 17 Oct 2017 10:51:56 +0800 Subject: [PATCH 146/175] AdventureSettingsPacket show broadcast, fix setAllowModifyWorld. --- src/main/java/cn/nukkit/AdventureSettings.java | 2 +- src/main/java/cn/nukkit/Player.java | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/cn/nukkit/AdventureSettings.java b/src/main/java/cn/nukkit/AdventureSettings.java index 39fe46ac43..7b62902ba8 100644 --- a/src/main/java/cn/nukkit/AdventureSettings.java +++ b/src/main/java/cn/nukkit/AdventureSettings.java @@ -56,7 +56,7 @@ public void update() { pk.playerPermission = (player.isOp() ? Player.PERMISSION_OPERATOR : Player.PERMISSION_MEMBER); pk.entityUniqueId = player.getId(); - player.dataPacket(pk); + Server.broadcastPacket(Server.getInstance().getOnlinePlayers().values(), pk); player.resetInAirTicks(); } diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 6a0375b749..75d381c09a 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -353,6 +353,7 @@ public boolean getAllowFlight() { public void setAllowModifyWorld(boolean value) { this.getAdventureSettings().set(Type.WORLD_IMMUTABLE, !value); this.getAdventureSettings().set(Type.BUILD_AND_MINE, value); + this.getAdventureSettings().set(Type.WORLD_BUILDER, value); this.getAdventureSettings().update(); } @@ -1181,8 +1182,9 @@ public boolean setGamemode(int gamemode, boolean clientSide, AdventureSettings n if (newSettings == null) { newSettings = this.getAdventureSettings().clone(this); - newSettings.set(Type.WORLD_IMMUTABLE, gamemode != 3); - newSettings.set(Type.BUILD_AND_MINE, gamemode != 3); + newSettings.set(Type.WORLD_IMMUTABLE, (gamemode & 0x02) > 0); + newSettings.set(Type.BUILD_AND_MINE, (gamemode & 0x02) <= 0); + newSettings.set(Type.WORLD_BUILDER, (gamemode & 0x02) <= 0); newSettings.set(Type.ALLOW_FLIGHT, (gamemode & 0x01) > 0); newSettings.set(Type.NO_CLIP, gamemode == 0x03); newSettings.set(Type.FLYING, gamemode == 0x03); @@ -1832,7 +1834,8 @@ protected void processLogin() { } this.adventureSettings = new AdventureSettings(this) - .set(Type.WORLD_IMMUTABLE, !isAdventure()) + .set(Type.WORLD_IMMUTABLE, isAdventure()) + .set(Type.WORLD_BUILDER, !isAdventure()) .set(Type.AUTO_JUMP, true) .set(Type.ALLOW_FLIGHT, isCreative()) .set(Type.NO_CLIP, isSpectator()); From 572eca58838c481cd04ebcb157958656c8c7b2f0 Mon Sep 17 00:00:00 2001 From: boybook Date: Tue, 17 Oct 2017 15:22:50 +0800 Subject: [PATCH 147/175] Fix Take Item animation --- .../java/cn/nukkit/network/protocol/TakeItemEntityPacket.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/cn/nukkit/network/protocol/TakeItemEntityPacket.java b/src/main/java/cn/nukkit/network/protocol/TakeItemEntityPacket.java index 93187f28c4..6eae2bebad 100644 --- a/src/main/java/cn/nukkit/network/protocol/TakeItemEntityPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/TakeItemEntityPacket.java @@ -17,8 +17,8 @@ public void decode() { @Override public void encode() { this.reset(); - this.putVarLong(this.target); - this.putVarLong(this.entityId); + this.putUnsignedVarLong(this.target); + this.putUnsignedVarLong(this.entityId); } @Override From 4a31ff519248f2ac0ed19d18ab82b6b0453d73e9 Mon Sep 17 00:00:00 2001 From: NuclearSteven Date: Wed, 18 Oct 2017 18:00:17 +0800 Subject: [PATCH 148/175] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 220403d2cc..a2ed31b89e 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,10 @@ There're some tools for Nukkit developers. * __[FDevTools](https://github.com/fengberd/FDevTools)__ (**Load source and pack them easily**) * __[PocketServer](https://github.com/fengberd/MinecraftPEServer)__ (**Run Nukkit on android devices**) +Contributing +------------ +Please read the [CONTRIBUTING](https://github.com/Nukkit/Nukkit/blob/master/.github/CONTRIBUTING.md) guide before submitting any issue. Issues with insufficient information or in the wrong format will be closed and will not be reviewed. + Discussion ------------- * __[Forums](https://forums.nukkit.io)__ From 39a2f08f826cb789ff056fc51e1c26b3f4263c12 Mon Sep 17 00:00:00 2001 From: NuclearSteven Date: Wed, 18 Oct 2017 18:10:57 +0800 Subject: [PATCH 149/175] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 12e754eebf..7f723a12e4 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -20,7 +20,11 @@ Nukkit will create a bug report for EVERY exception and error detected, and ther In the report, you can see if the error is caused by Nukkit or a plugin. However, when "PLUGIN ERROR" is "false" and there are plugins running, it does not necessarily indicates that the error is caused by Nukkit. -While sending issues, please provide **as much information as you could**, or our developers might got stuck or confused when looking into your issue. +To sumbit bugs and problems, please upload the automaticly generated report. Make sure you have filled in all blanks in the template. Please provide **as much information as you could**, or our developers might got stuck or confused when looking into your issue. + +To submit feature requests and suggestions, please explicitly describe the feature you want or your suggestion. + +Note that the Issues section on GitHub is not for contents that are not related to the two categories listed above. Irrelevant issues will be closed. Please visit our forums for other kinds of discussions. Example --- From d7816d04e63a0f79ccf0e2316db6b3c01a3999e4 Mon Sep 17 00:00:00 2001 From: NuclearSteven Date: Wed, 18 Oct 2017 18:11:41 +0800 Subject: [PATCH 150/175] Update CONTRIBUTING.md --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 7f723a12e4..630ae59e39 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -24,7 +24,7 @@ To sumbit bugs and problems, please upload the automaticly generated report. Mak To submit feature requests and suggestions, please explicitly describe the feature you want or your suggestion. -Note that the Issues section on GitHub is not for contents that are not related to the two categories listed above. Irrelevant issues will be closed. Please visit our forums for other kinds of discussions. +**Note that the Issues section on GitHub is not for contents that are not related to the two categories listed above. Irrelevant issues will be closed. Please visit our forums for other kinds of discussions.** Example --- From 02b2f65a0a62d548b1645613eecf7a4861d310a8 Mon Sep 17 00:00:00 2001 From: boybook Date: Wed, 18 Oct 2017 21:47:55 +0800 Subject: [PATCH 151/175] Fix title upgrade of Dummy boss bar --- src/main/java/cn/nukkit/utils/DummyBossBar.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/cn/nukkit/utils/DummyBossBar.java b/src/main/java/cn/nukkit/utils/DummyBossBar.java index ca434bc6cb..bc7488225a 100644 --- a/src/main/java/cn/nukkit/utils/DummyBossBar.java +++ b/src/main/java/cn/nukkit/utils/DummyBossBar.java @@ -87,6 +87,7 @@ public void setText(String text) { if (!this.text.equals(text)) { this.text = text; this.updateBossEntityNameTag(); + this.sendSetBossBarTitle(); } } @@ -181,6 +182,15 @@ private void sendSetBossBarTexture() { player.dataPacket(pk); } + private void sendSetBossBarTitle() { + BossEventPacket pkBoss = new BossEventPacket(); + pkBoss.bossEid = bossBarId; + pkBoss.type = BossEventPacket.TYPE_TITLE; + pkBoss.title = text; + pkBoss.healthPercent = this.length; + player.dataPacket(pkBoss); + } + /** * Don't let the entity go too far from the player, or the BossBar will disappear. * Update boss entity's position when teleport and each 5s. From 3bf4aa750a69130d7db39c52d7a9ce4997e99166 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Wed, 18 Oct 2017 19:31:25 +0200 Subject: [PATCH 152/175] Use method for entity IDs --- .../cn/nukkit/network/protocol/TakeItemEntityPacket.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/cn/nukkit/network/protocol/TakeItemEntityPacket.java b/src/main/java/cn/nukkit/network/protocol/TakeItemEntityPacket.java index 6eae2bebad..0604347484 100644 --- a/src/main/java/cn/nukkit/network/protocol/TakeItemEntityPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/TakeItemEntityPacket.java @@ -12,13 +12,15 @@ public class TakeItemEntityPacket extends DataPacket { @Override public void decode() { + this.target = this.getEntityRuntimeId(); + this.entityId = this.getEntityRuntimeId(); } @Override public void encode() { this.reset(); - this.putUnsignedVarLong(this.target); - this.putUnsignedVarLong(this.entityId); + this.putEntityRuntimeId(this.target); + this.putEntityRuntimeId(this.entityId); } @Override From 980670e080102ecc7a2523dae0c849af158fd204 Mon Sep 17 00:00:00 2001 From: boybook Date: Thu, 19 Oct 2017 16:54:25 +0800 Subject: [PATCH 153/175] Fixed sleeping bugs and optimized the bed's notices. --- src/main/java/cn/nukkit/block/BlockBed.java | 7 ++++--- src/main/java/cn/nukkit/entity/EntityHuman.java | 3 ++- src/main/java/cn/nukkit/utils/Binary.java | 8 +++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/cn/nukkit/block/BlockBed.java b/src/main/java/cn/nukkit/block/BlockBed.java index 72ffe14a2a..6f84f2bf02 100644 --- a/src/main/java/cn/nukkit/block/BlockBed.java +++ b/src/main/java/cn/nukkit/block/BlockBed.java @@ -5,6 +5,7 @@ import cn.nukkit.blockentity.BlockEntityBed; import cn.nukkit.item.Item; import cn.nukkit.item.ItemBed; +import cn.nukkit.lang.TranslationContainer; import cn.nukkit.level.Level; import cn.nukkit.math.AxisAlignedBB; import cn.nukkit.math.BlockFace; @@ -77,7 +78,7 @@ public boolean onActivate(Item item, Player player) { boolean isNight = (time >= Level.TIME_NIGHT && time < Level.TIME_SUNRISE); if (player != null && !isNight) { - player.sendMessage(TextFormat.GRAY + "You can only sleep at night"); + player.sendMessage(new TranslationContainer("tile.bed.noSleep")); return true; } @@ -100,7 +101,7 @@ public boolean onActivate(Item item, Player player) { b = blockWest; } else { if (player != null) { - player.sendMessage(TextFormat.GRAY + "This bed is incomplete"); + player.sendMessage(new TranslationContainer("tile.bed.notValid")); } return true; @@ -108,7 +109,7 @@ public boolean onActivate(Item item, Player player) { } if (player != null && !player.sleepOn(b)) { - player.sendMessage(TextFormat.GRAY + "This bed is occupied"); + player.sendMessage(new TranslationContainer("tile.bed.occupied")); } diff --git a/src/main/java/cn/nukkit/entity/EntityHuman.java b/src/main/java/cn/nukkit/entity/EntityHuman.java index 372caf882b..ca60201019 100644 --- a/src/main/java/cn/nukkit/entity/EntityHuman.java +++ b/src/main/java/cn/nukkit/entity/EntityHuman.java @@ -22,7 +22,8 @@ public class EntityHuman extends EntityHumanType { public static final int DATA_PLAYER_FLAG_DEAD = 2; //TODO: CHECK public static final int DATA_PLAYER_FLAGS = 27; - public static final int DATA_PLAYER_BED_POSITION = 17; + + public static final int DATA_PLAYER_BED_POSITION = 29; public static final int DATA_PLAYER_BUTTON_TEXT = 40; protected UUID uuid; diff --git a/src/main/java/cn/nukkit/utils/Binary.java b/src/main/java/cn/nukkit/utils/Binary.java index b50344000f..c07c44cf19 100644 --- a/src/main/java/cn/nukkit/utils/Binary.java +++ b/src/main/java/cn/nukkit/utils/Binary.java @@ -123,14 +123,12 @@ public static byte[] writeMetadata(EntityMetadata metadata) { break; case Entity.DATA_TYPE_SLOT: SlotEntityData slot = (SlotEntityData) d; - stream.putLShort(slot.blockId); - stream.putByte((byte) slot.meta); - stream.putLShort(slot.count); + stream.putSlot(slot.getData()); break; case Entity.DATA_TYPE_POS: IntPositionEntityData pos = (IntPositionEntityData) d; stream.putVarInt(pos.x); - stream.putByte((byte) pos.y); + stream.putVarInt(pos.y); stream.putVarInt(pos.z); break; case Entity.DATA_TYPE_LONG: @@ -177,7 +175,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.getBlockVector3(); + BlockVector3 v3 = stream.getSignedBlockPosition(); value = new IntPositionEntityData(key, v3.x, v3.y, v3.z); break; case Entity.DATA_TYPE_LONG: From 28614221b21792e0a35ae9cfdae2a55501a52b22 Mon Sep 17 00:00:00 2001 From: boybook Date: Thu, 19 Oct 2017 19:57:30 +0800 Subject: [PATCH 154/175] Restoring the DummyBossBar Entity is visible --- src/main/java/cn/nukkit/utils/DummyBossBar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/utils/DummyBossBar.java b/src/main/java/cn/nukkit/utils/DummyBossBar.java index bc7488225a..0fb66b68ec 100644 --- a/src/main/java/cn/nukkit/utils/DummyBossBar.java +++ b/src/main/java/cn/nukkit/utils/DummyBossBar.java @@ -143,7 +143,7 @@ private void createBossEntity() { .putShort(Entity.DATA_MAX_AIR, 400) .putLong(Entity.DATA_LEAD_HOLDER_EID, -1) .putString(Entity.DATA_NAMETAG, text) // Set the entity name - .putInt(Entity.DATA_SCALE, 0); // And make it invisible + .putFloat(Entity.DATA_SCALE, 0); // And make it invisible player.dataPacket(pkAdd); } From 57be4e312bee3c9e0bac05d5f50ef9fe5e5a0be3 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Fri, 20 Oct 2017 14:53:49 +0200 Subject: [PATCH 155/175] use String::isEmpty() --- src/main/java/cn/nukkit/Player.java | 8 ++++---- src/main/java/cn/nukkit/Server.java | 2 +- src/main/java/cn/nukkit/block/BlockPistonBase.java | 7 ++++--- src/main/java/cn/nukkit/network/query/QueryHandler.java | 2 +- src/main/java/cn/nukkit/raknet/server/SessionManager.java | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 75d381c09a..588b4e34a4 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -3243,7 +3243,7 @@ public boolean chat(String message) { } for (String msg : message.split("\n")) { - if (!"".equals(msg.trim()) && msg.length() <= 255 && this.messageCounter-- > 0) { + if (!msg.trim().isEmpty() && msg.length() <= 255 && this.messageCounter-- > 0) { PlayerChatEvent chatEvent = new PlayerChatEvent(this, msg); this.server.getPluginManager().callEvent(chatEvent); if (!chatEvent.isCancelled()) { @@ -3286,12 +3286,12 @@ public boolean kick(PlayerKickEvent.Reason reason, String reasonString, boolean String message; if (isAdmin) { if (!this.isBanned()) { - message = "Kicked by admin." + (!"".equals(reasonString) ? " Reason: " + reasonString : ""); + message = "Kicked by admin." + (!reasonString.isEmpty() ? " Reason: " + reasonString : ""); } else { message = reasonString; } } else { - if ("".equals(reasonString)) { + if (reasonString.isEmpty()) { message = "disconnectionScreen.noReason"; } else { message = reasonString; @@ -3606,7 +3606,7 @@ public void save(boolean async) { this.namedTag.putInt("foodLevel", this.getFoodData().getLevel()); this.namedTag.putFloat("foodSaturationLevel", this.getFoodData().getFoodSaturationLevel()); - if (!"".equals(this.username) && this.namedTag != null) { + if (!this.username.isEmpty() && this.namedTag != null) { this.server.saveOfflinePlayerData(this.username, this.namedTag, async); } } diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index 301f2ba5fa..b7f4943cfe 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -431,7 +431,7 @@ public class Server { if (this.getDefaultLevel() == null) { String defaultName = this.getPropertyString("level-name", "world"); - if (defaultName == null || "".equals(defaultName.trim())) { + if (defaultName == null || defaultName.trim().isEmpty()) { this.getLogger().warning("level-name cannot be null, using default"); defaultName = "world"; this.setPropertyString("level-name", defaultName); diff --git a/src/main/java/cn/nukkit/block/BlockPistonBase.java b/src/main/java/cn/nukkit/block/BlockPistonBase.java index 43212a2cd2..b1c0d16383 100644 --- a/src/main/java/cn/nukkit/block/BlockPistonBase.java +++ b/src/main/java/cn/nukkit/block/BlockPistonBase.java @@ -10,6 +10,7 @@ import cn.nukkit.level.sound.PistonOutSound; import cn.nukkit.math.BlockFace; import cn.nukkit.math.Vector3; +import cn.nukkit.nbt.tag.CompoundTag; import java.util.ArrayList; import java.util.List; @@ -56,14 +57,14 @@ public boolean place(Item item, Block block, Block target, BlockFace face, doubl } this.level.setBlock(block, this, true, false); - /*CompoundTag nbt = new CompoundTag("") + CompoundTag nbt = new CompoundTag("") .putString("id", BlockEntity.PISTON_ARM) .putInt("x", (int) this.x) .putInt("y", (int) this.y) .putInt("z", (int) this.z) - .putBoolean("Sticky", this.sticky);*/ + .putBoolean("Sticky", this.sticky); - //BlockEntityPistonArm be = new BlockEntityPistonArm(this.level.getChunk((int) this.x >> 4, (int) this.z >> 4), nbt); bug? + BlockEntityPistonArm be = new BlockEntityPistonArm(this.level.getChunk((int) this.x >> 4, (int) this.z >> 4), nbt); //this.checkState(); return true; diff --git a/src/main/java/cn/nukkit/network/query/QueryHandler.java b/src/main/java/cn/nukkit/network/query/QueryHandler.java index de232afe81..ff5fee844f 100644 --- a/src/main/java/cn/nukkit/network/query/QueryHandler.java +++ b/src/main/java/cn/nukkit/network/query/QueryHandler.java @@ -28,7 +28,7 @@ public QueryHandler() { this.server = Server.getInstance(); this.server.getLogger().info(this.server.getLanguage().translateString("nukkit.server.query.start")); String ip = this.server.getIp(); - String addr = (!"".equals(ip)) ? ip : "0.0.0.0"; + String addr = (!ip.isEmpty()) ? ip : "0.0.0.0"; int port = this.server.getPort(); this.server.getLogger().info(this.server.getLanguage().translateString("nukkit.server.query.info", String.valueOf(port))); diff --git a/src/main/java/cn/nukkit/raknet/server/SessionManager.java b/src/main/java/cn/nukkit/raknet/server/SessionManager.java index d5252f15eb..df6053554e 100644 --- a/src/main/java/cn/nukkit/raknet/server/SessionManager.java +++ b/src/main/java/cn/nukkit/raknet/server/SessionManager.java @@ -82,7 +82,7 @@ private void tickProcessor() throws Exception { } --max; } catch (Exception e) { - if (!"".equals(currentSource)) { + if (!currentSource.isEmpty()) { this.blockAddress(currentSource); } // else ignore From 82cf2fe5e6a568554b02c61bbfc1552882b0c78a Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Fri, 20 Oct 2017 15:23:13 +0200 Subject: [PATCH 156/175] Fixed item sending in in double chest inventory --- src/main/java/cn/nukkit/block/BlockLever.java | 2 +- src/main/java/cn/nukkit/inventory/DoubleChestInventory.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/block/BlockLever.java b/src/main/java/cn/nukkit/block/BlockLever.java index e1ab5b3ac7..498ed4c695 100644 --- a/src/main/java/cn/nukkit/block/BlockLever.java +++ b/src/main/java/cn/nukkit/block/BlockLever.java @@ -83,7 +83,7 @@ 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.isSolid()) { + if (target.isNormalBlock()) { this.meta = LeverOrientation.forFacings(face, player.getHorizontalFacing()).getMetadata(); this.getLevel().setBlock(block, this, true, true); return true; diff --git a/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java b/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java index 38f83cc912..522e030bae 100644 --- a/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java +++ b/src/main/java/cn/nukkit/inventory/DoubleChestInventory.java @@ -106,6 +106,8 @@ public void setContents(Map items) { @Override public void onOpen(Player who) { super.onOpen(who); + this.left.viewers.add(who); + this.right.viewers.add(who); if (this.getViewers().size() == 1) { BlockEventPacket pk1 = new BlockEventPacket(); @@ -165,6 +167,8 @@ public void onClose(Player who) { } } + this.left.viewers.remove(who); + this.right.viewers.remove(who); super.onClose(who); } From 797085563a8bc6f13835b82a37e11ec1a2ce1718 Mon Sep 17 00:00:00 2001 From: boybook Date: Sat, 21 Oct 2017 00:45:03 +0800 Subject: [PATCH 157/175] Add serverId in UnconnectedPong Packet --- src/main/java/cn/nukkit/network/RakNetInterface.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index 8e98db40e8..4dc2fba7a6 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -216,7 +216,8 @@ public void setName(String name) { ProtocolInfo.CURRENT_PROTOCOL + ";" + ProtocolInfo.MINECRAFT_VERSION_NETWORK + ";" + info.getPlayerCount() + ";" + - info.getMaxPlayerCount()); + info.getMaxPlayerCount() + ";" + + Server.getInstance().getServerUniqueId().toString()); } public void setPortCheck(boolean value) { From 1ad08c76b578c7443a7a0b6b551dd79ee344c697 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sat, 21 Oct 2017 12:59:06 +0200 Subject: [PATCH 158/175] Added jukebox --- src/main/java/cn/nukkit/Server.java | 1 + .../java/cn/nukkit/block/BlockJukebox.java | 41 ++++++++++- .../cn/nukkit/blockentity/BlockEntity.java | 1 + .../blockentity/BlockEntityJukebox.java | 70 +++++++++++++++++++ src/main/java/cn/nukkit/item/Item.java | 12 ++++ src/main/java/cn/nukkit/item/ItemRecord.java | 8 ++- .../java/cn/nukkit/item/ItemRecord11.java | 26 +++++++ .../java/cn/nukkit/item/ItemRecord13.java | 26 +++++++ .../java/cn/nukkit/item/ItemRecordBlocks.java | 26 +++++++ .../java/cn/nukkit/item/ItemRecordCat.java | 26 +++++++ .../java/cn/nukkit/item/ItemRecordChirp.java | 26 +++++++ .../java/cn/nukkit/item/ItemRecordFar.java | 26 +++++++ .../java/cn/nukkit/item/ItemRecordMall.java | 26 +++++++ .../cn/nukkit/item/ItemRecordMellohi.java | 26 +++++++ .../java/cn/nukkit/item/ItemRecordStal.java | 26 +++++++ .../java/cn/nukkit/item/ItemRecordStrad.java | 26 +++++++ .../java/cn/nukkit/item/ItemRecordWait.java | 26 +++++++ .../java/cn/nukkit/item/ItemRecordWard.java | 26 +++++++ 18 files changed, 441 insertions(+), 4 deletions(-) create mode 100644 src/main/java/cn/nukkit/blockentity/BlockEntityJukebox.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecord11.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecord13.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecordBlocks.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecordCat.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecordChirp.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecordFar.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecordMall.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecordMellohi.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecordStal.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecordStrad.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecordWait.java create mode 100644 src/main/java/cn/nukkit/item/ItemRecordWard.java diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index b7f4943cfe..665a53a998 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -1981,6 +1981,7 @@ private void registerBlockEntities() { BlockEntity.registerBlockEntity(BlockEntity.COMPARATOR, BlockEntityComparator.class); BlockEntity.registerBlockEntity(BlockEntity.HOPPER, BlockEntityHopper.class); BlockEntity.registerBlockEntity(BlockEntity.BED, BlockEntityBed.class); + BlockEntity.registerBlockEntity(BlockEntity.JUKEBOX, BlockEntityJukebox.class); } public static Server getInstance() { diff --git a/src/main/java/cn/nukkit/block/BlockJukebox.java b/src/main/java/cn/nukkit/block/BlockJukebox.java index bbe46f0c4a..419d11d1c7 100644 --- a/src/main/java/cn/nukkit/block/BlockJukebox.java +++ b/src/main/java/cn/nukkit/block/BlockJukebox.java @@ -1,7 +1,13 @@ package cn.nukkit.block; import cn.nukkit.Player; +import cn.nukkit.blockentity.BlockEntity; +import cn.nukkit.blockentity.BlockEntityJukebox; import cn.nukkit.item.Item; +import cn.nukkit.item.ItemRecord; +import cn.nukkit.math.BlockFace; +import cn.nukkit.nbt.tag.CompoundTag; +import cn.nukkit.nbt.tag.ListTag; /** * Created by CreeperFace on 7.8.2017. @@ -33,7 +39,40 @@ public boolean canBeActivated() { @Override public boolean onActivate(Item item, Player player) { - //TODO: music + BlockEntity blockEntity = this.getLevel().getBlockEntity(this); + if (blockEntity == null || !(blockEntity instanceof BlockEntityJukebox)) { + blockEntity = this.createBlockEntity(); + } + + BlockEntityJukebox jukebox = (BlockEntityJukebox) blockEntity; + if (jukebox.getRecordItem().getId() != 0) { + jukebox.dropItem(); + } else if (item instanceof ItemRecord) { + jukebox.setRecordItem(item); + jukebox.play(); + } + + return false; + } + + @Override + public boolean place(Item item, Block block, Block target, BlockFace face, double fx, double fy, double fz, Player player) { + if (super.place(item, block, target, face, fx, fy, fz, player)) { + createBlockEntity(); + return true; + } + return false; } + + private BlockEntity createBlockEntity() { + CompoundTag nbt = new CompoundTag() + .putList(new ListTag<>("Items")) + .putString("id", BlockEntity.JUKEBOX) + .putInt("x", getFloorX()) + .putInt("y", getFloorY()) + .putInt("z", getFloorZ()); + + return BlockEntity.createBlockEntity(BlockEntity.JUKEBOX, this.level.getChunk(getFloorX() >> 4, getFloorZ() >> 4), nbt); + } } diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntity.java b/src/main/java/cn/nukkit/blockentity/BlockEntity.java index ce054acb6d..f0571ec255 100644 --- a/src/main/java/cn/nukkit/blockentity/BlockEntity.java +++ b/src/main/java/cn/nukkit/blockentity/BlockEntity.java @@ -38,6 +38,7 @@ public abstract class BlockEntity extends Position { public static final String COMPARATOR = "Comparator"; public static final String HOPPER = "Hopper"; public static final String BED = "Bed"; + public static final String JUKEBOX = "Jukebox"; public static long count = 1; diff --git a/src/main/java/cn/nukkit/blockentity/BlockEntityJukebox.java b/src/main/java/cn/nukkit/blockentity/BlockEntityJukebox.java new file mode 100644 index 0000000000..6ae882863d --- /dev/null +++ b/src/main/java/cn/nukkit/blockentity/BlockEntityJukebox.java @@ -0,0 +1,70 @@ +package cn.nukkit.blockentity; + +import cn.nukkit.Server; +import cn.nukkit.block.Block; +import cn.nukkit.item.Item; +import cn.nukkit.item.ItemRecord; +import cn.nukkit.level.format.FullChunk; +import cn.nukkit.nbt.NBTIO; +import cn.nukkit.nbt.tag.CompoundTag; +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +import java.util.Objects; + +/** + * @author CreeperFace + */ +public class BlockEntityJukebox extends BlockEntitySpawnable { + + private Item recordItem; + + public BlockEntityJukebox(FullChunk chunk, CompoundTag nbt) { + super(chunk, nbt); + + this.recordItem = NBTIO.getItemHelper(nbt.getCompound("RecordItem")); + } + + @Override + public boolean isBlockEntityValid() { + return this.getLevel().getBlockIdAt(getFloorX(), getFloorY(), getFloorZ()) == Block.JUKEBOX; + } + + public void setRecordItem(Item recordItem) { + Objects.requireNonNull(recordItem, "Record item cannot be null"); + this.recordItem = recordItem; + } + + public Item getRecordItem() { + return recordItem; + } + + public void play() { + if (this.recordItem instanceof ItemRecord) { + LevelSoundEventPacket pk = new LevelSoundEventPacket(); + pk.sound = ((ItemRecord) this.recordItem).getSoundId(); + pk.pitch = 1; + pk.extraData = -1; + pk.x = (float) this.x; + pk.y = (float) this.y; + pk.z = (float) this.z; + + Server.broadcastPacket(this.level.getPlayers().values(), pk); + } + } + + public void dropItem() { + this.level.dropItem(this.up(), this.recordItem); + } + + @Override + public void saveNBT() { + super.saveNBT(); + this.namedTag.putCompound("RecordItem", NBTIO.putItemHelper(this.recordItem)); + } + + @Override + public CompoundTag getSpawnCompound() { + return getDefaultCompound(this, JUKEBOX) + .putCompound("RecordItem", NBTIO.putItemHelper(this.recordItem)); + } +} diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java index 9ebf5b52f3..52604de2ab 100644 --- a/src/main/java/cn/nukkit/item/Item.java +++ b/src/main/java/cn/nukkit/item/Item.java @@ -815,6 +815,18 @@ public static void init() { list[COOKED_SALMON] = ItemSalmonCooked.class; //463 list[GOLDEN_APPLE_ENCHANTED] = ItemAppleGoldEnchanted.class; //466 + list[RECORD_11] = ItemRecord11.class; + list[RECORD_CAT] = ItemRecordCat.class; + list[RECORD_13] = ItemRecord13.class; + list[RECORD_BLOCKS] = ItemRecordBlocks.class; + list[RECORD_CHIRP] = ItemRecordChirp.class; + list[RECORD_FAR] = ItemRecordFar.class; + list[RECORD_WARD] = ItemRecordWard.class; + list[RECORD_MALL] = ItemRecordMall.class; + list[RECORD_MELLOHI] = ItemRecordMellohi.class; + list[RECORD_STAL] = ItemRecordStal.class; + list[RECORD_STRAD] = ItemRecordStrad.class; + list[RECORD_WAIT] = ItemRecordWait.class; for (int i = 0; i < 256; ++i) { if (Block.list[i] != null) { diff --git a/src/main/java/cn/nukkit/item/ItemRecord.java b/src/main/java/cn/nukkit/item/ItemRecord.java index e58ab09194..84f5c0fec1 100644 --- a/src/main/java/cn/nukkit/item/ItemRecord.java +++ b/src/main/java/cn/nukkit/item/ItemRecord.java @@ -1,9 +1,9 @@ package cn.nukkit.item; /** - * Created by CreeperFace on 7.8.2017. + * @author CreeperFace */ -public class ItemRecord extends Item { +public abstract class ItemRecord extends Item { public ItemRecord() { this(0, 1); @@ -14,11 +14,13 @@ public ItemRecord(Integer meta) { } public ItemRecord(Integer meta, int count) { - super(meta, count); //TODO: records + super(meta, count); } @Override public int getMaxStackSize() { return 1; } + + public abstract int getSoundId(); } diff --git a/src/main/java/cn/nukkit/item/ItemRecord11.java b/src/main/java/cn/nukkit/item/ItemRecord11.java new file mode 100644 index 0000000000..a5117a0b2b --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecord11.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecord11 extends ItemRecord { + + public ItemRecord11() { + this(0, 1); + } + + public ItemRecord11(Integer meta) { + this(meta, 1); + } + + public ItemRecord11(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_11; + } +} diff --git a/src/main/java/cn/nukkit/item/ItemRecord13.java b/src/main/java/cn/nukkit/item/ItemRecord13.java new file mode 100644 index 0000000000..5537802709 --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecord13.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecord13 extends ItemRecord { + + public ItemRecord13() { + this(0, 1); + } + + public ItemRecord13(Integer meta) { + this(meta, 1); + } + + public ItemRecord13(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_13; + } +} diff --git a/src/main/java/cn/nukkit/item/ItemRecordBlocks.java b/src/main/java/cn/nukkit/item/ItemRecordBlocks.java new file mode 100644 index 0000000000..21aabbf583 --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecordBlocks.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecordBlocks extends ItemRecord { + + public ItemRecordBlocks() { + this(0, 1); + } + + public ItemRecordBlocks(Integer meta) { + this(meta, 1); + } + + public ItemRecordBlocks(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_BLOCKS; + } +} diff --git a/src/main/java/cn/nukkit/item/ItemRecordCat.java b/src/main/java/cn/nukkit/item/ItemRecordCat.java new file mode 100644 index 0000000000..ac826f6853 --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecordCat.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecordCat extends ItemRecord { + + public ItemRecordCat() { + this(0, 1); + } + + public ItemRecordCat(Integer meta) { + this(meta, 1); + } + + public ItemRecordCat(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_CAT; + } +} diff --git a/src/main/java/cn/nukkit/item/ItemRecordChirp.java b/src/main/java/cn/nukkit/item/ItemRecordChirp.java new file mode 100644 index 0000000000..3e8cc21ae0 --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecordChirp.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecordChirp extends ItemRecord { + + public ItemRecordChirp() { + this(0, 1); + } + + public ItemRecordChirp(Integer meta) { + this(meta, 1); + } + + public ItemRecordChirp(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_CHIRP; + } +} diff --git a/src/main/java/cn/nukkit/item/ItemRecordFar.java b/src/main/java/cn/nukkit/item/ItemRecordFar.java new file mode 100644 index 0000000000..cd84d1def5 --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecordFar.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecordFar extends ItemRecord { + + public ItemRecordFar() { + this(0, 1); + } + + public ItemRecordFar(Integer meta) { + this(meta, 1); + } + + public ItemRecordFar(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_FAR; + } +} diff --git a/src/main/java/cn/nukkit/item/ItemRecordMall.java b/src/main/java/cn/nukkit/item/ItemRecordMall.java new file mode 100644 index 0000000000..5c2da3936b --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecordMall.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecordMall extends ItemRecord { + + public ItemRecordMall() { + this(0, 1); + } + + public ItemRecordMall(Integer meta) { + this(meta, 1); + } + + public ItemRecordMall(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_MALL; + } +} diff --git a/src/main/java/cn/nukkit/item/ItemRecordMellohi.java b/src/main/java/cn/nukkit/item/ItemRecordMellohi.java new file mode 100644 index 0000000000..13fb5c2d11 --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecordMellohi.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecordMellohi extends ItemRecord { + + public ItemRecordMellohi() { + this(0, 1); + } + + public ItemRecordMellohi(Integer meta) { + this(meta, 1); + } + + public ItemRecordMellohi(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_MELLOHI; + } +} diff --git a/src/main/java/cn/nukkit/item/ItemRecordStal.java b/src/main/java/cn/nukkit/item/ItemRecordStal.java new file mode 100644 index 0000000000..3a4824de7c --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecordStal.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecordStal extends ItemRecord { + + public ItemRecordStal() { + this(0, 1); + } + + public ItemRecordStal(Integer meta) { + this(meta, 1); + } + + public ItemRecordStal(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_STAL; + } +} diff --git a/src/main/java/cn/nukkit/item/ItemRecordStrad.java b/src/main/java/cn/nukkit/item/ItemRecordStrad.java new file mode 100644 index 0000000000..1c7e42dd8c --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecordStrad.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecordStrad extends ItemRecord { + + public ItemRecordStrad() { + this(0, 1); + } + + public ItemRecordStrad(Integer meta) { + this(meta, 1); + } + + public ItemRecordStrad(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_STRAD; + } +} diff --git a/src/main/java/cn/nukkit/item/ItemRecordWait.java b/src/main/java/cn/nukkit/item/ItemRecordWait.java new file mode 100644 index 0000000000..738f26f088 --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecordWait.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecordWait extends ItemRecord { + + public ItemRecordWait() { + this(0, 1); + } + + public ItemRecordWait(Integer meta) { + this(meta, 1); + } + + public ItemRecordWait(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_WAIT; + } +} diff --git a/src/main/java/cn/nukkit/item/ItemRecordWard.java b/src/main/java/cn/nukkit/item/ItemRecordWard.java new file mode 100644 index 0000000000..b8f2f79154 --- /dev/null +++ b/src/main/java/cn/nukkit/item/ItemRecordWard.java @@ -0,0 +1,26 @@ +package cn.nukkit.item; + +import cn.nukkit.network.protocol.LevelSoundEventPacket; + +/** + * @author CreeperFace + */ +public class ItemRecordWard extends ItemRecord { + + public ItemRecordWard() { + this(0, 1); + } + + public ItemRecordWard(Integer meta) { + this(meta, 1); + } + + public ItemRecordWard(Integer meta, int count) { + super(meta, count); + } + + @Override + public int getSoundId() { + return LevelSoundEventPacket.SOUND_RECORD_WARD; + } +} From 83060d609f6cee4899cf9c2a5296a96b2d236058 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Sun, 22 Oct 2017 14:19:43 +0200 Subject: [PATCH 159/175] Make it public --- src/main/java/cn/nukkit/utils/ClientChainData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/utils/ClientChainData.java b/src/main/java/cn/nukkit/utils/ClientChainData.java index 21297693f5..6d1ce03ca8 100644 --- a/src/main/java/cn/nukkit/utils/ClientChainData.java +++ b/src/main/java/cn/nukkit/utils/ClientChainData.java @@ -21,7 +21,7 @@ * Nukkit Project * =============== */ -public final class ClientChainData { +public class ClientChainData { public static ClientChainData of(byte[] buffer) { return new ClientChainData(buffer); From 21718db93bf8e533ded908263deb9e94d29423e2 Mon Sep 17 00:00:00 2001 From: boybook Date: Wed, 25 Oct 2017 20:05:20 +0800 Subject: [PATCH 160/175] Full Pong result information: MOTD, Sub MOTD and default gamemode. But... But they do not seem to work... Let it go :D --- src/main/java/cn/nukkit/Server.java | 17 +++++++++++++---- src/main/java/cn/nukkit/network/Network.java | 13 +++++++++++-- .../java/cn/nukkit/network/RakNetInterface.java | 8 +++++--- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index 665a53a998..fe2c81520f 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -264,6 +264,7 @@ public class Server { this.properties = new Config(this.dataPath + "server.properties", Config.PROPERTIES, new ConfigSection() { { put("motd", "Nukkit Server For Minecraft: PE"); + put("sub-motd", "Powered by Nukkit"); put("server-port", 19132); put("server-ip", "0.0.0.0"); put("view-distance", 10); @@ -1185,15 +1186,19 @@ public boolean getForceGamemode() { } public static String getGamemodeString(int mode) { + return getGamemodeString(mode, false); + } + + public static String getGamemodeString(int mode, boolean direct) { switch (mode) { case Player.SURVIVAL: - return "%gameMode.survival"; + return direct ? "Survival" : "%gameMode.survival"; case Player.CREATIVE: - return "%gameMode.creative"; + return direct ? "Creative" : "%gameMode.creative"; case Player.ADVENTURE: - return "%gameMode.adventure"; + return direct ? "Adventure" : "%gameMode.adventure"; case Player.SPECTATOR: - return "%gameMode.spectator"; + return direct ? "Spectator" : "%gameMode.spectator"; } return "UNKNOWN"; } @@ -1281,6 +1286,10 @@ public String getMotd() { return this.getPropertyString("motd", "Nukkit Server For Minecraft: PE"); } + public String getSubMotd() { + return this.getPropertyString("sub-motd", "Powered by Nukkit"); + } + public boolean getForceResources() { return this.getPropertyBoolean("force-resources", false); } diff --git a/src/main/java/cn/nukkit/network/Network.java b/src/main/java/cn/nukkit/network/Network.java index 25185c798a..73506daa9a 100644 --- a/src/main/java/cn/nukkit/network/Network.java +++ b/src/main/java/cn/nukkit/network/Network.java @@ -41,6 +41,7 @@ public class Network { private double download = 0; private String name; + private String subName; public Network(Server server) { this.registerPackets(); @@ -91,7 +92,7 @@ public void registerInterface(SourceInterface interfaz) { this.advancedInterfaces.add((AdvancedSourceInterface) interfaz); ((AdvancedSourceInterface) interfaz).setNetwork(this); } - interfaz.setName(this.name); + interfaz.setName(this.name + "!@#" + this.subName); } public void unregisterInterface(SourceInterface interfaz) { @@ -108,9 +109,17 @@ public String getName() { return name; } + public String getSubName() { + return subName; + } + + public void setSubName(String subName) { + this.subName = subName; + } + public void updateName() { for (SourceInterface interfaz : this.interfaces) { - interfaz.setName(this.name); + interfaz.setName(this.name + "!@#" + this.subName); } } diff --git a/src/main/java/cn/nukkit/network/RakNetInterface.java b/src/main/java/cn/nukkit/network/RakNetInterface.java index 4dc2fba7a6..e5df71d4d0 100644 --- a/src/main/java/cn/nukkit/network/RakNetInterface.java +++ b/src/main/java/cn/nukkit/network/RakNetInterface.java @@ -210,14 +210,16 @@ public void notifyACK(String identifier, int identifierACK) { @Override public void setName(String name) { QueryRegenerateEvent info = this.server.getQueryInformation(); - + String[] names = name.split("!@#"); //Split double names within the program this.handler.sendOption("name", - "MCPE;" + Utils.rtrim(name.replace(";", "\\;"), '\\') + ";" + + "MCPE;" + Utils.rtrim(names[0].replace(";", "\\;"), '\\') + ";" + ProtocolInfo.CURRENT_PROTOCOL + ";" + ProtocolInfo.MINECRAFT_VERSION_NETWORK + ";" + info.getPlayerCount() + ";" + info.getMaxPlayerCount() + ";" + - Server.getInstance().getServerUniqueId().toString()); + this.server.getServerUniqueId().toString() + ";" + + (names.length > 1 ? Utils.rtrim(names[1].replace(";", "\\;"), '\\') : "") + ";" + + Server.getGamemodeString(this.server.getDefaultGamemode(), true) + ";"); } public void setPortCheck(boolean value) { From ae76c44ad4d8b809b9e6126397df2a7b5df6085b Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Wed, 25 Oct 2017 18:07:15 +0200 Subject: [PATCH 161/175] Fixed PlaySoundPacket, temporarily removed music discs --- src/main/java/cn/nukkit/item/Item.java | 4 ++-- src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java | 2 +- src/main/java/cn/nukkit/utils/ClientChainData.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java index 52604de2ab..a1728c361d 100644 --- a/src/main/java/cn/nukkit/item/Item.java +++ b/src/main/java/cn/nukkit/item/Item.java @@ -815,7 +815,7 @@ public static void init() { list[COOKED_SALMON] = ItemSalmonCooked.class; //463 list[GOLDEN_APPLE_ENCHANTED] = ItemAppleGoldEnchanted.class; //466 - list[RECORD_11] = ItemRecord11.class; + /*list[RECORD_11] = ItemRecord11.class; list[RECORD_CAT] = ItemRecordCat.class; list[RECORD_13] = ItemRecord13.class; list[RECORD_BLOCKS] = ItemRecordBlocks.class; @@ -826,7 +826,7 @@ public static void init() { list[RECORD_MELLOHI] = ItemRecordMellohi.class; list[RECORD_STAL] = ItemRecordStal.class; list[RECORD_STRAD] = ItemRecordStrad.class; - list[RECORD_WAIT] = ItemRecordWait.class; + list[RECORD_WAIT] = ItemRecordWait.class;*/ for (int i = 0; i < 256; ++i) { if (Block.list[i] != null) { diff --git a/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java b/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java index 081179ccb4..f8b131f453 100644 --- a/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/PlaySoundPacket.java @@ -25,7 +25,7 @@ public void decode() { public void encode() { this.reset(); this.putString(this.name); - this.putBlockVector3(this.x, this.y, this.z); + this.putBlockVector3(this.x * 8, this.y * 8, this.z * 8); this.putLFloat(this.volume); this.putLFloat(this.pitch); } diff --git a/src/main/java/cn/nukkit/utils/ClientChainData.java b/src/main/java/cn/nukkit/utils/ClientChainData.java index 6d1ce03ca8..b4367e63b5 100644 --- a/src/main/java/cn/nukkit/utils/ClientChainData.java +++ b/src/main/java/cn/nukkit/utils/ClientChainData.java @@ -133,7 +133,7 @@ public int hashCode() { private BinaryStream bs = new BinaryStream(); - private ClientChainData(byte[] buffer) { + public ClientChainData(byte[] buffer) { bs.setBuffer(buffer, 0); decodeChainData(); decodeSkinData(); From 830091c1e8f8b9b95b4945a471f61c1482c9e595 Mon Sep 17 00:00:00 2001 From: boybook Date: Thu, 26 Oct 2017 17:28:55 +0800 Subject: [PATCH 162/175] Strange careless of showXboxProfile --- src/main/java/cn/nukkit/Player.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 588b4e34a4..234c37f0ac 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -4668,7 +4668,7 @@ public boolean isBreakingBlock() { */ public void showXboxProfile(String xuid) { ShowProfilePacket pk = new ShowProfilePacket(); - pk.xuid = getLoginChainData().getXUID(); + pk.xuid = xuid; this.dataPacket(pk); } } From 29d35eb82b852dcb283491fcc7973c1c222bed73 Mon Sep 17 00:00:00 2001 From: NycuRO Date: Thu, 26 Oct 2017 12:52:04 +0300 Subject: [PATCH 163/175] Revert "Fix for issue #1817 -- main thread stuck (rollback Zlib)" (#1851) --- src/main/java/cn/nukkit/utils/Zlib.java | 54 ++++++++++++++----------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/main/java/cn/nukkit/utils/Zlib.java b/src/main/java/cn/nukkit/utils/Zlib.java index 8f29b8ae52..fbf69bcb18 100644 --- a/src/main/java/cn/nukkit/utils/Zlib.java +++ b/src/main/java/cn/nukkit/utils/Zlib.java @@ -9,55 +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; - } - - public static byte[] inflate(byte[] data) throws IOException { - return inflate(new ByteArrayInputStream(data)); + return buf.get(); } - public static byte[] inflate(byte[] data, int maxSize) throws IOException { - return inflate(new ByteArrayInputStream(data, 0, maxSize)); - } } + From 76d1fd7c32c6e507db83bb0d99db3bdefc43e6d2 Mon Sep 17 00:00:00 2001 From: boybook Date: Thu, 26 Oct 2017 19:34:13 +0800 Subject: [PATCH 164/175] Teleport with pitch. --- src/main/java/cn/nukkit/Player.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 234c37f0ac..64af62cf5b 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -4112,7 +4112,7 @@ 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); + this.sendPosition(this, this.yaw, this.pitch, MovePlayerPacket.MODE_TELEPORT); this.checkTeleportPosition(); From 5d010addeb03493fc932c9f5c9604c31384814ad Mon Sep 17 00:00:00 2001 From: boybook Date: Thu, 26 Oct 2017 23:49:08 +0800 Subject: [PATCH 165/175] Support fast equip armor by right click on hand --- src/main/java/cn/nukkit/item/ItemArmor.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/cn/nukkit/item/ItemArmor.java b/src/main/java/cn/nukkit/item/ItemArmor.java index 618bc70d60..5b1573b50d 100644 --- a/src/main/java/cn/nukkit/item/ItemArmor.java +++ b/src/main/java/cn/nukkit/item/ItemArmor.java @@ -1,5 +1,8 @@ package cn.nukkit.item; +import cn.nukkit.Player; +import cn.nukkit.math.Vector3; + /** * author: MagicDroidX * Nukkit Project @@ -38,6 +41,20 @@ public boolean isArmor() { return true; } + @Override + public boolean onClickAir(Player player, Vector3 directionVector) { + if (this.isHelmet() && player.getInventory().getHelmet().isNull()) { + if (player.getInventory().setHelmet(this)) this.setCount(0); + } else if (this.isChestplate() && player.getInventory().getChestplate().isNull()) { + if (player.getInventory().setChestplate(this)) this.setCount(0); + } else if (this.isLeggings() && player.getInventory().getLeggings().isNull()) { + if (player.getInventory().setHelmet(this)) this.setCount(0); + } else if (this.isBoots() && player.getInventory().getBoots().isNull()) { + if (player.getInventory().setBoots(this)) this.setCount(0); + } + return this.getCount() == 0; + } + @Override public int getEnchantAbility() { switch (this.getTier()) { From 90edc065560bcbba4c5833d31bc8c116a98f4b54 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 26 Oct 2017 18:54:02 +0200 Subject: [PATCH 166/175] Improved ClientChainData --- src/main/java/cn/nukkit/Player.java | 4 +- .../java/cn/nukkit/utils/ClientChainData.java | 19 ++++++- .../java/cn/nukkit/utils/LoginChainData.java | 39 ++++++++++++++ src/main/java/cn/nukkit/utils/Zlib.java | 51 +++++++++++-------- 4 files changed, 87 insertions(+), 26 deletions(-) create mode 100644 src/main/java/cn/nukkit/utils/LoginChainData.java diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 64af62cf5b..ef83775664 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -215,7 +215,7 @@ public class Player extends EntityHuman implements CommandSender, InventoryHolde protected int lastEnderPearl = -1; - private ClientChainData loginChainData; + private LoginChainData loginChainData; public Block breakingBlock = null; @@ -4537,7 +4537,7 @@ public void transfer(InetSocketAddress address) { this.close(message, message, false); } - public ClientChainData getLoginChainData() { + public LoginChainData getLoginChainData() { return this.loginChainData; } diff --git a/src/main/java/cn/nukkit/utils/ClientChainData.java b/src/main/java/cn/nukkit/utils/ClientChainData.java index b4367e63b5..358bd6fd25 100644 --- a/src/main/java/cn/nukkit/utils/ClientChainData.java +++ b/src/main/java/cn/nukkit/utils/ClientChainData.java @@ -21,7 +21,7 @@ * Nukkit Project * =============== */ -public class ClientChainData { +public final class ClientChainData implements LoginChainData { public static ClientChainData of(byte[] buffer) { return new ClientChainData(buffer); @@ -31,58 +31,72 @@ public static ClientChainData read(LoginPacket pk) { return of(pk.getBuffer()); } + @Override public String getUsername() { return username; } + @Override public UUID getClientUUID() { return clientUUID; } + @Override public String getIdentityPublicKey() { return identityPublicKey; } + @Override public long getClientId() { return clientId; } + @Override public String getServerAddress() { return serverAddress; } + @Override public String getDeviceModel() { return deviceModel; } + @Override public int getDeviceOS() { return deviceOS; } + @Override public String getGameVersion() { return gameVersion; } + @Override public int getGuiScale() { return guiScale; } + @Override public String getLanguageCode() { return languageCode; } + @Override public String getXUID() { return xuid; } + @Override public int getCurrentInputMode() { return currentInputMode; } + @Override public int getDefaultInputMode() { return defaultInputMode; } + @Override public String getCapeData() { return capeData; } @@ -90,6 +104,7 @@ public String getCapeData() { public final static int UI_PROFILE_CLASSIC = 0; public final static int UI_PROFILE_POCKET = 1; + @Override public int getUIProfile() { return UIProfile; } @@ -133,7 +148,7 @@ public int hashCode() { private BinaryStream bs = new BinaryStream(); - public ClientChainData(byte[] buffer) { + private ClientChainData(byte[] buffer) { bs.setBuffer(buffer, 0); decodeChainData(); decodeSkinData(); diff --git a/src/main/java/cn/nukkit/utils/LoginChainData.java b/src/main/java/cn/nukkit/utils/LoginChainData.java new file mode 100644 index 0000000000..f29fa36db3 --- /dev/null +++ b/src/main/java/cn/nukkit/utils/LoginChainData.java @@ -0,0 +1,39 @@ +package cn.nukkit.utils; + +import java.util.UUID; + +/** + * @author CreeperFace + */ +public interface LoginChainData { + + String getUsername(); + + UUID getClientUUID(); + + String getIdentityPublicKey(); + + long getClientId(); + + String getServerAddress(); + + String getDeviceModel(); + + int getDeviceOS(); + + String getGameVersion(); + + int getGuiScale(); + + String getLanguageCode(); + + String getXUID(); + + int getCurrentInputMode(); + + int getDefaultInputMode(); + + String getCapeData(); + + int getUIProfile(); +} diff --git a/src/main/java/cn/nukkit/utils/Zlib.java b/src/main/java/cn/nukkit/utils/Zlib.java index 41f73abcfe..b64c4ab3d6 100644 --- a/src/main/java/cn/nukkit/utils/Zlib.java +++ b/src/main/java/cn/nukkit/utils/Zlib.java @@ -15,49 +15,56 @@ public static byte[] deflate(byte[] data) throws Exception { } 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)); - } } \ No newline at end of file From 3cba5040634415f5d15c8e6619b33693cd0ae2c1 Mon Sep 17 00:00:00 2001 From: CreeperFace Date: Thu, 26 Oct 2017 19:17:47 +0200 Subject: [PATCH 167/175] Fixed armor equip --- src/main/java/cn/nukkit/item/ItemArmor.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/cn/nukkit/item/ItemArmor.java b/src/main/java/cn/nukkit/item/ItemArmor.java index 5b1573b50d..a292eb2cdc 100644 --- a/src/main/java/cn/nukkit/item/ItemArmor.java +++ b/src/main/java/cn/nukkit/item/ItemArmor.java @@ -44,14 +44,19 @@ public boolean isArmor() { @Override public boolean onClickAir(Player player, Vector3 directionVector) { if (this.isHelmet() && player.getInventory().getHelmet().isNull()) { - if (player.getInventory().setHelmet(this)) this.setCount(0); + if (player.getInventory().setHelmet(this)) + player.getInventory().clear(player.getInventory().getHeldItemIndex()); } else if (this.isChestplate() && player.getInventory().getChestplate().isNull()) { - if (player.getInventory().setChestplate(this)) this.setCount(0); + if (player.getInventory().setChestplate(this)) + player.getInventory().clear(player.getInventory().getHeldItemIndex()); } else if (this.isLeggings() && player.getInventory().getLeggings().isNull()) { - if (player.getInventory().setHelmet(this)) this.setCount(0); + if (player.getInventory().setHelmet(this)) + player.getInventory().clear(player.getInventory().getHeldItemIndex()); } else if (this.isBoots() && player.getInventory().getBoots().isNull()) { - if (player.getInventory().setBoots(this)) this.setCount(0); + if (player.getInventory().setBoots(this)) + player.getInventory().clear(player.getInventory().getHeldItemIndex()); } + return this.getCount() == 0; } From a09374451b86f5ca2ab4b16856c8959caa75fbb2 Mon Sep 17 00:00:00 2001 From: boybook Date: Fri, 27 Oct 2017 13:53:18 +0800 Subject: [PATCH 168/175] The xbox info will be show in the player list. --- src/main/java/cn/nukkit/Player.java | 4 +-- src/main/java/cn/nukkit/Server.java | 26 ++++++++++++------- .../java/cn/nukkit/entity/EntityHuman.java | 5 +++- .../network/protocol/PlayerListPacket.java | 6 +++++ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 64af62cf5b..d44a3544db 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -637,7 +637,7 @@ public String getDisplayName() { public void setDisplayName(String displayName) { this.displayName = displayName; if (this.spawned) { - this.server.updatePlayerListData(this.getUniqueId(), this.getId(), this.getDisplayName(), this.getSkin()); + this.server.updatePlayerListData(this.getUniqueId(), this.getId(), this.getDisplayName(), this.getSkin(), this.getLoginChainData().getXUID()); } } @@ -645,7 +645,7 @@ public void setDisplayName(String displayName) { public void setSkin(Skin skin) { super.setSkin(skin); if (this.spawned) { - this.server.updatePlayerListData(this.getUniqueId(), this.getId(), this.getDisplayName(), skin); + this.server.updatePlayerListData(this.getUniqueId(), this.getId(), this.getDisplayName(), skin, this.getLoginChainData().getXUID()); } } diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index fe2c81520f..640722f7b4 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -833,7 +833,7 @@ public void addPlayer(String identifier, Player player) { public void addOnlinePlayer(Player player) { this.playerList.put(player.getUniqueId(), player); - this.updatePlayerListData(player.getUniqueId(), player.getId(), player.getDisplayName(), player.getSkin()); + this.updatePlayerListData(player.getUniqueId(), player.getId(), player.getDisplayName(), player.getSkin(), player.getLoginChainData().getXUID()); } public void removeOnlinePlayer(Player player) { @@ -849,18 +849,26 @@ public void removeOnlinePlayer(Player player) { } public void updatePlayerListData(UUID uuid, long entityId, String name, Skin skin) { - this.updatePlayerListData(uuid, entityId, name, skin, this.playerList.values()); + this.updatePlayerListData(uuid, entityId, name, skin, "", this.playerList.values()); + } + + public void updatePlayerListData(UUID uuid, long entityId, String name, Skin skin, String xboxUserId) { + this.updatePlayerListData(uuid, entityId, name, skin, xboxUserId, this.playerList.values()); } public void updatePlayerListData(UUID uuid, long entityId, String name, Skin skin, Player[] players) { + this.updatePlayerListData(uuid, entityId, name, skin, "", players); + } + + public void updatePlayerListData(UUID uuid, long entityId, String name, Skin skin, String xboxUserId, Player[] players) { PlayerListPacket pk = new PlayerListPacket(); pk.type = PlayerListPacket.TYPE_ADD; - pk.entries = new PlayerListPacket.Entry[]{new PlayerListPacket.Entry(uuid, entityId, name, skin)}; + pk.entries = new PlayerListPacket.Entry[]{new PlayerListPacket.Entry(uuid, entityId, name, skin, xboxUserId)}; Server.broadcastPacket(players, pk); } - public void updatePlayerListData(UUID uuid, long entityId, String name, Skin skin, Collection players) { - this.updatePlayerListData(uuid, entityId, name, skin, + public void updatePlayerListData(UUID uuid, long entityId, String name, Skin skin, String xboxUserId, Collection players) { + this.updatePlayerListData(uuid, entityId, name, skin, xboxUserId, players.stream() .filter(p -> !p.getUniqueId().equals(uuid)) .toArray(Player[]::new)); @@ -882,17 +890,15 @@ public void removePlayerListData(UUID uuid, Collection players) { } public void sendFullPlayerListData(Player player) { - final UUID uuid = player.getUniqueId(); PlayerListPacket pk = new PlayerListPacket(); pk.type = PlayerListPacket.TYPE_ADD; - pk.entries = this.playerList.values() - .stream() - .filter(p -> !p.getUniqueId().equals(uuid)) + pk.entries = this.playerList.values().stream() .map(p -> new PlayerListPacket.Entry( p.getUniqueId(), p.getId(), p.getDisplayName(), - p.getSkin())) + p.getSkin(), + p.getLoginChainData().getXUID())) .toArray(PlayerListPacket.Entry[]::new); player.dataPacket(pk); diff --git a/src/main/java/cn/nukkit/entity/EntityHuman.java b/src/main/java/cn/nukkit/entity/EntityHuman.java index ca60201019..0fef9b4728 100644 --- a/src/main/java/cn/nukkit/entity/EntityHuman.java +++ b/src/main/java/cn/nukkit/entity/EntityHuman.java @@ -133,7 +133,10 @@ public void spawnTo(Player player) { throw new IllegalStateException(this.getClass().getSimpleName() + " must have a valid skin set"); } - this.server.updatePlayerListData(this.getUniqueId(), this.getId(), this.getName(), this.skin, new Player[]{player}); + if (this instanceof Player) + this.server.updatePlayerListData(this.getUniqueId(), this.getId(), this.getName(), this.skin, ((Player) this).getLoginChainData().getXUID(), new Player[]{player}); + else + this.server.updatePlayerListData(this.getUniqueId(), this.getId(), this.getName(), this.skin, new Player[]{player}); AddPlayerPacket pk = new AddPlayerPacket(); pk.uuid = this.getUniqueId(); diff --git a/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java b/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java index 37465f892e..26d9a5cf5d 100644 --- a/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/PlayerListPacket.java @@ -65,10 +65,16 @@ public Entry(UUID uuid) { } public Entry(UUID uuid, long entityId, String name, Skin skin) { + this(uuid, entityId, name, skin, ""); + } + + public Entry(UUID uuid, long entityId, String name, Skin skin, String xboxUserId) { this.uuid = uuid; this.entityId = entityId; this.name = name; this.skin = skin; + this.capeData = skin.getCape().getData(); + this.xboxUserId = xboxUserId == null ? "" : xboxUserId; } } From 1ed85d44baf12f94885f90406cb0aa496aa2a5db Mon Sep 17 00:00:00 2001 From: boybook Date: Sat, 28 Oct 2017 01:07:33 +0800 Subject: [PATCH 169/175] Fixed some incorrect command messages. --- src/main/java/cn/nukkit/Server.java | 2 +- src/main/java/cn/nukkit/command/Command.java | 2 +- src/main/java/cn/nukkit/command/defaults/DeopCommand.java | 4 ++-- src/main/java/cn/nukkit/command/defaults/OpCommand.java | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index 640722f7b4..838bc0cd87 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -645,7 +645,7 @@ public boolean dispatchCommand(CommandSender sender, String commandLine) throws return true; } - sender.sendMessage(new TranslationContainer(TextFormat.RED + "%commands.generic.notFound")); + sender.sendMessage(new TranslationContainer(TextFormat.RED + "%commands.generic.unknown", commandLine)); return false; } diff --git a/src/main/java/cn/nukkit/command/Command.java b/src/main/java/cn/nukkit/command/Command.java index 7294aff141..d94283a2d7 100644 --- a/src/main/java/cn/nukkit/command/Command.java +++ b/src/main/java/cn/nukkit/command/Command.java @@ -151,7 +151,7 @@ public boolean testPermission(CommandSender target) { } if (this.permissionMessage == null) { - target.sendMessage(new TranslationContainer(TextFormat.RED + "%commands.generic.permission")); + target.sendMessage(new TranslationContainer(TextFormat.RED + "%commands.generic.unknown", this.name)); } else if (!this.permissionMessage.equals("")) { target.sendMessage(this.permissionMessage.replace("", this.permission)); } diff --git a/src/main/java/cn/nukkit/command/defaults/DeopCommand.java b/src/main/java/cn/nukkit/command/defaults/DeopCommand.java index 4bc71c98fa..d87544af85 100644 --- a/src/main/java/cn/nukkit/command/defaults/DeopCommand.java +++ b/src/main/java/cn/nukkit/command/defaults/DeopCommand.java @@ -14,7 +14,7 @@ */ public class DeopCommand extends VanillaCommand { public DeopCommand(String name) { - super(name, "%nukkit.command.deop.description", "%commands.deop.usage"); + super(name, "%nukkit.command.deop.description", "%commands.deop.description"); this.setPermission("nukkit.command.op.take"); this.commandParameters.put("default", new CommandParameter[]{ new CommandParameter("player", CommandParameter.ARG_TYPE_TARGET, false) @@ -38,7 +38,7 @@ public boolean execute(CommandSender sender, String commandLabel, String[] args) player.setOp(false); if (player instanceof Player) { - ((Player) player).sendMessage(TextFormat.GRAY + "You are no longer op!"); + ((Player) player).sendMessage(new TranslationContainer(TextFormat.GRAY + "%commands.deop.message")); } Command.broadcastCommandMessage(sender, new TranslationContainer("commands.deop.success", new String[]{player.getName()})); diff --git a/src/main/java/cn/nukkit/command/defaults/OpCommand.java b/src/main/java/cn/nukkit/command/defaults/OpCommand.java index df0dc5c256..8e74af6316 100644 --- a/src/main/java/cn/nukkit/command/defaults/OpCommand.java +++ b/src/main/java/cn/nukkit/command/defaults/OpCommand.java @@ -15,7 +15,7 @@ public class OpCommand extends VanillaCommand { public OpCommand(String name) { - super(name, "%nukkit.command.op.description", "%commands.op.usage"); + super(name, "%nukkit.command.op.description", "%commands.op.description"); this.setPermission("nukkit.command.op.give"); this.commandParameters.clear(); this.commandParameters.put("default", new CommandParameter[]{ @@ -38,7 +38,7 @@ public boolean execute(CommandSender sender, String commandLabel, String[] args) Command.broadcastCommandMessage(sender, new TranslationContainer("commands.op.success", player.getName())); if (player instanceof Player) { - ((Player) player).sendMessage(TextFormat.GRAY + "You are now op!"); + ((Player) player).sendMessage(new TranslationContainer(TextFormat.GRAY + "%commands.op.message")); } player.setOp(true); From eed04a56df21ce5158087bafa829f17e456facef Mon Sep 17 00:00:00 2001 From: Sam Ezeh Date: Sun, 29 Oct 2017 04:15:33 +0000 Subject: [PATCH 170/175] Fixed mistake made in commit 410e127 (#1923) --- src/main/java/cn/nukkit/utils/MainLogger.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/cn/nukkit/utils/MainLogger.java b/src/main/java/cn/nukkit/utils/MainLogger.java index 0704e489e1..f03a6c16e2 100644 --- a/src/main/java/cn/nukkit/utils/MainLogger.java +++ b/src/main/java/cn/nukkit/utils/MainLogger.java @@ -52,49 +52,49 @@ public static MainLogger getLogger() { @Override public void emergency(String message) { - if (logLevel.getLevel() <= LogLevel.EMERGENCY.getLevel()) + if (LogLevel.EMERGENCY.getLevel() <= logLevel.getLevel()) this.send(TextFormat.RED + "[EMERGENCY] " + message); } @Override public void alert(String message) { - if (logLevel.getLevel() <= LogLevel.ALERT.getLevel()) + if (LogLevel.ALERT.getLevel() <= logLevel.getLevel()) this.send(TextFormat.RED + "[ALERT] " + message); } @Override public void critical(String message) { - if (logLevel.getLevel() <= LogLevel.CRITICAL.getLevel()) + if (LogLevel.CRITICAL.getLevel() <= logLevel.getLevel()) this.send(TextFormat.RED + "[CRITICAL] " + message); } @Override public void error(String message) { - if (logLevel.getLevel() <= LogLevel.ERROR.getLevel()) + if (LogLevel.ERROR.getLevel() <= logLevel.getLevel()) this.send(TextFormat.DARK_RED + "[ERROR] " + message); } @Override public void warning(String message) { - if (logLevel.getLevel() <= LogLevel.WARNING.getLevel()) + if (LogLevel.WARNING.getLevel() <= logLevel.getLevel()) this.send(TextFormat.YELLOW + "[WARNING] " + message); } @Override public void notice(String message) { - if (logLevel.getLevel() <= LogLevel.NOTICE.getLevel()) + if (LogLevel.NOTICE.getLevel() <= logLevel.getLevel()) this.send(TextFormat.AQUA + "[NOTICE] " + message); } @Override public void info(String message) { - if (logLevel.getLevel() <= LogLevel.INFO.getLevel()) + if (LogLevel.INFO.getLevel() <= logLevel.getLevel()) this.send(TextFormat.WHITE + "[INFO] " + message); } @Override public void debug(String message) { - if (logLevel.getLevel() <= LogLevel.DEBUG.getLevel()) + if (LogLevel.DEBUG.getLevel() <= logLevel.getLevel()) this.send(TextFormat.GRAY + "[DEBUG] " + message); } From d8e2fe0f61be12dc13abc4aa546107b1d9d22d59 Mon Sep 17 00:00:00 2001 From: boybook Date: Sun, 29 Oct 2017 19:41:53 +0800 Subject: [PATCH 171/175] A hack to solve the client-side teleporting bug! (inside into the block) --- src/main/java/cn/nukkit/Player.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 94b67bee6f..52f19ae9eb 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -4107,7 +4107,8 @@ public boolean teleport(Location location, TeleportCause cause) { } } - if (super.teleport(to, null)) { // null to prevent fire of duplicate EntityTeleportEvent + //TODO Remove it! A hack to solve the client-side teleporting bug! (inside into the block) + if (super.teleport(to.getY() == to.getFloorY() ? to.add(0, 0.00001, 0) : to, null)) { // null to prevent fire of duplicate EntityTeleportEvent this.removeAllWindows(); this.teleportPosition = new Vector3(this.x, this.y, this.z); From e8a220722b5f51facedee13bd0183f8002e47cfd Mon Sep 17 00:00:00 2001 From: boybook Date: Sun, 29 Oct 2017 19:42:51 +0800 Subject: [PATCH 172/175] Init the server sub-motd. --- src/main/java/cn/nukkit/Server.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/cn/nukkit/Server.java b/src/main/java/cn/nukkit/Server.java index 838bc0cd87..af8b134427 100644 --- a/src/main/java/cn/nukkit/Server.java +++ b/src/main/java/cn/nukkit/Server.java @@ -359,6 +359,7 @@ public class Server { this.network = new Network(this); this.network.setName(this.getMotd()); + this.network.setSubName(this.getSubMotd()); this.logger.info(this.getLanguage().translateString("nukkit.server.info", this.getName(), TextFormat.YELLOW + this.getNukkitVersion() + TextFormat.WHITE, TextFormat.AQUA + this.getCodename() + TextFormat.WHITE, this.getApiVersion())); this.logger.info(this.getLanguage().translateString("nukkit.server.license", this.getName())); From 4c6c078baf44c230d2df8d829e468ba1ffa1e2d1 Mon Sep 17 00:00:00 2001 From: boybook Date: Sun, 29 Oct 2017 20:38:13 +0800 Subject: [PATCH 173/175] If the player is a spectator, when received InventoryTransferPacket, we need calling events with canceled instead of breaking; --- src/main/java/cn/nukkit/Player.java | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/cn/nukkit/Player.java b/src/main/java/cn/nukkit/Player.java index 52f19ae9eb..b3a2447859 100644 --- a/src/main/java/cn/nukkit/Player.java +++ b/src/main/java/cn/nukkit/Player.java @@ -2846,11 +2846,6 @@ public void handleDataPacket(DataPacket packet) { this.level.addChunkPacket(this.getFloorX() >> 4, this.getFloorZ() >> 4, packet); break; case ProtocolInfo.INVENTORY_TRANSACTION_PACKET: - if (this.isSpectator()) { - this.sendAllInventories(); - break; - } - InventoryTransactionPacket transactionPacket = (InventoryTransactionPacket) packet; boolean isCrafting = false; @@ -2874,6 +2869,10 @@ public void handleDataPacket(DataPacket packet) { switch (transactionPacket.transactionType) { case InventoryTransactionPacket.TYPE_NORMAL: + if (this.isSpectator()) { + this.sendAllInventories(); + break; + } InventoryTransaction transaction = new SimpleInventoryTransaction(this, actions); if (!transaction.execute() && !isCrafting) { @@ -3046,6 +3045,7 @@ public void handleDataPacket(DataPacket packet) { switch (type) { case InventoryTransactionPacket.USE_ITEM_ON_ENTITY_ACTION_INTERACT: PlayerInteractEntityEvent playerInteractEntityEvent = new PlayerInteractEntityEvent(this, target, item); + if (this.isSpectator()) playerInteractEntityEvent.setCancelled(); getServer().getPluginManager().callEvent(playerInteractEntityEvent); if (playerInteractEntityEvent.isCancelled()) { @@ -3069,10 +3069,6 @@ public void handleDataPacket(DataPacket packet) { } break; case InventoryTransactionPacket.USE_ITEM_ON_ENTITY_ACTION_ATTACK: - if (this.getGamemode() == Player.VIEW) { - break; - } - float itemDamage = item.getAttackDamage(); for (Enchantment enchantment : item.getEnchantments()) { @@ -3092,7 +3088,9 @@ public void handleDataPacket(DataPacket packet) { } } - if (!target.attack(new EntityDamageByEntityEvent(this, target, DamageCause.ENTITY_ATTACK, damage))) { + EntityDamageByEntityEvent entityDamageByEntityEvent = new EntityDamageByEntityEvent(this, target, DamageCause.ENTITY_ATTACK, damage); + if (this.isSpectator()) entityDamageByEntityEvent.setCancelled(); + if (!target.attack(entityDamageByEntityEvent)) { if (item.isTool() && this.isSurvival()) { this.inventory.sendContents(this); } @@ -3117,6 +3115,10 @@ public void handleDataPacket(DataPacket packet) { break; case InventoryTransactionPacket.TYPE_RELEASE_ITEM: + if (this.isSpectator()) { + this.sendAllInventories(); + break packetswitch; + } ReleaseItemData releaseItemData = (ReleaseItemData) transactionPacket.transactionData; try { From b7aae63c6dc51882f3e3b4755dbd05cd1c2d1d91 Mon Sep 17 00:00:00 2001 From: kvetinac97 Date: Sun, 29 Oct 2017 17:58:47 +0100 Subject: [PATCH 174/175] Fix Logging (#45) --- src/main/java/cn/nukkit/utils/MainLogger.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/cn/nukkit/utils/MainLogger.java b/src/main/java/cn/nukkit/utils/MainLogger.java index 0704e489e1..68c29aa045 100644 --- a/src/main/java/cn/nukkit/utils/MainLogger.java +++ b/src/main/java/cn/nukkit/utils/MainLogger.java @@ -52,54 +52,54 @@ public static MainLogger getLogger() { @Override public void emergency(String message) { - if (logLevel.getLevel() <= LogLevel.EMERGENCY.getLevel()) + if (logLevel.getLevel() >= LogLevel.EMERGENCY.getLevel()) this.send(TextFormat.RED + "[EMERGENCY] " + message); } @Override public void alert(String message) { - if (logLevel.getLevel() <= LogLevel.ALERT.getLevel()) + if (logLevel.getLevel() >= LogLevel.ALERT.getLevel()) this.send(TextFormat.RED + "[ALERT] " + message); } @Override public void critical(String message) { - if (logLevel.getLevel() <= LogLevel.CRITICAL.getLevel()) + if (logLevel.getLevel() >= LogLevel.CRITICAL.getLevel()) this.send(TextFormat.RED + "[CRITICAL] " + message); } @Override public void error(String message) { - if (logLevel.getLevel() <= LogLevel.ERROR.getLevel()) + if (logLevel.getLevel() >= LogLevel.ERROR.getLevel()) this.send(TextFormat.DARK_RED + "[ERROR] " + message); } @Override public void warning(String message) { - if (logLevel.getLevel() <= LogLevel.WARNING.getLevel()) + if (logLevel.getLevel() >= LogLevel.WARNING.getLevel()) this.send(TextFormat.YELLOW + "[WARNING] " + message); } @Override public void notice(String message) { - if (logLevel.getLevel() <= LogLevel.NOTICE.getLevel()) + if (logLevel.getLevel() >= LogLevel.NOTICE.getLevel()) this.send(TextFormat.AQUA + "[NOTICE] " + message); } @Override public void info(String message) { - if (logLevel.getLevel() <= LogLevel.INFO.getLevel()) + if (logLevel.getLevel() >= LogLevel.INFO.getLevel()) this.send(TextFormat.WHITE + "[INFO] " + message); } @Override public void debug(String message) { - if (logLevel.getLevel() <= LogLevel.DEBUG.getLevel()) + if (logLevel.getLevel() >= LogLevel.DEBUG.getLevel()) this.send(TextFormat.GRAY + "[DEBUG] " + message); } public void setLogDebug(Boolean logDebug) { - this.logLevel = logDebug ? LogLevel.INFO : LogLevel.DEBUG; + this.logLevel = logDebug ? LogLevel.DEBUG : LogLevel.INFO; } public void logException(Exception e) { From 6e2e2568fd808234c6fe5644effdb3258a9944f8 Mon Sep 17 00:00:00 2001 From: boybook Date: Tue, 31 Oct 2017 20:56:38 +0800 Subject: [PATCH 175/175] Remove it in future! Compatible with 1.1.x, then we can do something like kicking... --- src/main/java/cn/nukkit/network/Network.java | 12 +++++++++--- .../java/cn/nukkit/network/protocol/LoginPacket.java | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/cn/nukkit/network/Network.java b/src/main/java/cn/nukkit/network/Network.java index 73506daa9a..f76f31530d 100644 --- a/src/main/java/cn/nukkit/network/Network.java +++ b/src/main/java/cn/nukkit/network/Network.java @@ -150,9 +150,15 @@ public void processBatch(BatchPacket packet, Player player) { if ((pk = this.getPacket(buf[0])) != null) { pk.setBuffer(buf, 3); //skip 2 more bytes - - pk.decode(); - + try { + pk.decode(); + } catch (Exception e) { + //TODO: Remove it in future! Compatible with 1.1.x, then we can do something like kicking... + if (pk.pid() == ProtocolInfo.LOGIN_PACKET) { + pk.setBuffer(buf, 1); + pk.decode(); + } else throw e; + } packets.add(pk); } } diff --git a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java index c1fab370b2..c4127a4790 100644 --- a/src/main/java/cn/nukkit/network/protocol/LoginPacket.java +++ b/src/main/java/cn/nukkit/network/protocol/LoginPacket.java @@ -38,6 +38,8 @@ public byte pid() { @Override public void decode() { this.protocol = this.getInt(); + //TODO: Remove it in future! Compatible with 1.1.x, then we can do something like kicking... + if (this.protocol <= 113) this.getByte(); this.setBuffer(this.getByteArray(), 0); decodeChainData(); decodeSkinData();