diff --git a/cache/src/main/org/apollo/cache/decoder/ItemDefinitionDecoder.java b/cache/src/main/org/apollo/cache/decoder/ItemDefinitionDecoder.java index ae3fb8e9..d7d495c2 100644 --- a/cache/src/main/org/apollo/cache/decoder/ItemDefinitionDecoder.java +++ b/cache/src/main/org/apollo/cache/decoder/ItemDefinitionDecoder.java @@ -1,6 +1,7 @@ package org.apollo.cache.decoder; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.ByteBuffer; import org.apollo.cache.IndexedFileSystem; @@ -13,47 +14,46 @@ import org.apollo.util.BufferUtil; * * @author Graham */ -public final class ItemDefinitionDecoder { +public final class ItemDefinitionDecoder implements Runnable { /** - * The {@link IndexedFileSystem}. + * The IndexedFileSystem. */ private final IndexedFileSystem fs; /** - * Creates the item definition decoder. + * Creates the ItemDefinitionDecoder. * - * @param fs The indexed file system. + * @param fs The {@link IndexedFileSystem}. */ public ItemDefinitionDecoder(IndexedFileSystem fs) { this.fs = fs; } - /** - * Decodes the item definitions. - * - * @return The item definitions. - * @throws IOException If an I/O error occurs. - */ - public ItemDefinition[] decode() throws IOException { - Archive config = fs.getArchive(0, 2); - ByteBuffer data = config.getEntry("obj.dat").getBuffer(); - ByteBuffer idx = config.getEntry("obj.idx").getBuffer(); + @Override + public void run() { + try { + Archive config = fs.getArchive(0, 2); + ByteBuffer data = config.getEntry("obj.dat").getBuffer(); + ByteBuffer idx = config.getEntry("obj.idx").getBuffer(); - int count = idx.getShort(), index = 2; - int[] indices = new int[count]; - for (int i = 0; i < count; i++) { - indices[i] = index; - index += idx.getShort(); + int count = idx.getShort(), index = 2; + int[] indices = new int[count]; + for (int i = 0; i < count; i++) { + indices[i] = index; + index += idx.getShort(); + } + + ItemDefinition[] definitions = new ItemDefinition[count]; + for (int i = 0; i < count; i++) { + data.position(indices[i]); + definitions[i] = decode(i, data); + } + + ItemDefinition.init(definitions); + } catch (IOException e) { + throw new UncheckedIOException("Error decoding ItemDefinitions.", e); } - - ItemDefinition[] defs = new ItemDefinition[count]; - for (int i = 0; i < count; i++) { - data.position(indices[i]); - defs[i] = decode(i, data); - } - - return defs; } /** diff --git a/cache/src/main/org/apollo/cache/decoder/MapFileDecoder.java b/cache/src/main/org/apollo/cache/decoder/MapFileDecoder.java index d1c94812..6b3d6425 100644 --- a/cache/src/main/org/apollo/cache/decoder/MapFileDecoder.java +++ b/cache/src/main/org/apollo/cache/decoder/MapFileDecoder.java @@ -121,12 +121,12 @@ public final class MapFileDecoder { int count = buffer.capacity() / (3 * Short.BYTES + Byte.BYTES); for (int times = 0; times < count; times++) { - int packed = buffer.getShort() & 0xFFFF; + int id = buffer.getShort() & 0xFFFF; int terrain = buffer.getShort() & 0xFFFF; int objects = buffer.getShort() & 0xFFFF; boolean members = buffer.get() == 1; - definitions.put(packed, new MapDefinition(packed, terrain, objects, members)); + definitions.put(id, new MapDefinition(id, terrain, objects, members)); } return definitions; diff --git a/cache/src/main/org/apollo/cache/decoder/NpcDefinitionDecoder.java b/cache/src/main/org/apollo/cache/decoder/NpcDefinitionDecoder.java index b67ae28f..89ddc8c3 100644 --- a/cache/src/main/org/apollo/cache/decoder/NpcDefinitionDecoder.java +++ b/cache/src/main/org/apollo/cache/decoder/NpcDefinitionDecoder.java @@ -1,6 +1,7 @@ package org.apollo.cache.decoder; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.ByteBuffer; import java.util.Arrays; @@ -14,47 +15,47 @@ import org.apollo.util.BufferUtil; * * @author Major */ -public final class NpcDefinitionDecoder { +public final class NpcDefinitionDecoder implements Runnable { /** - * The {@link IndexedFileSystem}. + * The IndexedFileSystem. */ private final IndexedFileSystem fs; /** - * Creates the npc definition decoder. + * Creates the NpcDefinitionDecoder. * - * @param fs The indexed file system. + * @param fs The {@link IndexedFileSystem}. */ public NpcDefinitionDecoder(IndexedFileSystem fs) { this.fs = fs; } - /** - * Decodes the npc definitions. - * - * @return An array of all parsed npc definitions. - * @throws IOException If an I/O error occurs. - */ - public NpcDefinition[] decode() throws IOException { - Archive config = fs.getArchive(0, 2); - ByteBuffer data = config.getEntry("npc.dat").getBuffer(); - ByteBuffer idx = config.getEntry("npc.idx").getBuffer(); + @Override + public void run() { + try { + Archive config = fs.getArchive(0, 2); + ByteBuffer data = config.getEntry("npc.dat").getBuffer(); + ByteBuffer idx = config.getEntry("npc.idx").getBuffer(); - int count = idx.getShort(), index = 2; - int[] indices = new int[count]; - for (int i = 0; i < count; i++) { - indices[i] = index; - index += idx.getShort(); + int count = idx.getShort(), index = 2; + int[] indices = new int[count]; + + for (int i = 0; i < count; i++) { + indices[i] = index; + index += idx.getShort(); + } + + NpcDefinition[] definitions = new NpcDefinition[count]; + for (int i = 0; i < count; i++) { + data.position(indices[i]); + definitions[i] = decode(i, data); + } + + NpcDefinition.init(definitions); + } catch (IOException e) { + throw new UncheckedIOException("Error decoding NpcDefinitions.", e); } - - NpcDefinition[] defs = new NpcDefinition[count]; - for (int i = 0; i < count; i++) { - data.position(indices[i]); - defs[i] = decode(i, data); - } - - return defs; } /** @@ -75,8 +76,8 @@ public final class NpcDefinitionDecoder { } else if (opcode == 1) { int length = buffer.get() & 0xFF; int[] models = new int[length]; - for (int i = 0; i < length; i++) { - models[i] = buffer.getShort(); + for (int index = 0; index < length; index++) { + models[index] = buffer.getShort(); } } else if (opcode == 2) { definition.setName(BufferUtil.readString(buffer)); @@ -92,24 +93,27 @@ public final class NpcDefinitionDecoder { definition .setWalkAnimations(buffer.getShort(), buffer.getShort(), buffer.getShort(), buffer.getShort()); } else if (opcode >= 30 && opcode < 40) { - String str = BufferUtil.readString(buffer); - if (str.equals("hidden")) { - str = null; + String action = BufferUtil.readString(buffer); + if (action.equals("hidden")) { + action = null; } - definition.setInteraction(opcode - 30, str); + + definition.setInteraction(opcode - 30, action); } else if (opcode == 40) { int length = buffer.get() & 0xFF; int[] originalColours = new int[length]; int[] replacementColours = new int[length]; - for (int i = 0; i < length; i++) { - originalColours[i] = buffer.getShort(); - replacementColours[i] = buffer.getShort(); + + for (int index = 0; index < length; index++) { + originalColours[index] = buffer.getShort(); + replacementColours[index] = buffer.getShort(); } } else if (opcode == 60) { int length = buffer.get() & 0xFF; int[] additionalModels = new int[length]; - for (int i = 0; i < length; i++) { - additionalModels[i] = buffer.getShort(); + + for (int index = 0; index < length; index++) { + additionalModels[index] = buffer.getShort(); } } else if (opcode >= 90 && opcode <= 92) { buffer.getShort(); // Dummy diff --git a/cache/src/main/org/apollo/cache/decoder/ObjectDefinitionDecoder.java b/cache/src/main/org/apollo/cache/decoder/ObjectDefinitionDecoder.java index 0283b753..3ffc797a 100644 --- a/cache/src/main/org/apollo/cache/decoder/ObjectDefinitionDecoder.java +++ b/cache/src/main/org/apollo/cache/decoder/ObjectDefinitionDecoder.java @@ -1,10 +1,12 @@ package org.apollo.cache.decoder; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.ByteBuffer; import org.apollo.cache.IndexedFileSystem; import org.apollo.cache.archive.Archive; +import org.apollo.cache.def.ItemDefinition; import org.apollo.cache.def.ObjectDefinition; import org.apollo.util.BufferUtil; @@ -13,15 +15,15 @@ import org.apollo.util.BufferUtil; * * @author Major */ -public final class ObjectDefinitionDecoder { +public final class ObjectDefinitionDecoder implements Runnable { /** - * The {@link IndexedFileSystem}. + * The IndexedFileSystem. */ private final IndexedFileSystem fs; /** - * Creates the decoder. + * Creates the ObjectDefinitionDecoder. * * @param fs The {@link IndexedFileSystem}. */ @@ -29,6 +31,32 @@ public final class ObjectDefinitionDecoder { this.fs = fs; } + @Override + public void run() { + try { + Archive config = fs.getArchive(0, 2); + ByteBuffer data = config.getEntry("loc.dat").getBuffer(); + ByteBuffer idx = config.getEntry("loc.idx").getBuffer(); + + int count = idx.getShort(), index = 2; + int[] indices = new int[count]; + for (int i = 0; i < count; i++) { + indices[i] = index; + index += idx.getShort(); + } + + ObjectDefinition[] definitions = new ObjectDefinition[count]; + for (int i = 0; i < count; i++) { + data.position(indices[i]); + definitions[i] = decode(i, data); + } + + ObjectDefinition.init(definitions); + } catch (IOException e) { + throw new UncheckedIOException("Error decoding ObjectDefinitions.", e); + } + } + /** * Decodes data from the cache into an {@link ObjectDefinition}. * @@ -36,7 +64,7 @@ public final class ObjectDefinitionDecoder { * @param data The {@link ByteBuffer} containing the data. * @return The object definition. */ - public ObjectDefinition decode(int id, ByteBuffer data) { + private ObjectDefinition decode(int id, ByteBuffer data) { ObjectDefinition definition = new ObjectDefinition(id); while (true) { int opcode = data.get() & 0xFF; @@ -111,30 +139,4 @@ public final class ObjectDefinitionDecoder { } } - /** - * Decodes all of the data into {@link ObjectDefinition}s. - * - * @return The definitions. - * @throws IOException If an error occurs when decoding the archive or finding an entry. - */ - public ObjectDefinition[] decode() throws IOException { - Archive config = fs.getArchive(0, 2); - ByteBuffer data = config.getEntry("loc.dat").getBuffer(); - ByteBuffer idx = config.getEntry("loc.idx").getBuffer(); - - int count = idx.getShort(), index = 2; - int[] indices = new int[count]; - for (int i = 0; i < count; i++) { - indices[i] = index; - index += idx.getShort(); - } - - ObjectDefinition[] defs = new ObjectDefinition[count]; - for (int i = 0; i < count; i++) { - data.position(indices[i]); - defs[i] = decode(i, data); - } - return defs; - } - } \ No newline at end of file diff --git a/cache/src/main/org/apollo/cache/def/NpcDefinition.java b/cache/src/main/org/apollo/cache/def/NpcDefinition.java index 1d8d60fe..0e81396d 100644 --- a/cache/src/main/org/apollo/cache/def/NpcDefinition.java +++ b/cache/src/main/org/apollo/cache/def/NpcDefinition.java @@ -36,14 +36,14 @@ public final class NpcDefinition { * Initialises the class with the specified set of definitions. * * @param definitions The definitions. - * @throws RuntimeException If there is an id mismatch. + * @throws IllegalStateException If there is an id mismatch. */ public static void init(NpcDefinition[] definitions) { NpcDefinition.definitions = definitions; for (int id = 0; id < definitions.length; id++) { NpcDefinition def = definitions[id]; if (def.getId() != id) { - throw new RuntimeException("Npc definition id mismatch."); + throw new IllegalStateException("Npc definition id mismatch."); } } } diff --git a/cache/src/main/org/apollo/cache/tools/EquipmentUpdater.java b/cache/src/main/org/apollo/cache/tools/EquipmentUpdater.java index c85466d5..847245a1 100644 --- a/cache/src/main/org/apollo/cache/tools/EquipmentUpdater.java +++ b/cache/src/main/org/apollo/cache/tools/EquipmentUpdater.java @@ -20,6 +20,44 @@ import com.google.common.base.Preconditions; */ public final class EquipmentUpdater { + /** + * The entry point of the application. + * + * @param args The command line arguments. + * @throws Exception If an error occurs. + */ + public static void main(String[] args) throws Exception { + Preconditions.checkArgument(args.length == 1, "Usage:\njava -cp ... org.apollo.tools.EquipmentUpdater [release]."); + String release = args[0]; + + try (DataOutputStream os = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("data/equipment-" + release + ".dat"))); + IndexedFileSystem fs = new IndexedFileSystem(Paths.get("data/fs/", release), true)) { + ItemDefinitionDecoder decoder = new ItemDefinitionDecoder(fs); + decoder.run(); + + int count = ItemDefinition.count(); + os.writeShort(count); + + for (int id = 0; id < count; id++) { + ItemDefinition definition = ItemDefinition.lookup(id); + int type = getWeaponType(definition); + os.writeByte(type); + + if (type != -1) { + os.writeBoolean(isTwoHanded(definition)); + os.writeBoolean(isFullBody(definition)); + os.writeBoolean(isFullHat(definition)); + os.writeBoolean(isFullMask(definition)); + os.writeByte(getAttackRequirement(definition)); + os.writeByte(getStrengthRequirement(definition)); + os.writeByte(getDefenceRequirement(definition)); + os.writeByte(getRangedRequirement(definition)); + os.writeByte(getMagicRequirement(definition)); + } + } + } + } + /** * Gets the attack requirement. * @@ -31,201 +69,139 @@ public final class EquipmentUpdater { if (name == null) { name = "null"; } + if (name.equals("Black sword")) { return 10; - } - if (name.equals("Black dagger")) { + } else if (name.equals("Black dagger")) { return 10; - } - if (name.equals("Black spear")) { + } else if (name.equals("Black spear")) { return 10; - } - if (name.equals("Black longsword")) { + } else if (name.equals("Black longsword")) { return 10; - } - if (name.equals("Black scimitar")) { + } else if (name.equals("Black scimitar")) { return 10; - } - if (name.equals("Black axe")) { + } else if (name.equals("Black axe")) { return 10; - } - if (name.equals("Black battleaxe")) { + } else if (name.equals("Black battleaxe")) { return 10; - } - if (name.equals("Black mace")) { + } else if (name.equals("Black mace")) { return 10; - } - if (name.equals("Black halberd")) { + } else if (name.equals("Black halberd")) { return 10; - } - if (name.equals("Mithril sword")) { + } else if (name.equals("Mithril sword")) { return 20; - } - if (name.equals("Mithril dagger")) { + } else if (name.equals("Mithril dagger")) { return 20; - } - if (name.equals("Mithril spear")) { + } else if (name.equals("Mithril spear")) { return 20; - } - if (name.equals("Mihril longsword")) { + } else if (name.equals("Mihril longsword")) { return 20; - } - if (name.equals("Mithril scimitar")) { + } else if (name.equals("Mithril scimitar")) { return 20; - } - if (name.equals("Mithril axe")) { + } else if (name.equals("Mithril axe")) { return 20; - } - if (name.equals("Mithril battleaxe")) { + } else if (name.equals("Mithril battleaxe")) { return 20; - } - if (name.equals("Mithril mace")) { + } else if (name.equals("Mithril mace")) { return 20; - } - if (name.equals("Mithril halberd")) { + } else if (name.equals("Mithril halberd")) { return 20; - } - if (name.equals("Adamant sword")) { + } else if (name.equals("Adamant sword")) { return 30; - } - if (name.equals("Adamant dagger")) { + } else if (name.equals("Adamant dagger")) { return 30; - } - if (name.equals("Adamant spear")) { + } else if (name.equals("Adamant spear")) { return 30; - } - if (name.equals("Adamant longsword")) { + } else if (name.equals("Adamant longsword")) { return 30; - } - if (name.equals("Adamant scimitar")) { + } else if (name.equals("Adamant scimitar")) { return 30; - } - if (name.equals("Adamant axe")) { + } else if (name.equals("Adamant axe")) { return 30; - } - if (name.equals("Adamant battleaxe")) { + } else if (name.equals("Adamant battleaxe")) { return 30; - } - if (name.equals("Adamant mace")) { + } else if (name.equals("Adamant mace")) { return 30; - } - if (name.equals("Adamant halberd")) { + } else if (name.equals("Adamant halberd")) { return 30; - } - if (name.equals("Rune sword")) { + } else if (name.equals("Rune sword")) { return 40; - } - if (name.equals("Rune dagger")) { + } else if (name.equals("Rune dagger")) { return 40; - } - if (name.equals("Rune spear")) { + } else if (name.equals("Rune spear")) { return 40; - } - if (name.equals("Rune longsword")) { + } else if (name.equals("Rune longsword")) { return 40; - } - if (name.equals("Rune scimitar")) { + } else if (name.equals("Rune scimitar")) { return 40; - } - if (name.equals("Rune axe")) { + } else if (name.equals("Rune axe")) { return 40; - } - if (name.equals("Rune battleaxe")) { + } else if (name.equals("Rune battleaxe")) { return 40; - } - if (name.equals("Rune mace")) { + } else if (name.equals("Rune mace")) { return 40; - } - if (name.equals("Rune halberd")) { + } else if (name.equals("Rune halberd")) { return 40; - } - if (name.equals("Dragon sword")) { + } else if (name.equals("Dragon sword")) { return 60; - } - if (name.equals("Dragon dagger(s)")) { + } else if (name.equals("Dragon dagger(s)")) { return 60; - } - if (name.equals("Dragon dagger")) { + } else if (name.equals("Dragon dagger")) { return 60; - } - if (name.startsWith("Dragon spear")) { + } else if (name.startsWith("Dragon spear")) { return 60; - } - if (name.equals("Dragon longsword")) { + } else if (name.equals("Dragon longsword")) { return 60; - } - if (name.equals("Dragon scimitar")) { + } else if (name.equals("Dragon scimitar")) { return 60; - } - if (name.equals("Dragon axe")) { + } else if (name.equals("Dragon axe")) { return 60; - } - if (name.equals("Dragon battleaxe")) { + } else if (name.equals("Dragon battleaxe")) { return 60; - } - if (name.equals("Dragon mace")) { + } else if (name.equals("Dragon mace")) { return 60; - } - if (name.equals("Dragon halberd")) { + } else if (name.equals("Dragon halberd")) { return 60; - } - if (name.equals("Abyssal whip")) { + } else if (name.equals("Abyssal whip")) { return 70; - } - if (name.equals("Veracs flail")) { + } else if (name.equals("Veracs flail")) { return 70; - } - if (name.equals("Torags hammers")) { + } else if (name.equals("Torags hammers")) { return 70; - } - if (name.equals("Dharoks greataxe")) { + } else if (name.equals("Dharoks greataxe")) { return 70; - } - if (name.equals("Guthans warspear")) { + } else if (name.equals("Guthans warspear")) { return 70; - } - if (name.equals("Ahrims staff")) { + } else if (name.equals("Ahrims staff")) { return 70; - } - if (name.equals("Granite maul")) { + } else if (name.equals("Granite maul")) { return 50; - } - if (name.equals("Toktz-xil-ak")) { + } else if (name.equals("Toktz-xil-ak")) { return 60; - } - if (name.equals("Tzhaar-ket-em")) { + } else if (name.equals("Tzhaar-ket-em")) { return 60; - } - if (name.equals("Toktz-xil-ek")) { + } else if (name.equals("Toktz-xil-ek")) { return 60; - } - if (name.equals("Granite legs")) { + } else if (name.equals("Granite legs")) { return 99; - } - if (name.equals("Mud staff")) { + } else if (name.equals("Mud staff")) { return 30; - } - if (name.equals("Armadyl godsword")) { + } else if (name.equals("Armadyl godsword")) { return 75; - } - if (name.equals("Bandos godsword")) { + } else if (name.equals("Bandos godsword")) { return 75; - } - if (name.equals("Saradomin godsword")) { + } else if (name.equals("Saradomin godsword")) { return 75; - } - if (name.equals("Zamorak godsword")) { + } else if (name.equals("Zamorak godsword")) { return 75; - } - if (name.equals("Lava battlestaff")) { + } else if (name.equals("Lava battlestaff")) { return 30; - } - if (name.equals("Toktz-mej-tal")) { + } else if (name.equals("Toktz-mej-tal")) { return 60; - } - if (name.equals("Ancient staff")) { + } else if (name.equals("Ancient staff")) { return 50; } + return 1; } @@ -241,441 +217,299 @@ public final class EquipmentUpdater { if (name == null) { name = "null"; } + if (name.equals("Rune boots")) { return 40; - } - if (id == 2499) { + } else if (id == 2499) { return 40; - } - if (id == 4123) { + } else if (id == 4123) { return 5; - } - if (id == 4125) { + } else if (id == 4125) { return 10; - } - if (id == 4127) { + } else if (id == 4127) { return 20; - } - if (id == 4129) { + } else if (id == 4129) { return 30; - } - if (id == 7990) { + } else if (id == 7990) { return 60; - } - if (id == 2501) { + } else if (id == 2501) { return 40; - } - if (id == 1131) { + } else if (id == 1131) { return 10; - } - if (id == 2503) { + } else if (id == 2503) { return 40; - } - if (id == 1135) { + } else if (id == 1135) { return 40; - } - if (id == 7462) { + } else if (id == 7462) { return 42; - } - if (id == 7461) { + } else if (id == 7461) { return 42; - } - if (id == 7460) { + } else if (id == 7460) { return 42; - } - if (id == 7459) { + } else if (id == 7459) { return 20; - } - if (id == 7458) { + } else if (id == 7458) { return 1; - } - if (id == 7457) { + } else if (id == 7457) { return 1; - } - if (id == 7456) { + } else if (id == 7456) { return 1; - } - if (name.equals("White med helm")) { + } else if (name.equals("White med helm")) { return 10; - } - if (name.equals("White chainbody")) { + } else if (name.equals("White chainbody")) { return 10; - } - if (name.startsWith("White full helm")) { + } else if (name.startsWith("White full helm")) { return 10; - } - if (name.startsWith("White platebody")) { + } else if (name.startsWith("White platebody")) { return 10; - } - if (name.startsWith("White plateskirt")) { + } else if (name.startsWith("White plateskirt")) { return 10; - } - if (name.startsWith("White platelegs")) { + } else if (name.startsWith("White platelegs")) { return 10; - } - if (name.startsWith("White kiteshield")) { + } else if (name.startsWith("White kiteshield")) { return 10; - } - if (name.startsWith("White sq shield")) { + } else if (name.startsWith("White sq shield")) { return 10; - } - if (name.startsWith("Studded chaps")) { + } else if (name.startsWith("Studded chaps")) { return 1; - } - if (name.startsWith("Studded")) { + } else if (name.startsWith("Studded")) { return 20; - } - if (name.startsWith("Black kiteshield(h)")) { + } else if (name.startsWith("Black kiteshield(h)")) { return 10; - } - if (name.startsWith("Rune kiteshield(h)")) { + } else if (name.startsWith("Rune kiteshield(h)")) { return 40; - } - if (name.equals("Black med helm")) { + } else if (name.equals("Black med helm")) { return 10; - } - if (name.equals("Black chainbody")) { + } else if (name.equals("Black chainbody")) { return 10; - } - if (name.startsWith("Black full helm")) { + } else if (name.startsWith("Black full helm")) { return 10; - } - if (name.startsWith("Black platebody")) { + } else if (name.startsWith("Black platebody")) { return 10; - } - if (name.startsWith("Black plateskirt")) { + } else if (name.startsWith("Black plateskirt")) { return 10; - } - if (name.startsWith("Black platelegs")) { + } else if (name.startsWith("Black platelegs")) { return 10; - } - if (name.startsWith("Black kiteshield")) { + } else if (name.startsWith("Black kiteshield")) { return 10; - } - if (name.startsWith("Black sq shield")) { + } else if (name.startsWith("Black sq shield")) { return 10; - } - if (name.equals("Mithril med helm")) { + } else if (name.equals("Mithril med helm")) { return 20; - } - if (name.equals("Mithril chainbody")) { + } else if (name.equals("Mithril chainbody")) { return 20; - } - if (name.startsWith("Mithril full helm")) { + } else if (name.startsWith("Mithril full helm")) { return 20; - } - if (name.startsWith("Mithril platebody")) { + } else if (name.startsWith("Mithril platebody")) { return 20; - } - if (name.startsWith("Mithril plateskirt")) { + } else if (name.startsWith("Mithril plateskirt")) { return 20; - } - if (name.startsWith("Mithril platelegs")) { + } else if (name.startsWith("Mithril platelegs")) { return 20; - } - if (name.startsWith("Mithril kiteshield")) { + } else if (name.startsWith("Mithril kiteshield")) { return 20; - } - if (name.startsWith("Mithril sq shield")) { + } else if (name.startsWith("Mithril sq shield")) { return 20; - } - if (name.equals("Adamant med helm")) { + } else if (name.equals("Adamant med helm")) { return 30; - } - if (name.equals("Adamant chainbody")) { + } else if (name.equals("Adamant chainbody")) { return 30; - } - if (name.startsWith("Adamant full helm")) { + } else if (name.startsWith("Adamant full helm")) { return 30; - } - if (name.startsWith("Adamant platebody")) { + } else if (name.startsWith("Adamant platebody")) { return 30; - } - if (name.startsWith("Adamant plateskirt")) { + } else if (name.startsWith("Adamant plateskirt")) { return 30; - } - if (name.startsWith("Adamant platelegs")) { + } else if (name.startsWith("Adamant platelegs")) { return 30; - } - if (name.startsWith("Adamant kiteshield")) { + } else if (name.startsWith("Adamant kiteshield")) { return 30; - } - if (name.startsWith("Adamant sq shield")) { + } else if (name.startsWith("Adamant sq shield")) { return 30; - } - if (name.startsWith("Adam full helm")) { + } else if (name.startsWith("Adam full helm")) { return 30; - } - if (name.startsWith("Adam platebody")) { + } else if (name.startsWith("Adam platebody")) { return 30; - } - if (name.startsWith("Adam plateskirt")) { + } else if (name.startsWith("Adam plateskirt")) { return 30; - } - if (name.startsWith("Adam platelegs")) { + } else if (name.startsWith("Adam platelegs")) { return 30; - } - if (name.startsWith("Adam kiteshield")) { + } else if (name.startsWith("Adam kiteshield")) { return 30; - } - if (name.startsWith("Adam kiteshield(h)")) { + } else if (name.startsWith("Adam kiteshield(h)")) { return 30; - } - if (name.startsWith("D-hide body(g)")) { + } else if (name.startsWith("D-hide body(g)")) { return 40; - } - if (name.startsWith("D-hide body(t)")) { + } else if (name.startsWith("D-hide body(t)")) { return 40; - } - if (name.equals("Dragon sq shield")) { + } else if (name.equals("Dragon sq shield")) { return 60; - } - if (name.equals("Dragon med helm")) { + } else if (name.equals("Dragon med helm")) { return 60; - } - if (name.equals("Dragon chainbody")) { + } else if (name.equals("Dragon chainbody")) { return 60; - } - if (name.equals("Dragon plateskirt")) { + } else if (name.equals("Dragon plateskirt")) { return 60; - } - if (name.equals("Dragon platelegs")) { + } else if (name.equals("Dragon platelegs")) { return 60; - } - if (name.equals("Dragon sq shield")) { + } else if (name.equals("Dragon sq shield")) { return 60; - } - if (name.equals("Rune med helm")) { + } else if (name.equals("Rune med helm")) { return 40; - } - if (name.equals("Rune chainbody")) { + } else if (name.equals("Rune chainbody")) { return 40; - } - if (name.startsWith("Rune full helm")) { + } else if (name.startsWith("Rune full helm")) { return 40; - } - if (name.startsWith("Rune platebody")) { + } else if (name.startsWith("Rune platebody")) { return 40; - } - if (name.startsWith("Rune plateskirt")) { + } else if (name.startsWith("Rune plateskirt")) { return 40; - } - if (name.startsWith("Rune platelegs")) { + } else if (name.startsWith("Rune platelegs")) { return 40; - } - if (name.startsWith("Rune kiteshield")) { + } else if (name.startsWith("Rune kiteshield")) { return 40; - } - if (name.startsWith("Zamorak full helm")) { + } else if (name.startsWith("Zamorak full helm")) { return 40; - } - if (name.startsWith("Zamorak platebody")) { + } else if (name.startsWith("Zamorak platebody")) { return 40; - } - if (name.startsWith("Zamorak plateskirt")) { + } else if (name.startsWith("Zamorak plateskirt")) { return 40; - } - if (name.startsWith("Zamorak platelegs")) { + } else if (name.startsWith("Zamorak platelegs")) { return 40; - } - if (name.startsWith("Zamorak kiteshield")) { + } else if (name.startsWith("Zamorak kiteshield")) { return 40; - } - if (name.startsWith("Guthix full helm")) { + } else if (name.startsWith("Guthix full helm")) { return 40; - } - if (name.startsWith("Guthix platebody")) { + } else if (name.startsWith("Guthix platebody")) { return 40; - } - if (name.startsWith("Guthix plateskirt")) { + } else if (name.startsWith("Guthix plateskirt")) { return 40; - } - if (name.startsWith("Guthix platelegs")) { + } else if (name.startsWith("Guthix platelegs")) { return 40; - } - if (name.startsWith("Guthix kiteshield")) { + } else if (name.startsWith("Guthix kiteshield")) { return 40; - } - if (name.startsWith("Saradomin full")) { + } else if (name.startsWith("Saradomin full")) { return 40; - } - if (name.startsWith("Saradomrangedin plate")) { + } else if (name.startsWith("Saradomrangedin plate")) { return 40; - } - if (name.startsWith("Saradomin plateskirt")) { + } else if (name.startsWith("Saradomin plateskirt")) { return 40; - } - if (name.startsWith("Saradomin legs")) { + } else if (name.startsWith("Saradomin legs")) { return 40; - } - if (name.startsWith("Zamorak kiteshield")) { + } else if (name.startsWith("Zamorak kiteshield")) { return 40; - } - if (name.startsWith("Rune sq shield")) { + } else if (name.startsWith("Rune sq shield")) { return 40; - } - if (name.equals("Gilded full helm")) { + } else if (name.equals("Gilded full helm")) { return 40; - } - if (name.equals("Gilded platebody")) { + } else if (name.equals("Gilded platebody")) { return 40; - } - if (name.equals("Gilded plateskirt")) { + } else if (name.equals("Gilded plateskirt")) { return 40; - } - if (name.equals("Gilded platelegs")) { + } else if (name.equals("Gilded platelegs")) { return 40; - } - if (name.equals("Gilded kiteshield")) { + } else if (name.equals("Gilded kiteshield")) { return 40; - } - if (name.equals("Fighter torso")) { + } else if (name.equals("Fighter torso")) { return 40; - } - if (name.equals("Granite legs")) { + } else if (name.equals("Granite legs")) { return 99; - } - if (name.equals("Toktz-ket-xil")) { + } else if (name.equals("Toktz-ket-xil")) { return 60; - } - if (name.equals("Dharoks helm")) { + } else if (name.equals("Dharoks helm")) { return 70; - } - if (name.equals("Dharoks platebody")) { + } else if (name.equals("Dharoks platebody")) { return 70; - } - if (name.equals("Dharoks platelegs")) { + } else if (name.equals("Dharoks platelegs")) { return 70; - } - if (name.equals("Guthans helm")) { + } else if (name.equals("Guthans helm")) { return 70; - } - if (name.equals("Guthans platebody")) { + } else if (name.equals("Guthans platebody")) { return 70; - } - if (name.equals("Guthans chainskirt")) { + } else if (name.equals("Guthans chainskirt")) { return 70; - } - if (name.equals("Torags helm")) { + } else if (name.equals("Torags helm")) { return 70; - } - if (name.equals("Torags platebody")) { + } else if (name.equals("Torags platebody")) { return 70; - } - if (name.equals("Torags platelegs")) { + } else if (name.equals("Torags platelegs")) { return 70; - } - if (name.equals("Veracs helm")) { + } else if (name.equals("Veracs helm")) { return 70; - } - if (name.equals("Veracs brassard")) { + } else if (name.equals("Veracs brassard")) { return 70; - } - if (name.equals("Veracs plateskirt")) { + } else if (name.equals("Veracs plateskirt")) { return 70; - } - if (name.equals("Ahrims hood")) { + } else if (name.equals("Ahrims hood")) { return 70; - } - if (name.equals("Ahrims robetop")) { + } else if (name.equals("Ahrims robetop")) { return 70; - } - if (name.equals("Ahrims robeskirt")) { + } else if (name.equals("Ahrims robeskirt")) { return 70; - } - if (name.equals("Karils coif")) { + } else if (name.equals("Karils coif")) { return 70; - } - if (name.equals("Karils leathertop")) { + } else if (name.equals("Karils leathertop")) { return 70; - } - if (name.equals("Karils leatherskirt")) { + } else if (name.equals("Karils leatherskirt")) { return 70; - } - if (name.equals("Granite shield")) { + } else if (name.equals("Granite shield")) { return 50; - } - if (name.equals("New crystal shield")) { + } else if (name.equals("New crystal shield")) { return 70; - } - if (name.equals("Archer helm")) { + } else if (name.equals("Archer helm")) { return 45; - } - if (name.equals("Berserker helm")) { + } else if (name.equals("Berserker helm")) { return 45; - } - if (name.equals("Warrior helm")) { + } else if (name.equals("Warrior helm")) { return 45; - } - if (name.equals("Farseer helm")) { + } else if (name.equals("Farseer helm")) { return 45; - } - if (name.equals("Initiate helm")) { + } else if (name.equals("Initiate helm")) { return 20; - } - if (name.equals("Initiate platemail")) { + } else if (name.equals("Initiate platemail")) { return 20; - } - if (name.equals("Initiate platelegs")) { + } else if (name.equals("Initiate platelegs")) { return 20; - } - if (name.equals("Dragonhide body")) { + } else if (name.equals("Dragonhide body")) { return 40; - } - if (name.equals("Mystic hat")) { + } else if (name.equals("Mystic hat")) { return 20; - } - if (name.equals("Mystic robe top")) { + } else if (name.equals("Mystic robe top")) { return 20; - } - if (name.equals("Mystic robe bottom")) { + } else if (name.equals("Mystic robe bottom")) { return 20; - } - if (name.equals("Mystic gloves")) { + } else if (name.equals("Mystic gloves")) { return 20; - } - if (name.equals("Mystic boots")) { + } else if (name.equals("Mystic boots")) { return 20; - } - if (name.equals("Enchanted hat")) { + } else if (name.equals("Enchanted hat")) { return 20; - } - if (name.equals("Enchanted top")) { + } else if (name.equals("Enchanted top")) { return 20; - } - if (name.equals("Enchanted robe")) { + } else if (name.equals("Enchanted robe")) { return 20; - } - if (name.equals("Splitbark helm")) { + } else if (name.equals("Splitbark helm")) { return 40; - } - if (name.equals("Splitbark body")) { + } else if (name.equals("Splitbark body")) { return 40; - } - if (name.equals("Splitbark gauntlets")) { + } else if (name.equals("Splitbark gauntlets")) { return 40; - } - if (name.equals("Splitbark legs")) { + } else if (name.equals("Splitbark legs")) { return 40; - } - if (name.equals("Splitbark greaves")) { + } else if (name.equals("Splitbark greaves")) { return 40; - } - if (name.equals("Infinity gloves")) { - return 25; - } - if (name.equals("Infinity hat")) { - return 25; - } - if (name.equals("Infinity top")) { - return 25; - } - if (name.equals("Infinity bottoms")) { - return 25; - } - if (name.equals("Infinity boots")) { + } else if (name.equals("Infinity gloves")) { + return 25; + } else if (name.equals("Infinity hat")) { + return 25; + } else if (name.equals("Infinity top")) { + return 25; + } else if (name.equals("Infinity bottoms")) { + return 25; + } else if (name.equals("Infinity boots")) { return 25; } + return 1; } @@ -690,99 +524,71 @@ public final class EquipmentUpdater { if (name == null) { name = "null"; } + if (name.equals("Mystic hat")) { return 40; - } - if (name.equals("Mystic robe top")) { + } else if (name.equals("Mystic robe top")) { return 40; - } - if (name.equals("Mystic robe bottom")) { + } else if (name.equals("Mystic robe bottom")) { return 40; - } - if (name.equals("Mystic gloves")) { + } else if (name.equals("Mystic gloves")) { return 40; - } - if (name.equals("Mystic boots")) { + } else if (name.equals("Mystic boots")) { return 40; - } - if (name.equals("Slayer's staff")) { + } else if (name.equals("Slayer's staff")) { return 50; - } - if (name.equals("Enchanted hat")) { + } else if (name.equals("Enchanted hat")) { return 40; - } - if (name.equals("Enchanted top")) { + } else if (name.equals("Enchanted top")) { return 40; - } - if (name.equals("Enchanted robe")) { + } else if (name.equals("Enchanted robe")) { return 40; - } - if (name.equals("Splitbark helm")) { + } else if (name.equals("Splitbark helm")) { return 40; - } - if (name.equals("Splitbark body")) { + } else if (name.equals("Splitbark body")) { return 40; - } - if (name.equals("Splitbark gauntlets")) { + } else if (name.equals("Splitbark gauntlets")) { return 40; - } - if (name.equals("Splitbark legs")) { + } else if (name.equals("Splitbark legs")) { return 40; - } - if (name.equals("Splitbark greaves")) { + } else if (name.equals("Splitbark greaves")) { return 40; - } - if (name.equals("Infinity gloves")) { + } else if (name.equals("Infinity gloves")) { return 50; - } - if (name.equals("Infinity hat")) { + } else if (name.equals("Infinity hat")) { return 50; - } - if (name.equals("Infinity top")) { + } else if (name.equals("Infinity top")) { return 50; - } - if (name.equals("Infinity bottoms")) { + } else if (name.equals("Infinity bottoms")) { return 50; - } - if (name.equals("Infinity boots")) { + } else if (name.equals("Infinity boots")) { return 50; - } - if (name.equals("Ahrims hood")) { + } else if (name.equals("Ahrims hood")) { return 70; - } - if (name.equals("Ahrims robetop")) { + } else if (name.equals("Ahrims robetop")) { return 70; - } - if (name.equals("Ahrims robeskirt")) { + } else if (name.equals("Ahrims robeskirt")) { return 70; - } - if (name.equals("Ahrims staff")) { + } else if (name.equals("Ahrims staff")) { return 70; - } - if (name.equals("Saradomin cape")) { + } else if (name.equals("Saradomin cape")) { return 60; - } - if (name.equals("Saradomin staff")) { + } else if (name.equals("Saradomin staff")) { return 60; - } - if (name.equals("Zamorak cape")) { + } else if (name.equals("Zamorak cape")) { return 60; - } - if (name.equals("Zamorak staff")) { + } else if (name.equals("Zamorak staff")) { return 60; - } - if (name.equals("Guthix cape")) { + } else if (name.equals("Guthix cape")) { return 60; - } - if (name.equals("Guthix staff")) { + } else if (name.equals("Guthix staff")) { return 60; - } - if (name.equals("mud staff")) { - return 30; - } - if (name.equals("Fire battlestaff")) { + } else if (name.equals("mud staff")) { + return 30; + } else if (name.equals("Fire battlestaff")) { return 30; } + return 1; } @@ -798,153 +604,107 @@ public final class EquipmentUpdater { if (name == null) { name = "null"; } + if (id == 2499) { return 50; - } - if (id == 1135) { + } else if (id == 1135) { return 40; - } - if (id == 1099) { + } else if (id == 1099) { return 40; - } - if (id == 1065) { + } else if (id == 1065) { return 40; - } - if (id == 2501) { + } else if (id == 2501) { return 60; - } - if (id == 2503) { + } else if (id == 2503) { return 70; - } - if (id == 2487) { + } else if (id == 2487) { return 50; - } - if (id == 2489) { + } else if (id == 2489) { return 60; - } - if (id == 2495) { + } else if (id == 2495) { return 60; - } - if (id == 2491) { + } else if (id == 2491) { return 70; - } - if (id == 2493) { + } else if (id == 2493) { return 50; - } - if (id == 2505) { + } else if (id == 2505) { return 60; - } - if (id == 2507) { + } else if (id == 2507) { return 70; - } - if (id == 859) { + } else if (id == 859) { return 40; - } - if (id == 861) { + } else if (id == 861) { return 40; - } - if (id == 7370) { + } else if (id == 7370) { return 40; - } - if (id == 7372) { + } else if (id == 7372) { return 40; - } - if (id == 7378) { + } else if (id == 7378) { return 40; - } - if (id == 7380) { + } else if (id == 7380) { return 40; - } - if (id == 7374) { + } else if (id == 7374) { return 50; - } - if (id == 7376) { + } else if (id == 7376) { return 50; - } - if (id == 7382) { + } else if (id == 7382) { return 50; - } - if (id == 7384) { + } else if (id == 7384) { return 50; - } - if (name.equals("Coif")) { + } else if (name.equals("Coif")) { return 20; - } - if (name.startsWith("Studded chaps")) { + } else if (name.startsWith("Studded chaps")) { return 20; - } - if (name.startsWith("Studded")) { + } else if (name.startsWith("Studded")) { return 20; - } - if (name.equals("Karils coif")) { + } else if (name.equals("Karils coif")) { return 70; - } - if (name.equals("Karils leathertop")) { + } else if (name.equals("Karils leathertop")) { return 70; - } - if (name.equals("Karils leatherskirt")) { + } else if (name.equals("Karils leatherskirt")) { return 70; - } - if (name.equals("Robin hood hat")) { + } else if (name.equals("Robin hood hat")) { return 40; - } - if (name.equals("Ranger boots")) { + } else if (name.equals("Ranger boots")) { return 40; - } - if (name.equals("Crystal bow full")) { + } else if (name.equals("Crystal bow full")) { return 70; - } - if (name.equals("New crystal bow")) { + } else if (name.equals("New crystal bow")) { return 70; - } - if (name.equals("Karils crossbow")) { + } else if (name.equals("Karils crossbow")) { return 70; - } - if (id == 2497) { + } else if (id == 2497) { return 70; - } - if (name.equals("Rune thrownaxe")) { + } else if (name.equals("Rune thrownaxe")) { return 40; - } - if (name.equals("Rune dart")) { + } else if (name.equals("Rune dart")) { return 40; - } - if (name.equals("Rune javelin")) { + } else if (name.equals("Rune javelin")) { return 40; - } - if (name.equals("Rune knife")) { + } else if (name.equals("Rune knife")) { return 40; - } - if (name.equals("Adamant thrownaxe")) { + } else if (name.equals("Adamant thrownaxe")) { return 30; - } - if (name.equals("Adamant dart")) { + } else if (name.equals("Adamant dart")) { return 30; - } - if (name.equals("Adamant javelin")) { + } else if (name.equals("Adamant javelin")) { return 30; - } - if (name.equals("Adamant knife")) { + } else if (name.equals("Adamant knife")) { return 30; - } - if (name.equals("Toktz-xil-ul")) { + } else if (name.equals("Toktz-xil-ul")) { return 60; - } - if (name.equals("Seercull")) { + } else if (name.equals("Seercull")) { return 50; - } - if (name.equals("Bolt rack")) { + } else if (name.equals("Bolt rack")) { return 70; - } - if (name.equals("Rune arrow")) { + } else if (name.equals("Rune arrow")) { return 40; - } - if (name.equals("Adamant arrow")) { + } else if (name.equals("Adamant arrow")) { return 30; - } - if (name.equals("Mithril arrow")) { + } else if (name.equals("Mithril arrow")) { return 1; } + return 1; } @@ -959,24 +719,21 @@ public final class EquipmentUpdater { if (name == null) { name = "null"; } + if (name.equals("Torags hammers")) { return 70; - } - if (name.equals("Dharoks greataxe")) { + } else if (name.equals("Dharoks greataxe")) { return 70; - } - if (name.equals("Granite maul")) { + } else if (name.equals("Granite maul")) { return 50; - } - if (name.equals("Granite legs")) { + } else if (name.equals("Granite legs")) { return 99; - } - if (name.equals("Tzhaar-ket-om")) { + } else if (name.equals("Tzhaar-ket-om")) { return 60; - } - if (name.equals("Granite shield")) { + } else if (name.equals("Granite shield")) { return 50; } + return 1; } @@ -1060,11 +817,13 @@ public final class EquipmentUpdater { if (name == null) { name = "null"; } + for (String element : EquipmentConstants.FULL_BODIES) { if (name.contains(element)) { return true; } } + return false; } @@ -1079,11 +838,13 @@ public final class EquipmentUpdater { if (name == null) { name = "null"; } + for (String element : EquipmentConstants.FULL_HATS) { if (name.endsWith(element)) { return true; } } + return false; } @@ -1098,11 +859,13 @@ public final class EquipmentUpdater { if (name == null) { name = "null"; } + for (String element : EquipmentConstants.FULL_MASKS) { if (name.endsWith(element)) { return true; } } + return false; } @@ -1118,6 +881,7 @@ public final class EquipmentUpdater { if (name == null) { name = "null"; } + if (id == 4212) { return true; } else if (id == 4214) { @@ -1157,44 +921,10 @@ public final class EquipmentUpdater { } else if (name.equals("Saradomin sword")) { return true; } + return false; } - /** - * The entry point of the application. - * - * @param args The command line arguments. - * @throws Exception If an error occurs. - */ - public static void main(String[] args) throws Exception { - Preconditions.checkArgument(args.length == 1, "Usage:\njava -cp ... org.apollo.tools.EquipmentUpdater [release]."); - String release = args[0]; - - try (DataOutputStream os = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("data/equipment-" + release + ".dat"))); IndexedFileSystem fs = new IndexedFileSystem(Paths.get("data/fs/", release), true)) { - ItemDefinitionDecoder decoder = new ItemDefinitionDecoder(fs); - ItemDefinition[] definitions = decoder.decode(); - ItemDefinition.init(definitions); - - os.writeShort(definitions.length); - for (int id = 0; id < definitions.length; id++) { - ItemDefinition def = ItemDefinition.lookup(id); - int type = getWeaponType(def); - os.writeByte(type); - if (type != -1) { - os.writeBoolean(isTwoHanded(def)); - os.writeBoolean(isFullBody(def)); - os.writeBoolean(isFullHat(def)); - os.writeBoolean(isFullMask(def)); - os.writeByte(getAttackRequirement(def)); - os.writeByte(getStrengthRequirement(def)); - os.writeByte(getDefenceRequirement(def)); - os.writeByte(getRangedRequirement(def)); - os.writeByte(getMagicRequirement(def)); - } - } - } - } - /** * Default private constructor to prevent instantiation. */ diff --git a/game/src/main/org/apollo/game/fs/decoder/GameObjectDecoder.java b/game/src/main/org/apollo/game/fs/decoder/GameObjectDecoder.java index a952d72c..f7e86124 100644 --- a/game/src/main/org/apollo/game/fs/decoder/GameObjectDecoder.java +++ b/game/src/main/org/apollo/game/fs/decoder/GameObjectDecoder.java @@ -1,6 +1,7 @@ package org.apollo.game.fs.decoder; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; @@ -11,6 +12,7 @@ import java.util.function.Predicate; import org.apollo.cache.IndexedFileSystem; import org.apollo.cache.decoder.MapFileDecoder; import org.apollo.cache.decoder.MapFileDecoder.MapDefinition; +import org.apollo.cache.decoder.ObjectDefinitionDecoder; import org.apollo.cache.def.ObjectDefinition; import org.apollo.game.model.Position; import org.apollo.game.model.World; @@ -31,7 +33,7 @@ import com.google.common.collect.Iterables; * @author Ryley * @author Major */ -public final class GameObjectDecoder { +public final class GameObjectDecoder implements Runnable { /** * A bit flag that indicates that the tile at the current Position is blocked. @@ -58,44 +60,51 @@ public final class GameObjectDecoder { */ private final RegionRepository regions; + /** + * The World to place the objects in. + */ + private final World world; + /** * Creates the GameObjectDecoder. * * @param fs The {@link IndexedFileSystem}. - * @param regions The {@link RegionRepository}. + * @param world The {@link World} to place the objects in. */ - public GameObjectDecoder(IndexedFileSystem fs, RegionRepository regions) { + public GameObjectDecoder(IndexedFileSystem fs, World world) { this.fs = fs; - this.regions = regions; + this.world = world; + regions = world.getRegionRepository(); } - /** - * Decodes the GameObjects from their MapDefinitions. - * - * @param world The {@link World} containing the StaticGameObjects. - * @return The decoded objects. - * @throws IOException If there is an error decoding the {@link MapDefinition}s. - */ - public GameObject[] decode(World world) throws IOException { - Map definitions = MapFileDecoder.decode(fs); + @Override + public void run() { + ObjectDefinitionDecoder decoder = new ObjectDefinitionDecoder(fs); + decoder.run(); - for (Entry entry : definitions.entrySet()) { - MapDefinition definition = entry.getValue(); + try { + Map definitions = MapFileDecoder.decode(fs); - int packed = definition.getPackedCoordinates(); - int x = (packed >> 8 & 0xFF) * 64; - int y = (packed & 0xFF) * 64; + for (Entry entry : definitions.entrySet()) { + MapDefinition definition = entry.getValue(); - ByteBuffer objects = fs.getFile(4, definition.getObjectFile()); - ByteBuffer decompressed = ByteBuffer.wrap(CompressionUtil.degzip(objects)); - decodeObjects(world, decompressed, x, y); + int packed = definition.getPackedCoordinates(); + int x = (packed >> 8 & 0xFF) * 64; + int y = (packed & 0xFF) * 64; - ByteBuffer terrain = fs.getFile(4, definition.getTerrainFile()); - decompressed = ByteBuffer.wrap(CompressionUtil.degzip(terrain)); - decodeTerrain(decompressed, x, y); + ByteBuffer objects = fs.getFile(4, definition.getObjectFile()); + ByteBuffer decompressed = ByteBuffer.wrap(CompressionUtil.degzip(objects)); + decodeObjects(world, decompressed, x, y); + + ByteBuffer terrain = fs.getFile(4, definition.getTerrainFile()); + decompressed = ByteBuffer.wrap(CompressionUtil.degzip(terrain)); + decodeTerrain(decompressed, x, y); + } + } catch (IOException e) { + throw new UncheckedIOException("Error decoding StaticGameObjects.", e); } - return Iterables.toArray(objects, GameObject.class); + objects.forEach(object -> regions.fromPosition(object.getPosition()).addEntity(object, false)); } /** @@ -112,24 +121,21 @@ public final class GameObjectDecoder { int x = position.getX(), y = position.getY(), height = position.getHeight(); CollisionMatrix matrix = region.getMatrix(height); - boolean block = false; if (type == ObjectType.FLOOR_DECORATION.getValue() && definition.isInteractive()) { block = true; } - Predicate walls = (value) -> value >= ObjectType.LENGTHWISE_WALL.getValue() + // TODO figure out the other ObjectTypes and get rid of all the getValue() calls + + Predicate walls = value -> value >= ObjectType.LENGTHWISE_WALL.getValue() && value <= ObjectType.RECTANGULAR_CORNER.getValue() || value == ObjectType.DIAGONAL_WALL.getValue(); - Predicate roofs = (value) -> value > ObjectType.DIAGONAL_INTERACTABLE.getValue() + Predicate roofs = value -> value > ObjectType.DIAGONAL_INTERACTABLE.getValue() && value < ObjectType.FLOOR_DECORATION.getValue(); - if (walls.test(type) || roofs.test(type)) { - block = true; - } - - if (type == 10 && definition.isSolid()) { + if (walls.test(type) || roofs.test(type) || type == ObjectType.INTERACTABLE.getValue() && definition.isSolid()) { block = true; } @@ -144,11 +150,13 @@ public final class GameObjectDecoder { Position nextPosition = new Position(nextLocalX, nextLocalY); Region next = regions.fromPosition(nextPosition); - int nextX = nextPosition.getX() % Region.SIZE + dx, nextY = nextPosition.getY() % Region.SIZE - + dy; + int nextX = nextPosition.getX() % Region.SIZE + dx; + int nextY = nextPosition.getY() % Region.SIZE + dy; + if (nextX > 7) { nextX -= 7; } + if (nextY > 7) { nextY -= 7; } @@ -173,12 +181,11 @@ public final class GameObjectDecoder { Region region = regions.fromPosition(position); int x = position.getX(), y = position.getY(), height = position.getHeight(); - CollisionMatrix current = region.getMatrix(height); - boolean block = false; if ((attributes & BLOCKED_TILE) != 0) { block = true; } + if ((attributes & BRIDGE_TILE) != 0) { if (height > 0) { block = true; @@ -188,7 +195,7 @@ public final class GameObjectDecoder { if (block) { int localX = x % Region.SIZE, localY = y % Region.SIZE; - current.block(localX, localY); + region.getMatrix(height).block(localX, localY); } } @@ -249,6 +256,7 @@ public final class GameObjectDecoder { int attributes = 0; while (true) { int attributeId = buffer.get() & 0xFF; + if (attributeId == 0) { decodeAttributes(attributes, position); break; diff --git a/game/src/main/org/apollo/game/fs/decoder/SynchronousDecoder.java b/game/src/main/org/apollo/game/fs/decoder/SynchronousDecoder.java new file mode 100644 index 00000000..acc88f53 --- /dev/null +++ b/game/src/main/org/apollo/game/fs/decoder/SynchronousDecoder.java @@ -0,0 +1,54 @@ +package org.apollo.game.fs.decoder; + +import org.apollo.util.ThreadUtil; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +/** + * A composite decoder that executes each child in parallel. + * + * @author Major + */ +public final class SynchronousDecoder { + + /** + * The time to wait before cancelling the decoding. + */ + private static final int TIMEOUT = 15_000; + + /** + * The Executor used to execute the Runnable(s). + */ + private final ExecutorService executor = Executors.newFixedThreadPool(ThreadUtil.AVAILABLE_PROCESSORS, + ThreadUtil.create("SynchronousDecoder")); + + /** + * The List of Runnables. + */ + private final List runnables; + + /** + * Creates the SynchronousDecoder. + * + * @param runnables The {@link Runnable}s to execute. + */ + public SynchronousDecoder(Runnable... runnables) { + this.runnables = Arrays.asList(runnables); + } + + /** + * Starts this SynchronousDecoder. + * + * @throws InterruptedException If a decoder is still running after {@link #TIMEOUT} ms. + */ + public void block() throws InterruptedException { + runnables.forEach(executor::submit); + executor.shutdown(); + executor.awaitTermination(TIMEOUT, TimeUnit.MILLISECONDS); + } + +} \ No newline at end of file diff --git a/game/src/main/org/apollo/game/io/EquipmentDefinitionParser.java b/game/src/main/org/apollo/game/io/EquipmentDefinitionParser.java index e1b27e84..07e6b0a3 100644 --- a/game/src/main/org/apollo/game/io/EquipmentDefinitionParser.java +++ b/game/src/main/org/apollo/game/io/EquipmentDefinitionParser.java @@ -1,67 +1,83 @@ package org.apollo.game.io; +import java.io.BufferedInputStream; import java.io.DataInputStream; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.UncheckedIOException; import org.apollo.cache.def.EquipmentDefinition; /** - * A class that parses the {@code data/equipment-[release].dat} file to create an array of {@link EquipmentDefinition}s. + * A class that parses the {@code data/equipment-[release].dat} file to create an array of {@link + * EquipmentDefinition}s. * * @author Graham */ -public final class EquipmentDefinitionParser { +public final class EquipmentDefinitionParser implements Runnable { /** - * The input stream. + * Creates an {@link EquipmentDefinitionParser} that reads from the file located at the specified {@code path}. + * + * @param path The path to the file. + * @return The EquipmentDefinitionParser. + * @throws UncheckedIOException If there is an error creating the {@link FileInputStream}. + */ + public static EquipmentDefinitionParser fromFile(String path) { + try { + return new EquipmentDefinitionParser(new BufferedInputStream(new FileInputStream(path))); + } catch (IOException e) { + throw new UncheckedIOException("Error creating EquipmentDefinitionParser.", e); + } + } + + /** + * The InputStream. */ private final InputStream is; /** - * Creates the equipment definition parser. + * Creates the EquipmentDefinitionParser. * - * @param is The input stream. + * @param is The {@link InputStream}. */ public EquipmentDefinitionParser(InputStream is) { this.is = is; } - /** - * Parses the input stream. - * - * @return The equipment definition array. - * @throws IOException If an I/O error occurs. - */ - public EquipmentDefinition[] parse() throws IOException { - DataInputStream dis = new DataInputStream(is); + @Override + public void run() { + try (DataInputStream in = new DataInputStream(is)) { + int count = in.readShort() & 0xFFFF; + EquipmentDefinition[] definitions = new EquipmentDefinition[count]; - int count = dis.readShort() & 0xFFFF; - EquipmentDefinition[] definitions = new EquipmentDefinition[count]; + for (int id = 0; id < count; id++) { + int slot = in.readByte() & 0xFF; + if (slot != 0xFF) { + boolean twoHanded = in.readBoolean(); + boolean fullBody = in.readBoolean(); + boolean fullHat = in.readBoolean(); + boolean fullMask = in.readBoolean(); + int attack = in.readByte() & 0xFF; + int strength = in.readByte() & 0xFF; + int defence = in.readByte() & 0xFF; + int ranged = in.readByte() & 0xFF; + int magic = in.readByte() & 0xFF; - for (int id = 0; id < count; id++) { - int slot = dis.readByte() & 0xFF; - if (slot != 0xFF) { - boolean twoHanded = dis.readBoolean(); - boolean fullBody = dis.readBoolean(); - boolean fullHat = dis.readBoolean(); - boolean fullMask = dis.readBoolean(); - int attack = dis.readByte() & 0xFF; - int strength = dis.readByte() & 0xFF; - int defence = dis.readByte() & 0xFF; - int ranged = dis.readByte() & 0xFF; - int magic = dis.readByte() & 0xFF; + EquipmentDefinition definition = new EquipmentDefinition(id); + definition.setLevels(attack, strength, defence, ranged, magic); + definition.setSlot(slot); + definition.setFlags(twoHanded, fullBody, fullHat, fullMask); - EquipmentDefinition definition = new EquipmentDefinition(id); - definition.setLevels(attack, strength, defence, ranged, magic); - definition.setSlot(slot); - definition.setFlags(twoHanded, fullBody, fullHat, fullMask); - - definitions[id] = definition; + definitions[id] = definition; + } } - } - return definitions; + EquipmentDefinition.init(definitions); + } catch (IOException e) { + throw new UncheckedIOException("Error parsing EquipmentDefinitions.", e); + } } } \ No newline at end of file diff --git a/game/src/main/org/apollo/game/model/World.java b/game/src/main/org/apollo/game/model/World.java index 57ae4706..af48bbf9 100644 --- a/game/src/main/org/apollo/game/model/World.java +++ b/game/src/main/org/apollo/game/model/World.java @@ -1,24 +1,18 @@ package org.apollo.game.model; -import java.io.BufferedInputStream; -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; +import org.apollo.Server; import org.apollo.Service; import org.apollo.cache.IndexedFileSystem; import org.apollo.cache.decoder.ItemDefinitionDecoder; import org.apollo.cache.decoder.NpcDefinitionDecoder; import org.apollo.cache.decoder.ObjectDefinitionDecoder; -import org.apollo.cache.def.EquipmentDefinition; -import org.apollo.cache.def.ItemDefinition; -import org.apollo.cache.def.NpcDefinition; -import org.apollo.cache.def.ObjectDefinition; import org.apollo.game.command.CommandDispatcher; import org.apollo.game.fs.decoder.GameObjectDecoder; +import org.apollo.game.fs.decoder.SynchronousDecoder; import org.apollo.game.io.EquipmentDefinitionParser; import org.apollo.game.model.area.Region; import org.apollo.game.model.area.RegionRepository; @@ -27,7 +21,6 @@ import org.apollo.game.model.entity.EntityType; import org.apollo.game.model.entity.MobRepository; import org.apollo.game.model.entity.Npc; import org.apollo.game.model.entity.Player; -import org.apollo.game.model.entity.obj.GameObject; import org.apollo.game.model.event.Event; import org.apollo.game.model.event.EventListener; import org.apollo.game.model.event.EventListenerChainSet; @@ -87,11 +80,6 @@ public final class World { */ private final EventListenerChainSet events = new EventListenerChainSet(); - /** - * The ScheduledTask that moves Npcs. - */ - private NpcMovementTask npcMovement; - /** * The {@link MobRepository} of {@link Npc}s. */ @@ -107,32 +95,30 @@ public final class World { */ private final Map players = new HashMap<>(); - /** - * The {@link PluginManager}. - */ - private PluginManager pluginManager; - /** * This world's {@link RegionRepository}. */ private final RegionRepository regions = RegionRepository.immutable(); - /** - * The release number (i.e. version) of this world. - */ - private int releaseNumber; - /** * The scheduler. */ private final Scheduler scheduler = new Scheduler(); /** - * Creates the world. + * The ScheduledTask that moves Npcs. */ - public World() { + private NpcMovementTask npcMovement; - } + /** + * The {@link PluginManager}. + */ + private PluginManager pluginManager; + + /** + * The release number (i.e. version) of this world. + */ + private int releaseNumber; /** * Gets the command dispatcher. @@ -210,32 +196,11 @@ public final class World { public void init(int release, IndexedFileSystem fs, PluginManager manager) throws Exception { releaseNumber = release; - ItemDefinitionDecoder itemDecoder = new ItemDefinitionDecoder(fs); - ItemDefinition[] items = itemDecoder.decode(); - ItemDefinition.init(items); - logger.fine("Loaded " + items.length + " item definitions."); + SynchronousDecoder decoder = new SynchronousDecoder(new ItemDefinitionDecoder(fs), + new NpcDefinitionDecoder(fs), new GameObjectDecoder(fs, this), + EquipmentDefinitionParser.fromFile("data/equipment-" + release + "" + ".dat")); - try (InputStream is = new BufferedInputStream(new FileInputStream("data/equipment-" + release + ".dat"))) { - EquipmentDefinitionParser parser = new EquipmentDefinitionParser(is); - EquipmentDefinition[] defs = parser.parse(); - EquipmentDefinition.init(defs); - logger.fine("Loaded " + defs.length + " equipment definitions."); - } - - NpcDefinitionDecoder npcDecoder = new NpcDefinitionDecoder(fs); - NpcDefinition[] npcs = npcDecoder.decode(); - NpcDefinition.init(npcs); - logger.fine("Loaded " + npcs.length + " npc definitions."); - - ObjectDefinitionDecoder objectDecoder = new ObjectDefinitionDecoder(fs); - ObjectDefinition[] objectDefs = objectDecoder.decode(); - ObjectDefinition.init(objectDefs); - logger.fine("Loaded " + objectDefs.length + " object definitions."); - - GameObjectDecoder staticDecoder = new GameObjectDecoder(fs, regions); - GameObject[] objects = staticDecoder.decode(this); - placeEntities(objects); - logger.fine("Loaded " + objects.length + " static objects."); + decoder.block(); npcMovement = new NpcMovementTask(regions); // Must be exactly here because of ordering issues. scheduler.schedule(npcMovement); @@ -291,6 +256,7 @@ public final class World { } else { logger.warning("Failed to register npc, repository capacity reached: [count=" + npcRepository.size() + "]"); } + return success; } @@ -384,13 +350,4 @@ public final class World { } } - /** - * Adds entities to regions in the {@link RegionRepository}. By default, we do not notify listeners. - * - * @param entities The entities. - */ - private void placeEntities(Entity... entities) { - Arrays.stream(entities).forEach(entity -> regions.fromPosition(entity.getPosition()).addEntity(entity, false)); - } - } \ No newline at end of file diff --git a/game/src/main/org/apollo/game/sync/task/NpcSynchronizationTask.java b/game/src/main/org/apollo/game/sync/task/NpcSynchronizationTask.java index bb34123a..7876936d 100644 --- a/game/src/main/org/apollo/game/sync/task/NpcSynchronizationTask.java +++ b/game/src/main/org/apollo/game/sync/task/NpcSynchronizationTask.java @@ -21,8 +21,13 @@ import org.apollo.game.sync.seg.SynchronizationSegment; public final class NpcSynchronizationTask extends SynchronizationTask { /** - * The maximum number of npcs to load per cycle. This prevents the update packet from becoming too large (the client - * uses a 5000 byte buffer) and also stops old spec PCs from crashing when they login or teleport. + * The maximum amount of local npcs. + */ + private static final int MAXIMUM_LOCAL_NPCS = 255; + + /** + * The maximum number of npcs to load per cycle. This prevents the update packet from becoming too large (the + * client uses a 5000 byte buffer) and also stops old spec PCs from crashing when they login or teleport. */ private static final int NEW_NPCS_PER_CYCLE = 20; @@ -42,41 +47,49 @@ public final class NpcSynchronizationTask extends SynchronizationTask { @Override public void run() { - List localNpcs = player.getLocalNpcList(); + List locals = player.getLocalNpcList(); List segments = new ArrayList<>(); - int oldLocalNpcs = localNpcs.size(); + + int originalCount = locals.size(); final Position playerPosition = player.getPosition(); - for (Iterator it = localNpcs.iterator(); it.hasNext();) { - Npc npc = it.next(); - if (!npc.isActive() || npc.isTeleporting() || npc.getPosition().getLongestDelta(playerPosition) > player.getViewingDistance() || !npc.getPosition().isWithinDistance(playerPosition, player.getViewingDistance())) { - it.remove(); + int distance = player.getViewingDistance(); + for (Iterator iterator = locals.iterator(); iterator.hasNext(); ) { + Npc npc = iterator.next(); + Position position = npc.getPosition(); + + if (!npc.isActive() || npc.isTeleporting() || position.getLongestDelta(playerPosition) > distance + || !position.isWithinDistance(playerPosition, distance)) { + iterator.remove(); + segments.add(new RemoveMobSegment()); } else { segments.add(new MovementSegment(npc.getBlockSet(), npc.getDirections())); } } - int added = 0; + int added = 0, count = locals.size(); for (Npc npc : player.getWorld().getNpcRepository()) { - if (localNpcs.size() >= 255) { + if (count >= MAXIMUM_LOCAL_NPCS) { player.flagExcessiveNpcs(); break; } else if (added >= NEW_NPCS_PER_CYCLE) { break; } - Position npcPosition = npc.getPosition(); - if (npcPosition.isWithinDistance(playerPosition, player.getViewingDistance()) && !localNpcs.contains(npc)) { - localNpcs.add(npc); + Position position = npc.getPosition(); + if (position.isWithinDistance(playerPosition, distance) && !locals.contains(npc)) { + locals.add(npc); + count++; added++; + npc.turnTo(npc.getFacingPosition()); - segments.add(new AddNpcSegment(npc.getBlockSet(), npc.getIndex(), npcPosition, npc.getId())); + segments.add(new AddNpcSegment(npc.getBlockSet(), npc.getIndex(), position, npc.getId())); } } - player.send(new NpcSynchronizationMessage(playerPosition, segments, oldLocalNpcs)); + player.send(new NpcSynchronizationMessage(playerPosition, segments, originalCount)); } } \ No newline at end of file diff --git a/game/src/main/org/apollo/game/sync/task/PlayerSynchronizationTask.java b/game/src/main/org/apollo/game/sync/task/PlayerSynchronizationTask.java index 3decca26..06290056 100644 --- a/game/src/main/org/apollo/game/sync/task/PlayerSynchronizationTask.java +++ b/game/src/main/org/apollo/game/sync/task/PlayerSynchronizationTask.java @@ -6,7 +6,6 @@ import java.util.List; import org.apollo.game.message.impl.PlayerSynchronizationMessage; import org.apollo.game.model.Position; -import org.apollo.game.model.entity.MobRepository; import org.apollo.game.model.entity.Player; import org.apollo.game.sync.block.AppearanceBlock; import org.apollo.game.sync.block.ChatBlock; @@ -25,6 +24,11 @@ import org.apollo.game.sync.seg.TeleportSegment; */ public final class PlayerSynchronizationTask extends SynchronizationTask { + /** + * The maximum amount of local players. + */ + private static final int MAXIMUM_LOCAL_PLAYERS = 255; + /** * The maximum number of players to load per cycle. This prevents the update packet from becoming too large (the * client uses a 5000 byte buffer) and also stops old spec PCs from crashing when they login or teleport. @@ -32,14 +36,14 @@ public final class PlayerSynchronizationTask extends SynchronizationTask { private static final int NEW_PLAYERS_PER_CYCLE = 20; /** - * The player. + * The Player. */ private final Player player; /** - * Creates the {@link PlayerSynchronizationTask} for the specified player. + * Creates the {@link PlayerSynchronizationTask} for the specified {@link Player}. * - * @param player The player. + * @param player The Player. */ public PlayerSynchronizationTask(Player player) { this.player = player; @@ -50,80 +54,80 @@ public final class PlayerSynchronizationTask extends SynchronizationTask { Position lastKnownRegion = player.getLastKnownRegion(); boolean regionChanged = player.hasRegionChanged(); - SynchronizationSegment segment; SynchronizationBlockSet blockSet = player.getBlockSet(); + if (blockSet.contains(ChatBlock.class)) { blockSet = blockSet.clone(); blockSet.remove(ChatBlock.class); } - if (player.isTeleporting() || player.hasRegionChanged()) { - segment = new TeleportSegment(blockSet, player.getPosition()); - } else { - segment = new MovementSegment(blockSet, player.getDirections()); - } + Position position = player.getPosition(); + + SynchronizationSegment segment = (player.isTeleporting() || player.hasRegionChanged()) ? + new TeleportSegment(blockSet, position) : new MovementSegment(blockSet, player.getDirections()); List localPlayers = player.getLocalPlayerList(); - int oldLocalPlayers = localPlayers.size(); + int oldCount = localPlayers.size(); + List segments = new ArrayList<>(); + int distance = player.getViewingDistance(); - for (Iterator it = localPlayers.iterator(); it.hasNext(); ) { - Player other = it.next(); + for (Iterator iterator = localPlayers.iterator(); iterator.hasNext(); ) { + Player other = iterator.next(); - if (removePlayer(other)) { - it.remove(); + if (removeable(position, distance, other)) { + iterator.remove(); segments.add(new RemoveMobSegment()); } else { segments.add(new MovementSegment(other.getBlockSet(), other.getDirections())); } } - int added = 0; + int added = 0, count = localPlayers.size(); - MobRepository repository = player.getWorld().getPlayerRepository(); - for (Player other : repository) { - if (localPlayers.size() >= 255) { + for (Player other : player.getWorld().getPlayerRepository()) { + if (count >= MAXIMUM_LOCAL_PLAYERS) { player.flagExcessivePlayers(); break; } else if (added >= NEW_PLAYERS_PER_CYCLE) { break; } - if (other != player && other.getPosition().isWithinDistance(player.getPosition(), player.getViewingDistance()) && !localPlayers.contains(other)) { + Position local = other.getPosition(); + + if (other != player && local.isWithinDistance(position, distance) && !localPlayers.contains(other)) { localPlayers.add(other); + count++; added++; blockSet = other.getBlockSet(); - if (!blockSet.contains(AppearanceBlock.class)) { - // TODO check if client has cached appearance + if (!blockSet.contains(AppearanceBlock.class)) { // TODO check if client has cached appearance blockSet = blockSet.clone(); blockSet.add(SynchronizationBlock.createAppearanceBlock(other)); } - segments.add(new AddPlayerSegment(blockSet, other.getIndex(), other.getPosition())); + segments.add(new AddPlayerSegment(blockSet, other.getIndex(), local)); } } - PlayerSynchronizationMessage message = new PlayerSynchronizationMessage(lastKnownRegion, player.getPosition(), - regionChanged, segment, oldLocalPlayers, segments); + PlayerSynchronizationMessage message = new PlayerSynchronizationMessage(lastKnownRegion, position, + regionChanged, segment, oldCount, segments); player.send(message); } /** * Returns whether or not the specified {@link Player} should be removed. * + * @param position The {@link Position} of the Player being updated. * @param other The Player being tested. * @return {@code true} iff the specified Player should be removed. */ - private boolean removePlayer(Player other) { + private boolean removeable(Position position, int distance, Player other) { if (other.isTeleporting() || !other.isActive()) { return true; } - Position position = player.getPosition(); Position otherPosition = other.getPosition(); - int distance = player.getViewingDistance(); - return otherPosition.getLongestDelta(position) > distance || !otherPosition.isWithinDistance(position, distance); } diff --git a/game/src/main/org/apollo/game/sync/task/PostPlayerSynchronizationTask.java b/game/src/main/org/apollo/game/sync/task/PostPlayerSynchronizationTask.java index fc95e3f6..baa4ecb3 100644 --- a/game/src/main/org/apollo/game/sync/task/PostPlayerSynchronizationTask.java +++ b/game/src/main/org/apollo/game/sync/task/PostPlayerSynchronizationTask.java @@ -28,6 +28,7 @@ public final class PostPlayerSynchronizationTask extends SynchronizationTask { player.setTeleporting(false); player.setRegionChanged(false); player.resetBlockSet(); + if (!player.isExcessivePlayersSet()) { player.incrementViewingDistance(); } else { diff --git a/util/src/main/org/apollo/util/CompressionUtil.java b/util/src/main/org/apollo/util/CompressionUtil.java index e64a67f7..8934b329 100644 --- a/util/src/main/org/apollo/util/CompressionUtil.java +++ b/util/src/main/org/apollo/util/CompressionUtil.java @@ -29,6 +29,7 @@ public final class CompressionUtil { */ public static byte[] bzip2(byte[] uncompressed) throws IOException { ByteArrayOutputStream bout = new ByteArrayOutputStream(); + try (BZip2CompressorOutputStream os = new BZip2CompressorOutputStream(bout, 1)) { os.write(uncompressed); os.finish(); @@ -40,22 +41,6 @@ public final class CompressionUtil { } } - /** - * Gzips the specified array. - * - * @param uncompressed The uncompressed array. - * @return The compressed array. - * @throws IOException If there is an error compressing the array. - */ - public static byte[] gzip(byte[] uncompressed) throws IOException { - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - try (DeflaterOutputStream os = new GZIPOutputStream(bout)) { - os.write(uncompressed); - os.finish(); - return bout.toByteArray(); - } - } - /** * Debzip2s the compressed array and places the result into the decompressed array. * @@ -90,27 +75,44 @@ public final class CompressionUtil { } /** - * Degzips the compressed {@link ByteBuffer} and returns the result as a byte array. + * Degzips all of the datain the specified {@link ByteBuffer}. * * @param compressed The compressed buffer. * @return The decompressed array. * @throws IOException If there is an error decompressing the buffer. */ public static byte[] degzip(ByteBuffer compressed) throws IOException { - byte[] data = new byte[compressed.remaining()]; - compressed.get(data); + try (InputStream is = new GZIPInputStream(new ByteArrayInputStream(compressed.array())); + ByteArrayOutputStream out = new ByteArrayOutputStream()) { + byte[] buffer = new byte[1024]; - try (InputStream is = new GZIPInputStream(new ByteArrayInputStream(data)); ByteArrayOutputStream os = new ByteArrayOutputStream()) { while (true) { - byte[] buf = new byte[1024]; - int read = is.read(buf, 0, buf.length); + int read = is.read(buffer, 0, buffer.length); if (read == -1) { break; } - os.write(buf, 0, read); + + out.write(buffer, 0, read); } - return os.toByteArray(); + return out.toByteArray(); + } + } + + /** + * Gzips the specified array. + * + * @param uncompressed The uncompressed array. + * @return The compressed array. + * @throws IOException If there is an error compressing the array. + */ + public static byte[] gzip(byte[] uncompressed) throws IOException { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + + try (DeflaterOutputStream os = new GZIPOutputStream(bout)) { + os.write(uncompressed); + os.finish(); + return bout.toByteArray(); } } diff --git a/util/src/main/org/apollo/util/ThreadUtil.java b/util/src/main/org/apollo/util/ThreadUtil.java index 22b765ae..429f49e1 100644 --- a/util/src/main/org/apollo/util/ThreadUtil.java +++ b/util/src/main/org/apollo/util/ThreadUtil.java @@ -27,20 +27,20 @@ public final class ThreadUtil { private static final Logger LOGGER = Logger.getLogger(ThreadUtil.class.getSimpleName()); /** - * The default {@link UncaughtExceptionHandler} which raises an error from the logger with the exception and name of + * The default {@link UncaughtExceptionHandler} which raises an error from the logger with the exception and name + * of * the specified thread the exception occurred in. */ - private static final UncaughtExceptionHandler DEFAULT_EXCEPTION_HANDLER = (thread, exception) -> LOGGER.log(Level.SEVERE, - "Exception occured in thread " + thread.getName(), exception); + private static final UncaughtExceptionHandler DEFAULT_EXCEPTION_HANDLER = + (thread, exception) -> LOGGER.log(Level.SEVERE, "Exception in thread " + thread.getName(), exception); /** * Builds a {@link ThreadFactory} using the specified {@code String} name-format, normal thread priority and the * default {@link UncaughtExceptionHandler}. - * - * @see #DEFAULT_EXCEPTION_HANDLER * - * @param name The name-format used when creating threads, may not be {@code null}. - * @return A new {@link ThreadFactory} from the specified parameters, never {@code null}. + * @param name The name-format used when creating threads. Must not be {@code null}. + * @return The {@link ThreadFactory}. Will never be {@code null}. + * @see #DEFAULT_EXCEPTION_HANDLER */ public static ThreadFactory create(String name) { return create(name, Thread.NORM_PRIORITY, DEFAULT_EXCEPTION_HANDLER); @@ -50,9 +50,9 @@ public final class ThreadUtil { * Builds a {@link ThreadFactory} using the specified {@code String} name-format, priority and the * {@link #DEFAULT_EXCEPTION_HANDLER}. * - * @param name The name-format used when creating threads, may not be {@code null}. + * @param name The name-format used when creating threads. Must not be {@code null}. * @param priority The priority used when creating threads. - * @return A new {@link ThreadFactory} from the specified parameters, never {@code null}. + * @return The {@link ThreadFactory}. Will never be {@code null}. */ public static ThreadFactory create(String name, int priority) { return create(name, priority, DEFAULT_EXCEPTION_HANDLER); @@ -65,10 +65,11 @@ public final class ThreadUtil { * @param name The name-format used when creating threads. Must not be {@code null}. * @param priority The priority used when creating threads. * @param handler The {@link UncaughtExceptionHandler} used when creating threads. Must not be {@code null}. - * @return A new {@link ThreadFactory} using the specified parameters. + * @return The {@link ThreadFactory}. Will never be {@code null}. */ public static ThreadFactory create(String name, int priority, UncaughtExceptionHandler handler) { - Objects.requireNonNull(priority); + Objects.requireNonNull(name, "ThreadFactory name must not be null."); + Objects.requireNonNull(handler, "UncaughtExceptionHandler must not be null."); ThreadFactoryBuilder builder = new ThreadFactoryBuilder(); builder.setNameFormat(name);