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