diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 6efbd4f892..ab21709a62 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -407,6 +407,16 @@ public interface Client extends GameShell */ IndexDataBase getIndexScripts(); + /** + * Gets the config archive, containing Varplayer and Varbit definitions + */ + IndexDataBase getConfigArchive(); + + /** + * Gets the config index. + */ + IndexDataBase getIndexConfig(); + /** * Returns the x-axis base coordinate. *

@@ -810,9 +820,10 @@ public interface Client extends GameShell void setVarbitValue(int[] varps, int varbit, int value); /** - * @return the total number of VarbitDefinition + * Gets the varbit composition for a given varbit id */ - int getVarbitCount(); + @Nullable + VarbitDefinition getVarbitDefinition(int id); /** * Gets the widget flags table. diff --git a/runelite-api/src/main/java/net/runelite/api/IndexDataBase.java b/runelite-api/src/main/java/net/runelite/api/IndexDataBase.java index 58fb7d498a..4aea415d86 100644 --- a/runelite-api/src/main/java/net/runelite/api/IndexDataBase.java +++ b/runelite-api/src/main/java/net/runelite/api/IndexDataBase.java @@ -9,4 +9,9 @@ public interface IndexDataBase * Returns true if any cache overlay in this index is outdated due to hash mismatch */ boolean isOverlayOutdated(); + + /** + * Get the child file ids for a given group + */ + int[] getFileIds(int group); } diff --git a/runelite-api/src/main/java/net/runelite/api/VarbitDefinition.java b/runelite-api/src/main/java/net/runelite/api/VarbitDefinition.java new file mode 100644 index 0000000000..b0fbf7266b --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/VarbitDefinition.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020, Adam + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.api; + +public interface VarbitDefinition +{ + /** + * The varp index for this varbit + */ + int getIndex(); + + /** + * The least significant bit of the varbit + */ + int getLeastSignificantBit(); + + /** + * The most significant bit of the varbit (inclusive) + */ + int getMostSignificantBit(); +} \ No newline at end of file diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/VarbitMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/VarbitMixin.java index ab0998a537..30932ffa1e 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/VarbitMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/VarbitMixin.java @@ -10,7 +10,6 @@ import net.runelite.api.mixins.Inject; import net.runelite.api.mixins.Mixin; import net.runelite.api.mixins.Shadow; import net.runelite.rs.api.RSClient; -import net.runelite.rs.api.RSEvictingDualNodeHashTable; import net.runelite.rs.api.RSVarbitDefinition; @Mixin(RSClient.class) @@ -54,25 +53,44 @@ public abstract class VarbitMixin implements RSClient setVarbitValue(getVarps(), varbitId, value); } + @Inject + @Override + public RSVarbitDefinition getVarbitDefinition(int id) + { + assert isClientThread(); + + RSVarbitDefinition varbit; + varbit = varbitCache.getIfPresent(id); + if (varbit != null) + { + return varbit; + } + varbit = (RSVarbitDefinition) getVarbitCache().get(id); + if (varbit != null && !(varbit.getIndex() == 0 && varbit.getMostSignificantBit() == 0 && varbit.getLeastSignificantBit() == 0)) + { + return varbit; + } + + byte[] fileData = getConfigArchive().getConfigData(VARBITS_GROUP, id); + if (fileData == null) + { + return null; + } + varbit = newVarbitDefinition(); + varbit.decode(newBuffer(fileData)); + return varbit; + } + @Inject @Override public int getVarbitValue(int[] varps, int varbitId) { assert client.isClientThread(); - RSVarbitDefinition v = varbitCache.getIfPresent(varbitId); + RSVarbitDefinition v = getVarbitDefinition(varbitId); if (v == null) { - client.getVarbit(varbitId); // load varbit into cache - RSEvictingDualNodeHashTable varbits = client.getVarbitCache(); - v = (RSVarbitDefinition) varbits.get(varbitId); // get from cache - varbitCache.put(varbitId, v); - } - - if (v.getIndex() == 0 && v.getLeastSignificantBit() == 0 && v.getMostSignificantBit() == 0) - { - getLogger().debug("Varbit {} doesn't exist!", varbitId); - return 0; + throw new IndexOutOfBoundsException(String.format("Varbit %d does not exist!", varbitId)); // oob for "backwards compatibility lol" } int value = varps[v.getIndex()]; @@ -86,13 +104,10 @@ public abstract class VarbitMixin implements RSClient @Override public void setVarbitValue(int[] varps, int varbitId, int value) { - RSVarbitDefinition v = varbitCache.getIfPresent(varbitId); + RSVarbitDefinition v = getVarbitDefinition(varbitId); if (v == null) { - client.getVarbit(varbitId); // load varbit into cache - RSEvictingDualNodeHashTable varbits = client.getVarbitCache(); - v = (RSVarbitDefinition) varbits.get(varbitId); // get from cache - varbitCache.put(varbitId, v); + throw new IndexOutOfBoundsException(String.format("Varbit %d does not exist!", varbitId)); // oob for "backwards compatibility lol" } int lsb = v.getLeastSignificantBit(); @@ -155,11 +170,4 @@ public abstract class VarbitMixin implements RSClient { return getVarcs().getVarcMap(); } - - @Inject - @Override - public int getVarbitCount() - { - return getConfigArchive().getGroupFileCount(VARBITS_GROUP); - } } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java index 653bd83962..fe3f6c7003 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSAbstractArchive.java @@ -8,6 +8,7 @@ public interface RSAbstractArchive extends IndexDataBase @Import("takeFile") byte[] getConfigData(int archiveId, int fileId); - @Import("getGroupFileCount") - int getGroupFileCount(int group); + @Import("getGroupFileIds") + @Override + int[] getFileIds(int group); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java index 597b93e4f1..8a74bb104f 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSClient.java @@ -458,6 +458,7 @@ public interface RSClient extends RSGameShell, Client void setIndexedSpritePalette(int[] indexedSpritePalette); @Import("archive2") + @Override RSArchive getConfigArchive(); @Import("archive6") @@ -1275,4 +1276,10 @@ public interface RSClient extends RSGameShell, Client @Import("rightTitleSprite") void setRightTitleSprite(Sprite background); + + @Construct + RSBuffer newBuffer(byte[] bytes); + + @Construct + RSVarbitDefinition newVarbitDefinition(); } diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSVarbitDefinition.java b/runescape-api/src/main/java/net/runelite/rs/api/RSVarbitDefinition.java index 947106c183..4e6850e27d 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSVarbitDefinition.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSVarbitDefinition.java @@ -1,8 +1,9 @@ package net.runelite.rs.api; +import net.runelite.api.VarbitDefinition; import net.runelite.mapping.Import; -public interface RSVarbitDefinition extends RSDualNode +public interface RSVarbitDefinition extends VarbitDefinition, RSDualNode { @Import("baseVar") int getIndex(); @@ -12,4 +13,7 @@ public interface RSVarbitDefinition extends RSDualNode @Import("endBit") int getMostSignificantBit(); + + @Import("decode") + void decode(RSBuffer buffer); }