mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 08:39:11 +00:00
Update to netty 4.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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,4 +1,5 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.Animation'
|
||||
java_import 'org.apollo.game.model.Graphic'
|
||||
|
||||
|
||||
@@ -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,4 +1,5 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.EquipmentConstants'
|
||||
|
||||
AIR_ELEMENTS = {}
|
||||
|
||||
@@ -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,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,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,4 +1,5 @@
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.model.Animation'
|
||||
|
||||
PICKAXES = {}
|
||||
|
||||
+29
-36
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
-1
@@ -1,4 +1,4 @@
|
||||
package org.apollo.game.model;
|
||||
package org.apollo.game.model.settings;
|
||||
|
||||
/**
|
||||
* An enumeration containing the two genders (male and female).
|
||||
+7
-7
@@ -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}.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
+16
-26
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,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,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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user