Update to netty 4.

This commit is contained in:
Major-
2014-01-26 21:02:18 +00:00
parent 4b346f4e24
commit 15141fd875
93 changed files with 793 additions and 1106 deletions
+4 -3
View File
@@ -16,13 +16,14 @@ require 'java'
java_import 'org.apollo.game.event.handler.EventHandler'
java_import 'org.apollo.game.command.CommandListener'
java_import 'org.apollo.game.model.Player'
java_import 'org.apollo.game.model.settings.PrivilegeLevel'
java_import 'org.apollo.game.model.World'
java_import 'org.apollo.game.scheduling.ScheduledTask'
# Alias the privilege levels.
RIGHTS_ADMIN = Player::PrivilegeLevel::ADMINISTRATOR
RIGHTS_MOD = Player::PrivilegeLevel::MODERATOR
RIGHTS_STANDARD = Player::PrivilegeLevel::STANDARD
RIGHTS_ADMIN = PrivilegeLevel::ADMINISTRATOR
RIGHTS_MOD = PrivilegeLevel::MODERATOR
RIGHTS_STANDARD = PrivilegeLevel::STANDARD
# Extends the (Ruby) String class with a method to convert a lower case,
# underscore delimited string to camel-case.
+5 -2
View File
@@ -1,5 +1,8 @@
require 'java'
java_import 'org.apollo.game.model.Player'
java_import 'org.apollo.game.model.def.ItemDefinition'
java_import 'org.apollo.game.model.def.NpcDefinition'
java_import 'org.apollo.game.model.def.ObjectDefinition'
on :command, :lookup, RIGHTS_ADMIN do |player, command|
args = command.arguments.to_a
@@ -11,7 +14,7 @@ on :command, :lookup, RIGHTS_ADMIN do |player, command|
type = args.shift.downcase
name = args.join(" ").downcase
if ["npc","object","item"].index(type) == nil
if ["npc", "object", "item"].index(type) == nil
player.send_message("Invalid syntax - ::lookup [npc/object/item] [name]")
return
end
@@ -37,6 +40,6 @@ on :command, :iteminfo, RIGHTS_ADMIN do |player, command|
definition = ItemDefinition.lookup(id)
members = definition.is_members_only ? "members" : "not members"
player.send_message("Item #{id} is called #{definition.name}, is #{members} only, and a has a team of #{definition.team}.")
player.send_message("Item #{id} is called #{definition.name}, is #{members} only, and has a team of #{definition.team}.")
player.send_message("Its description is \"#{definition.description}\".")
end
+25
View File
@@ -0,0 +1,25 @@
require 'java'
java_import 'org.apollo.game.model.Npc'
java_import 'org.apollo.game.model.World'
java_import 'org.apollo.game.model.Position'
def register(npc)
raise "Npc cannot be nil" if npc == nil
World.world.register(npc)
end
### Lumbridge spawns:
# Generic:
register Npc.new(4, Position.new(3232, 3207)) # woman, southernmost house
register Npc.new(1, Position.new(3231, 3237)) # man, house by willow tree
register Npc.new(2, Position.new(3224, 3240)) # man, house by willow tree
register Npc.new(5, Position.new(3229, 3239)) # woman, house by willow tree
# Other:
register Npc.new(0, Position.new(3221, 3221)) # hans
register Npc.new(456, Position.new(3243, 3210)) # father aereck
register Npc.new(519, Position.new(3231, 3203)) # bob from bob's axes
register Npc.new(520, Position.new(3212, 3247)) # shopkeeper
register Npc.new(521, Position.new(3211, 3245)) # shop assistant
register Npc.new(2244, Position.new(3232, 3229)) # lumbridge guide
+1
View File
@@ -1,4 +1,5 @@
require 'java'
java_import 'org.apollo.game.model.Animation'
java_import 'org.apollo.game.model.Graphic'
+1
View File
@@ -1,4 +1,5 @@
require 'java'
java_import 'org.apollo.game.model.Animation'
java_import 'org.apollo.game.model.Graphic'
java_import 'org.apollo.game.model.Item'
+1
View File
@@ -1,4 +1,5 @@
require 'java'
java_import 'org.apollo.game.model.EquipmentConstants'
AIR_ELEMENTS = {}
+1
View File
@@ -1,4 +1,5 @@
require 'java'
java_import 'org.apollo.game.model.Animation'
java_import 'org.apollo.game.model.Graphic'
java_import 'org.apollo.game.model.Item'
+1
View File
@@ -1,4 +1,5 @@
require 'java'
java_import 'org.apollo.game.action.Action'
java_import 'org.apollo.game.event.impl.DisplayTabInterfaceEvent'
java_import 'org.apollo.game.model.EquipmentConstants'
+1
View File
@@ -1,4 +1,5 @@
require 'java'
java_import 'org.apollo.game.action.DistancedAction'
java_import 'org.apollo.game.model.EquipmentConstants'
java_import 'org.apollo.game.model.def.ItemDefinition'
+1
View File
@@ -1,4 +1,5 @@
require 'java'
java_import 'org.apollo.game.model.Animation'
PICKAXES = {}
+29 -36
View File
@@ -1,30 +1,29 @@
package org.apollo;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import java.io.File;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apollo.fs.IndexedFileSystem;
import org.apollo.game.model.World;
import org.apollo.net.ApolloHandler;
import org.apollo.net.HttpPipelineFactory;
import org.apollo.net.JagGrabPipelineFactory;
import org.apollo.net.HttpChannelInitializer;
import org.apollo.net.JagGrabChannelInitializer;
import org.apollo.net.NetworkConstants;
import org.apollo.net.ServicePipelineFactory;
import org.apollo.net.ServiceChannelInitializer;
import org.apollo.net.release.Release;
import org.apollo.net.release.r317.Release317;
import org.apollo.util.plugin.PluginContext;
import org.apollo.util.plugin.PluginManager;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.util.HashedWheelTimer;
import org.jboss.netty.util.Timer;
/**
* The core class of the Apollo server.
@@ -74,27 +73,21 @@ public final class Server {
*/
private final ServerBootstrap jagGrabBootstrap = new ServerBootstrap();
/**
* The {@link ExecutorService} used for network events. The named thread factory is unused as Netty names threads
* itself.
*/
private final ExecutorService networkExecutor = Executors.newCachedThreadPool();
/**
* The {@link ServerBootstrap} for the service listener.
*/
private final ServerBootstrap serviceBootstrap = new ServerBootstrap();
/**
* The event loop group.
*/
private final EventLoopGroup loopGroup = new NioEventLoopGroup();
/**
* The service manager.
*/
private final ServiceManager serviceManager;
/**
* The timer used for idle checking.
*/
private final Timer timer = new HashedWheelTimer();
/**
* Creates the Apollo server.
*
@@ -145,22 +138,24 @@ public final class Server {
logger.info("Initialized release #" + release.getReleaseNumber() + ".");
ChannelFactory factory = new NioServerSocketChannelFactory(networkExecutor, networkExecutor);
serviceBootstrap.setFactory(factory);
httpBootstrap.setFactory(factory);
jagGrabBootstrap.setFactory(factory);
serviceBootstrap.group(loopGroup);
httpBootstrap.group(loopGroup);
jagGrabBootstrap.group(loopGroup);
context = new ServerContext(release, serviceManager);
ApolloHandler handler = new ApolloHandler(context);
ChannelPipelineFactory servicePipelineFactory = new ServicePipelineFactory(handler, timer);
serviceBootstrap.setPipelineFactory(servicePipelineFactory);
ChannelInitializer<SocketChannel> serviceInitializer = new ServiceChannelInitializer(handler);
serviceBootstrap.channel(NioServerSocketChannel.class);
serviceBootstrap.childHandler(serviceInitializer);
ChannelPipelineFactory httpPipelineFactory = new HttpPipelineFactory(handler, timer);
httpBootstrap.setPipelineFactory(httpPipelineFactory);
ChannelInitializer<SocketChannel> httpInitializer = new HttpChannelInitializer(handler);
httpBootstrap.channel(NioServerSocketChannel.class);
httpBootstrap.childHandler(httpInitializer);
ChannelPipelineFactory jagGrabPipelineFactory = new JagGrabPipelineFactory(handler, timer);
jagGrabBootstrap.setPipelineFactory(jagGrabPipelineFactory);
ChannelInitializer<SocketChannel> jagGrabInitializer = new JagGrabChannelInitializer(handler);
jagGrabBootstrap.channel(NioServerSocketChannel.class);
jagGrabBootstrap.childHandler(jagGrabInitializer);
}
/**
@@ -169,14 +164,12 @@ public final class Server {
* @throws Exception If an error occurs.
*/
public void start() throws Exception {
PluginManager mgr = new PluginManager(new PluginContext(context));
PluginManager manager = new PluginManager(new PluginContext(context));
serviceManager.startAll();
// TODO move this?
int releaseNo = context.getRelease().getReleaseNumber();
IndexedFileSystem fs = new IndexedFileSystem(new File("data/fs/" + releaseNo), true);
World.getWorld().init(releaseNo, fs, mgr);
World.getWorld().init(releaseNo, fs, manager);
}
}
-16
View File
@@ -1,8 +1,6 @@
package org.apollo;
import org.apollo.net.release.Release;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
/**
* A {@link ServerContext} is created along with the {@link Server} object. The primary difference is that a reference
@@ -15,11 +13,6 @@ import org.jboss.netty.channel.group.DefaultChannelGroup;
*/
public final class ServerContext {
/**
* The channel group.
*/
private final ChannelGroup group = new DefaultChannelGroup();
/**
* The current release.
*/
@@ -42,15 +35,6 @@ public final class ServerContext {
this.serviceManager.setContext(this);
}
/**
* Gets the channel group.
*
* @return The channel group.
*/
public ChannelGroup getChannelGroup() {
return group;
}
/**
* Gets the current release.
*
+2 -2
View File
@@ -109,8 +109,8 @@ public final class ServiceManager {
* @param ctx The server context.
*/
public void setContext(ServerContext ctx) {
for (Service s : services.values()) {
s.setContext(ctx);
for (Service service : services.values()) {
service.setContext(ctx);
}
}
-6
View File
@@ -109,13 +109,8 @@ public final class IndexedFileSystem implements Closeable {
}
}
// the number of archives
int archives = getFileCount(0);
// the hash
int hash = 1234;
// the CRCs
int[] crcs = new int[archives];
// calculate the CRCs
@@ -138,7 +133,6 @@ public final class IndexedFileSystem implements Closeable {
buffer.putInt(crc);
}
// place the hash into the buffer
buffer.putInt(hash);
buffer.flip();
+6
View File
@@ -25,6 +25,7 @@ public final class Archive {
int extractedSize = ByteBufferUtil.readUnsignedTriByte(buffer);
int size = ByteBufferUtil.readUnsignedTriByte(buffer);
boolean extracted = false;
if (size != extractedSize) {
byte[] compressed = new byte[size];
byte[] uncompressed = new byte[extractedSize];
@@ -33,15 +34,18 @@ public final class Archive {
buffer = ByteBuffer.wrap(uncompressed);
extracted = true;
}
int entries = buffer.getShort() & 0xFFFF;
int[] identifiers = new int[entries];
int[] extractedSizes = new int[entries];
int[] sizes = new int[entries];
for (int i = 0; i < entries; i++) {
identifiers[i] = buffer.getInt();
extractedSizes[i] = ByteBufferUtil.readUnsignedTriByte(buffer);
sizes[i] = ByteBufferUtil.readUnsignedTriByte(buffer);
}
ArchiveEntry[] entry = new ArchiveEntry[entries];
for (int i = 0; i < entries; i++) {
ByteBuffer entryBuffer;
@@ -85,9 +89,11 @@ public final class Archive {
public ArchiveEntry getEntry(String name) throws FileNotFoundException {
int hash = 0;
name = name.toUpperCase();
for (int i = 0; i < name.length(); i++) {
hash = hash * 61 + name.charAt(i) - 32;
}
for (ArchiveEntry entry : entries) {
if (entry.getIdentifier() == hash) {
return entry;
@@ -62,7 +62,7 @@ public abstract class DistancedAction<T extends Mob> extends Action<T> {
} else if (mob.getPosition().getDistance(position) <= distance) {
reached = true;
setDelay(delay);
if (immediate) { // TODO: required?
if (immediate) {
executeAction();
}
}
@@ -1,7 +1,7 @@
package org.apollo.game.command;
import org.apollo.game.model.Player;
import org.apollo.game.model.Player.PrivilegeLevel;
import org.apollo.game.model.settings.PrivilegeLevel;
/**
* An interface which should be implemented by classes to listen to {@link Command}s.
@@ -14,7 +14,7 @@ import org.apollo.util.plugin.PluginManager;
* @author Graham
*/
public final class CreditsCommandListener extends CommandListener {
/*
* If you are considering removing this command, please bear in mind that Apollo took several people thousands of
* hours to create. We released it to the world for free and it isn't much to ask to leave this command in. It isn't
@@ -2,8 +2,8 @@ package org.apollo.game.event.handler.impl;
import org.apollo.game.event.handler.EventHandler;
import org.apollo.game.event.handler.EventHandlerContext;
import org.apollo.game.event.impl.PlayerDesignEvent;
import org.apollo.game.event.impl.CloseInterfaceEvent;
import org.apollo.game.event.impl.PlayerDesignEvent;
import org.apollo.game.model.Player;
/**
@@ -4,8 +4,8 @@ import org.apollo.game.event.handler.EventHandler;
import org.apollo.game.event.handler.EventHandlerContext;
import org.apollo.game.event.impl.PlayerDesignEvent;
import org.apollo.game.model.Appearance;
import org.apollo.game.model.Gender;
import org.apollo.game.model.Player;
import org.apollo.game.model.settings.Gender;
/**
* A handler which verifies {@link PlayerDesignEvent}s.
@@ -1,7 +1,7 @@
package org.apollo.game.event.impl;
import org.apollo.game.event.Event;
import org.apollo.game.model.PrivacyState;
import org.apollo.game.model.settings.PrivacyState;
/**
* An {@link Event} sent by the client or server to update the chat and trade privacy state.
@@ -1,5 +1,7 @@
package org.apollo.game.model;
import org.apollo.game.model.settings.Gender;
/**
* Represents the appearance of a player.
*
+38
View File
@@ -37,4 +37,42 @@ public abstract class Entity {
return position;
}
/**
* Represents a type of {@link Entity}.
*
* @author Major
*/
public enum EntityType {
/**
* An item that has been dropped on the ground.
*/
DROPPED_ITEM,
/**
* A temporary object.
*/
GAME_OBJECT,
/**
* An npc.
*/
NPC,
/**
* A player.
*/
PLAYER,
/**
* A projectile (e.g. an arrow).
*/
PROJECTILE,
/**
* A permanent object appearing on the map, loaded from the game resources.
*/
STATIC_OBJECT;
}
}
-40
View File
@@ -1,40 +0,0 @@
package org.apollo.game.model;
/**
* Represents a type of {@link Entity}.
*
* @author Major
*/
public enum EntityType {
/**
* An item that has been dropped on the ground.
*/
DROPPED_ITEM,
/**
* A temporary object.
*/
GAME_OBJECT,
/**
* An npc.
*/
NPC,
/**
* A player.
*/
PLAYER,
/**
* A projectile (e.g. an arrow).
*/
PROJECTILE,
/**
* A permanent object appearing on the map, loaded from the cache.
*/
STATIC_OBJECT;
}
+1 -1
View File
@@ -46,7 +46,7 @@ public final class Npc extends Mob {
* @param id The id.
*/
public void transform(int id) {
if (id < 0 || id > NpcDefinition.count()) {
if (id < 0 || id >= NpcDefinition.count()) {
throw new IllegalArgumentException("Id to transform to is out of bounds");
}
definition = NpcDefinition.lookup(id);
+45 -81
View File
@@ -20,6 +20,9 @@ import org.apollo.game.model.inv.AppearanceInventoryListener;
import org.apollo.game.model.inv.FullInventoryListener;
import org.apollo.game.model.inv.InventoryListener;
import org.apollo.game.model.inv.SynchronizationInventoryListener;
import org.apollo.game.model.settings.PrivacyState;
import org.apollo.game.model.settings.PrivilegeLevel;
import org.apollo.game.model.settings.ScreenBrightness;
import org.apollo.game.model.skill.LevelUpSkillListener;
import org.apollo.game.model.skill.SkillListener;
import org.apollo.game.model.skill.SynchronizationSkillListener;
@@ -35,68 +38,6 @@ import org.apollo.util.Point;
*/
public final class Player extends Mob {
/**
* An enumeration with the different privilege levels a player can have.
*
* @author Graham
*/
public enum PrivilegeLevel {
/**
* An administrator (rights 2) account.
*/
ADMINISTRATOR(2),
/**
* A player moderator (rights 1) account.
*/
MODERATOR(1),
/**
* A standard (rights 0) account.
*/
STANDARD(0);
/**
* Gets the privilege level for the specified numerical level.
*
* @param value The numerical level.
* @return The privilege level.
* @throws IllegalArgumentException If the numerical level is invalid.
*/
public static PrivilegeLevel valueOf(int value) {
PrivilegeLevel[] values = values();
if (value < 0 || value > values.length) {
throw new IndexOutOfBoundsException("Invalid privilege level integer value supplied");
}
return values[value];
}
/**
* The numerical level used in the protocol.
*/
private final int value;
/**
* Creates the privilege level.
*
* @param value The numerical level.
*/
private PrivilegeLevel(int value) {
this.value = value;
}
/**
* Gets the numerical level.
*
* @return The numerical level used in the protocol.
*/
public int toInteger() {
return value;
}
}
/**
* The player's appearance.
*/
@@ -185,13 +126,18 @@ public final class Player extends Mob {
/**
* The player's run energy.
*/
private int runEnergy = 100;
private int runEnergy = 0;
/**
* A flag indicating if this player is running.
*/
private boolean running = false;
/**
* The brightness of this player's screen.
*/
private ScreenBrightness screenBrightness;
/**
* The {@link GameSession} currently attached to this {@link Player}.
*/
@@ -397,6 +343,15 @@ public final class Player extends Mob {
return runEnergy;
}
/**
* Gets this player's {@link ScreenBrightness}.
*
* @return The screen brightness.
*/
public ScreenBrightness getScreenBrightness() {
return screenBrightness;
}
/**
* Gets the game session.
*
@@ -715,24 +670,6 @@ public final class Player extends Mob {
this.privateChatPrivacy = privateChatPrivacy;
}
/**
* Sets the public chat {@link PrivacyState}.
*
* @param publicChatPrivacy The privacy state.
*/
public void setPublicChatPrivacy(PrivacyState publicChatPrivacy) {
this.publicChatPrivacy = publicChatPrivacy;
}
/**
* Sets the trade chat {@link PrivacyState}.
*
* @param tradeChatPrivacy The privacy state.
*/
public void setTradeChatPrivacy(PrivacyState tradeChatPrivacy) {
this.tradeChatPrivacy = tradeChatPrivacy;
}
/**
* Sets the privilege level.
*
@@ -742,6 +679,15 @@ public final class Player extends Mob {
this.privilegeLevel = privilegeLevel;
}
/**
* Sets the public chat {@link PrivacyState}.
*
* @param publicChatPrivacy The privacy state.
*/
public void setPublicChatPrivacy(PrivacyState publicChatPrivacy) {
this.publicChatPrivacy = publicChatPrivacy;
}
/**
* Sets the region changed flag.
*
@@ -761,6 +707,15 @@ public final class Player extends Mob {
send(new UpdateRunEnergyEvent(runEnergy));
}
/**
* Sets the {@link ScreenBrightness} of this player.
*
* @param brightness The screen brightness.
*/
public void setScreenBrightness(ScreenBrightness brightness) {
this.screenBrightness = brightness;
}
/**
* Sets the player's {@link GameSession}.
*
@@ -775,6 +730,15 @@ public final class Player extends Mob {
getBlockSet().add(SynchronizationBlock.createAppearanceBlock(this));
}
/**
* Sets the trade chat {@link PrivacyState}.
*
* @param tradeChatPrivacy The privacy state.
*/
public void setTradeChatPrivacy(PrivacyState tradeChatPrivacy) {
this.tradeChatPrivacy = tradeChatPrivacy;
}
/**
* Sets whether the player is withdrawing notes from the bank.
*
@@ -1,7 +1,6 @@
package org.apollo.game.model.obj;
import org.apollo.game.model.Entity;
import org.apollo.game.model.EntityType;
import org.apollo.game.model.Position;
import org.apollo.game.model.def.ObjectDefinition;
@@ -1,7 +1,6 @@
package org.apollo.game.model.obj;
import org.apollo.game.model.Entity;
import org.apollo.game.model.EntityType;
import org.apollo.game.model.Position;
import org.apollo.game.model.def.ObjectDefinition;
+2 -2
View File
@@ -47,8 +47,8 @@ public final class Sector {
}
/**
* Adds a {@link Entity} from to sector. Note that this does not spawn the entity, or do any other action
* other than register it to this sector.
* Adds a {@link Entity} from to sector. Note that this does not spawn the entity, or do any other action other than
* register it to this sector.
*
* @param entity The entity.
* @return {@code true} if the entity was added, otherwise {@code false}.
@@ -43,10 +43,7 @@ public final class SectorCoordinates {
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final SectorCoordinates other = (SectorCoordinates) obj;
@@ -1,4 +1,4 @@
package org.apollo.game.model;
package org.apollo.game.model.settings;
/**
* An enumeration containing the two genders (male and female).
@@ -1,4 +1,4 @@
package org.apollo.game.model;
package org.apollo.game.model.settings;
/**
* An enumeration representing the different privacy states for public, private and trade chat.
@@ -8,9 +8,9 @@ package org.apollo.game.model;
public enum PrivacyState {
/**
* Represents the 'friends' state, when only messages from friends and moderators are displayed.
* Represents the 'on' state, when all messages are displayed.
*/
FRIENDS(2),
ON(0),
/**
* Represents the 'hidden' state, when all public chat text is displayed over the heads of players, but not in the
@@ -19,14 +19,14 @@ public enum PrivacyState {
HIDE(1),
/**
* Represents the 'off' state, when only messages from moderators are displayed.
* Represents the 'friends' state, when only messages from friends and moderators are displayed.
*/
OFF(3),
FRIENDS(2),
/**
* Represents the 'on' state, when all messages are displayed.
* Represents the 'off' state, when only messages from moderators are displayed.
*/
ON(0);
OFF(3);
/**
* Gets the privacy state for the specified numerical value.
@@ -0,0 +1,63 @@
package org.apollo.game.model.settings;
/**
* An enumeration with the different privilege levels a player can have.
*
* @author Graham
*/
public enum PrivilegeLevel {
/**
* An administrator (rights 2) account.
*/
ADMINISTRATOR(2),
/**
* A player moderator (rights 1) account.
*/
MODERATOR(1),
/**
* A standard (rights 0) account.
*/
STANDARD(0);
/**
* Gets the privilege level for the specified numerical level.
*
* @param value The numerical level.
* @return The privilege level.
* @throws IllegalArgumentException If the numerical level is invalid.
*/
public static PrivilegeLevel valueOf(int value) {
PrivilegeLevel[] values = values();
if (value < 0 || value >= values.length) {
throw new IndexOutOfBoundsException("Invalid privilege level integer value supplied");
}
return values[value];
}
/**
* The numerical level used in the protocol.
*/
private final int value;
/**
* Creates the privilege level.
*
* @param value The numerical level.
*/
private PrivilegeLevel(int value) {
this.value = value;
}
/**
* Gets the numerical level.
*
* @return The numerical level used in the protocol.
*/
public int toInteger() {
return value;
}
}
@@ -0,0 +1,68 @@
package org.apollo.game.model.settings;
/**
* An enumeration representing
*
* @author Major
*/
public enum ScreenBrightness {
/**
* Represents the 'dark' screen brightness.
*/
DARK(0),
/**
* Represents the 'normal' screen brightness.
*/
NORMAL(1),
/**
* Represents the 'bright' screen brightness.
*/
BRIGHT(2),
/**
* Represents the 'very bright' screen brightness.
*/
VERY_BRIGHT(3);
/**
* Gets the screen brightness for the specified numerical value.
*
* @param value The numerical value.
* @return The screen brightness.
* @throws IllegalArgumentException If the numerical value is invalid.
*/
public static ScreenBrightness valueOf(int value) {
ScreenBrightness[] values = values();
if (value < 0 || value >= values.length) {
throw new IllegalArgumentException("Invalid screen brightness integer value specified");
}
return values[value];
}
/**
* The numerical value of this brightness.
*/
private final int value;
/**
* Creates the screen brightness.
*
* @param value The numerical value.
*/
private ScreenBrightness(int value) {
this.value = value;
}
/**
* Converts this screen brightness to an integer.
*
* @return The numerical value.
*/
public int toInteger() {
return value;
}
}
@@ -0,0 +1,4 @@
/**
* Contains player setting or customisation-related classes.
*/
package org.apollo.game.model.settings;
@@ -33,7 +33,7 @@ public final class LevelUpSkillListener extends SkillAdapter {
String article = LanguageUtil.getIndefiniteArticle(name);
player.sendMessage("You've just advanced " + article + " " + name + " level! You have reached level "
+ skill.getMaximumLevel() + ".");
if (Skill.isCombatSkill(id)) {
player.getSkillSet().calculateCombatLevel();
}
@@ -1,7 +1,7 @@
package org.apollo.game.sync.block;
import org.apollo.game.event.impl.ChatEvent;
import org.apollo.game.model.Player.PrivilegeLevel;
import org.apollo.game.model.settings.PrivilegeLevel;
/**
* The chat {@link SynchronizationBlock}.
+1 -1
View File
@@ -14,7 +14,7 @@ import org.xml.sax.SAXException;
*
* @author Major
*/
public class RsaKeyParser {
public final class RsaKeyParser {
/**
* The source {@link InputStream}.
@@ -6,15 +6,16 @@ import java.io.FileInputStream;
import java.io.IOException;
import org.apollo.game.model.Appearance;
import org.apollo.game.model.Gender;
import org.apollo.game.model.Inventory;
import org.apollo.game.model.Item;
import org.apollo.game.model.Player;
import org.apollo.game.model.Player.PrivilegeLevel;
import org.apollo.game.model.Position;
import org.apollo.game.model.PrivacyState;
import org.apollo.game.model.Skill;
import org.apollo.game.model.SkillSet;
import org.apollo.game.model.settings.Gender;
import org.apollo.game.model.settings.PrivacyState;
import org.apollo.game.model.settings.PrivilegeLevel;
import org.apollo.game.model.settings.ScreenBrightness;
import org.apollo.io.player.PlayerLoader;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.net.codec.login.LoginConstants;
@@ -35,14 +36,12 @@ public final class BinaryPlayerLoader implements PlayerLoader {
@Override
public PlayerLoaderResponse loadPlayer(PlayerCredentials credentials) throws IOException {
File f = BinaryPlayerUtil.getFile(credentials.getUsername());
if (!f.exists()) {
File file = BinaryPlayerUtil.getFile(credentials.getUsername());
if (!file.exists()) {
return new PlayerLoaderResponse(LoginConstants.STATUS_OK, new Player(credentials, SPAWN_POSITION));
}
DataInputStream in = new DataInputStream(new FileInputStream(f));
try {
try (DataInputStream in = new DataInputStream(new FileInputStream(file))) {
// read credentials and privileges
String name = StreamUtil.readString(in);
String pass = StreamUtil.readString(in);
@@ -58,6 +57,8 @@ public final class BinaryPlayerLoader implements PlayerLoader {
PrivacyState privacyPublicChat = PrivacyState.valueOf(in.readByte());
PrivacyState privacyPrivateChat = PrivacyState.valueOf(in.readByte());
PrivacyState privacyTradeCompete = PrivacyState.valueOf(in.readByte());
int runEnergy = in.readByte();
ScreenBrightness brightness = ScreenBrightness.valueOf(in.readByte());
// read position
int x = in.readUnsignedShort();
@@ -84,6 +85,9 @@ public final class BinaryPlayerLoader implements PlayerLoader {
player.setPublicChatPrivacy(privacyPublicChat);
player.setPrivateChatPrivacy(privacyPrivateChat);
player.setTradeChatPrivacy(privacyTradeCompete);
player.setRunEnergy(runEnergy);
player.setScreenBrightness(brightness);
player.setDesigned(designed);
player.setAppearance(new Appearance(gender, style, colors));
@@ -108,8 +112,6 @@ public final class BinaryPlayerLoader implements PlayerLoader {
}
return new PlayerLoaderResponse(LoginConstants.STATUS_OK, player);
} finally {
in.close();
}
}
@@ -24,9 +24,9 @@ public final class BinaryPlayerSaver implements PlayerSaver {
@Override
public void savePlayer(Player player) throws IOException {
File f = BinaryPlayerUtil.getFile(player.getName());
DataOutputStream out = new DataOutputStream(new FileOutputStream(f));
try {
File file = BinaryPlayerUtil.getFile(player.getName());
try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) {
// write credentials and privileges
StreamUtil.writeString(out, player.getName());
StreamUtil.writeString(out, player.getCredentials().getPassword());
@@ -37,6 +37,8 @@ public final class BinaryPlayerSaver implements PlayerSaver {
out.writeByte(player.getPublicChatPrivacy().toInteger());
out.writeByte(player.getPrivateChatPrivacy().toInteger());
out.writeByte(player.getTradeChatPrivacy().toInteger());
out.writeByte(player.getRunEnergy());
out.writeByte(player.getScreenBrightness().toInteger());
// write position
Position position = player.getPosition();
@@ -66,13 +68,11 @@ public final class BinaryPlayerSaver implements PlayerSaver {
// write skills
SkillSet skills = player.getSkillSet();
out.writeByte(skills.size());
for (int i = 0; i < skills.size(); i++) {
Skill skill = skills.getSkill(i);
for (int id = 0; id < skills.size(); id++) {
Skill skill = skills.getSkill(id);
out.writeByte(skill.getCurrentLevel());
out.writeDouble(skill.getExperience());
}
} finally {
out.close();
}
}
@@ -1,8 +1,8 @@
package org.apollo.io.player.impl;
import org.apollo.game.model.Player;
import org.apollo.game.model.Player.PrivilegeLevel;
import org.apollo.game.model.Position;
import org.apollo.game.model.settings.PrivilegeLevel;
import org.apollo.io.player.PlayerLoader;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.net.codec.login.LoginConstants;
+24 -42
View File
@@ -1,5 +1,11 @@
package org.apollo.net;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpRequest;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -10,22 +16,14 @@ import org.apollo.net.codec.jaggrab.JagGrabRequest;
import org.apollo.net.session.LoginSession;
import org.apollo.net.session.Session;
import org.apollo.net.session.UpdateSession;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.timeout.IdleStateAwareChannelUpstreamHandler;
import org.jboss.netty.handler.timeout.IdleStateEvent;
/**
* An implementation of {@link SimpleChannelUpstreamHandler} which handles incoming upstream events from Netty.
*
* @author Graham
*/
public final class ApolloHandler extends IdleStateAwareChannelUpstreamHandler {
@Sharable
public final class ApolloHandler extends ChannelInboundHandlerAdapter {
/**
* The logger for this class.
@@ -47,58 +45,42 @@ public final class ApolloHandler extends IdleStateAwareChannelUpstreamHandler {
}
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
Channel channel = ctx.getChannel();
logger.info("Channel connected: " + channel);
serverContext.getChannelGroup().add(channel);
}
@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
Channel channel = ctx.getChannel();
logger.info("Channel disconnected: " + channel);
serverContext.getChannelGroup().remove(channel);
Object attachment = ctx.getAttachment();
if (attachment != null) {
((Session) attachment).destroy();
public void channelInactive(ChannelHandlerContext ctx) {
Channel channel = ctx.channel();
Session session = ctx.attr(NetworkConstants.SESSION_KEY).getAndRemove();
if (session != null) {
session.destroy();
}
logger.info("Channel disconnected: " + channel);
channel.close();
}
@Override
public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) {
e.getChannel().close();
public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) {
logger.log(Level.WARNING, "Exception occured for channel: " + ctx.channel() + ", closing...", e);
ctx.channel().close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
logger.log(Level.WARNING, "Exception occured for channel: " + e.getChannel() + ", closing...", e.getCause());
ctx.getChannel().close();
}
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
if (ctx.getAttachment() == null) {
Object msg = e.getMessage();
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (ctx.attr(NetworkConstants.SESSION_KEY).get() == null) {
if (msg instanceof HttpRequest || msg instanceof JagGrabRequest) {
Session s = new UpdateSession(ctx.getChannel(), serverContext);
s.messageReceived(msg);
// we don't bother to set it as an attachment, as the connection
// will be closed once the request is completed anyway
new UpdateSession(ctx.channel(), serverContext).messageReceived(msg);
} else {
HandshakeMessage handshakeMessage = (HandshakeMessage) msg;
switch (handshakeMessage.getServiceId()) {
case HandshakeConstants.SERVICE_GAME:
ctx.setAttachment(new LoginSession(ctx.getChannel(), ctx, serverContext));
ctx.attr(NetworkConstants.SESSION_KEY).set(new LoginSession(ctx, serverContext));
break;
case HandshakeConstants.SERVICE_UPDATE:
ctx.setAttachment(new UpdateSession(ctx.getChannel(), serverContext));
ctx.attr(NetworkConstants.SESSION_KEY).set(new UpdateSession(ctx.channel(), serverContext));
break;
default:
throw new IllegalStateException("Invalid service id");
}
}
} else {
((Session) ctx.getAttachment()).messageReceived(e.getMessage());
ctx.attr(NetworkConstants.SESSION_KEY).get().messageReceived(msg);
}
}
@@ -0,0 +1,53 @@
package org.apollo.net;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.timeout.IdleStateHandler;
/**
* A {@link ChannelPipelineFactory} for the HTTP protocol.
*
* @author Graham
*/
public final class HttpChannelInitializer extends ChannelInitializer<SocketChannel> {
/**
* The maximum length of a request, in bytes.
*/
private static final int MAX_REQUEST_LENGTH = 8192;
/**
* The server event handler.
*/
private final ApolloHandler handler;
/**
* Creates the HTTP pipeline factory.
*
* @param handler The file server event handler.
*/
public HttpChannelInitializer(ApolloHandler handler) {
this.handler = handler;
}
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// decoders
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("chunker", new HttpObjectAggregator(MAX_REQUEST_LENGTH));
// encoders
pipeline.addLast("encoder", new HttpResponseEncoder());
// handler
pipeline.addLast("timeout", new IdleStateHandler(NetworkConstants.IDLE_TIME, 0, 0));
pipeline.addLast("handler", handler);
}
}
@@ -1,63 +0,0 @@
package org.apollo.net;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.util.Timer;
/**
* A {@link ChannelPipelineFactory} for the HTTP protocol.
*
* @author Graham
*/
public final class HttpPipelineFactory implements ChannelPipelineFactory {
/**
* The maximum length of a request, in bytes.
*/
private static final int MAX_REQUEST_LENGTH = 8192;
/**
* The server event handler.
*/
private final ApolloHandler handler;
/**
* The timer used for idle checking.
*/
private final Timer timer;
/**
* Creates the HTTP pipeline factory.
*
* @param handler The file server event handler.
* @param timer The timer used for idle checking.
*/
public HttpPipelineFactory(ApolloHandler handler, Timer timer) {
this.handler = handler;
this.timer = timer;
}
@Override
public ChannelPipeline getPipeline() {
ChannelPipeline pipeline = Channels.pipeline();
// decoders
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("chunker", new HttpChunkAggregator(MAX_REQUEST_LENGTH));
// encoders
pipeline.addLast("encoder", new HttpResponseEncoder());
// handler
pipeline.addLast("timeout", new IdleStateHandler(timer, NetworkConstants.IDLE_TIME, 0, 0));
pipeline.addLast("handler", handler);
return pipeline;
}
}
@@ -1,30 +1,30 @@
package org.apollo.net;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.timeout.IdleStateHandler;
import java.nio.charset.Charset;
import org.apollo.net.codec.jaggrab.JagGrabRequestDecoder;
import org.apollo.net.codec.jaggrab.JagGrabResponseEncoder;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.util.Timer;
/**
* A {@link ChannelPipelineFactory} for the JAGGRAB protocol.
*
* @author Graham
*/
public final class JagGrabPipelineFactory implements ChannelPipelineFactory {
public final class JagGrabChannelInitializer extends ChannelInitializer<SocketChannel> {
/**
* A buffer with two line feed (LF) characters in it.
*/
private static final ChannelBuffer DOUBLE_LINE_FEED_DELIMITER = ChannelBuffers.buffer(2);
private static final ByteBuf DOUBLE_LINE_FEED_DELIMITER = Unpooled.buffer(2);
/**
* The character set used in the request.
@@ -40,8 +40,7 @@ public final class JagGrabPipelineFactory implements ChannelPipelineFactory {
* Populates the double line feed buffer.
*/
static {
DOUBLE_LINE_FEED_DELIMITER.writeByte(10);
DOUBLE_LINE_FEED_DELIMITER.writeByte(10);
DOUBLE_LINE_FEED_DELIMITER.writeByte(10).writeByte(10);
}
/**
@@ -49,25 +48,18 @@ public final class JagGrabPipelineFactory implements ChannelPipelineFactory {
*/
private final ApolloHandler handler;
/**
* The timer used for idle checking.
*/
private final Timer timer;
/**
* Creates a {@code JAGGRAB} pipeline factory.
*
* @param handler The file server event handler.
* @param timer The timer used for idle checking.
*/
public JagGrabPipelineFactory(ApolloHandler handler, Timer timer) {
public JagGrabChannelInitializer(ApolloHandler handler) {
this.handler = handler;
this.timer = timer;
}
@Override
public ChannelPipeline getPipeline() {
ChannelPipeline pipeline = Channels.pipeline();
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// decoders
pipeline.addLast("framer", new DelimiterBasedFrameDecoder(MAX_REQUEST_LENGTH, DOUBLE_LINE_FEED_DELIMITER));
@@ -78,10 +70,8 @@ public final class JagGrabPipelineFactory implements ChannelPipelineFactory {
pipeline.addLast("jaggrab-encoder", new JagGrabResponseEncoder());
// handler
pipeline.addLast("timeout", new IdleStateHandler(timer, NetworkConstants.IDLE_TIME, 0, 0));
pipeline.addLast("timeout", new IdleStateHandler(NetworkConstants.IDLE_TIME, 0, 0));
pipeline.addLast("handler", handler);
return pipeline;
}
}
+9
View File
@@ -1,7 +1,11 @@
package org.apollo.net;
import io.netty.util.AttributeKey;
import java.math.BigInteger;
import org.apollo.net.session.Session;
/**
* Holds various network-related constants such as port numbers.
*
@@ -39,6 +43,11 @@ public final class NetworkConstants {
*/
public static final int SERVICE_PORT = 43594;
/**
* The {@link Session} {@link AttributeKey}.
*/
public static final AttributeKey<Session> SESSION_KEY = AttributeKey.valueOf("session");
/**
* The terminator of a string.
*/
@@ -0,0 +1,39 @@
package org.apollo.net;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import org.apollo.net.codec.handshake.HandshakeDecoder;
/**
* A {@link ChannelPipelineFactory} which creates {@link ChannelPipeline}s for the service pipeline.
*
* @author Graham
*/
public final class ServiceChannelInitializer extends ChannelInitializer<SocketChannel> {
/**
* The network event handler.
*/
private final ApolloHandler handler;
/**
* Creates the service pipeline factory.
*
* @param handler The networking event handler.
*/
public ServiceChannelInitializer(ApolloHandler handler) {
this.handler = handler;
}
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("handshakeDecoder", new HandshakeDecoder());
pipeline.addLast("timeout", new IdleStateHandler(NetworkConstants.IDLE_TIME, 0, 0));
pipeline.addLast("handler", handler);
}
}
@@ -1,47 +0,0 @@
package org.apollo.net;
import org.apollo.net.codec.handshake.HandshakeDecoder;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.util.Timer;
/**
* A {@link ChannelPipelineFactory} which creates {@link ChannelPipeline}s for the service pipeline.
*
* @author Graham
*/
public final class ServicePipelineFactory implements ChannelPipelineFactory {
/**
* The network event handler.
*/
private final ApolloHandler handler;
/**
* The timer used for idle checking.
*/
private final Timer timer;
/**
* Creates the service pipeline factory.
*
* @param handler The networking event handler.
* @param timer The timer used for idle checking.
*/
public ServicePipelineFactory(ApolloHandler handler, Timer timer) {
this.handler = handler;
this.timer = timer;
}
@Override
public ChannelPipeline getPipeline() {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("handshakeDecoder", new HandshakeDecoder());
pipeline.addLast("timeout", new IdleStateHandler(timer, NetworkConstants.IDLE_TIME, 0, 0));
pipeline.addLast("handler", handler);
return pipeline;
}
}
@@ -1,18 +1,20 @@
package org.apollo.net.codec.game;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List;
import org.apollo.game.event.Event;
import org.apollo.net.release.EventDecoder;
import org.apollo.net.release.Release;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
/**
* A {@link OneToOneDecoder} that decodes {@link GamePacket}s into {@link Event}s.
*
* @author Graham
*/
public final class GameEventDecoder extends OneToOneDecoder {
public final class GameEventDecoder extends MessageToMessageDecoder<GamePacket> {
/**
* The current release.
@@ -29,17 +31,14 @@ public final class GameEventDecoder extends OneToOneDecoder {
}
@Override
protected Object decode(ChannelHandlerContext ctx, Channel c, Object msg) {
if (msg instanceof GamePacket) {
GamePacket packet = (GamePacket) msg;
EventDecoder<?> decoder = release.getEventDecoder(packet.getOpcode());
if (decoder != null) {
return decoder.decode(packet);
}
protected void decode(ChannelHandlerContext ctx, GamePacket msg, List<Object> out) {
GamePacket packet = (GamePacket) msg;
EventDecoder<?> decoder = release.getEventDecoder(packet.getOpcode());
if (decoder != null) {
out.add(decoder.decode(packet));
} else {
System.out.println("Unidentified packet received - opcode: " + packet.getOpcode() + ".");
return null;
}
return msg;
}
}
@@ -1,18 +1,20 @@
package org.apollo.net.codec.game;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
import org.apollo.game.event.Event;
import org.apollo.net.release.EventEncoder;
import org.apollo.net.release.Release;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
/**
* A {@link OneToOneEncoder} which encodes {@link Event}s into {@link GamePacket}s.
*
* @author Graham
*/
public final class GameEventEncoder extends OneToOneEncoder {
public final class GameEventEncoder extends MessageToMessageEncoder<Event> {
/**
* The current release.
@@ -30,16 +32,11 @@ public final class GameEventEncoder extends OneToOneEncoder {
@SuppressWarnings("unchecked")
@Override
protected Object encode(ChannelHandlerContext ctx, Channel c, Object msg) {
if (msg instanceof Event) {
Event event = (Event) msg;
EventEncoder<Event> encoder = (EventEncoder<Event>) release.getEventEncoder(event.getClass());
if (encoder != null) {
return encoder.encode(event);
}
return null;
protected void encode(ChannelHandlerContext ctx, Event event, List<Object> out) {
EventEncoder<Event> encoder = (EventEncoder<Event>) release.getEventEncoder(event.getClass());
if (encoder != null) {
out.add(encoder.encode(event));
}
return msg;
}
}
@@ -1,7 +1,8 @@
package org.apollo.net.codec.game;
import io.netty.buffer.ByteBuf;
import org.apollo.net.meta.PacketType;
import org.jboss.netty.buffer.ChannelBuffer;
/**
* Represents a single packet used in the in-game protocol.
@@ -23,7 +24,7 @@ public final class GamePacket {
/**
* The payload.
*/
private final ChannelBuffer payload;
private final ByteBuf payload;
/**
* The packet type.
@@ -37,7 +38,7 @@ public final class GamePacket {
* @param type The packet type.
* @param payload The payload.
*/
public GamePacket(int opcode, PacketType type, ChannelBuffer payload) {
public GamePacket(int opcode, PacketType type, ByteBuf payload) {
this.opcode = opcode;
this.type = type;
length = payload.readableBytes();
@@ -67,7 +68,7 @@ public final class GamePacket {
*
* @return The payload.
*/
public ChannelBuffer getPayload() {
public ByteBuf getPayload() {
return payload;
}
@@ -1,9 +1,10 @@
package org.apollo.net.codec.game;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.apollo.net.NetworkConstants;
import org.apollo.net.meta.PacketType;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
/**
* A class which assists in creating a {@link GamePacket}.
@@ -20,7 +21,7 @@ public final class GamePacketBuilder {
/**
* The buffer.
*/
private final ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
private final ByteBuf buffer = Unpooled.buffer();
/**
* The current mode.
@@ -240,7 +241,7 @@ public final class GamePacketBuilder {
int requiredSpace = bytePos - buffer.writerIndex() + 1;
requiredSpace += (numBits + 7) / 8;
buffer.ensureWritableBytes(requiredSpace);
buffer.ensureWritable(requiredSpace);
for (; numBits > bitOffset; bitOffset = 8) {
int tmp = buffer.getByte(bytePos);
@@ -274,9 +275,9 @@ public final class GamePacketBuilder {
/**
* Puts the bytes from the specified buffer into this packet's buffer.
*
* @param buffer The source {@link ChannelBuffer}.
* @param buffer The source {@link ByteBuf}.
*/
public void putBytes(ChannelBuffer buffer) {
public void putBytes(ByteBuf buffer) {
byte[] bytes = new byte[buffer.readableBytes()];
buffer.markReaderIndex();
try {
@@ -318,9 +319,9 @@ public final class GamePacketBuilder {
/**
* Puts the bytes from the specified buffer into this packet's buffer, in reverse.
*
* @param buffer The source {@link ChannelBuffer}.
* @param buffer The source {@link ByteBuf}.
*/
public void putBytesReverse(ChannelBuffer buffer) {
public void putBytesReverse(ByteBuf buffer) {
byte[] bytes = new byte[buffer.readableBytes()];
buffer.markReaderIndex();
try {
@@ -1,6 +1,11 @@
package org.apollo.net.codec.game;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import java.io.IOException;
import java.util.List;
import net.burtleburtle.bob.rand.IsaacRandom;
@@ -8,10 +13,6 @@ import org.apollo.net.meta.PacketMetaData;
import org.apollo.net.meta.PacketType;
import org.apollo.net.release.Release;
import org.apollo.util.StatefulFrameDecoder;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
/**
* A {@link StatefulFrameDecoder} which decodes game packets.
@@ -58,15 +59,18 @@ public final class GamePacketDecoder extends StatefulFrameDecoder<GameDecoderSta
}
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, GameDecoderState state)
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out, GameDecoderState state)
throws IOException {
switch (state) {
case GAME_OPCODE:
return decodeOpcode(ctx, channel, buffer);
decodeOpcode(ctx, in, out);
break;
case GAME_LENGTH:
return decodeLength(ctx, channel, buffer);
decodeLength(ctx, in, out);
break;
case GAME_PAYLOAD:
return decodePayload(ctx, channel, buffer);
decodePayload(ctx, in, out);
break;
default:
throw new IllegalStateException("Invalid game decoder state");
}
@@ -81,11 +85,11 @@ public final class GamePacketDecoder extends StatefulFrameDecoder<GameDecoderSta
* @return The frame, or {@code null}.
* @throws Exception If an error occurs.
*/
private Object decodeLength(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) {
if (buffer.readable()) {
private Object decodeLength(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) {
if (buffer.isReadable()) {
length = buffer.readUnsignedByte();
if (length == 0) {
return decodeZeroLengthPacket(ctx, channel, buffer);
decodeZeroLengthPacket(ctx, buffer, out);
} else {
setState(GameDecoderState.GAME_PAYLOAD);
}
@@ -102,8 +106,8 @@ public final class GamePacketDecoder extends StatefulFrameDecoder<GameDecoderSta
* @return The frame, or {@code null}.
* @throws IOException If a received opcode or packet type is illegal.
*/
private Object decodeOpcode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws IOException {
if (buffer.readable()) {
private void decodeOpcode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws IOException {
if (buffer.isReadable()) {
int encryptedOpcode = buffer.readUnsignedByte();
opcode = encryptedOpcode - random.nextInt() & 0xFF;
@@ -117,7 +121,7 @@ public final class GamePacketDecoder extends StatefulFrameDecoder<GameDecoderSta
case FIXED:
length = metaData.getLength();
if (length == 0) {
return decodeZeroLengthPacket(ctx, channel, buffer);
decodeZeroLengthPacket(ctx, buffer, out);
} else {
setState(GameDecoderState.GAME_PAYLOAD);
}
@@ -129,7 +133,6 @@ public final class GamePacketDecoder extends StatefulFrameDecoder<GameDecoderSta
throw new IOException("Illegal packet type: " + type);
}
}
return null;
}
/**
@@ -141,17 +144,16 @@ public final class GamePacketDecoder extends StatefulFrameDecoder<GameDecoderSta
* @return The frame, or {@code null}.
* @throws Exception If an error occurs.
*/
private Object decodePayload(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) {
private void decodePayload(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) {
if (buffer.readableBytes() >= length) {
ChannelBuffer payload = buffer.readBytes(length);
ByteBuf payload = buffer.readBytes(length);
setState(GameDecoderState.GAME_OPCODE);
return new GamePacket(opcode, type, payload);
out.add(new GamePacket(opcode, type, payload));
}
return null;
}
/**
* Decodes a zero length packet. This hackery is required as Netty will throw an Exception If we return a frame but
* Decodes a zero length packet. This hackery is required as Netty will throw an exception if we return a frame but
* have read nothing!
*
* @param ctx The channel handler context.
@@ -160,10 +162,10 @@ public final class GamePacketDecoder extends StatefulFrameDecoder<GameDecoderSta
* @return The frame, or {@code null}.
* @throws Exception If an error occurs.
*/
private Object decodeZeroLengthPacket(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) {
ChannelBuffer payload = ChannelBuffers.buffer(0);
private void decodeZeroLengthPacket(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) {
ByteBuf payload = Unpooled.EMPTY_BUFFER;
setState(GameDecoderState.GAME_OPCODE);
return new GamePacket(opcode, type, payload);
out.add(new GamePacket(opcode, type, payload));
}
}
@@ -1,20 +1,22 @@
package org.apollo.net.codec.game;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
import net.burtleburtle.bob.rand.IsaacRandom;
import org.apollo.net.meta.PacketType;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
/**
* A {@link OneToOneEncoder} which encodes in-game packets.
*
* @author Graham
*/
public final class GamePacketEncoder extends OneToOneEncoder {
public final class GamePacketEncoder extends MessageToMessageEncoder<GamePacket> {
/**
* The random number generator.
@@ -31,11 +33,7 @@ public final class GamePacketEncoder extends OneToOneEncoder {
}
@Override
protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
if (!(msg instanceof GamePacket)) {
return msg;
}
protected void encode(ChannelHandlerContext ctx, GamePacket msg, List<Object> out) throws Exception {
GamePacket packet = (GamePacket) msg;
PacketType type = packet.getType();
int headerLength = 1;
@@ -52,7 +50,7 @@ public final class GamePacketEncoder extends OneToOneEncoder {
}
}
ChannelBuffer buffer = ChannelBuffers.buffer(headerLength + payloadLength);
ByteBuf buffer = Unpooled.buffer(headerLength + payloadLength);
buffer.writeByte(packet.getOpcode() + random.nextInt() & 0xFF);
if (type == PacketType.VARIABLE_BYTE) {
buffer.writeByte(payloadLength);
@@ -61,7 +59,7 @@ public final class GamePacketEncoder extends OneToOneEncoder {
}
buffer.writeBytes(packet.getPayload());
return buffer;
out.add(buffer);
}
}
@@ -1,7 +1,8 @@
package org.apollo.net.codec.game;
import org.apollo.util.ChannelBufferUtil;
import org.jboss.netty.buffer.ChannelBuffer;
import io.netty.buffer.ByteBuf;
import org.apollo.util.ByteBufUtil;
/**
* A utility class for reading {@link GamePacket}s.
@@ -18,7 +19,7 @@ public final class GamePacketReader {
/**
* The buffer.
*/
private final ChannelBuffer buffer;
private final ByteBuf buffer;
/**
* The current mode.
@@ -324,7 +325,7 @@ public final class GamePacketReader {
*/
public String getString() {
checkByteAccess();
return ChannelBufferUtil.readString(buffer);
return ByteBufUtil.readString(buffer);
}
/**
@@ -1,14 +1,15 @@
package org.apollo.net.codec.handshake;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.List;
import org.apollo.net.codec.login.LoginDecoder;
import org.apollo.net.codec.login.LoginEncoder;
import org.apollo.net.codec.update.UpdateDecoder;
import org.apollo.net.codec.update.UpdateEncoder;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
/**
* A {@link FrameDecoder} which decodes the handshake and makes changes to the pipeline as appropriate for the selected
@@ -16,46 +17,37 @@ import org.jboss.netty.handler.codec.frame.FrameDecoder;
*
* @author Graham
*/
public final class HandshakeDecoder extends FrameDecoder {
/**
* Creates the handshake frame decoder.
*/
public HandshakeDecoder() {
super(true);
}
public final class HandshakeDecoder extends ByteToMessageDecoder {
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) {
if (buffer.readable()) {
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) {
if (buffer.isReadable()) {
int id = buffer.readUnsignedByte();
switch (id) {
case HandshakeConstants.SERVICE_GAME:
ctx.getPipeline().addFirst("loginEncoder", new LoginEncoder());
ctx.getPipeline().addBefore("handler", "loginDecoder", new LoginDecoder());
ctx.pipeline().addFirst("loginEncoder", new LoginEncoder());
ctx.pipeline().addAfter("handshakeDecoder", "loginDecoder", new LoginDecoder());
break;
case HandshakeConstants.SERVICE_UPDATE:
ctx.getPipeline().addFirst("updateEncoder", new UpdateEncoder());
ctx.getPipeline().addBefore("handler", "updateDecoder", new UpdateDecoder());
ChannelBuffer buf = ChannelBuffers.buffer(8);
ctx.pipeline().addFirst("updateEncoder", new UpdateEncoder());
ctx.pipeline().addBefore("handler", "updateDecoder", new UpdateDecoder());
ByteBuf buf = ctx.alloc().buffer(8);
buf.writeLong(0);
channel.write(buf); // TODO should it be here?
ctx.channel().writeAndFlush(buf);
break;
default:
throw new IllegalArgumentException("Invalid service id");
}
ctx.getPipeline().remove(this);
ctx.pipeline().remove(this);
HandshakeMessage message = new HandshakeMessage(id);
if (buffer.readable()) {
return new Object[] { message, buffer.readBytes(buffer.readableBytes()) };
out.add(message);
if (buffer.isReadable()) {
out.add(buffer.readBytes(buffer.readableBytes()));
}
return message;
}
return null;
}
}
@@ -1,27 +1,26 @@
package org.apollo.net.codec.jaggrab;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List;
/**
* A {@link OneToOneDecoder} for the JAGGRAB protocol.
*
* @author Graham
*/
public final class JagGrabRequestDecoder extends OneToOneDecoder {
public final class JagGrabRequestDecoder extends MessageToMessageDecoder<String> {
@Override
protected Object decode(ChannelHandlerContext ctx, Channel c, Object msg) {
if (msg instanceof String) {
String str = (String) msg;
if (str.startsWith("JAGGRAB /")) {
String filePath = str.substring(8).trim();
return new JagGrabRequest(filePath);
}
protected void decode(ChannelHandlerContext ctx, String msg, List<Object> out) {
String request = (String) msg;
if (request.startsWith("JAGGRAB /")) {
String filePath = request.substring(8).trim();
out.add(new JagGrabRequest(filePath));
} else {
throw new IllegalArgumentException("corrupted request line");
}
return msg;
}
}
@@ -1,6 +1,6 @@
package org.apollo.net.codec.jaggrab;
import org.jboss.netty.buffer.ChannelBuffer;
import io.netty.buffer.ByteBuf;
/**
* Represents a single JAGGRAB response.
@@ -12,14 +12,14 @@ public final class JagGrabResponse {
/**
* The file data.
*/
private final ChannelBuffer fileData;
private final ByteBuf fileData;
/**
* Creates the response.
*
* @param fileData The file data.
*/
public JagGrabResponse(ChannelBuffer fileData) {
public JagGrabResponse(ByteBuf fileData) {
this.fileData = fileData;
}
@@ -28,7 +28,7 @@ public final class JagGrabResponse {
*
* @return The file data.
*/
public ChannelBuffer getFileData() {
public ByteBuf getFileData() {
return fileData;
}
@@ -1,23 +1,20 @@
package org.apollo.net.codec.jaggrab;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
/**
* A {@link OneToOneEncoder} for the JAGGRAB protocol.
*
* @author Graham
*/
public final class JagGrabResponseEncoder extends OneToOneEncoder {
public final class JagGrabResponseEncoder extends MessageToMessageEncoder<JagGrabResponse> {
@Override
protected Object encode(ChannelHandlerContext ctx, Channel c, Object msg) {
if (msg instanceof JagGrabResponse) {
JagGrabResponse resp = (JagGrabResponse) msg;
return resp.getFileData();
}
return msg;
protected void encode(ChannelHandlerContext ctx, JagGrabResponse response, List<Object> out) {
out.add(response.getFileData());
}
}
@@ -1,8 +1,13 @@
package org.apollo.net.codec.login;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import java.io.IOException;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.List;
import net.burtleburtle.bob.rand.IsaacRandom;
@@ -10,12 +15,8 @@ import org.apollo.fs.FileSystemConstants;
import org.apollo.net.NetworkConstants;
import org.apollo.security.IsaacRandomPair;
import org.apollo.security.PlayerCredentials;
import org.apollo.util.ChannelBufferUtil;
import org.apollo.util.ByteBufUtil;
import org.apollo.util.StatefulFrameDecoder;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
/**
* A {@link StatefulFrameDecoder} which decodes the login request frames.
@@ -57,15 +58,18 @@ public final class LoginDecoder extends StatefulFrameDecoder<LoginDecoderState>
}
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, LoginDecoderState state)
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out, LoginDecoderState state)
throws Exception {
switch (state) {
case LOGIN_HANDSHAKE:
return decodeHandshake(ctx, channel, buffer);
decodeHandshake(ctx, in, out);
break;
case LOGIN_HEADER:
return decodeHeader(ctx, channel, buffer);
decodeHeader(ctx, in, out);
break;
case LOGIN_PAYLOAD:
return decodePayload(ctx, channel, buffer);
decodePayload(ctx, in, out);
break;
default:
throw new IllegalStateException("Invalid login decoder state");
}
@@ -80,20 +84,19 @@ public final class LoginDecoder extends StatefulFrameDecoder<LoginDecoderState>
* @return The frame, or {@code null}.
* @throws Exception If an error occurs.
*/
private Object decodeHandshake(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) {
if (buffer.readable()) {
private void decodeHandshake(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) {
if (buffer.isReadable()) {
usernameHash = buffer.readUnsignedByte();
serverSeed = random.nextLong();
ChannelBuffer resp = ChannelBuffers.buffer(17);
ByteBuf resp = ctx.alloc().buffer(17);
resp.writeByte(LoginConstants.STATUS_EXCHANGE_DATA);
resp.writeLong(0);
resp.writeLong(serverSeed);
channel.write(resp);
ctx.channel().writeAndFlush(resp);
setState(LoginDecoderState.LOGIN_HEADER);
}
return null;
}
/**
@@ -105,7 +108,7 @@ public final class LoginDecoder extends StatefulFrameDecoder<LoginDecoderState>
* @return The frame, or {@code null}.
* @throws IOException If the login type sent by the client is invalid.
*/
private Object decodeHeader(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws IOException {
private void decodeHeader(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws IOException {
if (buffer.readableBytes() >= 2) {
int loginType = buffer.readUnsignedByte();
@@ -114,12 +117,10 @@ public final class LoginDecoder extends StatefulFrameDecoder<LoginDecoderState>
}
reconnecting = loginType == LoginConstants.TYPE_RECONNECTION;
loginLength = buffer.readUnsignedByte();
setState(LoginDecoderState.LOGIN_PAYLOAD);
}
return null;
}
/**
@@ -131,9 +132,9 @@ public final class LoginDecoder extends StatefulFrameDecoder<LoginDecoderState>
* @return The frame, or {@code null}.
* @throws Exception If an error occurs.
*/
private Object decodePayload(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
private void decodePayload(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
if (buffer.readableBytes() >= loginLength) {
ChannelBuffer payload = buffer.readBytes(loginLength);
ByteBuf payload = buffer.readBytes(loginLength);
if (payload.readUnsignedByte() != 0xFF) {
throw new Exception("Invalid magic id");
}
@@ -157,12 +158,12 @@ public final class LoginDecoder extends StatefulFrameDecoder<LoginDecoderState>
throw new Exception("Secure payload length mismatch");
}
ChannelBuffer securePayload = payload.readBytes(securePayloadLength);
ByteBuf securePayload = payload.readBytes(securePayloadLength);
BigInteger bigInteger = new BigInteger(securePayload.array());
bigInteger = bigInteger.modPow(NetworkConstants.RSA_EXPONENT, NetworkConstants.RSA_MODULUS);
securePayload = ChannelBuffers.wrappedBuffer(bigInteger.toByteArray());
securePayload = Unpooled.wrappedBuffer(bigInteger.toByteArray());
int secureId = securePayload.readUnsignedByte();
if (secureId != 10) {
@@ -177,8 +178,8 @@ public final class LoginDecoder extends StatefulFrameDecoder<LoginDecoderState>
int uid = securePayload.readInt();
String username = ChannelBufferUtil.readString(securePayload);
String password = ChannelBufferUtil.readString(securePayload);
String username = ByteBufUtil.readString(securePayload);
String password = ByteBufUtil.readString(securePayload);
if (username.length() > 12 || password.length() > 20) {
throw new Exception("Username or password too long.");
@@ -199,15 +200,14 @@ public final class LoginDecoder extends StatefulFrameDecoder<LoginDecoderState>
PlayerCredentials credentials = new PlayerCredentials(username, password, usernameHash, uid);
IsaacRandomPair randomPair = new IsaacRandomPair(encodingRandom, decodingRandom);
LoginRequest req = new LoginRequest(credentials, randomPair, reconnecting, lowMemory, releaseNumber,
LoginRequest request = new LoginRequest(credentials, randomPair, reconnecting, lowMemory, releaseNumber,
archiveCrcs);
if (buffer.readable()) {
return new Object[] { req, buffer.readBytes(buffer.readableBytes()) };
out.add(request);
if (buffer.isReadable()) {
out.add(buffer.readBytes(buffer.readableBytes()));
}
return req;
}
return null;
}
}
@@ -1,34 +1,31 @@
package org.apollo.net.codec.login;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
/**
* A class which encodes login response messages.
*
* @author Graham
*/
public final class LoginEncoder extends OneToOneEncoder {
public final class LoginEncoder extends MessageToMessageEncoder<LoginResponse> {
public LoginEncoder() {
super(LoginResponse.class);
}
@Override
protected Object encode(ChannelHandlerContext ctx, Channel channel, Object message) {
if (!(message instanceof LoginResponse)) {
return message;
}
LoginResponse response = (LoginResponse) message;
ChannelBuffer buffer = ChannelBuffers.buffer(3);
protected void encode(ChannelHandlerContext ctx, LoginResponse response, List<Object> out) {
ByteBuf buffer = ctx.alloc().buffer(3);
buffer.writeByte(response.getStatus());
if (response.getStatus() == LoginConstants.STATUS_OK) {
buffer.writeByte(response.getRights());
buffer.writeByte(response.isFlagged() ? 1 : 0);
}
return buffer;
out.add(buffer);
}
}
@@ -1,7 +1,8 @@
package org.apollo.net.codec.update;
import io.netty.buffer.ByteBuf;
import org.apollo.fs.FileDescriptor;
import org.jboss.netty.buffer.ChannelBuffer;
/**
* Represents a single 'on-demand' response.
@@ -13,7 +14,7 @@ public final class OnDemandResponse {
/**
* The chunk data.
*/
private final ChannelBuffer chunkData;
private final ByteBuf chunkData;
/**
* The chunk id.
@@ -38,7 +39,7 @@ public final class OnDemandResponse {
* @param chunkId The chunk id.
* @param chunkData The chunk data.
*/
public OnDemandResponse(FileDescriptor fileDescriptor, int fileSize, int chunkId, ChannelBuffer chunkData) {
public OnDemandResponse(FileDescriptor fileDescriptor, int fileSize, int chunkId, ByteBuf chunkData) {
this.fileDescriptor = fileDescriptor;
this.fileSize = fileSize;
this.chunkId = chunkId;
@@ -50,7 +51,7 @@ public final class OnDemandResponse {
*
* @return The chunk data.
*/
public ChannelBuffer getChunkData() {
public ByteBuf getChunkData() {
return chunkData;
}
@@ -1,32 +1,31 @@
package org.apollo.net.codec.update;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import java.util.List;
import org.apollo.fs.FileDescriptor;
import org.apollo.net.codec.update.OnDemandRequest.Priority;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
/**
* A {@link FrameDecoder} for the 'on-demand' protocol.
* A {@link ByteToMessageDecoder} for the 'on-demand' protocol.
*
* @author Graham
*/
public final class UpdateDecoder extends FrameDecoder {
public final class UpdateDecoder extends ByteToMessageDecoder {
@Override
protected Object decode(ChannelHandlerContext ctx, Channel c, ChannelBuffer buf) {
if (buf.readableBytes() >= 4) {
int type = buf.readUnsignedByte() + 1;
int file = buf.readUnsignedShort();
int priority = buf.readUnsignedByte();
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) {
if (buffer.readableBytes() >= 4) {
int type = buffer.readUnsignedByte() + 1;
int file = buffer.readUnsignedShort();
Priority priority = Priority.valueOf(buffer.readUnsignedByte());
FileDescriptor desc = new FileDescriptor(type, file);
Priority p = Priority.valueOf(priority);
return new OnDemandRequest(desc, p);
out.add(new OnDemandRequest(desc, priority));
}
return null;
}
}
@@ -1,39 +1,39 @@
package org.apollo.net.codec.update;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
import org.apollo.fs.FileDescriptor;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
/**
* A {@link OneToOneEncoder} for the 'on-demand' protocol.
* A {@link MessageToMessageEncoder} for the 'on-demand' protocol.
*
* @author Graham
*/
public final class UpdateEncoder extends OneToOneEncoder {
public final class UpdateEncoder extends MessageToMessageEncoder<OnDemandResponse> {
@Override
protected Object encode(ChannelHandlerContext ctx, Channel c, Object msg) {
protected void encode(ChannelHandlerContext ctx, OnDemandResponse msg, List<Object> out) {
if (msg instanceof OnDemandResponse) {
OnDemandResponse response = (OnDemandResponse) msg;
FileDescriptor descriptor = response.getFileDescriptor();
int fileSize = response.getFileSize();
int chunkId = response.getChunkId();
ChannelBuffer chunkData = response.getChunkData();
ByteBuf chunkData = response.getChunkData();
ChannelBuffer buffer = ChannelBuffers.buffer(6 + chunkData.readableBytes());
ByteBuf buffer = ctx.alloc().buffer(6 + chunkData.readableBytes());
buffer.writeByte(descriptor.getType() - 1);
buffer.writeShort(descriptor.getFile());
buffer.writeShort(fileSize);
buffer.writeByte(chunkId);
buffer.writeBytes(chunkData);
return buffer;
out.add(buffer);
}
return msg;
}
}
@@ -1,10 +1,11 @@
package org.apollo.net.release.r317;
import io.netty.buffer.Unpooled;
import org.apollo.game.event.impl.EnterAmountEvent;
import org.apollo.net.codec.game.GamePacket;
import org.apollo.net.meta.PacketType;
import org.apollo.net.release.EventEncoder;
import org.jboss.netty.buffer.ChannelBuffers;
/**
* An {@link EventEncoder} for the {@link EnterAmountEvent}.
@@ -15,7 +16,7 @@ public final class EnterAmountEventEncoder extends EventEncoder<EnterAmountEvent
@Override
public GamePacket encode(EnterAmountEvent event) {
return new GamePacket(27, PacketType.FIXED, ChannelBuffers.EMPTY_BUFFER);
return new GamePacket(27, PacketType.FIXED, Unpooled.EMPTY_BUFFER);
}
}
@@ -2,7 +2,7 @@ package org.apollo.net.release.r317;
import org.apollo.game.event.impl.PlayerDesignEvent;
import org.apollo.game.model.Appearance;
import org.apollo.game.model.Gender;
import org.apollo.game.model.settings.Gender;
import org.apollo.net.codec.game.DataType;
import org.apollo.net.codec.game.GamePacket;
import org.apollo.net.codec.game.GamePacketReader;
@@ -5,12 +5,12 @@ import org.apollo.game.model.Animation;
import org.apollo.game.model.Appearance;
import org.apollo.game.model.Direction;
import org.apollo.game.model.EquipmentConstants;
import org.apollo.game.model.Gender;
import org.apollo.game.model.Graphic;
import org.apollo.game.model.Inventory;
import org.apollo.game.model.Item;
import org.apollo.game.model.Position;
import org.apollo.game.model.def.EquipmentDefinition;
import org.apollo.game.model.settings.Gender;
import org.apollo.game.sync.block.AnimationBlock;
import org.apollo.game.sync.block.AppearanceBlock;
import org.apollo.game.sync.block.ChatBlock;
@@ -1,10 +1,11 @@
package org.apollo.net.release.r377;
import io.netty.buffer.Unpooled;
import org.apollo.game.event.impl.EnterAmountEvent;
import org.apollo.net.codec.game.GamePacket;
import org.apollo.net.meta.PacketType;
import org.apollo.net.release.EventEncoder;
import org.jboss.netty.buffer.ChannelBuffers;
/**
* An {@link EventEncoder} for the {@link EnterAmountEvent}.
@@ -15,7 +16,7 @@ public final class EnterAmountEventEncoder extends EventEncoder<EnterAmountEvent
@Override
public GamePacket encode(EnterAmountEvent event) {
return new GamePacket(58, PacketType.FIXED, ChannelBuffers.EMPTY_BUFFER);
return new GamePacket(58, PacketType.FIXED, Unpooled.EMPTY_BUFFER);
}
}
@@ -2,7 +2,7 @@ package org.apollo.net.release.r377;
import org.apollo.game.event.impl.PlayerDesignEvent;
import org.apollo.game.model.Appearance;
import org.apollo.game.model.Gender;
import org.apollo.game.model.settings.Gender;
import org.apollo.net.codec.game.DataType;
import org.apollo.net.codec.game.GamePacket;
import org.apollo.net.codec.game.GamePacketReader;
@@ -5,12 +5,12 @@ import org.apollo.game.model.Animation;
import org.apollo.game.model.Appearance;
import org.apollo.game.model.Direction;
import org.apollo.game.model.EquipmentConstants;
import org.apollo.game.model.Gender;
import org.apollo.game.model.Graphic;
import org.apollo.game.model.Inventory;
import org.apollo.game.model.Item;
import org.apollo.game.model.Position;
import org.apollo.game.model.def.EquipmentDefinition;
import org.apollo.game.model.settings.Gender;
import org.apollo.game.sync.block.AnimationBlock;
import org.apollo.game.sync.block.AppearanceBlock;
import org.apollo.game.sync.block.ChatBlock;
+7 -6
View File
@@ -1,5 +1,9 @@
package org.apollo.net.session;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.logging.Level;
@@ -13,9 +17,6 @@ import org.apollo.game.event.handler.chain.EventHandlerChain;
import org.apollo.game.event.handler.chain.EventHandlerChainGroup;
import org.apollo.game.event.impl.LogoutEvent;
import org.apollo.game.model.Player;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
/**
* A game session.
@@ -69,8 +70,8 @@ public final class GameSession extends Session {
*/
public void dispatchEvent(Event event) {
Channel channel = getChannel();
if (channel.isBound() && channel.isConnected() && channel.isOpen()) {
ChannelFuture future = channel.write(event);
if (channel.isActive() && channel.isOpen()) {
ChannelFuture future = channel.writeAndFlush(event);
if (event.getClass() == LogoutEvent.class) {
future.addListener(ChannelFutureListener.CLOSE);
}
@@ -106,7 +107,7 @@ public final class GameSession extends Session {
try {
chain.handle(player, event);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Error handling event.", ex);
logger.log(Level.SEVERE, "Error handling event: ", ex);
}
}
}
+18 -17
View File
@@ -1,5 +1,10 @@
package org.apollo.net.session;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import org.apollo.ServerContext;
import org.apollo.game.GameService;
import org.apollo.game.model.Player;
@@ -7,6 +12,7 @@ import org.apollo.game.model.World.RegistrationStatus;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.login.LoginService;
import org.apollo.net.ApolloHandler;
import org.apollo.net.NetworkConstants;
import org.apollo.net.codec.game.GameEventDecoder;
import org.apollo.net.codec.game.GameEventEncoder;
import org.apollo.net.codec.game.GamePacketDecoder;
@@ -16,10 +22,6 @@ import org.apollo.net.codec.login.LoginRequest;
import org.apollo.net.codec.login.LoginResponse;
import org.apollo.net.release.Release;
import org.apollo.security.IsaacRandomPair;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
/**
* A login session.
@@ -41,13 +43,12 @@ public final class LoginSession extends Session {
/**
* Creates a login session for the specified channel.
*
* @param channel The channel.
* @param channelContext The context of the {@link ApolloHandler}.
* @param ctx The context of the {@link ApolloHandler}.
* @param serverContext The server context.
*/
public LoginSession(Channel channel, ChannelHandlerContext channelContext, ServerContext serverContext) {
super(channel);
this.channelContext = channelContext;
public LoginSession(ChannelHandlerContext ctx, ServerContext serverContext) {
super(ctx.channel());
this.channelContext = ctx;
this.serverContext = serverContext;
}
@@ -107,7 +108,7 @@ public final class LoginSession extends Session {
}
}
ChannelFuture future = channel.write(new LoginResponse(status, rights, log));
ChannelFuture future = channel.writeAndFlush(new LoginResponse(status, rights, log));
destroy();
@@ -115,18 +116,18 @@ public final class LoginSession extends Session {
IsaacRandomPair randomPair = request.getRandomPair();
Release release = serverContext.getRelease();
channel.getPipeline().addFirst("eventEncoder", new GameEventEncoder(release));
channel.getPipeline().addBefore("eventEncoder", "gameEncoder",
channel.pipeline().addFirst("eventEncoder", new GameEventEncoder(release));
channel.pipeline().addBefore("eventEncoder", "gameEncoder",
new GamePacketEncoder(randomPair.getEncodingRandom()));
channel.getPipeline().addBefore("handler", "gameDecoder",
channel.pipeline().addBefore("handler", "gameDecoder",
new GamePacketDecoder(randomPair.getDecodingRandom(), serverContext.getRelease()));
channel.getPipeline().addAfter("gameDecoder", "eventDecoder", new GameEventDecoder(release));
channel.pipeline().addAfter("gameDecoder", "eventDecoder", new GameEventDecoder(release));
channel.getPipeline().remove("loginDecoder");
channel.getPipeline().remove("loginEncoder");
channel.pipeline().remove("loginDecoder");
channel.pipeline().remove("loginEncoder");
channelContext.setAttachment(player.getSession());
channelContext.attr(NetworkConstants.SESSION_KEY).set(player.getSession());
} else {
future.addListener(ChannelFutureListener.CLOSE);
}
+3 -3
View File
@@ -1,10 +1,10 @@
package org.apollo.net.session;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
/**
* A session which is used as the attachment of a {@link ChannelHandlerContext} in Netty.
* A session which is used as an attribute of a {@link ChannelHandlerContext} in Netty.
*
* @author Graham
*/
@@ -1,12 +1,13 @@
package org.apollo.net.session;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.HttpRequest;
import org.apollo.ServerContext;
import org.apollo.net.codec.jaggrab.JagGrabRequest;
import org.apollo.net.codec.update.OnDemandRequest;
import org.apollo.update.UpdateDispatcher;
import org.apollo.update.UpdateService;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.handler.codec.http.HttpRequest;
/**
* An update session.
+1 -1
View File
@@ -1,6 +1,6 @@
/**
* Contains {@link org.apollo.net.session.Session} classes which are the
* equivalent of Netty's {@link org.jboss.netty.channel.Channel}s but are
* equivalent of Netty's {@link io.netty.channel.Channel}s but are
* designed for Apollo to use itself - unlike Netty's which are purely
* designed for networking.
*/
+1 -1
View File
@@ -1,6 +1,6 @@
package org.apollo.update;
import org.jboss.netty.channel.Channel;
import io.netty.channel.Channel;
/**
* A specialised request which contains a channel as well as the request object itself.
+24 -24
View File
@@ -1,5 +1,14 @@
package org.apollo.update;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.handler.codec.http.DefaultHttpResponse;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -11,14 +20,6 @@ import org.apollo.update.resource.CombinedResourceProvider;
import org.apollo.update.resource.HypertextResourceProvider;
import org.apollo.update.resource.ResourceProvider;
import org.apollo.update.resource.VirtualResourceProvider;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
/**
* A worker which services HTTP requests.
@@ -60,8 +61,8 @@ public final class HttpRequestWorker extends RequestWorker<HttpRequest, Resource
* @param description The error description.
* @return The error page as a buffer.
*/
private ChannelBuffer createErrorPage(HttpResponseStatus status, String description) {
String title = status.getCode() + " " + status.getReasonPhrase();
private ByteBuf createErrorPage(HttpResponseStatus status, String description) {
String title = status.code() + " " + status.reasonPhrase();
StringBuilder builder = new StringBuilder();
@@ -75,7 +76,7 @@ public final class HttpRequestWorker extends RequestWorker<HttpRequest, Resource
builder.append(SERVER_IDENTIFIER);
builder.append(" Server</address></body></html>");
return ChannelBuffers.copiedBuffer(builder.toString(), Charset.defaultCharset());
return Unpooled.copiedBuffer(builder.toString(), Charset.defaultCharset());
}
/**
@@ -116,7 +117,7 @@ public final class HttpRequestWorker extends RequestWorker<HttpRequest, Resource
String path = request.getUri();
ByteBuffer buf = provider.get(path);
ChannelBuffer wrapped;
ByteBuf wrapped;
HttpResponseStatus status = HttpResponseStatus.OK;
String mime = getMimeType(request.getUri());
@@ -126,23 +127,22 @@ public final class HttpRequestWorker extends RequestWorker<HttpRequest, Resource
wrapped = createErrorPage(status, "The page you requested could not be found.");
mime = "text/html";
} else {
wrapped = ChannelBuffers.wrappedBuffer(buf);
wrapped = Unpooled.wrappedBuffer(buf);
}
HttpResponse response = new DefaultHttpResponse(request.getProtocolVersion(), status);
response.setHeader("Date", new Date());
response.setHeader("Server", SERVER_IDENTIFIER);
response.setHeader("Content-type", mime + ", charset=" + CHARACTER_SET.name());
response.setHeader("Cache-control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", new Date(0));
response.setHeader("Connection", "close");
response.setHeader("Content-length", wrapped.readableBytes());
response.setChunked(false);
response.setContent(wrapped);
response.headers().set("Date", new Date());
response.headers().set("Server", SERVER_IDENTIFIER);
response.headers().set("Content-type", mime + ", charset=" + CHARACTER_SET.name());
response.headers().set("Cache-control", "no-cache");
response.headers().set("Pragma", "no-cache");
response.headers().set("Expires", new Date(0));
response.headers().set("Connection", "close");
response.headers().set("Content-length", wrapped.readableBytes());
channel.write(response).addListener(ChannelFutureListener.CLOSE);
channel.write(response);
channel.writeAndFlush(wrapped).addListener(ChannelFutureListener.CLOSE);
}
}
@@ -1,5 +1,10 @@
package org.apollo.update;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -8,10 +13,6 @@ import org.apollo.net.codec.jaggrab.JagGrabRequest;
import org.apollo.net.codec.jaggrab.JagGrabResponse;
import org.apollo.update.resource.ResourceProvider;
import org.apollo.update.resource.VirtualResourceProvider;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFutureListener;
/**
* A worker which services JAGGRAB requests.
@@ -41,8 +42,8 @@ public final class JagGrabRequestWorker extends RequestWorker<JagGrabRequest, Re
if (buf == null) {
channel.close();
} else {
ChannelBuffer wrapped = ChannelBuffers.wrappedBuffer(buf);
channel.write(new JagGrabResponse(wrapped)).addListener(ChannelFutureListener.CLOSE);
ByteBuf wrapped = Unpooled.wrappedBuffer(buf);
channel.writeAndFlush(new JagGrabResponse(wrapped)).addListener(ChannelFutureListener.CLOSE);
}
}
@@ -1,5 +1,9 @@
package org.apollo.update;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -7,9 +11,6 @@ import org.apollo.fs.FileDescriptor;
import org.apollo.fs.IndexedFileSystem;
import org.apollo.net.codec.update.OnDemandRequest;
import org.apollo.net.codec.update.OnDemandResponse;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
/**
* A worker which services 'on-demand' requests.
@@ -53,10 +54,10 @@ public final class OnDemandRequestWorker extends RequestWorker<OnDemandRequest,
byte[] tmp = new byte[chunkSize];
buffer.get(tmp, 0, tmp.length);
ChannelBuffer chunkData = ChannelBuffers.wrappedBuffer(tmp, 0, chunkSize);
ByteBuf chunkData = Unpooled.wrappedBuffer(tmp, 0, chunkSize);
OnDemandResponse response = new OnDemandResponse(desc, length, chunk, chunkData);
channel.write(response);
channel.writeAndFlush(response);
}
}
+2 -2
View File
@@ -1,8 +1,8 @@
package org.apollo.update;
import java.io.IOException;
import io.netty.channel.Channel;
import org.jboss.netty.channel.Channel;
import java.io.IOException;
/**
* The base class for request workers.
+3 -2
View File
@@ -1,13 +1,14 @@
package org.apollo.update;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.HttpRequest;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import org.apollo.net.codec.jaggrab.JagGrabRequest;
import org.apollo.net.codec.update.OnDemandRequest;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.handler.codec.http.HttpRequest;
/**
* A class which dispatches requests to worker threads.
@@ -30,36 +30,36 @@ public final class HypertextResourceProvider extends ResourceProvider {
@Override
public boolean accept(String path) throws IOException {
File f = new File(base, path);
URI target = f.toURI().normalize();
File file = new File(base, path);
URI target = file.toURI().normalize();
if (target.toASCIIString().startsWith(base.toURI().normalize().toASCIIString())) {
if (f.isDirectory()) {
f = new File(f, "index.html");
if (file.isDirectory()) {
file = new File(file, "index.html");
}
return f.exists();
return file.exists();
}
return false;
}
@Override
public ByteBuffer get(String path) throws IOException {
File f = new File(base, path);
if (f.isDirectory()) {
f = new File(f, "index.html");
File file = new File(base, path);
if (file.isDirectory()) {
file = new File(file, "index.html");
}
if (!f.exists()) {
if (!file.exists()) {
return null;
}
RandomAccessFile raf = new RandomAccessFile(f, "r");
ByteBuffer buf;
RandomAccessFile raf = new RandomAccessFile(file, "r");
ByteBuffer buffer;
try {
buf = raf.getChannel().map(MapMode.READ_ONLY, 0, raf.length());
buffer = raf.getChannel().map(MapMode.READ_ONLY, 0, raf.length());
} finally {
raf.close();
}
return buf;
return buffer;
}
}
@@ -1,15 +1,15 @@
package org.apollo.util;
import io.netty.buffer.ByteBuf;
import org.apollo.net.NetworkConstants;
import org.jboss.netty.buffer.ChannelBuffer;
/**
* A utility class which provides extra {@link ChannelBuffer}-related methods which deal with data types used in the
* protocol.
* A utility class which provides extra {@link ByteBuf}-related methods which deal with data types used in the protocol.
*
* @author Graham
*/
public final class ChannelBufferUtil {
public final class ByteBufUtil {
/**
* Reads a string from the specified buffer.
@@ -17,10 +17,10 @@ public final class ChannelBufferUtil {
* @param buffer The buffer.
* @return The string.
*/
public static String readString(ChannelBuffer buffer) {
public static String readString(ByteBuf buffer) {
StringBuilder builder = new StringBuilder();
int character;
while (buffer.readable() && (character = buffer.readUnsignedByte()) != NetworkConstants.STRING_TERMINATOR) {
while (buffer.isReadable() && (character = buffer.readUnsignedByte()) != NetworkConstants.STRING_TERMINATOR) {
builder.append((char) character);
}
return builder.toString();
@@ -29,7 +29,7 @@ public final class ChannelBufferUtil {
/**
* Default private constructor to prevent instantiation by other classes.
*/
private ChannelBufferUtil() {
private ByteBufUtil() {
}
+17 -20
View File
@@ -1,11 +1,12 @@
package org.apollo.util;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
import org.jboss.netty.handler.codec.replay.ReplayingDecoder;
import org.jboss.netty.handler.codec.replay.VoidEnum;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.ReplayingDecoder;
import java.util.List;
/**
* A stateful implementation of a {@link FrameDecoder} which may be extended and used by other classes. The current
@@ -14,8 +15,8 @@ import org.jboss.netty.handler.codec.replay.VoidEnum;
* The state may be changed by calling the {@link StatefulFrameDecoder#setState(Enum)} method.
*
* The current state is supplied as a parameter in the
* {@link StatefulFrameDecoder#decode(ChannelHandlerContext, Channel, ChannelBuffer, Enum)} and
* {@link StatefulFrameDecoder#decodeLast(ChannelHandlerContext, Channel, ChannelBuffer, Enum)} methods.
* {@link StatefulFrameDecoder#decode(ChannelHandlerContext, Channel, ByteBuf, Enum)} and
* {@link StatefulFrameDecoder#decodeLast(ChannelHandlerContext, Channel, ByteBuf, Enum)} methods.
*
* This class is not thread safe: it is recommended that the state is only set in the decode methods overriden.
*
@@ -25,7 +26,7 @@ import org.jboss.netty.handler.codec.replay.VoidEnum;
* @author Graham
* @param <T> The state enumeration.
*/
public abstract class StatefulFrameDecoder<T extends Enum<T>> extends FrameDecoder {
public abstract class StatefulFrameDecoder<T extends Enum<T>> extends ByteToMessageDecoder {
/**
* The current state.
@@ -50,13 +51,12 @@ public abstract class StatefulFrameDecoder<T extends Enum<T>> extends FrameDecod
* @throws NullPointerException If the state is {@code null}.
*/
public StatefulFrameDecoder(T state, boolean unwrap) {
super(unwrap);
setState(state);
}
@Override
protected final Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
return decode(ctx, channel, buffer, state);
protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
decode(ctx, in, out, state);
}
/**
@@ -66,14 +66,12 @@ public abstract class StatefulFrameDecoder<T extends Enum<T>> extends FrameDecod
* @param channel The channel.
* @param buffer The cumulative buffer, which may contain zero or more bytes.
* @param state The current state. The state may be changed by calling {@link #setState(Enum)}.
* @return The decoded frame, or {@code null} if not enough data was received.
*/
protected abstract Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, T state)
throws Exception;
protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out, T state) throws Exception;
@Override
protected final Object decodeLast(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) {
return decodeLast(ctx, channel, buffer, state);
protected final void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
decodeLast(ctx, in, out, state);
}
/**
@@ -84,10 +82,9 @@ public abstract class StatefulFrameDecoder<T extends Enum<T>> extends FrameDecod
* @param channel The channel.
* @param buffer The cumulative buffer, which may contain zero or more bytes.
* @param state The current state. The state may be changed by calling {@link #setState(Enum)}.
* @return The decoded frame, or {@code null} if not enough data was received.
*/
protected Object decodeLast(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, T state) {
return null;
protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, List<Object> out, T state) {
}
/**
@@ -41,7 +41,7 @@ public final class PluginContext {
* @param listener The listener.
*/
public void addCommandListener(String name, CommandListener listener) {
World.getWorld().getCommandDispatcher().register(name, listener); // TODO best way?
World.getWorld().getCommandDispatcher().register(name, listener);
}
/**
@@ -160,7 +160,6 @@ public final class PluginManager {
if (dependency == null) {
throw new DependencyException("Unresolved dependency: " + dependencyId + ".");
}
start(env, plugin, plugins, started);
}
@@ -1,66 +0,0 @@
package org.apollo.net.codec.game;
import static org.junit.Assert.*;
import net.burtleburtle.bob.rand.IsaacRandom;
import org.apollo.net.meta.PacketType;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.junit.Test;
/**
* A test for the {@link GamePacketEncoder} class.
* @author Graham
*/
public class TestGamePacketEncoder {
/**
* Tests the {@link GamePacketEncoder#encode(org.jboss.netty.channel.ChannelHandlerContext, org.jboss.netty.channel.Channel, Object)}
* method.
* @throws Exception If an error occurs.
*/
@Test
public void testEncode() throws Exception {
// generates 243, 141, 34, -223, 121...
IsaacRandom random = new IsaacRandom(new int[] { 0, 0, 0, 0 });
GamePacketEncoder encoder = new GamePacketEncoder(random);
ChannelBuffer payload = ChannelBuffers.wrappedBuffer("Hello".getBytes());
GamePacket packet = new GamePacket(10, PacketType.FIXED, payload.copy());
ChannelBuffer buf = (ChannelBuffer) encoder.encode(null, null, packet);
assertEquals(6, buf.readableBytes());
assertEquals(253, buf.readUnsignedByte());
assertEquals('H', buf.readUnsignedByte());
assertEquals('e', buf.readUnsignedByte());
assertEquals('l', buf.readUnsignedByte());
assertEquals('l', buf.readUnsignedByte());
assertEquals('o', buf.readUnsignedByte());
packet = new GamePacket(9, PacketType.VARIABLE_BYTE, payload.copy());
buf = (ChannelBuffer) encoder.encode(null, null, packet);
assertEquals(7, buf.readableBytes());
assertEquals(150, buf.readUnsignedByte());
assertEquals(5, buf.readUnsignedByte());
assertEquals('H', buf.readUnsignedByte());
assertEquals('e', buf.readUnsignedByte());
assertEquals('l', buf.readUnsignedByte());
assertEquals('l', buf.readUnsignedByte());
assertEquals('o', buf.readUnsignedByte());
packet = new GamePacket(0, PacketType.VARIABLE_SHORT, payload.copy());
buf = (ChannelBuffer) encoder.encode(null, null, packet);
assertEquals(8, buf.readableBytes());
assertEquals(34, buf.readUnsignedByte());
assertEquals(5, buf.readUnsignedShort());
assertEquals('H', buf.readUnsignedByte());
assertEquals('e', buf.readUnsignedByte());
assertEquals('l', buf.readUnsignedByte());
assertEquals('l', buf.readUnsignedByte());
assertEquals('o', buf.readUnsignedByte());
}
}
@@ -1,49 +0,0 @@
package org.apollo.util;
import static org.junit.Assert.*;
import java.nio.ByteBuffer;
import org.apollo.net.NetworkConstants;
import org.junit.Test;
/**
* A test for the {@link ByteBufferUtil} class.
* @author Graham
*/
public class TestByteBufferUtil {
/**
* Tests the {@link ByteBufferUtil#readUnsignedTriByte(ByteBuffer)} method.
*/
@Test
public void testReadUnsignedTriByte() {
ByteBuffer buf = ByteBuffer.allocate(3);
buf.put((byte) 123);
buf.put((byte) 45);
buf.put((byte) 67);
buf.flip();
assertEquals(8072515, ByteBufferUtil.readUnsignedTriByte(buf));
}
/**
* Tests the {@link ByteBufferUtil#readString(ByteBuffer)} method.
*/
@Test
public void testReadString() {
ByteBuffer buf = ByteBuffer.allocate(8);
buf.put((byte) 'h');
buf.put((byte) 'e');
buf.put((byte) 'l');
buf.put((byte) 'l');
buf.put((byte) 'o');
buf.put((byte) NetworkConstants.STRING_TERMINATOR);
buf.put((byte) 66);
buf.put((byte) 6);
buf.flip();
assertEquals("hello", ByteBufferUtil.readString(buf));
}
}
@@ -1,44 +0,0 @@
package org.apollo.util;
import static org.junit.Assert.*;
import org.apollo.util.ChannelBufferUtil;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.junit.Test;
/**
* A test for the {@link ChannelBufferUtil} class.
* @author Graham
*/
public final class TestChannelBufferUtil {
/**
* Test the {@link ChannelBufferUtil#readString(ChannelBuffer)}
* method.
*/
@Test
public void testReadString() {
ChannelBuffer buf = ChannelBuffers.buffer(6);
buf.writeBytes(new byte[] { 'H', 'e', 'l', 'l', 'o', 10 });
String str = ChannelBufferUtil.readString(buf);
assertEquals("Hello", str);
buf = ChannelBuffers.buffer(5);
buf.writeBytes(new byte[] { 'W', 'o', 'r', 'l', 'd' });
str = ChannelBufferUtil.readString(buf);
assertEquals("World", str);
buf = ChannelBuffers.buffer(3);
buf.writeByte('!');
buf.writeByte(10);
buf.writeByte('.');
str = ChannelBufferUtil.readString(buf);
assertEquals("!", str);
str = ChannelBufferUtil.readString(buf);
assertEquals(".", str);
}
}
@@ -1,43 +0,0 @@
package org.apollo.util;
import static org.junit.Assert.*;
import java.io.IOException;
import org.junit.Test;
/**
* A test for the {@link CompressionUtil} class.
* @author Graham
*/
public class TestCompressionUtil {
/**
* Tests the {@link CompressionUtil#gzip(byte[])} and
* {@link CompressionUtil#ungzip(byte[], byte[])} methods.
* @throws IOException If an I/O error occurs.
*/
@Test
public void testGzip() throws IOException {
String str = "Hello, World!";
byte[] data = str.getBytes();
byte[] compressed = CompressionUtil.gzip(data);
CompressionUtil.ungzip(compressed, data);
assertEquals(str, new String(data));
}
/**
* Tests the {@link CompressionUtil#bzip2(byte[])} and
* {@link CompressionUtil#unbzip2(byte[], byte[])} methods.
* @throws IOException If an I/O error occurs.
*/
@Test
public void testBzip2() throws IOException {
String str = "Hello, World!";
byte[] data = str.getBytes();
byte[] compressed = CompressionUtil.bzip2(data);
CompressionUtil.unbzip2(compressed, data);
assertEquals(str, new String(data));
}
}
@@ -1,24 +0,0 @@
package org.apollo.util;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* A test for the {@link LanguageUtil} class.
* @author Graham
*/
public class TestLanguageUtil {
/**
* Tests the {@link LanguageUtil#getIndefiniteArticle(String)} method.
*/
@Test
public void testIndefiniteArticle() {
assertEquals("an", LanguageUtil.getIndefiniteArticle("apple"));
assertEquals("an", LanguageUtil.getIndefiniteArticle("urn"));
assertEquals("a", LanguageUtil.getIndefiniteArticle("nose"));
assertEquals("a", LanguageUtil.getIndefiniteArticle("foot"));
}
}
-48
View File
@@ -1,48 +0,0 @@
package org.apollo.util;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* A test for the {@link TextUtil} class.
* @author Graham
*/
public class TestTextUtil {
/**
* Tests the {@link TextUtil#compress(String, byte[])} and
* {@link TextUtil#uncompress(byte[], int)} methods.
*/
@Test
public void testCompression() {
String str = "hello, world!";
byte[] compressed = new byte[128];
int len = TextUtil.compress(str, compressed);
String uncompressed = TextUtil.uncompress(compressed, len);
assertEquals(str, uncompressed);
}
/**
* Tests the {@link TextUtil#filterInvalidCharacters(String)} method.
*/
@Test
public void testFilter() {
String str = "this contains <<< invalid characters";
String filtered = "this contains invalid characters";
assertEquals(filtered, TextUtil.filterInvalidCharacters(str));
}
/**
* Tets the {@link TextUtil#capitalize(String)} method.
*/
@Test
public void testCapitalize() {
String str = "tHiS is CRAP capitAliZation. do You AGreE? YES!";
String capitalized = "This is crap capitalization. Do you agree? Yes!";
assertEquals(capitalized, TextUtil.capitalize(str));
}
}
@@ -1,99 +0,0 @@
package org.apollo.util.xml;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.Set;
import org.junit.Test;
import org.xml.sax.SAXException;
/**
* A test for the {@link XmlParser} class.
* @author Graham
*/
public final class TestXmlParser {
/**
* A test for the {@link XmlParser#parse(java.io.InputStream)} method.
* @throws SAXException If a SAX error occurs.
* @throws IOException If an I/O error occurs.
*/
@Test
public void testParseInputStream() throws SAXException, IOException {
XmlParser parser = new XmlParser();
InputStream is = new ByteArrayInputStream("<root a='1' b='2' c='3'><z><y><x></x></y></z></root>".getBytes());
XmlNode root = parser.parse(is);
assertEquals(root.getName(), "root");
assertEquals(root.getAttributeCount(), 3);
assertEquals(root.getChildCount(), 1);
assertFalse(root.hasValue());
Set<String> attributeNames = root.getAttributeNames();
assertTrue(attributeNames.contains("a"));
assertTrue(attributeNames.contains("b"));
assertTrue(attributeNames.contains("c"));
assertFalse(attributeNames.contains("z"));
assertFalse(attributeNames.contains("y"));
assertFalse(attributeNames.contains("x"));
assertEquals("1", root.getAttribute("a"));
assertEquals("2", root.getAttribute("b"));
assertEquals("3", root.getAttribute("c"));
assertNull(root.getAttribute("z"));
assertNull(root.getAttribute("y"));
assertNull(root.getAttribute("x"));
XmlNode[] firstChild = root.getChildren().toArray(new XmlNode[1]);
assertEquals(1, firstChild.length);
assertEquals("z", firstChild[0].getName());
XmlNode[] secondChild = firstChild[0].getChildren().toArray(new XmlNode[1]);
assertEquals(1, secondChild.length);
assertEquals("y", secondChild[0].getName());
XmlNode[] thirdChild = secondChild[0].getChildren().toArray(new XmlNode[1]);
assertEquals(1, thirdChild.length);
assertEquals("x", thirdChild[0].getName());
assertEquals(0, thirdChild[0].getChildCount());
}
/**
* A test for the {@link XmlParser#parse(java.io.Reader)} method.
* @throws SAXException If a SAX error occurs.
* @throws IOException If an I/O error occurs.
*/
@Test
public void testParseReader() throws SAXException, IOException {
XmlParser parser = new XmlParser();
Reader reader = new StringReader("<alphabet><a>1</a><b>2</b><c>3</c></alphabet>");
XmlNode root = parser.parse(reader);
assertEquals(root.getName(), "alphabet");
assertEquals(root.getAttributeCount(), 0);
assertEquals(root.getChildCount(), 3);
assertFalse(root.hasValue());
XmlNode[] children = root.getChildren().toArray(new XmlNode[3]);
assertEquals(children[0].getName(), "a");
assertEquals(children[1].getName(), "b");
assertEquals(children[2].getName(), "c");
assertEquals(children[0].getValue(), "1");
assertEquals(children[1].getValue(), "2");
assertEquals(children[2].getValue(), "3");
for (int i = 0; i < 3; i++) {
assertTrue(children[i].hasValue());
assertEquals(children[i].getAttributeCount(), 0);
}
}
}