Class member sorting.

This commit is contained in:
Major-
2013-11-03 04:58:21 +00:00
parent e93e60e143
commit cf61a22146
111 changed files with 3789 additions and 3471 deletions
+61 -61
View File
@@ -43,7 +43,7 @@ public final class IsaacRandom {
/**
* A mask for pseudorandom lookup.
*/
private static int MASK = (SIZE - 1) << 2;
private static int MASK = SIZE - 1 << 2;
/**
* The count through the results in the results array.
@@ -98,66 +98,6 @@ public final class IsaacRandom {
init(true);
}
/**
* Generates 256 results.
*/
private void isaac() {
int i, j, x, y;
b += ++c;
for (i = 0, j = SIZE / 2; i < SIZE / 2;) {
x = mem[i];
a ^= a << 13;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[((y >> SIZEL) & MASK) >> 2] + x;
x = mem[i];
a ^= a >>> 6;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[((y >> SIZEL) & MASK) >> 2] + x;
x = mem[i];
a ^= a << 2;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[((y >> SIZEL) & MASK) >> 2] + x;
x = mem[i];
a ^= a >>> 16;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[((y >> SIZEL) & MASK) >> 2] + x;
}
for (j = 0; j < SIZE / 2;) {
x = mem[i];
a ^= a << 13;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[((y >> SIZEL) & MASK) >> 2] + x;
x = mem[i];
a ^= a >>> 6;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[((y >> SIZEL) & MASK) >> 2] + x;
x = mem[i];
a ^= a << 2;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[((y >> SIZEL) & MASK) >> 2] + x;
x = mem[i];
a ^= a >>> 16;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[((y >> SIZEL) & MASK) >> 2] + x;
}
}
/**
* Initialises this random number generator.
*
@@ -289,6 +229,66 @@ public final class IsaacRandom {
count = SIZE;
}
/**
* Generates 256 results.
*/
private void isaac() {
int i, j, x, y;
b += ++c;
for (i = 0, j = SIZE / 2; i < SIZE / 2;) {
x = mem[i];
a ^= a << 13;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[(y >> SIZEL & MASK) >> 2] + x;
x = mem[i];
a ^= a >>> 6;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[(y >> SIZEL & MASK) >> 2] + x;
x = mem[i];
a ^= a << 2;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[(y >> SIZEL & MASK) >> 2] + x;
x = mem[i];
a ^= a >>> 16;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[(y >> SIZEL & MASK) >> 2] + x;
}
for (j = 0; j < SIZE / 2;) {
x = mem[i];
a ^= a << 13;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[(y >> SIZEL & MASK) >> 2] + x;
x = mem[i];
a ^= a >>> 6;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[(y >> SIZEL & MASK) >> 2] + x;
x = mem[i];
a ^= a << 2;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[(y >> SIZEL & MASK) >> 2] + x;
x = mem[i];
a ^= a >>> 16;
a += mem[j++];
mem[i] = y = mem[(x & MASK) >> 2] + a + b;
rsl[i++] = b = mem[(y >> SIZEL & MASK) >> 2] + x;
}
}
/**
* Gets the next random value.
*
+26 -26
View File
@@ -13,8 +13,8 @@ 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.ServicePipelineFactory;
import org.apollo.net.NetworkConstants;
import org.apollo.net.ServicePipelineFactory;
import org.apollo.net.release.Release;
import org.apollo.net.release.r317.Release317;
import org.apollo.util.plugin.PluginContext;
@@ -106,6 +106,31 @@ public final class Server {
serviceManager = new ServiceManager();
}
/**
* Binds the server to the specified address.
*
* @param serviceAddress The service address to bind to.
* @param httpAddress The HTTP address to bind to.
* @param jagGrabAddress The JAGGRAB address to bind to.
*/
public void bind(SocketAddress serviceAddress, SocketAddress httpAddress, SocketAddress jagGrabAddress) {
logger.info("Binding service listener to address: " + serviceAddress + "...");
serviceBootstrap.bind(serviceAddress);
logger.info("Binding HTTP listener to address: " + httpAddress + "...");
try {
httpBootstrap.bind(httpAddress);
} catch (Throwable t) {
logger.log(Level.WARNING,
"Binding to HTTP failed: client will use JAGGRAB as a fallback (not recommended)!", t);
}
logger.info("Binding JAGGRAB listener to address: " + jagGrabAddress + "...");
jagGrabBootstrap.bind(jagGrabAddress);
logger.info("Ready for connections.");
}
/**
* Initialises the server.
*
@@ -139,31 +164,6 @@ public final class Server {
jagGrabBootstrap.setPipelineFactory(jagGrabPipelineFactory);
}
/**
* Binds the server to the specified address.
*
* @param serviceAddress The service address to bind to.
* @param httpAddress The HTTP address to bind to.
* @param jagGrabAddress The JAGGRAB address to bind to.
*/
public void bind(SocketAddress serviceAddress, SocketAddress httpAddress, SocketAddress jagGrabAddress) {
logger.info("Binding service listener to address: " + serviceAddress + "...");
serviceBootstrap.bind(serviceAddress);
logger.info("Binding HTTP listener to address: " + httpAddress + "...");
try {
httpBootstrap.bind(httpAddress);
} catch (Throwable t) {
logger.log(Level.WARNING,
"Binding to HTTP failed: client will use JAGGRAB as a fallback (not recommended)!", t);
}
logger.info("Binding JAGGRAB listener to address: " + jagGrabAddress + "...");
jagGrabBootstrap.bind(jagGrabAddress);
logger.info("Ready for connections.");
}
/**
* Starts the server.
*
+9 -9
View File
@@ -60,15 +60,6 @@ public final class ServerContext {
return release;
}
/**
* Gets the service manager.
*
* @return The service manager.
*/
public ServiceManager getServiceManager() {
return serviceManager;
}
/**
* Gets a service. This method is shorthand for {@code getServiceManager().getService(...)}.
*
@@ -80,4 +71,13 @@ public final class ServerContext {
return serviceManager.getService(clazz);
}
/**
* Gets the service manager.
*
* @return The service manager.
*/
public ServiceManager getServiceManager() {
return serviceManager;
}
}
+18 -18
View File
@@ -35,6 +35,18 @@ public final class ServiceManager {
init();
}
/**
* Gets a service.
*
* @param <S> The type of service.
* @param clazz The service class.
* @return The service.
*/
@SuppressWarnings("unchecked")
public <S extends Service> S getService(Class<S> clazz) {
return (S) services.get(clazz);
}
/**
* Initializes this service manager.
*
@@ -85,15 +97,14 @@ public final class ServiceManager {
}
/**
* Gets a service.
* Sets the context of all services.
*
* @param <S> The type of service.
* @param clazz The service class.
* @return The service.
* @param ctx The server context.
*/
@SuppressWarnings("unchecked")
public <S extends Service> S getService(Class<S> clazz) {
return (S) services.get(clazz);
public void setContext(ServerContext ctx) {
for (Service s : services.values()) {
s.setContext(ctx);
}
}
/**
@@ -107,15 +118,4 @@ public final class ServiceManager {
}
}
/**
* Sets the context of all services.
*
* @param ctx The server context.
*/
public void setContext(ServerContext ctx) {
for (Service s : services.values()) {
s.setContext(ctx);
}
}
}
+9 -9
View File
@@ -28,15 +28,6 @@ public final class FileDescriptor {
this.file = file;
}
/**
* Gets the file type.
*
* @return The file type.
*/
public int getType() {
return type;
}
/**
* Gets the file id.
*
@@ -46,4 +37,13 @@ public final class FileDescriptor {
return file;
}
/**
* Gets the file type.
*
* @return The file type.
*/
public int getType() {
return type;
}
}
+11 -11
View File
@@ -19,8 +19,8 @@ public final class Index {
throw new IllegalArgumentException("Incorrect buffer length.");
}
int size = ((buffer[0] & 0xFF) << 16) | ((buffer[1] & 0xFF) << 8) | (buffer[2] & 0xFF);
int block = ((buffer[3] & 0xFF) << 16) | ((buffer[4] & 0xFF) << 8) | (buffer[5] & 0xFF);
int size = (buffer[0] & 0xFF) << 16 | (buffer[1] & 0xFF) << 8 | buffer[2] & 0xFF;
int block = (buffer[3] & 0xFF) << 16 | (buffer[4] & 0xFF) << 8 | buffer[5] & 0xFF;
return new Index(size, block);
}
@@ -46,15 +46,6 @@ public final class Index {
this.block = block;
}
/**
* Gets the size of the file.
*
* @return The size of the file.
*/
public int getSize() {
return size;
}
/**
* Gets the first block of the file.
*
@@ -64,4 +55,13 @@ public final class Index {
return block;
}
/**
* Gets the size of the file.
*
* @return The size of the file.
*/
public int getSize() {
return size;
}
}
+84 -84
View File
@@ -48,13 +48,21 @@ public final class IndexedFileSystem implements Closeable {
detectLayout(base);
}
/**
* Checks if this {@link IndexedFileSystem} is read only.
*
* @return {@code true} if so, {@code false} if not.
*/
public boolean isReadOnly() {
return readOnly;
@Override
public void close() throws IOException {
if (data != null) {
synchronized (data) {
data.close();
}
}
for (RandomAccessFile index : indices) {
if (index != null) {
synchronized (index) {
index.close();
}
}
}
}
/**
@@ -87,52 +95,6 @@ public final class IndexedFileSystem implements Closeable {
}
}
/**
* Gets the index of a file.
*
* @param fd The {@link FileDescriptor} which points to the file.
* @return The {@link Index}.
* @throws IOException If an I/O error occurs.
*/
private Index getIndex(FileDescriptor fd) throws IOException {
int index = fd.getType();
if (index < 0 || index >= indices.length) {
throw new IndexOutOfBoundsException();
}
byte[] buffer = new byte[FileSystemConstants.INDEX_SIZE];
RandomAccessFile indexFile = indices[index];
synchronized (indexFile) {
long ptr = (long) fd.getFile() * (long) FileSystemConstants.INDEX_SIZE;
if (ptr >= 0 && indexFile.length() >= (ptr + FileSystemConstants.INDEX_SIZE)) {
indexFile.seek(ptr);
indexFile.readFully(buffer);
} else {
throw new FileNotFoundException();
}
}
return Index.decode(buffer);
}
/**
* Gets the number of files with the specified type.
*
* @param type The type.
* @return The number of files.
* @throws IOException If an I/O error occurs.
*/
private int getFileCount(int type) throws IOException {
if (type < 0 || type >= indices.length) {
throw new IndexOutOfBoundsException();
}
RandomAccessFile indexFile = indices[type];
synchronized (indexFile) {
return (int) (indexFile.length() / FileSystemConstants.INDEX_SIZE);
}
}
/**
* Gets the CRC table.
*
@@ -171,9 +133,9 @@ public final class IndexedFileSystem implements Closeable {
// hash the CRCs and place them in the buffer
ByteBuffer buf = ByteBuffer.allocate(crcs.length * 4 + 4);
for (int i = 0; i < crcs.length; i++) {
hash = (hash << 1) + crcs[i];
buf.putInt(crcs[i]);
for (int crc : crcs) {
hash = (hash << 1) + crc;
buf.putInt(crc);
}
// place the hash into the buffer
@@ -189,18 +151,6 @@ public final class IndexedFileSystem implements Closeable {
}
}
/**
* Gets a file.
*
* @param type The file type.
* @param file The file id.
* @return A {@link ByteBuffer} which contains the contents of the file.
* @throws IOException If an I/O error occurs.
*/
public ByteBuffer getFile(int type, int file) throws IOException {
return getFile(new FileDescriptor(type, file));
}
/**
* Gets a file.
*
@@ -234,9 +184,9 @@ public final class IndexedFileSystem implements Closeable {
ptr += FileSystemConstants.HEADER_SIZE;
// parse header
int nextFile = ((header[0] & 0xFF) << 8) | (header[1] & 0xFF);
int curChunk = ((header[2] & 0xFF) << 8) | (header[3] & 0xFF);
int nextBlock = ((header[4] & 0xFF) << 16) | ((header[5] & 0xFF) << 8) | (header[6] & 0xFF);
int nextFile = (header[0] & 0xFF) << 8 | header[1] & 0xFF;
int curChunk = (header[2] & 0xFF) << 8 | header[3] & 0xFF;
int nextBlock = (header[4] & 0xFF) << 16 | (header[5] & 0xFF) << 8 | header[6] & 0xFF;
int nextType = header[7] & 0xFF;
// check expected chunk id is correct
@@ -265,7 +215,7 @@ public final class IndexedFileSystem implements Closeable {
// if we still have more data to read, check the validity of the
// header
if (size > read) {
if (nextType != (fd.getType() + 1)) {
if (nextType != fd.getType() + 1) {
throw new IOException("File type mismatch.");
}
@@ -279,21 +229,71 @@ public final class IndexedFileSystem implements Closeable {
return buffer;
}
@Override
public void close() throws IOException {
if (data != null) {
synchronized (data) {
data.close();
}
/**
* Gets a file.
*
* @param type The file type.
* @param file The file id.
* @return A {@link ByteBuffer} which contains the contents of the file.
* @throws IOException If an I/O error occurs.
*/
public ByteBuffer getFile(int type, int file) throws IOException {
return getFile(new FileDescriptor(type, file));
}
/**
* Gets the number of files with the specified type.
*
* @param type The type.
* @return The number of files.
* @throws IOException If an I/O error occurs.
*/
private int getFileCount(int type) throws IOException {
if (type < 0 || type >= indices.length) {
throw new IndexOutOfBoundsException();
}
for (RandomAccessFile index : indices) {
if (index != null) {
synchronized (index) {
index.close();
}
}
RandomAccessFile indexFile = indices[type];
synchronized (indexFile) {
return (int) (indexFile.length() / FileSystemConstants.INDEX_SIZE);
}
}
/**
* Gets the index of a file.
*
* @param fd The {@link FileDescriptor} which points to the file.
* @return The {@link Index}.
* @throws IOException If an I/O error occurs.
*/
private Index getIndex(FileDescriptor fd) throws IOException {
int index = fd.getType();
if (index < 0 || index >= indices.length) {
throw new IndexOutOfBoundsException();
}
byte[] buffer = new byte[FileSystemConstants.INDEX_SIZE];
RandomAccessFile indexFile = indices[index];
synchronized (indexFile) {
long ptr = (long) fd.getFile() * (long) FileSystemConstants.INDEX_SIZE;
if (ptr >= 0 && indexFile.length() >= ptr + FileSystemConstants.INDEX_SIZE) {
indexFile.seek(ptr);
indexFile.readFully(buffer);
} else {
throw new FileNotFoundException();
}
}
return Index.decode(buffer);
}
/**
* Checks if this {@link IndexedFileSystem} is read only.
*
* @return {@code true} if so, {@code false} if not.
*/
public boolean isReadOnly() {
return readOnly;
}
}
+1 -1
View File
@@ -86,7 +86,7 @@ public final class Archive {
int hash = 0;
name = name.toUpperCase();
for (int i = 0; i < name.length(); i++) {
hash = (hash * 61 + name.charAt(i)) - 32;
hash = hash * 61 + name.charAt(i) - 32;
}
for (ArchiveEntry entry : entries) {
if (entry.getIdentifier() == hash) {
+9 -9
View File
@@ -30,15 +30,6 @@ public final class ArchiveEntry {
this.buffer = buffer.asReadOnlyBuffer();
}
/**
* Gets the identifier of this entry.
*
* @return The identifier of this entry.
*/
public int getIdentifier() {
return identifier;
}
/**
* Gets the buffer of this entry.
*
@@ -48,4 +39,13 @@ public final class ArchiveEntry {
return buffer.duplicate();
}
/**
* Gets the identifier of this entry.
*
* @return The identifier of this entry.
*/
public int getIdentifier() {
return identifier;
}
}
+20 -20
View File
@@ -64,6 +64,17 @@ public final class GameService extends Service {
init();
}
/**
* Finalizes the unregistration of a player.
*
* @param player The player.
*/
public void finalizePlayerUnregistration(Player player) {
synchronized (this) {
World.getWorld().unregister(player);
}
}
/**
* Gets the event handler chains.
*
@@ -108,15 +119,6 @@ public final class GameService extends Service {
}
}
/**
* Starts the game service.
*/
@Override
public void start() {
scheduledExecutor.scheduleAtFixedRate(new GamePulseHandler(this), GameConstants.PULSE_DELAY,
GameConstants.PULSE_DELAY, TimeUnit.MILLISECONDS);
}
/**
* Called every pulse.
*/
@@ -157,6 +159,15 @@ public final class GameService extends Service {
}
}
/**
* Starts the game service.
*/
@Override
public void start() {
scheduledExecutor.scheduleAtFixedRate(new GamePulseHandler(this), GameConstants.PULSE_DELAY,
GameConstants.PULSE_DELAY, TimeUnit.MILLISECONDS);
}
/**
* Unregisters a player. Returns immediately. The player is unregistered at the start of the next cycle.
*
@@ -166,15 +177,4 @@ public final class GameService extends Service {
oldPlayers.add(player);
}
/**
* Finalizes the unregistration of a player.
*
* @param player The player.
*/
public void finalizePlayerUnregistration(Player player) {
synchronized (this) {
World.getWorld().unregister(player);
}
}
}
+9 -9
View File
@@ -28,15 +28,6 @@ public final class Command {
this.arguments = arguments;
}
/**
* Gets the name of the command.
*
* @return The name of the command.
*/
public String getName() {
return name;
}
/**
* Gets the command's arguments.
*
@@ -46,4 +37,13 @@ public final class Command {
return arguments;
}
/**
* Gets the name of the command.
*
* @return The name of the command.
*/
public String getName() {
return name;
}
}
@@ -25,16 +25,6 @@ public final class CommandDispatcher {
listeners.put("credits", new CreditsCommandListener());
}
/**
* Registers a listener with the
*
* @param command The command's name.
* @param listener The listener.
*/
public void register(String command, CommandListener listener) {
listeners.put(command.toLowerCase(), listener);
}
/**
* Dispatches a command to the appropriate listener.
*
@@ -48,4 +38,14 @@ public final class CommandDispatcher {
}
}
/**
* Registers a listener with the
*
* @param command The command's name.
* @param listener The listener.
*/
public void register(String command, CommandListener listener) {
listeners.put(command.toLowerCase(), listener);
}
}
@@ -24,6 +24,13 @@ public abstract class PrivilegedCommandListener implements CommandListener {
this.level = level;
}
@Override
public final void execute(Player player, Command command) {
if (player.getPrivilegeLevel().toInteger() >= level.toInteger()) {
executePrivileged(player, command);
}
}
/**
* Executes a privileged command.
*
@@ -32,11 +39,4 @@ public abstract class PrivilegedCommandListener implements CommandListener {
*/
public abstract void executePrivileged(Player player, Command command);
@Override
public final void execute(Player player, Command command) {
if (player.getPrivilegeLevel().toInteger() >= level.toInteger()) {
executePrivileged(player, command);
}
}
}
@@ -39,6 +39,25 @@ public final class BankEventHandler extends EventHandler<ItemActionEvent> {
throw new IllegalArgumentException();
}
/**
* Handles a deposit action.
*
* @param ctx The event handler context.
* @param player The player.
* @param event The event.
*/
private void deposit(EventHandlerContext ctx, Player player, ItemActionEvent event) {
int amount = optionToAmount(event.getOption());
if (amount == -1) {
player.getInterfaceSet().openEnterAmountDialog(
new BankDepositEnterAmountListener(player, event.getSlot(), event.getId()));
} else {
if (!BankUtils.deposit(player, event.getSlot(), event.getId(), amount)) {
ctx.breakHandlerChain();
}
}
}
@Override
public void handle(EventHandlerContext ctx, Player player, ItemActionEvent event) {
if (!player.getInterfaceSet().contains(BankConstants.BANK_WINDOW_ID)) {
@@ -71,23 +90,4 @@ public final class BankEventHandler extends EventHandler<ItemActionEvent> {
}
}
/**
* Handles a deposit action.
*
* @param ctx The event handler context.
* @param player The player.
* @param event The event.
*/
private void deposit(EventHandlerContext ctx, Player player, ItemActionEvent event) {
int amount = optionToAmount(event.getOption());
if (amount == -1) {
player.getInterfaceSet().openEnterAmountDialog(
new BankDepositEnterAmountListener(player, event.getSlot(), event.getId()));
} else {
if (!BankUtils.deposit(player, event.getSlot(), event.getId(), amount)) {
ctx.breakHandlerChain();
}
}
}
}
@@ -46,24 +46,6 @@ public final class CharacterDesignVerificationHandler extends EventHandler<Chara
}
}
/**
* Checks if a {@link Gender#MALE} style combination is valid.
*
* @param appearance The appearance combination.
* @return {@code true} if so, {@code false} if not.
*/
private boolean validMaleStyle(Appearance appearance) {
int[] styles = appearance.getStyle();
int[] minStyles = new int[] { 0, 10, 18, 26, 33, 36, 42 };
int[] maxStyles = new int[] { 8, 17, 25, 31, 34, 40, 43 };
for (int i = 0; i < styles.length; i++) {
if (styles[i] < minStyles[i] || styles[i] > maxStyles[i]) {
return false;
}
}
return true;
}
/**
* Checks if a {@link Gender#FEMALE} style combination is valid.
*
@@ -82,4 +64,22 @@ public final class CharacterDesignVerificationHandler extends EventHandler<Chara
return true;
}
/**
* Checks if a {@link Gender#MALE} style combination is valid.
*
* @param appearance The appearance combination.
* @return {@code true} if so, {@code false} if not.
*/
private boolean validMaleStyle(Appearance appearance) {
int[] styles = appearance.getStyle();
int[] minStyles = new int[] { 0, 10, 18, 26, 33, 36, 42 };
int[] maxStyles = new int[] { 8, 17, 25, 31, 34, 40, 43 };
for (int i = 0; i < styles.length; i++) {
if (styles[i] < minStyles[i] || styles[i] > maxStyles[i]) {
return false;
}
}
return true;
}
}
@@ -66,7 +66,7 @@ public final class EquipEventHandler extends EventHandler<EquipEvent> {
Item shield = equipment.get(EquipmentConstants.SHIELD);
if (equippingDef.isTwoHanded()) {
int slotsRequired = weapon != null ? (shield != null ? 1 : 0) : 0;
int slotsRequired = weapon != null ? shield != null ? 1 : 0 : 0;
if (inventory.freeSlots() < slotsRequired) {
ctx.breakHandlerChain();
return;
@@ -5,9 +5,9 @@ import org.apollo.game.event.handler.EventHandlerContext;
import org.apollo.game.event.impl.ItemActionEvent;
import org.apollo.game.model.Inventory;
import org.apollo.game.model.Item;
import org.apollo.game.model.Player;
import org.apollo.game.model.def.ItemDefinition;
import org.apollo.game.model.inv.SynchronizationInventoryListener;
import org.apollo.game.model.Player;
/**
* An event handler which removes equipped items.
@@ -44,6 +44,15 @@ public final class ChatEvent extends Event {
this.effects = effects;
}
/**
* Gets the compressed message.
*
* @return The compressed message.
*/
public byte[] getCompressedMessage() {
return compressedMessage;
}
/**
* Gets the message.
*
@@ -71,13 +80,4 @@ public final class ChatEvent extends Event {
return effects;
}
/**
* Gets the compressed message.
*
* @return The compressed message.
*/
public byte[] getCompressedMessage() {
return compressedMessage;
}
}
@@ -37,15 +37,6 @@ public final class EquipEvent extends Event {
this.slot = slot;
}
/**
* Gets the interface id.
*
* @return The interface id.
*/
public int getInterfaceId() {
return interfaceId;
}
/**
* Gets the item id.
*
@@ -55,6 +46,15 @@ public final class EquipEvent extends Event {
return id;
}
/**
* Gets the interface id.
*
* @return The interface id.
*/
public int getInterfaceId() {
return interfaceId;
}
/**
* Gets the slot.
*
@@ -45,12 +45,12 @@ public abstract class ItemActionEvent extends Event {
}
/**
* Gets the option number.
* Gets the item id.
*
* @return The option number.
* @return The item id.
*/
public int getOption() {
return option;
public int getId() {
return id;
}
/**
@@ -63,12 +63,12 @@ public abstract class ItemActionEvent extends Event {
}
/**
* Gets the item id.
* Gets the option number.
*
* @return The item id.
* @return The option number.
*/
public int getId() {
return id;
public int getOption() {
return option;
}
/**
@@ -38,15 +38,6 @@ public abstract class ObjectActionEvent extends Event {
this.position = position;
}
/**
* Gets the option number.
*
* @return The option number.
*/
public int getOption() {
return option;
}
/**
* Gets the id of the object.
*
@@ -56,6 +47,15 @@ public abstract class ObjectActionEvent extends Event {
return id;
}
/**
* Gets the option number.
*
* @return The option number.
*/
public int getOption() {
return option;
}
/**
* Gets the position of the object.
*
@@ -72,6 +72,15 @@ public final class PlayerSynchronizationEvent extends Event {
return lastKnownRegion;
}
/**
* Gets the number of local players.
*
* @return The number of local players.
*/
public int getLocalPlayers() {
return localPlayers;
}
/**
* Gets the player's position.
*
@@ -81,15 +90,6 @@ public final class PlayerSynchronizationEvent extends Event {
return position;
}
/**
* Checks if the region has changed.
*
* @return {@code true} if so, {@code false} if not.
*/
public boolean hasRegionChanged() {
return regionChanged;
}
/**
* Gets the current player's segment.
*
@@ -99,15 +99,6 @@ public final class PlayerSynchronizationEvent extends Event {
return segment;
}
/**
* Gets the number of local players.
*
* @return The number of local players.
*/
public int getLocalPlayers() {
return localPlayers;
}
/**
* Gets the synchronization segments.
*
@@ -117,4 +108,13 @@ public final class PlayerSynchronizationEvent extends Event {
return segments;
}
/**
* Checks if the region has changed.
*
* @return {@code true} if so, {@code false} if not.
*/
public boolean hasRegionChanged() {
return regionChanged;
}
}
@@ -53,6 +53,24 @@ public final class SwitchItemEvent extends Event {
return interfaceId;
}
/**
* Gets the new slot.
*
* @return The new slot.
*/
public int getNewSlot() {
return newSlot;
}
/**
* Gets the old slot.
*
* @return The old slot.
*/
public int getOldSlot() {
return oldSlot;
}
/**
* Checks if this event is in insertion mode.
*
@@ -71,22 +89,4 @@ public final class SwitchItemEvent extends Event {
return !inserting;
}
/**
* Gets the old slot.
*
* @return The old slot.
*/
public int getOldSlot() {
return oldSlot;
}
/**
* Gets the new slot.
*
* @return The new slot.
*/
public int getNewSlot() {
return newSlot;
}
}
@@ -30,15 +30,6 @@ public final class SwitchTabInterfaceEvent extends Event {
this.interfaceId = interfaceId;
}
/**
* Gets the tab id.
*
* @return The tab id.
*/
public int getTabId() {
return tab;
}
/**
* Gets the interface id.
*
@@ -48,4 +39,13 @@ public final class SwitchTabInterfaceEvent extends Event {
return interfaceId;
}
/**
* Gets the tab id.
*
* @return The tab id.
*/
public int getTabId() {
return tab;
}
}
+9 -9
View File
@@ -182,15 +182,6 @@ public final class Animation {
this.delay = delay;
}
/**
* Gets the animation's id.
*
* @return The animation's id.
*/
public int getId() {
return id;
}
/**
* Gets the animation's delay.
*
@@ -200,4 +191,13 @@ public final class Animation {
return delay;
}
/**
* Gets the animation's id.
*
* @return The animation's id.
*/
public int getId() {
return id;
}
}
+22 -22
View File
@@ -50,6 +50,15 @@ public final class Appearance {
this.colors = colors;
}
/**
* Gets the player's colors.
*
* @return The player's colors.
*/
public int[] getColors() {
return colors;
}
/**
* Gets the gender of the player.
*
@@ -59,24 +68,6 @@ public final class Appearance {
return gender;
}
/**
* Checks if the player is male.
*
* @return {@code true} if so, {@code false} if not.
*/
public boolean isMale() {
return gender == Gender.MALE;
}
/**
* Checks if the player is female.
*
* @return {@code true} if so, {@code false} if not.
*/
public boolean isFemale() {
return gender == Gender.FEMALE;
}
/**
* Gets the player's styles.
*
@@ -92,12 +83,21 @@ public final class Appearance {
}
/**
* Gets the player's colors.
* Checks if the player is female.
*
* @return The player's colors.
* @return {@code true} if so, {@code false} if not.
*/
public int[] getColors() {
return colors;
public boolean isFemale() {
return gender == Gender.FEMALE;
}
/**
* Checks if the player is male.
*
* @return {@code true} if so, {@code false} if not.
*/
public boolean isMale() {
return gender == Gender.MALE;
}
}
+5 -5
View File
@@ -318,8 +318,8 @@ public abstract class Character {
* @param second The second direction.
*/
public void setDirections(Direction first, Direction second) {
this.firstDirection = first;
this.secondDirection = second;
firstDirection = first;
secondDirection = second;
}
/**
@@ -399,10 +399,10 @@ public abstract class Character {
* @param position The position.
*/
public void teleport(Position position) {
this.teleporting = true;
teleporting = true;
this.position = position;
this.walkingQueue.clear();
this.stopAction(); // TODO do it on any movement is a must.. walking queue perhaps?
walkingQueue.clear();
stopAction(); // TODO do it on any movement is a must.. walking queue perhaps?
}
/**
+12 -12
View File
@@ -57,18 +57,6 @@ public enum Direction {
*/
public static final Direction[] EMPTY_DIRECTION_ARRAY = new Direction[0];
/**
* Checks if the direction represented by the two delta values can connect two points together in a single
* direction.
*
* @param deltaX The difference in X coordinates.
* @param deltaY The difference in X coordinates.
* @return {@code true} if so, {@code false} if not.
*/
public static boolean isConnectable(int deltaX, int deltaY) {
return Math.abs(deltaX) == Math.abs(deltaY) || deltaX == 0 || deltaY == 0;
}
/**
* Creates a direction from the differences between X and Y.
*
@@ -103,6 +91,18 @@ public enum Direction {
return Direction.NONE;
}
/**
* Checks if the direction represented by the two delta values can connect two points together in a single
* direction.
*
* @param deltaX The difference in X coordinates.
* @param deltaY The difference in X coordinates.
* @return {@code true} if so, {@code false} if not.
*/
public static boolean isConnectable(int deltaX, int deltaY) {
return Math.abs(deltaX) == Math.abs(deltaY) || deltaX == 0 || deltaY == 0;
}
/**
* The direction as an integer.
*/
+9 -9
View File
@@ -59,15 +59,6 @@ public final class Graphic {
this.height = height;
}
/**
* Gets the graphic's id.
*
* @return The graphic's id.
*/
public int getId() {
return id;
}
/**
* Gets the graphic's delay.
*
@@ -86,4 +77,13 @@ public final class Graphic {
return height;
}
/**
* Gets the graphic's id.
*
* @return The graphic's id.
*/
public int getId() {
return id;
}
}
+60 -60
View File
@@ -70,6 +70,41 @@ public final class InterfaceSet {
player.send(new CloseInterfaceEvent());
}
/**
* An internal method for closing the interface, notifying the listener if appropriate, but not sending any events.
*/
private void closeAndNotify() {
amountListener = null; // TODO should we notify??
interfaces.clear();
if (listener != null) {
listener.interfaceClosed();
listener = null;
}
}
/**
* Checks if this interface sets contains the specified interface.
*
* @param id The interface's id.
* @return {@code true} if so, {@code false} if not.
*/
public boolean contains(int id) {
return interfaces.containsValue(id);
}
/**
* Called when the client has entered the specified amount. Notifies the current listener.
*
* @param amount The amount.
*/
public void enteredAmount(int amount) {
if (amountListener != null) {
amountListener.amountEntered(amount);
amountListener = null;
}
}
/**
* Sent by the client when it has closed an interface.
*/
@@ -83,11 +118,35 @@ public final class InterfaceSet {
* @param listener The enter amount listener.
*/
public void openEnterAmountDialog(EnterAmountListener listener) {
this.amountListener = listener;
amountListener = listener;
player.send(new EnterAmountEvent());
}
/**
* Opens a window.
*
* @param windowId The window's id.
*/
public void openWindow(int windowId) {
openWindow(null, windowId);
}
/**
* Opens a window with the specified listener.
*
* @param listener The listener for this interface.
* @param windowId The window's id.
*/
public void openWindow(InterfaceListener listener, int windowId) {
closeAndNotify();
this.listener = listener;
interfaces.put(InterfaceType.WINDOW, windowId);
player.send(new OpenInterfaceEvent(windowId));
}
/**
* Opens a window and inventory sidebar.
*
@@ -115,63 +174,4 @@ public final class InterfaceSet {
player.send(new OpenInterfaceSidebarEvent(windowId, sidebarId));
}
/**
* Opens a window.
*
* @param windowId The window's id.
*/
public void openWindow(int windowId) {
openWindow(null, windowId);
}
/**
* Opens a window with the specified listener.
*
* @param listener The listener for this interface.
* @param windowId The window's id.
*/
public void openWindow(InterfaceListener listener, int windowId) {
closeAndNotify();
this.listener = listener;
interfaces.put(InterfaceType.WINDOW, windowId);
player.send(new OpenInterfaceEvent(windowId));
}
/**
* Checks if this interface sets contains the specified interface.
*
* @param id The interface's id.
* @return {@code true} if so, {@code false} if not.
*/
public boolean contains(int id) {
return interfaces.containsValue(id);
}
/**
* An internal method for closing the interface, notifying the listener if appropriate, but not sending any events.
*/
private void closeAndNotify() {
amountListener = null; // TODO should we notify??
interfaces.clear();
if (listener != null) {
listener.interfaceClosed();
listener = null;
}
}
/**
* Called when the client has entered the specified amount. Notifies the current listener.
*
* @param amount The amount.
*/
public void enteredAmount(int amount) {
if (amountListener != null) {
amountListener.amountEntered(amount);
amountListener = null;
}
}
}
+265 -265
View File
@@ -95,126 +95,8 @@ public final class Inventory implements Cloneable {
throw new NullPointerException("mode");
}
this.capacity = capacity;
this.items = new Item[capacity];
this.mode = mode;
}
/**
* Creates a copy of this inventory. Listeners are not copied, they must be added again yourself! This is so cloned
* copies don't send updates to their counterparts.
*/
@Override
public Inventory clone() {
Inventory copy = new Inventory(capacity, mode);
System.arraycopy(items, 0, copy.items, 0, capacity);
copy.size = size;
return copy;
}
/**
* Checks if this inventory contains an item with the specified id.
*
* @param id The item's id.
* @return {@code true} if so, {@code false} if not.
*/
public boolean contains(int id) {
for (int i = 0; i < capacity; i++) {
Item item = items[i];
if (item != null && item.getId() == id) {
return true;
}
}
return false;
}
/**
* Gets the number of free slots.
*
* @return The number of free slots.
*/
public int freeSlots() {
return capacity - size;
}
/**
* Clears the inventory.
*/
public void clear() {
items = new Item[capacity];
size = 0;
notifyItemsUpdated();
}
/**
* Gets the capacity of this inventory.
*
* @return The capacity.
*/
public int capacity() {
return capacity;
}
/**
* Gets the size of this inventory - the number of used slots.
*
* @return The size.
*/
public int size() {
return size;
}
/**
* Gets the item in the specified slot.
*
* @param slot The slot.
* @return The item, or {@code null} if the slot is empty.
* @throws IndexOutOfBoundsException If the slot is out of bounds.
*/
public Item get(int slot) {
checkBounds(slot);
return items[slot];
}
/**
* Sets the item that is in the specified slot.
*
* @param slot The slot.
* @param item The item, or {@code null} to remove the item that is in the slot.
* @return The item that was in the slot.
* @throws IndexOutOfBoundsException If the slot is out of bounds.
*/
public Item set(int slot, Item item) {
if (item == null) {
return reset(slot);
}
checkBounds(slot);
Item old = items[slot];
if (old == null) {
size++;
}
items[slot] = item;
notifyItemUpdated(slot);
return old;
}
/**
* Removes the item (if any) that is in the specified slot.
*
* @param slot
* @return The item that was in the slot.
* @throws IndexOutOfBoundsException If the slot is out of bounds.
*/
public Item reset(int slot) {
checkBounds(slot);
Item old = items[slot];
if (old != null) {
size--;
}
items[slot] = null;
notifyItemUpdated(slot);
return old;
this.mode = mode;
}
/**
@@ -312,6 +194,178 @@ public final class Inventory implements Cloneable {
return new Item(item.getId(), remaining);
}
/**
* Adds a listener.
*
* @param listener The listener to add.
*/
public void addListener(InventoryListener listener) {
listeners.add(listener);
}
/**
* Gets the capacity of this inventory.
*
* @return The capacity.
*/
public int capacity() {
return capacity;
}
/**
* Checks the bounds of the specified slot.
*
* @param slot The slot.
* @throws IndexOutOfBoundsException If the slot is out of bounds.
*/
private void checkBounds(int slot) {
if (slot < 0 || slot >= capacity) {
throw new IndexOutOfBoundsException("slot out of bounds");
}
}
/**
* Clears the inventory.
*/
public void clear() {
items = new Item[capacity];
size = 0;
notifyItemsUpdated();
}
/**
* Creates a copy of this inventory. Listeners are not copied, they must be added again yourself! This is so cloned
* copies don't send updates to their counterparts.
*/
@Override
public Inventory clone() {
Inventory copy = new Inventory(capacity, mode);
System.arraycopy(items, 0, copy.items, 0, capacity);
copy.size = size;
return copy;
}
/**
* Checks if this inventory contains an item with the specified id.
*
* @param id The item's id.
* @return {@code true} if so, {@code false} if not.
*/
public boolean contains(int id) {
for (int i = 0; i < capacity; i++) {
Item item = items[i];
if (item != null && item.getId() == id) {
return true;
}
}
return false;
}
/**
* Forces the capacity to exceeded event to be fired.
*/
public void forceCapacityExceeded() {
notifyCapacityExceeded();
}
/**
* Forces the refresh of this inventory.
*/
public void forceRefresh() {
notifyItemsUpdated();
}
/**
* Forces a refresh of a specific slot.
*
* @param slot The slot.
*/
public void forceRefresh(int slot) {
notifyItemUpdated(slot);
}
/**
* Gets the number of free slots.
*
* @return The number of free slots.
*/
public int freeSlots() {
return capacity - size;
}
/**
* Gets the item in the specified slot.
*
* @param slot The slot.
* @return The item, or {@code null} if the slot is empty.
* @throws IndexOutOfBoundsException If the slot is out of bounds.
*/
public Item get(int slot) {
checkBounds(slot);
return items[slot];
}
/**
* Gets a clone of the items array.
*
* @return A clone of the items array.
*/
public Item[] getItems() {
return items.clone();
}
/**
* Checks if the item specified by the definition should be stacked.
*
* @param def The definition.
* @return {@code true} if the item should be stacked, {@code false} otherwise.
*/
private boolean isStackable(ItemDefinition def) {
if (mode == StackMode.STACK_ALWAYS) {
return true;
} else if (mode == StackMode.STACK_STACKABLE_ITEMS) {
return def.isStackable();
} else { // will be STACK_NEVER
return false;
}
}
/**
* Notifies listeners that the capacity of this inventory has been exceeded.
*/
private void notifyCapacityExceeded() {
if (firingEvents) {
for (InventoryListener listener : listeners) {
listener.capacityExceeded(this);
}
}
}
/**
* Notifies listeners that all the items have been updated.
*/
private void notifyItemsUpdated() {
if (firingEvents) {
for (InventoryListener listener : listeners) {
listener.itemsUpdated(this);
}
}
}
/**
* Notifies listeners that the specified slot has been updated.
*
* @param slot The slot.
*/
private void notifyItemUpdated(int slot) {
if (firingEvents) {
Item item = items[slot];
for (InventoryListener listener : listeners) {
listener.itemUpdated(this, slot, item);
}
}
}
/**
* Removes one item with the specified id.
*
@@ -322,16 +376,6 @@ public final class Inventory implements Cloneable {
return remove(id, 1) == 1;
}
/**
* An alias for {@code remove(item.getId(), item.getAmount())}.
*
* @param item The item to remove.
* @return The amount that was removed.
*/
public int remove(Item item) {
return remove(item.getId(), item.getAmount());
}
/**
* Removes {@code amount} of the item with the specified {@code id}. If the item is stackable, it will remove it
* from the stack. If not, it'll remove {@code amount} items.
@@ -373,6 +417,74 @@ public final class Inventory implements Cloneable {
return removed;
}
/**
* An alias for {@code remove(item.getId(), item.getAmount())}.
*
* @param item The item to remove.
* @return The amount that was removed.
*/
public int remove(Item item) {
return remove(item.getId(), item.getAmount());
}
/**
* Removes all the listeners.
*/
public void removeAllListeners() {
listeners.clear();
}
/**
* Removes a listener.
*
* @param listener The listener to remove.
*/
public void removeListener(InventoryListener listener) {
listeners.remove(listener);
}
/**
* Removes the item (if any) that is in the specified slot.
*
* @param slot
* @return The item that was in the slot.
* @throws IndexOutOfBoundsException If the slot is out of bounds.
*/
public Item reset(int slot) {
checkBounds(slot);
Item old = items[slot];
if (old != null) {
size--;
}
items[slot] = null;
notifyItemUpdated(slot);
return old;
}
/**
* Sets the item that is in the specified slot.
*
* @param slot The slot.
* @param item The item, or {@code null} to remove the item that is in the slot.
* @return The item that was in the slot.
* @throws IndexOutOfBoundsException If the slot is out of bounds.
*/
public Item set(int slot, Item item) {
if (item == null) {
return reset(slot);
}
checkBounds(slot);
Item old = items[slot];
if (old == null) {
size++;
}
items[slot] = item;
notifyItemUpdated(slot);
return old;
}
/**
* Shifts all items to the top left of the container, leaving no gaps.
*/
@@ -390,14 +502,26 @@ public final class Inventory implements Cloneable {
}
/**
* Swaps the two items at the specified slots.
* Gets the size of this inventory - the number of used slots.
*
* @param oldSlot The old slot.
* @param newSlot The new slot.
* @throws IndexOutOufBoundsException If the slot is out of bounds.
* @return The size.
*/
public void swap(int oldSlot, int newSlot) {
swap(false, oldSlot, newSlot);
public int size() {
return size;
}
/**
* Starts the firing of events.
*/
public void startFiringEvents() {
firingEvents = true;
}
/**
* Stops the firing of events.
*/
public void stopFiringEvents() {
firingEvents = false;
}
/**
@@ -431,138 +555,14 @@ public final class Inventory implements Cloneable {
}
/**
* Adds a listener.
* Swaps the two items at the specified slots.
*
* @param listener The listener to add.
* @param oldSlot The old slot.
* @param newSlot The new slot.
* @throws IndexOutOufBoundsException If the slot is out of bounds.
*/
public void addListener(InventoryListener listener) {
listeners.add(listener);
}
/**
* Removes a listener.
*
* @param listener The listener to remove.
*/
public void removeListener(InventoryListener listener) {
listeners.remove(listener);
}
/**
* Removes all the listeners.
*/
public void removeAllListeners() {
listeners.clear();
}
/**
* Notifies listeners that the capacity of this inventory has been exceeded.
*/
private void notifyCapacityExceeded() {
if (firingEvents) {
for (InventoryListener listener : listeners) {
listener.capacityExceeded(this);
}
}
}
/**
* Notifies listeners that all the items have been updated.
*/
private void notifyItemsUpdated() {
if (firingEvents) {
for (InventoryListener listener : listeners) {
listener.itemsUpdated(this);
}
}
}
/**
* Notifies listeners that the specified slot has been updated.
*
* @param slot The slot.
*/
private void notifyItemUpdated(int slot) {
if (firingEvents) {
Item item = items[slot];
for (InventoryListener listener : listeners) {
listener.itemUpdated(this, slot, item);
}
}
}
/**
* Checks the bounds of the specified slot.
*
* @param slot The slot.
* @throws IndexOutOfBoundsException If the slot is out of bounds.
*/
private void checkBounds(int slot) {
if (slot < 0 || slot >= capacity) {
throw new IndexOutOfBoundsException("slot out of bounds");
}
}
/**
* Checks if the item specified by the definition should be stacked.
*
* @param def The definition.
* @return {@code true} if the item should be stacked, {@code false} otherwise.
*/
private boolean isStackable(ItemDefinition def) {
if (mode == StackMode.STACK_ALWAYS) {
return true;
} else if (mode == StackMode.STACK_STACKABLE_ITEMS) {
return def.isStackable();
} else { // will be STACK_NEVER
return false;
}
}
/**
* Gets a clone of the items array.
*
* @return A clone of the items array.
*/
public Item[] getItems() {
return items.clone();
}
/**
* Stops the firing of events.
*/
public void stopFiringEvents() {
firingEvents = false;
}
/**
* Starts the firing of events.
*/
public void startFiringEvents() {
firingEvents = true;
}
/**
* Forces the refresh of this inventory.
*/
public void forceRefresh() {
notifyItemsUpdated();
}
/**
* Forces a refresh of a specific slot.
*
* @param slot The slot.
*/
public void forceRefresh(int slot) {
notifyItemUpdated(slot);
}
/**
* Forces the capacity to exceeded event to be fired.
*/
public void forceCapacityExceeded() {
notifyCapacityExceeded();
public void swap(int oldSlot, int newSlot) {
swap(false, oldSlot, newSlot);
}
}
+9 -9
View File
@@ -43,15 +43,6 @@ public final class Item {
this.amount = amount;
}
/**
* Gets the id.
*
* @return The id.
*/
public int getId() {
return id;
}
/**
* Gets the amount.
*
@@ -70,6 +61,15 @@ public final class Item {
return ItemDefinition.lookup(id);
}
/**
* Gets the id.
*
* @return The id.
*/
public int getId() {
return id;
}
@Override
public String toString() {
return Item.class.getName() + " [id=" + id + ", amount=" + amount + "]";
+1
View File
@@ -41,6 +41,7 @@ public class Npc extends Character {
*
* @return The definition.
*/
@Override
public NpcDefinition getNpcDefinition() {
return definition;
}
+21 -21
View File
@@ -200,7 +200,7 @@ public final class Player extends Character {
* Sets the excessive npcs flag.
*/
public void flagExcessiveNpcs() {
this.excessiveNpcs = true;
excessiveNpcs = true;
}
/**
@@ -434,6 +434,15 @@ public final class Player extends Character {
return members;
}
/**
* Gets whether the player is running or not.
*
* @return {@code true} if the player is running, otherwise {@code false}.
*/
public boolean isRunning() {
return running;
}
/**
* Gets the withdrawing notes flag.
*
@@ -527,7 +536,7 @@ public final class Player extends Character {
*/
public void setAppearance(Appearance appearance) {
this.appearance = appearance;
this.getBlockSet().add(SynchronizationBlock.createAppearanceBlock(this));
getBlockSet().add(SynchronizationBlock.createAppearanceBlock(this));
}
/**
@@ -593,6 +602,16 @@ public final class Player extends Character {
this.regionChanged = regionChanged;
}
/**
* Sets whether the running toggle is enabled.
*
* @param running The toggle.
*/
public void setRunning(boolean running) {
this.running = running;
getWalkingQueue().setRunningQueue(running);
}
/**
* Sets the player's {@link GameSession}.
*
@@ -628,23 +647,4 @@ public final class Player extends Character {
+ privilegeLevel + "]";
}
/**
* Gets whether the player is running or not.
*
* @return {@code true} if the player is running, otherwise {@code false}.
*/
public boolean isRunning() {
return running;
}
/**
* Sets whether the running toggle is enabled.
*
* @param running The toggle.
*/
public void setRunning(boolean running) {
this.running = running;
getWalkingQueue().setRunningQueue(running);
}
}
+144 -144
View File
@@ -58,150 +58,6 @@ public final class Position {
this.height = height;
}
/**
* Gets the x coordinate.
*
* @return The x coordinate.
*/
public int getX() {
return x;
}
/**
* Gets the y coordinate.
*
* @return The y coordinate.
*/
public int getY() {
return y;
}
/**
* Gets the height level.
*
* @return The height level.
*/
public int getHeight() {
return height;
}
/**
* Gets the x coordinate of the region.
*
* @return The region x coordinate.
*/
public int getTopLeftRegionX() {
return (x / 8) - 6;
}
/**
* Gets the y coordinate of the region.
*
* @return The region y coordinate.
*/
public int getTopLeftRegionY() {
return (y / 8) - 6;
}
/**
* Gets the x coordinate of the central region.
*
* @return The x coordinate of the central region.
*/
public int getCentralRegionX() {
return x / 8;
}
/**
* Gets the y coordinate of the central region.
*
* @return The y coordinate of the central region.
*/
public int getCentralRegionY() {
return y / 8;
}
/**
* Gets the x coordinate inside the region of this position.
*
* @return The local x coordinate.
*/
public int getLocalX() {
return getLocalX(this);
}
/**
* Gets the y coordinate inside the region of this position.
*
* @return The local y coordinate.
*/
public int getLocalY() {
return getLocalY(this);
}
/**
* Gets the local x coordinate inside the region of the {@code base} position.
*
* @param base The base position.
* @return The local x coordinate.
*/
public int getLocalX(Position base) {
return x - (base.getTopLeftRegionX() * 8);
}
/**
* Gets the local y coordinate inside the region of the {@code base} position.
*
* @param base The base position.
* @return The local y coordinate.
*/
public int getLocalY(Position base) {
return y - (base.getTopLeftRegionY() * 8);
}
@Override
public int hashCode() {
return ((height << 30) & 0xC0000000) | ((y << 15) & 0x3FFF8000) | (x & 0x7FFF);
}
/**
* Gets the distance between this position and another position. Only X and Y are considered (i.e. 2 dimensions).
*
* @param other The other position.
* @return The distance.
*/
public int getDistance(Position other) {
int deltaX = x - other.x;
int deltaY = y - other.y;
// TODO will rounding up interfere with other stuff?
return (int) Math.ceil(Math.sqrt(deltaX * deltaX + deltaY * deltaY));
}
/**
* Gets the longest horizontal or vertical delta between the two positions.
*
* @param other The other position.
* @return The longest horizontal or vertical delta.
*/
public int getLongestDelta(Position other) {
int deltaX = x - other.x;
int deltaY = y - other.y;
return Math.max(deltaX, deltaY);
}
/**
* Checks if the position is within distance of another.
*
* @param other The other position.
* @param distance The distance.
* @return {@code true} if so, {@code false} if not.
*/
public boolean isWithinDistance(Position other, int distance) {
int deltaX = Math.abs(x - other.x);
int deltaY = Math.abs(y - other.y);
return deltaX <= distance && deltaY <= distance;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
@@ -226,6 +82,150 @@ public final class Position {
return true;
}
/**
* Gets the x coordinate of the central region.
*
* @return The x coordinate of the central region.
*/
public int getCentralRegionX() {
return x / 8;
}
/**
* Gets the y coordinate of the central region.
*
* @return The y coordinate of the central region.
*/
public int getCentralRegionY() {
return y / 8;
}
/**
* Gets the distance between this position and another position. Only X and Y are considered (i.e. 2 dimensions).
*
* @param other The other position.
* @return The distance.
*/
public int getDistance(Position other) {
int deltaX = x - other.x;
int deltaY = y - other.y;
// TODO will rounding up interfere with other stuff?
return (int) Math.ceil(Math.sqrt(deltaX * deltaX + deltaY * deltaY));
}
/**
* Gets the height level.
*
* @return The height level.
*/
public int getHeight() {
return height;
}
/**
* Gets the x coordinate inside the region of this position.
*
* @return The local x coordinate.
*/
public int getLocalX() {
return getLocalX(this);
}
/**
* Gets the local x coordinate inside the region of the {@code base} position.
*
* @param base The base position.
* @return The local x coordinate.
*/
public int getLocalX(Position base) {
return x - base.getTopLeftRegionX() * 8;
}
/**
* Gets the y coordinate inside the region of this position.
*
* @return The local y coordinate.
*/
public int getLocalY() {
return getLocalY(this);
}
/**
* Gets the local y coordinate inside the region of the {@code base} position.
*
* @param base The base position.
* @return The local y coordinate.
*/
public int getLocalY(Position base) {
return y - base.getTopLeftRegionY() * 8;
}
/**
* Gets the longest horizontal or vertical delta between the two positions.
*
* @param other The other position.
* @return The longest horizontal or vertical delta.
*/
public int getLongestDelta(Position other) {
int deltaX = x - other.x;
int deltaY = y - other.y;
return Math.max(deltaX, deltaY);
}
/**
* Gets the x coordinate of the region.
*
* @return The region x coordinate.
*/
public int getTopLeftRegionX() {
return x / 8 - 6;
}
/**
* Gets the y coordinate of the region.
*
* @return The region y coordinate.
*/
public int getTopLeftRegionY() {
return y / 8 - 6;
}
/**
* Gets the x coordinate.
*
* @return The x coordinate.
*/
public int getX() {
return x;
}
/**
* Gets the y coordinate.
*
* @return The y coordinate.
*/
public int getY() {
return y;
}
@Override
public int hashCode() {
return height << 30 & 0xC0000000 | y << 15 & 0x3FFF8000 | x & 0x7FFF;
}
/**
* Checks if the position is within distance of another.
*
* @param other The other position.
* @param distance The distance.
* @return {@code true} if so, {@code false} if not.
*/
public boolean isWithinDistance(Position other, int distance) {
int deltaX = Math.abs(x - other.x);
int deltaY = Math.abs(y - other.y);
return deltaX <= distance && deltaY <= distance;
}
@Override
public String toString() {
return Position.class.getName() + " [x=" + x + ", y=" + y + ", height=" + height + "]";
+9 -9
View File
@@ -157,15 +157,6 @@ public final class Skill {
this.maximumLevel = maximumLevel;
}
/**
* Gets the experience.
*
* @return The experience.
*/
public double getExperience() {
return experience;
}
/**
* Gets the current level.
*
@@ -175,6 +166,15 @@ public final class Skill {
return currentLevel;
}
/**
* Gets the experience.
*
* @return The experience.
*/
public double getExperience() {
return experience;
}
/**
* Gets the maximum level.
*
+134 -134
View File
@@ -22,6 +22,44 @@ public final class SkillSet {
*/
public static final double MAXIMUM_EXP = 200000000;
/**
* Gets the minimum experience required for the specified level.
*
* @param level The level.
* @return The minimum experience.
*/
public static double getExperienceForLevel(int level) {
int points = 0;
int output = 0;
for (int lvl = 1; lvl <= level; lvl++) {
points += Math.floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0));
if (lvl >= level) {
return output;
}
output = (int) Math.floor(points / 4);
}
return 0;
}
/**
* Gets the minimum level to get the specified experience.
*
* @param experience The experience.
* @return The minimum level.
*/
public static int getLevelForExperience(double experience) {
int points = 0;
int output = 0;
for (int lvl = 1; lvl <= 99; lvl++) {
points += Math.floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0));
output = (int) Math.floor(points / 4);
if (output >= experience + 1) {
return lvl;
}
}
return 99;
}
/**
* A list of skill listeners.
*/
@@ -44,41 +82,6 @@ public final class SkillSet {
init();
}
/**
* Gets the number of skills.
*
* @return The number of skills.
*/
public int size() {
return skills.length;
}
/**
* Initialises the skill set.
*/
private void init() {
for (int i = 0; i < skills.length; i++) {
if (i == Skill.HITPOINTS) {
skills[i] = new Skill(1154, 10, 10);
} else {
skills[i] = new Skill(0, 1, 1);
}
// DO NOT CALL notifyXXX here!!
}
}
/**
* Gets a skill by its id.
*
* @param id The id.
* @return The skill.
* @throws IndexOutOfBoundsException If the id is out of bounds.
*/
public Skill getSkill(int id) {
checkBounds(id);
return skills[id];
}
/**
* Adds experience to the specified skill.
*
@@ -113,16 +116,31 @@ public final class SkillSet {
}
/**
* Gets the total level for this skill set.
* Adds a listener.
*
* @return The total level.
* @param listener The listener to add.
*/
public int getTotalLevel() {
int total = 0;
for (int i = 0; i < skills.length; i++) {
total += skills[i].getMaximumLevel();
public void addListener(SkillListener listener) {
listeners.add(listener);
}
/**
* Checks the bounds of the id.
*
* @param id The id.
* @throws IndexOutOfBoundsException If the id is out of bounds.
*/
private void checkBounds(int id) {
if (id < 0 || id >= skills.length) {
throw new IndexOutOfBoundsException();
}
return total;
}
/**
* Forces this skill set to refresh.
*/
public void forceRefresh() {
notifySkillsUpdated();
}
/**
@@ -156,41 +174,42 @@ public final class SkillSet {
}
/**
* Gets the minimum experience required for the specified level.
* Gets a skill by its id.
*
* @param level The level.
* @return The minimum experience.
* @param id The id.
* @return The skill.
* @throws IndexOutOfBoundsException If the id is out of bounds.
*/
public static double getExperienceForLevel(int level) {
int points = 0;
int output = 0;
for (int lvl = 1; lvl <= level; lvl++) {
points += Math.floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0));
if (lvl >= level) {
return output;
}
output = (int) Math.floor(points / 4);
}
return 0;
public Skill getSkill(int id) {
checkBounds(id);
return skills[id];
}
/**
* Gets the minimum level to get the specified experience.
* Gets the total level for this skill set.
*
* @param experience The experience.
* @return The minimum level.
* @return The total level.
*/
public static int getLevelForExperience(double experience) {
int points = 0;
int output = 0;
for (int lvl = 1; lvl <= 99; lvl++) {
points += Math.floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0));
output = (int) Math.floor(points / 4);
if (output >= (experience + 1)) {
return lvl;
}
public int getTotalLevel() {
int total = 0;
for (Skill skill : skills) {
total += skill.getMaximumLevel();
}
return total;
}
/**
* Initialises the skill set.
*/
private void init() {
for (int i = 0; i < skills.length; i++) {
if (i == Skill.HITPOINTS) {
skills[i] = new Skill(1154, 10, 10);
} else {
skills[i] = new Skill(0, 1, 1);
}
// DO NOT CALL notifyXXX here!!
}
return 99;
}
/**
@@ -214,31 +233,6 @@ public final class SkillSet {
}
}
/**
* Sets a skill.
*
* @param id The id.
* @param skill The skill.
* @throws IndexOutOfBoundsException If the id is out of bounds.
*/
public void setSkill(int id, Skill skill) {
checkBounds(id);
skills[id] = skill;
notifySkillUpdated(id);
}
/**
* Checks the bounds of the id.
*
* @param id The id.
* @throws IndexOutOfBoundsException If the id is out of bounds.
*/
private void checkBounds(int id) {
if (id < 0 || id >= skills.length) {
throw new IndexOutOfBoundsException();
}
}
/**
* Notifies listeners that a skill has been levelled up.
*
@@ -254,6 +248,17 @@ public final class SkillSet {
}
}
/**
* Notifies listeners that the skills in this listener have been updated.
*/
private void notifySkillsUpdated() {
if (firingEvents) {
for (SkillListener listener : listeners) {
listener.skillsUpdated(this);
}
}
}
/**
* Notifies listeners that a skill has been updated.
*
@@ -270,44 +275,10 @@ public final class SkillSet {
}
/**
* Notifies listeners that the skills in this listener have been updated.
* Removes all the listeners.
*/
private void notifySkillsUpdated() {
if (firingEvents) {
for (SkillListener listener : listeners) {
listener.skillsUpdated(this);
}
}
}
/**
* Stops events from being fired.
*/
public void stopFiringEvents() {
firingEvents = false;
}
/**
* Re-enables the firing of events.
*/
public void startFiringEvents() {
firingEvents = true;
}
/**
* Forces this skill set to refresh.
*/
public void forceRefresh() {
notifySkillsUpdated();
}
/**
* Adds a listener.
*
* @param listener The listener to add.
*/
public void addListener(SkillListener listener) {
listeners.add(listener);
public void removeAllListeners() {
listeners.clear();
}
/**
@@ -320,10 +291,39 @@ public final class SkillSet {
}
/**
* Removes all the listeners.
* Sets a skill.
*
* @param id The id.
* @param skill The skill.
* @throws IndexOutOfBoundsException If the id is out of bounds.
*/
public void removeAllListeners() {
listeners.clear();
public void setSkill(int id, Skill skill) {
checkBounds(id);
skills[id] = skill;
notifySkillUpdated(id);
}
/**
* Gets the number of skills.
*
* @return The number of skills.
*/
public int size() {
return skills.length;
}
/**
* Re-enables the firing of events.
*/
public void startFiringEvents() {
firingEvents = true;
}
/**
* Stops events from being fired.
*/
public void stopFiringEvents() {
firingEvents = false;
}
}
+9 -9
View File
@@ -28,15 +28,6 @@ public final class SlottedItem {
this.item = item;
}
/**
* Gets the slot.
*
* @return The slot.
*/
public int getSlot() {
return slot;
}
/**
* Gets the item.
*
@@ -46,4 +37,13 @@ public final class SlottedItem {
return item;
}
/**
* Gets the slot.
*
* @return The slot.
*/
public int getSlot() {
return slot;
}
}
+66 -66
View File
@@ -11,11 +11,6 @@ import java.util.Queue;
*/
public final class WalkingQueue {
/**
* The maximum size of the queue. If any additional steps are added, they are discarded.
*/
private static final int MAXIMUM_SIZE = 128;
/**
* Represents a single point in the queue.
*
@@ -51,6 +46,11 @@ public final class WalkingQueue {
}
/**
* The maximum size of the queue. If any additional steps are added, they are discarded.
*/
private static final int MAXIMUM_SIZE = 128;
/**
* The character whose walking queue this is.
*/
@@ -80,42 +80,6 @@ public final class WalkingQueue {
this.character = character;
}
/**
* Called every pulse, updates the queue.
*/
public void pulse() {
Position position = character.getPosition();
Direction first = Direction.NONE;
Direction second = Direction.NONE;
Point next = points.poll();
if (next != null) {
first = next.direction;
position = next.position;
if (runningQueue /* or run toggled AND enough energy */) {
next = points.poll();
if (next != null) {
second = next.direction;
position = next.position;
}
}
}
character.setDirections(first, second);
character.setPosition(position);
}
/**
* Sets the running queue flag.
*
* @param running The running queue flag.
*/
public void setRunningQueue(boolean running) {
this.runningQueue = running;
}
/**
* Adds the first step to the queue, attempting to connect the server and client position by looking at the previous
* queue.
@@ -165,6 +129,31 @@ public final class WalkingQueue {
return false;
}
/**
* Adds a step.
*
* @param x The x coordinate of this step.
* @param y The y coordinate of this step.
*/
private void addStep(int x, int y) {
if (points.size() >= MAXIMUM_SIZE) {
return;
}
Point last = getLast();
int deltaX = x - last.position.getX();
int deltaY = y - last.position.getY();
Direction direction = Direction.fromDeltas(deltaX, deltaY);
if (direction != Direction.NONE) {
Point p = new Point(new Position(x, y, character.getPosition().getHeight()), direction);
points.add(p);
oldPoints.add(p);
}
}
/**
* Adds a step to the queue.
*
@@ -199,28 +188,11 @@ public final class WalkingQueue {
}
/**
* Adds a step.
*
* @param x The x coordinate of this step.
* @param y The y coordinate of this step.
* Clears the walking queue.
*/
private void addStep(int x, int y) {
if (points.size() >= MAXIMUM_SIZE) {
return;
}
Point last = getLast();
int deltaX = x - last.position.getX();
int deltaY = y - last.position.getY();
Direction direction = Direction.fromDeltas(deltaX, deltaY);
if (direction != Direction.NONE) {
Point p = new Point(new Position(x, y, character.getPosition().getHeight()), direction);
points.add(p);
oldPoints.add(p);
}
public void clear() {
points.clear();
oldPoints.clear();
}
/**
@@ -237,11 +209,39 @@ public final class WalkingQueue {
}
/**
* Clears the walking queue.
* Called every pulse, updates the queue.
*/
public void clear() {
points.clear();
oldPoints.clear();
public void pulse() {
Position position = character.getPosition();
Direction first = Direction.NONE;
Direction second = Direction.NONE;
Point next = points.poll();
if (next != null) {
first = next.direction;
position = next.position;
if (runningQueue /* or run toggled AND enough energy */) {
next = points.poll();
if (next != null) {
second = next.direction;
position = next.position;
}
}
}
character.setDirections(first, second);
character.setPosition(position);
}
/**
* Sets the running queue flag.
*
* @param running The running queue flag.
*/
public void setRunningQueue(boolean running) {
runningQueue = running;
}
/**
@@ -1,5 +1,7 @@
package org.apollo.game.model.def;
import org.apollo.game.model.Npc;
/**
* Represents a type of {@link Npc}.
*
@@ -15,27 +15,6 @@ import org.apollo.game.model.inv.SynchronizationInventoryListener;
*/
public final class BankUtils {
/**
* Opens a player's bank.
*
* @param player The player.
*/
public static void openBank(Player player) {
InventoryListener invListener = new SynchronizationInventoryListener(player, BankConstants.SIDEBAR_INVENTORY_ID);
InventoryListener bankListener = new SynchronizationInventoryListener(player, BankConstants.BANK_INVENTORY_ID);
player.getInventory().addListener(invListener);
player.getBank().addListener(bankListener);
player.getInventory().forceRefresh();
player.getBank().forceRefresh();
InterfaceListener interListener = new BankInterfaceListener(player, invListener, bankListener);
player.getInterfaceSet().openWindowWithSidebar(interListener, BankConstants.BANK_WINDOW_ID,
BankConstants.SIDEBAR_ID);
}
/**
* Deposits an item into the player's bank.
*
@@ -88,6 +67,27 @@ public final class BankUtils {
return true;
}
/**
* Opens a player's bank.
*
* @param player The player.
*/
public static void openBank(Player player) {
InventoryListener invListener = new SynchronizationInventoryListener(player, BankConstants.SIDEBAR_INVENTORY_ID);
InventoryListener bankListener = new SynchronizationInventoryListener(player, BankConstants.BANK_INVENTORY_ID);
player.getInventory().addListener(invListener);
player.getBank().addListener(bankListener);
player.getInventory().forceRefresh();
player.getBank().forceRefresh();
InterfaceListener interListener = new BankInterfaceListener(player, invListener, bankListener);
player.getInterfaceSet().openWindowWithSidebar(interListener, BankConstants.BANK_WINDOW_ID,
BankConstants.SIDEBAR_ID);
}
/**
* Withdraws an item from a player's bank.
*
@@ -26,11 +26,9 @@ public final class AppearanceInventoryListener extends InventoryAdapter {
this.player = player;
}
/**
* Updates the player's appearance.
*/
private void update() {
player.getBlockSet().add(SynchronizationBlock.createAppearanceBlock(player));
@Override
public void itemsUpdated(Inventory inventory) {
update();
}
@Override
@@ -38,9 +36,11 @@ public final class AppearanceInventoryListener extends InventoryAdapter {
update();
}
@Override
public void itemsUpdated(Inventory inventory) {
update();
/**
* Updates the player's appearance.
*/
private void update() {
player.getBlockSet().add(SynchronizationBlock.createAppearanceBlock(player));
}
}
@@ -45,7 +45,7 @@ public final class FullInventoryListener extends InventoryAdapter {
*/
public FullInventoryListener(Player player, String message) {
this.player = player;
this.event = new ServerMessageEvent(message);
event = new ServerMessageEvent(message);
}
@Override
@@ -15,14 +15,14 @@ public abstract class InventoryAdapter implements InventoryListener {
/* empty */
}
@Override
public void itemUpdated(Inventory inventory, int slot, Item item) {
/* empty */
}
@Override
public void itemsUpdated(Inventory inventory) {
/* empty */
}
@Override
public void itemUpdated(Inventory inventory, int slot, Item item) {
/* empty */
}
}
@@ -17,6 +17,13 @@ public interface InventoryListener {
*/
public void capacityExceeded(Inventory inventory);
/**
* Called when items have been updated in bulk.
*
* @param inventory The inventory.
*/
public void itemsUpdated(Inventory inventory);
/**
* Called when an item has been updated.
*
@@ -26,11 +33,4 @@ public interface InventoryListener {
*/
public void itemUpdated(Inventory inventory, int slot, Item item);
/**
* Called when items have been updated in bulk.
*
* @param inventory The inventory.
*/
public void itemsUpdated(Inventory inventory);
}
@@ -45,14 +45,14 @@ public final class SynchronizationInventoryListener extends InventoryAdapter {
this.interfaceId = interfaceId;
}
@Override
public void itemUpdated(Inventory inventory, int slot, Item item) {
player.send(new UpdateSlottedItemsEvent(interfaceId, new SlottedItem(slot, item)));
}
@Override
public void itemsUpdated(Inventory inventory) {
player.send(new UpdateItemsEvent(interfaceId, inventory.getItems()));
}
@Override
public void itemUpdated(Inventory inventory, int slot, Item item) {
player.send(new UpdateSlottedItemsEvent(interfaceId, new SlottedItem(slot, item)));
}
}
@@ -56,7 +56,7 @@ public final class StaticObject {
this.position = position;
this.type = (byte) type;
this.rotation = (byte) rotation;
this.definition = ObjectDefinition.lookup(id);
definition = ObjectDefinition.lookup(id);
}
/**
@@ -28,6 +28,24 @@ public final class RegionCoordinates {
this.y = y;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final RegionCoordinates other = (RegionCoordinates) obj;
if (x != other.x) {
return false;
}
if (y != other.y) {
return false;
}
return true;
}
/**
* Gets the X coordinate.
*
@@ -46,29 +64,11 @@ public final class RegionCoordinates {
return y;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final RegionCoordinates other = (RegionCoordinates) obj;
if (this.x != other.x) {
return false;
}
if (this.y != other.y) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 7;
hash = 61 * hash + this.x;
hash = 61 * hash + this.y;
hash = 61 * hash + x;
hash = 61 * hash + y;
return hash;
}
@@ -15,14 +15,14 @@ public abstract class SkillAdapter implements SkillListener {
/* empty */
}
@Override
public void skillUpdated(SkillSet set, int id, Skill skill) {
/* empty */
}
@Override
public void skillsUpdated(SkillSet set) {
/* empty */
}
@Override
public void skillUpdated(SkillSet set, int id, Skill skill) {
/* empty */
}
}
@@ -11,13 +11,13 @@ import org.apollo.game.model.SkillSet;
public interface SkillListener {
/**
* Called when a single skill is updated.
* Called when a skill is levelled up.
*
* @param set The skill set.
* @param id The skill's id.
* @param skill The skill.
*/
public void skillUpdated(SkillSet set, int id, Skill skill);
public void levelledUp(SkillSet set, int id, Skill skill);
/**
* Called when all the skills are updated.
@@ -27,12 +27,12 @@ public interface SkillListener {
public void skillsUpdated(SkillSet set);
/**
* Called when a skill is levelled up.
* Called when a single skill is updated.
*
* @param set The skill set.
* @param id The skill's id.
* @param skill The skill.
*/
public void levelledUp(SkillSet set, int id, Skill skill);
public void skillUpdated(SkillSet set, int id, Skill skill);
}
@@ -32,11 +32,6 @@ public final class SynchronizationSkillListener extends SkillAdapter {
player.getBlockSet().add(SynchronizationBlock.createAppearanceBlock(player));
}
@Override
public void skillUpdated(SkillSet set, int id, Skill skill) {
player.send(new UpdateSkillEvent(id, skill));
}
@Override
public void skillsUpdated(SkillSet set) {
for (int id = 0; id < set.size(); id++) {
@@ -44,4 +39,9 @@ public final class SynchronizationSkillListener extends SkillAdapter {
}
}
@Override
public void skillUpdated(SkillSet set, int id, Skill skill) {
player.send(new UpdateSkillEvent(id, skill));
}
}
@@ -32,9 +32,14 @@ public abstract class ScheduledTask {
*/
public ScheduledTask(int delay, boolean immediate) {
setDelay(delay);
this.pulses = immediate ? 0 : delay;
pulses = immediate ? 0 : delay;
}
/**
* Executes this task.
*/
public abstract void execute();
/**
* Checks if this task is running.
*
@@ -44,6 +49,16 @@ public abstract class ScheduledTask {
return running;
}
/**
* Pulses this task: updates the delay and calls {@link #execute()} if necessary.
*/
final void pulse() {
if (running && pulses-- == 0) {
execute();
pulses = delay;
}
}
/**
* Sets the delay.
*
@@ -64,19 +79,4 @@ public abstract class ScheduledTask {
running = false;
}
/**
* Pulses this task: updates the delay and calls {@link #execute()} if necessary.
*/
final void pulse() {
if (running && pulses-- == 0) {
execute();
pulses = delay;
}
}
/**
* Executes this task.
*/
public abstract void execute();
}
@@ -23,15 +23,6 @@ public final class Scheduler {
*/
private List<ScheduledTask> tasks = new ArrayList<ScheduledTask>();
/**
* Schedules a new task.
*
* @param task The task to schedule.
*/
public void schedule(ScheduledTask task) {
newTasks.add(task);
}
/**
* Called every pulse: executes tasks that are still pending, adds new tasks and stops old tasks.
*/
@@ -50,4 +41,13 @@ public final class Scheduler {
}
}
/**
* Schedules a new task.
*
* @param task The task to schedule.
*/
public void schedule(ScheduledTask task) {
newTasks.add(task);
}
}
@@ -7,8 +7,8 @@ import java.util.concurrent.ThreadFactory;
import org.apollo.game.GameService;
import org.apollo.game.model.Npc;
import org.apollo.game.model.World;
import org.apollo.game.model.Player;
import org.apollo.game.model.World;
import org.apollo.game.sync.task.NpcSynchronizationTask;
import org.apollo.game.sync.task.PhasedSynchronizationTask;
import org.apollo.game.sync.task.PlayerSynchronizationTask;
@@ -2,8 +2,8 @@ package org.apollo.game.sync;
import org.apollo.game.GameService;
import org.apollo.game.model.Npc;
import org.apollo.game.model.World;
import org.apollo.game.model.Player;
import org.apollo.game.model.World;
import org.apollo.game.sync.task.NpcSynchronizationTask;
import org.apollo.game.sync.task.PlayerSynchronizationTask;
import org.apollo.game.sync.task.PostNpcSynchronizationTask;
@@ -1,7 +1,7 @@
package org.apollo.game.sync.block;
import org.apollo.game.model.Inventory;
import org.apollo.game.model.Appearance;
import org.apollo.game.model.Inventory;
/**
* The appearance {@link SynchronizationBlock}.
@@ -4,8 +4,8 @@ import org.apollo.game.event.impl.ChatEvent;
import org.apollo.game.model.Animation;
import org.apollo.game.model.Direction;
import org.apollo.game.model.Graphic;
import org.apollo.game.model.Position;
import org.apollo.game.model.Player;
import org.apollo.game.model.Position;
import org.apollo.game.sync.seg.SynchronizationSegment;
/**
@@ -13,8 +13,8 @@ import org.apollo.game.sync.block.ChatBlock;
import org.apollo.game.sync.block.SynchronizationBlock;
import org.apollo.game.sync.block.SynchronizationBlockSet;
import org.apollo.game.sync.seg.AddPlayerSegment;
import org.apollo.game.sync.seg.RemoveCharacterSegment;
import org.apollo.game.sync.seg.MovementSegment;
import org.apollo.game.sync.seg.RemoveCharacterSegment;
import org.apollo.game.sync.seg.SynchronizationSegment;
import org.apollo.game.sync.seg.TeleportSegment;
import org.apollo.util.CharacterRepository;
@@ -82,8 +82,7 @@ public final class PlayerSynchronizationTask extends SynchronizationTask {
int added = 0;
CharacterRepository<Player> repository = World.getWorld().getPlayerRepository();
for (Iterator<Player> it = repository.iterator(); it.hasNext();) {
Player p = it.next();
for (Player p : repository) {
if (localPlayers.size() >= 255) {
player.flagExcessivePlayers();
break;
@@ -25,6 +25,21 @@ public final class PrePlayerSynchronizationTask extends SynchronizationTask {
this.player = player;
}
/**
* Checks if a region update is required.
*
* @return {@code true} if so, {@code false} otherwise.
*/
private boolean isRegionUpdateRequired() {
Position current = player.getPosition();
Position last = player.getLastKnownRegion();
int deltaX = current.getLocalX(last);
int deltaY = current.getLocalY(last);
return deltaX < 16 || deltaX >= 88 || deltaY < 16 || deltaY >= 88;
}
@Override
public void run() {
player.getWalkingQueue().pulse();
@@ -47,19 +62,4 @@ public final class PrePlayerSynchronizationTask extends SynchronizationTask {
}
}
/**
* Checks if a region update is required.
*
* @return {@code true} if so, {@code false} otherwise.
*/
private boolean isRegionUpdateRequired() {
Position current = player.getPosition();
Position last = player.getLastKnownRegion();
int deltaX = current.getLocalX(last);
int deltaY = current.getLocalY(last);
return deltaX < 16 || deltaX >= 88 || deltaY < 16 || deltaY >= 88;
}
}
@@ -9,8 +9,8 @@ import java.util.Map;
import org.apollo.game.event.Event;
import org.apollo.game.event.handler.EventHandler;
import org.apollo.game.event.handler.chain.EventHandlerChainGroup;
import org.apollo.game.event.handler.chain.EventHandlerChain;
import org.apollo.game.event.handler.chain.EventHandlerChainGroup;
import org.apollo.util.xml.XmlNode;
import org.apollo.util.xml.XmlParser;
import org.xml.sax.SAXException;
@@ -39,7 +39,7 @@ public final class EventHandlerChainParser {
* @throws SAXException If a SAX error occurs.
*/
public EventHandlerChainParser(InputStream is) throws SAXException {
this.parser = new XmlParser();
parser = new XmlParser();
this.is = is;
}
+17 -17
View File
@@ -37,10 +37,26 @@ public final class PluginMetaDataParser {
* @throws SAXException If a SAX error occurs.
*/
public PluginMetaDataParser(InputStream is) throws SAXException {
this.parser = new XmlParser();
parser = new XmlParser();
this.is = is;
}
/**
* Gets the specified child element, if it exists.
*
* @param node The root node.
* @param name The element name.
* @return The node object.
* @throws IOException If the element does not exist.
*/
private XmlNode getElement(XmlNode node, String name) throws IOException {
XmlNode child = node.getChild(name);
if (child == null) {
throw new IOException("no " + name + " element found");
}
return child;
}
/**
* Parses the XML and creates a meta data object.
*
@@ -103,20 +119,4 @@ public final class PluginMetaDataParser {
return new PluginMetaData(id, name, description, authors, scripts, dependencies, version);
}
/**
* Gets the specified child element, if it exists.
*
* @param node The root node.
* @param name The element name.
* @return The node object.
* @throws IOException If the element does not exist.
*/
private XmlNode getElement(XmlNode node, String name) throws IOException {
XmlNode child = node.getChild(name);
if (child == null) {
throw new IOException("no " + name + " element found");
}
return child;
}
}
@@ -31,7 +31,7 @@ public final class PlayerLoaderResponse {
throw new IllegalArgumentException("player required for this status code");
}
this.status = status;
this.player = null;
player = null;
}
/**
@@ -49,15 +49,6 @@ public final class PlayerLoaderResponse {
this.player = player;
}
/**
* Gets the status code.
*
* @return The status code.
*/
public int getStatus() {
return status;
}
/**
* Gets the player.
*
@@ -67,4 +58,13 @@ public final class PlayerLoaderResponse {
return player;
}
/**
* Gets the status code.
*
* @return The status code.
*/
public int getStatus() {
return status;
}
}
@@ -10,10 +10,10 @@ 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.Skill;
import org.apollo.game.model.SkillSet;
import org.apollo.game.model.Player.PrivilegeLevel;
import org.apollo.io.player.PlayerLoader;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.net.codec.login.LoginConstants;
@@ -44,12 +44,12 @@ public final class BinaryPlayerSaver implements PlayerSaver {
Appearance appearance = player.getAppearance();
out.writeByte(appearance.getGender().toInteger());
int[] style = appearance.getStyle();
for (int i = 0; i < style.length; i++) {
out.writeByte(style[i]);
for (int element : style) {
out.writeByte(element);
}
int[] colors = appearance.getColors();
for (int i = 0; i < colors.length; i++) {
out.writeByte(colors[i]);
for (int color : colors) {
out.writeByte(color);
}
out.flush();
@@ -1,8 +1,8 @@
package org.apollo.io.player.impl;
import org.apollo.game.model.Player;
import org.apollo.game.model.Position;
import org.apollo.game.model.Player.PrivilegeLevel;
import org.apollo.game.model.Position;
import org.apollo.io.player.PlayerLoader;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.net.codec.login.LoginConstants;
+8 -8
View File
@@ -87,6 +87,14 @@ public final class LoginService extends Service {
saver = (PlayerSaver) saverClazz.newInstance();
}
/**
* Starts the login service.
*/
@Override
public void start() {
/* empty - here for consistency with other services */
}
/**
* Submits a login request.
*
@@ -113,12 +121,4 @@ public final class LoginService extends Service {
executor.submit(new PlayerSaverWorker(saver, session, player));
}
/**
* Starts the login service.
*/
@Override
public void start() {
/* empty - here for consistency with other services */
}
}
+12 -12
View File
@@ -43,12 +43,7 @@ public final class ApolloHandler extends IdleStateAwareChannelUpstreamHandler {
* @param context The server context.
*/
public ApolloHandler(ServerContext context) {
this.serverContext = context;
}
@Override
public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception {
e.getChannel().close();
serverContext = context;
}
@Override
@@ -69,6 +64,17 @@ public final class ApolloHandler extends IdleStateAwareChannelUpstreamHandler {
}
}
@Override
public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception {
e.getChannel().close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
logger.log(Level.WARNING, "Exception occured for channel: " + e.getChannel() + ", closing...", e.getCause());
ctx.getChannel().close();
}
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
if (ctx.getAttachment() == null) {
@@ -96,10 +102,4 @@ public final class ApolloHandler extends IdleStateAwareChannelUpstreamHandler {
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
logger.log(Level.WARNING, "Exception occured for channel: " + e.getChannel() + ", closing...", e.getCause());
ctx.getChannel().close();
}
}
@@ -17,7 +17,7 @@ public final class DataConstants {
*/
static {
for (int i = 0; i < BIT_MASK.length; i++) {
BIT_MASK[i] = ((1 << i) - 1);
BIT_MASK[i] = (1 << i) - 1;
}
}
+10 -10
View File
@@ -40,19 +40,10 @@ public final class GamePacket {
public GamePacket(int opcode, PacketType type, ChannelBuffer payload) {
this.opcode = opcode;
this.type = type;
this.length = payload.readableBytes();
length = payload.readableBytes();
this.payload = payload;
}
/**
* Gets the opcode.
*
* @return The opcode.
*/
public int getOpcode() {
return opcode;
}
/**
* Gets the payload length.
*
@@ -62,6 +53,15 @@ public final class GamePacket {
return length;
}
/**
* Gets the opcode.
*
* @return The opcode.
*/
public int getOpcode() {
return opcode;
}
/**
* Gets the payload.
*
@@ -66,19 +66,25 @@ public final class GamePacketBuilder {
}
/**
* Creates a {@link GamePacket} based on the current contents of this builder.
* Checks that this builder is in the bit access mode.
*
* @return The {@link GamePacket}.
* @throws IllegalStateException If the builder is not in byte access mode, or if the packet is raw.
* @throws IllegalStateException If the builder is not in bit access mode.
*/
public GamePacket toGamePacket() {
if (type == PacketType.RAW) {
throw new IllegalStateException("Raw packets cannot be converted to a game packet");
private void checkBitAccess() {
if (mode != AccessMode.BIT_ACCESS) {
throw new IllegalStateException("For bit-based calls to work, the mode must be bit access");
}
}
/**
* Checks that this builder is in the byte access mode.
*
* @throws IllegalStateException If the builder is not in byte access mode.
*/
private void checkByteAccess() {
if (mode != AccessMode.BYTE_ACCESS) {
throw new IllegalStateException("Must be in byte access mode to convert to a packet");
throw new IllegalStateException("For byte-based calls to work, the mode must be byte access");
}
return new GamePacket(opcode, type, buffer);
}
/**
@@ -92,97 +98,6 @@ public final class GamePacketBuilder {
return buffer.writerIndex();
}
/**
* Switches this builder's mode to the byte access mode.
*
* @throws IllegalStateException If the builder is already in byte access mode.
*/
public void switchToByteAccess() {
if (mode == AccessMode.BYTE_ACCESS) {
throw new IllegalStateException("Already in byte access mode");
}
mode = AccessMode.BYTE_ACCESS;
buffer.writerIndex((bitIndex + 7) / 8);
}
/**
* Switches this builder's mode to the bit access mode.
*
* @throws IllegalStateException If the builder is already in bit access mode.
*/
public void switchToBitAccess() {
if (mode == AccessMode.BIT_ACCESS) {
throw new IllegalStateException("Already in bit access mode");
}
mode = AccessMode.BIT_ACCESS;
bitIndex = buffer.writerIndex() * 8;
}
/**
* Puts a raw builder. Both builders (this and parameter) must be in byte access mode.
*
* @param builder The builder.
*/
public void putRawBuilder(GamePacketBuilder builder) {
checkByteAccess();
if (builder.type != PacketType.RAW) {
throw new IllegalArgumentException("Builder must be raw!");
}
builder.checkByteAccess();
putBytes(builder.buffer);
}
/**
* Puts a raw builder in reverse. Both builders (this and parameter) must be in byte access mode.
*
* @param builder The builder.
*/
public void putRawBuilderReverse(GamePacketBuilder builder) {
checkByteAccess();
if (builder.type != PacketType.RAW) {
throw new IllegalArgumentException("Builder must be raw!");
}
builder.checkByteAccess();
putBytesReverse(builder.buffer);
}
/**
* Puts a standard data type with the specified value.
*
* @param type The data type.
* @param value The value.
* @throws IllegalStateException If this reader is not in byte access mode.
*/
public void put(DataType type, Number value) {
put(type, DataOrder.BIG, DataTransformation.NONE, value);
}
/**
* Puts a standard data type with the specified value and byte order.
*
* @param type The data type.
* @param order The byte order.
* @param value The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public void put(DataType type, DataOrder order, Number value) {
put(type, order, DataTransformation.NONE, value);
}
/**
* Puts a standard data type with the specified value and transformation.
*
* @param type The type.
* @param transformation The transformation.
* @param value The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public void put(DataType type, DataTransformation transformation, Number value) {
put(type, DataOrder.BIG, transformation, value);
}
/**
* Puts a standard data type with the specified value, byte order and transformation.
*
@@ -203,14 +118,14 @@ public final class GamePacketBuilder {
if (transformation == DataTransformation.ADD) {
buffer.writeByte((byte) (longValue + 128));
} else if (transformation == DataTransformation.NEGATE) {
buffer.writeByte((byte) (-longValue));
buffer.writeByte((byte) -longValue);
} else if (transformation == DataTransformation.SUBTRACT) {
buffer.writeByte((byte) (128 - longValue));
} else {
throw new IllegalArgumentException("unknown transformation");
}
} else {
buffer.writeByte((byte) (longValue >> (i * 8)));
buffer.writeByte((byte) (longValue >> i * 8));
}
}
} else if (order == DataOrder.LITTLE) {
@@ -219,14 +134,14 @@ public final class GamePacketBuilder {
if (transformation == DataTransformation.ADD) {
buffer.writeByte((byte) (longValue + 128));
} else if (transformation == DataTransformation.NEGATE) {
buffer.writeByte((byte) (-longValue));
buffer.writeByte((byte) -longValue);
} else if (transformation == DataTransformation.SUBTRACT) {
buffer.writeByte((byte) (128 - longValue));
} else {
throw new IllegalArgumentException("unknown transformation");
}
} else {
buffer.writeByte((byte) (longValue >> (i * 8)));
buffer.writeByte((byte) (longValue >> i * 8));
}
}
} else if (order == DataOrder.MIDDLE) {
@@ -257,122 +172,40 @@ public final class GamePacketBuilder {
}
/**
* Puts a string into the buffer.
*
* @param str The string.
*/
public void putString(String str) {
checkByteAccess();
char[] chars = str.toCharArray();
for (char c : chars) {
buffer.writeByte((byte) c);
}
buffer.writeByte(NetworkConstants.STRING_TERMINATOR);
}
/**
* Puts a smart into the buffer.
* Puts a standard data type with the specified value and byte order.
*
* @param type The data type.
* @param order The byte order.
* @param value The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public void putSmart(int value) {
checkByteAccess();
if (value < 128) {
buffer.writeByte(value);
} else {
buffer.writeShort(value);
}
public void put(DataType type, DataOrder order, Number value) {
put(type, order, DataTransformation.NONE, value);
}
/**
* Puts the bytes from the specified buffer into this packet's buffer.
*
* @param buffer The source {@link ChannelBuffer}.
* @throws IllegalStateException If the builder is not in byte access mode.
*/
public void putBytes(ChannelBuffer buffer) {
byte[] bytes = new byte[buffer.readableBytes()];
buffer.markReaderIndex();
try {
buffer.readBytes(bytes);
} finally {
buffer.resetReaderIndex();
}
putBytes(bytes);
}
/**
* Puts the bytes from the specified buffer into this packet's buffer, in reverse.
*
* @param buffer The source {@link ChannelBuffer}.
* @throws IllegalStateException If the builder is not in byte access mode.
*/
public void putBytesReverse(ChannelBuffer buffer) {
byte[] bytes = new byte[buffer.readableBytes()];
buffer.markReaderIndex();
try {
buffer.readBytes(bytes);
} finally {
buffer.resetReaderIndex();
}
putBytesReverse(bytes);
}
/**
* Puts the specified byte array into the buffer.
*
* @param bytes The byte array.
* @throws IllegalStateException If the builder is not in bit access mode.
*/
public void putBytes(byte[] bytes) {
buffer.writeBytes(bytes);
}
/**
* Puts the bytes into the buffer with the specified transformation.
* Puts a standard data type with the specified value and transformation.
*
* @param type The type.
* @param transformation The transformation.
* @param bytes The byte array.
* @throws IllegalStateException If the builder is not in byte access mode.
* @param value The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public void putBytes(DataTransformation transformation, byte[] bytes) {
if (transformation == DataTransformation.NONE) {
putBytes(bytes);
} else {
for (byte b : bytes) {
put(DataType.BYTE, transformation, b);
}
}
public void put(DataType type, DataTransformation transformation, Number value) {
put(type, DataOrder.BIG, transformation, value);
}
/**
* Puts the specified byte array into the buffer in reverse.
* Puts a standard data type with the specified value.
*
* @param bytes The byte array.
* @throws IllegalStateException If the builder is not in byte access mode.
* @param type The data type.
* @param value The value.
* @throws IllegalStateException If this reader is not in byte access mode.
*/
public void putBytesReverse(byte[] bytes) {
checkByteAccess();
for (int i = bytes.length - 1; i >= 0; i--) {
buffer.writeByte(bytes[i]);
}
}
/**
* Puts the specified byte array into the buffer in reverse with the specified transformation.
*
* @param transformation The transformation.
* @param bytes The byte array.
* @throws IllegalStateException If the builder is not in byte access mode.
*/
public void putBytesReverse(DataTransformation transformation, byte[] bytes) {
if (transformation == DataTransformation.NONE) {
putBytesReverse(bytes);
} else {
for (int i = bytes.length - 1; i >= 0; i--) {
put(DataType.BYTE, transformation, bytes[i]);
}
}
public void put(DataType type, Number value) {
put(type, DataOrder.BIG, DataTransformation.NONE, value);
}
/**
@@ -422,7 +255,7 @@ public final class GamePacketBuilder {
for (; numBits > bitOffset; bitOffset = 8) {
int tmp = buffer.getByte(bytePos);
tmp &= ~DataConstants.BIT_MASK[bitOffset];
tmp |= (value >> (numBits - bitOffset)) & DataConstants.BIT_MASK[bitOffset];
tmp |= value >> numBits - bitOffset & DataConstants.BIT_MASK[bitOffset];
buffer.setByte(bytePos++, tmp);
numBits -= bitOffset;
}
@@ -433,32 +266,199 @@ public final class GamePacketBuilder {
buffer.setByte(bytePos, tmp);
} else {
int tmp = buffer.getByte(bytePos);
tmp &= ~(DataConstants.BIT_MASK[numBits] << (bitOffset - numBits));
tmp |= (value & DataConstants.BIT_MASK[numBits]) << (bitOffset - numBits);
tmp &= ~(DataConstants.BIT_MASK[numBits] << bitOffset - numBits);
tmp |= (value & DataConstants.BIT_MASK[numBits]) << bitOffset - numBits;
buffer.setByte(bytePos, tmp);
}
}
/**
* Checks that this builder is in the byte access mode.
* Puts the specified byte array into the buffer.
*
* @param bytes The byte array.
* @throws IllegalStateException If the builder is not in bit access mode.
*/
public void putBytes(byte[] bytes) {
buffer.writeBytes(bytes);
}
/**
* Puts the bytes from the specified buffer into this packet's buffer.
*
* @param buffer The source {@link ChannelBuffer}.
* @throws IllegalStateException If the builder is not in byte access mode.
*/
private void checkByteAccess() {
if (mode != AccessMode.BYTE_ACCESS) {
throw new IllegalStateException("For byte-based calls to work, the mode must be byte access");
public void putBytes(ChannelBuffer buffer) {
byte[] bytes = new byte[buffer.readableBytes()];
buffer.markReaderIndex();
try {
buffer.readBytes(bytes);
} finally {
buffer.resetReaderIndex();
}
putBytes(bytes);
}
/**
* Puts the bytes into the buffer with the specified transformation.
*
* @param transformation The transformation.
* @param bytes The byte array.
* @throws IllegalStateException If the builder is not in byte access mode.
*/
public void putBytes(DataTransformation transformation, byte[] bytes) {
if (transformation == DataTransformation.NONE) {
putBytes(bytes);
} else {
for (byte b : bytes) {
put(DataType.BYTE, transformation, b);
}
}
}
/**
* Checks that this builder is in the bit access mode.
* Puts the specified byte array into the buffer in reverse.
*
* @throws IllegalStateException If the builder is not in bit access mode.
* @param bytes The byte array.
* @throws IllegalStateException If the builder is not in byte access mode.
*/
private void checkBitAccess() {
if (mode != AccessMode.BIT_ACCESS) {
throw new IllegalStateException("For bit-based calls to work, the mode must be bit access");
public void putBytesReverse(byte[] bytes) {
checkByteAccess();
for (int i = bytes.length - 1; i >= 0; i--) {
buffer.writeByte(bytes[i]);
}
}
/**
* Puts the bytes from the specified buffer into this packet's buffer, in reverse.
*
* @param buffer The source {@link ChannelBuffer}.
* @throws IllegalStateException If the builder is not in byte access mode.
*/
public void putBytesReverse(ChannelBuffer buffer) {
byte[] bytes = new byte[buffer.readableBytes()];
buffer.markReaderIndex();
try {
buffer.readBytes(bytes);
} finally {
buffer.resetReaderIndex();
}
putBytesReverse(bytes);
}
/**
* Puts the specified byte array into the buffer in reverse with the specified transformation.
*
* @param transformation The transformation.
* @param bytes The byte array.
* @throws IllegalStateException If the builder is not in byte access mode.
*/
public void putBytesReverse(DataTransformation transformation, byte[] bytes) {
if (transformation == DataTransformation.NONE) {
putBytesReverse(bytes);
} else {
for (int i = bytes.length - 1; i >= 0; i--) {
put(DataType.BYTE, transformation, bytes[i]);
}
}
}
/**
* Puts a raw builder. Both builders (this and parameter) must be in byte access mode.
*
* @param builder The builder.
*/
public void putRawBuilder(GamePacketBuilder builder) {
checkByteAccess();
if (builder.type != PacketType.RAW) {
throw new IllegalArgumentException("Builder must be raw!");
}
builder.checkByteAccess();
putBytes(builder.buffer);
}
/**
* Puts a raw builder in reverse. Both builders (this and parameter) must be in byte access mode.
*
* @param builder The builder.
*/
public void putRawBuilderReverse(GamePacketBuilder builder) {
checkByteAccess();
if (builder.type != PacketType.RAW) {
throw new IllegalArgumentException("Builder must be raw!");
}
builder.checkByteAccess();
putBytesReverse(builder.buffer);
}
/**
* Puts a smart into the buffer.
*
* @param value The value.
*/
public void putSmart(int value) {
checkByteAccess();
if (value < 128) {
buffer.writeByte(value);
} else {
buffer.writeShort(value);
}
}
/**
* Puts a string into the buffer.
*
* @param str The string.
*/
public void putString(String str) {
checkByteAccess();
char[] chars = str.toCharArray();
for (char c : chars) {
buffer.writeByte((byte) c);
}
buffer.writeByte(NetworkConstants.STRING_TERMINATOR);
}
/**
* Switches this builder's mode to the bit access mode.
*
* @throws IllegalStateException If the builder is already in bit access mode.
*/
public void switchToBitAccess() {
if (mode == AccessMode.BIT_ACCESS) {
throw new IllegalStateException("Already in bit access mode");
}
mode = AccessMode.BIT_ACCESS;
bitIndex = buffer.writerIndex() * 8;
}
/**
* Switches this builder's mode to the byte access mode.
*
* @throws IllegalStateException If the builder is already in byte access mode.
*/
public void switchToByteAccess() {
if (mode == AccessMode.BYTE_ACCESS) {
throw new IllegalStateException("Already in byte access mode");
}
mode = AccessMode.BYTE_ACCESS;
buffer.writerIndex((bitIndex + 7) / 8);
}
/**
* Creates a {@link GamePacket} based on the current contents of this builder.
*
* @return The {@link GamePacket}.
* @throws IllegalStateException If the builder is not in byte access mode, or if the packet is raw.
*/
public GamePacket toGamePacket() {
if (type == PacketType.RAW) {
throw new IllegalStateException("Raw packets cannot be converted to a game packet");
}
if (mode != AccessMode.BYTE_ACCESS) {
throw new IllegalStateException("Must be in byte access mode to convert to a packet");
}
return new GamePacket(opcode, type, buffer);
}
}
@@ -70,6 +70,27 @@ public final class GamePacketDecoder extends StatefulFrameDecoder<GameDecoderSta
}
}
/**
* Decodes in the length state.
*
* @param ctx The channel handler context.
* @param channel The channel.
* @param buffer The buffer.
* @return The frame, or {@code null}.
* @throws Exception If an error occurs.
*/
private Object decodeLength(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
if (buffer.readable()) {
length = buffer.readUnsignedByte();
if (length == 0) {
return decodeZeroLengthPacket(ctx, channel, buffer);
} else {
setState(GameDecoderState.GAME_PAYLOAD);
}
}
return null;
}
/**
* Decodes in the opcode state.
*
@@ -82,7 +103,7 @@ public final class GamePacketDecoder extends StatefulFrameDecoder<GameDecoderSta
private Object decodeOpcode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
if (buffer.readable()) {
int encryptedOpcode = buffer.readUnsignedByte();
opcode = (encryptedOpcode - random.nextInt()) & 0xFF;
opcode = encryptedOpcode - random.nextInt() & 0xFF;
PacketMetaData metaData = release.getIncomingPacketMetaData(opcode);
if (metaData == null) {
@@ -109,27 +130,6 @@ public final class GamePacketDecoder extends StatefulFrameDecoder<GameDecoderSta
return null;
}
/**
* Decodes in the length state.
*
* @param ctx The channel handler context.
* @param channel The channel.
* @param buffer The buffer.
* @return The frame, or {@code null}.
* @throws Exception If an error occurs.
*/
private Object decodeLength(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
if (buffer.readable()) {
length = buffer.readUnsignedByte();
if (length == 0) {
return decodeZeroLengthPacket(ctx, channel, buffer);
} else {
setState(GameDecoderState.GAME_PAYLOAD);
}
}
return null;
}
/**
* Decodes in the payload state.
*
@@ -53,7 +53,7 @@ public final class GamePacketEncoder extends OneToOneEncoder {
}
ChannelBuffer buffer = ChannelBuffers.buffer(headerLength + payloadLength);
buffer.writeByte((packet.getOpcode() + random.nextInt()) & 0xFF);
buffer.writeByte(packet.getOpcode() + random.nextInt() & 0xFF);
if (type == PacketType.VARIABLE_BYTE) {
buffer.writeByte(payloadLength);
} else if (type == PacketType.VARIABLE_SHORT) {
@@ -35,197 +35,27 @@ public final class GamePacketReader {
}
/**
* Gets the length of this reader.
* Checks that this reader is in the bit access mode.
*
* @return The length of this reader.
* @throws IllegalStateException If the reader is not in bit access mode.
*/
public int getLength() {
checkByteAccess();
return buffer.writableBytes();
}
/**
* Switches this builder's mode to the byte access mode.
*
* @throws IllegalStateException If the builder is already in byte access mode.
*/
public void switchToByteAccess() {
if (mode == AccessMode.BYTE_ACCESS) {
throw new IllegalStateException("Already in byte access mode");
}
mode = AccessMode.BYTE_ACCESS;
buffer.readerIndex((bitIndex + 7) / 8);
}
/**
* Switches this builder's mode to the bit access mode.
*
* @throws IllegalStateException If the builder is already in bit access mode.
*/
public void switchToBitAccess() {
if (mode == AccessMode.BIT_ACCESS) {
throw new IllegalStateException("Already in bit access mode");
}
mode = AccessMode.BIT_ACCESS;
bitIndex = buffer.readerIndex() * 8;
}
/**
* Gets a string from the buffer.
*
* @return The string.
* @throws IllegalStateException If this reader is not in byte access mode.
*/
public String getString() {
checkByteAccess();
return ChannelBufferUtil.readString(buffer);
}
/**
* Gets a signed smart from the buffer.
*
* @return The smart.
* @throws IllegalStateException If this reader is not in byte access mode.
*/
public int getSignedSmart() {
checkByteAccess();
int peek = buffer.getByte(buffer.readerIndex());
if (peek < 128) {
return buffer.readByte() - 64;
} else {
return buffer.readShort() - 49152;
private void checkBitAccess() {
if (mode != AccessMode.BIT_ACCESS) {
throw new IllegalStateException("For bit-based calls to work, the mode must be bit access");
}
}
/**
* Gets an unsigned smart from the buffer.
* Checks that this reader is in the byte access mode.
*
* @return The smart.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalStateException If the reader is not in byte access mode.
*/
public int getUnsignedSmart() {
checkByteAccess();
int peek = buffer.getByte(buffer.readerIndex());
if (peek < 128) {
return buffer.readByte();
} else {
return buffer.readShort() - 32768;
private void checkByteAccess() {
if (mode != AccessMode.BYTE_ACCESS) {
throw new IllegalStateException("For byte-based calls to work, the mode must be byte access");
}
}
/**
* Gets a signed data type from the buffer.
*
* @param type The data type.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
*/
public long getSigned(DataType type) {
return getSigned(type, DataOrder.BIG, DataTransformation.NONE);
}
/**
* Gets a signed data type from the buffer with the specified order.
*
* @param type The data type.
* @param order The byte order.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public long getSigned(DataType type, DataOrder order) {
return getSigned(type, order, DataTransformation.NONE);
}
/**
* Gets a signed data type from the buffer with the specified transformation.
*
* @param type The data type.
* @param transformation The data transformation.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public long getSigned(DataType type, DataTransformation transformation) {
return getSigned(type, DataOrder.BIG, transformation);
}
/**
* Gets a signed data type from the buffer with the specified order and transformation.
*
* @param type The data type.
* @param order The byte order.
* @param transformation The data transformation.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public long getSigned(DataType type, DataOrder order, DataTransformation transformation) {
long longValue = get(type, order, transformation);
if (type != DataType.LONG) {
int max = (int) (Math.pow(2, type.getBytes() * 8 - 1) - 1);
if (longValue > max) {
longValue -= (max + 1) * 2;
}
}
return longValue;
}
/**
* Gets an unsigned data type from the buffer.
*
* @param type The data type.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
*/
public long getUnsigned(DataType type) {
return getUnsigned(type, DataOrder.BIG, DataTransformation.NONE);
}
/**
* Gets an unsigned data type from the buffer with the specified order.
*
* @param type The data type.
* @param order The byte order.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public long getUnsigned(DataType type, DataOrder order) {
return getUnsigned(type, order, DataTransformation.NONE);
}
/**
* Gets an unsigned data type from the buffer with the specified transformation.
*
* @param type The data type.
* @param transformation The data transformation.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public long getUnsigned(DataType type, DataTransformation transformation) {
return getUnsigned(type, DataOrder.BIG, transformation);
}
/**
* Gets an unsigned data type from the buffer with the specified order and transformation.
*
* @param type The data type.
* @param order The byte order.
* @param transformation The data transformation.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public long getUnsigned(DataType type, DataOrder order, DataTransformation transformation) {
long longValue = get(type, order, transformation);
if (type == DataType.LONG) {
throw new IllegalArgumentException("due to java restrictions, longs must be read as signed types");
}
return longValue & 0xFFFFFFFFFFFFFFFFL;
}
/**
* Reads a standard data type from the buffer with the specified order and transformation.
*
@@ -244,32 +74,32 @@ public final class GamePacketReader {
for (int i = length - 1; i >= 0; i--) {
if (i == 0 && transformation != DataTransformation.NONE) {
if (transformation == DataTransformation.ADD) {
longValue |= (buffer.readByte() - 128) & 0xFF;
longValue |= buffer.readByte() - 128 & 0xFF;
} else if (transformation == DataTransformation.NEGATE) {
longValue |= (-buffer.readByte()) & 0xFF;
longValue |= -buffer.readByte() & 0xFF;
} else if (transformation == DataTransformation.SUBTRACT) {
longValue |= (128 - buffer.readByte()) & 0xFF;
longValue |= 128 - buffer.readByte() & 0xFF;
} else {
throw new IllegalArgumentException("unknown transformation");
}
} else {
longValue |= ((buffer.readByte() & 0xFF) << (i * 8));
longValue |= (buffer.readByte() & 0xFF) << i * 8;
}
}
} else if (order == DataOrder.LITTLE) {
for (int i = 0; i < length; i++) {
if (i == 0 && transformation != DataTransformation.NONE) {
if (transformation == DataTransformation.ADD) {
longValue |= (buffer.readByte() - 128) & 0xFF;
longValue |= buffer.readByte() - 128 & 0xFF;
} else if (transformation == DataTransformation.NEGATE) {
longValue |= (-buffer.readByte()) & 0xFF;
longValue |= -buffer.readByte() & 0xFF;
} else if (transformation == DataTransformation.SUBTRACT) {
longValue |= (128 - buffer.readByte()) & 0xFF;
longValue |= 128 - buffer.readByte() & 0xFF;
} else {
throw new IllegalArgumentException("unknown transformation");
}
} else {
longValue |= ((buffer.readByte() & 0xFF) << (i * 8));
longValue |= (buffer.readByte() & 0xFF) << i * 8;
}
}
} else if (order == DataOrder.MIDDLE) {
@@ -300,6 +130,48 @@ public final class GamePacketReader {
return longValue;
}
/**
* Gets a bit from the buffer.
*
* @return The value.
* @throws IllegalStateException If the reader is not in bit access mode.
*/
public int getBit() {
return getBits(1);
}
/**
* Gets {@code numBits} from the buffer.
*
* @param numBits The number of bits.
* @return The value.
* @throws IllegalStateException If the reader is not in bit access mode.
* @throws IllegalArgumentException If the number of bits is not between 1 and 31 inclusive.
*/
public int getBits(int numBits) {
if (numBits < 0 || numBits > 32) {
throw new IllegalArgumentException("Number of bits must be between 1 and 32 inclusive");
}
checkBitAccess();
int bytePos = bitIndex >> 3;
int bitOffset = 8 - (bitIndex & 7);
int value = 0;
bitIndex += numBits;
for (; numBits > bitOffset; bitOffset = 8) {
value += (buffer.getByte(bytePos++) & DataConstants.BIT_MASK[bitOffset]) << numBits - bitOffset;
numBits -= bitOffset;
}
if (numBits == bitOffset) {
value += buffer.getByte(bytePos) & DataConstants.BIT_MASK[bitOffset];
} else {
value += buffer.getByte(bytePos) >> bitOffset - numBits & DataConstants.BIT_MASK[numBits];
}
return value;
}
/**
* Gets bytes.
*
@@ -361,67 +233,195 @@ public final class GamePacketReader {
}
/**
* Checks that this reader is in the byte access mode.
* Gets the length of this reader.
*
* @throws IllegalStateException If the reader is not in byte access mode.
* @return The length of this reader.
*/
private void checkByteAccess() {
if (mode != AccessMode.BYTE_ACCESS) {
throw new IllegalStateException("For byte-based calls to work, the mode must be byte access");
}
public int getLength() {
checkByteAccess();
return buffer.writableBytes();
}
/**
* Checks that this reader is in the bit access mode.
*
* @throws IllegalStateException If the reader is not in bit access mode.
*/
private void checkBitAccess() {
if (mode != AccessMode.BIT_ACCESS) {
throw new IllegalStateException("For bit-based calls to work, the mode must be bit access");
}
}
/**
* Gets a bit from the buffer.
* Gets a signed data type from the buffer.
*
* @param type The data type.
* @return The value.
* @throws IllegalStateException If the reader is not in bit access mode.
* @throws IllegalStateException If this reader is not in byte access mode.
*/
public int getBit() {
return getBits(1);
public long getSigned(DataType type) {
return getSigned(type, DataOrder.BIG, DataTransformation.NONE);
}
/**
* Gets {@code numBits} from the buffer.
* Gets a signed data type from the buffer with the specified order.
*
* @param numBits The number of bits.
* @param type The data type.
* @param order The byte order.
* @return The value.
* @throws IllegalStateException If the reader is not in bit access mode.
* @throws IllegalArgumentException If the number of bits is not between 1 and 31 inclusive.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public int getBits(int numBits) {
if (numBits < 0 || numBits > 32) {
throw new IllegalArgumentException("Number of bits must be between 1 and 32 inclusive");
public long getSigned(DataType type, DataOrder order) {
return getSigned(type, order, DataTransformation.NONE);
}
/**
* Gets a signed data type from the buffer with the specified order and transformation.
*
* @param type The data type.
* @param order The byte order.
* @param transformation The data transformation.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public long getSigned(DataType type, DataOrder order, DataTransformation transformation) {
long longValue = get(type, order, transformation);
if (type != DataType.LONG) {
int max = (int) (Math.pow(2, type.getBytes() * 8 - 1) - 1);
if (longValue > max) {
longValue -= (max + 1) * 2;
}
}
return longValue;
}
checkBitAccess();
/**
* Gets a signed data type from the buffer with the specified transformation.
*
* @param type The data type.
* @param transformation The data transformation.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public long getSigned(DataType type, DataTransformation transformation) {
return getSigned(type, DataOrder.BIG, transformation);
}
int bytePos = bitIndex >> 3;
int bitOffset = 8 - (bitIndex & 7);
int value = 0;
bitIndex += numBits;
for (; numBits > bitOffset; bitOffset = 8) {
value += (buffer.getByte(bytePos++) & DataConstants.BIT_MASK[bitOffset]) << numBits - bitOffset;
numBits -= bitOffset;
}
if (numBits == bitOffset) {
value += buffer.getByte(bytePos) & DataConstants.BIT_MASK[bitOffset];
/**
* Gets a signed smart from the buffer.
*
* @return The smart.
* @throws IllegalStateException If this reader is not in byte access mode.
*/
public int getSignedSmart() {
checkByteAccess();
int peek = buffer.getByte(buffer.readerIndex());
if (peek < 128) {
return buffer.readByte() - 64;
} else {
value += buffer.getByte(bytePos) >> bitOffset - numBits & DataConstants.BIT_MASK[numBits];
return buffer.readShort() - 49152;
}
return value;
}
/**
* Gets a string from the buffer.
*
* @return The string.
* @throws IllegalStateException If this reader is not in byte access mode.
*/
public String getString() {
checkByteAccess();
return ChannelBufferUtil.readString(buffer);
}
/**
* Gets an unsigned data type from the buffer.
*
* @param type The data type.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
*/
public long getUnsigned(DataType type) {
return getUnsigned(type, DataOrder.BIG, DataTransformation.NONE);
}
/**
* Gets an unsigned data type from the buffer with the specified order.
*
* @param type The data type.
* @param order The byte order.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public long getUnsigned(DataType type, DataOrder order) {
return getUnsigned(type, order, DataTransformation.NONE);
}
/**
* Gets an unsigned data type from the buffer with the specified order and transformation.
*
* @param type The data type.
* @param order The byte order.
* @param transformation The data transformation.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public long getUnsigned(DataType type, DataOrder order, DataTransformation transformation) {
long longValue = get(type, order, transformation);
if (type == DataType.LONG) {
throw new IllegalArgumentException("due to java restrictions, longs must be read as signed types");
}
return longValue & 0xFFFFFFFFFFFFFFFFL;
}
/**
* Gets an unsigned data type from the buffer with the specified transformation.
*
* @param type The data type.
* @param transformation The data transformation.
* @return The value.
* @throws IllegalStateException If this reader is not in byte access mode.
* @throws IllegalArgumentException If the combination is invalid.
*/
public long getUnsigned(DataType type, DataTransformation transformation) {
return getUnsigned(type, DataOrder.BIG, transformation);
}
/**
* Gets an unsigned smart from the buffer.
*
* @return The smart.
* @throws IllegalStateException If this reader is not in byte access mode.
*/
public int getUnsignedSmart() {
checkByteAccess();
int peek = buffer.getByte(buffer.readerIndex());
if (peek < 128) {
return buffer.readByte();
} else {
return buffer.readShort() - 32768;
}
}
/**
* Switches this builder's mode to the bit access mode.
*
* @throws IllegalStateException If the builder is already in bit access mode.
*/
public void switchToBitAccess() {
if (mode == AccessMode.BIT_ACCESS) {
throw new IllegalStateException("Already in bit access mode");
}
mode = AccessMode.BIT_ACCESS;
bitIndex = buffer.readerIndex() * 8;
}
/**
* Switches this builder's mode to the byte access mode.
*
* @throws IllegalStateException If the builder is already in byte access mode.
*/
public void switchToByteAccess() {
if (mode == AccessMode.BYTE_ACCESS) {
throw new IllegalStateException("Already in byte access mode");
}
mode = AccessMode.BYTE_ACCESS;
buffer.readerIndex((bitIndex + 7) / 8);
}
}
@@ -14,7 +14,7 @@ public final class JagGrabRequestDecoder extends OneToOneDecoder {
@Override
protected Object decode(ChannelHandlerContext ctx, Channel c, Object msg) throws Exception {
if (msg instanceof String) {
String str = ((String) msg);
String str = (String) msg;
if (str.startsWith("JAGGRAB /")) {
String filePath = str.substring(8).trim();
return new JagGrabRequest(filePath);
@@ -150,7 +150,7 @@ public final class LoginDecoder extends StatefulFrameDecoder<LoginDecoderState>
}
int securePayloadLength = payload.readUnsignedByte();
if (securePayloadLength != (loginLength - 41)) {
if (securePayloadLength != loginLength - 41) {
throw new Exception("Secure payload length mismatch");
}
@@ -60,6 +60,15 @@ public final class LoginRequest {
this.archiveCrcs = archiveCrcs;
}
/**
* Gets the archive CRCs.
*
* @return The array of archive CRCs.
*/
public int[] getArchiveCrcs() {
return archiveCrcs;
}
/**
* Gets the player's credentials.
*
@@ -78,6 +87,15 @@ public final class LoginRequest {
return randomPair;
}
/**
* Gets the release number.
*
* @return The release number.
*/
public int getReleaseNumber() {
return releaseNumber;
}
/**
* Checks if this client is in low memory mode.
*
@@ -96,22 +114,4 @@ public final class LoginRequest {
return reconnecting;
}
/**
* Gets the release number.
*
* @return The release number.
*/
public int getReleaseNumber() {
return releaseNumber;
}
/**
* Gets the archive CRCs.
*
* @return The array of archive CRCs.
*/
public int[] getArchiveCrcs() {
return archiveCrcs;
}
}
@@ -35,6 +35,15 @@ public final class LoginResponse {
this.flagged = flagged;
}
/**
* Gets the rights level.
*
* @return The rights level.
*/
public int getRights() {
return rights;
}
/**
* Gets the status.
*
@@ -53,13 +62,4 @@ public final class LoginResponse {
return flagged;
}
/**
* Gets the rights level.
*
* @return The rights level.
*/
public int getRights() {
return rights;
}
}
@@ -98,6 +98,20 @@ public final class OnDemandRequest implements Comparable<OnDemandRequest> {
this.priority = priority;
}
@Override
public int compareTo(OnDemandRequest o) {
int thisPriority = priority.toInteger();
int otherPriority = o.priority.toInteger();
if (thisPriority < otherPriority) {
return 1;
} else if (thisPriority == otherPriority) {
return 0;
} else {
return -1;
}
}
/**
* Gets the file descriptor.
*
@@ -116,18 +130,4 @@ public final class OnDemandRequest implements Comparable<OnDemandRequest> {
return priority;
}
@Override
public int compareTo(OnDemandRequest o) {
int thisPriority = priority.toInteger();
int otherPriority = o.priority.toInteger();
if (thisPriority < otherPriority) {
return 1;
} else if (thisPriority == otherPriority) {
return 0;
} else {
return -1;
}
}
}
@@ -45,6 +45,24 @@ public final class OnDemandResponse {
this.chunkData = chunkData;
}
/**
* Gets the chunk data.
*
* @return The chunk data.
*/
public ChannelBuffer getChunkData() {
return chunkData;
}
/**
* Gets the chunk id.
*
* @return The chunk id.
*/
public int getChunkId() {
return chunkId;
}
/**
* Gets the file descriptor.
*
@@ -63,22 +81,4 @@ public final class OnDemandResponse {
return fileSize;
}
/**
* Gets the chunk id.
*
* @return The chunk id.
*/
public int getChunkId() {
return chunkId;
}
/**
* Gets the chunk data.
*
* @return The chunk data.
*/
public ChannelBuffer getChunkData() {
return chunkData;
}
}
+9 -9
View File
@@ -61,15 +61,6 @@ public final class PacketMetaData {
this.length = length;
}
/**
* Gets the type of packet.
*
* @return The type of packet.
*/
public PacketType getType() {
return type;
}
/**
* Gets the length of this packet.
*
@@ -83,4 +74,13 @@ public final class PacketMetaData {
return length;
}
/**
* Gets the type of packet.
*
* @return The type of packet.
*/
public PacketType getType() {
return type;
}
}
+42 -42
View File
@@ -45,48 +45,6 @@ public abstract class Release {
this.incomingPacketMetaData = incomingPacketMetaData;
}
/**
* Gets the release number.
*
* @return The release number.
*/
public final int getReleaseNumber() {
return releaseNumber;
}
/**
* Registers a {@link EventDecoder} for the specified opcode.
*
* @param opcode The opcode, between 0 and 255 inclusive.
* @param decoder The {@link EventDecoder}.
*/
public final <E extends Event> void register(int opcode, EventDecoder<E> decoder) {
if (opcode < 0 || opcode >= decoders.length) {
throw new IndexOutOfBoundsException();
}
decoders[opcode] = decoder;
}
/**
* Registers a {@link EventEncoder} for the specified event type.
*
* @param type The event type.
* @param encoder The {@link EventEncoder}.
*/
public final <E extends Event> void register(Class<E> type, EventEncoder<E> encoder) {
encoders.put(type, encoder);
}
/**
* Gets meta data for the specified incoming packet.
*
* @param opcode The opcode of the incoming packet.
* @return The {@link PacketMetaData} object.
*/
public final PacketMetaData getIncomingPacketMetaData(int opcode) {
return incomingPacketMetaData.getMetaData(opcode);
}
/**
* Gets the {@link EventDecoder} for the specified opcode.
*
@@ -111,4 +69,46 @@ public abstract class Release {
return (EventEncoder<E>) encoders.get(type);
}
/**
* Gets meta data for the specified incoming packet.
*
* @param opcode The opcode of the incoming packet.
* @return The {@link PacketMetaData} object.
*/
public final PacketMetaData getIncomingPacketMetaData(int opcode) {
return incomingPacketMetaData.getMetaData(opcode);
}
/**
* Gets the release number.
*
* @return The release number.
*/
public final int getReleaseNumber() {
return releaseNumber;
}
/**
* Registers a {@link EventEncoder} for the specified event type.
*
* @param type The event type.
* @param encoder The {@link EventEncoder}.
*/
public final <E extends Event> void register(Class<E> type, EventEncoder<E> encoder) {
encoders.put(type, encoder);
}
/**
* Registers a {@link EventDecoder} for the specified opcode.
*
* @param opcode The opcode, between 0 and 255 inclusive.
* @param decoder The {@link EventDecoder}.
*/
public final <E extends Event> void register(int opcode, EventDecoder<E> decoder) {
if (opcode < 0 || opcode >= decoders.length) {
throw new IndexOutOfBoundsException();
}
decoders[opcode] = decoder;
}
}
@@ -16,6 +16,7 @@ import org.apollo.net.release.EventDecoder;
*/
public final class FirstObjectActionEventDecoder extends EventDecoder<FirstObjectActionEvent> {
@Override
public FirstObjectActionEvent decode(GamePacket packet) {
GamePacketReader reader = new GamePacketReader(packet);
int x = (int) reader.getUnsigned(DataType.SHORT, DataOrder.LITTLE, DataTransformation.ADD);
@@ -2,15 +2,15 @@ package org.apollo.net.release.r317;
import org.apollo.game.event.impl.PlayerSynchronizationEvent;
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.Appearance;
import org.apollo.game.model.EquipmentConstants;
import org.apollo.game.sync.block.AnimationBlock;
import org.apollo.game.sync.block.AppearanceBlock;
import org.apollo.game.sync.block.ChatBlock;
@@ -86,8 +86,7 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
* @param event The event.
* @param builder The builder.
*/
private void putAddCharacterUpdate(AddPlayerSegment seg, PlayerSynchronizationEvent event,
GamePacketBuilder builder) {
private void putAddCharacterUpdate(AddPlayerSegment seg, PlayerSynchronizationEvent event, GamePacketBuilder builder) {
boolean updateRequired = seg.getBlockSet().size() > 0;
Position player = event.getPosition();
Position other = seg.getPosition();
@@ -26,8 +26,7 @@ public final class UpdateItemsEventEncoder extends EventEncoder<UpdateItemsEvent
builder.put(DataType.SHORT, event.getInterfaceId());
builder.put(DataType.SHORT, items.length);
for (int i = 0; i < items.length; i++) {
Item item = items[i];
for (Item item : items) {
int id = item == null ? -1 : item.getId();
int amount = item == null ? 0 : item.getAmount();
@@ -2,15 +2,15 @@ package org.apollo.net.release.r377;
import org.apollo.game.event.impl.PlayerSynchronizationEvent;
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.Appearance;
import org.apollo.game.model.EquipmentConstants;
import org.apollo.game.sync.block.AnimationBlock;
import org.apollo.game.sync.block.AppearanceBlock;
import org.apollo.game.sync.block.ChatBlock;
@@ -86,8 +86,7 @@ public final class PlayerSynchronizationEventEncoder extends EventEncoder<Player
* @param event The event.
* @param builder The builder.
*/
private void putAddCharacterUpdate(AddPlayerSegment seg, PlayerSynchronizationEvent event,
GamePacketBuilder builder) {
private void putAddCharacterUpdate(AddPlayerSegment seg, PlayerSynchronizationEvent event, GamePacketBuilder builder) {
boolean updateRequired = seg.getBlockSet().size() > 0;
Position player = event.getPosition();
Position other = seg.getPosition();
@@ -26,8 +26,7 @@ public final class UpdateItemsEventEncoder extends EventEncoder<UpdateItemsEvent
builder.put(DataType.SHORT, event.getInterfaceId());
builder.put(DataType.SHORT, items.length);
for (int i = 0; i < items.length; i++) {
Item item = items[i];
for (Item item : items) {
int id = item == null ? -1 : item.getId();
int amount = item == null ? 0 : item.getAmount();
+10 -10
View File
@@ -9,8 +9,8 @@ import org.apollo.ServerContext;
import org.apollo.game.GameConstants;
import org.apollo.game.GameService;
import org.apollo.game.event.Event;
import org.apollo.game.event.handler.chain.EventHandlerChainGroup;
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;
@@ -58,13 +58,8 @@ public final class GameSession extends Session {
}
@Override
public void messageReceived(Object message) throws Exception {
Event event = (Event) message;
if (eventQueue.size() >= GameConstants.EVENTS_PER_PULSE) {
logger.warning("Too many events in queue for game session, dropping...");
} else {
eventQueue.add(event);
}
public void destroy() throws Exception {
context.getService(GameService.class).unregisterPlayer(player);
}
/**
@@ -127,8 +122,13 @@ public final class GameSession extends Session {
}
@Override
public void destroy() throws Exception {
context.getService(GameService.class).unregisterPlayer(player);
public void messageReceived(Object message) throws Exception {
Event event = (Event) message;
if (eventQueue.size() >= GameConstants.EVENTS_PER_PULSE) {
logger.warning("Too many events in queue for game session, dropping...");
} else {
eventQueue.add(event);
}
}
}
+6 -6
View File
@@ -52,10 +52,8 @@ public final class LoginSession extends Session {
}
@Override
public void messageReceived(Object message) throws Exception {
if (message.getClass() == LoginRequest.class) {
handleLoginRequest((LoginRequest) message);
}
public void destroy() {
}
/**
@@ -135,8 +133,10 @@ public final class LoginSession extends Session {
}
@Override
public void destroy() {
public void messageReceived(Object message) throws Exception {
if (message.getClass() == LoginRequest.class) {
handleLoginRequest((LoginRequest) message);
}
}
}
+7 -7
View File
@@ -24,6 +24,13 @@ public abstract class Session {
this.channel = channel;
}
/**
* Destroys this session.
*
* @throws Exception If an error occurs.
*/
public abstract void destroy() throws Exception;
/**
* Gets the channel.
*
@@ -41,11 +48,4 @@ public abstract class Session {
*/
public abstract void messageReceived(Object message) throws Exception;
/**
* Destroys this session.
*
* @throws Exception If an error occurs.
*/
public abstract void destroy() throws Exception;
}
@@ -31,6 +31,11 @@ public final class UpdateSession extends Session {
this.context = context;
}
@Override
public void destroy() throws Exception {
// TODO implement
}
@Override
public void messageReceived(Object message) throws Exception {
UpdateDispatcher dispatcher = context.getService(UpdateService.class).getDispatcher();
@@ -45,9 +50,4 @@ public final class UpdateSession extends Session {
}
}
@Override
public void destroy() throws Exception {
// TODO implement
}
}
+9 -9
View File
@@ -31,15 +31,6 @@ public final class IsaacRandomPair {
this.decodingRandom = decodingRandom;
}
/**
* Gets the random number generator used for encoding.
*
* @return The random number generator used for encoding.
*/
public IsaacRandom getEncodingRandom() {
return encodingRandom;
}
/**
* Gets the random number generator used for decoding.
*
@@ -49,4 +40,13 @@ public final class IsaacRandomPair {
return decodingRandom;
}
/**
* Gets the random number generator used for encoding.
*
* @return The random number generator used for encoding.
*/
public IsaacRandom getEncodingRandom() {
return encodingRandom;
}
}
+19 -19
View File
@@ -44,21 +44,12 @@ public final class PlayerCredentials {
*/
public PlayerCredentials(String username, String password, int usernameHash, int uid) {
this.username = username;
this.encodedUsername = NameUtil.encodeBase37(username);
encodedUsername = NameUtil.encodeBase37(username);
this.password = password;
this.usernameHash = usernameHash;
this.uid = uid;
}
/**
* Gets the player's username.
*
* @return The player's username.
*/
public String getUsername() {
return username;
}
/**
* Gets the player's username encoded as a long.
*
@@ -77,15 +68,6 @@ public final class PlayerCredentials {
return password;
}
/**
* Gets the username hash.
*
* @return The username hash.
*/
public int getUsernameHash() {
return usernameHash;
}
/**
* Gets the computer's uid.
*
@@ -95,4 +77,22 @@ public final class PlayerCredentials {
return uid;
}
/**
* Gets the player's username.
*
* @return The player's username.
*/
public String getUsername() {
return username;
}
/**
* Gets the username hash.
*
* @return The username hash.
*/
public int getUsernameHash() {
return usernameHash;
}
}
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -31,6 +31,15 @@ public final class ChannelRequest<T> implements Comparable<ChannelRequest<T>> {
this.request = request;
}
@SuppressWarnings("unchecked")
@Override
public int compareTo(ChannelRequest<T> o) {
if (request instanceof Comparable<?> && o.request instanceof Comparable<?>) {
return ((Comparable<T>) request).compareTo(o.request);
}
return 0;
}
/**
* Gets the channel.
*
@@ -49,13 +58,4 @@ public final class ChannelRequest<T> implements Comparable<ChannelRequest<T>> {
return request;
}
@SuppressWarnings("unchecked")
@Override
public int compareTo(ChannelRequest<T> o) {
if (request instanceof Comparable<?> && o.request instanceof Comparable<?>) {
return ((Comparable<T>) request).compareTo(o.request);
}
return 0;
}
}
+53 -53
View File
@@ -53,6 +53,59 @@ public final class HttpRequestWorker extends RequestWorker<HttpRequest, Resource
WWW_DIRECTORY)));
}
/**
* Creates an error page.
*
* @param status The HTTP status.
* @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();
StringBuilder bldr = new StringBuilder();
bldr.append("<!DOCTYPE html><html><head><title>");
bldr.append(title);
bldr.append("</title></head><body><h1>");
bldr.append(title);
bldr.append("</h1><p>");
bldr.append(description);
bldr.append("</p><hr /><address>");
bldr.append(SERVER_IDENTIFIER);
bldr.append(" Server</address></body></html>");
return ChannelBuffers.copiedBuffer(bldr.toString(), Charset.defaultCharset());
}
/**
* Gets the MIME type of a file by its name.
*
* @param name The file name.
* @return The MIME type.
*/
private String getMimeType(String name) {
if (name.endsWith("/")) {
name = name.concat("index.html");
}
if (name.endsWith(".htm") || name.endsWith(".html")) {
return "text/html";
} else if (name.endsWith(".css")) {
return "text/css";
} else if (name.endsWith(".js")) {
return "text/javascript";
} else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) {
return "image/jpeg";
} else if (name.endsWith(".gif")) {
return "image/gif";
} else if (name.endsWith(".png")) {
return "image/png";
} else if (name.endsWith(".txt")) {
return "text/plain";
}
return "application/octect-stream";
}
@Override
protected ChannelRequest<HttpRequest> nextRequest(UpdateDispatcher dispatcher) throws InterruptedException {
return dispatcher.nextHttpRequest();
@@ -92,57 +145,4 @@ public final class HttpRequestWorker extends RequestWorker<HttpRequest, Resource
channel.write(resp).addListener(ChannelFutureListener.CLOSE);
}
/**
* Gets the MIME type of a file by its name.
*
* @param name The file name.
* @return The MIME type.
*/
private String getMimeType(String name) {
if (name.endsWith("/")) {
name = name.concat("index.html");
}
if (name.endsWith(".htm") || name.endsWith(".html")) {
return "text/html";
} else if (name.endsWith(".css")) {
return "text/css";
} else if (name.endsWith(".js")) {
return "text/javascript";
} else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) {
return "image/jpeg";
} else if (name.endsWith(".gif")) {
return "image/gif";
} else if (name.endsWith(".png")) {
return "image/png";
} else if (name.endsWith(".txt")) {
return "text/plain";
}
return "application/octect-stream";
}
/**
* Creates an error page.
*
* @param status The HTTP status.
* @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();
StringBuilder bldr = new StringBuilder();
bldr.append("<!DOCTYPE html><html><head><title>");
bldr.append(title);
bldr.append("</title></head><body><h1>");
bldr.append(title);
bldr.append("</h1><p>");
bldr.append(description);
bldr.append("</p><hr /><address>");
bldr.append(SERVER_IDENTIFIER);
bldr.append(" Server</address></body></html>");
return ChannelBuffers.copiedBuffer(bldr.toString(), Charset.defaultCharset());
}
}
+15 -15
View File
@@ -40,13 +40,13 @@ public abstract class RequestWorker<T, P> implements Runnable {
}
/**
* Stops this worker. The worker's thread may need to be interrupted.
* Gets the next request.
*
* @param dispatcher The dispatcher.
* @return The next request.
* @throws InterruptedException If the thread is interrupted.
*/
public final void stop() {
synchronized (this) {
running = false;
}
}
protected abstract ChannelRequest<T> nextRequest(UpdateDispatcher dispatcher) throws InterruptedException;
@Override
public final void run() {
@@ -75,15 +75,6 @@ public abstract class RequestWorker<T, P> implements Runnable {
}
}
/**
* Gets the next request.
*
* @param dispatcher The dispatcher.
* @return The next request.
* @throws InterruptedException If the thread is interrupted.
*/
protected abstract ChannelRequest<T> nextRequest(UpdateDispatcher dispatcher) throws InterruptedException;
/**
* Services a request.
*
@@ -94,4 +85,13 @@ public abstract class RequestWorker<T, P> implements Runnable {
*/
protected abstract void service(P provider, Channel channel, T request) throws IOException;
/**
* Stops this worker. The worker's thread may need to be interrupted.
*/
public final void stop() {
synchronized (this) {
running = false;
}
}
}
+38 -38
View File
@@ -37,46 +37,16 @@ public final class UpdateDispatcher {
private final BlockingQueue<ChannelRequest<HttpRequest>> httpQueue = new LinkedBlockingQueue<ChannelRequest<HttpRequest>>();
/**
* Gets the next 'on-demand' request from the queue, blocking if none are available.
*
* @return The 'on-demand' request.
* @throws InterruptedException If the thread is interrupted.
*/
ChannelRequest<OnDemandRequest> nextOnDemandRequest() throws InterruptedException {
return onDemandQueue.take();
}
/**
* Gets the next JAGGRAB request from the queue, blocking if none are available.
*
* @return The JAGGRAB request.
* @throws InterruptedException If the thread is interrupted.
*/
ChannelRequest<JagGrabRequest> nextJagGrabRequest() throws InterruptedException {
return jagGrabQueue.take();
}
/**
* Gets the next HTTP request from the queue, blocking if none are available.
*
* @return The HTTP request.
* @throws InterruptedException If the thread is interrupted.
*/
ChannelRequest<HttpRequest> nextHttpRequest() throws InterruptedException {
return httpQueue.take();
}
/**
* Dispatches an 'on-demand' request.
* Dispatches a HTTP request.
*
* @param channel The channel.
* @param request The request.
*/
public void dispatch(Channel channel, OnDemandRequest request) {
if (onDemandQueue.size() >= MAXIMUM_QUEUE_SIZE) {
public void dispatch(Channel channel, HttpRequest request) {
if (httpQueue.size() >= MAXIMUM_QUEUE_SIZE) {
channel.close();
}
onDemandQueue.add(new ChannelRequest<OnDemandRequest>(channel, request));
httpQueue.add(new ChannelRequest<HttpRequest>(channel, request));
}
/**
@@ -93,16 +63,46 @@ public final class UpdateDispatcher {
}
/**
* Dispatches a HTTP request.
* Dispatches an 'on-demand' request.
*
* @param channel The channel.
* @param request The request.
*/
public void dispatch(Channel channel, HttpRequest request) {
if (httpQueue.size() >= MAXIMUM_QUEUE_SIZE) {
public void dispatch(Channel channel, OnDemandRequest request) {
if (onDemandQueue.size() >= MAXIMUM_QUEUE_SIZE) {
channel.close();
}
httpQueue.add(new ChannelRequest<HttpRequest>(channel, request));
onDemandQueue.add(new ChannelRequest<OnDemandRequest>(channel, request));
}
/**
* Gets the next HTTP request from the queue, blocking if none are available.
*
* @return The HTTP request.
* @throws InterruptedException If the thread is interrupted.
*/
ChannelRequest<HttpRequest> nextHttpRequest() throws InterruptedException {
return httpQueue.take();
}
/**
* Gets the next JAGGRAB request from the queue, blocking if none are available.
*
* @return The JAGGRAB request.
* @throws InterruptedException If the thread is interrupted.
*/
ChannelRequest<JagGrabRequest> nextJagGrabRequest() throws InterruptedException {
return jagGrabQueue.take();
}
/**
* Gets the next 'on-demand' request from the queue, blocking if none are available.
*
* @return The 'on-demand' request.
* @throws InterruptedException If the thread is interrupted.
*/
ChannelRequest<OnDemandRequest> nextOnDemandRequest() throws InterruptedException {
return onDemandQueue.take();
}
}
+1 -1
View File
@@ -47,7 +47,7 @@ public final class ByteBufferUtil {
* @return The tri byte.
*/
public static int readUnsignedTriByte(ByteBuffer buffer) {
return ((buffer.get() & 0xFF) << 16) | ((buffer.get() & 0xFF) << 8) | (buffer.get() & 0xFF);
return (buffer.get() & 0xFF) << 16 | (buffer.get() & 0xFF) << 8 | buffer.get() & 0xFF;
}
/**
+1 -1
View File
@@ -20,7 +20,7 @@ public final class ChannelBufferUtil {
public static String readString(ChannelBuffer buffer) {
StringBuilder builder = new StringBuilder();
int character;
while (buffer.readable() && ((character = buffer.readUnsignedByte()) != NetworkConstants.STRING_TERMINATOR)) {
while (buffer.readable() && (character = buffer.readUnsignedByte()) != NetworkConstants.STRING_TERMINATOR) {
builder.append((char) character);
}
return builder.toString();
+109 -109
View File
@@ -13,115 +13,6 @@ import org.apollo.game.model.Character;
*/
public final class CharacterRepository<T extends Character> implements Iterable<T> {
/**
* The array of characters in this repository.
*/
private final Character[] characters;
/**
* The current size of this repository.
*/
private int size = 0;
/**
* The position of the next free index.
*/
private int pointer = 0;
/**
* Creates a new character repository with the specified capacity.
*
* @param capacity The maximum number of characters that can be present in the repository.
*/
public CharacterRepository(int capacity) {
this.characters = new Character[capacity];
}
/**
* Gets the size of this repository.
*
* @return The number of characters in this repository.
*/
public int size() {
return size;
}
/**
* Gets the capacity of this repository.
*
* @return The maximum size of this repository.
*/
public int capacity() {
return characters.length;
}
/**
* Adds a character to the repository.
*
* @param character The character to add.
* @return {@code true} if the character was added, {@code false} if the size has reached the capacity of this
* repository.
*/
public boolean add(T character) {
if (size == characters.length) {
return false;
}
int index = -1;
for (int i = pointer; i < characters.length; i++) {
if (characters[i] == null) {
index = i;
break;
}
}
if (index == -1) {
for (int i = 0; i < pointer; i++) {
if (characters[i] == null) {
index = i;
break;
}
}
}
if (index == -1) {
return false; // shouldn't happen, but just in case
}
characters[index] = character;
character.setIndex(index + 1);
if (index == (characters.length - 1)) {
pointer = 0;
} else {
pointer = index;
}
size++;
return true;
}
/**
* Removes a character from the repository.
*
* @param character The character to remove.
* @return {@code true} if the character was removed, {@code false} if it was not (e.g. if it was never added or has
* been removed already).
*/
public boolean remove(T character) {
int index = character.getIndex() - 1;
if (index < 0 || index >= characters.length) {
return false;
}
if (characters[index] == character) {
characters[index] = null;
character.setIndex(-1);
size--;
return true;
} else {
return false;
}
}
@Override
public Iterator<T> iterator() {
return new CharacterRepositoryIterator();
}
/**
* The {@link Iterator} implementation for the {@link CharacterRepository} class.
*
@@ -181,4 +72,113 @@ public final class CharacterRepository<T extends Character> implements Iterable<
}
/**
* The array of characters in this repository.
*/
private final Character[] characters;
/**
* The current size of this repository.
*/
private int size = 0;
/**
* The position of the next free index.
*/
private int pointer = 0;
/**
* Creates a new character repository with the specified capacity.
*
* @param capacity The maximum number of characters that can be present in the repository.
*/
public CharacterRepository(int capacity) {
this.characters = new Character[capacity];
}
/**
* Adds a character to the repository.
*
* @param character The character to add.
* @return {@code true} if the character was added, {@code false} if the size has reached the capacity of this
* repository.
*/
public boolean add(T character) {
if (size == characters.length) {
return false;
}
int index = -1;
for (int i = pointer; i < characters.length; i++) {
if (characters[i] == null) {
index = i;
break;
}
}
if (index == -1) {
for (int i = 0; i < pointer; i++) {
if (characters[i] == null) {
index = i;
break;
}
}
}
if (index == -1) {
return false; // shouldn't happen, but just in case
}
characters[index] = character;
character.setIndex(index + 1);
if (index == characters.length - 1) {
pointer = 0;
} else {
pointer = index;
}
size++;
return true;
}
/**
* Gets the capacity of this repository.
*
* @return The maximum size of this repository.
*/
public int capacity() {
return characters.length;
}
@Override
public Iterator<T> iterator() {
return new CharacterRepositoryIterator();
}
/**
* Removes a character from the repository.
*
* @param character The character to remove.
* @return {@code true} if the character was removed, {@code false} if it was not (e.g. if it was never added or has
* been removed already).
*/
public boolean remove(T character) {
int index = character.getIndex() - 1;
if (index < 0 || index >= characters.length) {
return false;
}
if (characters[index] == character) {
characters[index] = null;
character.setIndex(-1);
size--;
return true;
} else {
return false;
}
}
/**
* Gets the size of this repository.
*
* @return The number of characters in this repository.
*/
public int size() {
return size;
}
}

Some files were not shown because too many files have changed in this diff Show More