diff --git a/pom.xml b/pom.xml index 891a6b0bd..e54854f64 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ org.bukkit bukkit - 1.8.1-R4-SNAPSHOT + 1.8.1-R5-SNAPSHOT jar compile @@ -93,7 +93,12 @@ junit 4.8.1 test - + + + net.sf.trove4j + trove4j + 3.0.1 + diff --git a/src/main/java/net/glowstone/EventFactory.java b/src/main/java/net/glowstone/EventFactory.java index 8716d7eeb..2e4339c3f 100644 --- a/src/main/java/net/glowstone/EventFactory.java +++ b/src/main/java/net/glowstone/EventFactory.java @@ -108,6 +108,10 @@ public static PlayerPreLoginEvent onPlayerPreLogin(String name, Session session) public static PlayerChangedWorldEvent onPlayerChangedWorld(GlowPlayer player, GlowWorld fromWorld) { return callEvent(new PlayerChangedWorldEvent(player, fromWorld)); } + + public static PlayerAnimationEvent onPlayerAnimate(GlowPlayer player) { + return callEvent(new PlayerAnimationEvent(player)); + } // -- Block Events diff --git a/src/main/java/net/glowstone/GlowChunk.java b/src/main/java/net/glowstone/GlowChunk.java index eae030e2c..6aa0766a0 100644 --- a/src/main/java/net/glowstone/GlowChunk.java +++ b/src/main/java/net/glowstone/GlowChunk.java @@ -313,6 +313,7 @@ public void initializeTypes(byte[] types) { * @return A GlowBlockState if the entity exists, or null otherwise. */ public GlowBlockState getEntity(int x, int y, int z) { + if (y >= world.getMaxHeight() - 1 || y < 0) return null; load(); return tileEntities.get(coordToIndex(x, z, y)); } @@ -325,6 +326,7 @@ public GlowBlockState getEntity(int x, int y, int z) { * @return The type. */ public int getType(int x, int z, int y) { + if (y >= world.getMaxHeight() - 1 || y < 0) return 0; load(); return types[coordToIndex(x, z, y)]; } @@ -371,6 +373,7 @@ public void setType(int x, int z, int y, int type) { * @return The metadata. */ public int getMetaData(int x, int z, int y) { + if (y >= world.getMaxHeight() - 1 || y < 0) return 0; load(); return metaData[coordToIndex(x, z, y)]; } @@ -398,6 +401,7 @@ public void setMetaData(int x, int z, int y, int metaData) { * @return The sky light level. */ public int getSkyLight(int x, int z, int y) { + if (y >= world.getMaxHeight() - 1 || y < 0) return 0; load(); return skyLight[coordToIndex(x, z, y)]; } @@ -425,6 +429,7 @@ public void setSkyLight(int x, int z, int y, int skyLight) { * @return The block light level. */ public int getBlockLight(int x, int z, int y) { + if (y >= world.getMaxHeight() - 1 || y < 0) return 0; load(); return blockLight[coordToIndex(x, z, y)]; } diff --git a/src/main/java/net/glowstone/GlowWorld.java b/src/main/java/net/glowstone/GlowWorld.java index d24b65d99..6c173f039 100644 --- a/src/main/java/net/glowstone/GlowWorld.java +++ b/src/main/java/net/glowstone/GlowWorld.java @@ -487,7 +487,7 @@ public synchronized GlowBlock getBlockAt(int x, int y, int z) { } public int getBlockTypeIdAt(int x, int y, int z) { - return ((GlowChunk) getChunkAt(x >> 4, z >> 4)).getType(x & 0xF, z & 0xF, y & 0x7F); + return ((GlowChunk) getChunkAt(x >> 4, z >> 4)).getType(x & 0xF, z & 0xF, y); } public int getHighestBlockYAt(int x, int z) { diff --git a/src/main/java/net/glowstone/block/GlowBlock.java b/src/main/java/net/glowstone/block/GlowBlock.java index d8913af70..a744440e7 100644 --- a/src/main/java/net/glowstone/block/GlowBlock.java +++ b/src/main/java/net/glowstone/block/GlowBlock.java @@ -113,7 +113,7 @@ public Material getType() { } public int getTypeId() { - return chunk.getType(x & 0xf, z & 0xf, y & 0x7f); + return chunk.getType(x & 0xf, z & 0xf, y); } public void setType(Material type) { @@ -129,8 +129,8 @@ public boolean setTypeId(int type, boolean applyPhysics) { } public boolean setTypeIdAndData(int type, byte data, boolean applyPhysics) { - chunk.setType(x & 0xf, z & 0xf, y & 0x7f, type); - chunk.setMetaData(x & 0xf, z & 0xf, y & 0x7f, data); + chunk.setType(x & 0xf, z & 0xf, y, type); + chunk.setMetaData(x & 0xf, z & 0xf, y, data); BlockChangeMessage bcmsg = new BlockChangeMessage(x, y, z, type, data); for (GlowPlayer p : getWorld().getRawPlayers()) { @@ -151,7 +151,7 @@ public boolean isLiquid() { // data and light getters/setters public byte getData() { - return (byte) chunk.getMetaData(x & 0xf, z & 0xf, y & 0x7f); + return (byte) chunk.getMetaData(x & 0xf, z & 0xf, y); } public void setData(byte data) { @@ -168,7 +168,7 @@ public void setData(byte data, boolean applyPhyiscs) { } public byte getLightLevel() { - return (byte) Math.max(chunk.getSkyLight(x & 0xf, z & 0xf, y & 0x7f), chunk.getBlockLight(x & 0xf, z & 0xf, y & 0x7f)); + return (byte) Math.max(chunk.getSkyLight(x & 0xf, z & 0xf, y), chunk.getBlockLight(x & 0xf, z & 0xf, y)); } // redstone-related shenanigans @@ -202,4 +202,9 @@ public PistonMoveReaction getPistonMoveReaction() { throw new UnsupportedOperationException("Not supported yet."); } + @Override + public String toString() { + return "GlowBlock{loc=" + getLocation().toString() + ",type=" + getTypeId() + ",data=" + getData() + "}"; + } + } diff --git a/src/main/java/net/glowstone/entity/GlowLivingEntity.java b/src/main/java/net/glowstone/entity/GlowLivingEntity.java index f7e6e5d64..7bada632a 100644 --- a/src/main/java/net/glowstone/entity/GlowLivingEntity.java +++ b/src/main/java/net/glowstone/entity/GlowLivingEntity.java @@ -1,10 +1,14 @@ package net.glowstone.entity; +import java.util.Arrays; import java.util.HashSet; import java.util.ArrayList; import java.util.List; + +import gnu.trove.set.hash.TIntHashSet; import net.glowstone.GlowServer; +import net.glowstone.util.TargetBlock; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Arrow; @@ -24,7 +28,7 @@ import net.glowstone.GlowWorld; /** - * A GlowLivingEntity is a {@link Player} or {@link Monster}. + * A GlowLivingEntity is a {@link org.bukkit.entity.Player} or {@link org.bukkit.entity.Monster}. * @author Graham Edgecombe. */ public abstract class GlowLivingEntity extends GlowEntity implements LivingEntity { @@ -107,15 +111,53 @@ public Location getEyeLocation() { } public List getLineOfSight(HashSet transparent, int maxDistance) { - throw new UnsupportedOperationException("Not supported yet."); + TIntHashSet transparentBlocks = new TIntHashSet(); + if (transparent != null) { + for (byte byt : transparent) { + transparentBlocks.add(byt); + } + } else { + transparentBlocks.add(0); + } + List ret = new ArrayList(); + TargetBlock target = new TargetBlock(this, maxDistance, 0.2, transparentBlocks); + while (target.getNextBlock() != null) { + Block block = target.getCurrentBlock().getBlock(); + if (!transparentBlocks.contains(block.getTypeId())) { + ret.add(block); + } + } + return ret; } public Block getTargetBlock(HashSet transparent, int maxDistance) { - throw new UnsupportedOperationException("Not supported yet."); + TIntHashSet transparentBlocks = new TIntHashSet(); + if (transparent != null) { + for (byte byt : transparent) { + transparentBlocks.add(byt); + } + } else { + transparentBlocks = null; + } + Location loc = new TargetBlock(this, maxDistance, 0.2, transparentBlocks).getSolidTargetBlock(); + return loc == null ? null : loc.getBlock(); } public List getLastTwoTargetBlocks(HashSet transparent, int maxDistance) { - throw new UnsupportedOperationException("Not supported yet."); + TIntHashSet transparentBlocks = new TIntHashSet(); + if (transparent != null) { + for (byte byt : transparent) { + transparentBlocks.add(byt); + } + } else { + transparentBlocks = null; + } + TargetBlock target = new TargetBlock(this, maxDistance, 0.2, transparentBlocks); + Location last = target.getSolidTargetBlock(); + if (last == null) { + return new ArrayList(Arrays.asList(target.getPreviousBlock().getBlock())); + } + return new ArrayList(Arrays.asList(target.getPreviousBlock().getBlock(), last.getBlock())); } public Egg throwEgg() { diff --git a/src/main/java/net/glowstone/entity/GlowPlayer.java b/src/main/java/net/glowstone/entity/GlowPlayer.java index d5d63ac63..404a0a607 100644 --- a/src/main/java/net/glowstone/entity/GlowPlayer.java +++ b/src/main/java/net/glowstone/entity/GlowPlayer.java @@ -131,6 +131,12 @@ public final class GlowPlayer extends GlowHumanEntity implements Player, Invento */ private String playerListName; + /** + * Stores the last block placement message to work around a bug in the + * vanilla client where duplicate packets are sent. + */ + private BlockPlacementMessage lastPlacement; + /** * Creates a new player and adds it to the world. * @param session The player's session. @@ -877,4 +883,12 @@ public Map serialize() { ret.put("name", getName()); return ret; } + + public BlockPlacementMessage getPreviousPlacement() { + return lastPlacement; + } + + public void setPreviousPlacement(BlockPlacementMessage message) { + this.lastPlacement = message; + } } diff --git a/src/main/java/net/glowstone/msg/ActivateItemMessage.java b/src/main/java/net/glowstone/msg/ActivateItemMessage.java index e4d4e1577..08ecd4b95 100644 --- a/src/main/java/net/glowstone/msg/ActivateItemMessage.java +++ b/src/main/java/net/glowstone/msg/ActivateItemMessage.java @@ -12,4 +12,8 @@ public int getSlot() { return slot; } + @Override + public String toString() { + return "ActivateItemMessage{slot=" + slot + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/AnimateEntityMessage.java b/src/main/java/net/glowstone/msg/AnimateEntityMessage.java index 0bd1ac49e..0cb26be1f 100644 --- a/src/main/java/net/glowstone/msg/AnimateEntityMessage.java +++ b/src/main/java/net/glowstone/msg/AnimateEntityMessage.java @@ -21,4 +21,8 @@ public int getAnimation() { return animation; } + @Override + public String toString() { + return "AnimateEntityMessage{id=" + id + ",animation=" + animation + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/AttachEntityMessage.java b/src/main/java/net/glowstone/msg/AttachEntityMessage.java index 0dcd70556..ecd87febb 100644 --- a/src/main/java/net/glowstone/msg/AttachEntityMessage.java +++ b/src/main/java/net/glowstone/msg/AttachEntityMessage.java @@ -17,4 +17,8 @@ public int getVehicle() { return vehicle; } + @Override + public String toString() { + return "AttachEntityMessage{id=" + id + ",vehicle=" + vehicle + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/BlockChangeMessage.java b/src/main/java/net/glowstone/msg/BlockChangeMessage.java index 0abdcd256..73a76eb0b 100644 --- a/src/main/java/net/glowstone/msg/BlockChangeMessage.java +++ b/src/main/java/net/glowstone/msg/BlockChangeMessage.java @@ -32,4 +32,8 @@ public int getMetadata() { return metadata; } + @Override + public String toString() { + return "BlockChangeMessage{x=" + x + ",y=" + y +",z=" + z + ",type=" + type + ",metadata=" + metadata + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/BlockPlacementMessage.java b/src/main/java/net/glowstone/msg/BlockPlacementMessage.java index a8a76ae41..acb5aaf0f 100644 --- a/src/main/java/net/glowstone/msg/BlockPlacementMessage.java +++ b/src/main/java/net/glowstone/msg/BlockPlacementMessage.java @@ -46,4 +46,8 @@ public int getDirection() { return direction; } + @Override + public String toString() { + return "BlockPlacementMessage{x=" + x + ",y=" + y +",z=" + z + ",direction=" + direction + ",id=" + id + ",count=" + count + ",damage=" + damage + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/ChatMessage.java b/src/main/java/net/glowstone/msg/ChatMessage.java index 2a49d500e..23f118db0 100644 --- a/src/main/java/net/glowstone/msg/ChatMessage.java +++ b/src/main/java/net/glowstone/msg/ChatMessage.java @@ -12,4 +12,8 @@ public String getMessage() { return message; } + @Override + public String toString() { + return "ChatMessage{message=" + message + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/CloseWindowMessage.java b/src/main/java/net/glowstone/msg/CloseWindowMessage.java index 5afb0180a..51afee5ae 100644 --- a/src/main/java/net/glowstone/msg/CloseWindowMessage.java +++ b/src/main/java/net/glowstone/msg/CloseWindowMessage.java @@ -12,4 +12,8 @@ public int getId() { return id; } + @Override + public String toString() { + return "CloseWindowMessage{id=" + id + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/CollectItemMessage.java b/src/main/java/net/glowstone/msg/CollectItemMessage.java index d726023cb..a60be3230 100644 --- a/src/main/java/net/glowstone/msg/CollectItemMessage.java +++ b/src/main/java/net/glowstone/msg/CollectItemMessage.java @@ -17,4 +17,8 @@ public int getCollector() { return collector; } + @Override + public String toString() { + return "CollectItemMessage{id=" + id + ",collector=" + collector + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/CompressedChunkMessage.java b/src/main/java/net/glowstone/msg/CompressedChunkMessage.java index 4a16f870c..3ff8f64a9 100644 --- a/src/main/java/net/glowstone/msg/CompressedChunkMessage.java +++ b/src/main/java/net/glowstone/msg/CompressedChunkMessage.java @@ -45,4 +45,8 @@ public byte[] getData() { return data; } + @Override + public String toString() { + return "CompressedChunkMessage{x=" + x + ",y=" + y + ",z=" + z + ",width=" + width + ",height=" + height + ",depth=" + depth + ",data=" + depth + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/CreateEntityMessage.java b/src/main/java/net/glowstone/msg/CreateEntityMessage.java index 73f94b0e4..75d4afbc8 100644 --- a/src/main/java/net/glowstone/msg/CreateEntityMessage.java +++ b/src/main/java/net/glowstone/msg/CreateEntityMessage.java @@ -12,4 +12,8 @@ public int getId() { return id; } + @Override + public String toString() { + return "CreateEntityMessage{id=" + id + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/DestroyEntityMessage.java b/src/main/java/net/glowstone/msg/DestroyEntityMessage.java index d4bc29de6..b062b1406 100644 --- a/src/main/java/net/glowstone/msg/DestroyEntityMessage.java +++ b/src/main/java/net/glowstone/msg/DestroyEntityMessage.java @@ -12,4 +12,8 @@ public int getId() { return id; } + @Override + public String toString() { + return "DestroyEntityMessage{id=" + id + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/DiggingMessage.java b/src/main/java/net/glowstone/msg/DiggingMessage.java index f491d9b47..62016cbff 100644 --- a/src/main/java/net/glowstone/msg/DiggingMessage.java +++ b/src/main/java/net/glowstone/msg/DiggingMessage.java @@ -36,4 +36,8 @@ public int getFace() { return face; } + @Override + public String toString() { + return "DiggingMessage{state=" + state + ",x=" + x + ",y=" + y + ",z=" + z + ",face=" + face + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/EntityActionMessage.java b/src/main/java/net/glowstone/msg/EntityActionMessage.java index b792c7ee0..cb4340342 100644 --- a/src/main/java/net/glowstone/msg/EntityActionMessage.java +++ b/src/main/java/net/glowstone/msg/EntityActionMessage.java @@ -21,4 +21,8 @@ public int getAction() { return action; } + @Override + public String toString() { + return "EntityActionMessage{id=" + id + ",action=" + action + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/EntityEffectMessage.java b/src/main/java/net/glowstone/msg/EntityEffectMessage.java index 46a9c241e..d58538dce 100644 --- a/src/main/java/net/glowstone/msg/EntityEffectMessage.java +++ b/src/main/java/net/glowstone/msg/EntityEffectMessage.java @@ -28,5 +28,9 @@ public byte getAmplifier() { public short getDuration() { return duration; } - + + @Override + public String toString() { + return "EntityEffectMessage{id=" + id + ",effect=" + effect + ",amplifier=" + amplifier + ",duration=" + duration +"}"; + } } diff --git a/src/main/java/net/glowstone/msg/EntityEquipmentMessage.java b/src/main/java/net/glowstone/msg/EntityEquipmentMessage.java index e723d5a50..80b81730d 100644 --- a/src/main/java/net/glowstone/msg/EntityEquipmentMessage.java +++ b/src/main/java/net/glowstone/msg/EntityEquipmentMessage.java @@ -33,4 +33,8 @@ public int getDamage() { return damage; } + @Override + public String toString() { + return "EntityEquipmentMessage{id=" + id + ",slot=" + slot + ",item=" + item + ",damage" + damage +"}"; + } } diff --git a/src/main/java/net/glowstone/msg/EntityInteractionMessage.java b/src/main/java/net/glowstone/msg/EntityInteractionMessage.java index fb9ac6252..1c38efd6b 100644 --- a/src/main/java/net/glowstone/msg/EntityInteractionMessage.java +++ b/src/main/java/net/glowstone/msg/EntityInteractionMessage.java @@ -23,4 +23,8 @@ public boolean isPunching() { return punching; } + @Override + public String toString() { + return "EntityInteractionMessage{id=" + id + ",target=" + target + ",punching=" + punching + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/EntityMetadataMessage.java b/src/main/java/net/glowstone/msg/EntityMetadataMessage.java index 0c3b37fac..bf4604f41 100644 --- a/src/main/java/net/glowstone/msg/EntityMetadataMessage.java +++ b/src/main/java/net/glowstone/msg/EntityMetadataMessage.java @@ -22,4 +22,14 @@ public List> getParameters() { return parameters; } + @Override + public String toString() { + StringBuilder build = new StringBuilder("EntityInteractionMessage{id="); + build.append(id).append(",metadata=["); + for (Parameter param : parameters) { + build.append(param.toString()).append(","); + } + build.append("]}"); + return build.toString(); + } } diff --git a/src/main/java/net/glowstone/msg/EntityRemoveEffectMessage.java b/src/main/java/net/glowstone/msg/EntityRemoveEffectMessage.java index c137ae1b9..8f3abe441 100644 --- a/src/main/java/net/glowstone/msg/EntityRemoveEffectMessage.java +++ b/src/main/java/net/glowstone/msg/EntityRemoveEffectMessage.java @@ -17,5 +17,9 @@ public int getId() { public byte getEffect() { return effect; } - + + @Override + public String toString() { + return "EntityRemoveMessage{id=" + id + ",effect=" + effect + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/EntityRotationMessage.java b/src/main/java/net/glowstone/msg/EntityRotationMessage.java index 38eea1fb2..dec1d0212 100644 --- a/src/main/java/net/glowstone/msg/EntityRotationMessage.java +++ b/src/main/java/net/glowstone/msg/EntityRotationMessage.java @@ -22,4 +22,8 @@ public int getPitch() { return pitch; } + @Override + public String toString() { + return "EntityRotationMessage{id=" + id + ",rotation=" + rotation + ",pitch=" + pitch + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/EntityStatusMessage.java b/src/main/java/net/glowstone/msg/EntityStatusMessage.java index 2c1c0156e..41dbe0c9f 100644 --- a/src/main/java/net/glowstone/msg/EntityStatusMessage.java +++ b/src/main/java/net/glowstone/msg/EntityStatusMessage.java @@ -17,4 +17,8 @@ public int getStatus() { return status; } + @Override + public String toString() { + return "EntityStatusMessage{id=" + id + ",status=" + status + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/EntityTeleportMessage.java b/src/main/java/net/glowstone/msg/EntityTeleportMessage.java index b94217916..45f8780e6 100644 --- a/src/main/java/net/glowstone/msg/EntityTeleportMessage.java +++ b/src/main/java/net/glowstone/msg/EntityTeleportMessage.java @@ -37,4 +37,8 @@ public int getPitch() { return pitch; } + @Override + public String toString() { + return "EntityTeleportMessage{id=" + id + ",x=" + x + ",y=" + y + ",z=" + z + ",rotation=" + rotation + ",pitch=" + pitch + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/EntityVelocityMessage.java b/src/main/java/net/glowstone/msg/EntityVelocityMessage.java index 132320f56..5feb9640e 100644 --- a/src/main/java/net/glowstone/msg/EntityVelocityMessage.java +++ b/src/main/java/net/glowstone/msg/EntityVelocityMessage.java @@ -27,4 +27,8 @@ public int getVelocityZ() { return velocityZ; } + @Override + public String toString() { + return "EntityVelocityMessage{id=" + id + ",velocityX=" + velocityX + ",velocityY=" + velocityY + ",velocityZ=" + velocityZ + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/ExperienceMessage.java b/src/main/java/net/glowstone/msg/ExperienceMessage.java index 34d9280be..8726b57c2 100644 --- a/src/main/java/net/glowstone/msg/ExperienceMessage.java +++ b/src/main/java/net/glowstone/msg/ExperienceMessage.java @@ -22,5 +22,9 @@ public byte getLevel() { public short getTotalExp() { return totalExp; } - + + @Override + public String toString() { + return "ExperienceMessage{barValue=" + barValue + ",level=" + level + ",totalExp=" + totalExp + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/ExperienceOrbMessage.java b/src/main/java/net/glowstone/msg/ExperienceOrbMessage.java index 9bd326dc6..957f81a32 100644 --- a/src/main/java/net/glowstone/msg/ExperienceOrbMessage.java +++ b/src/main/java/net/glowstone/msg/ExperienceOrbMessage.java @@ -31,4 +31,9 @@ public int getZ() { public short getCount() { return count; } + + @Override + public String toString() { + return "ExperienceOrbMessage{id=" + id + ",x=" + x + ",y=" + y + ",z=" + z + ",count=" + count + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/ExplosionMessage.java b/src/main/java/net/glowstone/msg/ExplosionMessage.java index 3921de169..f2542b17d 100644 --- a/src/main/java/net/glowstone/msg/ExplosionMessage.java +++ b/src/main/java/net/glowstone/msg/ExplosionMessage.java @@ -1,5 +1,7 @@ package net.glowstone.msg; +import java.util.Arrays; + public final class ExplosionMessage extends Message { private final double x, y, z; @@ -41,4 +43,8 @@ public byte[] getCoordinates() { return coordinates; } + @Override + public String toString() { + return "ExplosionMessage{x=" + x + ",y=" + y + ",z=" + z + ",radius=" + radius + ",coordinates=" + Arrays.toString(coordinates) + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/GroundMessage.java b/src/main/java/net/glowstone/msg/GroundMessage.java index 0a38e5c95..bc168bfcd 100644 --- a/src/main/java/net/glowstone/msg/GroundMessage.java +++ b/src/main/java/net/glowstone/msg/GroundMessage.java @@ -12,4 +12,8 @@ public boolean isOnGround() { return onGround; } + @Override + public String toString() { + return "GroundMessage{onGround=" + onGround + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/HandshakeMessage.java b/src/main/java/net/glowstone/msg/HandshakeMessage.java index 00ba1e995..45d32a4e4 100644 --- a/src/main/java/net/glowstone/msg/HandshakeMessage.java +++ b/src/main/java/net/glowstone/msg/HandshakeMessage.java @@ -12,4 +12,8 @@ public String getIdentifier() { return identifier; } + @Override + public String toString() { + return "HandshakeMessage{identifier=" + identifier + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/HealthMessage.java b/src/main/java/net/glowstone/msg/HealthMessage.java index 842cf52e7..73b92fe61 100644 --- a/src/main/java/net/glowstone/msg/HealthMessage.java +++ b/src/main/java/net/glowstone/msg/HealthMessage.java @@ -23,4 +23,8 @@ public float getFoodSaturation() { return foodSaturation; } + @Override + public String toString() { + return "HealthMessage{health=" + health + ",food=" + food + ",foodSaturation=" + foodSaturation + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/IdentificationMessage.java b/src/main/java/net/glowstone/msg/IdentificationMessage.java index 596eed4dc..9b4bc844b 100644 --- a/src/main/java/net/glowstone/msg/IdentificationMessage.java +++ b/src/main/java/net/glowstone/msg/IdentificationMessage.java @@ -49,4 +49,10 @@ public int getMaxPlayers() { return maxPlayers; } + @Override + public String toString() { + return "IdentificationMessage{id=" + id + ",name=" + name + ",seed=" + seed + + ",gameMode=" + mode + ",dimension=" + dimension + ",difficulty=" + + difficulty + ",worldHeight=" + worldHeight + ",maxPlayers=" + maxPlayers + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/KickMessage.java b/src/main/java/net/glowstone/msg/KickMessage.java index 098fd1666..bc2daab9d 100644 --- a/src/main/java/net/glowstone/msg/KickMessage.java +++ b/src/main/java/net/glowstone/msg/KickMessage.java @@ -12,4 +12,8 @@ public String getReason() { return reason; } + @Override + public String toString() { + return "KickMessage{reason=" + reason + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/LoadChunkMessage.java b/src/main/java/net/glowstone/msg/LoadChunkMessage.java index 8f42d81f2..a62dcd117 100644 --- a/src/main/java/net/glowstone/msg/LoadChunkMessage.java +++ b/src/main/java/net/glowstone/msg/LoadChunkMessage.java @@ -23,4 +23,8 @@ public boolean isLoaded() { return loaded; } + @Override + public String toString() { + return "LoadChunkMessage{x=" + x + ",z=" + z + ",loaded=" + loaded + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/MapDataMessage.java b/src/main/java/net/glowstone/msg/MapDataMessage.java index 07ccf4d9b..963acb528 100644 --- a/src/main/java/net/glowstone/msg/MapDataMessage.java +++ b/src/main/java/net/glowstone/msg/MapDataMessage.java @@ -1,5 +1,7 @@ package net.glowstone.msg; +import java.util.Arrays; + public class MapDataMessage extends Message { private final short type, id; @@ -22,5 +24,9 @@ public short getId() { public byte[] getData() { return data; } - + + @Override + public String toString() { + return "MapDataMessage{type=" + type + ",id=" + ",data=" + Arrays.toString(data) + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/Message.java b/src/main/java/net/glowstone/msg/Message.java index edf499ffe..c812979c3 100644 --- a/src/main/java/net/glowstone/msg/Message.java +++ b/src/main/java/net/glowstone/msg/Message.java @@ -2,4 +2,6 @@ public abstract class Message { + public abstract String toString(); + } diff --git a/src/main/java/net/glowstone/msg/MultiBlockChangeMessage.java b/src/main/java/net/glowstone/msg/MultiBlockChangeMessage.java index b3a35ea0e..fb3439839 100644 --- a/src/main/java/net/glowstone/msg/MultiBlockChangeMessage.java +++ b/src/main/java/net/glowstone/msg/MultiBlockChangeMessage.java @@ -1,5 +1,7 @@ package net.glowstone.msg; +import java.util.Arrays; + public final class MultiBlockChangeMessage extends Message { private final int chunkX, chunkZ; @@ -42,4 +44,11 @@ public byte[] getMetadata() { return metadata; } + @Override + public String toString() { + return "MultiBlockChangeMessage{chunkX=" + chunkX + ",chunkZ=" + chunkZ + + ",coordinates=" + Arrays.toString(coordinates) + + ",types=" + Arrays.toString(types) + + ",metadata=" + Arrays.toString(metadata) + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/OpenWindowMessage.java b/src/main/java/net/glowstone/msg/OpenWindowMessage.java index 56f0c997c..28605e4a6 100644 --- a/src/main/java/net/glowstone/msg/OpenWindowMessage.java +++ b/src/main/java/net/glowstone/msg/OpenWindowMessage.java @@ -28,4 +28,8 @@ public String getTitle() { return title; } + @Override + public String toString() { + return "OpenWindowMessage{id=" + id + ",type=" + type + ",slots=" + slots + ",title=" + title + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/PingMessage.java b/src/main/java/net/glowstone/msg/PingMessage.java index e41a5830e..9b22e8985 100644 --- a/src/main/java/net/glowstone/msg/PingMessage.java +++ b/src/main/java/net/glowstone/msg/PingMessage.java @@ -11,4 +11,8 @@ public int getPingId() { return pingId; } + @Override + public String toString() { + return "PingMessage{id=" + pingId + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/PlayEffectMessage.java b/src/main/java/net/glowstone/msg/PlayEffectMessage.java index 6871fce38..2b2d4e0d8 100644 --- a/src/main/java/net/glowstone/msg/PlayEffectMessage.java +++ b/src/main/java/net/glowstone/msg/PlayEffectMessage.java @@ -34,4 +34,8 @@ public int getData() { return data; } + @Override + public String toString() { + return "PlayEffectMessage{id=" + id + ",x=" + x + ",y=" + y + ",z=" + z + ",data=" + data + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/PlayNoteMessage.java b/src/main/java/net/glowstone/msg/PlayNoteMessage.java index 53b866722..da5710f7e 100644 --- a/src/main/java/net/glowstone/msg/PlayNoteMessage.java +++ b/src/main/java/net/glowstone/msg/PlayNoteMessage.java @@ -32,4 +32,8 @@ public int getPitch() { return pitch; } + @Override + public String toString() { + return "PlayNoteMessage{x=" + x + ",y=" + y + ",z=" + z + ",instrument=" + instrument + ",pitch=" + pitch + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/PositionMessage.java b/src/main/java/net/glowstone/msg/PositionMessage.java index bae0c96c5..e30ff4948 100644 --- a/src/main/java/net/glowstone/msg/PositionMessage.java +++ b/src/main/java/net/glowstone/msg/PositionMessage.java @@ -33,4 +33,8 @@ public boolean isOnGround() { return onGround; } + @Override + public String toString() { + return "PositionMessage{x=" + x + ",y=" + y + ",z=" + z + ",stance=" + stance + ",onGround=" + onGround + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/PositionRotationMessage.java b/src/main/java/net/glowstone/msg/PositionRotationMessage.java index c32030e8d..132d29089 100644 --- a/src/main/java/net/glowstone/msg/PositionRotationMessage.java +++ b/src/main/java/net/glowstone/msg/PositionRotationMessage.java @@ -44,4 +44,10 @@ public boolean isOnGround() { return onGround; } + @Override + public String toString() { + return "PositionRotationMessage{x=" + x + ",y=" + y + ",z=" + z + + ",stance=" + stance + ",rotation=" + rotation + ",pitch=" + + pitch + ",onGround=" + onGround + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/ProgressBarMessage.java b/src/main/java/net/glowstone/msg/ProgressBarMessage.java index 710dcb4ef..24ef14fe1 100644 --- a/src/main/java/net/glowstone/msg/ProgressBarMessage.java +++ b/src/main/java/net/glowstone/msg/ProgressBarMessage.java @@ -22,4 +22,8 @@ public int getValue() { return value; } + @Override + public String toString() { + return "ProgressBarMessage{id=" + id + ",progressBar=" + progressBar + ",value=" + value + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/QuickBarMessage.java b/src/main/java/net/glowstone/msg/QuickBarMessage.java index 54a2a2dcf..04ce0b727 100644 --- a/src/main/java/net/glowstone/msg/QuickBarMessage.java +++ b/src/main/java/net/glowstone/msg/QuickBarMessage.java @@ -26,5 +26,9 @@ public short getAmount() { public short getDamage() { return damage; } - + + @Override + public String toString() { + return "QuickBarMessage{slot=" + slot + ",id=" + id + ",amount=" + amount + ",damage=" + damage + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/RelativeEntityPositionMessage.java b/src/main/java/net/glowstone/msg/RelativeEntityPositionMessage.java index e2552e7fb..f53200fda 100644 --- a/src/main/java/net/glowstone/msg/RelativeEntityPositionMessage.java +++ b/src/main/java/net/glowstone/msg/RelativeEntityPositionMessage.java @@ -27,4 +27,8 @@ public int getDeltaZ() { return deltaZ; } + @Override + public String toString() { + return "RelativeEntityPositionMessage{id=" + id + ",deltaX=" + deltaX + ",deltaY=" + deltaY + ",deltaZ=" + deltaZ + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/RelativeEntityPositionRotationMessage.java b/src/main/java/net/glowstone/msg/RelativeEntityPositionRotationMessage.java index 0a84e0646..c15136559 100644 --- a/src/main/java/net/glowstone/msg/RelativeEntityPositionRotationMessage.java +++ b/src/main/java/net/glowstone/msg/RelativeEntityPositionRotationMessage.java @@ -37,4 +37,10 @@ public int getPitch() { return pitch; } + @Override + public String toString() { + return "RelativeEntityPositionRotationMessage{id=" + id + ",deltaX=" + + deltaX + ",deltaY=" + deltaY + ",deltaZ=" + deltaZ + "rotation=" + + rotation + ",pitch=" + pitch + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/RespawnMessage.java b/src/main/java/net/glowstone/msg/RespawnMessage.java index ec3279892..7cae24979 100644 --- a/src/main/java/net/glowstone/msg/RespawnMessage.java +++ b/src/main/java/net/glowstone/msg/RespawnMessage.java @@ -33,5 +33,9 @@ public short getWorldHeight() { public long getSeed() { return seed; } - + + @Override + public String toString() { + return "RespawnMessage{dimension=" + dimension + ",difficulty=" + difficulty + ",gameMode=" + mode + ",worldHeight=" + worldHeight + ",seed=" + seed + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/RotationMessage.java b/src/main/java/net/glowstone/msg/RotationMessage.java index 6d4acffc6..4131ed2cf 100644 --- a/src/main/java/net/glowstone/msg/RotationMessage.java +++ b/src/main/java/net/glowstone/msg/RotationMessage.java @@ -23,4 +23,8 @@ public boolean isOnGround() { return onGround; } + @Override + public String toString() { + return "RotationMessage{rotation=" + rotation + ",pitch=" + pitch + ",onGround=" + onGround + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/ServerListPingMessage.java b/src/main/java/net/glowstone/msg/ServerListPingMessage.java index cc65bffd1..3ac8e550e 100644 --- a/src/main/java/net/glowstone/msg/ServerListPingMessage.java +++ b/src/main/java/net/glowstone/msg/ServerListPingMessage.java @@ -2,4 +2,8 @@ public class ServerListPingMessage extends Message { + @Override + public String toString() { + return "ServerListPingMessage{}"; + } } diff --git a/src/main/java/net/glowstone/msg/SetWindowSlotMessage.java b/src/main/java/net/glowstone/msg/SetWindowSlotMessage.java index 6d600f422..7054de0e1 100644 --- a/src/main/java/net/glowstone/msg/SetWindowSlotMessage.java +++ b/src/main/java/net/glowstone/msg/SetWindowSlotMessage.java @@ -36,4 +36,8 @@ public int getDamage() { return damage; } + @Override + public String toString() { + return "SetWindowSlotMessage{id=" + id + ",slot=" + slot + ",item=" + item + ",count=" + count + ",damage=" + damage + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/SetWindowSlotsMessage.java b/src/main/java/net/glowstone/msg/SetWindowSlotsMessage.java index 04b175fa3..7e3fa6571 100644 --- a/src/main/java/net/glowstone/msg/SetWindowSlotsMessage.java +++ b/src/main/java/net/glowstone/msg/SetWindowSlotsMessage.java @@ -2,6 +2,8 @@ import org.bukkit.inventory.ItemStack; +import java.util.Arrays; + public final class SetWindowSlotsMessage extends Message { private final int id; @@ -20,4 +22,8 @@ public ItemStack[] getItems() { return items; } + @Override + public String toString() { + return "SetWindowSlotsMessage{id=" + id + ",slots=" + Arrays.toString(items) + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/SpawnItemMessage.java b/src/main/java/net/glowstone/msg/SpawnItemMessage.java index ffe7c7f00..f68195879 100644 --- a/src/main/java/net/glowstone/msg/SpawnItemMessage.java +++ b/src/main/java/net/glowstone/msg/SpawnItemMessage.java @@ -50,4 +50,8 @@ public int getRoll() { return roll; } + @Override + public String toString() { + return "SpawnItemMessage{id=" + id + ",item=" + item + ",x=" + x + ",y=" + y + ",z=" + z + ",rotation=" + rotation + ",pitch=" + pitch + ",roll=" + roll + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/SpawnLightningStrikeMessage.java b/src/main/java/net/glowstone/msg/SpawnLightningStrikeMessage.java index d54dabeaf..3d0a4dd99 100644 --- a/src/main/java/net/glowstone/msg/SpawnLightningStrikeMessage.java +++ b/src/main/java/net/glowstone/msg/SpawnLightningStrikeMessage.java @@ -35,5 +35,9 @@ public int getY() { public int getZ() { return z; } - + + @Override + public String toString() { + return "SpawnLightningStrikeMessage{id=" + id + ",mode=" + mode + ",x=" + x + ",y=" + y + ",z=" + z + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/SpawnMobMessage.java b/src/main/java/net/glowstone/msg/SpawnMobMessage.java index 9b8055ee0..bd8948311 100644 --- a/src/main/java/net/glowstone/msg/SpawnMobMessage.java +++ b/src/main/java/net/glowstone/msg/SpawnMobMessage.java @@ -52,4 +52,16 @@ public List> getParameters() { return parameters; } + @Override + public String toString() { + StringBuilder build = new StringBuilder("SpawnMobMessage{id=").append(id). + append(",type=").append(type).append(",x=").append(x).append(",y="). + append(y).append(",z=").append(z).append(",rotation="). + append(rotation).append(",pitch=").append(pitch).append(",parameters=["); + for (Parameter parm : parameters) { + build.append(parm).append(","); + } + build.append("]}"); + return build.toString(); + } } diff --git a/src/main/java/net/glowstone/msg/SpawnPaintingMessage.java b/src/main/java/net/glowstone/msg/SpawnPaintingMessage.java index 0f402d296..1f9210822 100644 --- a/src/main/java/net/glowstone/msg/SpawnPaintingMessage.java +++ b/src/main/java/net/glowstone/msg/SpawnPaintingMessage.java @@ -38,4 +38,8 @@ public String getTitle() { return title; } + @Override + public String toString() { + return "SpawnPaintingMessage{id=" + id + ",x=" + x + ",y=" + y + ",z=" + z + ",type=" + type + ",title=" + title + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/SpawnPlayerMessage.java b/src/main/java/net/glowstone/msg/SpawnPlayerMessage.java index 1cb6151ae..4fd6ef2a8 100644 --- a/src/main/java/net/glowstone/msg/SpawnPlayerMessage.java +++ b/src/main/java/net/glowstone/msg/SpawnPlayerMessage.java @@ -51,4 +51,8 @@ public int getItem() { return item; } + @Override + public String toString() { + return "SpawnPlayerMessage{id=" + id + ",name=" + name + ",x=" + x + ",y=" + y + ",z=" + z + ",rotation=" + rotation + ",pitch=" + pitch + ",item=" + item + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/SpawnPositionMessage.java b/src/main/java/net/glowstone/msg/SpawnPositionMessage.java index 7464cda67..aec48d590 100644 --- a/src/main/java/net/glowstone/msg/SpawnPositionMessage.java +++ b/src/main/java/net/glowstone/msg/SpawnPositionMessage.java @@ -22,4 +22,8 @@ public int getZ() { return z; } + @Override + public String toString() { + return "SpawnPositionMessage{x=" + x + ",y=" + y + ",z=" + z + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/SpawnVehicleMessage.java b/src/main/java/net/glowstone/msg/SpawnVehicleMessage.java index e605b2d8a..7a9e3aa97 100644 --- a/src/main/java/net/glowstone/msg/SpawnVehicleMessage.java +++ b/src/main/java/net/glowstone/msg/SpawnVehicleMessage.java @@ -59,4 +59,14 @@ public int getFireballZ() { return fireballZ; } + @Override + public String toString() { + StringBuilder build = new StringBuilder("SpawnVehicleMessage{id="); + build.append(id).append(",type=").append(type).append(",x=").append(x).append(",y=").append(y); + build.append(",z=").append(z).append(",fireballId=").append(fireballId); + if (hasFireball()) build.append(",fireballX=").append(fireballX).append(",fireballY=").append(fireballY). + append(",fireballZ=").append(fireballZ); + build.append("}"); + return build.toString(); + } } diff --git a/src/main/java/net/glowstone/msg/StateChangeMessage.java b/src/main/java/net/glowstone/msg/StateChangeMessage.java index 74fe68269..5d5d6d050 100644 --- a/src/main/java/net/glowstone/msg/StateChangeMessage.java +++ b/src/main/java/net/glowstone/msg/StateChangeMessage.java @@ -17,4 +17,8 @@ public byte getGameMode() { return gameMode; } + @Override + public String toString() { + return "StateChangeMessage{state=" + state + ",gamemode=" + gameMode + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/StatisticMessage.java b/src/main/java/net/glowstone/msg/StatisticMessage.java index 4bc72900a..c399d0d50 100644 --- a/src/main/java/net/glowstone/msg/StatisticMessage.java +++ b/src/main/java/net/glowstone/msg/StatisticMessage.java @@ -18,4 +18,8 @@ public byte getAmount() { return amount; } + @Override + public String toString() { + return "StatisticMessage{id=" + id + ",amount=" + amount + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/TimeMessage.java b/src/main/java/net/glowstone/msg/TimeMessage.java index 2d9d697e2..9d0da483c 100644 --- a/src/main/java/net/glowstone/msg/TimeMessage.java +++ b/src/main/java/net/glowstone/msg/TimeMessage.java @@ -12,4 +12,8 @@ public long getTime() { return time; } + @Override + public String toString() { + return "TimeMessage{time=" + time + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/TransactionMessage.java b/src/main/java/net/glowstone/msg/TransactionMessage.java index 0833aace2..f6e9ea173 100644 --- a/src/main/java/net/glowstone/msg/TransactionMessage.java +++ b/src/main/java/net/glowstone/msg/TransactionMessage.java @@ -23,4 +23,8 @@ public boolean isAccepted() { return accepted; } + @Override + public String toString() { + return "TransactionMessage{id=" + id + ",transaction=" + transaction +",isAccepted=" + accepted + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/UpdateSignMessage.java b/src/main/java/net/glowstone/msg/UpdateSignMessage.java index d13a73838..9b8a6493b 100644 --- a/src/main/java/net/glowstone/msg/UpdateSignMessage.java +++ b/src/main/java/net/glowstone/msg/UpdateSignMessage.java @@ -1,5 +1,7 @@ package net.glowstone.msg; +import java.util.Arrays; + public final class UpdateSignMessage extends Message { private final int x, y, z; @@ -32,4 +34,8 @@ public String[] getMessage() { return message; } + @Override + public String toString() { + return "UpdateSignMessage{x=" + x + ",y=" + y + ",z=" + z + ",message=" + Arrays.toString(message) + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/UserListItemMessage.java b/src/main/java/net/glowstone/msg/UserListItemMessage.java index 5f2ebc313..9b2143247 100644 --- a/src/main/java/net/glowstone/msg/UserListItemMessage.java +++ b/src/main/java/net/glowstone/msg/UserListItemMessage.java @@ -23,5 +23,9 @@ public boolean addOrRemove() { public short getPing() { return ping; } - + + @Override + public String toString() { + return "UserListItemMessage{name=" + name + ",addOrRemove=" + addOrRemove + ",ping=" + ping + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/WindowClickMessage.java b/src/main/java/net/glowstone/msg/WindowClickMessage.java index c04c28ba1..0d78b9eaa 100644 --- a/src/main/java/net/glowstone/msg/WindowClickMessage.java +++ b/src/main/java/net/glowstone/msg/WindowClickMessage.java @@ -53,4 +53,10 @@ public int getDamage() { return damage; } + @Override + public String toString() { + return "WindowClickMessage{id=" + id + ",slot=" + slot + ",rightClick=" + rightClick + + ",shift=" + shift + ",transaction=" + transaction + + ",item=" + item + ",count=" + count + ",damage=" + damage + "}"; + } } diff --git a/src/main/java/net/glowstone/msg/handler/AnimateEntityMessageHandler.java b/src/main/java/net/glowstone/msg/handler/AnimateEntityMessageHandler.java index b056204c1..19267d4ab 100644 --- a/src/main/java/net/glowstone/msg/handler/AnimateEntityMessageHandler.java +++ b/src/main/java/net/glowstone/msg/handler/AnimateEntityMessageHandler.java @@ -1,16 +1,25 @@ package net.glowstone.msg.handler; +import net.glowstone.EventFactory; +import net.glowstone.block.BlockID; import net.glowstone.entity.GlowPlayer; import net.glowstone.msg.AnimateEntityMessage; import net.glowstone.net.Session; +import org.bukkit.block.Block; +import org.bukkit.event.block.Action; /** - * A {@link MessageHandler} which handles {@link Entity} animation messages. + * A {@link MessageHandler} which handles {@link org.bukkit.entity.Entity} animation messages. */ public final class AnimateEntityMessageHandler extends MessageHandler { @Override public void handle(Session session, GlowPlayer player, AnimateEntityMessage message) { + Block block = player.getTargetBlock(null, 6); + if (block == null || block.getTypeId() == BlockID.AIR) { + if (EventFactory.onPlayerInteract(player, Action.LEFT_CLICK_AIR).isCancelled()) return; // TODO: Item interactions + } + if (EventFactory.onPlayerAnimate(player).isCancelled()) return; switch (message.getAnimation()) { case AnimateEntityMessage.ANIMATION_SWING_ARM: AnimateEntityMessage toSend = new AnimateEntityMessage(player.getEntityId(), AnimateEntityMessage.ANIMATION_SWING_ARM); diff --git a/src/main/java/net/glowstone/msg/handler/BlockPlacementMessageHandler.java b/src/main/java/net/glowstone/msg/handler/BlockPlacementMessageHandler.java index 5850e47f7..50a8b0c98 100644 --- a/src/main/java/net/glowstone/msg/handler/BlockPlacementMessageHandler.java +++ b/src/main/java/net/glowstone/msg/handler/BlockPlacementMessageHandler.java @@ -14,6 +14,7 @@ import net.glowstone.entity.GlowPlayer; import net.glowstone.msg.BlockPlacementMessage; import net.glowstone.net.Session; +import org.omg.SendingContext.RunTime; /** * A {@link MessageHandler} which processes digging messages. @@ -24,28 +25,36 @@ public final class BlockPlacementMessageHandler extends MessageHandler 255) + * Sends both the normal block placement packet and a (-1,255,-1) one + * If the client is placing a block in range with a block in hand, only one normal packet is sent + * That is how it usually happens. Sometimes it doesn't happen like that. + * Therefore, a hacky workaround. + */ + if (message.getDirection() == 255) { // Right-clicked air. Note that the client doesn't send this if they are holding nothing. - EventFactory.onPlayerInteract(player, Action.RIGHT_CLICK_AIR); + BlockPlacementMessage previous = player.getPreviousPlacement(); + if (previous == null + || previous.getCount() == message.getCount() + || previous.getId() == message.getId() + || previous.getDamage() == message.getDamage()) { + EventFactory.onPlayerInteract(player, Action.RIGHT_CLICK_AIR); + } + player.setPreviousPlacement(null); return; } Block against = player.getWorld().getBlockAt(message.getX(), message.getY(), message.getZ()); - BlockFace face; - switch (message.getDirection()) { - case 0: face = BlockFace.DOWN; break; - case 1: face = BlockFace.UP; break; - case 2: face = BlockFace.EAST; break; - case 3: face = BlockFace.WEST; break; - case 4: face = BlockFace.NORTH; break; - case 5: face = BlockFace.SOUTH; break; - default: return; - } + BlockFace face = MessageHandlerUtils.messageToBlockFace(message.getDirection()); + if (face == BlockFace.SELF) return; Block target = against.getRelative(face); ItemStack holding = player.getItemInHand(); - + if (EventFactory.onPlayerInteract(player, Action.RIGHT_CLICK_BLOCK, target, face).isCancelled()) return; if (holding != null && holding.getTypeId() < 256) { if (target.isEmpty() || target.isLiquid()) { BlockState newState = target.getState(); diff --git a/src/main/java/net/glowstone/msg/handler/DiggingMessageHandler.java b/src/main/java/net/glowstone/msg/handler/DiggingMessageHandler.java index cef1e05e7..040d37aff 100644 --- a/src/main/java/net/glowstone/msg/handler/DiggingMessageHandler.java +++ b/src/main/java/net/glowstone/msg/handler/DiggingMessageHandler.java @@ -4,8 +4,11 @@ import org.bukkit.Effect; import org.bukkit.GameMode; import org.bukkit.block.Block; +import org.bukkit.event.Event; +import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; import net.glowstone.EventFactory; @@ -36,6 +39,14 @@ public void handle(Session session, GlowPlayer player, DiggingMessage message) { // Need to have some sort of verification to deal with malicious clients. if (message.getState() == DiggingMessage.STATE_START_DIGGING) { + Action act = Action.LEFT_CLICK_BLOCK; + if (player.getLocation().distanceSquared(block.getLocation()) > 36 || block.getTypeId() == BlockID.AIR) { + act = Action.LEFT_CLICK_AIR; + } + PlayerInteractEvent interactEvent = EventFactory.onPlayerInteract(player, act, block, MessageHandlerUtils.messageToBlockFace(message.getFace())); + if (interactEvent.isCancelled()) return; + if (interactEvent.useItemInHand() == Event.Result.DENY) return; + // TODO: Item interactions BlockDamageEvent event = EventFactory.onBlockDamage(player, block); if (!event.isCancelled()) { blockBroken = event.getInstaBreak() || player.getGameMode() == GameMode.CREATIVE; diff --git a/src/main/java/net/glowstone/msg/handler/HandlerLookupService.java b/src/main/java/net/glowstone/msg/handler/HandlerLookupService.java index bc5e55316..b81683627 100644 --- a/src/main/java/net/glowstone/msg/handler/HandlerLookupService.java +++ b/src/main/java/net/glowstone/msg/handler/HandlerLookupService.java @@ -29,6 +29,7 @@ public final class HandlerLookupService { bind(ServerListPingMessage.class, ServerListPingMessageHandler.class); bind(PingMessage.class, PingMessageHandler.class); bind(QuickBarMessage.class, QuickBarMessageHandler.class); + bind(RespawnMessage.class, RespawnMessageHandler.class); } catch (Exception ex) { throw new ExceptionInInitializerError(ex); } diff --git a/src/main/java/net/glowstone/msg/handler/MessageHandlerUtils.java b/src/main/java/net/glowstone/msg/handler/MessageHandlerUtils.java new file mode 100644 index 000000000..e9f22c2c2 --- /dev/null +++ b/src/main/java/net/glowstone/msg/handler/MessageHandlerUtils.java @@ -0,0 +1,19 @@ +package net.glowstone.msg.handler; + +import org.bukkit.block.BlockFace; + +public class MessageHandlerUtils { + public static BlockFace messageToBlockFace(int id) { + BlockFace face; + switch (id) { + case 0: face = BlockFace.DOWN; break; + case 1: face = BlockFace.UP; break; + case 2: face = BlockFace.EAST; break; + case 3: face = BlockFace.WEST; break; + case 4: face = BlockFace.NORTH; break; + case 5: face = BlockFace.SOUTH; break; + default: face = BlockFace.SELF; + } + return face; + } +} diff --git a/src/main/java/net/glowstone/msg/handler/RespawnMessageHandler.java b/src/main/java/net/glowstone/msg/handler/RespawnMessageHandler.java new file mode 100644 index 000000000..ff03c18ec --- /dev/null +++ b/src/main/java/net/glowstone/msg/handler/RespawnMessageHandler.java @@ -0,0 +1,14 @@ +package net.glowstone.msg.handler; + +import net.glowstone.entity.GlowPlayer; +import net.glowstone.msg.RespawnMessage; +import net.glowstone.net.Session; + +public class RespawnMessageHandler extends MessageHandler { + + @Override + public void handle(Session session, GlowPlayer player, RespawnMessage message) { + player.setHealth(20); + player.teleport(player.getWorld().getSpawnLocation()); + } +} diff --git a/src/main/java/net/glowstone/net/Session.java b/src/main/java/net/glowstone/net/Session.java index df4e5b281..2c86d344c 100644 --- a/src/main/java/net/glowstone/net/Session.java +++ b/src/main/java/net/glowstone/net/Session.java @@ -104,6 +104,11 @@ public enum State { */ private int pingMessageId; + /** + * Handling per-session debug mode. + */ + private boolean isDebugging; + /** * Creates a new session. * @param server The server this session belongs to. diff --git a/src/main/java/net/glowstone/scheduler/GlowScheduler.java b/src/main/java/net/glowstone/scheduler/GlowScheduler.java index ef57d94b3..2154db049 100644 --- a/src/main/java/net/glowstone/scheduler/GlowScheduler.java +++ b/src/main/java/net/glowstone/scheduler/GlowScheduler.java @@ -1,15 +1,14 @@ package net.glowstone.scheduler; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.logging.Level; import net.glowstone.GlowServer; import net.glowstone.GlowWorld; @@ -56,6 +55,8 @@ public final class GlowScheduler implements BukkitScheduler { */ private final List tasks = new ArrayList(); + private final List activeWorkers = Collections.synchronizedList(new ArrayList()); + /** * Creates a new task scheduler. */ @@ -124,7 +125,11 @@ private void pulse() { GlowTask task = it.next(); boolean cont = false; try { - cont = task.pulse(); + if (task.isSync()) { + cont = task.pulse(); + } else { + activeWorkers.add(new GlowWorker(task, this)); + } } finally { if (!cont) it.remove(); } @@ -132,30 +137,27 @@ private void pulse() { } public int scheduleSyncDelayedTask(Plugin plugin, Runnable task, long delay) { - return schedule(new GlowTask(plugin, task, delay, -1)); + return scheduleSyncRepeatingTask(plugin, task, delay, -1); } public int scheduleSyncDelayedTask(Plugin plugin, Runnable task) { - return schedule(new GlowTask(plugin, task, 0, -1)); + return scheduleSyncDelayedTask(plugin, task, 0); } public int scheduleSyncRepeatingTask(Plugin plugin, Runnable task, long delay, long period) { - return schedule(new GlowTask(plugin, task, delay, period)); + return schedule(new GlowTask(plugin, task, true, delay, period)); } public int scheduleAsyncDelayedTask(Plugin plugin, Runnable task, long delay) { - GlowServer.logger.log(Level.WARNING, "Plugin {0}: Async tasks are not yet supported", plugin.getDescription().getName()); - return scheduleSyncDelayedTask(plugin, task, delay); + return scheduleAsyncRepeatingTask(plugin, task, delay, -1); } public int scheduleAsyncDelayedTask(Plugin plugin, Runnable task) { - GlowServer.logger.log(Level.WARNING, "Plugin {0}: Async tasks are not yet supported", plugin.getDescription().getName()); - return scheduleSyncDelayedTask(plugin, task, 0); + return scheduleAsyncRepeatingTask(plugin, task, 0, -1); } public int scheduleAsyncRepeatingTask(Plugin plugin, Runnable task, long delay, long period) { - GlowServer.logger.log(Level.WARNING, "Plugin {0}: Async tasks are not yet supported", plugin.getDescription().getName()); - return scheduleSyncRepeatingTask(plugin, task, delay, period); + return schedule(new GlowTask(plugin, task, false, delay, period)); } public Future callSyncMethod(Plugin plugin, Callable task) { @@ -194,17 +196,23 @@ public void cancelAllTasks() { } public boolean isCurrentlyRunning(int taskId) { - // Can safely return false since this only refers to async tasks. + for (GlowWorker worker : activeWorkers) { + if (worker.getTaskId() == taskId && worker.getThread().isAlive()) return true; + } return false; } public boolean isQueued(int taskId) { - // Can safely return false since this only refers to async tasks. + synchronized (tasks) { + for (GlowTask task : tasks) { + if (task.getTaskId() == taskId) return true; + } + } return false; } public List getActiveWorkers() { - return new ArrayList(); + return new ArrayList(activeWorkers); } public List getPendingTasks() { @@ -215,4 +223,11 @@ public List getPendingTasks() { return result; } + synchronized void workerComplete(GlowWorker worker) { + activeWorkers.remove(worker); + if (!worker.shouldContinue()) { + oldTasks.add(worker.getTask()); + } + } + } diff --git a/src/main/java/net/glowstone/scheduler/GlowTask.java b/src/main/java/net/glowstone/scheduler/GlowTask.java index e4bb74c49..f919d1e7e 100644 --- a/src/main/java/net/glowstone/scheduler/GlowTask.java +++ b/src/main/java/net/glowstone/scheduler/GlowTask.java @@ -3,8 +3,6 @@ import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitTask; -import net.glowstone.GlowServer; - /** * Represents a task which is executed periodically. * @author Graham Edgecombe @@ -56,12 +54,14 @@ public class GlowTask implements BukkitTask { */ private boolean running = true; + private final boolean sync; + /** * Creates a new task with the specified number of ticks between * consecutive calls to {@link #execute()}. * @param ticks The number of ticks. */ - public GlowTask(Plugin owner, Runnable task, long delay, long period) { + public GlowTask(Plugin owner, Runnable task, boolean sync, long delay, long period) { synchronized (nextTaskIdLock) { this.taskId = nextTaskId++; } @@ -70,6 +70,7 @@ public GlowTask(Plugin owner, Runnable task, long delay, long period) { this.delay = delay; this.period = period; this.counter = 0; + this.sync = sync; } /** diff --git a/src/main/java/net/glowstone/scheduler/GlowWorker.java b/src/main/java/net/glowstone/scheduler/GlowWorker.java new file mode 100644 index 000000000..62c5280f6 --- /dev/null +++ b/src/main/java/net/glowstone/scheduler/GlowWorker.java @@ -0,0 +1,59 @@ +package net.glowstone.scheduler; + +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitWorker; + +public class GlowWorker implements BukkitWorker, Runnable { + private final int id; + private final Plugin owner; + private final GlowTask task; + private Thread thread = null; + private boolean shouldContinue = true; + + protected GlowWorker(final GlowTask task, final GlowScheduler scheduler) { + this.id = task.getTaskId(); + this.owner = task.getOwner(); + this.task = task; + this.thread = new Thread(new Runnable() { + public void run() { + task.pulse(); + scheduler.workerComplete(GlowWorker.this); + } + }); + thread.start(); + } + + public int getTaskId() { + return id; + } + + public Plugin getOwner() { + return owner; + } + + public Thread getThread() { + return thread; + } + + public GlowTask getTask() { + return task; + } + + public boolean shouldContinue() { + return shouldContinue; + } + + public void cancel() { + if (thread == null) return; + if (!thread.isAlive()) { + thread.interrupt(); + return; + } + task.stop(); + } + + public void run() { + + shouldContinue = task.pulse(); + } +} diff --git a/src/main/java/net/glowstone/util/Parameter.java b/src/main/java/net/glowstone/util/Parameter.java index ed10bb367..454028fcd 100644 --- a/src/main/java/net/glowstone/util/Parameter.java +++ b/src/main/java/net/glowstone/util/Parameter.java @@ -88,4 +88,9 @@ public T getValue() { return value; } + @Override + public String toString() { + return "Parameter{type=" + type + ",index=" + index + ",value=" + value + "}"; + } + } diff --git a/src/main/java/net/glowstone/util/TargetBlock.java b/src/main/java/net/glowstone/util/TargetBlock.java new file mode 100644 index 000000000..6844b0824 --- /dev/null +++ b/src/main/java/net/glowstone/util/TargetBlock.java @@ -0,0 +1,201 @@ +// $Id$ +/* + * Copyright (c) 2011 toi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. +*/ + +package net.glowstone.util; + +import gnu.trove.set.hash.TIntHashSet; +import net.glowstone.block.BlockID; +import net.glowstone.entity.GlowLivingEntity; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.util.Vector; + +/** + * This class uses an inefficient method to figure out what block a player + * is looking towards. + * + * Originally written by toi. It was ported to WorldEdit and trimmed down by + * sk89q. Thanks to Raphfrk for optimization of toi's original class. + * Ported to Glowstone by zml2008. This classs has come a long way. Treat it nicely. + * + * @author toi + */ +public class TargetBlock { + private World world; + private int maxDistance; + private double checkDistance, curDistance; + private Vector targetPos = new Vector(); + private Vector targetPosDouble = new Vector(); + private Vector prevPos = new Vector(); + private Vector offset = new Vector(); + private TIntHashSet transparentBlocks = null; + + /** + * Constructor requiring a player, uses default values + * + * @param player player to work with + */ + public TargetBlock(GlowLivingEntity player, TIntHashSet transparent) { + this.world = player.getWorld(); + this.setValues(player.getLocation(), 300, player.getEyeHeight(), 0.2, transparent); + } + + /** + * Constructor requiring a player, max distance and a checking distance + * + * @param player LocalPlayer to work with + * @param maxDistance how far it checks for blocks + * @param checkDistance how often to check for blocks, the smaller the more precise + */ + public TargetBlock(GlowLivingEntity player, int maxDistance, double checkDistance, TIntHashSet transparent) { + this.world = player.getWorld(); + this.setValues(player.getLocation(), + maxDistance, player.getEyeHeight(), checkDistance, transparent); + } + + /** + * Set the values, all constructors uses this function + * + * @param loc location of the view + * @param maxDistance how far it checks for blocks + * @param viewHeight where the view is positioned in y-axis + * @param checkDistance how often to check for blocks, the smaller the more precise + */ + private void setValues(Location loc, + int maxDistance, double viewHeight, double checkDistance, TIntHashSet transparent) { + this.maxDistance = maxDistance; + this.checkDistance = checkDistance; + this.curDistance = 0; + int xRotation = (int)(loc.getYaw() + 90) % 360; + int yRotation = (int)loc.getPitch() * -1; + + double h = (checkDistance * Math.cos(Math.toRadians(yRotation))); + + offset = new Vector((h * Math.cos(Math.toRadians(xRotation))), + (checkDistance * Math.sin(Math.toRadians(yRotation))), + (h * Math.sin(Math.toRadians(xRotation)))); + + targetPosDouble = loc.clone().add(0, viewHeight, 0).toVector(); + targetPos = targetPosDouble.toBlockVector(); + prevPos = targetPos; + this.transparentBlocks = transparent; + if (transparentBlocks == null) { + transparentBlocks = new TIntHashSet(new int[] {0}); + } + } + + /** + * Returns any block at the sight. Returns null if out of range or if no + * viable target was found. Will try to return the last valid air block it finds. + * + * @return Block + */ + public Location getAnyTargetBlock() { + boolean searchForLastBlock = true; + Location lastBlock = null; + while (getNextBlock() != null) { + if (world.getBlockTypeIdAt(getCurrentBlock()) == BlockID.AIR) { + if(searchForLastBlock) { + lastBlock = getCurrentBlock(); + if (lastBlock.getBlockY() <= 0 || lastBlock.getBlockY() >= world.getMaxHeight() - 1) { + searchForLastBlock = false; + } + } + } else { + break; + } + } + Location currentBlock = getCurrentBlock(); + return (currentBlock != null ? currentBlock : lastBlock); + } + + /** + * Returns the block at the sight. Returns null if out of range or if no + * viable target was found + * + * @return Block + */ + public Location getTargetBlock() { + while ((getNextBlock() != null) + && (world.getBlockTypeIdAt(getCurrentBlock()) == BlockID.AIR)); + return getCurrentBlock(); + } + + /** + * Returns the block at the sight. Returns null if out of range or if no + * viable target was found + * + * @return Block + */ + public Location getSolidTargetBlock() { + while ((getNextBlock() != null) + && transparentBlocks.contains(world.getBlockTypeIdAt(getCurrentBlock()))); + return getCurrentBlock(); + } + + /** + * Get next block + * + * @return next block position + */ + public Location getNextBlock() { + prevPos = targetPos; + do { + curDistance += checkDistance; + + targetPosDouble = offset.clone().add(targetPosDouble); + targetPos = targetPosDouble.toBlockVector(); + } while (curDistance <= maxDistance + && targetPos.getBlockX() == prevPos.getBlockX() + && targetPos.getBlockY() == prevPos.getBlockY() + && targetPos.getBlockZ() == prevPos.getBlockZ()); + + if (curDistance > maxDistance) { + return null; + } + + return new Location(world, targetPos.getX(), targetPos.getY(), targetPos.getZ()); + } + + /** + * Returns the current block along the line of vision + * + * @return block position + */ + public Location getCurrentBlock() { + if (curDistance > maxDistance) { + return null; + } else { + return new Location(world, targetPos.getX(), targetPos.getY(), targetPos.getZ()); + } + } + + /** + * Returns the previous block in the aimed path + * + * @return block position + */ + public Location getPreviousBlock() { + return new Location(world, prevPos.getX(), prevPos.getY(), prevPos.getZ()); + } +} \ No newline at end of file