* This method operates in constant time.
*
- * @param entity The entity.
- * @return {@code true} if this sector contains the entity, otherwise {@code false}.
+ * @param entity The Entity.
+ * @return {@code true} if this sector contains the Entity, otherwise {@code false}.
*/
public boolean contains(Entity entity) {
Position position = entity.getPosition();
@@ -114,12 +122,13 @@ public final class Sector {
* @return The list.
*/
public Set
- * Both the {@code old} and current positions of the entity must belong to this sector.
+ * Both the {@code old} and current positions of the Entity must belong to this sector.
*
- * @param old The old position of the entity.
- * @param entity The entity to move.
+ * @param old The old position of the Entity.
+ * @param entity The Entity to move.
* @throws IllegalArgumentException If either of the positions do not belong to this sector.
*/
public void moveEntity(Position old, Entity entity) {
@@ -175,8 +187,8 @@ public final class Sector {
/**
* Removes a {@link Entity} from this sector.
*
- * @param entity The entity.
- * @throws IllegalArgumentException If the entity does not belong in this sector, or if it was never added.
+ * @param entity The Entity.
+ * @throws IllegalArgumentException If the Entity does not belong in this sector, or if it was never added.
*/
public void removeEntity(Entity entity) {
Position position = entity.getPosition();
@@ -191,6 +203,20 @@ public final class Sector {
notifyListeners(entity, SectorOperation.REMOVE);
}
+ /**
+ * Returns whether or not an Entity of the specified {@link EntityType type} can traverse the tile at the specified
+ * coordinate pair.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @param entity The {@link EntityType}.
+ * @param direction The {@link Direction} the Entity is approaching from.
+ * @return {@code true} if the tile at the specified coordinate pair is traversable, {@code false} if not.
+ */
+ public boolean traversable(int x, int y, EntityType entity, Direction direction) {
+ return matrix.traversable(x, y, entity, direction);
+ }
+
/**
* Checks that the specified {@link Position} is included in this sector.
*
diff --git a/src/org/apollo/game/model/area/collision/CollisionFlag.java b/src/org/apollo/game/model/area/collision/CollisionFlag.java
new file mode 100644
index 00000000..b129511b
--- /dev/null
+++ b/src/org/apollo/game/model/area/collision/CollisionFlag.java
@@ -0,0 +1,100 @@
+package org.apollo.game.model.area.collision;
+
+/**
+ * A type of flag in a {@link CollisionMatrix}.
+ *
+ * @author Major
+ */
+public enum CollisionFlag {
+
+ /**
+ * The walk north flag.
+ */
+ MOB_NORTH(0),
+
+ /**
+ * The walk east flag.
+ */
+ MOB_EAST(1),
+
+ /**
+ * The walk south flag.
+ */
+ MOB_SOUTH(2),
+
+ /**
+ * The walk west flag.
+ */
+ MOB_WEST(3),
+
+ /**
+ * The projectile north flag.
+ */
+ PROJECTILE_NORTH(4),
+
+ /**
+ * The projectile east flag.
+ */
+ PROJECTILE_EAST(5),
+
+ /**
+ * The projectile south flag.
+ */
+ PROJECTILE_SOUTH(6),
+
+ /**
+ * The projectile west flag.
+ */
+ PROJECTILE_WEST(7);
+
+ /**
+ * Returns an array of CollisionFlags that indicate if a Mob can traverse over a tile.
+ *
+ * @return The array of CollisionFlags.
+ */
+ public static CollisionFlag[] mobs() {
+ return new CollisionFlag[] { MOB_NORTH, MOB_EAST, MOB_SOUTH, MOB_WEST };
+ }
+
+ /**
+ * Returns an array of CollisionFlags that indicate if a Projectile can traverse over a tile.
+ *
+ * @return The array of CollisionFlags.
+ */
+ public static CollisionFlag[] projectiles() {
+ return new CollisionFlag[] { PROJECTILE_NORTH, PROJECTILE_EAST, PROJECTILE_SOUTH, PROJECTILE_WEST };
+ }
+
+ /**
+ * The index of the bit this flag is stored in.
+ */
+ private final int bit;
+
+ /**
+ * Creates the CollisionFlag.
+ *
+ * @param bit The index of the bit this flag is stored in.
+ */
+ private CollisionFlag(int bit) {
+ this.bit = bit;
+ }
+
+ /**
+ * Gets this CollisionFlag, as a {@code byte}.
+ *
+ * @return The value, as a {@code byte}.
+ */
+ public byte asByte() {
+ return (byte) (1 << bit);
+ }
+
+ /**
+ * Gets the index of the bit this flag is stored in.
+ *
+ * @return The index of the bit.
+ */
+ public int getBit() {
+ return bit;
+ }
+
+}
\ No newline at end of file
diff --git a/src/org/apollo/game/model/area/collision/CollisionMatrix.java b/src/org/apollo/game/model/area/collision/CollisionMatrix.java
new file mode 100644
index 00000000..6c370591
--- /dev/null
+++ b/src/org/apollo/game/model/area/collision/CollisionMatrix.java
@@ -0,0 +1,227 @@
+package org.apollo.game.model.area.collision;
+
+import java.util.Arrays;
+
+import org.apollo.game.model.Direction;
+import org.apollo.game.model.entity.Entity.EntityType;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+
+/**
+ * A 2-dimensional adjacency matrix containing tile collision data.
+ *
+ * @author Major
+ */
+public final class CollisionMatrix {
+
+ /**
+ * Indicates that all types of traversal are allowed.
+ */
+ private static final byte ALL_ALLOWED = 0b0000_0000;
+
+ /**
+ * Indicates that no types of traversal are allowed.
+ */
+ private static final byte ALL_BLOCKED = (byte) 0b1111_1111;
+
+ /**
+ * The length of the matrix.
+ */
+ private final int length;
+
+ /**
+ * The collision matrix, as a {@code byte} array.
+ */
+ private final byte[] matrix;
+
+ /**
+ * The width of the matrix.
+ */
+ private final int width;
+
+ /**
+ * Creates the CollisionMatrix.
+ *
+ * @param width The width of the matrix.
+ * @param length The length of the matrix.
+ */
+ public CollisionMatrix(int width, int length) {
+ this.width = width;
+ this.length = length;
+ matrix = new byte[width * length];
+ }
+
+ /**
+ * Returns whether or not all of the specified {@link CollisionFlag}s are set for the specified
+ * coordinate pair.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @param flags The CollisionFlags.
+ * @return {@code true} if all of the CollisionFlags are set, otherwise {@code false}.
+ */
+ public boolean all(int x, int y, CollisionFlag... flags) {
+ for (CollisionFlag flag : flags) {
+ if ((get(x, y) & flag.asByte()) == 0) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns whether or not any of the specified {@link CollisionFlag}s are set for the specified
+ * coordinate pair.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @param flags The CollisionFlags.
+ * @return {@code true} if any of the CollisionFlags are set, otherwise {@code false}.
+ */
+ public boolean any(int x, int y, CollisionFlag... flags) {
+ for (CollisionFlag flag : flags) {
+ if ((get(x, y) & flag.asByte()) != 0) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Completely blocks the tile at the specified coordinate pair.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ */
+ public void block(int x, int y) {
+ set(x, y, ALL_BLOCKED);
+ }
+
+ /**
+ * Clears (i.e. sets to {@code false}) the value of the specified {@link CollisionFlag} for the specified coordinate
+ * pair.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @param flag The CollisionFlag.
+ */
+ public void clear(int x, int y, CollisionFlag flag) {
+ set(x, y, (byte) ~flag.asByte());
+ }
+
+ /**
+ * Returns whether or not the specified {@link CollisionFlag} is set for the specified coordinate pair.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @param flag The CollisionFlag.
+ * @return {@code true} if the CollisionFlag is set, {@code false} if not.
+ */
+ public boolean flagged(int x, int y, CollisionFlag flag) {
+ return (get(x, y) & flag.asByte()) != 0;
+ }
+
+ /**
+ * Gets the value of the specified tile.
+ *
+ * @param x The x coordinate of the tile.
+ * @param y The y coordinate of the tile.
+ * @return The value.
+ */
+ public int get(int x, int y) {
+ return matrix[indexOf(x, y)] & 0xFF;
+ }
+
+ /**
+ * Resets the cell of the specified coordinate pair.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ */
+ public void reset(int x, int y) {
+ set(x, y, ALL_ALLOWED);
+ }
+
+ /**
+ * Sets (i.e. sets to {@code true}) the value of the specified {@link CollisionFlag} for the specified coordinate
+ * pair.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @param flag The CollisionFlag.
+ */
+ public void set(int x, int y, CollisionFlag flag) {
+ set(x, y, flag.asByte());
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("width", width).add("length", length).add("matrix", Arrays.toString(matrix))
+ .toString();
+ }
+
+ /**
+ * Returns whether or not an Entity of the specified {@link EntityType type} can traverse the tile at the specified
+ * coordinate pair.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @param entity The {@link EntityType}.
+ * @param direction The {@link Direction} the Entity is approaching from.
+ * @return {@code true} if the tile at the specified coordinate pair is traversable, {@code false} if not.
+ */
+ public boolean traversable(int x, int y, EntityType entity, Direction direction) {
+ CollisionFlag[] flags = (entity == EntityType.PROJECTILE) ? CollisionFlag.projectiles() : CollisionFlag.mobs();
+ int north = 0, east = 1, south = 2, west = 3;
+
+ switch (direction) {
+ case NORTH_WEST:
+ return any(x, y, flags[south], flags[east]);
+ case NORTH:
+ return flagged(x, y, flags[south]);
+ case NORTH_EAST:
+ return any(x, y, flags[south], flags[west]);
+ case EAST:
+ return flagged(x, y, flags[west]);
+ case SOUTH_EAST:
+ return any(x, y, flags[north], flags[west]);
+ case SOUTH:
+ return flagged(x, y, flags[north]);
+ case SOUTH_WEST:
+ return any(x, y, flags[north], flags[east]);
+ case WEST:
+ return flagged(x, y, flags[east]);
+ }
+
+ throw new IllegalArgumentException("Unrecognised direction " + direction + ".");
+ }
+
+ /**
+ * Gets the index in the matrix for the specified coordinate pair.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @return The index.
+ * @throws ArrayIndexOutOfBoundsException If the specified coordinate pair does not fit in this matrix.
+ */
+ private int indexOf(int x, int y) {
+ int index = y * width + x;
+ Preconditions.checkElementIndex(index, matrix.length, "Index out of bounds.");
+ return index;
+ }
+
+ /**
+ * Sets the appropriate index for the specified coordinate pair to the specified value.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @param value The value.
+ */
+ private void set(int x, int y, byte value) {
+ matrix[indexOf(x, y)] = value;
+ }
+
+}
\ No newline at end of file
diff --git a/src/org/apollo/game/model/area/collision/package-info.java b/src/org/apollo/game/model/area/collision/package-info.java
new file mode 100644
index 00000000..aeb5e04c
--- /dev/null
+++ b/src/org/apollo/game/model/area/collision/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Contains classes related to tile collision data.
+ */
+package org.apollo.game.model.area.collision;
\ No newline at end of file
diff --git a/src/org/apollo/game/model/entity/Mob.java b/src/org/apollo/game/model/entity/Mob.java
index 8bdf5f6f..17c4f8ca 100644
--- a/src/org/apollo/game/model/entity/Mob.java
+++ b/src/org/apollo/game/model/entity/Mob.java
@@ -16,6 +16,7 @@ import org.apollo.game.model.area.SectorRepository;
import org.apollo.game.model.def.NpcDefinition;
import org.apollo.game.model.entity.attr.Attribute;
import org.apollo.game.model.entity.attr.AttributeMap;
+import org.apollo.game.model.event.impl.MobPositionUpdateEvent;
import org.apollo.game.model.inv.Inventory;
import org.apollo.game.model.inv.Inventory.StackMode;
import org.apollo.game.model.inv.InventoryConstants;
@@ -402,7 +403,7 @@ public abstract class Mob extends Entity {
this.index = index;
}
}
-
+
/**
* Returns this mobs interacting index.
*
@@ -428,6 +429,9 @@ public abstract class Mob extends Entity {
* @param position The position.
*/
public final void setPosition(Position position) {
+ World.getWorld().submit(new MobPositionUpdateEvent(this, position));
+ // Intentionally ignore the Event result - accidentally terminating this method would break the entire server.
+
Position old = this.position;
SectorRepository repository = World.getWorld().getSectorRepository();
Sector current = repository.fromPosition(old);
diff --git a/src/org/apollo/game/model/entity/Player.java b/src/org/apollo/game/model/entity/Player.java
index 578dfecd..8b02a12b 100644
--- a/src/org/apollo/game/model/entity/Player.java
+++ b/src/org/apollo/game/model/entity/Player.java
@@ -19,6 +19,9 @@ import org.apollo.game.model.Appearance;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.area.Sector;
+import org.apollo.game.model.entity.setting.PrivacyState;
+import org.apollo.game.model.entity.setting.PrivilegeLevel;
+import org.apollo.game.model.entity.setting.ScreenBrightness;
import org.apollo.game.model.event.impl.LoginEvent;
import org.apollo.game.model.event.impl.LogoutEvent;
import org.apollo.game.model.inter.InterfaceConstants;
@@ -33,9 +36,6 @@ import org.apollo.game.model.inv.Inventory.StackMode;
import org.apollo.game.model.inv.InventoryConstants;
import org.apollo.game.model.inv.InventoryListener;
import org.apollo.game.model.inv.SynchronizationInventoryListener;
-import org.apollo.game.model.setting.PrivacyState;
-import org.apollo.game.model.setting.PrivilegeLevel;
-import org.apollo.game.model.setting.ScreenBrightness;
import org.apollo.game.model.skill.LevelUpSkillListener;
import org.apollo.game.model.skill.SynchronizationSkillListener;
import org.apollo.game.sync.block.SynchronizationBlock;
diff --git a/src/org/apollo/game/model/setting/Gender.java b/src/org/apollo/game/model/entity/setting/Gender.java
similarity index 91%
rename from src/org/apollo/game/model/setting/Gender.java
rename to src/org/apollo/game/model/entity/setting/Gender.java
index 1e95bae1..9cd43668 100644
--- a/src/org/apollo/game/model/setting/Gender.java
+++ b/src/org/apollo/game/model/entity/setting/Gender.java
@@ -1,4 +1,4 @@
-package org.apollo.game.model.setting;
+package org.apollo.game.model.entity.setting;
/**
* An enumeration containing the two genders (male and female). This enumeration relies on the ordering of the elements
diff --git a/src/org/apollo/game/model/setting/PrivacyState.java b/src/org/apollo/game/model/entity/setting/PrivacyState.java
similarity index 98%
rename from src/org/apollo/game/model/setting/PrivacyState.java
rename to src/org/apollo/game/model/entity/setting/PrivacyState.java
index 0a62b1fc..76fbec8d 100644
--- a/src/org/apollo/game/model/setting/PrivacyState.java
+++ b/src/org/apollo/game/model/entity/setting/PrivacyState.java
@@ -1,4 +1,4 @@
-package org.apollo.game.model.setting;
+package org.apollo.game.model.entity.setting;
import com.google.common.base.Preconditions;
diff --git a/src/org/apollo/game/model/setting/PrivilegeLevel.java b/src/org/apollo/game/model/entity/setting/PrivilegeLevel.java
similarity index 96%
rename from src/org/apollo/game/model/setting/PrivilegeLevel.java
rename to src/org/apollo/game/model/entity/setting/PrivilegeLevel.java
index e5738f7c..fbdaf7c6 100644
--- a/src/org/apollo/game/model/setting/PrivilegeLevel.java
+++ b/src/org/apollo/game/model/entity/setting/PrivilegeLevel.java
@@ -1,4 +1,4 @@
-package org.apollo.game.model.setting;
+package org.apollo.game.model.entity.setting;
import com.google.common.base.Preconditions;
diff --git a/src/org/apollo/game/model/setting/ScreenBrightness.java b/src/org/apollo/game/model/entity/setting/ScreenBrightness.java
similarity index 96%
rename from src/org/apollo/game/model/setting/ScreenBrightness.java
rename to src/org/apollo/game/model/entity/setting/ScreenBrightness.java
index 9ae6cd9c..4a190a44 100644
--- a/src/org/apollo/game/model/setting/ScreenBrightness.java
+++ b/src/org/apollo/game/model/entity/setting/ScreenBrightness.java
@@ -1,4 +1,4 @@
-package org.apollo.game.model.setting;
+package org.apollo.game.model.entity.setting;
import com.google.common.base.Preconditions;
diff --git a/src/org/apollo/game/model/setting/ServerStatus.java b/src/org/apollo/game/model/entity/setting/ServerStatus.java
similarity index 95%
rename from src/org/apollo/game/model/setting/ServerStatus.java
rename to src/org/apollo/game/model/entity/setting/ServerStatus.java
index 05bc3d8e..651d4b88 100644
--- a/src/org/apollo/game/model/setting/ServerStatus.java
+++ b/src/org/apollo/game/model/entity/setting/ServerStatus.java
@@ -1,4 +1,4 @@
-package org.apollo.game.model.setting;
+package org.apollo.game.model.entity.setting;
import com.google.common.base.Preconditions;
diff --git a/src/org/apollo/game/model/setting/package-info.java b/src/org/apollo/game/model/entity/setting/package-info.java
similarity index 60%
rename from src/org/apollo/game/model/setting/package-info.java
rename to src/org/apollo/game/model/entity/setting/package-info.java
index 5c8ed99e..db35d20a 100644
--- a/src/org/apollo/game/model/setting/package-info.java
+++ b/src/org/apollo/game/model/entity/setting/package-info.java
@@ -1,4 +1,4 @@
/**
* Contains player setting or customisation-related classes.
*/
-package org.apollo.game.model.setting;
\ No newline at end of file
+package org.apollo.game.model.entity.setting;
\ No newline at end of file
diff --git a/src/org/apollo/game/model/event/impl/MobPositionUpdateEvent.java b/src/org/apollo/game/model/event/impl/MobPositionUpdateEvent.java
new file mode 100644
index 00000000..82f9a470
--- /dev/null
+++ b/src/org/apollo/game/model/event/impl/MobPositionUpdateEvent.java
@@ -0,0 +1,56 @@
+package org.apollo.game.model.event.impl;
+
+import org.apollo.game.model.Position;
+import org.apollo.game.model.entity.Mob;
+import org.apollo.game.model.event.Event;
+
+/**
+ * An {@link Event} created when a Mob's Position is being updated.
+ *
+ * This Event intentionally ignores the result of execution - it should not be possible for a plugin to prevent this
+ * Event from happening, only to listen for it.
+ *
+ * @author Major
+ */
+public final class MobPositionUpdateEvent extends Event {
+
+ /**
+ * The Mob whose position is being updated.
+ */
+ private final Mob mob;
+
+ /**
+ * The next Position of the Mob.
+ */
+ private final Position next;
+
+ /**
+ * Creates the MobPositionUpdateEvent.
+ *
+ * @param mob The {@link Mob} whose Position is being updated.
+ * @param next The next {@link Position} of the Mob.
+ */
+ public MobPositionUpdateEvent(Mob mob, Position next) {
+ this.mob = mob;
+ this.next = next;
+ }
+
+ /**
+ * Gets the {@link Mob} being moved.
+ *
+ * @return The Mob.
+ */
+ public Mob getMob() {
+ return mob;
+ }
+
+ /**
+ * Gets the {@link Position} this {@link Mob} is being moved to.
+ *
+ * @return The Position.
+ */
+ public Position getNext() {
+ return next;
+ }
+
+}
\ No newline at end of file
diff --git a/src/org/apollo/game/model/inter/InterfaceSet.java b/src/org/apollo/game/model/inter/InterfaceSet.java
index 5743a956..3e77387e 100644
--- a/src/org/apollo/game/model/inter/InterfaceSet.java
+++ b/src/org/apollo/game/model/inter/InterfaceSet.java
@@ -7,6 +7,7 @@ import java.util.Optional;
import org.apollo.game.message.impl.CloseInterfaceMessage;
import org.apollo.game.message.impl.EnterAmountMessage;
import org.apollo.game.message.impl.OpenDialogueInterfaceMessage;
+import org.apollo.game.message.impl.OpenDialogueOverlayMessage;
import org.apollo.game.message.impl.OpenInterfaceMessage;
import org.apollo.game.message.impl.OpenInterfaceSidebarMessage;
import org.apollo.game.message.impl.OpenOverlayMessage;
@@ -144,10 +145,10 @@ public final class InterfaceSet {
}
/**
- * Opens a chat box dialogue.
+ * Opens a dialogue interface.
*
- * @param listener The listener for the dialogue.
- * @param dialogueId The dialogue's id.
+ * @param listener The {@link DialogueListener}.
+ * @param dialogueId The dialogue id.
*/
public void openDialogue(DialogueListener listener, int dialogueId) {
closeAndNotify();
@@ -160,14 +161,39 @@ public final class InterfaceSet {
}
/**
- * Opens a chat box dialogue.
+ * Opens a dialogue.
*
- * @param dialogueId The dialogue's id.
+ * @param dialogueId The dialogue id.
*/
public void openDialogue(int dialogueId) {
openDialogue(null, dialogueId);
}
+ /**
+ * Opens a dialogue overlay interface.
+ *
+ * @param listener The {@link DialogueListener}.
+ * @param dialogueId The dialogue id.
+ */
+ public void openDialogueOverlay(DialogueListener listener, int dialogueId) {
+ closeAndNotify();
+
+ this.dialogueListener = Optional.ofNullable(listener);
+ this.listener = Optional.ofNullable(listener);
+
+ interfaces.put(InterfaceType.DIALOGUE, dialogueId);
+ player.send(new OpenDialogueOverlayMessage(dialogueId));
+ }
+
+ /**
+ * Opens a dialogue overlay.
+ *
+ * @param dialogueId The dialogue id.
+ */
+ public void openDialogueOverlay(int dialogueId) {
+ openDialogueOverlay(null, dialogueId);
+ }
+
/**
* Opens the enter amount dialogue.
*
diff --git a/src/org/apollo/game/sync/block/ChatBlock.java b/src/org/apollo/game/sync/block/ChatBlock.java
index de3eb001..14bbba81 100644
--- a/src/org/apollo/game/sync/block/ChatBlock.java
+++ b/src/org/apollo/game/sync/block/ChatBlock.java
@@ -1,7 +1,7 @@
package org.apollo.game.sync.block;
import org.apollo.game.message.impl.ChatMessage;
-import org.apollo.game.model.setting.PrivilegeLevel;
+import org.apollo.game.model.entity.setting.PrivilegeLevel;
/**
* The chat {@link SynchronizationBlock}. Only players can utilise this block.
diff --git a/src/org/apollo/io/player/impl/BinaryPlayerLoader.java b/src/org/apollo/io/player/impl/BinaryPlayerLoader.java
index ada3d857..00d2fe89 100644
--- a/src/org/apollo/io/player/impl/BinaryPlayerLoader.java
+++ b/src/org/apollo/io/player/impl/BinaryPlayerLoader.java
@@ -20,11 +20,11 @@ import org.apollo.game.model.entity.attr.AttributeType;
import org.apollo.game.model.entity.attr.BooleanAttribute;
import org.apollo.game.model.entity.attr.NumericalAttribute;
import org.apollo.game.model.entity.attr.StringAttribute;
+import org.apollo.game.model.entity.setting.Gender;
+import org.apollo.game.model.entity.setting.PrivacyState;
+import org.apollo.game.model.entity.setting.PrivilegeLevel;
+import org.apollo.game.model.entity.setting.ScreenBrightness;
import org.apollo.game.model.inv.Inventory;
-import org.apollo.game.model.setting.Gender;
-import org.apollo.game.model.setting.PrivacyState;
-import org.apollo.game.model.setting.PrivilegeLevel;
-import org.apollo.game.model.setting.ScreenBrightness;
import org.apollo.io.player.PlayerLoader;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.net.codec.login.LoginConstants;
diff --git a/src/org/apollo/io/player/impl/DummyPlayerLoader.java b/src/org/apollo/io/player/impl/DummyPlayerLoader.java
index 0cc48ed4..95cd971d 100644
--- a/src/org/apollo/io/player/impl/DummyPlayerLoader.java
+++ b/src/org/apollo/io/player/impl/DummyPlayerLoader.java
@@ -2,7 +2,7 @@ package org.apollo.io.player.impl;
import org.apollo.game.model.Position;
import org.apollo.game.model.entity.Player;
-import org.apollo.game.model.setting.PrivilegeLevel;
+import org.apollo.game.model.entity.setting.PrivilegeLevel;
import org.apollo.io.player.PlayerLoader;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.net.codec.login.LoginConstants;
diff --git a/src/org/apollo/net/ApolloHandler.java b/src/org/apollo/net/ApolloHandler.java
index ad51eb83..ce0adfc9 100644
--- a/src/org/apollo/net/ApolloHandler.java
+++ b/src/org/apollo/net/ApolloHandler.java
@@ -5,6 +5,8 @@ import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpRequest;
+import io.netty.util.Attribute;
+import io.netty.util.ReferenceCountUtil;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -65,25 +67,36 @@ public final class ApolloHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object message) {
- if (ctx.attr(NetworkConstants.SESSION_KEY).get() == null) {
+ try {
+ Attribute