lostItems = new ArrayList<>();
- for (Item i : items)
- {
- int id = i.getId();
- if (id == -1)
- {
- continue;
- }
-
- ItemDefinition c = itemManager.getItemDefinition(i.getId());
- Widget itemWidget = createItemWidget(i.getQuantity(), c);
-
- // Bonds are always kept and do not count towards the limit.
- if (id == ItemID.OLD_SCHOOL_BOND || id == ItemID.OLD_SCHOOL_BOND_UNTRADEABLE)
- {
- keptItems.add(itemWidget);
- continue;
- }
-
- // Certain items are always lost on death and have a white outline which we need to readd
- AlwaysLostItem item = AlwaysLostItem.getByItemID(i.getId());
- if (item != null)
- {
- // Some of these items are kept on death (outside wildy), like the Rune pouch. Ignore them
- if (!item.isKept() || wildyLevel > 0)
- {
- itemWidget.setOnOpListener(SCRIPT_ID, 0, i.getQuantity(), c.getName());
- itemWidget.setBorderType(2);
- lostItems.add(itemWidget);
- hasAlwaysLost = true;
- continue;
- }
- }
-
- // Keep most valuable items regardless of trade-ability.
- if (keepCount > 0)
- {
- if (i.getQuantity() > keepCount)
- {
- keptItems.add(createItemWidget(keepCount, c));
- itemWidget.setItemQuantity(i.getQuantity() - keepCount);
- keepCount = 0;
- }
- else
- {
- keptItems.add(itemWidget);
- keepCount -= i.getQuantity();
- continue;
- }
- }
-
-
- if (!checkTradeable(i.getId(), c) && wildyLevel < 21)
- {
- // Certain items are turned into broken variants inside the wilderness.
- if (BrokenOnDeathItem.check(i.getId()))
- {
- keptItems.add(itemWidget);
- continue;
- }
-
- // Ignore all non tradeables in wildy except for the above case(s).
- if (wildyLevel > 0)
- {
- lostItems.add(itemWidget);
- continue;
- }
-
- keptItems.add(itemWidget);
- }
- else
- {
- itemWidget.setOnOpListener(SCRIPT_ID, 0, i.getQuantity(), c.getName());
- lostItems.add(itemWidget);
- }
- }
-
- int rows = keptItems.size() > MAX_ROW_ITEMS ? keptItems.size() / MAX_ROW_ITEMS : 0;
- // Adjust items lost container position if new rows were added to kept items container
- lost.setOriginalY(ORIGINAL_LOST_Y + (rows * Y_INCREMENT));
- lost.setOriginalHeight(ORIGINAL_LOST_HEIGHT - (rows * Y_INCREMENT));
- setWidgetChildren(kept, keptItems);
- setWidgetChildren(lost, lostItems);
-
- updateKeptWidgetInfoText();
- }
- }
-
- */
-/**
- * Wrapper for widget.setChildren() but updates the child index and original positions
- * Used for Items Kept and Lost containers
- *
- * @param parent Widget to override children
- * @param widgets Children to set on parent
- *
- * Creates the text to be displayed in the right side of the interface based on current selections
- *
- * Corrects the Information panel based on the item containers
- *
- * Creates an Item Widget for use inside the Kept on Death Interface
- * @param qty Amount of item
- * @param c Items Composition
- * @return
- *//*
-
- private void setWidgetChildren(Widget parent, List widgets)
- {
- Widget[] children = parent.getChildren();
- if (children == null)
- {
- // Create a child so we can copy the returned Widget[] and avoid hn casting issues from creating a new Widget[]
- parent.createChild(0, WidgetType.GRAPHIC);
- children = parent.getChildren();
- }
- Widget[] itemsArray = Arrays.copyOf(children, widgets.size());
-
- int parentId = parent.getId();
- int startingIndex = 0;
- for (Widget w : widgets)
- {
- int originalX = STARTING_X + ((startingIndex % MAX_ROW_ITEMS) * X_INCREMENT);
- int originalY = STARTING_Y + ((startingIndex / MAX_ROW_ITEMS) * Y_INCREMENT);
-
- w.setParentId(parentId);
- w.setId(parentId);
- w.setIndex(startingIndex);
-
- w.setOriginalX(originalX);
- w.setOriginalY(originalY);
- w.revalidate();
-
- itemsArray[startingIndex] = w;
- startingIndex++;
- }
-
- parent.setChildren(itemsArray);
- parent.revalidate();
- }
-
- */
-/**
- * Creates the text to be displayed in the right side of the interface based on current selections
- *//*
-
- private String getUpdatedInfoText()
- {
- String textToAdd = DEFAULT;
-
- if (isUltimateIronman())
- {
- textToAdd = UIM_DEFAULT;
- }
- else
- {
- if (isSkulled)
- {
- textToAdd += LINE_BREAK + IS_SKULLED;
- }
-
- if (protectingItem)
- {
- textToAdd += LINE_BREAK + PROTECTING_ITEM;
- }
-
- textToAdd += LINE_BREAK + String.format(ACTUAL, getDefaultItemsKept());
- }
-
-
- if (wildyLevel < 1)
- {
- textToAdd += LINE_BREAK + LINE_BREAK + NON_PVP;
- }
-
- if (hasAlwaysLost)
- {
- textToAdd += LINE_BREAK + LINE_BREAK + WHITE_OUTLINE;
- }
-
- textToAdd += LINE_BREAK + LINE_BREAK + CHANGED_MECHANICS;
-
- return textToAdd;
- }
-
- */
-/**
- * Corrects the Information panel based on the item containers
- *//*
-
- private void updateKeptWidgetInfoText()
- {
- // Add Information text widget
- createNewTextWidget();
-
- // Update Items lost total value
- Widget lost = client.getWidget(WidgetInfo.ITEMS_LOST_ON_DEATH_CONTAINER);
- double total = 0;
- for (Widget w : lost.getChildren())
- {
- if (w.getItemId() == -1)
- {
- continue;
- }
- double price = itemManager.getItemPrice(w.getItemId());
- if (price == 0)
- {
- // Default to alch price
- price = itemManager.getItemDefinition(w.getItemId()).getPrice() * HIGH_ALCH;
- }
- total += price;
- }
- Widget lostValue = client.getWidget(WidgetInfo.ITEMS_LOST_VALUE);
- lostValue.setText(NUMBER_FORMAT.format(total) + " gp");
-
- // Update Max items kept
- Widget kept = client.getWidget(WidgetInfo.ITEMS_KEPT_ON_DEATH_CONTAINER);
- Widget max = client.getWidget(WidgetInfo.ITEMS_KEPT_MAX);
- max.setText(String.format(MAX_KEPT_ITEMS_FORMAT, kept.getChildren().length));
- }
-
- // isTradeable checks if they are traded on the grand exchange, some items are trade-able but not via GE
- private boolean checkTradeable(int id, ItemDefinition c)
- {
- // If the item is a note check the unnoted variants trade ability
- if (c.getNote() != -1)
- {
- return checkTradeable(c.getLinkedNoteId(), itemManager.getItemDefinition(c.getLinkedNoteId()));
- }
-
- switch (id)
- {
- case ItemID.COINS_995:
- case ItemID.PLATINUM_TOKEN:
- return true;
- default:
- if (ActuallyTradeableItem.check(id))
- {
- return true;
- }
- }
-
- return c.isTradeable();
- }
-
- private void createNewTextWidget()
- {
- // The text use to be put inside this container but since we can't create LAYER widgets
- // We needed to edit this to be a layer for adding buttons
- Widget old = client.getWidget(WidgetInfo.ITEMS_KEPT_INFORMATION_CONTAINER);
-
- // Update the existing TEXT container if it exists. It should be the last child of the old text widget
- // client.getWidget() seems to not find indexed child widgets
- Widget[] children = old.getChildren();
- if (children != null && children.length > 0)
- {
- Widget x = old.getChild(children.length - 1);
- if (x.getId() == WidgetInfo.ITEMS_KEPT_CUSTOM_TEXT_CONTAINER.getId())
- {
- x.setText(getUpdatedInfoText());
- x.revalidate();
- return;
- }
- }
-
- Widget w = old.createChild(-1, WidgetType.TEXT);
- // Position under buttons taking remaining space
- w.setOriginalWidth(old.getOriginalWidth());
- w.setOriginalHeight(ORIGINAL_INFO_HEIGHT - old.getOriginalHeight());
- w.setOriginalY(old.getOriginalHeight());
-
- w.setFontId(FontID.PLAIN_11);
- w.setTextShadowed(true);
- w.setTextColor(FONT_COLOR);
-
- w.setText(getUpdatedInfoText());
- w.setId(WidgetInfo.ITEMS_KEPT_CUSTOM_TEXT_CONTAINER.getId());
- w.revalidate();
-
- // Need to reset height so text is visible?
- old.setOriginalHeight(ORIGINAL_INFO_HEIGHT);
- old.revalidate();
- }
-
- private void createWidgetButtons()
- {
- buttonMap.clear();
-
- // Ultimate Iron men are always skulled and can't use the protect item prayer
- if (!isUltimateIronman())
- {
- createButton(PROTECT_ITEM_BUTTON_NAME, PROTECT_ITEM_SPRITE_ID, protectingItem);
- createButton(SKULLED_BUTTON_NAME, SKULL_SPRITE_ID, isSkulled);
- }
- createButton(LOW_WILDY_BUTTON_NAME, SWORD_SPRITE_ID, wildyLevel > 0 && wildyLevel <= 20);
- createButton(DEEP_WILDY_BUTTON_NAME, SKULL_2_SPRITE_ID, wildyLevel > 20);
-
- Widget parent = client.getWidget(WidgetInfo.ITEMS_KEPT_INFORMATION_CONTAINER);
- parent.setType(WidgetType.LAYER);
- parent.revalidate();
- WidgetButton.addButtonsToContainerWidget(parent, buttonMap.values());
- }
-
- private void createButton(String name, int spriteID, boolean startingFlag)
- {
- WidgetButton button = new WidgetButton(name, spriteID, startingFlag, this::buttonCallback, client);
- buttonMap.put(name, button);
- }
-
- private void buttonCallback(String name, boolean selected)
- {
- log.debug("Clicked Widget Button {}. New value: {}", name, selected);
- switch (name)
- {
- case PROTECT_ITEM_BUTTON_NAME:
- protectingItem = selected;
- break;
- case SKULLED_BUTTON_NAME:
- isSkulled = selected;
- break;
- case LOW_WILDY_BUTTON_NAME:
- if (!selected)
- {
- syncCurrentWildyLevel();
- break;
- }
- wildyLevel = 1;
- buttonMap.get(DEEP_WILDY_BUTTON_NAME).setSelected(false);
- break;
- case DEEP_WILDY_BUTTON_NAME:
- if (!selected)
- {
- syncCurrentWildyLevel();
- break;
- }
- wildyLevel = 21;
- buttonMap.get(LOW_WILDY_BUTTON_NAME).setSelected(false);
- break;
- default:
- log.warn("Unhandled Button Name: {}", name);
- return;
- }
-
- recreateItemsKeptOnDeathWidget();
- }
-
- */
-/**
- * Creates an Item Widget for use inside the Kept on Death Interface
- *
- * @param qty Amount of item
- * @param c Items Composition
- * @return
- *//*
-
- private Widget createItemWidget(int qty, ItemDefinition c)
- {
- Widget itemWidget = client.createWidget();
- itemWidget.setType(WidgetType.GRAPHIC);
- itemWidget.setItemId(c.getId());
- itemWidget.setItemQuantity(qty);
- itemWidget.setHasListener(true);
- itemWidget.setIsIf3(true);
- itemWidget.setOriginalWidth(ORIGINAL_WIDTH);
- itemWidget.setOriginalHeight(ORIGINAL_HEIGHT);
- itemWidget.setBorderType(1);
-
- itemWidget.setAction(1, String.format(ACTION_TEXT, c.getName()));
- itemWidget.setOnOpListener(SCRIPT_ID, 1, qty, c.getName());
-
- return itemWidget;
- }
-}*/
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/menuentryswapper/Parse.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/menuentryswapper/Parse.java
deleted file mode 100644
index 75a225589c..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/menuentryswapper/Parse.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.runelite.client.plugins.menuentryswapper;
-
-import com.google.common.base.Splitter;
-
-public class Parse
-{
- public static boolean parse(String value)
- {
- try
- {
- Splitter NEWLINE_SPLITTER = Splitter
- .on("\n")
- .omitEmptyStrings()
- .trimResults();
-
- NEWLINE_SPLITTER.withKeyValueSeparator(':').split(value);
- return true;
- }
- catch (IllegalArgumentException ex)
- {
- return false;
- }
- }
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/metronome/MetronomePlugin.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/metronome/MetronomePlugin.java
deleted file mode 100644
index 59ef3a6c1a..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/metronome/MetronomePlugin.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2018, SomeoneWithAnInternetConnection
- * Copyright (c) 2018, oplosthee
- * 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.client.plugins.metronome;
-
-import com.google.inject.Provides;
-import javax.inject.Inject;
-import api.Client;
-import api.SoundEffectID;
-import api.events.GameTick;
-import net.runelite.client.config.ConfigManager;
-import net.runelite.client.eventbus.Subscribe;
-import net.runelite.client.plugins.Plugin;
-import net.runelite.client.plugins.PluginDescriptor;
-
-@PluginDescriptor(
- name = "Metronome",
- description = "Play a sound on a specified tick to aid in efficient skilling",
- tags = {"skilling", "tick", "timers"},
- enabledByDefault = false
-)
-public class MetronomePlugin extends Plugin
-{
- @Inject
- private Client client;
-
- @Inject
- private MetronomePluginConfiguration config;
-
- private int tickCounter = 0;
- private boolean shouldTock = false;
-
- @Provides
- MetronomePluginConfiguration provideConfig(ConfigManager configManager)
- {
- return configManager.getConfig(MetronomePluginConfiguration.class);
- }
-
- @Subscribe
- public void onGameTick(GameTick tick)
- {
- if (config.tickCount() == 0)
- {
- return;
- }
-
- if (++tickCounter % config.tickCount() == 0)
- {
- if (config.enableTock() && shouldTock)
- {
- client.playSoundEffect(SoundEffectID.GE_DECREMENT_PLOP);
- }
- else
- {
- client.playSoundEffect(SoundEffectID.GE_INCREMENT_PLOP);
- }
- shouldTock = !shouldTock;
- }
- }
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java
deleted file mode 100644
index 1e4dda5bd4..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningOverlay.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2018, Seth
- * 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.client.plugins.mining;
-
-import com.google.common.collect.ImmutableSet;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.Set;
-import javax.inject.Inject;
-import static api.AnimationID.MINING_MOTHERLODE_ADAMANT;
-import static api.AnimationID.MINING_MOTHERLODE_BLACK;
-import static api.AnimationID.MINING_MOTHERLODE_BRONZE;
-import static api.AnimationID.MINING_MOTHERLODE_DRAGON;
-import static api.AnimationID.MINING_MOTHERLODE_DRAGON_ORN;
-import static api.AnimationID.MINING_MOTHERLODE_INFERNAL;
-import static api.AnimationID.MINING_MOTHERLODE_IRON;
-import static api.AnimationID.MINING_MOTHERLODE_MITHRIL;
-import static api.AnimationID.MINING_MOTHERLODE_RUNE;
-import static api.AnimationID.MINING_MOTHERLODE_STEEL;
-import api.Client;
-import net.runelite.client.ui.overlay.Overlay;
-import net.runelite.client.ui.overlay.OverlayPosition;
-import net.runelite.client.ui.overlay.components.LineComponent;
-import net.runelite.client.ui.overlay.components.PanelComponent;
-import net.runelite.client.ui.overlay.components.TitleComponent;
-
-class MiningOverlay extends Overlay
-{
- private static final Set MINING_ANIMATION_IDS = ImmutableSet.of(
- MINING_MOTHERLODE_BRONZE, MINING_MOTHERLODE_IRON, MINING_MOTHERLODE_STEEL,
- MINING_MOTHERLODE_BLACK, MINING_MOTHERLODE_MITHRIL, MINING_MOTHERLODE_ADAMANT,
- MINING_MOTHERLODE_RUNE, MINING_MOTHERLODE_DRAGON, MINING_MOTHERLODE_DRAGON_ORN,
- MINING_MOTHERLODE_INFERNAL
- );
-
- private final Client client;
- private final MiningPlugin plugin;
- private final MiningConfig config;
- private final PanelComponent panelComponent = new PanelComponent();
-
- @Inject
- MiningOverlay(Client client, MiningPlugin plugin, MiningConfig config)
- {
- setPosition(OverlayPosition.TOP_LEFT);
- this.client = client;
- this.plugin = plugin;
- this.config = config;
- }
-
- @Override
- public Dimension render(Graphics2D graphics)
- {
- if (!plugin.isInMlm() || !config.showMiningStats())
- {
- return null;
- }
-
- MiningSession session = plugin.getSession();
-
- if (session.getLastPayDirtMined() == null)
- {
- return null;
- }
-
- Duration statTimeout = Duration.ofMinutes(config.statTimeout());
- Duration sinceCut = Duration.between(session.getLastPayDirtMined(), Instant.now());
-
- if (sinceCut.compareTo(statTimeout) >= 0)
- {
- return null;
- }
-
- panelComponent.getChildren().clear();
-
- if (config.showMiningState())
- {
- if (MINING_ANIMATION_IDS.contains(client.getLocalPlayer().getAnimation()))
- {
- panelComponent.getChildren().add(TitleComponent.builder()
- .text("Mining")
- .color(Color.GREEN)
- .build());
- }
- else
- {
- panelComponent.getChildren().add(TitleComponent.builder()
- .text("NOT mining")
- .color(Color.RED)
- .build());
- }
- }
-
- panelComponent.getChildren().add(LineComponent.builder()
- .left("Pay-dirt mined:")
- .right(Integer.toString(session.getTotalMined()))
- .build());
-
- panelComponent.getChildren().add(LineComponent.builder()
- .left("Pay-dirt/hr:")
- .right(session.getRecentMined() > 2 ? Integer.toString(session.getPerHour()) : "")
- .build());
-
- return panelComponent.render(graphics);
- }
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java
deleted file mode 100644
index c5256691b2..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright (c) 2018, Seth
- * Copyright (c) 2018, Adam
- * Copyright (c) 2018, Lars
- * 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.client.plugins.mining;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.inject.Provides;
-import java.time.temporal.ChronoUnit;
-import java.util.HashSet;
-import java.util.Set;
-import javax.inject.Inject;
-import lombok.AccessLevel;
-import lombok.Getter;
-import api.Client;
-import api.GameObject;
-import api.GameState;
-import api.ItemID;
-import static api.ObjectID.ORE_VEIN_26661;
-import static api.ObjectID.ORE_VEIN_26662;
-import static api.ObjectID.ORE_VEIN_26663;
-import static api.ObjectID.ORE_VEIN_26664;
-import api.WallObject;
-import api.events.GameObjectChanged;
-import api.events.GameObjectDespawned;
-import api.events.GameObjectSpawned;
-import api.events.GameStateChanged;
-import net.runelite.client.callback.ClientThread;
-import net.runelite.client.config.ConfigManager;
-import net.runelite.client.eventbus.Subscribe;
-import net.runelite.client.plugins.Plugin;
-import net.runelite.client.plugins.PluginDescriptor;
-import net.runelite.client.plugins.PluginType;
-import net.runelite.client.task.Schedule;
-import net.runelite.client.ui.overlay.OverlayManager;
-
-@PluginDescriptor(
- name = "Mining",
- description = "Show helpful information about Mining",
- tags = {"mining", "skilling", "overlay"},
- type = PluginType.SKILLING,
- enabledByDefault = false
-)
-public class MiningPlugin extends Plugin
-{
- private static final Set MOTHERLODE_MAP_REGIONS = ImmutableSet.of(14679, 14680, 14681, 14935, 14936, 14937, 15191, 15192, 15193);
- private static final Set MINE_SPOTS = ImmutableSet.of(ORE_VEIN_26661, ORE_VEIN_26662, ORE_VEIN_26663, ORE_VEIN_26664);
- private static final Set MLM_ORE_TYPES = ImmutableSet.of(ItemID.RUNITE_ORE, ItemID.ADAMANTITE_ORE,
- ItemID.MITHRIL_ORE, ItemID.GOLD_ORE, ItemID.COAL, ItemID.GOLDEN_NUGGET);
- private static final Set MINING_ROCKS = ImmutableSet.of(
- // another website says depleted rocks are 7468, 7469
- // website says stoney 2902, 2962, 2963, 2964,
- 2231, 2257, 2584, 2704, 3722, 3723, 3748, 3790, 3791, 3803, 3804, 3805, 3806, 3807, 3808, 4437, 4438, 4676, 6669, 6670, 6671, 6672, 6673, 7453, 7454, 7455, 7456, 7457, 7458, 7459, 7460, 7461, 7462, 7463, 7464, 7467, 7470, 7484, 7485, 7486, 7487, 7488, 7489, 7490, 7491, 7492, 7493, 7494, 7495, 8727, 8828, 8829, 8830, 10079, 10080, 10081, 11441, 11924, 12590, 15127, 15128, 15213, 16464, 16514, 16515, 16521, 16522, 16523, 16524, 16534, 16535, 16545, 16549, 16550, 16998, 16999, 17042, 17043, 17064, 17065, 18817, 18840, 18952, 18953, 18954, 18961, 19849, 19969, 19970, 19971, 19972, 19973, 22665, 22667, 23280, 23281, 23640, 24146, 24147, 24148, 24557, 26873, 26874, 27984, 27985, 27987, 27988, 28596, 28597, 28752, 28753, 28890
- //2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2231, 2257, 2328, 3042, 3043, 3722, 3723, 3748, 3790, 3791, 3803, 3804, 4676, 6943, 6944, 6945, 6946, 6947, 6948, 9296, 9297, 9303, 9304, 9305, 9306, 9316, 9317, 9331, 9332, 9335, 9336, 9708, 9709, 9710, 9711, 9712, 9713, 9714, 9715, 9716, 9717, 9718, 9719, 9720, 9721, 9722, 9723, 9724, 9725, 9726, 9727, 9728, 9729, 9730, 9731, 9732, 9733, 9734, 9735, 9736, 9737, 10583, 10584, 10585, 10586, 10587, 10944, 10945, 10946, 10947, 10948, 10949, 11165, 11166, 11167, 11168, 11169, 11170, 11171, 11172, 11173, 11174, 11175, 11176, 11177, 11178, 11179, 11180, 11181, 11182, 11183, 11184, 11185, 11186, 11187, 11188, 11189, 11190, 11191, 11192, 11193, 11194, 11195, 11424, 11425, 11426, 11427, 11428, 11429, 11430, 11431, 11432, 11433, 11434, 11435, 11436, 11437, 11438, 11439, 11440, 11441, 11442, 11443, 11444, 11552, 11553, 11554, 11555, 11556, 11557, 11915, 11916, 11917, 11918, 11919, 11920, 11921, 11922, 11923, 11924, 11925, 11926, 11927, 11928, 11929, 11930, 11931, 11932, 11933, 11934, 11935, 11936, 11937, 11938, 11939, 11940, 11941, 11942, 11943, 11944, 11945, 11946, 11947, 11948, 11949, 11950, 11951, 11952, 11953, 11954, 11955, 11956, 11957, 11958, 11959, 11960, 11961, 11962, 11963, 11964, 11965
- //968, 1480, 1855, 4043, 4487, 7533, 9716, 21250, 1997, 2581, 2582, 2694, 2695, 2696, 2697, 2835, 2836, 2837, 2901, 2965, 3339, 3364, 4526, 4552, 4553, 4554, 4555, 4556, 4557, 4558, 4887, 5604, 5605, 5606, 5844, 5845, 5896, 5985, 5987, 6622, 6623, 6707, 6708, 6709, 7466, 8725, 8726, 8950, 8951, 8952, 9031, 9032, 10036, 10782, 10783, 10784, 10785, 10786, 10787, 10788, 11097, 11098, 11182, 11183, 11424, 11425, 12564, 12565, 12566, 12567, 12588, 12589, 12774, 14814, 14815, 14816, 14817, 15198, 15199, 15217, 15218, 15219, 15410, 15536, 15537, 16077, 16078, 16079, 16080, 16115, 16136, 16284, 16303, 17350, 17351, 17352, 17353, 17354, 17355, 17356, 17357, 17358, 17364, 17365, 17366, 17679, 17958, 17959, 17960, 17970, 17971, 17972, 18871, 18872, 18873, 19131, 21571, 21572, 21573, 22549, 22550, 22551, 23124, 23125, 23126, 23127, 23165, 23976, 23977, 23978, 23979, 23980, 23981, 24693, 24694, 24695, 24696, 24697, 24698, 24699, 24700, 24701, 24781, 25158, 25159, 25160, 25422, 25423, 26372, 26373, 26376, 26377, 26850, 26856, 28580, 29102, 29883, 29884, 29885, 30344, 30519, 30521, 30522, 30857, 30858, 31045, 31781, 31782, 31783, 31784, 31785, 31786, 31787, 31788, 31789
- );
- private static final int MAX_INVENTORY_SIZE = 28;
-
-// private static final int SACK_LARGE_SIZE = 162;
-// private static final int SACK_SIZE = 81;
-//
-// private static final int UPPER_FLOOR_HEIGHT = -500;
-
- @Inject
- private OverlayManager overlayManager;
-
- @Inject
- private MiningOverlay overlay;
-
- @Inject
- private MiningRocksOverlay rocksOverlay;
-
- @Inject
- private MiningConfig config;
-
- @Inject
- private Client client;
-
- @Inject
- private ClientThread clientThread;
-
- @Getter(AccessLevel.PACKAGE)
- private boolean inMlm;
-
- @Getter(AccessLevel.PACKAGE)
- private int curSackSize;
- @Getter(AccessLevel.PACKAGE)
- private int maxSackSize;
- @Getter(AccessLevel.PACKAGE)
- private Integer depositsLeft;
-
- private MiningSession session;
-
- @Getter(AccessLevel.PACKAGE)
- private final Set veins = new HashSet<>();
- @Getter(AccessLevel.PACKAGE)
- private final Set rocks = new HashSet<>();
-
- @Provides
- MiningConfig getConfig(ConfigManager configManager)
- {
- return configManager.getConfig(MiningConfig.class);
- }
-
- @Override
- protected void startUp()
- {
- overlayManager.add(overlay);
- overlayManager.add(rocksOverlay);
-// overlayManager.add(motherlodeGemOverlay);
-// overlayManager.add(motherlodeSackOverlay);
-
- session = new MiningSession();
- //inMlm = checkInMlm();
-
-// if (inMlm)
-// {
-// clientThread.invokeLater(this::refreshSackValues);
-// }
- }
-
- @Override
- protected void shutDown() throws Exception
- {
- overlayManager.remove(overlay);
- overlayManager.remove(rocksOverlay);
-// overlayManager.remove(motherlodeGemOverlay);
-// overlayManager.remove(motherlodeSackOverlay);
- session = null;
-// veins.clear();
- rocks.clear();
-
-// Widget sack = client.getWidget(WidgetInfo.MOTHERLODE_MINE);
-
-// clientThread.invokeLater(() ->
-// {
-// if (sack != null && sack.isHidden())
-// {
-// sack.setHidden(false);
-// }
-// });
- }
-
- public MiningSession getSession()
- {
- return session;
- }
-
-// @Subscribe
-// public void onVarbitChanged(VarbitChanged event)
-// {
-// if (inMlm)
-// {
-// refreshSackValues();
-// }
-// }
-
-// @Subscribe
-// public void onChatMessage(ChatMessage event)
-// {
-// if (!inMlm || event.getType() != ChatMessageType.FILTERED)
-// {
-// return;
-// }
-//
-// String chatMessage = event.getMessage();
-//
-// switch (chatMessage)
-// {
-// case "You manage to mine some pay-dirt.":
-// session.incrementPayDirtMined();
-// break;
-//
-// case "You just found a Diamond!":
-// session.incrementGemFound(ItemID.UNCUT_DIAMOND);
-// break;
-//
-// case "You just found a Ruby!":
-// session.incrementGemFound(ItemID.UNCUT_RUBY);
-// break;
-//
-// case "You just found an Emerald!":
-// session.incrementGemFound(ItemID.UNCUT_EMERALD);
-// break;
-//
-// case "You just found a Sapphire!":
-// session.incrementGemFound(ItemID.UNCUT_SAPPHIRE);
-// break;
-// }
-// }
-
- @Schedule(
- period = 1,
- unit = ChronoUnit.SECONDS
- )
-// public void checkMining()
-// {
-// if (!inMlm)
-// {
-// return;
-// }
-//
-// depositsLeft = calculateDepositsLeft();
-//
-// Instant lastPayDirtMined = session.getLastPayDirtMined();
-// if (lastPayDirtMined == null)
-// {
-// return;
-// }
-//
-// // reset recentPayDirtMined if you haven't mined anything recently
-// Duration statTimeout = Duration.ofMinutes(config.statTimeout());
-// Duration sinceMined = Duration.between(lastPayDirtMined, Instant.now());
-//
-// if (sinceMined.compareTo(statTimeout) >= 0)
-// {
-// session.resetRecent();
-// }
-// }
-
- @Subscribe
- public void onGameObjectSpawned(GameObjectSpawned event)
- {
- GameObject gameObject = event.getGameObject();
- if (MINING_ROCKS.contains(gameObject.getId()))
- {
- rocks.add(gameObject);
- }
- }
-
- @Subscribe
- public void onGameObjectChanged(GameObjectChanged event)
- {
- GameObject previous = event.getPrevious();
- GameObject gameObject = event.getGameObject();
- rocks.remove(previous);
- if (MINING_ROCKS.contains(gameObject.getId()))
- {
- rocks.add(gameObject);
- }
- }
-
- @Subscribe
- public void onGameObjectDespawned(GameObjectDespawned event)
- {
- GameObject gameObject = event.getGameObject();
- rocks.remove(gameObject);
- }
-
- @Subscribe
- public void onGameStateChanged(GameStateChanged event)
- {
- if (event.getGameState() == GameState.LOADING)
- {
- // on region changes the tiles get set to null
- rocks.clear();
- }
- }
-
-// private Integer calculateDepositsLeft()
-// {
-// if (maxSackSize == 0) // check if maxSackSize has been initialized
-// {
-// refreshSackValues();
-// }
-//
-// double depositsLeft = 0;
-// int nonPayDirtItems = 0;
-//
-// ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY);
-// if (inventory == null)
-// {
-// return null;
-// }
-//
-// Item[] result = inventory.getItems();
-// assert result != null;
-//
-// for (Item item : result)
-// {
-// // Assume that MLM ores are being banked and exclude them from the check,
-// // so the user doesn't see the Overlay switch between deposits left and N/A.
-// //
-// // Count other items at nonPayDirtItems so depositsLeft is calculated accordingly.
-// if (item.getId() != ItemID.PAYDIRT && item.getId() != -1 && !MLM_ORE_TYPES.contains(item.getId()))
-// {
-// nonPayDirtItems += 1;
-// }
-// }
-//
-// double inventorySpace = MAX_INVENTORY_SIZE - nonPayDirtItems;
-// double sackSizeRemaining = maxSackSize - curSackSize;
-//
-// if (inventorySpace > 0 && sackSizeRemaining > 0)
-// {
-// depositsLeft = Math.ceil(sackSizeRemaining / inventorySpace);
-// }
-// else if (inventorySpace == 0)
-// {
-// return null;
-// }
-//
-// return (int) depositsLeft;
-// }
-//
-// private boolean checkInMlm()
-// {
-// if (client.getGameState() != GameState.LOGGED_IN)
-// {
-// return false;
-// }
-//
-// int[] currentMapRegions = client.getMapRegions();
-//
-// // Verify that all regions exist in MOTHERLODE_MAP_REGIONS
-// for (int region : currentMapRegions)
-// {
-// if (!MOTHERLODE_MAP_REGIONS.contains(region))
-// {
-// return false;
-// }
-// }
-//
-// return true;
-// }
-//
-// private void refreshSackValues()
-// {
-// curSackSize = client.getVar(Varbits.SACK_NUMBER);
-// boolean sackUpgraded = client.getVar(Varbits.SACK_UPGRADED) == 1;
-// maxSackSize = sackUpgraded ? SACK_LARGE_SIZE : SACK_SIZE;
-// }
-//
-// /**
-// * Checks if the given point is "upstairs" in the mlm.
-// * The upper floor is actually on z=0.
-// * @param localPoint
-// * @return
-// */
-// boolean isUpstairs(LocalPoint localPoint)
-// {
-// return Perspective.getTileHeight(client, localPoint, 0) < UPPER_FLOOR_HEIGHT;
-// }
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningRocksOverlay.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningRocksOverlay.java
deleted file mode 100644
index 9225d59c5b..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningRocksOverlay.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2018, Seth
- * Copyright (c) 2018, Adam
- * Copyright (c) 2018, Lars
- * 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.client.plugins.mining;
-
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.image.BufferedImage;
-import javax.inject.Inject;
-import api.Client;
-import api.GameObject;
-import api.Perspective;
-import api.Player;
-import api.Point;
-import api.Skill;
-import api.coords.LocalPoint;
-import net.runelite.client.game.SkillIconManager;
-import net.runelite.client.ui.overlay.Overlay;
-import net.runelite.client.ui.overlay.OverlayLayer;
-import net.runelite.client.ui.overlay.OverlayPosition;
-
-class MiningRocksOverlay extends Overlay
-{
- private static final int MAX_DISTANCE = 2350;
-
- private final Client client;
- private final MiningPlugin plugin;
- private final MiningConfig config;
-
- private final BufferedImage miningIcon;
-
- @Inject
- MiningRocksOverlay(Client client, MiningPlugin plugin, MiningConfig config, SkillIconManager iconManager)
- {
- setPosition(OverlayPosition.DYNAMIC);
- setLayer(OverlayLayer.ABOVE_SCENE);
- this.client = client;
- this.plugin = plugin;
- this.config = config;
-
- miningIcon = iconManager.getSkillImage(Skill.MINING);
- }
-
- @Override
- public Dimension render(Graphics2D graphics)
- {
- Player local = client.getLocalPlayer();
-
- renderTiles(graphics, local);
-
- return null;
- }
-
- private void renderTiles(Graphics2D graphics, Player local)
- {
- LocalPoint localLocation = local.getLocalLocation();
-
- if (config.showMiningRocks())
- {
- for (GameObject rock : plugin.getRocks())
- {
-
- LocalPoint location = rock.getLocalLocation();
- if (localLocation.distanceTo(location) <= MAX_DISTANCE)
- {
- renderMiningRock(graphics, rock);
- }
- }
- }
-
- }
-
- private void renderMiningRock(Graphics2D graphics, GameObject rock)
- {
- Point canvasLoc = Perspective.getCanvasImageLocation(client, rock.getLocalLocation(), miningIcon, 0);
- if (canvasLoc != null)
- {
- graphics.drawImage(miningIcon, canvasLoc.getX(), canvasLoc.getY(), null);
- }
- }
-
-// private void renderMiningRockSquare(Graphics2D graphics, GameObject rock)
-// {
-// Polygon poly = Perspective.getCanvasTilePoly(client, rock.getLocalLocation());
-//
-// if (poly != null)
-// {
-// OverlayUtil.renderPolygon(graphics, poly, Color.red);
-// }
-// }
-
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningSession.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningSession.java
deleted file mode 100644
index b245268e8c..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/mining/MiningSession.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2018, Seth
- * 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.client.plugins.mining;
-
-import java.time.Duration;
-import java.time.Instant;
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.extern.slf4j.Slf4j;
-import api.ItemID;
-
-@Slf4j
-public class MiningSession
-{
- private static final Duration HOUR = Duration.ofHours(1);
-
- private int perHour;
-
- private Instant lastPayDirtMined;
- private int totalMined;
-
- private Instant recentPayDirtMined;
- private int recentMined;
-
- @Getter(AccessLevel.PACKAGE)
- private Instant lastGemFound;
-
- @Getter(AccessLevel.PACKAGE)
- private int diamondsFound;
-
- @Getter(AccessLevel.PACKAGE)
- private int rubiesFound;
-
- @Getter(AccessLevel.PACKAGE)
- private int emeraldsFound;
-
- @Getter(AccessLevel.PACKAGE)
- private int sapphiresFound;
-
- public void incrementGemFound(int gemID)
- {
- lastGemFound = Instant.now();
-
- switch (gemID)
- {
- case ItemID.UNCUT_DIAMOND:
- diamondsFound++;
- break;
-
- case ItemID.UNCUT_RUBY:
- rubiesFound++;
- break;
-
- case ItemID.UNCUT_EMERALD:
- emeraldsFound++;
- break;
-
- case ItemID.UNCUT_SAPPHIRE:
- sapphiresFound++;
- break;
-
- default:
- log.error("Invalid gem type specified. The gem count will not be incremented.");
- }
- }
-
- public void incrementPayDirtMined()
- {
- Instant now = Instant.now();
-
- lastPayDirtMined = now;
- ++totalMined;
-
- if (recentMined == 0)
- {
- recentPayDirtMined = now;
- }
- ++recentMined;
-
- Duration timeSinceStart = Duration.between(recentPayDirtMined, now);
- if (!timeSinceStart.isZero())
- {
- perHour = (int) ((double) recentMined * (double) HOUR.toMillis() / (double) timeSinceStart.toMillis());
- }
- }
-
- public void resetRecent()
- {
- recentPayDirtMined = null;
- recentMined = 0;
- }
-
- public int getPerHour()
- {
- return perHour;
- }
-
- public Instant getLastPayDirtMined()
- {
- return lastPayDirtMined;
- }
-
- public int getTotalMined()
- {
- return totalMined;
- }
-
- public Instant getRecentPayDirtMined()
- {
- return recentPayDirtMined;
- }
-
- public int getRecentMined()
- {
- return recentMined;
- }
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/poh/PohIcons.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/poh/PohIcons.java
deleted file mode 100644
index 4985fe5f67..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/poh/PohIcons.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (c) 2018, Seth
- * 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.client.plugins.poh;
-
-import com.google.common.collect.ImmutableMap;
-import java.awt.image.BufferedImage;
-import java.util.Map;
-import lombok.Getter;
-import static api.NullObjectID.NULL_13615;
-import static api.NullObjectID.NULL_13618;
-import static api.NullObjectID.NULL_13620;
-import static api.NullObjectID.NULL_13622;
-import static api.NullObjectID.NULL_13625;
-import static api.NullObjectID.NULL_13627;
-import static api.NullObjectID.NULL_13629;
-import static api.NullObjectID.NULL_13632;
-import static api.NullObjectID.NULL_13634;
-import static api.NullObjectID.NULL_29228;
-import static api.NullObjectID.NULL_29229;
-import static api.ObjectID.ALTAR_13179;
-import static api.ObjectID.ALTAR_13180;
-import static api.ObjectID.ALTAR_13181;
-import static api.ObjectID.ALTAR_13182;
-import static api.ObjectID.ALTAR_13183;
-import static api.ObjectID.ALTAR_13184;
-import static api.ObjectID.ALTAR_13185;
-import static api.ObjectID.ALTAR_13186;
-import static api.ObjectID.ALTAR_13187;
-import static api.ObjectID.ALTAR_13188;
-import static api.ObjectID.ALTAR_13189;
-import static api.ObjectID.ALTAR_13190;
-import static api.ObjectID.ALTAR_13191;
-import static api.ObjectID.ALTAR_13192;
-import static api.ObjectID.ALTAR_13193;
-import static api.ObjectID.ALTAR_13194;
-import static api.ObjectID.ALTAR_13196;
-import static api.ObjectID.ALTAR_13197;
-import static api.ObjectID.ALTAR_13198;
-import static api.ObjectID.ALTAR_13199;
-import static api.ObjectID.ALTAR_OF_THE_OCCULT;
-import static api.ObjectID.AMULET_OF_GLORY;
-import static api.ObjectID.ANCIENT_ALTAR;
-import static api.ObjectID.ANNAKARL_PORTAL;
-import static api.ObjectID.ANNAKARL_PORTAL_29349;
-import static api.ObjectID.ANNAKARL_PORTAL_29357;
-import static api.ObjectID.ARDOUGNE_PORTAL;
-import static api.ObjectID.ARDOUGNE_PORTAL_13626;
-import static api.ObjectID.ARDOUGNE_PORTAL_13633;
-import static api.ObjectID.ARMOUR_REPAIR_STAND;
-import static api.ObjectID.BASIC_JEWELLERY_BOX;
-import static api.ObjectID.CARRALLANGAR_PORTAL;
-import static api.ObjectID.CARRALLANGAR_PORTAL_33437;
-import static api.ObjectID.CARRALLANGAR_PORTAL_33440;
-import static api.ObjectID.CATHERBY_PORTAL;
-import static api.ObjectID.CATHERBY_PORTAL_33435;
-import static api.ObjectID.CATHERBY_PORTAL_33438;
-import static api.ObjectID.DARK_ALTAR;
-import static api.ObjectID.DIGSITE_PENDANT;
-import static api.ObjectID.DIGSITE_PENDANT_33417;
-import static api.ObjectID.DIGSITE_PENDANT_33418;
-import static api.ObjectID.DIGSITE_PENDANT_33420;
-import static api.ObjectID.FALADOR_PORTAL;
-import static api.ObjectID.FALADOR_PORTAL_13624;
-import static api.ObjectID.FALADOR_PORTAL_13631;
-import static api.ObjectID.FANCY_JEWELLERY_BOX;
-import static api.ObjectID.FANCY_REJUVENATION_POOL;
-import static api.ObjectID.FISHING_GUILD_PORTAL;
-import static api.ObjectID.FISHING_GUILD_PORTAL_29351;
-import static api.ObjectID.FISHING_GUILD_PORTAL_29359;
-import static api.ObjectID.GHORROCK_PORTAL;
-import static api.ObjectID.GHORROCK_PORTAL_33436;
-import static api.ObjectID.GHORROCK_PORTAL_33439;
-import static api.ObjectID.KHARYRLL_PORTAL;
-import static api.ObjectID.KHARYRLL_PORTAL_29346;
-import static api.ObjectID.KHARYRLL_PORTAL_29354;
-import static api.ObjectID.KOUREND_PORTAL;
-import static api.ObjectID.KOUREND_PORTAL_29353;
-import static api.ObjectID.KOUREND_PORTAL_29361;
-import static api.ObjectID.LUMBRIDGE_PORTAL;
-import static api.ObjectID.LUMBRIDGE_PORTAL_13623;
-import static api.ObjectID.LUMBRIDGE_PORTAL_13630;
-import static api.ObjectID.LUNAR_ALTAR;
-import static api.ObjectID.LUNAR_ISLE_PORTAL;
-import static api.ObjectID.LUNAR_ISLE_PORTAL_29347;
-import static api.ObjectID.LUNAR_ISLE_PORTAL_29355;
-import static api.ObjectID.MARIM_PORTAL;
-import static api.ObjectID.MARIM_PORTAL_29352;
-import static api.ObjectID.MARIM_PORTAL_29360;
-import static api.ObjectID.OBELISK_31554;
-import static api.ObjectID.ORNATE_JEWELLERY_BOX;
-import static api.ObjectID.ORNATE_REJUVENATION_POOL;
-import static api.ObjectID.POOL_OF_REJUVENATION;
-import static api.ObjectID.POOL_OF_RESTORATION;
-import static api.ObjectID.POOL_OF_REVITALISATION;
-import static api.ObjectID.PORTAL_4525;
-import static api.ObjectID.PORTAL_NEXUS;
-import static api.ObjectID.PORTAL_NEXUS_33355;
-import static api.ObjectID.PORTAL_NEXUS_33356;
-import static api.ObjectID.PORTAL_NEXUS_33357;
-import static api.ObjectID.PORTAL_NEXUS_33358;
-import static api.ObjectID.PORTAL_NEXUS_33359;
-import static api.ObjectID.PORTAL_NEXUS_33360;
-import static api.ObjectID.PORTAL_NEXUS_33361;
-import static api.ObjectID.PORTAL_NEXUS_33362;
-import static api.ObjectID.PORTAL_NEXUS_33363;
-import static api.ObjectID.PORTAL_NEXUS_33364;
-import static api.ObjectID.PORTAL_NEXUS_33365;
-import static api.ObjectID.PORTAL_NEXUS_33366;
-import static api.ObjectID.PORTAL_NEXUS_33367;
-import static api.ObjectID.PORTAL_NEXUS_33368;
-import static api.ObjectID.PORTAL_NEXUS_33369;
-import static api.ObjectID.PORTAL_NEXUS_33370;
-import static api.ObjectID.PORTAL_NEXUS_33371;
-import static api.ObjectID.PORTAL_NEXUS_33372;
-import static api.ObjectID.PORTAL_NEXUS_33373;
-import static api.ObjectID.PORTAL_NEXUS_33374;
-import static api.ObjectID.PORTAL_NEXUS_33375;
-import static api.ObjectID.PORTAL_NEXUS_33376;
-import static api.ObjectID.PORTAL_NEXUS_33377;
-import static api.ObjectID.PORTAL_NEXUS_33378;
-import static api.ObjectID.PORTAL_NEXUS_33379;
-import static api.ObjectID.PORTAL_NEXUS_33380;
-import static api.ObjectID.PORTAL_NEXUS_33381;
-import static api.ObjectID.PORTAL_NEXUS_33382;
-import static api.ObjectID.PORTAL_NEXUS_33383;
-import static api.ObjectID.PORTAL_NEXUS_33384;
-import static api.ObjectID.PORTAL_NEXUS_33385;
-import static api.ObjectID.PORTAL_NEXUS_33386;
-import static api.ObjectID.PORTAL_NEXUS_33387;
-import static api.ObjectID.PORTAL_NEXUS_33388;
-import static api.ObjectID.PORTAL_NEXUS_33389;
-import static api.ObjectID.PORTAL_NEXUS_33390;
-import static api.ObjectID.PORTAL_NEXUS_33391;
-import static api.ObjectID.PORTAL_NEXUS_33392;
-import static api.ObjectID.PORTAL_NEXUS_33393;
-import static api.ObjectID.PORTAL_NEXUS_33394;
-import static api.ObjectID.PORTAL_NEXUS_33395;
-import static api.ObjectID.PORTAL_NEXUS_33396;
-import static api.ObjectID.PORTAL_NEXUS_33397;
-import static api.ObjectID.PORTAL_NEXUS_33398;
-import static api.ObjectID.PORTAL_NEXUS_33399;
-import static api.ObjectID.PORTAL_NEXUS_33400;
-import static api.ObjectID.PORTAL_NEXUS_33401;
-import static api.ObjectID.PORTAL_NEXUS_33402;
-import static api.ObjectID.PORTAL_NEXUS_33403;
-import static api.ObjectID.PORTAL_NEXUS_33404;
-import static api.ObjectID.PORTAL_NEXUS_33405;
-import static api.ObjectID.PORTAL_NEXUS_33406;
-import static api.ObjectID.PORTAL_NEXUS_33407;
-import static api.ObjectID.PORTAL_NEXUS_33408;
-import static api.ObjectID.PORTAL_NEXUS_33409;
-import static api.ObjectID.PORTAL_NEXUS_33410;
-import static api.ObjectID.PORTAL_NEXUS_33423;
-import static api.ObjectID.PORTAL_NEXUS_33424;
-import static api.ObjectID.PORTAL_NEXUS_33425;
-import static api.ObjectID.PORTAL_NEXUS_33426;
-import static api.ObjectID.PORTAL_NEXUS_33427;
-import static api.ObjectID.PORTAL_NEXUS_33428;
-import static api.ObjectID.PORTAL_NEXUS_33429;
-import static api.ObjectID.PORTAL_NEXUS_33430;
-import static api.ObjectID.PORTAL_NEXUS_33431;
-import static api.ObjectID.SENNTISTEN_PORTAL;
-import static api.ObjectID.SENNTISTEN_PORTAL_29348;
-import static api.ObjectID.SENNTISTEN_PORTAL_29356;
-import static api.ObjectID.SPIRIT_TREE_29227;
-import static api.ObjectID.TROLL_STRONGHOLD_PORTAL;
-import static api.ObjectID.TROLL_STRONGHOLD_PORTAL_33180;
-import static api.ObjectID.TROLL_STRONGHOLD_PORTAL_33181;
-import static api.ObjectID.WATERBIRTH_ISLAND_PORTAL;
-import static api.ObjectID.WATERBIRTH_ISLAND_PORTAL_29350;
-import static api.ObjectID.WATERBIRTH_ISLAND_PORTAL_29358;
-import static api.ObjectID.XERICS_TALISMAN;
-import static api.ObjectID.XERICS_TALISMAN_33412;
-import static api.ObjectID.XERICS_TALISMAN_33413;
-import static api.ObjectID.XERICS_TALISMAN_33414;
-import static api.ObjectID.XERICS_TALISMAN_33415;
-import static api.ObjectID.XERICS_TALISMAN_33419;
-import net.runelite.client.util.ImageUtil;
-
-public enum PohIcons
-{
- EXITPORTAL("exitportal", PORTAL_4525),
- VARROCK("varrock", NULL_13615, NULL_13622, NULL_13629),
- FALADOR("falador", FALADOR_PORTAL, FALADOR_PORTAL_13624, FALADOR_PORTAL_13631),
- LUMBRIDGE("lumbridge", LUMBRIDGE_PORTAL, LUMBRIDGE_PORTAL_13623, LUMBRIDGE_PORTAL_13630),
- ARDOUGNE("ardougne", ARDOUGNE_PORTAL, ARDOUGNE_PORTAL_13626, ARDOUGNE_PORTAL_13633),
- YANILLE("yanille", NULL_13620, NULL_13627, NULL_13634),
- CAMELOT("camelot", NULL_13618, NULL_13625, NULL_13632),
- LUNARISLE("lunarisle", LUNAR_ISLE_PORTAL, LUNAR_ISLE_PORTAL_29347, LUNAR_ISLE_PORTAL_29355),
- WATERBIRTH("waterbirth", WATERBIRTH_ISLAND_PORTAL, WATERBIRTH_ISLAND_PORTAL_29350, WATERBIRTH_ISLAND_PORTAL_29358),
- FISHINGGUILD("fishingguild", FISHING_GUILD_PORTAL, FISHING_GUILD_PORTAL_29351, FISHING_GUILD_PORTAL_29359),
- SENNTISTEN("senntisten", SENNTISTEN_PORTAL, SENNTISTEN_PORTAL_29348, SENNTISTEN_PORTAL_29356),
- KHARYLL("kharyll", KHARYRLL_PORTAL, KHARYRLL_PORTAL_29346, KHARYRLL_PORTAL_29354),
- ANNAKARL("annakarl", ANNAKARL_PORTAL, ANNAKARL_PORTAL_29349, ANNAKARL_PORTAL_29357),
- KOUREND("kourend", KOUREND_PORTAL, KOUREND_PORTAL_29353, KOUREND_PORTAL_29361),
- MARIM("marim", MARIM_PORTAL, MARIM_PORTAL_29352, MARIM_PORTAL_29360),
- TROLLSTRONGHOLD("trollheim", TROLL_STRONGHOLD_PORTAL, TROLL_STRONGHOLD_PORTAL_33180, TROLL_STRONGHOLD_PORTAL_33181),
- GHORROCK("ghorrock", GHORROCK_PORTAL, GHORROCK_PORTAL_33436, GHORROCK_PORTAL_33439),
- CARRALLANGAR("carrallangar", CARRALLANGAR_PORTAL, CARRALLANGAR_PORTAL_33437, CARRALLANGAR_PORTAL_33440),
- CATHERBY("catherby", CATHERBY_PORTAL, CATHERBY_PORTAL_33435, CATHERBY_PORTAL_33438),
- ALTAR("altar",
- ALTAR_13179, ALTAR_13180, ALTAR_13181, ALTAR_13182, ALTAR_13183, ALTAR_13184, ALTAR_13185, ALTAR_13186,
- ALTAR_13187, ALTAR_13188, ALTAR_13189, ALTAR_13190, ALTAR_13191, ALTAR_13192, ALTAR_13193, ALTAR_13194,
- ALTAR_13196, ALTAR_13197, ALTAR_13198, ALTAR_13199
- ),
- POOLS("pool", POOL_OF_RESTORATION, POOL_OF_REVITALISATION, POOL_OF_REJUVENATION, FANCY_REJUVENATION_POOL, ORNATE_REJUVENATION_POOL),
- GLORY("glory", AMULET_OF_GLORY),
- REPAIR("repair", ARMOUR_REPAIR_STAND),
- SPELLBOOKALTAR("spellbook", ANCIENT_ALTAR, LUNAR_ALTAR, DARK_ALTAR, ALTAR_OF_THE_OCCULT),
- JEWELLERYBOX("jewellery", BASIC_JEWELLERY_BOX, FANCY_JEWELLERY_BOX, ORNATE_JEWELLERY_BOX),
- MAGICTRAVEL("transportation", SPIRIT_TREE_29227, NULL_29228, NULL_29229, OBELISK_31554),
- PORTALNEXUS("portalnexus",
- PORTAL_NEXUS, PORTAL_NEXUS_33355, PORTAL_NEXUS_33356, PORTAL_NEXUS_33357, PORTAL_NEXUS_33358, PORTAL_NEXUS_33359, PORTAL_NEXUS_33360,
- PORTAL_NEXUS_33361, PORTAL_NEXUS_33362, PORTAL_NEXUS_33363, PORTAL_NEXUS_33364, PORTAL_NEXUS_33365, PORTAL_NEXUS_33366, PORTAL_NEXUS_33367,
- PORTAL_NEXUS_33368, PORTAL_NEXUS_33369, PORTAL_NEXUS_33370, PORTAL_NEXUS_33371, PORTAL_NEXUS_33372, PORTAL_NEXUS_33373, PORTAL_NEXUS_33374,
- PORTAL_NEXUS_33375, PORTAL_NEXUS_33376, PORTAL_NEXUS_33377, PORTAL_NEXUS_33378, PORTAL_NEXUS_33379, PORTAL_NEXUS_33380, PORTAL_NEXUS_33381,
- PORTAL_NEXUS_33382, PORTAL_NEXUS_33383, PORTAL_NEXUS_33384, PORTAL_NEXUS_33385, PORTAL_NEXUS_33386, PORTAL_NEXUS_33387, PORTAL_NEXUS_33388,
- PORTAL_NEXUS_33389, PORTAL_NEXUS_33390, PORTAL_NEXUS_33391, PORTAL_NEXUS_33392, PORTAL_NEXUS_33393, PORTAL_NEXUS_33394, PORTAL_NEXUS_33395,
- PORTAL_NEXUS_33396, PORTAL_NEXUS_33397, PORTAL_NEXUS_33398, PORTAL_NEXUS_33399, PORTAL_NEXUS_33400, PORTAL_NEXUS_33401, PORTAL_NEXUS_33402,
- PORTAL_NEXUS_33403, PORTAL_NEXUS_33404, PORTAL_NEXUS_33405, PORTAL_NEXUS_33406, PORTAL_NEXUS_33407, PORTAL_NEXUS_33408, PORTAL_NEXUS_33409,
- PORTAL_NEXUS_33410, PORTAL_NEXUS_33423, PORTAL_NEXUS_33424, PORTAL_NEXUS_33425, PORTAL_NEXUS_33426, PORTAL_NEXUS_33427, PORTAL_NEXUS_33428,
- PORTAL_NEXUS_33429, PORTAL_NEXUS_33430, PORTAL_NEXUS_33431
- ),
- XERICSTALISMAN("xericstalisman",
- XERICS_TALISMAN, XERICS_TALISMAN_33412, XERICS_TALISMAN_33413, XERICS_TALISMAN_33414, XERICS_TALISMAN_33415, XERICS_TALISMAN_33419
- ),
- DIGSITEPENDANT("digsitependant",
- DIGSITE_PENDANT, DIGSITE_PENDANT_33417, DIGSITE_PENDANT_33418, DIGSITE_PENDANT_33420
- );
-
- private static final Map minimapIcons;
-
- @Getter
- private final String imageResource;
- @Getter
- private final int[] Ids;
-
- private BufferedImage image;
-
- static
- {
- ImmutableMap.Builder builder = new ImmutableMap.Builder<>();
-
- for (PohIcons icon : values())
- {
- for (Integer spotId : icon.getIds())
- {
- builder.put(spotId, icon);
- }
- }
-
- minimapIcons = builder.build();
- }
-
- PohIcons(String imageResource, int... ids)
- {
- this.imageResource = imageResource;
- this.Ids = ids;
- }
-
- public static PohIcons getIcon(int id)
- {
- return minimapIcons.get(id);
- }
-
- public BufferedImage getImage()
- {
- if (image != null)
- {
- return image;
- }
-
- image = ImageUtil.getResourceStreamFromClass(getClass(), getImageResource() + ".png");
-
- return image;
- }
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/runedoku/RunedokuConfig.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/runedoku/RunedokuConfig.java
deleted file mode 100644
index ddfc69a4dd..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/runedoku/RunedokuConfig.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package net.runelite.client.plugins.runedoku;
-
-import java.awt.Color;
-import net.runelite.client.config.Config;
-import net.runelite.client.config.ConfigGroup;
-import net.runelite.client.config.ConfigItem;
-
-@ConfigGroup("runedoku")
-public interface RunedokuConfig extends Config
-{
-
- @ConfigItem(
- position = 0,
- keyName = "mindRuneColor",
- name = "Mind Rune Color",
- description = "Color used to highlight Mind runes."
- )
- default Color mindRuneColor()
- {
- return Color.PINK;
- }
-
- @ConfigItem(
- position = 1,
- keyName = "fireRuneColor",
- name = "Fire Rune Color",
- description = "Color used to highlight Fire runes."
- )
- default Color fireRuneColor()
- {
- return Color.RED;
- }
-
- @ConfigItem(
- position = 2,
- keyName = "bodyRuneColor",
- name = "Body Rune Color",
- description = "Color used to highlight Body runes."
- )
- default Color bodyRuneColor()
- {
- return Color.MAGENTA;
- }
-
- @ConfigItem(
- position = 3,
- keyName = "airRuneColor",
- name = "Air Rune Color",
- description = "Color used to highlight Air runes."
- )
- default Color airRuneColor()
- {
- return Color.WHITE;
- }
-
- @ConfigItem(
- position = 4,
- keyName = "deathRuneColor",
- name = "Death Rune Color",
- description = "Color used to highlight Death runes."
- )
- default Color deathRuneColor()
- {
- return Color.BLACK;
- }
-
- @ConfigItem(
- position = 5,
- keyName = "waterRuneColor",
- name = "Water Rune Color",
- description = "Color used to highlight Water runes."
- )
- default Color waterRuneColor()
- {
- return Color.BLUE;
- }
-
- @ConfigItem(
- position = 6,
- keyName = "chaosRuneColor",
- name = "Chaos Rune Color",
- description = "Color used to highlight Chaos runes."
- )
- default Color chaosRuneColor()
- {
- return Color.YELLOW;
- }
-
- @ConfigItem(
- position = 7,
- keyName = "earthRuneColor",
- name = "Earth Rune Color",
- description = "Color used to highlight Earth runes."
- )
- default Color earthRuneColor()
- {
- return Color.GREEN;
- }
-
- @ConfigItem(
- position = 8,
- keyName = "lawRuneColor",
- name = "Law Rune Color",
- description = "Color used to highlight Law runes."
- )
- default Color lawRuneColor()
- {
- return Color.CYAN;
- }
-
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsOverlay.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsOverlay.java
deleted file mode 100644
index c2908f8107..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/statusbars/StatusBarsOverlay.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 2018, Jos
- * 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.client.plugins.statusbars;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.Image;
-import javax.inject.Inject;
-import api.Client;
-import api.MenuEntry;
-import api.Point;
-import api.Skill;
-import api.VarPlayer;
-import api.Varbits;
-import api.widgets.Widget;
-import api.widgets.WidgetInfo;
-import net.runelite.client.game.SkillIconManager;
-import net.runelite.client.plugins.itemstats.Effect;
-import net.runelite.client.plugins.itemstats.ItemStatChangesService;
-import net.runelite.client.plugins.itemstats.StatChange;
-import net.runelite.client.plugins.itemstats.StatsChanges;
-import net.runelite.client.ui.FontManager;
-import net.runelite.client.ui.overlay.Overlay;
-import net.runelite.client.ui.overlay.OverlayLayer;
-import net.runelite.client.ui.overlay.OverlayPosition;
-import net.runelite.client.ui.overlay.components.TextComponent;
-import net.runelite.client.util.ImageUtil;
-
-class StatusBarsOverlay extends Overlay
-{
- private static final Color PRAYER_COLOR = new Color(50, 200, 200, 175);
- private static final Color QUICK_PRAYER_COLOR = new Color(57, 255, 186, 225);
- private static final Color BACKGROUND = new Color(0, 0, 0, 150);
- private static final Color HEALTH_COLOR = new Color(225, 35, 0, 125);
- private static final Color POISONED_COLOR = new Color(0, 145, 0, 150);
- private static final Color VENOMED_COLOR = new Color(0, 65, 0, 150);
- private static final Color HEAL_COLOR = new Color(255, 112, 6, 150);
- private static final Color PRAYER_HEAL_COLOR = new Color(57, 255, 186, 75);
- private static final Color OVERHEAL_COLOR = new Color(216, 255, 139, 150);
- private static final int HEIGHT = 252;
- private static final int RESIZED_BOTTOM_HEIGHT = 272;
- private static final int WIDTH = 20;
- private static final int PADDING = 1;
- private static final int IMAGE_SIZE = 17;
- private static final int HEALTH_LOCATION_X = 0;
- private static final int PRAYER_LOCATION_X = 1;
- private static final int RESIZED_BOTTOM_OFFSET_Y = 12;
- private static final int RESIZED_BOTTOM_OFFSET_X = 10;
- private static final int OVERHEAL_OFFSET = 2;
- private static final int HEAL_OFFSET = 3;
- private static final int ICON_AND_COUNTER_OFFSET_X = 1;
- private static final int ICON_AND_COUNTER_OFFSET_Y = 21;
- private static final int SKILL_ICON_HEIGHT = 35;
- private static final int COUNTER_ICON_HEIGHT = 18;
- private static final int OFFSET = 2;
-
- private final Client client;
- private final StatusBarsConfig config;
- private final SkillIconManager skillIconManager;
- private final TextComponent textComponent = new TextComponent();
- private final ItemStatChangesService itemStatService;
-
- private final Image prayerImage;
-
- @Inject
- private StatusBarsOverlay(Client client, StatusBarsConfig config, SkillIconManager skillIconManager, ItemStatChangesService itemstatservice)
- {
- setPosition(OverlayPosition.DYNAMIC);
- setLayer(OverlayLayer.ABOVE_WIDGETS);
- this.client = client;
- this.config = config;
- this.skillIconManager = skillIconManager;
- this.itemStatService = itemstatservice;
-
- prayerImage = ImageUtil.resizeImage(skillIconManager.getSkillImage(Skill.PRAYER, true), IMAGE_SIZE, IMAGE_SIZE);
- }
-
- @Override
- public Dimension render(Graphics2D g)
- {
- final Widget widgetBankTitleBar = client.getWidget(WidgetInfo.BANK_TITLE_BAR);
- if (widgetBankTitleBar != null && !widgetBankTitleBar.isHidden())
- {
- return null;
- }
-
- Viewport curViewport = null;
- Widget curWidget = null;
-
- for (Viewport viewport : Viewport.values())
- {
- final Widget viewportWidget = client.getWidget(viewport.getViewport());
- if (viewportWidget != null && !viewportWidget.isHidden())
- {
- curViewport = viewport;
- curWidget = viewportWidget;
- break;
- }
- }
-
- if (curViewport == null || curWidget.isHidden())
- {
- return null;
- }
-
- final Point offsetLeft = curViewport.getOffsetLeft();
- final Point offsetRight = curViewport.getOffsetRight();
- final Point location = curWidget.getCanvasLocation();
- final int height, offsetHealthX, offsetHealthY, offsetPrayerX, offsetPrayerY;
-
- if (curViewport == Viewport.RESIZED_BOTTOM)
- {
- height = RESIZED_BOTTOM_HEIGHT;
- offsetHealthX = (location.getX() + RESIZED_BOTTOM_OFFSET_X - offsetLeft.getX());
- offsetHealthY = (location.getY() - RESIZED_BOTTOM_OFFSET_Y - offsetRight.getY());
- offsetPrayerX = (location.getX() + RESIZED_BOTTOM_OFFSET_X - offsetRight.getX());
- offsetPrayerY = (location.getY() - RESIZED_BOTTOM_OFFSET_Y - offsetRight.getY());
- }
- else
- {
- height = HEIGHT;
- offsetHealthX = (location.getX() - offsetLeft.getX());
- offsetHealthY = (location.getY() - offsetLeft.getY());
- offsetPrayerX = (location.getX() - offsetRight.getX()) + curWidget.getWidth();
- offsetPrayerY = (location.getY() - offsetRight.getY());
- }
-
- final int poisonState = client.getVar(VarPlayer.IS_POISONED);
- final Color healthBar;
-
- if (poisonState >= 1000000)
- {
- healthBar = VENOMED_COLOR;
- }
- else if (poisonState > 0)
- {
- healthBar = POISONED_COLOR;
- }
- else
- {
- healthBar = HEALTH_COLOR;
- }
-
- final int maxHealth = client.getRealSkillLevel(Skill.HITPOINTS);
- final int maxPrayer = client.getRealSkillLevel(Skill.PRAYER);
- final int currentHealth = client.getBoostedSkillLevel(Skill.HITPOINTS);
- final int currentPrayer = client.getBoostedSkillLevel(Skill.PRAYER);
- final int quickPrayerState = client.getVar(Varbits.QUICK_PRAYER);
- final Color prayerBar = quickPrayerState == 1 ? QUICK_PRAYER_COLOR : PRAYER_COLOR;
-
- renderBar(g, offsetHealthX, offsetHealthY,
- maxHealth, currentHealth, height, healthBar);
-
- renderBar(g, offsetPrayerX, offsetPrayerY,
- maxPrayer, currentPrayer, height, prayerBar);
-
- if (config.enableRestorationBars())
- {
- final MenuEntry[] menu = client.getMenuEntries();
- final int menuSize = menu.length;
- final MenuEntry entry = menuSize > 0 ? menu[menuSize - 1] : null;
- int prayerHealValue = 0;
- int foodHealValue = 0;
- if (entry != null && entry.getParam1() == WidgetInfo.INVENTORY.getId())
- {
- final Effect change = itemStatService.getItemStatChanges(entry.getIdentifier());
-
- if (change != null)
- {
- final StatsChanges statsChanges = change.calculate(client);
-
- for (final StatChange c : statsChanges.getStatChanges())
- {
- final int theoreticalBoost = c.getTheoretical();
-
- if (c.getStat().getName().equals(Skill.HITPOINTS.getName()))
- {
- foodHealValue = theoreticalBoost;
- }
-
- if (c.getStat().getName().equals(Skill.PRAYER.getName()))
- {
- prayerHealValue = theoreticalBoost;
- }
-
- if (foodHealValue != 0 && prayerHealValue != 0)
- {
- break;
- }
- }
- }
- }
-
- renderHealingBar(g, offsetHealthX, offsetHealthY,
- maxHealth, currentHealth, height,
- foodHealValue, HEAL_COLOR);
-
- renderHealingBar(g, offsetPrayerX, offsetPrayerY,
- maxPrayer, currentPrayer, height,
- prayerHealValue, PRAYER_HEAL_COLOR);
- }
-
- if (config.enableSkillIcon() || config.enableCounter())
- {
- final Image healthImage = skillIconManager.getSkillImage(Skill.HITPOINTS, true);
- final int counterHealth = client.getBoostedSkillLevel(Skill.HITPOINTS);
- final int counterPrayer = client.getBoostedSkillLevel(Skill.PRAYER);
- final String counterHealthText = Integer.toString(counterHealth);
- final String counterPrayerText = Integer.toString(counterPrayer);
-
- renderIconsAndCounters(g, offsetPrayerX, offsetPrayerY, prayerImage, counterPrayerText, PRAYER_LOCATION_X);
- renderIconsAndCounters(g, offsetHealthX, offsetHealthY, healthImage, counterHealthText, HEALTH_LOCATION_X);
- }
-
- return null;
- }
-
- private static void renderBar(Graphics2D graphics, int x, int y, int max, int current, int height, Color filled)
- {
- graphics.setColor(BACKGROUND);
- graphics.drawRect(x, y, WIDTH - PADDING, height - PADDING);
- graphics.fillRect(x, y, WIDTH, height);
-
- final int filledHeight = getBarHeight(max, current, height);
- graphics.setColor(filled);
- graphics.fillRect(x + PADDING,
- y + PADDING + (height - filledHeight),
- WIDTH - PADDING * OFFSET,
- filledHeight - PADDING * OFFSET);
- }
-
- private static void renderHealingBar(Graphics2D graphics, int x, int y, int max, int current, int height, int heal, Color color)
- {
- if (heal <= 0)
- {
- return;
- }
-
- final int filledCurrentHeight = getBarHeight(max, current, height);
- int filledHeight = getBarHeight(max, heal, height);
- graphics.setColor(color);
-
- if (filledHeight + filledCurrentHeight > height)
- {
- final int overHeal = filledHeight + filledCurrentHeight - height;
- filledHeight = filledHeight - overHeal + OVERHEAL_OFFSET;
- graphics.setColor(OVERHEAL_COLOR);
- graphics.fillRect(x + PADDING,
- y - filledCurrentHeight + (height - filledHeight) + HEAL_OFFSET,
- WIDTH - PADDING * OVERHEAL_OFFSET,
- filledHeight - PADDING * OVERHEAL_OFFSET);
- }
- else
- {
- graphics.fillRect(x + PADDING,
- y - OVERHEAL_OFFSET - filledCurrentHeight + (height - filledHeight) + HEAL_OFFSET,
- WIDTH - PADDING * OVERHEAL_OFFSET,
- filledHeight + OVERHEAL_OFFSET - PADDING * OVERHEAL_OFFSET);
- }
- }
-
- private static int getBarHeight(int base, int current, int size)
- {
- final double ratio = (double) current / base;
-
- if (ratio >= 1)
- {
- return size;
- }
-
- return (int) Math.round(ratio * size);
- }
-
- private void renderIconsAndCounters(Graphics2D graphics, int x, int y, Image image, String counterText, int counterPadding)
- {
- final int widthOfCounter = graphics.getFontMetrics().stringWidth(counterText);
- final int centerText = (WIDTH - PADDING) / 2 - (widthOfCounter / 2);
-
- if (config.enableCounter())
- {
- graphics.setFont(FontManager.getRunescapeSmallFont());
- textComponent.setColor(Color.WHITE);
- textComponent.setText(counterText);
- textComponent.setPosition(new java.awt.Point(x + centerText + counterPadding, y + COUNTER_ICON_HEIGHT));
- }
- else
- {
- textComponent.setText("");
- }
-
- if (config.enableSkillIcon())
- {
- graphics.drawImage(image, x + ICON_AND_COUNTER_OFFSET_X + PADDING, y + ICON_AND_COUNTER_OFFSET_Y - image.getWidth(null), null);
- textComponent.setPosition(new java.awt.Point(x + centerText + counterPadding, y + SKILL_ICON_HEIGHT));
- }
-
- textComponent.render(graphics);
- }
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/test/Test.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/test/Test.java
deleted file mode 100644
index c6772da865..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/test/Test.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2018, https://runelitepl.us
- * 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.client.plugins.test;
-
-import api.Client;
-import api.events.ChatMessage;
-import api.events.ClientTick;
-import api.events.GameTick;
-import api.events.MenuOpened;
-import api.events.VarbitChanged;
-import com.google.common.eventbus.Subscribe;
-import com.google.inject.Binder;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import com.google.inject.Provides;
-import lombok.extern.slf4j.Slf4j;
-import net.runelite.client.config.ConfigManager;
-import net.runelite.client.plugins.Plugin;
-import net.runelite.client.plugins.PluginDescriptor;
-import net.runelite.client.ui.overlay.OverlayManager;
-
-/**
- * Authors gazivodag longstreet
- */
-@PluginDescriptor(
- name = "Test",
- description = "Testing plugin for building functionality",
- tags = {}
-)
-@Singleton
-@Slf4j
-public class Test extends Plugin
-{
-
- @Provides
- TestConfig getConfig(ConfigManager configManager)
- {
- return configManager.getConfig(TestConfig.class);
- }
-
- @Inject
- private TestOverlay testOverlay;
-
- @Inject
- private TestConfig config;
-
- @Inject
- private Client client;
-
- @Inject
- private OverlayManager overlayManager;
-
- @Override
- public void configure(Binder binder)
- {
- }
-
- @Override
- protected void startUp() throws Exception
- {
- overlayManager.add(testOverlay);
- System.out.println("Test Plugin started");
- }
-
- @Override
- protected void shutDown() throws Exception
- {
-
- }
-
- @Subscribe
- public void onMenuOpened(MenuOpened event)
- {
- System.out.println("[Test Plugin] Menu Opened");
- }
-
- @Subscribe
- public void onChatMessage(ChatMessage chatMessage)
- {
- System.out.println("[Test Plugin] Chat Message");
- }
-
- @Subscribe
- public void onVarbitChanged(VarbitChanged event)
- {
- System.out.println("[Test Plugin] Varbit Changed");
- }
-}
\ No newline at end of file
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterConfig.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterConfig.java
deleted file mode 100644
index ef349f58d1..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterConfig.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2018, James Munson
- * 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 HOLDER 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.client.plugins.tickcounter;
-
-import java.awt.Color;
-import net.runelite.client.config.Alpha;
-import net.runelite.client.config.Config;
-import net.runelite.client.config.ConfigGroup;
-import net.runelite.client.config.ConfigItem;
-
-@ConfigGroup("tickcounter")
-public interface TickCounterConfig extends Config
-{
- @ConfigItem(
- keyName = "resetInstance",
- name = "Reset on new instances",
- description = "",
- position = 1
- )
- default boolean instance()
- {
- return true;
- }
-
- @Alpha
- @ConfigItem(
- keyName = "selfColor",
- name = "Your color",
- description = "",
- position = 4
- )
- default Color selfColor()
- {
- return Color.green;
- }
-
- @Alpha
- @ConfigItem(
- keyName = "totalColor",
- name = "Total color",
- description = "",
- position = 6
- )
- default Color totalColor()
- {
- return Color.RED;
- }
-
- @Alpha
- @ConfigItem(
- keyName = "otherColor",
- name = "Other players color",
- description = "",
- position = 5
- )
- default Color otherColor()
- {
- return Color.white;
- }
-
- @Alpha
- @ConfigItem(
- keyName = "bgColor",
- name = "Background color",
- description = "",
- position = 3
- )
- default Color bgColor()
- {
- return new Color(70, 61, 50, 156);
- }
-
- @Alpha
- @ConfigItem(
- keyName = "titleColor",
- name = "Title color",
- description = "",
- position = 2
- )
- default Color titleColor()
- {
- return Color.white;
- }
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterOverlay.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterOverlay.java
deleted file mode 100644
index cb6821ec72..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterOverlay.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2018, James Munson
- * 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 HOLDER 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.client.plugins.tickcounter;
-
-/*public class TickCounterOverlay extends Overlay
-{
-
- private TickCounterPlugin plugin;
- private TickCounterConfig config;
- private Client client;
- private PanelComponent panelComponent = new PanelComponent();
-
- @Inject
- public TickCounterOverlay(TickCounterPlugin plugin, Client client, TickCounterConfig config)
- {
- super(plugin);
- setPosition(OverlayPosition.DYNAMIC);
- setPosition(OverlayPosition.DETACHED);
- setPosition(OverlayPosition.BOTTOM_RIGHT);
- this.plugin = plugin;
- this.client = client;
- this.config = config;
- }
-
- @Override
- public Dimension render(Graphics2D g)
- {
- List elems = panelComponent.getChildren();
- elems.clear();
- panelComponent.setBackgroundColor(config.bgColor());
- elems.add(TitleComponent.builder().text("Combat counter").color(config.titleColor()).build());
- List> list = new ArrayList<>(plugin.activity.entrySet());
- list.sort((o1, o2) ->
- {
- int value = -Integer.compare(o1.getValue(), o2.getValue());
- if (value == 0)
- {
- value = o1.getKey().compareTo(o2.getKey());
- }
- return value;
- });
- int total = 0;
- for (Entry e : list)
- {
- total += e.getValue();
- if (e.getKey().equals(client.getLocalPlayer().getName()))
- {
- elems.add(LineComponent.builder().leftColor(config.selfColor()).rightColor(config.selfColor()).left(e.getKey()).right(e.getValue().toString()).build());
- }
- else
- {
- elems.add(LineComponent.builder().left(e.getKey()).right(e.getValue().toString()).leftColor(config.otherColor()).rightColor(config.otherColor()).build());
-
- }
- }
- elems.add(LineComponent.builder().left("Total").leftColor(config.totalColor()).rightColor(config.totalColor()).right(String.valueOf(total)).build());
- return this.panelComponent.render(g);
- }
-
-}*/
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterPlugin.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterPlugin.java
deleted file mode 100644
index 74c7c3a612..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/tickcounter/TickCounterPlugin.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (c) 2018, James Munson
- * 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 HOLDER 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.client.plugins.tickcounter;
-
-import net.runelite.client.plugins.Plugin;
-import net.runelite.client.plugins.PluginDescriptor;
-import net.runelite.client.plugins.PluginType;
-
-@PluginDescriptor(name = "Tick Counter",
- description = "Counts combat activity for nearby players",
- enabledByDefault = false,
- type = PluginType.PVP
-)
-public class TickCounterPlugin extends Plugin
-{
- //todo once bytecodes work again, re-enable
-/*
- @Inject
- private OverlayManager overlayManager;
-
- @Inject
- private TickCounterConfig config;
-
- @Inject
- private Client client;
-
- @Provides
- TickCounterConfig provideConfig(ConfigManager configManager)
- {
- return configManager.getConfig(TickCounterConfig.class);
- }
-
- @Inject
- private TickCounterOverlay overlay;
-
- Map activity = new HashMap<>();
-
- private List blowpiping = new ArrayList<>();
- private boolean instanced = false;
-
- @Override
- protected void startUp() throws Exception
- {
- overlayManager.add(overlay);
- }
-
- @Override
- protected void shutDown() throws Exception
- {
- overlayManager.remove(overlay);
- activity.clear();
- }
-
- @Subscribe
- public void onAnimationChanged(AnimationChanged e)
- {
- if (!(e.getActor() instanceof Player))
- {
- return;
- }
- Player p = (Player) e.getActor();
- int weapon = -1;
- if (p.getPlayerAppearance() != null)
- {
- weapon = p.getPlayerAppearance().getEquipmentId(KitType.WEAPON);
- }
- int delta = 0;
- switch (p.getAnimation())
- {
- case 7617: // rune knife
- case 8194: // dragon knife
- case 8291: // dragon knife spec
- case 5061: // blowpipe
- if (weapon == 12926)
- {
- blowpiping.add(p);
- }
- else
- {
- delta = 2;
- }
- break;
- case 2323: // rpg
- case 7618: // chin
- delta = 3;
- break;
- case 426: // bow shoot
- if (weapon == 20997) // twisted bow
- {
- delta = 5;
- }
- else // shortbow
- {
- delta = 3;
- }
- break;
- case 376: // dds poke
- case 377: // dds slash
- case 422: // punch
- case 423: // kick
- case 386: // lunge
- case 390: // generic slash
- case 1062: // dds spec
- case 1067: // claw stab
- case 1074: // msb spec
- case 1167: // trident cast
- case 1658: // whip
- case 2890: // arclight spec
- case 3294: // abby dagger slash
- case 3297: // abby dagger poke
- case 3298: // bludgeon attack
- case 3299: // bludgeon spec
- case 3300: // abby dagger spec
- case 7514: // claw spec
- case 7515: // d sword spec
- case 8145: // rapier stab
- case 8288: // dhl stab
- case 8289: // dhl slash
- case 8290: // dhl crush
- delta = 4;
- break;
- case 393: // staff bash
- if (weapon == 13652)
- { // claw scratch
- delta = 4;
- break;
- }
- case 395: // axe autos
- case 400: // pick smash
- case 1379: //burst or blitz
- case 1979: // barrage spell cast
- case 1162: // strike/bolt spells
- case 7552: // generic crossbow
- case 7855: // surge spells
- case 8056: // scythe swing
- delta = 5;
- break;
- case 401:
- if (weapon == 13576) // dwh bop
- {
- delta = 6;
- }
- else // used by pickaxe and axe
- {
- delta = 5;
- }
- break;
- case 1378:
- case 7045:
- case 7054:
- case 7055: // godsword autos
- case 7511: // dinh's attack
- case 7516: // maul attack
- case 7555: // ballista attack
- case 7638: // zgs spec
- case 7640: // sgs spec
- case 7642: // bgs spec
- case 7643: // bgs spec
- case 7644: // ags spec
- delta = 6;
- break;
- case 428: // chally swipe
- case 440: // chally jab
- case 1203: // chally spec
- delta = 7;
- break;
- case -1:
- blowpiping.remove(p);
- break;
- }
- if (delta > 0)
- {
- String name = p.getName();
- this.activity.put(name, this.activity.getOrDefault(name, 0) + delta);
- }
- }
-
- @Subscribe
- public void onClientTick(ClientTick e)
- {
- *//*
- * Hack for blowpipe since the AnimationChanged event doesn't fire when using a
- * blowpipe because of its speed. If blowpipe animation restarts, then add 2
- *//*
- for (Player p : blowpiping)
- {
- if (p.getActionFrame() == 0 && p.getActionFrameCycle() == 1)
- {
- String name = p.getName();
- int activity = this.activity.getOrDefault(name, 0);
- this.activity.put(name, activity + 2);
- }
- }
- }
-
- @Subscribe
- public void onGameTick(GameTick tick)
- {
- if (!config.instance())
- {
- return;
- }
- boolean prevInstance = instanced;
- instanced = client.isInInstancedRegion();
- if (!prevInstance && instanced)
- {
- activity.clear();
- }
- }*/
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java
deleted file mode 100644
index 2472b26277..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/vorkath/VorkathPlugin.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (c) 2018, https://runelitepl.us
- * 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.client.plugins.vorkath;
-
-import java.awt.image.BufferedImage;
-import javax.inject.Inject;
-import lombok.Getter;
-import api.AnimationID;
-import api.Client;
-import api.GameState;
-import api.NPC;
-import api.NpcID;
-import api.events.GameStateChanged;
-import api.events.GameTick;
-import api.events.NpcDespawned;
-import api.events.NpcSpawned;
-import net.runelite.client.callback.ClientThread;
-import net.runelite.client.eventbus.Subscribe;
-import net.runelite.client.plugins.Plugin;
-import net.runelite.client.plugins.PluginDescriptor;
-import net.runelite.client.plugins.PluginType;
-import net.runelite.client.ui.overlay.OverlayManager;
-import net.runelite.client.util.ImageUtil;
-
-@PluginDescriptor(
- name = "Vorkath Helper",
- description = "Count vorkath attacks, and which phase is coming next",
- tags = {"combat", "overlay", "pve", "pvm"},
- type = PluginType.PVM
-)
-public class VorkathPlugin extends Plugin
-{
- @Inject
- private Client client;
-
- @Inject
- private OverlayManager overlayManager;
-
- @Inject
- private VorkathOverlay overlay;
-
- @Inject
- private ZombifiedSpawnOverlay SpawnOverlay;
-
- @Inject
- private ClientThread clientThread;
-
- @Getter
- private Vorkath vorkath;
-
- @Getter
- private ZombifiedSpawn spawn;
-
- static final BufferedImage ACID;
- static final BufferedImage ICE;
- static final BufferedImage MAGERANGE;
-
- static
- {
- ACID = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "acid.png");
- ICE = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "ice.png");
- MAGERANGE = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "magerange.png");
- }
-
- @Override
- protected void startUp()
- {
- overlayManager.add(overlay);
- overlayManager.add(SpawnOverlay);
- clientThread.invoke(this::reset);
- }
-
- @Override
- protected void shutDown()
- {
- overlayManager.remove(overlay);
- overlayManager.remove(SpawnOverlay);
- }
-
- private void reset()
- {
- this.vorkath = null;
- for (NPC npc : client.getNpcs())
- {
- if (isNpcVorkath(npc.getId()))
- {
- this.vorkath = new Vorkath(npc);
- }
- else if (isNpcZombifiedSpawn(npc.getId()))
- {
- this.spawn = new ZombifiedSpawn(npc);
- }
- }
- }
-
- private static boolean isNpcVorkath(int npcId)
- {
- return npcId == NpcID.VORKATH ||
- npcId == NpcID.VORKATH_8058 ||
- npcId == NpcID.VORKATH_8059 ||
- npcId == NpcID.VORKATH_8060 ||
- npcId == NpcID.VORKATH_8061;
- }
-
- private static boolean isNpcZombifiedSpawn(int id)
- {
- return id == NpcID.ZOMBIFIED_SPAWN ||
- id == NpcID.ZOMBIFIED_SPAWN_8063;
- }
-
- @Subscribe
- public void onNpcSpawned(NpcSpawned event)
- {
- NPC npc = event.getNpc();
- if (isNpcVorkath(npc.getId()))
- {
- this.vorkath = new Vorkath(npc);
- }
- else if (isNpcZombifiedSpawn(npc.getId()))
- {
- this.spawn = new ZombifiedSpawn(npc);
- }
- }
-
- @Subscribe
- public void onNpcDespawned(NpcDespawned npcDespawned)
- {
- final NPC npc = npcDespawned.getNpc();
- if (this.vorkath != null)
- {
- if (npc.getId() == this.vorkath.getNpc().getId())
- {
- this.vorkath = null;
- reset();
- }
- }
-
- if (this.spawn != null)
- {
- if (npc.getId() == this.spawn.getNpc().getId())
- {
- this.spawn = null;
- }
- }
- }
-
-
- @Subscribe
- public void onGameStateChanged(GameStateChanged event)
- {
- GameState gs = event.getGameState();
- if (gs == GameState.LOGGING_IN ||
- gs == GameState.CONNECTION_LOST ||
- gs == GameState.HOPPING)
- {
- reset();
- }
- }
-
- @Subscribe
- public void onGameTick(GameTick event)
- {
- if (vorkath != null)
- {
- int animationId = vorkath.getNpc().getAnimation();
-
- if (animationId != vorkath.getLastTickAnimation())
- {
- if (animationId == AnimationID.VORKATH_ACID_ATTACK)
- {
- vorkath.setPhase(2);
- vorkath.setAttacksUntilSwitch(Vorkath.ATTACKS_PER_SWITCH);
- }
- else if (animationId == AnimationID.VORKATH_ATTACK && vorkath.getAttacksUntilSwitch() == 0)
- {
- vorkath.setPhase(1);
- vorkath.setAttacksUntilSwitch(Vorkath.ATTACKS_PER_SWITCH);
- //Vorkath does a bomb animation after the ice dragon breathe, we need to account for it
- vorkath.setIcePhaseAttack(true);
- }
- else if (animationId == AnimationID.VORKATH_ATTACK || animationId == AnimationID.VORKATH_FIRE_BOMB_ATTACK)
- {
- if (vorkath.isIcePhaseAttack())
- {
- vorkath.setIcePhaseAttack(false);
- }
- else
- {
- vorkath.setAttacksUntilSwitch(vorkath.getAttacksUntilSwitch() - 1);
- }
- }
- }
-
- vorkath.setLastTickAnimation(animationId);
- }
- }
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraListener.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraListener.java
deleted file mode 100644
index ee6181b55d..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/wasdcamera/WASDCameraListener.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2018, Adam
- * Copyright (c) 2018, Abexlry
- * 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.client.plugins.wasdcamera;
-
-import com.google.common.base.Strings;
-import java.awt.event.KeyEvent;
-import java.util.HashMap;
-import java.util.Map;
-import javax.inject.Inject;
-import api.Client;
-import api.GameState;
-import api.VarClientStr;
-import net.runelite.client.callback.ClientThread;
-import net.runelite.client.input.KeyListener;
-import net.runelite.client.input.MouseAdapter;
-
-class WASDCameraListener extends MouseAdapter implements KeyListener
-{
- @Inject
- private WASDCameraPlugin plugin;
-
- @Inject
- private WASDCameraConfig config;
-
- @Inject
- private Client client;
-
- @Inject
- private ClientThread clientThread;
-
- private final Map modified = new HashMap<>();
-
- @Override
- public void keyTyped(KeyEvent e)
- {
- }
-
- @Override
- public void keyPressed(KeyEvent e)
- {
- if (client.getGameState() != GameState.LOGGED_IN || !plugin.chatboxFocused())
- {
- return;
- }
-
- if (!plugin.isTyping())
- {
- if (config.up().matches(e))
- {
- modified.put(e.getKeyCode(), KeyEvent.VK_UP);
- e.setKeyCode(KeyEvent.VK_UP);
- }
- else if (config.down().matches(e))
- {
- modified.put(e.getKeyCode(), KeyEvent.VK_DOWN);
- e.setKeyCode(KeyEvent.VK_DOWN);
- }
- else if (config.left().matches(e))
- {
- modified.put(e.getKeyCode(), KeyEvent.VK_LEFT);
- e.setKeyCode(KeyEvent.VK_LEFT);
- }
- else if (config.right().matches(e))
- {
- modified.put(e.getKeyCode(), KeyEvent.VK_RIGHT);
- e.setKeyCode(KeyEvent.VK_RIGHT);
- }
- else
- {
- switch (e.getKeyCode())
- {
- case KeyEvent.VK_ENTER:
- case KeyEvent.VK_SLASH:
- case KeyEvent.VK_COLON:
- // refocus chatbox
- plugin.setTyping(true);
- clientThread.invoke(() ->
- {
- plugin.unlockChat();
- });
- break;
- }
- }
- }
- else
- {
- switch (e.getKeyCode())
- {
- case KeyEvent.VK_ENTER:
- plugin.setTyping(false);
- clientThread.invoke(() ->
- {
- plugin.lockChat();
- });
- break;
- case KeyEvent.VK_ESCAPE:
- plugin.setTyping(false);
- clientThread.invoke(() ->
- {
- client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, "");
- plugin.lockChat();
- });
- break;
- case KeyEvent.VK_BACK_SPACE:
- if (Strings.isNullOrEmpty(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT)))
- {
- plugin.setTyping(false);
- clientThread.invoke(() -> plugin.lockChat());
- }
- }
- }
- }
-
- @Override
- public void keyReleased(KeyEvent e)
- {
- if (client.getGameState() != GameState.LOGGED_IN)
- {
- return;
- }
-
- if (plugin.chatboxFocused() && !plugin.isTyping())
- {
- modified.remove(e.getKeyCode());
-
- if (config.up().matches(e))
- {
- e.setKeyCode(KeyEvent.VK_UP);
- }
- else if (config.down().matches(e))
- {
- e.setKeyCode(KeyEvent.VK_DOWN);
- }
- else if (config.left().matches(e))
- {
- e.setKeyCode(KeyEvent.VK_LEFT);
- }
- else if (config.right().matches(e))
- {
- e.setKeyCode(KeyEvent.VK_RIGHT);
- }
- }
- else
- {
- // press d + enter + release d - causes the right arrow to never be released
- Integer m = modified.get(e.getKeyCode());
- if (m != null)
- {
- modified.remove(e.getKeyCode());
- e.setKeyCode(m);
- }
- }
- }
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java b/RuneLitePlus/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java
deleted file mode 100644
index e1e8ec2e8d..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/worldmap/QuestStartLocation.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2018, John James Hamilton
- * 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 HOLDER 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.client.plugins.worldmap;
-
-import lombok.Getter;
-import api.coords.WorldPoint;
-
-enum QuestStartLocation
-{
- //Free Quests
- COOKS_ASSISTANT_RFD("Cook's Assistant", new WorldPoint(3211, 3216, 0)),
- THE_CORSAIR_CURSE("The Corsair Curse", new WorldPoint(3029, 3273, 0)),
- DEMON_SLAYER("Demon Slayer", new WorldPoint(3204, 3424, 0)),
- DORICS_QUEST("Doric's Quest", new WorldPoint(2952, 3450, 0)),
- DRAGON_SLAYER("Dragon Slayer", new WorldPoint(3190, 3362, 0)),
- ERNEST_THE_CHICKEN("Ernest the Chicken", new WorldPoint(3109, 3330, 0)),
- GOBLIN_DIPLOMACY("Goblin Diplomacy", new WorldPoint(2957, 3509, 0)),
- IMP_CATCHER("Imp Catcher", new WorldPoint(3108, 3160, 0)),
- THE_KNIGHTS_SWORD("The Knight's Sword", new WorldPoint(2976, 3342, 0)),
- MISTHALIN_MYSTERY("Misthalin Mystery", new WorldPoint(3234, 3155, 0)),
- PIRATES_TREASURE("Pirate's Treasure", new WorldPoint(3051, 3252, 0)),
- PRINCE_ALI_RESCUE("Prince Ali Rescue", new WorldPoint(3301, 3163, 0)),
- THE_RESTLESS_GHOST("The Restless Ghost", new WorldPoint(3240, 3210, 0)),
- RUNE_MYSTERIES("Rune Mysteries", new WorldPoint(3210, 3220, 0)),
- SHEEP_SHEARER("Sheep Shearer", new WorldPoint(3190, 3272, 0)),
- SHIELD_OF_ARRAV_PHOENIX_GANG("Shield of Arrav (Phoenix Gang)", new WorldPoint(3208, 3495, 0)),
- SHIELD_OF_ARRAV_BLACK_ARM_GANG("Shield of Arrav (Black Arm Gang)", new WorldPoint(3208, 3392, 0)),
- VAMPIRE_SLAYER("Vampire Slayer", new WorldPoint(3096, 3266, 0)),
- WITCHS_POTION("Witch's Potion", new WorldPoint(2967, 3203, 0)),
- X_MARKS_THE_SPOT("X Marks the Spot", new WorldPoint(3227, 3242, 0)),
-
- //Members' Quests
- ANIMAL_MAGNETISM("Animal Magnetism", new WorldPoint(3094, 3360, 0)),
- ANOTHER_SLICE_OF_HAM("Another Slice of H.A.M.", new WorldPoint(2799, 5428, 0)),
- THE_ASCENT_OF_ARCEUUS("The Ascent of Arceuus", new WorldPoint(1700, 3742, 0)),
- BETWEEN_A_ROCK("Between a Rock...", new WorldPoint(2823, 10168, 0)),
- BIG_CHOMPY_BIRD_HUNTING("Big Chompy Bird Hunting", new WorldPoint(2629, 2981, 0)),
- BIOHAZARD("Biohazard", new WorldPoint(2591, 3335, 0)),
- BONE_VOYAGE("Bone Voyage", new WorldPoint(3259, 3450, 0)),
- CABIN_FEVER("Cabin Fever", new WorldPoint(3674, 3496, 0)),
- CLIENT_OF_KOUREND("Client of Kourend", new WorldPoint(1823, 3690, 0)),
- CLOCK_TOWER("Clock Tower", new WorldPoint(2568, 3249, 0)),
- COLD_WAR("Cold War", new WorldPoint(2593, 3265, 0)),
- CONTACT("Contact!", new WorldPoint(3280, 2770, 0)),
- CREATURE_OF_FENKENSTRAIN("Creature of Fenkenstrain", new WorldPoint(3487, 3485, 0)),
- DARKNESS_OF_HALLOWVALE("Darkness of Hallowvale", new WorldPoint(3494, 9628, 0)),
- DEATH_PLATEAU_TROLL_STRONGHOLD("Death Plateau & Troll Stronghold", new WorldPoint(2895, 3528, 0)),
- DEATH_TO_THE_DORGESHUUN("Death to the Dorgeshuun", new WorldPoint(3316, 9613, 0)),
- THE_DEPTHS_OF_DESPAIR("The Depths of Despair", new WorldPoint(1846, 3556, 0)),
- DESERT_TREASURE("Desert Treasure", new WorldPoint(3177, 3043, 0)),
- DEVIOUS_MINDS("Devious Minds", new WorldPoint(3405, 3492, 0)),
- THE_DIG_SITE("The Dig Site", new WorldPoint(3363, 3337, 0)),
- DRAGON_SLAYER_II("Dragon Slayer II", new WorldPoint(2456, 2868, 0)),
- DREAM_MENTOR("Dream Mentor", new WorldPoint(2144, 10346, 0)),
- DRUIDIC_RITUAL("Druidic Ritual", new WorldPoint(2916, 3484, 0)),
- DWARF_CANNON("Dwarf Cannon", new WorldPoint(2566, 3461, 0)),
- EADGARS_RUSE("Eadgar's Ruse", new WorldPoint(2896, 3426, 0)),
- EAGLES_PEAK("Eagles' Peak", new WorldPoint(2605, 3264, 0)),
- ELEMENTAL_WORKSHOP("Elemental Workshop I & II", new WorldPoint(2714, 3482, 0)),
- ENAKHRAS_LAMENT("Enakhra's Lament", new WorldPoint(3190, 2926, 0)),
- ENLIGHTENED_JOURNEY("Enlightened Journey", new WorldPoint(2809, 3356, 0)),
- THE_EYES_OF_GLOUPHRIE("The Eyes of Glouphrie", new WorldPoint(2400, 3419, 0)),
- FAIRYTALE("Fairytale I & II", new WorldPoint(3077, 3258, 0)),
- FAMILY_CREST("Family Crest", new WorldPoint(3278, 3404, 0)),
- THE_FEUD("The Feud", new WorldPoint(3301, 3211, 0)),
- FIGHT_ARENA("Fight Arena", new WorldPoint(2565, 3199, 0)),
- FISHING_CONTEST_1("Fishing Contest", new WorldPoint(2875, 3483, 0)),
- FISHING_CONTEST_2("Fishing Contest", new WorldPoint(2820, 3487, 0)),
- FORGETTABLE_TALE("Forgettable Tale...", new WorldPoint(2826, 10215, 0)),
- THE_FORSAKEN_TOWER("The Forsaken Tower", new WorldPoint(1484, 3747, 0)),
- THE_FREMENNIK_ISLES("The Fremennik Isles", new WorldPoint(2645, 3711, 0)),
- THE_FREMENNIK_TRIALS("The Fremennik Trials", new WorldPoint(2657, 3669, 0)),
- GARDEN_OF_TRANQUILLITY("Garden of Tranquillity", new WorldPoint(3227, 3477, 0)),
- GERTRUDES_CAT_RATCATCHERS("Gertrude's Cat & Ratcatchers", new WorldPoint(3150, 3411, 0)),
- GHOSTS_AHOY("Ghosts Ahoy", new WorldPoint(3677, 3510, 0)),
- THE_GIANT_DWARF("The Giant Dwarf", new WorldPoint(2841, 10129, 0)),
- THE_GOLEM("The Golem", new WorldPoint(3487, 3089, 0)),
- THE_GRAND_TREE_MONKEY_MADNESS("The Grand Tree & Monkey Madness I & II", new WorldPoint(2466, 3497, 0)),
- THE_GREAT_BRAIN_ROBBERY("The Great Brain Robbery", new WorldPoint(3681, 2963, 0)),
- GRIM_TALES("Grim Tales", new WorldPoint(2890, 3454, 0)),
- THE_HAND_IN_THE_SAND("The Hand in the Sand", new WorldPoint(2552, 3101, 0)),
- HAUNTED_MINE("Haunted Mine", new WorldPoint(3443, 3258, 0)),
- HAZEEL_CULT("Hazeel Cult", new WorldPoint(2565, 3271, 0)),
- HEROES_QUEST("Heroes' Quest", new WorldPoint(2903, 3511, 0)),
- HOLY_GRAIL("Holy Grail & Merlin's Crystal", new WorldPoint(2763, 3515, 0)),
- HORROR_FROM_THE_DEEP("Horror from the Deep", new WorldPoint(2507, 3635, 0)),
- ICTHLARINS_LITTLE_HELPER("Icthlarin's Little Helper", new WorldPoint(3314, 2849, 0)),
- IN_SEARCH_OF_THE_MYREQUE("In Search of the Myreque", new WorldPoint(3502, 3477, 0)),
- JUNGLE_POTION("Jungle Potion", new WorldPoint(2809, 3086, 0)),
- KINGS_RANSOM("King's Ransom", new WorldPoint(2741, 3554, 0)),
- LEGENDS_QUEST("Legends' Quest", new WorldPoint(2725, 3367, 0)),
- LOST_CITY("Lost City", new WorldPoint(3149, 3205, 0)),
- THE_LOST_TRIBE("The Lost Tribe", new WorldPoint(3211, 3224, 0)),
- LUNAR_DIPLOMACY("Lunar Diplomacy", new WorldPoint(2619, 3689, 0)),
- MAKING_FRIENDS_WITH_MY_ARM("Making Friends with My Arm", new WorldPoint(2904, 10092, 0)),
- MAKING_HISTORY("Making History", new WorldPoint(2435, 3346, 0)),
- MONKS_FRIEND("Monk's Friend", new WorldPoint(2605, 3209, 0)),
- MOUNTAIN_DAUGHTER("Mountain Daughter", new WorldPoint(2810, 3672, 0)),
- MOURNINGS_ENDS_PART_I("Mourning's Ends Part I", new WorldPoint(2289, 3149, 0)),
- MOURNINGS_ENDS_PART_II("Mourning's Ends Part II", new WorldPoint(2352, 3172, 0)),
- MURDER_MYSTERY("Murder Mystery", new WorldPoint(2740, 3562, 0)),
- MY_ARMS_BIG_ADVENTURE("My Arm's Big Adventure", new WorldPoint(2908, 10088, 0)),
- NATURE_SPIRIT("Nature Spirit", new WorldPoint(3440, 9894, 0)),
- OBSERVATORY_QUEST("Observatory Quest", new WorldPoint(2438, 3185, 0)),
- OLAFS_QUEST("Olaf's Quest", new WorldPoint(2723, 3729, 0)),
- ONE_SMALL_FAVOUR("One Small Favour", new WorldPoint(2834, 2985, 0)),
- PLAGUE_CITY("Plague City", new WorldPoint(2567, 3334, 0)),
- PRIEST_IN_PERIL("Priest in Peril", new WorldPoint(3219, 3473, 0)),
- THE_QUEEN_OF_THIEVES("The Queen of Thieves", new WorldPoint(1795, 3782, 0)),
- RAG_AND_BONE_MAN("Rag and Bone Man I & II", new WorldPoint(3359, 3504, 0)),
- RECRUITMENT_DRIVE_BLACK_KNIGHTS_FORTRESS("Recruitment Drive & Black Knights' Fortress", new WorldPoint(2959, 3336, 0)),
- ROVING_ELVES("Roving Elves", new WorldPoint(2289, 3146, 0)),
- RUM_DEAL("Rum Deal", new WorldPoint(3679, 3535, 0)),
- SCORPION_CATCHER("Scorpion Catcher", new WorldPoint(2701, 3399, 0)),
- SEA_SLUG("Sea Slug", new WorldPoint(2715, 3302, 0)),
- SHADES_OF_MORTTON("Shades of Mort'ton", new WorldPoint(3463, 3308, 0)),
- SHADOW_OF_THE_STORM("Shadow of the Storm", new WorldPoint(3270, 3159, 0)),
- SHEEP_HERDER("Sheep Herder", new WorldPoint(2616, 3299, 0)),
- SHILO_VILLAGE("Shilo Village", new WorldPoint(2882, 2951, 0)),
- A_SOULS_BANE("A Soul's Bane", new WorldPoint(3307, 3454, 0)),
- SPIRITS_OF_THE_ELID("Spirits of the Elid", new WorldPoint(3441, 2911, 0)),
- SWAN_SONG("Swan Song", new WorldPoint(2345, 3652, 0)),
- TAI_BWO_WANNAI_TRIO("Tai Bwo Wannai Trio", new WorldPoint(2779, 3087, 0)),
- A_TAIL_OF_TWO_CATS("A Tail of Two Cats", new WorldPoint(2917, 3557, 0)),
- TALE_OF_THE_RIGHTEOUS("Tale of the Righteous", new WorldPoint(1511, 3631, 0)),
- A_TASTE_OF_HOPE("A Taste of Hope", new WorldPoint(3668, 3216, 0)),
- TEARS_OF_GUTHIX("Tears of Guthix", new WorldPoint(3251, 9517, 0)),
- TEMPLE_OF_IKOV("Temple of Ikov", new WorldPoint(2574, 3320, 0)),
- THRONE_OF_MISCELLANIA_ROYAL_TROUBLE("Throne of Miscellania & Royal Trouble", new WorldPoint(2497, 3859, 0)),
- THE_TOURIST_TRAP("The Tourist Trap", new WorldPoint(3302, 3113, 0)),
- TOWER_OF_LIFE("Tower of Life", new WorldPoint(2640, 3218, 0)),
- TREE_GNOME_VILLAGE("Tree Gnome Village", new WorldPoint(2541, 3169, 0)),
- TRIBAL_TOTEM("Tribal Totem", new WorldPoint(2790, 3182, 0)),
- TROLL_ROMANCE("Troll Romance", new WorldPoint(2890, 10097, 0)),
- UNDERGROUND_PASS_REGICIDE("Underground Pass & Regicide", new WorldPoint(2575, 3293, 0)),
- WANTED_SLUG_MENACE("Wanted! & The Slug Menace", new WorldPoint(2996, 3373, 0)),
- WATCHTOWER("Watchtower", new WorldPoint(2545, 3112, 0)),
- WATERFALL_QUEST("Waterfall Quest", new WorldPoint(2521, 3498, 0)),
- WHAT_LIES_BELOW("What Lies Below", new WorldPoint(3265, 3333, 0)),
- WITCHS_HOUSE("Witch's House", new WorldPoint(2927, 3456, 0)),
- ZOGRE_FLESH_EATERS("Zogre Flesh Eaters", new WorldPoint(2442, 3051, 0));
-
- @Getter
- private final String tooltip;
-
- @Getter
- private final WorldPoint location;
-
- QuestStartLocation(String description, WorldPoint location)
- {
- this.tooltip = "Quest Start - " + description;
- this.location = location;
- }
-}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/rs/ClientLoader.java b/RuneLitePlus/src/main/java/net/runelite/client/rs/ClientLoader.java
deleted file mode 100644
index 694f5de7e3..0000000000
--- a/RuneLitePlus/src/main/java/net/runelite/client/rs/ClientLoader.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (c) 2016-2017, Adam
- * Copyright (c) 2018, Tomas Slusny
- * Copyright (c) 2018 Abex
- * 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.client.rs;
-
-import api.Client;
-import com.google.common.io.ByteStreams;
-import io.sigpipe.jbsdiff.InvalidHeaderException;
-import io.sigpipe.jbsdiff.Patch;
-import java.applet.Applet;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-import lombok.extern.slf4j.Slf4j;
-import static net.runelite.client.rs.ClientUpdateCheckMode.AUTO;
-import static net.runelite.client.rs.ClientUpdateCheckMode.CUSTOM;
-import static net.runelite.client.rs.ClientUpdateCheckMode.NONE;
-import net.runelite.http.api.RuneLiteAPI;
-import okhttp3.Request;
-import okhttp3.Response;
-import org.apache.commons.compress.compressors.CompressorException;
-
-@Slf4j
-@Singleton
-public class ClientLoader
-{
- private static final File CUSTOMFILE = new File("./injected-client/target/injected-client-1.5.25-SNAPSHOT.jar");
- private final ClientConfigLoader clientConfigLoader;
- private ClientUpdateCheckMode updateCheckMode;
-
- @Inject
- private ClientLoader(
- @Named("updateCheckMode") final ClientUpdateCheckMode updateCheckMode,
- final ClientConfigLoader clientConfigLoader)
- {
- this.updateCheckMode = updateCheckMode;
- this.clientConfigLoader = clientConfigLoader;
- }
-
- public Applet load()
- {
- if (updateCheckMode == NONE)
- {
- return null;
- }
- updateCheckMode = CUSTOM;
- try
- {
- Manifest manifest = new Manifest();
- manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
- RSConfig config = clientConfigLoader.fetch();
-
- Map zipFile = new HashMap<>();
- {
- Certificate[] jagexCertificateChain = getJagexCertificateChain();
- String codebase = config.getCodeBase();
- String initialJar = config.getInitialJar();
- URL url = new URL(codebase + initialJar);
- Request request = new Request.Builder()
- .url(url)
- .build();
-
- try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
- {
- JarInputStream jis;
-
- jis = new JarInputStream(response.body().byteStream());
- byte[] tmp = new byte[4096];
- ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
- for (; ; )
- {
- JarEntry metadata = jis.getNextJarEntry();
- if (metadata == null)
- {
- break;
- }
-
- buffer.reset();
- for (; ; )
- {
- int n = jis.read(tmp);
- if (n <= -1)
- {
- break;
- }
- buffer.write(tmp, 0, n);
- }
-
- if (!Arrays.equals(metadata.getCertificates(), jagexCertificateChain))
- {
- if (metadata.getName().startsWith("META-INF/"))
- {
- // META-INF/JAGEXLTD.SF and META-INF/JAGEXLTD.RSA are not signed, but we don't need
- // anything in META-INF anyway.
- continue;
- }
- else
- {
- throw new VerificationException("Unable to verify jar entry: " + metadata.getName());
- }
- }
-
- zipFile.put(metadata.getName(), buffer.toByteArray());
- }
- }
- }
-
-
- if (updateCheckMode == AUTO)
- {
- ByteArrayOutputStream patchOs = new ByteArrayOutputStream(756 * 1024);
- int patchCount = 0;
-
- for (Map.Entry file : zipFile.entrySet())
- {
- byte[] bytes;
- try (InputStream is = ClientLoader.class.getResourceAsStream("/patch/" + file.getKey() + ".bs"))
- {
- if (is == null)
- {
- continue;
- }
-
- bytes = ByteStreams.toByteArray(is);
- }
-
- patchOs.reset();
- Patch.patch(file.getValue(), bytes, patchOs);
- file.setValue(patchOs.toByteArray());
-
- ++patchCount;
- }
-
- log.info("Patched {} classes", patchCount);
- }
-
- if (updateCheckMode == CUSTOM)
- {
- JarInputStream fis = new JarInputStream(new FileInputStream(CUSTOMFILE));
- byte[] tmp = new byte[4096];
- ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
- for (; ; )
- {
- JarEntry metadata = fis.getNextJarEntry();
- if (metadata == null)
- {
- break;
- }
-
- buffer.reset();
- for (; ; )
- {
- int n = fis.read(tmp);
- if (n <= -1)
- {
- break;
- }
- buffer.write(tmp, 0, n);
- }
- zipFile.replace(metadata.getName(), buffer.toByteArray());
- }
- }
-
- String initialClass = config.getInitialClass();
-
- ClassLoader rsClassLoader = new ClassLoader(ClientLoader.class.getClassLoader())
- {
- @Override
- protected Class> findClass(String name) throws ClassNotFoundException
- {
- String path = name.replace('.', '/').concat(".class");
- byte[] data = zipFile.get(path);
- if (data == null)
- {
- throw new ClassNotFoundException(name);
- }
-
- return defineClass(name, data, 0, data.length);
- }
- };
-
- Class> clientClass = rsClassLoader.loadClass(initialClass);
-
- Applet rs = (Applet) clientClass.newInstance();
- rs.setStub(new RSAppletStub(config));
-
- if (rs instanceof Client)
- {
- log.info("client-patch {}", "420 blaze it RL pricks");
- }
-
- return rs;
- }
- catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException | SecurityException | VerificationException | CertificateException | CompressorException | InvalidHeaderException e)
- {
- if (e instanceof ClassNotFoundException)
- {
- log.error("Unable to load client - class not found. This means you"
- + " are not running RuneLite with Maven as the client patch"
- + " is not in your classpath.");
- }
-
- log.error("Error loading RS!", e);
- return null;
- }
- }
-
- private static Certificate[] getJagexCertificateChain() throws CertificateException
- {
- CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
- Collection extends Certificate> certificates = certificateFactory.generateCertificates(ClientLoader.class.getResourceAsStream("jagex.crt"));
- return certificates.toArray(new Certificate[0]);
- }
-}
diff --git a/RuneLitePlus/src/main/resources/com/runeswag/client/rlp.properties b/RuneLitePlus/src/main/resources/com/runeswag/client/rlp.properties
deleted file mode 100644
index b89682ed8a..0000000000
--- a/RuneLitePlus/src/main/resources/com/runeswag/client/rlp.properties
+++ /dev/null
@@ -1,8 +0,0 @@
-runeliteplus.title=RuneLitePlus
-runeliteplus.version=1.0
-runeliteplus.version=1.0
-runeliteplus.discord.appid=409416265891971072
-runeliteplus.discord.invite=https://discord.gg/HN5gf3m
-runeliteplus.github.link=https://github.com/runelite-extended/runelite
-runeliteplus.wiki.link=https://github.com/runelite-extended/runelite/wiki
-runeliteplus.patreon.link=https://www.patreon.com/RuneLitePlus
\ No newline at end of file
diff --git a/RuneLitePlus/src/main/resources/com/runeswag/client/ui/runeliteplus.png b/RuneLitePlus/src/main/resources/com/runeswag/client/ui/runeliteplus.png
deleted file mode 100644
index 2b5357ab17..0000000000
Binary files a/RuneLitePlus/src/main/resources/com/runeswag/client/ui/runeliteplus.png and /dev/null differ
diff --git a/RuneLitePlus/src/main/resources/net/runelite/client/plugins/barbarianassault/clock.png b/RuneLitePlus/src/main/resources/net/runelite/client/plugins/barbarianassault/clock.png
deleted file mode 100644
index c0f39269e1..0000000000
Binary files a/RuneLitePlus/src/main/resources/net/runelite/client/plugins/barbarianassault/clock.png and /dev/null differ
diff --git a/RuneLitePlus/src/main/resources/net/runelite/client/plugins/interfacestyles/2005/900.png b/RuneLitePlus/src/main/resources/net/runelite/client/plugins/interfacestyles/2005/900.png
deleted file mode 100644
index 407e476c54..0000000000
Binary files a/RuneLitePlus/src/main/resources/net/runelite/client/plugins/interfacestyles/2005/900.png and /dev/null differ
diff --git a/RuneLitePlus/src/main/resources/net/runelite/client/ui/open.png b/RuneLitePlus/src/main/resources/net/runelite/client/ui/open.png
deleted file mode 100644
index 6d5ca35ad4..0000000000
Binary files a/RuneLitePlus/src/main/resources/net/runelite/client/ui/open.png and /dev/null differ
diff --git a/RuneLitePlus/src/main/resources/net/runelite/client/ui/open_rs.png b/RuneLitePlus/src/main/resources/net/runelite/client/ui/open_rs.png
deleted file mode 100644
index e0cb3df043..0000000000
Binary files a/RuneLitePlus/src/main/resources/net/runelite/client/ui/open_rs.png and /dev/null differ
diff --git a/RuneLitePlus/src/main/resources/net/runelite/client/ui/runescape.ttf b/RuneLitePlus/src/main/resources/net/runelite/client/ui/runescape.ttf
deleted file mode 100644
index 9d15fc64ff..0000000000
Binary files a/RuneLitePlus/src/main/resources/net/runelite/client/ui/runescape.ttf and /dev/null differ
diff --git a/RuneLitePlus/src/main/resources/net/runelite/client/ui/runescape_bold.ttf b/RuneLitePlus/src/main/resources/net/runelite/client/ui/runescape_bold.ttf
deleted file mode 100644
index 1eaf0e7b82..0000000000
Binary files a/RuneLitePlus/src/main/resources/net/runelite/client/ui/runescape_bold.ttf and /dev/null differ
diff --git a/RuneLitePlus/src/main/resources/net/runelite/client/ui/runescape_small.ttf b/RuneLitePlus/src/main/resources/net/runelite/client/ui/runescape_small.ttf
deleted file mode 100644
index 7998560026..0000000000
Binary files a/RuneLitePlus/src/main/resources/net/runelite/client/ui/runescape_small.ttf and /dev/null differ
diff --git a/RuneLitePlus/src/main/resources/net/runelite/client/ui/skin/RuneLite.colorschemes b/RuneLitePlus/src/main/resources/net/runelite/client/ui/skin/RuneLite.colorschemes
deleted file mode 100644
index 1d9ffee41b..0000000000
--- a/RuneLitePlus/src/main/resources/net/runelite/client/ui/skin/RuneLite.colorschemes
+++ /dev/null
@@ -1,166 +0,0 @@
-# Copyright (c) 2018, Tomas Slusny
-# Copyright (c) 2018, Psikoi
-# 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.
-
-RuneLite Enabled {
- kind=Dark
- colorUltraLight=#232323
- colorExtraLight=#232323
- colorLight=#232323
- colorMid=#232323
- colorDark=#232323
- colorUltraDark=#232323
- colorForeground=#C6C6C6
-}
-
-RuneLite Active {
- kind=Light
- colorUltraLight=#4e4e4e
- colorExtraLight=#4e4e4e
- colorLight=#4e4e4e
- colorMid=#232323
- colorDark=#232323
- colorUltraDark=#232323
- colorForeground=#000000
-}
-
-RuneLite Selected Disabled Border {
- kind=Dark
- colorUltraLight=#191919
- colorExtraLight=#191919
- colorLight=#191919
- colorMid=#191919
- colorDark=#191919
- colorUltraDark=#191919
- colorForeground=#C6C6C6
-}
-
-RuneLite Border {
- kind=Dark
- colorUltraLight=#191919
- colorExtraLight=#191919
- colorLight=#191919
- colorMid=#191919
- colorDark=#191919
- colorUltraDark=#191919
- colorForeground=#C6C6C6
-}
-
-RuneLite Tab Border {
- kind=Light
- colorUltraLight=#232323
- colorExtraLight=#232323
- colorLight=#232323
- colorMid=#232323
- colorDark=#232323
- colorUltraDark=#232323
- colorForeground=#232323
-}
-
-RuneLite Mark Active {
- kind=Dark
- colorUltraLight=#191919
- colorExtraLight=#191919
- colorLight=#191919
- colorMid=#191919
- colorDark=#191919
- colorUltraDark=#191919
- colorForeground=#191919
-}
-
-RuneLite Highlight {
- kind=Light
- colorUltraLight=#C6C6C6
- colorExtraLight=#C6C6C6
- colorLight=#C6C6C6
- colorMid=#C6C6C6
- colorDark=#C6C6C6
- colorUltraDark=#C6C6C6
- colorForeground=#191919
-}
-
-RuneLite Watermark {
- kind=Light
- colorUltraLight=#313131
- colorExtraLight=#313131
- colorLight=#313131
- colorMid=#313131
- colorDark=#313131
- colorUltraDark=#313131
- colorForeground=#C6C6C6
-}
-
-RuneLite Decorations Watermark {
- kind=Light
- colorUltraLight=#1e1e1e
- colorExtraLight=#1e1e1e
- colorLight=#1e1e1e
- colorMid=#1e1e1e
- colorDark=#1e1e1e
- colorUltraDark=#1e1e1e
- colorForeground=#1e1e1e
-}
-
-RuneLite Separator {
- kind=Dark
- colorUltraLight=#232323
- colorExtraLight=#232323
- colorLight=#232323
- colorMid=#232323
- colorDark=#232323
- colorUltraDark=#232323
- colorForeground=#232323
-}
-
-RuneLite Decorations Separator {
- kind=Dark
- colorUltraLight=#232323
- colorExtraLight=#232323
- colorLight=#232323
- colorMid=#232323
- colorDark=#232323
- colorUltraDark=#232323
- colorForeground=#232323
-}
-
-RuneLite Header Watermark {
- kind=Dark
- colorUltraLight=#1e1e1e
- colorExtraLight=#1e1e1e
- colorLight=#1e1e1e
- colorMid=#1e1e1e
- colorDark=#1e1e1e
- colorUltraDark=#1e1e1e
- colorForeground=#C6C6C6
-}
-
-RuneLite Header Border {
- kind=Dark
- colorUltraLight=#1e1e1e
- colorExtraLight=#1e1e1e
- colorLight=#1e1e1e
- colorMid=#1e1e1e
- colorDark=#1e1e1e
- colorUltraDark=#1e1e1e
- colorForeground=#C6C6C6
-}
\ No newline at end of file
diff --git a/api/src/main/java/api/vars/AccountType.java b/api/src/main/java/api/vars/AccountType.java
deleted file mode 100644
index 6e8c2de5b6..0000000000
--- a/api/src/main/java/api/vars/AccountType.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package api.vars;
-
-/**
- * An enumeration of possible account types.
- */
-public enum AccountType
-{
- /**
- * Normal account type.
- */
- NORMAL,
- /**
- * Ironman account type.
- */
- IRONMAN,
- /**
- * Ultimate ironman account type.
- */
- ULTIMATE_IRONMAN,
- /**
- * Hardcore ironman account type.
- */
- HARDCORE_IRONMAN;
-
- /**
- * Checks whether this type is an ironman.
- *
- * @return {@code true} if the type is any of the ironman types.
- */
- public boolean isIronman()
- {
- return this.ordinal() >= IRONMAN.ordinal() && this.ordinal() <= HARDCORE_IRONMAN.ordinal();
- }
-
-}
\ No newline at end of file
diff --git a/api/src/main/java/rs/api/RSClanMate.java b/api/src/main/java/rs/api/RSClanMate.java
deleted file mode 100644
index 362d7a8904..0000000000
--- a/api/src/main/java/rs/api/RSClanMate.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package rs.api;
-
-import api.ClanMember;
-
-public interface RSClanMate extends RSBuddy, ClanMember
-{
-}
diff --git a/api/src/main/java/rs/api/RSFriend.java b/api/src/main/java/rs/api/RSFriend.java
deleted file mode 100644
index 4c5b799d9a..0000000000
--- a/api/src/main/java/rs/api/RSFriend.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package rs.api;
-
-import api.Friend;
-
-public interface RSFriend extends Friend, RSBuddy
-{
-}
diff --git a/api/src/main/java/rs/api/RSIgnored.java b/api/src/main/java/rs/api/RSIgnored.java
deleted file mode 100644
index 1e17d128d1..0000000000
--- a/api/src/main/java/rs/api/RSIgnored.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package rs.api;
-
-import api.Ignore;
-
-public interface RSIgnored extends Ignore, RSUser
-{
-}
diff --git a/api/src/main/java/rs/api/RSPacketBuffer.java b/api/src/main/java/rs/api/RSPacketBuffer.java
deleted file mode 100644
index f9dbfac32e..0000000000
--- a/api/src/main/java/rs/api/RSPacketBuffer.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package rs.api;
-
-import api.PacketBuffer;
-
-public interface RSPacketBuffer extends PacketBuffer
-{
-}
diff --git a/api/src/main/java/rs/api/RSSoundEffect.java b/api/src/main/java/rs/api/RSSoundEffect.java
deleted file mode 100644
index 7c7fd22ffe..0000000000
--- a/api/src/main/java/rs/api/RSSoundEffect.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package rs.api;
-
-public interface RSSoundEffect
-{
-}
diff --git a/bootstrap.json b/bootstrap.json
new file mode 100644
index 0000000000..2052530dbe
--- /dev/null
+++ b/bootstrap.json
@@ -0,0 +1,299 @@
+{
+ "buildCommit": "2d0c2b8eb66a8088b41b29d42ec2a58ead460581",
+ "artifacts": [
+ {
+ "hash": "b12331da8683e5f107d294adeebb83ecf9124abc1db533554d2a8d3c62832d75",
+ "name": "asm-all-6.0_BETA.jar",
+ "path": "https://mvn.runelite.net/org/ow2/asm/asm-all/6.0_BETA/asm-all-6.0_BETA.jar",
+ "size": "265176"
+ },
+ {
+ "hash": "37abf0103ce5318bfda004fabc004c75ed0dc6d392a8459175692ab7eac97083",
+ "name": "naturalmouse-2.0.0.jar",
+ "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/naturalmouse-2.0.0.jar",
+ "size": "3168921"
+ },
+ {
+ "hash": "50d1e07f11827672249dee9ce8a23691fc59f663deed084bb7b52a4f778d5fbc",
+ "name": "jcl-core-2.9-SNAPSHOT.jar",
+ "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/jcl-core-2.9-SNAPSHOT.jar",
+ "size": "3168921"
+ },
+ {
+ "hash": "4c388a85fb538bbb8cb6e0fd93e0ba0666605123d77b976764818be6f090bbe5",
+ "name": "client-1.5.28-SNAPSHOT.jar",
+ "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/client-1.5.28-SNAPSHOT.jar",
+ "size": "5871886"
+ },
+ {
+ "hash": "18c4a0095d5c1da6b817592e767bb23d29dd2f560ad74df75ff3961dbde25b79",
+ "name": "slf4j-api-1.7.25.jar",
+ "path": "https://mvn.runelite.net/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar",
+ "size": "41203"
+ },
+ {
+ "hash": "fb53f8539e7fcb8f093a56e138112056ec1dc809ebb020b59d8a36a5ebac37e0",
+ "name": "logback-classic-1.2.3.jar",
+ "path": "https://mvn.runelite.net/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar",
+ "size": "290339"
+ },
+ {
+ "hash": "5946d837fe6f960c02a53eda7a6926ecc3c758bbdd69aa453ee429f858217f22",
+ "name": "logback-core-1.2.3.jar",
+ "path": "https://mvn.runelite.net/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar",
+ "size": "471901"
+ },
+ {
+ "hash": "9f0c8d50fa4b79b6ff1502dbec8502179d6b9497cacbe17a13074001aed537ec",
+ "name": "jopt-simple-5.0.1.jar",
+ "path": "https://mvn.runelite.net/net/sf/jopt-simple/jopt-simple/5.0.1/jopt-simple-5.0.1.jar",
+ "size": "78826"
+ },
+ {
+ "hash": "5be9a7d05ba0ccd74708bc8018ae412255f85843c0b92302e9b9befa6ed52564",
+ "name": "guava-23.2-jre.jar",
+ "path": "https://mvn.runelite.net/com/google/guava/guava/23.2-jre/guava-23.2-jre.jar",
+ "size": "2649860"
+ },
+ {
+ "hash": "905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed",
+ "name": "jsr305-1.3.9.jar",
+ "path": "https://mvn.runelite.net/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar",
+ "size": "33015"
+ },
+ {
+ "hash": "cb4cfad870bf563a07199f3ebea5763f0dec440fcda0b318640b1feaa788656b",
+ "name": "error_prone_annotations-2.0.18.jar",
+ "path": "https://mvn.runelite.net/com/google/errorprone/error_prone_annotations/2.0.18/error_prone_annotations-2.0.18.jar",
+ "size": "12078"
+ },
+ {
+ "hash": "2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6",
+ "name": "j2objc-annotations-1.1.jar",
+ "path": "https://mvn.runelite.net/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.jar",
+ "size": "8782"
+ },
+ {
+ "hash": "2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d",
+ "name": "animal-sniffer-annotations-1.14.jar",
+ "path": "https://mvn.runelite.net/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.jar",
+ "size": "3482"
+ },
+ {
+ "hash": "9264c6931c431e928dc64adc842584d5f57d17b2f3aff29221f2b3fdea673dad",
+ "name": "guice-4.1.0-no_aop.jar",
+ "path": "https://mvn.runelite.net/com/google/inject/guice/4.1.0/guice-4.1.0-no_aop.jar",
+ "size": "428603"
+ },
+ {
+ "hash": "91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff",
+ "name": "javax.inject-1.jar",
+ "path": "https://mvn.runelite.net/javax/inject/javax.inject/1/javax.inject-1.jar",
+ "size": "2497"
+ },
+ {
+ "hash": "0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08",
+ "name": "aopalliance-1.0.jar",
+ "path": "https://mvn.runelite.net/aopalliance/aopalliance/1.0/aopalliance-1.0.jar",
+ "size": "4467"
+ },
+ {
+ "hash": "233a0149fc365c9f6edbd683cfe266b19bdc773be98eabdaf6b3c924b48e7d81",
+ "name": "gson-2.8.5.jar",
+ "path": "https://mvn.runelite.net/com/google/code/gson/gson/2.8.5/gson-2.8.5.jar",
+ "size": "241622"
+ },
+ {
+ "hash": "0467d25f408428824d5c9c09ec60ee1f0bc341d9bf48971a77fd14939a826c83",
+ "name": "substance-8.0.02.jar",
+ "path": "https://repo.runelite.net/net/runelite/pushingpixels/substance/8.0.02/substance-8.0.02.jar",
+ "size": "1589195"
+ },
+ {
+ "hash": "3214e1c23d549d5d67c91da4da1ef33c5248470bb824f91cbe8f9e0beea59eef",
+ "name": "trident-1.5.00.jar",
+ "path": "https://repo.runelite.net/net/runelite/pushingpixels/trident/1.5.00/trident-1.5.00.jar",
+ "size": "79726"
+ },
+ {
+ "hash": "d4a57bbc1627da7c391308fd0fe910b83170fb66afd117236a5b111d2db1590b",
+ "name": "commons-text-1.2.jar",
+ "path": "https://mvn.runelite.net/org/apache/commons/commons-text/1.2/commons-text-1.2.jar",
+ "size": "136544"
+ },
+ {
+ "hash": "6e8dc31e046508d9953c96534edf0c2e0bfe6f468966b5b842b3f87e43b6a847",
+ "name": "commons-lang3-3.7.jar",
+ "path": "https://mvn.runelite.net/org/apache/commons/commons-lang3/3.7/commons-lang3-3.7.jar",
+ "size": "499634"
+ },
+ {
+ "hash": "e74603dc77b4183f108480279dbbf7fed3ac206069478636406c1fb45e83b31a",
+ "name": "jogl-all-2.3.2.jar",
+ "path": "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2.jar",
+ "size": "3414448"
+ },
+ {
+ "hash": "8c53b1884cef19309d34fd10a94b010136d9d6de9a88c386f46006fb47acab5d",
+ "name": "jogl-all-2.3.2-natives-windows-amd64.jar",
+ "path": "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-windows-amd64.jar",
+ "size": "240721"
+ },
+ {
+ "hash": "507a0e6bd1ee4e81c3dfb287783af93775864eec742988d4162f98ce0cbac9d6",
+ "name": "jogl-all-2.3.2-natives-windows-i586.jar",
+ "path": "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-windows-i586.jar",
+ "size": "209445"
+ },
+ {
+ "hash": "82637302ae9effdf7d6f302e1050ad6aee3b13019914ddda5b502b9faa980216",
+ "name": "jogl-all-2.3.2-natives-linux-amd64.jar",
+ "path": "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-linux-amd64.jar",
+ "size": "224010"
+ },
+ {
+ "hash": "f474ef2ef01be24ec811d3858b0f4bc5659076975f4a58ddd79abd787e9305c7",
+ "name": "jogl-all-2.3.2-natives-linux-i586.jar",
+ "path": "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-linux-i586.jar",
+ "size": "217274"
+ },
+ {
+ "hash": "084844543b18f7ff71b4c0437852bd22f0cb68d7e44c2c611c1bbea76f8c6fdf",
+ "name": "gluegen-rt-2.3.2.jar",
+ "path": "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2.jar",
+ "size": "345605"
+ },
+ {
+ "hash": "3474017422eff384db466bdb56c96c61220c43133a9da6329cf1781bea16c6b6",
+ "name": "gluegen-rt-2.3.2-natives-windows-amd64.jar",
+ "path": "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-windows-amd64.jar",
+ "size": "8159"
+ },
+ {
+ "hash": "4eeed9fc2ebea5b9dc48a342b9478d127e989a2e1aa7129b512a98ec75cde338",
+ "name": "gluegen-rt-2.3.2-natives-windows-i586.jar",
+ "path": "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-windows-i586.jar",
+ "size": "7577"
+ },
+ {
+ "hash": "f2dfd1800202059cf7e0294db5d57755147304e6eb220a9277526dbe6842bde2",
+ "name": "gluegen-rt-2.3.2-natives-linux-amd64.jar",
+ "path": "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-linux-amd64.jar",
+ "size": "4149"
+ },
+ {
+ "hash": "1365d463f98c0abec92f3ad6b35aa4b53a9599a517800cf99fdabea6712ca7ec",
+ "name": "gluegen-rt-2.3.2-natives-linux-i586.jar",
+ "path": "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-linux-i586.jar",
+ "size": "4130"
+ },
+ {
+ "hash": "7b7ae00e2aa98c3b2b5ac76e793e2c9b752bf51c86c54654dbd473843a25f1aa",
+ "name": "jbsdiff-1.0.jar",
+ "path": "https://mvn.runelite.net/io/sigpipe/jbsdiff/1.0/jbsdiff-1.0.jar",
+ "size": "24589"
+ },
+ {
+ "hash": "55bbfe26cee9296fd5b7c0d47ce6a00ea4dd572e235b63e9bb4eaf6f802315e4",
+ "name": "commons-compress-1.5.jar",
+ "path": "https://mvn.runelite.net/org/apache/commons/commons-compress/1.5/commons-compress-1.5.jar",
+ "size": "256241"
+ },
+ {
+ "hash": "fbc9de96a0cc193a125b4008dbc348e9ed54e5e13fc67b8ed40e645d303cc51b",
+ "name": "jna-4.5.1.jar",
+ "path": "https://mvn.runelite.net/net/java/dev/jna/jna/4.5.1/jna-4.5.1.jar",
+ "size": "1440662"
+ },
+ {
+ "hash": "84c8667555ee8dd91fef44b451419f6f16f71f727d5fc475a10c2663eba83abb",
+ "name": "jna-platform-4.5.1.jar",
+ "path": "https://mvn.runelite.net/net/java/dev/jna/jna-platform/4.5.1/jna-platform-4.5.1.jar",
+ "size": "2327547"
+ },
+ {
+ "hash": "440c629bec3905eb21dc5965fa38464f160a4cb8f87ca76806cdecc18b2c5992",
+ "name": "runelite-api-1.5.28-SNAPSHOT.jar",
+ "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runelite-api-1.5.28-SNAPSHOT.jar",
+ "size": "1019717"
+ },
+ {
+ "hash": "45e3bcec9e7bae4ca2facd0fbee1f3da5e0700584e8419deed784a95255552c1",
+ "name": "runescape-api-1.5.28-SNAPSHOT.jar",
+ "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runescape-api-1.5.28-SNAPSHOT.jar",
+ "size": "56079"
+ },
+ {
+ "hash": "811aadce9ce35ac638712da86123d4cb99570a9550614931471295cb26f91c36",
+ "name": "http-api-1.5.28-SNAPSHOT.jar",
+ "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/http-api-1.5.28-SNAPSHOT.jar",
+ "size": "101785"
+ },
+ {
+ "hash": "f55abda036da75e1af45bd43b9dfa79b2a3d90905be9cb38687c6621597a8165",
+ "name": "okhttp-3.7.0.jar",
+ "path": "https://mvn.runelite.net/com/squareup/okhttp3/okhttp/3.7.0/okhttp-3.7.0.jar",
+ "size": "394987"
+ },
+ {
+ "hash": "bfe7dfe483c37137966a1690f0c7d0b448ba217902c1fed202aaffdbba3291ae",
+ "name": "okio-1.12.0.jar",
+ "path": "https://mvn.runelite.net/com/squareup/okio/okio/1.12.0/okio-1.12.0.jar",
+ "size": "81088"
+ },
+ {
+ "hash": "9d4924588d6280c7516db3a4b7298306db5b6f0d1cdf568ce738309b5660f008",
+ "name": "commons-csv-1.4.jar",
+ "path": "https://mvn.runelite.net/org/apache/commons/commons-csv/1.4/commons-csv-1.4.jar",
+ "size": "39978"
+ },
+ {
+ "hash": "7e26a8d043418f2f22d5f6a3083a9a131817009ee8cd72c004e83b50d1849a7c",
+ "name": "discord-1.1.jar",
+ "path": "https://repo.runelite.net/net/runelite/discord/1.1/discord-1.1.jar",
+ "size": "617294"
+ },
+ {
+ "hash": "a3cab9293960d1d61968ce1591c87859ddcaa6cb2faca554cc938961c8fb3d3a",
+ "name": "injected-client-1.5.28-SNAPSHOT.jar",
+ "path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/injected-client-1.5.28-SNAPSHOT.jar",
+ "size": "2193046"
+ }
+ ],
+ "client": {
+ "artifactId": "client",
+ "classifier": "",
+ "extension": "jar",
+ "groupId": "net.runelite",
+ "properties": "",
+ "version": "1.5.28"
+ },
+ "clientJvm9Arguments": [
+ "-XX:+DisableAttachMechanism",
+ "-Xmx512m",
+ "-Xss2m",
+ "-XX:CompileThreshold=1500",
+ "-Djna.nosys=true"
+ ],
+ "clientJvmArguments": [
+ "-XX:+DisableAttachMechanism",
+ "-Xmx512m",
+ "-Xss2m",
+ "-XX:CompileThreshold=1500",
+ "-Xincgc",
+ "-XX:+UseConcMarkSweepGC",
+ "-XX:+UseParNewGC",
+ "-Djna.nosys=true"
+ ],
+ "launcherArguments": [
+ "-XX:+DisableAttachMechanism",
+ "-Drunelite.launcher.nojvm=true",
+ "-Xmx512m",
+ "-Xss2m",
+ "-XX:CompileThreshold=1500",
+ "-Xincgc",
+ "-XX:+UseConcMarkSweepGC",
+ "-XX:+UseParNewGC",
+ "-Djna.nosys=true"
+ ]
+}
\ No newline at end of file
diff --git a/cache-client/pom.xml b/cache-client/pom.xml
new file mode 100644
index 0000000000..59b213541f
--- /dev/null
+++ b/cache-client/pom.xml
@@ -0,0 +1,70 @@
+
+
+
+ 4.0.0
+
+
+ net.runelite
+ runelite-parent
+ 1.5.28-SNAPSHOT
+
+
+ cache-client
+ Cache Client
+
+
+
+ net.runelite
+ cache
+ ${project.version}
+
+
+ net.runelite
+ protocol
+ ${project.version}
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.slf4j
+ slf4j-simple
+ 1.7.12
+ test
+
+
+ net.runelite
+ cache
+ ${project.version}
+ test-jar
+ test
+
+
+
diff --git a/cache-client/src/main/java/net/runelite/cache/client/ArchiveResponseHandler.java b/cache-client/src/main/java/net/runelite/cache/client/ArchiveResponseHandler.java
new file mode 100644
index 0000000000..f6bffbeba1
--- /dev/null
+++ b/cache-client/src/main/java/net/runelite/cache/client/ArchiveResponseHandler.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.client;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import net.runelite.protocol.api.update.ArchiveResponsePacket;
+
+public class ArchiveResponseHandler extends SimpleChannelInboundHandler
+{
+ private final CacheClient client;
+
+ public ArchiveResponseHandler(CacheClient client)
+ {
+ this.client = client;
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, ArchiveResponsePacket archiveResponse) throws Exception
+ {
+ client.onFileFinish(archiveResponse.getIndex(),
+ archiveResponse.getArchive(),
+ archiveResponse.getData());
+ }
+
+}
diff --git a/cache-client/src/main/java/net/runelite/cache/client/CacheClient.java b/cache-client/src/main/java/net/runelite/cache/client/CacheClient.java
new file mode 100644
index 0000000000..273da5d5fa
--- /dev/null
+++ b/cache-client/src/main/java/net/runelite/cache/client/CacheClient.java
@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.client;
+
+import com.google.common.base.Stopwatch;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.CompletableFuture;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+import net.runelite.cache.index.ArchiveData;
+import net.runelite.cache.index.IndexData;
+import net.runelite.protocol.update.decoders.HandshakeResponseDecoder;
+import net.runelite.protocol.update.encoders.ArchiveRequestEncoder;
+import net.runelite.protocol.update.encoders.EncryptionEncoder;
+import net.runelite.protocol.api.update.ArchiveRequestPacket;
+import net.runelite.protocol.api.login.HandshakeResponseType;
+import net.runelite.cache.util.Crc32;
+import net.runelite.protocol.api.handshake.UpdateHandshakePacket;
+import net.runelite.protocol.handshake.UpdateHandshakeEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CacheClient implements AutoCloseable
+{
+ private static final Logger logger = LoggerFactory.getLogger(CacheClient.class);
+
+ private static final String HOST = "oldschool1.runescape.com";
+ private static final int PORT = 43594;
+
+ private static final int MAX_REQUESTS = 19; // too many and the server closes the conncetion
+
+ private final Store store; // store cache will be written to
+ private final String host;
+ private final int clientRevision;
+ private DownloadWatcher watcher;
+
+ private ClientState state;
+
+ private final EventLoopGroup group = new NioEventLoopGroup(1);
+ private Channel channel;
+
+ private CompletableFuture handshakeFuture;
+ private final Queue requests = new ArrayDeque<>();
+
+ public CacheClient(Store store, int clientRevision)
+ {
+ this(store, HOST, clientRevision);
+ }
+
+ public CacheClient(Store store, String host, int clientRevision)
+ {
+ this.store = store;
+ this.host = host;
+ this.clientRevision = clientRevision;
+ }
+
+ public CacheClient(Store store, int clientRevision, DownloadWatcher watcher)
+ {
+ this(store, clientRevision);
+ this.watcher = watcher;
+ }
+
+ public void connect()
+ {
+ Bootstrap b = new Bootstrap();
+ b.group(group)
+ .channel(NioSocketChannel.class)
+ .option(ChannelOption.TCP_NODELAY, true)
+ .handler(new ChannelInitializer()
+ {
+ @Override
+ public void initChannel(SocketChannel ch) throws Exception
+ {
+ ChannelPipeline p = ch.pipeline();
+
+ //p.addFirst(new HttpProxyHandler(new InetSocketAddress("runelite.net", 3128)));
+ p.addLast("decoder", new HandshakeResponseDecoder());
+
+ p.addLast(
+ new CacheClientHandler(),
+ new HandshakeResponseHandler(CacheClient.this),
+ new ArchiveResponseHandler(CacheClient.this)
+ );
+
+ p.addLast(
+ new UpdateHandshakeEncoder(),
+ new EncryptionEncoder(),
+ new ArchiveRequestEncoder()
+ );
+ }
+ });
+
+ // Start the client.
+ ChannelFuture f = b.connect(host, PORT).syncUninterruptibly();
+ channel = f.channel();
+ }
+
+ public CompletableFuture handshake()
+ {
+ UpdateHandshakePacket handshakePacket = new UpdateHandshakePacket();
+ handshakePacket.setRevision(getClientRevision());
+
+ state = ClientState.HANDSHAKING;
+
+ assert handshakeFuture == null;
+ handshakeFuture = new CompletableFuture<>();
+
+ channel.writeAndFlush(handshakePacket);
+
+ logger.info("Sent handshake with revision {}", handshakePacket.getRevision());
+
+ return handshakeFuture;
+ }
+
+ @Override
+ public void close()
+ {
+ channel.close().syncUninterruptibly();
+ group.shutdownGracefully();
+ }
+
+ public int getClientRevision()
+ {
+ return clientRevision;
+ }
+
+ public ClientState getState()
+ {
+ return state;
+ }
+
+ void setState(ClientState state)
+ {
+ this.state = state;
+ }
+
+ CompletableFuture getHandshakeFuture()
+ {
+ return handshakeFuture;
+ }
+
+ public List requestIndexes() throws IOException
+ {
+ logger.info("Requesting indexes");
+
+ FileResult result = requestFile(255, 255, true).join();
+ result.decompress(null);
+
+ ByteBuf buffer = Unpooled.wrappedBuffer(result.getContents());
+ int indexCount = result.getContents().length / 8;
+ List indexInfo = new ArrayList<>();
+
+ for (int i = 0; i < indexCount; ++i)
+ {
+ int crc = buffer.readInt();
+ int revision = buffer.readInt();
+ indexInfo.add(new IndexInfo(i, crc, revision));
+ }
+
+ return indexInfo;
+ }
+
+ public void download() throws IOException
+ {
+ Stopwatch stopwatch = Stopwatch.createStarted();
+
+ List indexes = requestIndexes();
+ for (IndexInfo indexInfo : indexes)
+ {
+ int i = indexInfo.getId();
+ int crc = indexInfo.getCrc();
+ int revision = indexInfo.getRevision();
+
+ Index index = store.findIndex(i);
+
+ if (index == null)
+ {
+ logger.info("Index {} does not exist, creating", i);
+ }
+ else if (index.getRevision() != revision)
+ {
+ if (revision < index.getRevision())
+ {
+ logger.warn("Index {} revision is going BACKWARDS! (our revision {}, their revision {})", index.getId(), index.getRevision(), revision);
+ }
+ else
+ {
+ logger.info("Index {} has the wrong revision (our revision {}, their revision {})", index.getId(), index.getRevision(), revision);
+ }
+ }
+ else if (index.getCrc() != crc)
+ {
+ logger.warn("Index {} CRC has changed! (our crc {}, their crc {})",
+ index.getCrc(), index.getCrc(), crc);
+ }
+ else
+ {
+ // despite the index being up to date, not everything
+ // can be downloaded, eg. for tracks.
+ logger.info("Index {} is up to date", index.getId());
+ }
+
+ logger.info("Downloading index {}", i);
+
+ FileResult indexFileResult = requestFile(255, i, true).join();
+ indexFileResult.decompress(null);
+
+ logger.info("Downloaded index {}", i);
+
+ if (indexFileResult.getCrc() != crc)
+ {
+ logger.warn("Corrupted download for index {}", i);
+ continue;
+ }
+
+ IndexData indexData = new IndexData();
+ indexData.load(indexFileResult.getContents());
+
+ if (index == null)
+ {
+ index = store.addIndex(i);
+ }
+
+ // update index settings
+ index.setProtocol(indexData.getProtocol());
+ index.setNamed(indexData.isNamed());
+ index.setCrc(crc);
+ index.setRevision(revision);
+
+ logger.info("Index {} has {} archives", i, indexData.getArchives().length);
+
+ for (ArchiveData ad : indexData.getArchives())
+ {
+ Archive existing = index.getArchive(ad.getId());
+
+ if (existing != null && existing.getRevision() == ad.getRevision()
+ && existing.getCrc() == ad.getCrc()
+ && existing.getNameHash() == ad.getNameHash())
+ {
+ logger.debug("Archive {}/{} in index {} is up to date",
+ ad.getId(), indexData.getArchives().length, index.getId());
+ continue;
+ }
+
+ if (existing == null)
+ {
+ logger.info("Archive {}/{} in index {} is out of date, downloading",
+ ad.getId(), indexData.getArchives().length, index.getId());
+ }
+ else if (ad.getRevision() < existing.getRevision())
+ {
+ logger.warn("Archive {}/{} in index {} revision is going BACKWARDS! (our revision {}, their revision {})",
+ ad.getId(), indexData.getArchives().length, index.getId(),
+ existing.getRevision(), ad.getRevision());
+ }
+ else
+ {
+ logger.info("Archive {}/{} in index {} is out of date, downloading. " +
+ "revision: ours: {} theirs: {}, crc: ours: {} theirs {}, name: ours {} theirs {}",
+ ad.getId(), indexData.getArchives().length, index.getId(),
+ existing.getRevision(), ad.getRevision(),
+ existing.getCrc(), ad.getCrc(),
+ existing.getNameHash(), ad.getNameHash());
+ }
+
+ final Archive archive = existing == null
+ ? index.addArchive(ad.getId())
+ : existing;
+
+ archive.setRevision(ad.getRevision());
+ archive.setCrc(ad.getCrc());
+ archive.setNameHash(ad.getNameHash());
+
+ // Add files
+ archive.setFileData(ad.getFiles());
+
+ CompletableFuture future = requestFile(index.getId(), ad.getId(), false);
+ future.handle((fr, ex) ->
+ {
+ byte[] data = fr.getCompressedData();
+
+ Crc32 crc32 = new Crc32();
+ crc32.update(data, 0, data.length);
+ int hash = crc32.getHash();
+
+ if (hash != archive.getCrc())
+ {
+ logger.warn("crc mismatch on downloaded archive {}/{}: {} != {}",
+ archive.getIndex().getId(), archive.getArchiveId(),
+ hash, archive.getCrc());
+ throw new RuntimeException("crc mismatch");
+ }
+
+ if (watcher != null)
+ {
+ watcher.downloadComplete(archive, data);
+ }
+ else
+ {
+ try
+ {
+ Storage storage = store.getStorage();
+ storage.saveArchive(archive, data);
+ }
+ catch (IOException ex1)
+ {
+ logger.warn("unable to save archive data", ex1);
+ }
+ }
+ return null;
+ });
+ }
+ }
+
+ // flush any pending requests
+ channel.flush();
+
+ while (!requests.isEmpty())
+ {
+ // wait for pending requests
+ synchronized (this)
+ {
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException ex)
+ {
+ logger.warn(null, ex);
+ }
+ }
+ }
+
+ stopwatch.stop();
+ logger.info("Download completed in {}", stopwatch);
+ }
+
+ private synchronized CompletableFuture requestFile(int index, int fileId, boolean flush)
+ {
+ if (state != ClientState.CONNECTED)
+ {
+ throw new IllegalStateException("Can't request files until connected!");
+ }
+
+ if (!flush)
+ {
+ while (requests.size() >= MAX_REQUESTS)
+ {
+ channel.flush();
+
+ try
+ {
+ wait();
+ }
+ catch (InterruptedException ex)
+ {
+ logger.warn("interrupted while waiting for requests", ex);
+ }
+ }
+ }
+
+ ArchiveRequestPacket archiveRequest = new ArchiveRequestPacket();
+ archiveRequest.setPriority(false);
+ archiveRequest.setIndex(index);
+ archiveRequest.setArchive(fileId);
+
+ CompletableFuture future = new CompletableFuture<>();
+ PendingFileRequest pf = new PendingFileRequest(index,
+ fileId, future);
+
+ logger.trace("Sending request for {}/{}", index, fileId);
+
+ requests.add(pf);
+
+ if (!flush)
+ {
+ channel.write(archiveRequest);
+ }
+ else
+ {
+ channel.writeAndFlush(archiveRequest);
+ }
+
+ return future;
+ }
+
+ private PendingFileRequest findRequest(int index, int file)
+ {
+ for (PendingFileRequest pr : requests)
+ {
+ if (pr.getIndex() == index && pr.getArchive() == file)
+ {
+ return pr;
+ }
+ }
+ return null;
+ }
+
+ protected synchronized void onFileFinish(int index, int file, byte[] compressedData)
+ {
+ PendingFileRequest pr = findRequest(index, file);
+
+ if (pr == null)
+ {
+ logger.warn("File download {}/{} with no pending request", index, file);
+ return;
+ }
+
+ requests.remove(pr);
+
+ notify();
+
+ FileResult result = new FileResult(index, file, compressedData);
+
+ logger.debug("File download finished for index {} file {}, length {}", index, file, compressedData.length);
+
+ pr.getFuture().complete(result);
+ }
+}
diff --git a/cache-client/src/main/java/net/runelite/cache/client/CacheClientHandler.java b/cache-client/src/main/java/net/runelite/cache/client/CacheClientHandler.java
new file mode 100644
index 0000000000..9afe8f976b
--- /dev/null
+++ b/cache-client/src/main/java/net/runelite/cache/client/CacheClientHandler.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.client;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CacheClientHandler extends ChannelInboundHandlerAdapter
+{
+ private static final Logger logger = LoggerFactory.getLogger(CacheClientHandler.class);
+
+ @Override
+ public void channelInactive(ChannelHandlerContext ctx) throws Exception
+ {
+ logger.warn("Channel has gone inactive");
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
+ {
+ // Close the connection when an exception is raised.
+ logger.warn(null, cause);
+ ctx.close();
+ }
+}
diff --git a/cache-client/src/main/java/net/runelite/cache/client/ClientState.java b/cache-client/src/main/java/net/runelite/cache/client/ClientState.java
new file mode 100644
index 0000000000..5c859aa61c
--- /dev/null
+++ b/cache-client/src/main/java/net/runelite/cache/client/ClientState.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.client;
+
+public enum ClientState
+{
+ HANDSHAKING,
+ CONNECTED
+}
diff --git a/cache-client/src/main/java/net/runelite/cache/client/DownloadWatcher.java b/cache-client/src/main/java/net/runelite/cache/client/DownloadWatcher.java
new file mode 100644
index 0000000000..3924c74541
--- /dev/null
+++ b/cache-client/src/main/java/net/runelite/cache/client/DownloadWatcher.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.client;
+
+import net.runelite.cache.fs.Archive;
+
+@FunctionalInterface
+public interface DownloadWatcher
+{
+ void downloadComplete(Archive archive, byte[] data);
+}
diff --git a/cache-client/src/main/java/net/runelite/cache/client/FileResult.java b/cache-client/src/main/java/net/runelite/cache/client/FileResult.java
new file mode 100644
index 0000000000..2c5046af62
--- /dev/null
+++ b/cache-client/src/main/java/net/runelite/cache/client/FileResult.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.client;
+
+import java.io.IOException;
+import net.runelite.cache.fs.Container;
+
+public class FileResult
+{
+ private final int index;
+ private final int fileId;
+ private final byte[] compressedData;
+
+ private byte[] contents;
+ private int revision;
+ private int crc;
+ private int compression; // compression method used by archive data
+
+ public FileResult(int index, int fileId, byte[] compressedData)
+ {
+ this.index = index;
+ this.fileId = fileId;
+ this.compressedData = compressedData;
+ }
+
+ public int getIndex()
+ {
+ return index;
+ }
+
+ public int getFileId()
+ {
+ return fileId;
+ }
+
+ public byte[] getCompressedData()
+ {
+ return compressedData;
+ }
+
+ public void decompress(int[] keys) throws IOException
+ {
+ Container res = Container.decompress(compressedData, keys);
+
+ contents = res.data;
+ revision = res.revision;
+ crc = res.crc;
+ compression = res.compression;
+ }
+
+ public byte[] getContents()
+ {
+ return contents;
+ }
+
+ public int getRevision()
+ {
+ return revision;
+ }
+
+ public int getCrc()
+ {
+ return crc;
+ }
+
+ public int getCompression()
+ {
+ return compression;
+ }
+}
diff --git a/cache-client/src/main/java/net/runelite/cache/client/HandshakeResponseHandler.java b/cache-client/src/main/java/net/runelite/cache/client/HandshakeResponseHandler.java
new file mode 100644
index 0000000000..bcbb01bafb
--- /dev/null
+++ b/cache-client/src/main/java/net/runelite/cache/client/HandshakeResponseHandler.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.client;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.SimpleChannelInboundHandler;
+import java.util.concurrent.CompletableFuture;
+import net.runelite.protocol.update.decoders.ArchiveResponseDecoder;
+import net.runelite.protocol.api.update.EncryptionPacket;
+import net.runelite.protocol.api.handshake.HandshakeResponsePacket;
+import net.runelite.protocol.api.login.HandshakeResponseType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HandshakeResponseHandler extends SimpleChannelInboundHandler
+{
+ private static final Logger logger = LoggerFactory.getLogger(HandshakeResponseHandler.class);
+
+ private final CacheClient client;
+
+ public HandshakeResponseHandler(CacheClient client)
+ {
+ this.client = client;
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, HandshakeResponsePacket handshakeResponse) throws Exception
+ {
+ Channel channel = ctx.channel();
+ ChannelPipeline p = ctx.pipeline();
+ CompletableFuture handshakeFuture = client.getHandshakeFuture();
+
+ assert handshakeFuture != null;
+
+ if (handshakeResponse.getResponse() != HandshakeResponseType.RESPONSE_OK)
+ {
+ logger.warn("Non-ok response from server {}", handshakeResponse.getResponse());
+ handshakeFuture.complete(handshakeResponse.getResponse());
+ ctx.close();
+ return;
+ }
+
+ // Send encryption packet
+ EncryptionPacket encryptionPacket = new EncryptionPacket();
+ encryptionPacket.setKey((byte) 0);
+ channel.writeAndFlush(encryptionPacket);
+
+ client.setState(ClientState.CONNECTED);
+
+ logger.info("Client is now connected!");
+
+ p.replace("decoder", "decoder", new ArchiveResponseDecoder());
+
+ handshakeFuture.complete(handshakeResponse.getResponse());
+ }
+
+}
diff --git a/cache-client/src/main/java/net/runelite/cache/client/IndexInfo.java b/cache-client/src/main/java/net/runelite/cache/client/IndexInfo.java
new file mode 100644
index 0000000000..b6f088e84b
--- /dev/null
+++ b/cache-client/src/main/java/net/runelite/cache/client/IndexInfo.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.client;
+
+public class IndexInfo
+{
+ private final int id;
+ private final int crc;
+ private final int revision;
+
+ public IndexInfo(int id, int crc, int revision)
+ {
+ this.id = id;
+ this.crc = crc;
+ this.revision = revision;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "IndexInfo{" + "id=" + id + ", crc=" + crc + ", revision=" + revision + '}';
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 5;
+ hash = 71 * hash + this.id;
+ hash = 71 * hash + this.crc;
+ hash = 71 * hash + this.revision;
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (obj == null)
+ {
+ return false;
+ }
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+ final IndexInfo other = (IndexInfo) obj;
+ if (this.id != other.id)
+ {
+ return false;
+ }
+ if (this.crc != other.crc)
+ {
+ return false;
+ }
+ if (this.revision != other.revision)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public int getId()
+ {
+ return id;
+ }
+
+ public int getCrc()
+ {
+ return crc;
+ }
+
+ public int getRevision()
+ {
+ return revision;
+ }
+}
diff --git a/cache-client/src/main/java/net/runelite/cache/client/PendingFileRequest.java b/cache-client/src/main/java/net/runelite/cache/client/PendingFileRequest.java
new file mode 100644
index 0000000000..d07dc4f606
--- /dev/null
+++ b/cache-client/src/main/java/net/runelite/cache/client/PendingFileRequest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.client;
+
+import java.util.concurrent.CompletableFuture;
+
+public class PendingFileRequest
+{
+ private final int index;
+ private final int archive;
+ private final CompletableFuture future;
+
+ public PendingFileRequest(int index, int archive, CompletableFuture future)
+ {
+ this.index = index;
+ this.archive = archive;
+ this.future = future;
+ }
+
+ public int getIndex()
+ {
+ return index;
+ }
+
+ public int getArchive()
+ {
+ return archive;
+ }
+
+ public CompletableFuture getFuture()
+ {
+ return future;
+ }
+}
diff --git a/cache-client/src/test/java/net/runelite/cache/client/CacheClientTest.java b/cache-client/src/test/java/net/runelite/cache/client/CacheClientTest.java
new file mode 100644
index 0000000000..f5ba5d6824
--- /dev/null
+++ b/cache-client/src/test/java/net/runelite/cache/client/CacheClientTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.client;
+
+import java.io.File;
+import java.util.concurrent.CompletableFuture;
+import net.runelite.cache.CacheProperties;
+import net.runelite.cache.fs.Store;
+import net.runelite.protocol.api.login.HandshakeResponseType;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.impl.SimpleLogger;
+
+public class CacheClientTest
+{
+ private static final Logger logger = LoggerFactory.getLogger(CacheClientTest.class);
+
+ @Before
+ public void before()
+ {
+ System.setProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "TRACE");
+ }
+
+ @Test
+ @Ignore
+ public void test() throws Exception
+ {
+ try (Store store = new Store(new File("D:\\rs\\07\\temp\\cache")))
+ {
+ store.load();
+
+ CacheClient c = new CacheClient(store, CacheProperties.getRsVersion());
+ c.connect();
+ CompletableFuture handshake = c.handshake();
+
+ HandshakeResponseType result = handshake.get();
+ logger.info("Handshake result: {}", result);
+
+ Assert.assertEquals(HandshakeResponseType.RESPONSE_OK, result);
+
+ c.download();
+
+ c.close();
+
+ store.save();
+ }
+ }
+}
diff --git a/cache-updater/pom.xml b/cache-updater/pom.xml
new file mode 100644
index 0000000000..4eb3f28217
--- /dev/null
+++ b/cache-updater/pom.xml
@@ -0,0 +1,105 @@
+
+
+
+ 4.0.0
+
+ net.runelite
+ runelite-parent
+ 1.5.28-SNAPSHOT
+
+
+ Cache Updater
+ cache-updater
+
+
+ 1.5.6.RELEASE
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+ ${spring.boot.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+ ${spring.boot.version}
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ ${spring.boot.version}
+ true
+
+
+ mysql
+ mysql-connector-java
+ 5.1.45
+
+
+ net.runelite
+ cache-client
+ ${project.version}
+
+
+ org.sql2o
+ sql2o
+ 1.5.4
+
+
+ io.minio
+ minio
+ 3.0.6
+
+
+ org.projectlombok
+ lombok
+ provided
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ ${spring.boot.version}
+
+
+
+ repackage
+
+
+ spring-boot
+ net.runelite.cache.updater.CacheUpdater
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cache-updater/schema.sql b/cache-updater/schema.sql
new file mode 100644
index 0000000000..a4e063e1a6
--- /dev/null
+++ b/cache-updater/schema.sql
@@ -0,0 +1,118 @@
+-- MySQL dump 10.16 Distrib 10.2.9-MariaDB, for Linux (x86_64)
+--
+-- Host: localhost Database: cache
+-- ------------------------------------------------------
+-- Server version 10.2.9-MariaDB
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `archive`
+--
+
+DROP TABLE IF EXISTS `archive`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `archive` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `archiveId` int(11) NOT NULL,
+ `nameHash` int(11) NOT NULL,
+ `crc` int(11) NOT NULL,
+ `revision` int(11) NOT NULL,
+ `hash` binary(32) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `archive_revision` (`archiveId`,`revision`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `cache`
+--
+
+DROP TABLE IF EXISTS `cache`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `cache` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `revision` int(11) NOT NULL,
+ `date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `revision_date` (`revision`,`date`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `file`
+--
+
+DROP TABLE IF EXISTS `file`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `file` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `archive` int(11) NOT NULL,
+ `fileId` int(11) NOT NULL,
+ `nameHash` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `archive_file` (`archive`,`fileId`),
+ CONSTRAINT `file_ibfk_1` FOREIGN KEY (`archive`) REFERENCES `archive` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `index`
+--
+
+DROP TABLE IF EXISTS `index`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `index` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `cache` int(11) NOT NULL,
+ `indexId` int(11) NOT NULL,
+ `crc` int(11) NOT NULL,
+ `revision` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `indexId` (`cache`,`indexId`,`revision`,`crc`) USING BTREE,
+ CONSTRAINT `index_ibfk_1` FOREIGN KEY (`cache`) REFERENCES `cache` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `index_archive`
+--
+
+DROP TABLE IF EXISTS `index_archive`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `index_archive` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `index` int(11) NOT NULL,
+ `archive` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `idx_index_archive` (`index`,`archive`) USING BTREE,
+ KEY `archive` (`archive`) USING BTREE,
+ CONSTRAINT `index_archive_ibfk_1` FOREIGN KEY (`index`) REFERENCES `index` (`id`),
+ CONSTRAINT `index_archive_ibfk_2` FOREIGN KEY (`archive`) REFERENCES `archive` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2018-02-02 21:55:48
diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/CacheConfiguration.java b/cache-updater/src/main/java/net/runelite/cache/updater/CacheConfiguration.java
new file mode 100644
index 0000000000..229ea1d268
--- /dev/null
+++ b/cache-updater/src/main/java/net/runelite/cache/updater/CacheConfiguration.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018, 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.cache.updater;
+
+import io.minio.MinioClient;
+import io.minio.errors.InvalidEndpointException;
+import io.minio.errors.InvalidPortException;
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.Map;
+import javax.sql.DataSource;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.sql2o.Sql2o;
+import org.sql2o.converters.Converter;
+import org.sql2o.quirks.NoQuirks;
+
+@Configuration
+public class CacheConfiguration
+{
+ @Value("${minio.endpoint}")
+ private String minioUrl;
+
+ @Value("${minio.accesskey}")
+ private String minioAccessKey;
+
+ @Value("${minio.secretkey}")
+ private String minioSecretKey;
+
+ @Bean
+ @ConfigurationProperties(prefix = "datasource.runelite-cache")
+ public DataSource dataSource()
+ {
+ return DataSourceBuilder.create().build();
+ }
+
+ @Bean
+ @Qualifier("Runelite Cache SQL2O")
+ public Sql2o sql2o(DataSource dataSource)
+ {
+ Map converters = new HashMap<>();
+ converters.put(Instant.class, new InstantConverter());
+ return new Sql2o(dataSource, new NoQuirks(converters));
+ }
+
+ @Bean
+ public MinioClient minioClient() throws InvalidEndpointException, InvalidPortException
+ {
+ return new MinioClient(minioUrl, minioAccessKey, minioSecretKey);
+ }
+}
diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/CacheDAO.java b/cache-updater/src/main/java/net/runelite/cache/updater/CacheDAO.java
new file mode 100644
index 0000000000..2834e5bb1e
--- /dev/null
+++ b/cache-updater/src/main/java/net/runelite/cache/updater/CacheDAO.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2017, 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.cache.updater;
+
+import java.time.Instant;
+import java.util.List;
+import net.runelite.cache.updater.beans.ArchiveEntry;
+import net.runelite.cache.updater.beans.CacheEntry;
+import net.runelite.cache.updater.beans.IndexEntry;
+import org.sql2o.Connection;
+import org.sql2o.Query;
+import org.sql2o.ResultSetIterable;
+
+class CacheDAO
+{
+ // cache prepared statements for high volume queries
+ private Query associateArchive;
+ private Query findArchive, insertArchive;
+ private Query associateFile;
+
+ public CacheEntry findMostRecent(Connection con)
+ {
+ return con.createQuery("select id, revision, date from cache order by revision desc, date desc limit 1")
+ .executeAndFetchFirst(CacheEntry.class);
+ }
+
+ public List findIndexesForCache(Connection con, CacheEntry cache)
+ {
+ return con.createQuery("select id, indexId, crc, revision from `index` where cache = :cache")
+ .addParameter("cache", cache.getId())
+ .executeAndFetch(IndexEntry.class);
+ }
+
+ public ResultSetIterable findArchivesForIndex(Connection con, IndexEntry indexEntry)
+ {
+ return con.createQuery("select archive.id, archive.archiveId, archive.nameHash,"
+ + " archive.crc, archive.revision, archive.hash from index_archive "
+ + "join archive on index_archive.archive = archive.id "
+ + "where index_archive.index = :id")
+ .addParameter("id", indexEntry.getId())
+ .executeAndFetchLazy(ArchiveEntry.class);
+ }
+
+ public CacheEntry createCache(Connection con, int revision, Instant date)
+ {
+ int cacheId = con.createQuery("insert into cache (revision, date) values (:revision, :date)")
+ .addParameter("revision", revision)
+ .addParameter("date", date)
+ .executeUpdate()
+ .getKey(int.class);
+
+ CacheEntry entry = new CacheEntry();
+ entry.setId(cacheId);
+ entry.setRevision(revision);
+ entry.setDate(date);
+ return entry;
+ }
+
+ public IndexEntry createIndex(Connection con, CacheEntry cache, int indexId, int crc, int revision)
+ {
+ int id = con.createQuery("insert into `index` (cache, indexId, crc, revision) values (:cache, :indexId, :crc, :revision)")
+ .addParameter("cache", cache.getId())
+ .addParameter("indexId", indexId)
+ .addParameter("crc", crc)
+ .addParameter("revision", revision)
+ .executeUpdate()
+ .getKey(int.class);
+
+ IndexEntry entry = new IndexEntry();
+ entry.setId(id);
+ entry.setIndexId(indexId);
+ entry.setCrc(crc);
+ entry.setRevision(revision);
+ return entry;
+ }
+
+ public void associateArchiveToIndex(Connection con, ArchiveEntry archive, IndexEntry index)
+ {
+ if (associateArchive == null)
+ {
+ associateArchive = con.createQuery("insert into index_archive (`index`, archive) values (:index, :archive)");
+ }
+ associateArchive
+ .addParameter("index", index.getId())
+ .addParameter("archive", archive.getId())
+ .executeUpdate();
+ }
+
+ public ArchiveEntry findArchive(Connection con, IndexEntry index,
+ int archiveId, int nameHash, int crc, int revision)
+ {
+ if (findArchive == null)
+ {
+ findArchive = con.createQuery("select distinct archive.id, archive.archiveId, archive.nameHash,"
+ + " archive.crc, archive.revision, archive.hash from archive "
+ + " join index_archive on index_archive.archive = archive.id"
+ + " join `index` on index.id = index_archive.index"
+ + " where archive.archiveId = :archiveId"
+ + " and archive.nameHash = :nameHash"
+ + " and archive.crc = :crc"
+ + " and archive.revision = :revision"
+ + " and index.indexId = :indexId");
+ }
+
+ ArchiveEntry entry = findArchive
+ .addParameter("archiveId", archiveId)
+ .addParameter("nameHash", nameHash)
+ .addParameter("crc", crc)
+ .addParameter("revision", revision)
+ .addParameter("indexId", index.getIndexId())
+ .executeAndFetchFirst(ArchiveEntry.class);
+ return entry;
+ }
+
+ public ArchiveEntry createArchive(Connection con, IndexEntry index,
+ int archiveId, int nameHash, int crc, int revision, byte[] hash)
+ {
+ if (insertArchive == null)
+ {
+ insertArchive = con.createQuery("insert into archive (archiveId, nameHash, crc, revision, hash) values "
+ + "(:archiveId, :nameHash, :crc, :revision, :hash)");
+ }
+
+ int id = insertArchive
+ .addParameter("archiveId", archiveId)
+ .addParameter("nameHash", nameHash)
+ .addParameter("crc", crc)
+ .addParameter("revision", revision)
+ .addParameter("hash", hash)
+ .executeUpdate()
+ .getKey(int.class);
+
+ ArchiveEntry entry = new ArchiveEntry();
+ entry.setId(id);
+ entry.setArchiveId(archiveId);
+ entry.setNameHash(nameHash);
+ entry.setCrc(crc);
+ entry.setRevision(revision);
+ entry.setHash(hash);
+ return entry;
+ }
+
+ public void associateFileToArchive(Connection con, ArchiveEntry archive, int fileId, int nameHash)
+ {
+ if (associateFile == null)
+ {
+ associateFile = con.createQuery("insert into file (archive, fileId, nameHash) values (:archive, :fileId, :nameHash)");
+ }
+ associateFile
+ .addParameter("archive", archive.getId())
+ .addParameter("fileId", fileId)
+ .addParameter("nameHash", nameHash)
+ .executeUpdate();
+ }
+}
diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/CacheStorage.java b/cache-updater/src/main/java/net/runelite/cache/updater/CacheStorage.java
new file mode 100644
index 0000000000..cac605da09
--- /dev/null
+++ b/cache-updater/src/main/java/net/runelite/cache/updater/CacheStorage.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017, 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.cache.updater;
+
+import java.io.IOException;
+import java.util.List;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+import net.runelite.cache.index.FileData;
+import net.runelite.cache.updater.beans.ArchiveEntry;
+import net.runelite.cache.updater.beans.CacheEntry;
+import net.runelite.cache.updater.beans.IndexEntry;
+import org.sql2o.Connection;
+import org.sql2o.ResultSetIterable;
+
+public class CacheStorage implements Storage
+{
+ private CacheEntry cacheEntry;
+ private final CacheDAO cacheDao;
+ private final Connection con;
+
+ public CacheStorage(CacheEntry cacheEntry, CacheDAO cacheDao, Connection con)
+ {
+ this.cacheEntry = cacheEntry;
+ this.cacheDao = cacheDao;
+ this.con = con;
+ }
+
+ public CacheEntry getCacheEntry()
+ {
+ return cacheEntry;
+ }
+
+ public void setCacheEntry(CacheEntry cacheEntry)
+ {
+ this.cacheEntry = cacheEntry;
+ }
+
+ @Override
+ public void init(Store store) throws IOException
+ {
+ }
+
+ @Override
+ public void close() throws IOException
+ {
+ }
+
+ @Override
+ public void load(Store store) throws IOException
+ {
+ List indexes = cacheDao.findIndexesForCache(con, cacheEntry);
+ for (IndexEntry indexEntry : indexes)
+ {
+ Index index = store.addIndex(indexEntry.getIndexId());
+ index.setCrc(indexEntry.getCrc());
+ index.setRevision(indexEntry.getRevision());
+
+ try (ResultSetIterable archives = cacheDao.findArchivesForIndex(con, indexEntry))
+ {
+ for (ArchiveEntry archiveEntry : archives)
+ {
+ if (index.getArchive(archiveEntry.getArchiveId()) != null)
+ {
+ throw new IOException("Duplicate archive " + archiveEntry + " on " + indexEntry);
+ }
+
+ Archive archive = index.addArchive(archiveEntry.getArchiveId());
+ archive.setNameHash(archiveEntry.getNameHash());
+ archive.setCrc(archiveEntry.getCrc());
+ archive.setRevision(archiveEntry.getRevision());
+ archive.setHash(archiveEntry.getHash());
+
+ // File data is not necessary for cache updating
+ }
+ }
+ }
+ }
+
+ @Override
+ public void save(Store store) throws IOException
+ {
+ for (Index index : store.getIndexes())
+ {
+ IndexEntry entry = cacheDao.createIndex(con, cacheEntry, index.getId(), index.getCrc(), index.getRevision());
+
+ for (Archive archive : index.getArchives())
+ {
+ ArchiveEntry archiveEntry = cacheDao.findArchive(con, entry, archive.getArchiveId(),
+ archive.getNameHash(), archive.getCrc(), archive.getRevision());
+ if (archiveEntry == null)
+ {
+ byte[] hash = archive.getHash();
+ archiveEntry = cacheDao.createArchive(con, entry, archive.getArchiveId(),
+ archive.getNameHash(), archive.getCrc(), archive.getRevision(), hash);
+
+ for (FileData file : archive.getFileData())
+ {
+ cacheDao.associateFileToArchive(con, archiveEntry, file.getId(), file.getNameHash());
+ }
+ }
+
+ cacheDao.associateArchiveToIndex(con, archiveEntry, entry);
+ }
+ }
+ }
+
+ @Override
+ public byte[] loadArchive(Archive archive) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void saveArchive(Archive archive, byte[] data) throws IOException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/CacheUpdater.java b/cache-updater/src/main/java/net/runelite/cache/updater/CacheUpdater.java
new file mode 100644
index 0000000000..1a8f81c5ec
--- /dev/null
+++ b/cache-updater/src/main/java/net/runelite/cache/updater/CacheUpdater.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2017, 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.cache.updater;
+
+import io.minio.MinioClient;
+import io.minio.errors.InvalidEndpointException;
+import io.minio.errors.InvalidPortException;
+import java.io.IOException;
+import java.time.Instant;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import net.runelite.cache.client.CacheClient;
+import net.runelite.cache.client.IndexInfo;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.Store;
+import net.runelite.cache.updater.beans.CacheEntry;
+import net.runelite.cache.updater.beans.IndexEntry;
+import net.runelite.http.api.RuneLiteAPI;
+import net.runelite.protocol.api.login.HandshakeResponseType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.sql2o.Connection;
+import org.sql2o.Sql2o;
+
+@SpringBootApplication
+public class CacheUpdater implements CommandLineRunner
+{
+ private static final Logger logger = LoggerFactory.getLogger(CacheUpdater.class);
+
+ private final Sql2o sql2o;
+ private final MinioClient minioClient;
+
+ @Value("${minio.bucket}")
+ private String minioBucket;
+
+ @Autowired
+ public CacheUpdater(
+ @Qualifier("Runelite Cache SQL2O") Sql2o sql2o,
+ MinioClient minioClient
+ )
+ {
+ this.sql2o = sql2o;
+ this.minioClient = minioClient;
+ }
+
+ public void update() throws IOException, InvalidEndpointException, InvalidPortException, InterruptedException
+ {
+ int rsVersion = RuneLiteAPI.getRsVersion();
+
+ try (Connection con = sql2o.beginTransaction())
+ {
+ CacheDAO cacheDao = new CacheDAO();
+ CacheEntry cache = cacheDao.findMostRecent(con);
+ boolean created = false;
+ if (cache == null)
+ {
+ created = true;
+ cache = cacheDao.createCache(con, rsVersion, Instant.now());
+ }
+
+ CacheStorage storage = new CacheStorage(cache, cacheDao, con);
+ Store store = new Store(storage);
+ store.load();
+
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+
+ CacheClient client = new CacheClient(store, rsVersion,
+ (Archive archive, byte[] data) -> executor.submit(new CacheUploader(minioClient, minioBucket, archive, data)));
+
+ client.connect();
+ HandshakeResponseType result = client.handshake().join();
+
+ if (result != HandshakeResponseType.RESPONSE_OK)
+ {
+ logger.warn("Out of date!");
+ return;
+ }
+
+ List indexes = client.requestIndexes();
+ List entries = cacheDao.findIndexesForCache(con, cache);
+
+ if (!checkOutOfDate(indexes, entries))
+ {
+ logger.info("All up to date.");
+ return;
+ }
+
+ client.download();
+
+ CacheEntry newCache = created ? cache : cacheDao.createCache(con, rsVersion, Instant.now());
+
+ storage.setCacheEntry(newCache);
+ store.save();
+
+ // ensure objects are added to the store before they become
+ // visible in the database
+ executor.shutdown();
+ while (!executor.awaitTermination(1, TimeUnit.SECONDS))
+ {
+ logger.debug("Waiting for termination of executor...");
+ }
+
+ // commit database
+ con.commit();
+ }
+ }
+
+ private boolean checkOutOfDate(List indexes, List dbIndexes)
+ {
+ if (indexes.size() != dbIndexes.size())
+ {
+ return true;
+ }
+
+ for (int i = 0; i < indexes.size(); ++i)
+ {
+ IndexInfo ii = indexes.get(i);
+ IndexEntry ie = dbIndexes.get(i);
+
+ if (ii.getId() != ie.getIndexId()
+ || ii.getRevision() != ie.getRevision()
+ || ii.getCrc() != ie.getCrc())
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void run(String... args) throws Exception
+ {
+ update();
+ }
+
+ public static void main(String[] args)
+ {
+ SpringApplication.run(CacheUpdater.class, args).close();
+ System.exit(0);
+ }
+
+}
diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/CacheUploader.java b/cache-updater/src/main/java/net/runelite/cache/updater/CacheUploader.java
new file mode 100644
index 0000000000..ed685a9034
--- /dev/null
+++ b/cache-updater/src/main/java/net/runelite/cache/updater/CacheUploader.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, 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.cache.updater;
+
+import com.google.common.hash.Hashing;
+import com.google.common.io.BaseEncoding;
+import io.minio.MinioClient;
+import io.minio.errors.ErrorResponseException;
+import io.minio.errors.InsufficientDataException;
+import io.minio.errors.InternalException;
+import io.minio.errors.InvalidArgumentException;
+import io.minio.errors.InvalidBucketNameException;
+import io.minio.errors.NoResponseException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import net.runelite.cache.fs.Archive;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xmlpull.v1.XmlPullParserException;
+
+public class CacheUploader implements Runnable
+{
+ private static final Logger logger = LoggerFactory.getLogger(CacheUploader.class);
+
+ private final MinioClient minioClient;
+ private final String minioBucket;
+ private final Archive archive;
+ private final byte[] data;
+
+ public CacheUploader(MinioClient minioClient, String minioBucket, Archive archive, byte[] data)
+ {
+ this.minioClient = minioClient;
+ this.minioBucket = minioBucket;
+ this.archive = archive;
+ this.data = data;
+ }
+
+ @Override
+ public void run()
+ {
+ byte[] hash = Hashing.sha256().hashBytes(data).asBytes();
+ String hashStr = BaseEncoding.base16().encode(hash);
+
+ archive.setHash(hash);
+
+ String path = new StringBuilder()
+ .append(hashStr, 0, 2)
+ .append('/')
+ .append(hashStr.substring(2))
+ .toString();
+
+ try
+ {
+ try (InputStream in = minioClient.getObject(minioBucket, path))
+ {
+ return; // already exists
+ }
+ catch (ErrorResponseException ex)
+ {
+ // doesn't exist
+ }
+
+ minioClient.putObject(minioBucket, path, new ByteArrayInputStream(data), data.length, "binary/octet-stream");
+ }
+ catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidArgumentException | InvalidBucketNameException | NoResponseException | IOException | InvalidKeyException | NoSuchAlgorithmException | XmlPullParserException ex)
+ {
+ logger.warn("unable to upload data to store", ex);
+ }
+ }
+
+}
diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/InstantConverter.java b/cache-updater/src/main/java/net/runelite/cache/updater/InstantConverter.java
new file mode 100644
index 0000000000..953fe9bd3a
--- /dev/null
+++ b/cache-updater/src/main/java/net/runelite/cache/updater/InstantConverter.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017, 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:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 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 HOLDER 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.cache.updater;
+
+import java.sql.Timestamp;
+import java.time.Instant;
+import org.sql2o.converters.Converter;
+import org.sql2o.converters.ConverterException;
+
+public class InstantConverter implements Converter
+{
+ @Override
+ public Instant convert(Object val) throws ConverterException
+ {
+ Timestamp ts = (Timestamp) val;
+ return ts.toInstant();
+ }
+
+ @Override
+ public Object toDatabaseParam(Instant val)
+ {
+ return Timestamp.from(val);
+ }
+
+}
diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/beans/ArchiveEntry.java b/cache-updater/src/main/java/net/runelite/cache/updater/beans/ArchiveEntry.java
new file mode 100644
index 0000000000..9bacab75b8
--- /dev/null
+++ b/cache-updater/src/main/java/net/runelite/cache/updater/beans/ArchiveEntry.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017, 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.cache.updater.beans;
+
+import lombok.Data;
+
+@Data
+public class ArchiveEntry
+{
+ private int id;
+ private int archiveId;
+ private int nameHash;
+ private int crc;
+ private int revision;
+ private byte[] hash;
+}
diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/beans/CacheEntry.java b/cache-updater/src/main/java/net/runelite/cache/updater/beans/CacheEntry.java
new file mode 100644
index 0000000000..c9081cd883
--- /dev/null
+++ b/cache-updater/src/main/java/net/runelite/cache/updater/beans/CacheEntry.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 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.cache.updater.beans;
+
+import java.time.Instant;
+import lombok.Data;
+
+@Data
+public class CacheEntry
+{
+ private int id;
+ private int revision;
+ private Instant date;
+}
diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/beans/FileEntry.java b/cache-updater/src/main/java/net/runelite/cache/updater/beans/FileEntry.java
new file mode 100644
index 0000000000..bb43c2a189
--- /dev/null
+++ b/cache-updater/src/main/java/net/runelite/cache/updater/beans/FileEntry.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 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.cache.updater.beans;
+
+import lombok.Data;
+
+@Data
+public class FileEntry
+{
+ private int id;
+ private int archiveId;
+ private int fileId;
+ private int nameHash;
+}
diff --git a/cache-updater/src/main/java/net/runelite/cache/updater/beans/IndexEntry.java b/cache-updater/src/main/java/net/runelite/cache/updater/beans/IndexEntry.java
new file mode 100644
index 0000000000..a5a0748f18
--- /dev/null
+++ b/cache-updater/src/main/java/net/runelite/cache/updater/beans/IndexEntry.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 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.cache.updater.beans;
+
+import lombok.Data;
+
+@Data
+public class IndexEntry
+{
+ private int id;
+ private int indexId;
+ private int crc;
+ private int revision;
+}
diff --git a/cache-updater/src/main/resources/application.yaml b/cache-updater/src/main/resources/application.yaml
new file mode 100644
index 0000000000..df290d680f
--- /dev/null
+++ b/cache-updater/src/main/resources/application.yaml
@@ -0,0 +1,16 @@
+---
+# Database
+datasource:
+ runelite-cache:
+ driverClassName: com.mysql.jdbc.Driver
+ type: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
+ url: jdbc:mysql://localhost/runelite-cache
+ username: runelite
+ password: runelite
+
+# Minio client storage for cache
+minio:
+ endpoint: http://localhost:9000
+ accesskey: AM54M27O4WZK65N6F8IP
+ secretkey: /PZCxzmsJzwCHYlogcymuprniGCaaLUOET2n6yMP
+ bucket: runelite
diff --git a/cache/pom.xml b/cache/pom.xml
new file mode 100644
index 0000000000..9fd6153b3b
--- /dev/null
+++ b/cache/pom.xml
@@ -0,0 +1,171 @@
+
+
+
+ 4.0.0
+
+
+ net.runelite
+ runelite-parent
+ 1.5.28-SNAPSHOT
+
+
+ cache
+ Cache
+
+
+ 165
+
+ 4.6
+
+
+
+
+ net.runelite
+ http-api
+ ${project.version}
+
+
+
+ com.google.guava
+ guava
+
+
+ org.slf4j
+ slf4j-api
+
+
+ org.apache.commons
+ commons-compress
+ 1.10
+
+
+ com.google.code.gson
+ gson
+
+
+ io.netty
+ netty-buffer
+ 4.1.0.Final
+
+
+ org.antlr
+ antlr4-runtime
+ ${antlr4.version}
+
+
+ commons-cli
+ commons-cli
+ 1.3.1
+
+
+ org.projectlombok
+ lombok
+ provided
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.slf4j
+ slf4j-simple
+ 1.7.12
+ test
+
+
+ net.runelite.rs
+ cache
+ ${cache.version}
+ test
+
+
+
+
+
+
+ src/test/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+ -Xmx2048m
+
+ ${cache.tmpdir}
+
+
+
+
+ maven-assembly-plugin
+
+
+ jar-with-dependencies
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+ org.antlr
+ antlr4-maven-plugin
+ ${antlr4.version}
+
+
+ process-resources
+
+ antlr4
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ test-jar
+
+
+
+
+
+
+
diff --git a/cache/src/main/antlr4/net/runelite/cache/script/assembler/rs2asm.g4 b/cache/src/main/antlr4/net/runelite/cache/script/assembler/rs2asm.g4
new file mode 100644
index 0000000000..f8b33e8676
--- /dev/null
+++ b/cache/src/main/antlr4/net/runelite/cache/script/assembler/rs2asm.g4
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+grammar rs2asm;
+
+prog: NEWLINE* (header NEWLINE+)* (line NEWLINE+)+ ;
+
+header: id | int_stack_count | string_stack_count | int_var_count | string_var_count ;
+
+id: '.id ' id_value ;
+int_stack_count: '.int_stack_count ' int_stack_value ;
+string_stack_count: '.string_stack_count ' string_stack_value ;
+int_var_count: '.int_var_count ' int_var_value ;
+string_var_count: '.string_var_count ' string_var_value ;
+
+id_value: INT ;
+int_stack_value: INT ;
+string_stack_value: INT ;
+int_var_value: INT ;
+string_var_value: INT ;
+
+line: instruction | label | switch_lookup ;
+instruction: instruction_name instruction_operand ;
+label: IDENTIFIER ':' ;
+
+instruction_name: name_string | name_opcode ;
+name_string: IDENTIFIER ;
+name_opcode: INT ;
+
+instruction_operand: operand_int | operand_qstring | operand_label | ;
+operand_int: INT ;
+operand_qstring: QSTRING ;
+operand_label: IDENTIFIER ;
+
+switch_lookup: switch_key ':' switch_value ;
+switch_key: INT ;
+switch_value: IDENTIFIER ;
+
+NEWLINE: ( '\r' | '\n' )+ ;
+INT: '-'? [0-9]+ ;
+QSTRING: '"' (~('"' | '\\' | '\r' | '\n') | '\\' ('"' | '\\'))* '"' ;
+IDENTIFIER: [a-zA-Z0-9_]+ ;
+COMMENT: ';' ~( '\r' | '\n' )* -> channel(HIDDEN) ;
+
+WS: (' ' | '\t')+ -> channel(HIDDEN) ;
\ No newline at end of file
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/barbarianassault/Calls.java b/cache/src/main/java/net/runelite/cache/AreaManager.java
similarity index 51%
rename from RuneLitePlus/src/main/java/net/runelite/client/plugins/barbarianassault/Calls.java
rename to cache/src/main/java/net/runelite/cache/AreaManager.java
index 5cba373d95..96967b84b6 100644
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/barbarianassault/Calls.java
+++ b/cache/src/main/java/net/runelite/cache/AreaManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, https://runelitepl.us
+ * Copyright (c) 2017, Adam
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -22,62 +22,56 @@
* (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.client.plugins.barbarianassault;
+package net.runelite.cache;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import net.runelite.cache.definitions.AreaDefinition;
+import net.runelite.cache.definitions.loaders.AreaLoader;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.ArchiveFiles;
+import net.runelite.cache.fs.FSFile;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
-public enum Calls
-{ //Attacker Calls
- RED_EGG("Red egg", "Tell-red"),
- GREEN_EGG("Green egg", "Tell-green"),
- BLUE_EGG("Blue egg", "Tell-blue"),
- //Collector Calls
- CONTROLLED("Controlled/Bullet/Wind", "Tell-controlled"),
- ACCURATE("Accurate/Field/Water", "Tell-accurate"),
- AGGRESSIVE("Aggressive/Blunt/Earth", "Tell-aggressive"),
- DEFENSIVE("Defensive/Barbed/Fire", "Tell-defensive"),
- //Healer Calls
- TOFU("Tofu", "Tell-tofu"),
- CRACKERS("Crackers", "Tell-crackers"),
- WORMS("Worms", "Tell-worms"),
- //Defender Calls
- POIS_WORMS("Pois. Worms", "Tell-worms"),
- POIS_TOFU("Pois. Tofu", "Tell-tofu"),
- POIS_MEAT("Pois. Meat", "Tell-meat");
+public class AreaManager
+{
+ private final Store store;
+ private final Map areas = new HashMap<>();
- private final String call;
- private final String option;
-
- private static final Map CALL_MENU = new HashMap<>();
-
- static
+ public AreaManager(Store store)
{
- for (Calls s : values())
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.CONFIGS);
+ Archive archive = index.getArchive(ConfigType.AREA.getId());
+
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ for (FSFile file : files.getFiles())
{
- CALL_MENU.put(s.getCall(), s.getOption());
+ AreaLoader loader = new AreaLoader();
+ AreaDefinition area = loader.load(file.getContents(), file.getFileId());
+ areas.put(area.id, area);
}
}
- Calls(String call, String option)
+ public Collection getAreas()
{
- this.call = call;
- this.option = option;
+ return Collections.unmodifiableCollection(areas.values());
}
- public String getCall()
+ public AreaDefinition getArea(int areaId)
{
- return call;
+ return areas.get(areaId);
}
-
- public String getOption()
- {
- return option;
- }
-
- public static String getOption(String call)
- {
- return CALL_MENU.get(call);
- }
-
-}
\ No newline at end of file
+}
diff --git a/cache/src/main/java/net/runelite/cache/Cache.java b/cache/src/main/java/net/runelite/cache/Cache.java
new file mode 100644
index 0000000000..0f2c2d36b1
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/Cache.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2017, 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.cache;
+
+import java.io.File;
+import java.io.IOException;
+import net.runelite.cache.fs.Store;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+public class Cache
+{
+ public static void main(String[] args) throws IOException
+ {
+ Options options = new Options();
+
+ options.addOption("c", "cache", true, "cache base");
+
+ options.addOption(null, "items", true, "directory to dump items to");
+ options.addOption(null, "npcs", true, "directory to dump npcs to");
+ options.addOption(null, "objects", true, "directory to dump objects to");
+ options.addOption(null, "sprites", true, "directory to dump sprites to");
+
+ CommandLineParser parser = new DefaultParser();
+ CommandLine cmd;
+ try
+ {
+ cmd = parser.parse(options, args);
+ }
+ catch (ParseException ex)
+ {
+ System.err.println("Error parsing command line options: " + ex.getMessage());
+ System.exit(-1);
+ return;
+ }
+
+ String cache = cmd.getOptionValue("cache");
+
+ Store store = loadStore(cache);
+
+ if (cmd.hasOption("items"))
+ {
+ String itemdir = cmd.getOptionValue("items");
+
+ if (itemdir == null)
+ {
+ System.err.println("Item directory must be specified");
+ return;
+ }
+
+ System.out.println("Dumping items to " + itemdir);
+ dumpItems(store, new File(itemdir));
+ }
+ else if (cmd.hasOption("npcs"))
+ {
+ String npcdir = cmd.getOptionValue("npcs");
+
+ if (npcdir == null)
+ {
+ System.err.println("NPC directory must be specified");
+ return;
+ }
+
+ System.out.println("Dumping npcs to " + npcdir);
+ dumpNpcs(store, new File(npcdir));
+ }
+ else if (cmd.hasOption("objects"))
+ {
+ String objectdir = cmd.getOptionValue("objects");
+
+ if (objectdir == null)
+ {
+ System.err.println("Object directory must be specified");
+ return;
+ }
+
+ System.out.println("Dumping objects to " + objectdir);
+ dumpObjects(store, new File(objectdir));
+ }
+ else if (cmd.hasOption("sprites"))
+ {
+ String spritedir = cmd.getOptionValue("sprites");
+
+ if (spritedir == null)
+ {
+ System.err.println("Sprite directory must be specified");
+ return;
+ }
+
+ System.out.println("Dumping sprites to " + spritedir);
+ dumpSprites(store, new File(spritedir));
+ }
+ else
+ {
+ System.err.println("Nothing to do");
+ }
+ }
+
+ private static Store loadStore(String cache) throws IOException
+ {
+ Store store = new Store(new File(cache));
+ store.load();
+ return store;
+ }
+
+ private static void dumpItems(Store store, File itemdir) throws IOException
+ {
+ ItemManager dumper = new ItemManager(store);
+ dumper.load();
+ dumper.export(itemdir);
+ dumper.java(itemdir);
+ }
+
+ private static void dumpNpcs(Store store, File npcdir) throws IOException
+ {
+ NpcManager dumper = new NpcManager(store);
+ dumper.load();
+ dumper.dump(npcdir);
+ dumper.java(npcdir);
+ }
+
+ private static void dumpObjects(Store store, File objectdir) throws IOException
+ {
+ ObjectManager dumper = new ObjectManager(store);
+ dumper.load();
+ dumper.dump(objectdir);
+ dumper.java(objectdir);
+ }
+
+ private static void dumpSprites(Store store, File spritedir) throws IOException
+ {
+ SpriteManager dumper = new SpriteManager(store);
+ dumper.load();
+ dumper.export(spritedir);
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/ConfigType.java b/cache/src/main/java/net/runelite/cache/ConfigType.java
new file mode 100644
index 0000000000..48d8e229c0
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/ConfigType.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache;
+
+public enum ConfigType
+{
+ // types from https://github.com/im-frizzy/OpenRS/blob/master/source/net/openrs/cache/type/ConfigArchive.java
+ UNDERLAY(1),
+ IDENTKIT(3),
+ OVERLAY(4),
+ INV(5),
+ OBJECT(6),
+ ENUM(8),
+ NPC(9),
+ ITEM(10),
+ SEQUENCE(12),
+ SPOTANIM(13),
+ VARBIT(14),
+ VARCLIENT(19),
+ VARCLIENTSTRING(15),
+ VARPLAYER(16),
+ STRUCT(34),
+ AREA(35);
+
+ private final int id;
+
+ ConfigType(int id)
+ {
+ this.id = id;
+ }
+
+ public int getId()
+ {
+ return id;
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/HeightMapDumper.java b/cache/src/main/java/net/runelite/cache/HeightMapDumper.java
new file mode 100644
index 0000000000..5db30815ff
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/HeightMapDumper.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache;
+
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import net.runelite.cache.fs.Store;
+import net.runelite.cache.region.Region;
+import net.runelite.cache.region.RegionLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class HeightMapDumper
+{
+ private static final Logger logger = LoggerFactory.getLogger(HeightMapDumper.class);
+
+ private static final int MAP_SCALE = 1;
+ private static final float MAX_HEIGHT = 2048f;
+
+ private final Store store;
+ private RegionLoader regionLoader;
+
+ public HeightMapDumper(Store store)
+ {
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ regionLoader = new RegionLoader(store);
+ regionLoader.loadRegions();
+ regionLoader.calculateBounds();
+ }
+
+ public BufferedImage drawHeightMap(int z)
+ {
+ int minX = regionLoader.getLowestX().getBaseX();
+ int minY = regionLoader.getLowestY().getBaseY();
+
+ int maxX = regionLoader.getHighestX().getBaseX() + Region.X;
+ int maxY = regionLoader.getHighestY().getBaseY() + Region.Y;
+
+ int dimX = maxX - minX;
+ int dimY = maxY - minY;
+
+ dimX *= MAP_SCALE;
+ dimY *= MAP_SCALE;
+
+ logger.info("Map image dimensions: {}px x {}px, {}px per map square ({} MB)", dimX, dimY, MAP_SCALE, (dimX * dimY / 1024 / 1024));
+
+ BufferedImage image = new BufferedImage(dimX, dimY, BufferedImage.TYPE_INT_RGB);
+ draw(image, z);
+ return image;
+ }
+
+ private void draw(BufferedImage image, int z)
+ {
+ int max = Integer.MIN_VALUE;
+ int min = Integer.MAX_VALUE;
+
+ for (Region region : regionLoader.getRegions())
+ {
+ int baseX = region.getBaseX();
+ int baseY = region.getBaseY();
+
+ // to pixel X
+ int drawBaseX = baseX - regionLoader.getLowestX().getBaseX();
+
+ // to pixel Y. top most y is 0, but the top most
+ // region has the greatest y, so invert
+ int drawBaseY = regionLoader.getHighestY().getBaseY() - baseY;
+
+ for (int x = 0; x < Region.X; ++x)
+ {
+ int drawX = drawBaseX + x;
+
+ for (int y = 0; y < Region.Y; ++y)
+ {
+ int drawY = drawBaseY + (Region.Y - 1 - y);
+
+ int height = region.getTileHeight(z, x, y);
+ if (height > max)
+ {
+ max = height;
+ }
+ if (height < min)
+ {
+ min = height;
+ }
+
+ int rgb = toColor(height);
+
+ drawMapSquare(image, drawX, drawY, rgb);
+ }
+ }
+ }
+ System.out.println("max " + max);
+ System.out.println("min " + min);
+ }
+
+ private int toColor(int height)
+ {
+ // height seems to be between -2040 and 0, inclusive
+ height = -height;
+ // Convert to between 0 and 1
+ float color = (float) height / MAX_HEIGHT;
+
+ assert color >= 0.0f && color <= 1.0f;
+
+ return new Color(color, color, color).getRGB();
+ }
+
+ private void drawMapSquare(BufferedImage image, int x, int y, int rgb)
+ {
+ x *= MAP_SCALE;
+ y *= MAP_SCALE;
+
+ for (int i = 0; i < MAP_SCALE; ++i)
+ {
+ for (int j = 0; j < MAP_SCALE; ++j)
+ {
+ image.setRGB(x + i, y + j, rgb);
+ }
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/IndexType.java b/cache/src/main/java/net/runelite/cache/IndexType.java
new file mode 100644
index 0000000000..813594bac5
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/IndexType.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache;
+
+public enum IndexType
+{
+ FRAMES(0),
+ FRAMEMAPS(1),
+ CONFIGS(2),
+ INTERFACES(3),
+ SOUNDEFFECTS(4),
+ MAPS(5),
+ TRACK1(6),
+ MODELS(7),
+ SPRITES(8),
+ TEXTURES(9),
+ BINARY(10),
+ TRACK2(11),
+ CLIENTSCRIPT(12),
+ FONTS(13),
+ VORBIS(14),
+ INSTRUMENTS(15),
+ WORLDMAP(16);
+
+ private int id;
+
+ IndexType(int id)
+ {
+ this.id = id;
+ }
+
+ public int getNumber()
+ {
+ return id;
+ }
+}
\ No newline at end of file
diff --git a/cache/src/main/java/net/runelite/cache/InterfaceManager.java b/cache/src/main/java/net/runelite/cache/InterfaceManager.java
new file mode 100644
index 0000000000..ccfcfedd3b
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/InterfaceManager.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2017, 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.cache;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import net.runelite.cache.definitions.InterfaceDefinition;
+import net.runelite.cache.definitions.exporters.InterfaceExporter;
+import net.runelite.cache.definitions.loaders.InterfaceLoader;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.ArchiveFiles;
+import net.runelite.cache.fs.FSFile;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+import net.runelite.cache.util.Namer;
+
+public class InterfaceManager
+{
+ private final Store store;
+ private InterfaceDefinition[][] interfaces;
+ private final Namer namer = new Namer();
+
+ public InterfaceManager(Store store)
+ {
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ InterfaceLoader loader = new InterfaceLoader();
+
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.INTERFACES);
+
+ int max = index.getArchives().stream().mapToInt(a -> a.getArchiveId()).max().getAsInt();
+ interfaces = new InterfaceDefinition[max + 1][];
+
+ for (Archive archive : index.getArchives())
+ {
+ int archiveId = archive.getArchiveId();
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ InterfaceDefinition[] ifaces = interfaces[archiveId];
+ if (ifaces == null)
+ {
+ ifaces = interfaces[archiveId] = new InterfaceDefinition[archive.getFileData().length];
+ }
+
+ for (FSFile file : files.getFiles())
+ {
+ int fileId = file.getFileId();
+
+ int widgetId = (archiveId << 16) + fileId;
+
+ InterfaceDefinition iface = loader.load(widgetId, file.getContents());
+ ifaces[fileId] = iface;
+ }
+ }
+ }
+
+ public int getNumInterfaceGroups()
+ {
+ return interfaces.length;
+ }
+
+ public int getNumChildren(int groupId)
+ {
+ return interfaces[groupId].length;
+ }
+
+ public InterfaceDefinition[] getIntefaceGroup(int groupId)
+ {
+ return interfaces[groupId];
+ }
+
+ public InterfaceDefinition getInterface(int groupId, int childId)
+ {
+ return interfaces[groupId][childId];
+ }
+
+ public InterfaceDefinition[][] getInterfaces()
+ {
+ return interfaces;
+ }
+
+ public void export(File out) throws IOException
+ {
+ out.mkdirs();
+
+ for (InterfaceDefinition[] defs : interfaces)
+ {
+ if (defs == null)
+ {
+ continue;
+ }
+
+ for (InterfaceDefinition def : defs)
+ {
+ if (def == null)
+ {
+ continue;
+ }
+
+ InterfaceExporter exporter = new InterfaceExporter(def);
+
+ File folder = new File(out, "" + (def.id >>> 16));
+ folder.mkdirs();
+
+ File targ = new File(folder, (def.id & 0xffff) + ".json");
+ exporter.exportTo(targ);
+ }
+ }
+ }
+
+ public void java(File java) throws IOException
+ {
+ System.setProperty("line.separator", "\n");
+ java.mkdirs();
+ File targ = new File(java, "InterfaceID.java");
+ try (PrintWriter fw = new PrintWriter(targ))
+ {
+ fw.println("/* This file is automatically generated. Do not edit. */");
+ fw.println("package net.runelite.api;");
+ fw.println("");
+ fw.println("public final class InterfaceID {");
+ for (InterfaceDefinition[] defs : interfaces)
+ {
+ if (defs == null)
+ {
+ continue;
+ }
+ for (InterfaceDefinition def : defs)
+ {
+ if (def == null || def.name == null || def.name.equalsIgnoreCase("NULL"))
+ {
+ continue;
+ }
+
+ String name = namer.name(def.name, def.id);
+ if (name == null)
+ {
+ continue;
+ }
+
+ fw.println(" public static final int " + name + " = " + def.id + ";");
+ }
+ }
+ fw.println("}");
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/InventoryManager.java b/cache/src/main/java/net/runelite/cache/InventoryManager.java
new file mode 100644
index 0000000000..772d48b1a9
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/InventoryManager.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, 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.cache;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import net.runelite.cache.definitions.InventoryDefinition;
+import net.runelite.cache.definitions.loaders.InventoryLoader;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.ArchiveFiles;
+import net.runelite.cache.fs.FSFile;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+
+public class InventoryManager
+{
+ private final Store store;
+ private final List inventories = new ArrayList<>();
+
+ public InventoryManager(Store store)
+ {
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ InventoryLoader loader = new InventoryLoader();
+
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.CONFIGS);
+ Archive archive = index.getArchive(ConfigType.INV.getId());
+
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ for (FSFile file : files.getFiles())
+ {
+ InventoryDefinition inv = loader.load(file.getFileId(), file.getContents());
+ inventories.add(inv);
+ }
+ }
+
+ public List getInventories()
+ {
+ return Collections.unmodifiableList(inventories);
+ }
+
+ public InventoryDefinition findInventory(int id)
+ {
+ for (InventoryDefinition def : inventories)
+ {
+ if (def.id == id)
+ {
+ return def;
+ }
+ }
+ return null;
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/ItemManager.java b/cache/src/main/java/net/runelite/cache/ItemManager.java
new file mode 100644
index 0000000000..b3449a51a4
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/ItemManager.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import net.runelite.cache.definitions.ItemDefinition;
+import net.runelite.cache.definitions.exporters.ItemExporter;
+import net.runelite.cache.definitions.loaders.ItemLoader;
+import net.runelite.cache.definitions.providers.ItemProvider;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.ArchiveFiles;
+import net.runelite.cache.fs.FSFile;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+import net.runelite.cache.util.IDClass;
+
+public class ItemManager implements ItemProvider
+{
+ private final Store store;
+ private final Map items = new HashMap<>();
+
+ public ItemManager(Store store)
+ {
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ ItemLoader loader = new ItemLoader();
+
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.CONFIGS);
+ Archive archive = index.getArchive(ConfigType.ITEM.getId());
+
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ for (FSFile f : files.getFiles())
+ {
+ ItemDefinition def = loader.load(f.getFileId(), f.getContents());
+ items.put(f.getFileId(), def);
+ }
+ }
+
+ public Collection getItems()
+ {
+ return Collections.unmodifiableCollection(items.values());
+ }
+
+ public ItemDefinition getItem(int itemId)
+ {
+ return items.get(itemId);
+ }
+
+ public void export(File out) throws IOException
+ {
+ out.mkdirs();
+
+ for (ItemDefinition def : items.values())
+ {
+ ItemExporter exporter = new ItemExporter(def);
+
+ File targ = new File(out, def.id + ".json");
+ exporter.exportTo(targ);
+ }
+ }
+
+ public void java(File java) throws IOException
+ {
+ java.mkdirs();
+ try (IDClass ids = IDClass.create(java, "ItemID"))
+ {
+ try (IDClass nulls = IDClass.create(java, "NullItemID"))
+ {
+ for (ItemDefinition def : items.values())
+ {
+ if (def.name.equalsIgnoreCase("NULL"))
+ {
+ nulls.add(def.name, def.id);
+ }
+ else
+ {
+ ids.add(def.name, def.id);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public ItemDefinition provide(int itemId)
+ {
+ return getItem(itemId);
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/MapImageDumper.java b/cache/src/main/java/net/runelite/cache/MapImageDumper.java
new file mode 100644
index 0000000000..5235d97fb6
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/MapImageDumper.java
@@ -0,0 +1,987 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import lombok.Getter;
+import lombok.Setter;
+import net.runelite.cache.definitions.AreaDefinition;
+import net.runelite.cache.definitions.ObjectDefinition;
+import net.runelite.cache.definitions.OverlayDefinition;
+import net.runelite.cache.definitions.SpriteDefinition;
+import net.runelite.cache.definitions.UnderlayDefinition;
+import net.runelite.cache.definitions.loaders.OverlayLoader;
+import net.runelite.cache.definitions.loaders.SpriteLoader;
+import net.runelite.cache.definitions.loaders.UnderlayLoader;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.ArchiveFiles;
+import net.runelite.cache.fs.FSFile;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+import net.runelite.cache.item.ColorPalette;
+import net.runelite.cache.item.RSTextureProvider;
+import net.runelite.cache.region.Location;
+import net.runelite.cache.region.Region;
+import net.runelite.cache.region.RegionLoader;
+import net.runelite.cache.util.Djb2;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MapImageDumper
+{
+ private static final Logger logger = LoggerFactory.getLogger(MapImageDumper.class);
+
+ private static final int MAP_SCALE = 4; // this squared is the number of pixels per map square
+ private static final int MAPICON_MAX_WIDTH = 5; // scale minimap icons down to this size so they fit..
+ private static final int MAPICON_MAX_HEIGHT = 6;
+ private static final int BLEND = 5; // number of surrounding tiles for ground blending
+
+ private static int[] colorPalette = new ColorPalette(0.9d, 0, 512).getColorPalette();
+
+ private static int[][] TILE_SHAPE_2D = new int[][]{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1}, {1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1}, {0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0}, {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1}, {1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1}};
+ private static int[][] TILE_ROTATION_2D = new int[][]{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, {12, 8, 4, 0, 13, 9, 5, 1, 14, 10, 6, 2, 15, 11, 7, 3}, {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, {3, 7, 11, 15, 2, 6, 10, 14, 1, 5, 9, 13, 0, 4, 8, 12}};
+
+ private final int wallColor = (238 + (int) (Math.random() * 20.0D) - 10 << 16) + (238 + (int) (Math.random() * 20.0D) - 10 << 8) + (238 + (int) (Math.random() * 20.0D) - 10);
+ private final int doorColor = 238 + (int) (Math.random() * 20.0D) - 10 << 16;
+
+ private final Store store;
+
+ private final Map underlays = new HashMap<>();
+ private final Map overlays = new HashMap<>();
+ private final Map scaledMapIcons = new HashMap<>();
+
+ private RegionLoader regionLoader;
+ private final AreaManager areas;
+ private final SpriteManager sprites;
+ private RSTextureProvider rsTextureProvider;
+ private final ObjectManager objectManager;
+
+ @Getter
+ @Setter
+ private boolean labelRegions;
+
+ @Getter
+ @Setter
+ private boolean outlineRegions;
+
+ public MapImageDumper(Store store)
+ {
+ this.store = store;
+ this.areas = new AreaManager(store);
+ this.sprites = new SpriteManager(store);
+ objectManager = new ObjectManager(store);
+ }
+
+ public void load() throws IOException
+ {
+ loadUnderlays(store);
+ loadOverlays(store);
+ objectManager.load();
+
+ TextureManager textureManager = new TextureManager(store);
+ textureManager.load();
+ rsTextureProvider = new RSTextureProvider(textureManager, sprites);
+
+ loadRegions(store);
+ areas.load();
+ sprites.load();
+ loadSprites();
+ }
+
+ public BufferedImage drawMap(int z)
+ {
+ int minX = regionLoader.getLowestX().getBaseX();
+ int minY = regionLoader.getLowestY().getBaseY();
+
+ int maxX = regionLoader.getHighestX().getBaseX() + Region.X;
+ int maxY = regionLoader.getHighestY().getBaseY() + Region.Y;
+
+ int dimX = maxX - minX;
+ int dimY = maxY - minY;
+
+ int pixelsX = dimX * MAP_SCALE;
+ int pixelsY = dimY * MAP_SCALE;
+
+ logger.info("Map image dimensions: {}px x {}px, {}px per map square ({} MB). Max memory: {}mb", pixelsX, pixelsY,
+ MAP_SCALE, (pixelsX * pixelsY * 3 / 1024 / 1024),
+ Runtime.getRuntime().maxMemory() / 1024L / 1024L);
+
+ BufferedImage image = new BufferedImage(pixelsX, pixelsY, BufferedImage.TYPE_INT_RGB);
+
+ drawMap(image, z);
+ drawObjects(image, z);
+ drawMapIcons(image, z);
+
+ return image;
+ }
+
+ public BufferedImage drawRegion(Region region, int z)
+ {
+ int pixelsX = Region.X * MAP_SCALE;
+ int pixelsY = Region.Y * MAP_SCALE;
+
+ BufferedImage image = new BufferedImage(pixelsX, pixelsY, BufferedImage.TYPE_INT_RGB);
+
+ drawMap(image, 0, 0, z, region);
+ drawObjects(image, 0, 0, region, z);
+ drawMapIcons(image, 0, 0, region, z);
+
+ return image;
+ }
+
+ private void drawMap(BufferedImage image, int drawBaseX, int drawBaseY, int z, Region region)
+ {
+ int[][] map = new int[Region.X * MAP_SCALE][Region.Y * MAP_SCALE];
+ drawMap(map, region, z);
+
+ int[][] above = null;
+ if (z < 3)
+ {
+ above = new int[Region.X * MAP_SCALE][Region.Y * MAP_SCALE];
+ drawMap(above, region, z + 1);
+ }
+
+ for (int x = 0; x < Region.X; ++x)
+ {
+ for (int y = 0; y < Region.Y; ++y)
+ {
+ boolean isBridge = (region.getTileSetting(1, x, Region.Y - y - 1) & 2) != 0;
+
+ int tileSetting = region.getTileSetting(z, x, Region.Y - y - 1);
+ if (!isBridge && ((tileSetting & 24) == 0))
+ {
+ drawTile(image, map, drawBaseX, drawBaseY, x, y);
+ }
+
+ if (z < 3 && isBridge) // client also has a check for &8 != 0 here
+ {
+ drawTile(image, above, drawBaseX, drawBaseY, x, y);
+ }
+ }
+ }
+ }
+
+ private void drawMap(BufferedImage image, int z)
+ {
+ for (Region region : regionLoader.getRegions())
+ {
+ int baseX = region.getBaseX();
+ int baseY = region.getBaseY();
+
+ // to pixel X
+ int drawBaseX = baseX - regionLoader.getLowestX().getBaseX();
+
+ // to pixel Y. top most y is 0, but the top most
+ // region has the greatest y, so invert
+ int drawBaseY = regionLoader.getHighestY().getBaseY() - baseY;
+
+ drawMap(image, drawBaseX, drawBaseY, z, region);
+ }
+ }
+
+ private void drawTile(BufferedImage to, int[][] pixels, int drawBaseX, int drawBaseY, int x, int y)
+ {
+ for (int i = 0; i < MAP_SCALE; ++i)
+ {
+ for (int j = 0; j < MAP_SCALE; ++j)
+ {
+ to.setRGB(drawBaseX * MAP_SCALE + x * MAP_SCALE + i,
+ drawBaseY * MAP_SCALE + y * MAP_SCALE + j,
+ pixels[x * MAP_SCALE + i][y * MAP_SCALE + j]);
+ }
+ }
+ }
+
+ private void drawMap(int[][] pixels, Region region, int z)
+ {
+ int baseX = region.getBaseX();
+ int baseY = region.getBaseY();
+
+ int len = Region.X + BLEND * 2;
+ int[] hues = new int[len];
+ int[] sats = new int[len];
+ int[] light = new int[len];
+ int[] mul = new int[len];
+ int[] num = new int[len];
+
+ boolean hasLeftRegion = regionLoader.findRegionForWorldCoordinates(baseX - 1, baseY) != null;
+ boolean hasRightRegion = regionLoader.findRegionForWorldCoordinates(baseX + Region.X, baseY) != null;
+ boolean hasUpRegion = regionLoader.findRegionForWorldCoordinates(baseX, baseY + Region.Y) != null;
+ boolean hasDownRegion = regionLoader.findRegionForWorldCoordinates(baseX, baseY - 1) != null;
+
+ for (int xi = (hasLeftRegion ? -BLEND * 2 : -BLEND); xi < Region.X + (hasRightRegion ? BLEND * 2 : BLEND); ++xi)
+ {
+ for (int yi = (hasDownRegion ? -BLEND : 0); yi < Region.Y + (hasUpRegion ? BLEND : 0); ++yi)
+ {
+ int xr = xi + BLEND;
+ if (xr >= (hasLeftRegion ? -BLEND : 0) && xr < Region.X + (hasRightRegion ? BLEND : 0))
+ {
+ Region r = regionLoader.findRegionForWorldCoordinates(baseX + xr, baseY + yi);
+ if (r != null)
+ {
+ int underlayId = r.getUnderlayId(z, convert(xr), convert(yi));
+ if (underlayId > 0)
+ {
+ UnderlayDefinition underlay = findUnderlay(underlayId - 1);
+ hues[yi + BLEND] += underlay.getHue();
+ sats[yi + BLEND] += underlay.getSaturation();
+ light[yi + BLEND] += underlay.getLightness();
+ mul[yi + BLEND] += underlay.getHueMultiplier();
+ num[yi + BLEND]++;
+ }
+ }
+ }
+
+ int xl = xi - BLEND;
+ if (xl >= (hasLeftRegion ? -BLEND : 0) && xl < Region.X + (hasRightRegion ? BLEND : 0))
+ {
+ Region r = regionLoader.findRegionForWorldCoordinates(baseX + xl, baseY + yi);
+ if (r != null)
+ {
+ int underlayId = r.getUnderlayId(z, convert(xl), convert(yi));
+ if (underlayId > 0)
+ {
+ UnderlayDefinition underlay = findUnderlay(underlayId - 1);
+ hues[yi + BLEND] -= underlay.getHue();
+ sats[yi + BLEND] -= underlay.getSaturation();
+ light[yi + BLEND] -= underlay.getLightness();
+ mul[yi + BLEND] -= underlay.getHueMultiplier();
+ num[yi + BLEND]--;
+ }
+ }
+ }
+ }
+
+ if (xi >= 0 && xi < Region.X)
+ {
+ int runningHues = 0;
+ int runningSat = 0;
+ int runningLight = 0;
+ int runningMultiplier = 0;
+ int runningNumber = 0;
+
+ for (int yi = (hasDownRegion ? -BLEND * 2 : -BLEND); yi < Region.Y + (hasUpRegion ? BLEND * 2 : BLEND); ++yi)
+ {
+ int yu = yi + BLEND;
+ if (yu >= (hasDownRegion ? -BLEND : 0) && yu < Region.Y + (hasUpRegion ? BLEND : 0))
+ {
+ runningHues += hues[yu + BLEND];
+ runningSat += sats[yu + BLEND];
+ runningLight += light[yu + BLEND];
+ runningMultiplier += mul[yu + BLEND];
+ runningNumber += num[yu + BLEND];
+ }
+
+ int yd = yi - BLEND;
+ if (yd >= (hasDownRegion ? -BLEND : 0) && yd < Region.Y + (hasUpRegion ? BLEND : 0))
+ {
+ runningHues -= hues[yd + BLEND];
+ runningSat -= sats[yd + BLEND];
+ runningLight -= light[yd + BLEND];
+ runningMultiplier -= mul[yd + BLEND];
+ runningNumber -= num[yd + BLEND];
+ }
+
+ if (yi >= 0 && yi < Region.Y)
+ {
+ Region r = regionLoader.findRegionForWorldCoordinates(baseX + xi, baseY + yi);
+ if (r != null)
+ {
+ int underlayId = r.getUnderlayId(z, convert(xi), convert(yi));
+ int overlayId = r.getOverlayId(z, convert(xi), convert(yi));
+
+ if (underlayId > 0 || overlayId > 0)
+ {
+ int underlayHsl = -1;
+ if (underlayId > 0)
+ {
+ int avgHue = runningHues * 256 / runningMultiplier;
+ int avgSat = runningSat / runningNumber;
+ int avgLight = runningLight / runningNumber;
+ // randomness is added to avgHue here
+
+ if (avgLight < 0)
+ {
+ avgLight = 0;
+ }
+ else if (avgLight > 255)
+ {
+ avgLight = 255;
+ }
+
+ underlayHsl = packHsl(avgHue, avgSat, avgLight);
+ }
+
+ int underlayRgb = 0;
+ if (underlayHsl != -1)
+ {
+ int var0 = method1792(underlayHsl, 96);
+ underlayRgb = colorPalette[var0];
+ }
+
+ int shape, rotation;
+ Integer overlayRgb = null;
+ if (overlayId == 0)
+ {
+ shape = rotation = 0;
+ }
+ else
+ {
+ shape = r.getOverlayPath(z, convert(xi), convert(yi)) + 1;
+ rotation = r.getOverlayRotation(z, convert(xi), convert(yi));
+
+ OverlayDefinition overlayDefinition = findOverlay(overlayId - 1);
+ int overlayTexture = overlayDefinition.getTexture();
+ int rgb;
+
+ if (overlayTexture >= 0)
+ {
+ rgb = rsTextureProvider.getAverageTextureRGB(overlayTexture);
+ }
+ else if (overlayDefinition.getRgbColor() == 0xFF_00FF)
+ {
+ rgb = -2;
+ }
+ else
+ {
+ // randomness added here
+ int overlayHsl = packHsl(overlayDefinition.getHue(), overlayDefinition.getSaturation(), overlayDefinition.getLightness());
+ rgb = overlayHsl;
+ }
+
+ overlayRgb = 0;
+ if (rgb != -2)
+ {
+ int var0 = adjustHSLListness0(rgb, 96);
+ overlayRgb = colorPalette[var0];
+ }
+
+ if (overlayDefinition.getSecondaryRgbColor() != -1)
+ {
+ int hue = overlayDefinition.getOtherHue();
+ int sat = overlayDefinition.getOtherSaturation();
+ int olight = overlayDefinition.getOtherLightness();
+ rgb = packHsl(hue, sat, olight);
+ int var0 = adjustHSLListness0(rgb, 96);
+ overlayRgb = colorPalette[var0];
+ }
+ }
+
+ if (shape == 0)
+ {
+ int drawX = xi;
+ int drawY = Region.Y - 1 - yi;
+ if (underlayRgb != 0)
+ {
+ drawMapSquare(pixels, drawX, drawY, underlayRgb);
+ }
+ }
+ else if (shape == 1)
+ {
+ int drawX = xi;
+ int drawY = Region.Y - 1 - yi;
+ drawMapSquare(pixels, drawX, drawY, overlayRgb);
+ }
+ else
+ {
+ int drawX = xi * MAP_SCALE;
+ int drawY = (Region.Y - 1 - yi) * MAP_SCALE;
+ int[] tileShapes = TILE_SHAPE_2D[shape];
+ int[] tileRotations = TILE_ROTATION_2D[rotation];
+ if (underlayRgb != 0)
+ {
+ int rotIdx = 0;
+ for (int i = 0; i < Region.Z; ++i)
+ {
+ int p1 = tileShapes[tileRotations[rotIdx++]] == 0 ? underlayRgb : overlayRgb;
+ int p2 = tileShapes[tileRotations[rotIdx++]] == 0 ? underlayRgb : overlayRgb;
+ int p3 = tileShapes[tileRotations[rotIdx++]] == 0 ? underlayRgb : overlayRgb;
+ int p4 = tileShapes[tileRotations[rotIdx++]] == 0 ? underlayRgb : overlayRgb;
+ pixels[drawX + 0][drawY + i] = p1;
+ pixels[drawX + 1][drawY + i] = p2;
+ pixels[drawX + 2][drawY + i] = p3;
+ pixels[drawX + 3][drawY + i] = p4;
+ }
+ }
+ else
+ {
+ int rotIdx = 0;
+ for (int i = 0; i < Region.Z; ++i)
+ {
+ int p1 = tileShapes[tileRotations[rotIdx++]];
+ int p2 = tileShapes[tileRotations[rotIdx++]];
+ int p3 = tileShapes[tileRotations[rotIdx++]];
+ int p4 = tileShapes[tileRotations[rotIdx++]];
+
+ if (p1 != 0)
+ {
+ pixels[drawX + 0][drawY + i] = overlayRgb;
+ }
+
+ if (p2 != 0)
+ {
+ pixels[drawX + 1][drawY + i] = overlayRgb;
+ }
+
+ if (p3 != 0)
+ {
+ pixels[drawX + 2][drawY + i] = overlayRgb;
+ }
+
+ if (p4 != 0)
+ {
+ pixels[drawX + 3][drawY + i] = overlayRgb;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static int convert(int d)
+ {
+ if (d >= 0)
+ {
+ return d % 64;
+ }
+ else
+ {
+ return 64 - -(d % 64) - 1;
+ }
+ }
+
+ private void drawObjects(BufferedImage image, int drawBaseX, int drawBaseY, Region region, int z)
+ {
+ Graphics2D graphics = image.createGraphics();
+
+ for (Location location : region.getLocations())
+ {
+
+ int rotation = location.getOrientation();
+ int type = location.getType();
+
+ int localX = location.getPosition().getX() - region.getBaseX();
+ int localY = location.getPosition().getY() - region.getBaseY();
+
+ boolean isBridge = (region.getTileSetting(1, localX, localY) & 2) != 0;
+
+ if (location.getPosition().getZ() == z + 1)
+ {
+ if (!isBridge)
+ {
+ continue;
+ }
+ }
+ else if (location.getPosition().getZ() == z)
+ {
+ if (isBridge)
+ {
+ continue;
+ }
+
+ if ((region.getTileSetting(z, localX, localY) & 24) != 0)
+ {
+ continue;
+ }
+ }
+ else
+ {
+ continue;
+ }
+
+ ObjectDefinition object = findObject(location.getId());
+
+ int drawX = (drawBaseX + localX) * MAP_SCALE;
+ int drawY = (drawBaseY + (Region.Y - 1 - localY)) * MAP_SCALE;
+
+ if (type >= 0 && type <= 3)
+ {
+ // this is a wall
+ int hash = (localY << 7) + localX + (location.getId() << 14) + 0x4000_0000;
+ if (object.getAnInt2088() == 0)
+ {
+ hash -= Integer.MIN_VALUE;
+ }
+
+ int rgb = wallColor;
+ if (hash > 0)
+ {
+ rgb = doorColor;
+ }
+
+ if (object.getMapSceneID() != -1)
+ {
+ Image spriteImage = scaledMapIcons.get(object.getMapSceneID());
+ graphics.drawImage(spriteImage, drawX * MAP_SCALE, drawY * MAP_SCALE, null);
+ }
+ else
+ {
+ if (type == 0 || type == 2)
+ {
+ if (rotation == 0)
+ {
+ image.setRGB(drawX + 0, drawY + 0, rgb);
+ image.setRGB(drawX + 0, drawY + 1, rgb);
+ image.setRGB(drawX + 0, drawY + 2, rgb);
+ image.setRGB(drawX + 0, drawY + 3, rgb);
+ }
+ else if (rotation == 1)
+ {
+ image.setRGB(drawX + 0, drawY + 0, rgb);
+ image.setRGB(drawX + 1, drawY + 0, rgb);
+ image.setRGB(drawX + 2, drawY + 0, rgb);
+ image.setRGB(drawX + 3, drawY + 0, rgb);
+ }
+ else if (rotation == 2)
+ {
+ image.setRGB(drawX + 3, drawY + 0, rgb);
+ image.setRGB(drawX + 3, drawY + 1, rgb);
+ image.setRGB(drawX + 3, drawY + 2, rgb);
+ image.setRGB(drawX + 3, drawY + 3, rgb);
+ }
+ else if (rotation == 3)
+ {
+ image.setRGB(drawX + 0, drawY + 3, rgb);
+ image.setRGB(drawX + 1, drawY + 3, rgb);
+ image.setRGB(drawX + 2, drawY + 3, rgb);
+ image.setRGB(drawX + 3, drawY + 3, rgb);
+ }
+ }
+
+ if (type == 3)
+ {
+ if (rotation == 0)
+ {
+ image.setRGB(drawX + 0, drawY + 0, rgb);
+ }
+ else if (rotation == 1)
+ {
+ image.setRGB(drawX + 3, drawY + 0, rgb);
+ }
+ else if (rotation == 2)
+ {
+ image.setRGB(drawX + 3, drawY + 3, rgb);
+ }
+ else if (rotation == 3)
+ {
+ image.setRGB(drawX + 0, drawY + 3, rgb);
+ }
+ }
+
+ if (type == 2)
+ {
+ if (rotation == 3)
+ {
+ image.setRGB(drawX + 0, drawY + 0, rgb);
+ image.setRGB(drawX + 0, drawY + 1, rgb);
+ image.setRGB(drawX + 0, drawY + 2, rgb);
+ image.setRGB(drawX + 0, drawY + 3, rgb);
+ }
+ else if (rotation == 0)
+ {
+ image.setRGB(drawX + 0, drawY + 0, rgb);
+ image.setRGB(drawX + 1, drawY + 0, rgb);
+ image.setRGB(drawX + 2, drawY + 0, rgb);
+ image.setRGB(drawX + 3, drawY + 0, rgb);
+ }
+ else if (rotation == 1)
+ {
+ image.setRGB(drawX + 3, drawY + 0, rgb);
+ image.setRGB(drawX + 3, drawY + 1, rgb);
+ image.setRGB(drawX + 3, drawY + 2, rgb);
+ image.setRGB(drawX + 3, drawY + 3, rgb);
+ }
+ else if (rotation == 2)
+ {
+ image.setRGB(drawX + 0, drawY + 3, rgb);
+ image.setRGB(drawX + 1, drawY + 3, rgb);
+ image.setRGB(drawX + 2, drawY + 3, rgb);
+ image.setRGB(drawX + 3, drawY + 3, rgb);
+ }
+ }
+ }
+ }
+ else if (type == 9)
+ {
+ if (object.getMapSceneID() != -1)
+ {
+ Image spriteImage = scaledMapIcons.get(object.getMapSceneID());
+ graphics.drawImage(spriteImage, drawX, drawY, null);
+ continue;
+ }
+
+ int hash = (localY << 7) + localX + (location.getId() << 14) + 0x4000_0000;
+ if (object.getAnInt2088() == 0)
+ {
+ hash -= Integer.MIN_VALUE;
+ }
+
+ if ((hash >> 29 & 3) != 2)
+ {
+ continue;
+ }
+
+ int rgb = 0xEE_EEEE;
+ if (hash > 0)
+ {
+ rgb = 0xEE_0000;
+ }
+
+ if (rotation != 0 && rotation != 2)
+ {
+ image.setRGB(drawX + 0, drawY + 0, rgb);
+ image.setRGB(drawX + 1, drawY + 1, rgb);
+ image.setRGB(drawX + 2, drawY + 2, rgb);
+ image.setRGB(drawX + 3, drawY + 3, rgb);
+ }
+ else
+ {
+ image.setRGB(drawX + 0, drawY + 3, rgb);
+ image.setRGB(drawX + 1, drawY + 2, rgb);
+ image.setRGB(drawX + 2, drawY + 1, rgb);
+ image.setRGB(drawX + 3, drawY + 0, rgb);
+ }
+ }
+ else if (type == 22 || (type >= 9 && type <= 11))
+ {
+ // ground object
+ if (object.getMapSceneID() != -1)
+ {
+ Image spriteImage = scaledMapIcons.get(object.getMapSceneID());
+ graphics.drawImage(spriteImage, drawX, drawY, null);
+ }
+ }
+ }
+
+ graphics.dispose();
+ }
+
+ private void drawObjects(BufferedImage image, int z)
+ {
+ for (Region region : regionLoader.getRegions())
+ {
+ int baseX = region.getBaseX();
+ int baseY = region.getBaseY();
+
+ // to pixel X
+ int drawBaseX = baseX - regionLoader.getLowestX().getBaseX();
+
+ // to pixel Y. top most y is 0, but the top most
+ // region has the greatest y, so invert
+ int drawBaseY = regionLoader.getHighestY().getBaseY() - baseY;
+
+ drawObjects(image, drawBaseX, drawBaseY, region, z);
+ }
+ }
+
+ private void drawMapIcons(BufferedImage image, int drawBaseX, int drawBaseY, Region region, int z)
+ {
+ int baseX = region.getBaseX();
+ int baseY = region.getBaseY();
+
+ Graphics2D graphics = image.createGraphics();
+
+ drawMapIcons(graphics, region, z, drawBaseX, drawBaseY);
+
+ if (labelRegions)
+ {
+ graphics.setColor(Color.WHITE);
+ String str = baseX + "," + baseY + " (" + region.getRegionX() + "," + region.getRegionY() + ")";
+ graphics.drawString(str, drawBaseX * MAP_SCALE, drawBaseY * MAP_SCALE + graphics.getFontMetrics().getHeight());
+ }
+
+ if (outlineRegions)
+ {
+ graphics.setColor(Color.WHITE);
+ graphics.drawRect(drawBaseX * MAP_SCALE, drawBaseY * MAP_SCALE, Region.X * MAP_SCALE, Region.Y * MAP_SCALE);
+ }
+
+ graphics.dispose();
+ }
+
+ private void drawMapIcons(BufferedImage image, int z)
+ {
+ // map icons
+ for (Region region : regionLoader.getRegions())
+ {
+ int baseX = region.getBaseX();
+ int baseY = region.getBaseY();
+
+ // to pixel X
+ int drawBaseX = baseX - regionLoader.getLowestX().getBaseX();
+
+ // to pixel Y. top most y is 0, but the top most
+ // region has the greatest y, so invert
+ int drawBaseY = regionLoader.getHighestY().getBaseY() - baseY;
+
+ drawMapIcons(image, drawBaseX, drawBaseY, region, z);
+ }
+ }
+
+ private ObjectDefinition findObject(int id)
+ {
+ return objectManager.getObject(id);
+ }
+
+ private int packHsl(int var0, int var1, int var2)
+ {
+ if (var2 > 179)
+ {
+ var1 /= 2;
+ }
+
+ if (var2 > 192)
+ {
+ var1 /= 2;
+ }
+
+ if (var2 > 217)
+ {
+ var1 /= 2;
+ }
+
+ if (var2 > 243)
+ {
+ var1 /= 2;
+ }
+
+ int var3 = (var1 / 32 << 7) + (var0 / 4 << 10) + var2 / 2;
+ return var3;
+ }
+
+ static int method1792(int var0, int var1)
+ {
+ if (var0 == -1)
+ {
+ return 12345678;
+ }
+ else
+ {
+ var1 = (var0 & 127) * var1 / 128;
+ if (var1 < 2)
+ {
+ var1 = 2;
+ }
+ else if (var1 > 126)
+ {
+ var1 = 126;
+ }
+
+ return (var0 & 65408) + var1;
+ }
+ }
+
+ static final int adjustHSLListness0(int var0, int var1)
+ {
+ if (var0 == -2)
+ {
+ return 12345678;
+ }
+ else if (var0 == -1)
+ {
+ if (var1 < 2)
+ {
+ var1 = 2;
+ }
+ else if (var1 > 126)
+ {
+ var1 = 126;
+ }
+
+ return var1;
+ }
+ else
+ {
+ var1 = (var0 & 127) * var1 / 128;
+ if (var1 < 2)
+ {
+ var1 = 2;
+ }
+ else if (var1 > 126)
+ {
+ var1 = 126;
+ }
+
+ return (var0 & 65408) + var1;
+ }
+ }
+
+ private void drawMapSquare(int[][] pixels, int x, int y, int rgb)
+ {
+ x *= MAP_SCALE;
+ y *= MAP_SCALE;
+
+ for (int i = 0; i < MAP_SCALE; ++i)
+ {
+ for (int j = 0; j < MAP_SCALE; ++j)
+ {
+ pixels[x + i][y + j] = rgb;
+ }
+ }
+ }
+
+ private void drawMapIcons(Graphics2D graphics, Region region, int z, int drawBaseX, int drawBaseY)
+ {
+ for (Location location : region.getLocations())
+ {
+ int localZ = location.getPosition().getZ();
+ if (z != 0 && localZ != z)
+ {
+ // draw all icons on z=0
+ continue;
+ }
+
+ ObjectDefinition od = findObject(location.getId());
+
+ assert od != null;
+
+ int localX = location.getPosition().getX() - region.getBaseX();
+ int localY = location.getPosition().getY() - region.getBaseY();
+
+ int drawX = drawBaseX + localX;
+ int drawY = drawBaseY + (Region.Y - 1 - localY);
+
+ if (od.getMapAreaId() != -1)
+ {
+ AreaDefinition area = areas.getArea(od.getMapAreaId());
+ assert area != null;
+
+ int spriteId = area.spriteId;
+
+ SpriteDefinition sprite = sprites.findSprite(spriteId, 0);
+ assert sprite != null;
+
+ BufferedImage iconImage = sprites.getSpriteImage(sprite);
+ graphics.drawImage(iconImage, drawX * MAP_SCALE, drawY * MAP_SCALE, null);
+ }
+ }
+ }
+
+ private void loadRegions(Store store) throws IOException
+ {
+ regionLoader = new RegionLoader(store);
+ regionLoader.loadRegions();
+ regionLoader.calculateBounds();
+
+ logger.info("North most region: {}", regionLoader.getLowestY().getBaseY());
+ logger.info("South most region: {}", regionLoader.getHighestY().getBaseY());
+ logger.info("West most region: {}", regionLoader.getLowestX().getBaseX());
+ logger.info("East most region: {}", regionLoader.getHighestX().getBaseX());
+ }
+
+ private void loadUnderlays(Store store) throws IOException
+ {
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.CONFIGS);
+ Archive archive = index.getArchive(ConfigType.UNDERLAY.getId());
+
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ for (FSFile file : files.getFiles())
+ {
+ UnderlayLoader loader = new UnderlayLoader();
+ UnderlayDefinition underlay = loader.load(file.getFileId(), file.getContents());
+
+ underlays.put(underlay.getId(), underlay);
+ }
+ }
+
+ private UnderlayDefinition findUnderlay(int id)
+ {
+ return underlays.get(id);
+ }
+
+ private void loadOverlays(Store store) throws IOException
+ {
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.CONFIGS);
+ Archive archive = index.getArchive(ConfigType.OVERLAY.getId());
+
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ for (FSFile file : files.getFiles())
+ {
+ OverlayLoader loader = new OverlayLoader();
+ OverlayDefinition overlay = loader.load(file.getFileId(), file.getContents());
+
+ overlays.put(overlay.getId(), overlay);
+ }
+ }
+
+ private OverlayDefinition findOverlay(int id)
+ {
+ return overlays.get(id);
+ }
+
+ private void loadSprites() throws IOException
+ {
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.SPRITES);
+ final int mapsceneHash = Djb2.hash("mapscene");
+
+ for (Archive a : index.getArchives())
+ {
+ byte[] contents = a.decompress(storage.loadArchive(a));
+
+ SpriteLoader loader = new SpriteLoader();
+ SpriteDefinition[] sprites = loader.load(a.getArchiveId(), contents);
+
+ for (SpriteDefinition sprite : sprites)
+ {
+ if (sprite.getHeight() <= 0 || sprite.getWidth() <= 0)
+ {
+ continue;
+ }
+
+ if (a.getNameHash() == mapsceneHash)
+ {
+ BufferedImage spriteImage = new BufferedImage(sprite.getWidth(), sprite.getHeight(), BufferedImage.TYPE_INT_ARGB);
+ spriteImage.setRGB(0, 0, sprite.getWidth(), sprite.getHeight(), sprite.getPixels(), 0, sprite.getWidth());
+
+ // scale image down so it fits
+ Image scaledImage = spriteImage.getScaledInstance(MAPICON_MAX_WIDTH, MAPICON_MAX_HEIGHT, 0);
+
+ assert scaledMapIcons.containsKey(sprite.getFrame()) == false;
+ scaledMapIcons.put(sprite.getFrame(), scaledImage);
+ }
+ }
+ }
+ }
+
+}
diff --git a/cache/src/main/java/net/runelite/cache/NpcManager.java b/cache/src/main/java/net/runelite/cache/NpcManager.java
new file mode 100644
index 0000000000..3124eb455f
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/NpcManager.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import net.runelite.cache.definitions.NpcDefinition;
+import net.runelite.cache.definitions.exporters.NpcExporter;
+import net.runelite.cache.definitions.loaders.NpcLoader;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.ArchiveFiles;
+import net.runelite.cache.fs.FSFile;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+import net.runelite.cache.util.IDClass;
+
+public class NpcManager
+{
+ private final Store store;
+ private final Map npcs = new HashMap<>();
+
+ public NpcManager(Store store)
+ {
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ NpcLoader loader = new NpcLoader();
+
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.CONFIGS);
+ Archive archive = index.getArchive(ConfigType.NPC.getId());
+
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ for (FSFile f : files.getFiles())
+ {
+ NpcDefinition npc = loader.load(f.getFileId(), f.getContents());
+ npcs.put(f.getFileId(), npc);
+ }
+ }
+
+ public Collection getNpcs()
+ {
+ return Collections.unmodifiableCollection(npcs.values());
+ }
+
+ public NpcDefinition get(int npcId)
+ {
+ return npcs.get(npcId);
+ }
+
+ public void dump(File out) throws IOException
+ {
+ out.mkdirs();
+
+ for (NpcDefinition def : npcs.values())
+ {
+ NpcExporter exporter = new NpcExporter(def);
+
+ File targ = new File(out, def.id + ".json");
+ exporter.exportTo(targ);
+ }
+ }
+
+ public void java(File java) throws IOException
+ {
+ java.mkdirs();
+ try (IDClass ids = IDClass.create(java, "NpcID"))
+ {
+ for (NpcDefinition def : npcs.values())
+ {
+ if (def.name.equalsIgnoreCase("NULL"))
+ {
+ continue;
+ }
+
+ ids.add(def.name, def.id);
+ }
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/ObjectManager.java b/cache/src/main/java/net/runelite/cache/ObjectManager.java
new file mode 100644
index 0000000000..cb1372ed65
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/ObjectManager.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import net.runelite.cache.definitions.ObjectDefinition;
+import net.runelite.cache.definitions.exporters.ObjectExporter;
+import net.runelite.cache.definitions.loaders.ObjectLoader;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.ArchiveFiles;
+import net.runelite.cache.fs.FSFile;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+import net.runelite.cache.util.IDClass;
+
+public class ObjectManager
+{
+ private final Store store;
+ private final Map objects = new HashMap<>();
+
+ public ObjectManager(Store store)
+ {
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ ObjectLoader loader = new ObjectLoader();
+
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.CONFIGS);
+ Archive archive = index.getArchive(ConfigType.OBJECT.getId());
+
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ for (FSFile f : files.getFiles())
+ {
+ ObjectDefinition def = loader.load(f.getFileId(), f.getContents());
+ objects.put(f.getFileId(), def);
+ }
+ }
+
+ public Collection getObjects()
+ {
+ return Collections.unmodifiableCollection(objects.values());
+ }
+
+ public ObjectDefinition getObject(int id)
+ {
+ return objects.get(id);
+ }
+
+ public void dump(File out) throws IOException
+ {
+ out.mkdirs();
+
+ for (ObjectDefinition def : objects.values())
+ {
+ ObjectExporter exporter = new ObjectExporter(def);
+
+ File targ = new File(out, def.getId() + ".json");
+ exporter.exportTo(targ);
+ }
+ }
+
+ public void java(File java) throws IOException
+ {
+ java.mkdirs();
+ try (IDClass ids = IDClass.create(java, "ObjectID"))
+ {
+ try (IDClass nulls = IDClass.create(java, "NullObjectID"))
+ {
+ for (ObjectDefinition def : objects.values())
+ {
+ if ("null".equals(def.getName()))
+ {
+ nulls.add(def.getName(), def.getId());
+ }
+ else
+ {
+ ids.add(def.getName(), def.getId());
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/OverlayManager.java b/cache/src/main/java/net/runelite/cache/OverlayManager.java
new file mode 100644
index 0000000000..6940227c0f
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/OverlayManager.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018, 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.cache;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import net.runelite.cache.definitions.OverlayDefinition;
+import net.runelite.cache.definitions.loaders.OverlayLoader;
+import net.runelite.cache.definitions.providers.OverlayProvider;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.ArchiveFiles;
+import net.runelite.cache.fs.FSFile;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+
+public class OverlayManager implements OverlayProvider
+{
+ private final Store store;
+ private final Map overlays = new HashMap<>();
+
+ public OverlayManager(Store store)
+ {
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.CONFIGS);
+ Archive archive = index.getArchive(ConfigType.OVERLAY.getId());
+
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ for (FSFile file : files.getFiles())
+ {
+ OverlayLoader loader = new OverlayLoader();
+ OverlayDefinition overlay = loader.load(file.getFileId(), file.getContents());
+
+ overlays.put(overlay.getId(), overlay);
+ }
+ }
+
+ public Collection getOverlays()
+ {
+ return Collections.unmodifiableCollection(overlays.values());
+ }
+
+ @Override
+ public OverlayDefinition provide(int overlayId)
+ {
+ return overlays.get(overlayId);
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/SpriteManager.java b/cache/src/main/java/net/runelite/cache/SpriteManager.java
new file mode 100644
index 0000000000..a18dd4f6ba
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/SpriteManager.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache;
+
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.Multimap;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import net.runelite.cache.definitions.SpriteDefinition;
+import net.runelite.cache.definitions.exporters.SpriteExporter;
+import net.runelite.cache.definitions.loaders.SpriteLoader;
+import net.runelite.cache.definitions.providers.SpriteProvider;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+
+public class SpriteManager implements SpriteProvider
+{
+ private final Store store;
+ private final Multimap sprites = LinkedListMultimap.create();
+
+ public SpriteManager(Store store)
+ {
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.SPRITES);
+
+ for (Archive a : index.getArchives())
+ {
+ byte[] contents = a.decompress(storage.loadArchive(a));
+
+ SpriteLoader loader = new SpriteLoader();
+ SpriteDefinition[] defs = loader.load(a.getArchiveId(), contents);
+
+ for (SpriteDefinition sprite : defs)
+ {
+ sprites.put(sprite.getId(), sprite);
+ }
+ }
+ }
+
+ public Collection getSprites()
+ {
+ return Collections.unmodifiableCollection(sprites.values());
+ }
+
+ public SpriteDefinition findSprite(int spriteId, int frameId)
+ {
+ for (SpriteDefinition sprite : sprites.get(spriteId))
+ {
+ if (sprite.getFrame() == frameId)
+ {
+ return sprite;
+ }
+ }
+ return null;
+ }
+
+ public BufferedImage getSpriteImage(SpriteDefinition sprite)
+ {
+ BufferedImage image = new BufferedImage(sprite.getWidth(), sprite.getHeight(), BufferedImage.TYPE_INT_ARGB);
+ image.setRGB(0, 0, sprite.getWidth(), sprite.getHeight(), sprite.getPixels(), 0, sprite.getWidth());
+ return image;
+ }
+
+ public void export(File outDir) throws IOException
+ {
+ for (SpriteDefinition sprite : sprites.values())
+ {
+ // I don't know why this happens
+ if (sprite.getHeight() <= 0 || sprite.getWidth() <= 0)
+ {
+ continue;
+ }
+
+ SpriteExporter exporter = new SpriteExporter(sprite);
+ File png = new File(outDir, sprite.getId() + "-" + sprite.getFrame() + ".png");
+
+ exporter.exportTo(png);
+ }
+ }
+
+ @Override
+ public SpriteDefinition provide(int spriteId, int frameId)
+ {
+ return findSprite(spriteId, frameId);
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/StructManager.java b/cache/src/main/java/net/runelite/cache/StructManager.java
new file mode 100644
index 0000000000..bd816a4abb
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/StructManager.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2018, Joshua Filby
+ * 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.cache;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import net.runelite.cache.definitions.StructDefinition;
+import net.runelite.cache.definitions.loaders.StructLoader;
+import net.runelite.cache.definitions.providers.StructProvider;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.ArchiveFiles;
+import net.runelite.cache.fs.FSFile;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+
+public class StructManager implements StructProvider
+{
+ private final Store store;
+ private final Map structs = new HashMap<>();
+
+ public StructManager(Store store)
+ {
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ StructLoader loader = new StructLoader();
+
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.CONFIGS);
+ Archive archive = index.getArchive(ConfigType.STRUCT.getId());
+
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ for (FSFile f : files.getFiles())
+ {
+ StructDefinition def = loader.load(f.getFileId(), f.getContents());
+ structs.put(f.getFileId(), def);
+ }
+ }
+
+ public Map getStructs()
+ {
+ return Collections.unmodifiableMap(structs);
+ }
+
+ public StructDefinition getStruct(int structId)
+ {
+ return structs.get(structId);
+ }
+
+ @Override
+ public StructDefinition provide(int structId)
+ {
+ return getStruct(structId);
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/TextureManager.java b/cache/src/main/java/net/runelite/cache/TextureManager.java
new file mode 100644
index 0000000000..9eeb3504f2
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/TextureManager.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2017, 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.cache;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import net.runelite.cache.definitions.TextureDefinition;
+import net.runelite.cache.definitions.loaders.TextureLoader;
+import net.runelite.cache.definitions.providers.TextureProvider;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.ArchiveFiles;
+import net.runelite.cache.fs.FSFile;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+
+public class TextureManager implements TextureProvider
+{
+ private final Store store;
+ private final List textures = new ArrayList<>();
+
+ public TextureManager(Store store)
+ {
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.TEXTURES);
+ Archive archive = index.getArchive(0);
+
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ TextureLoader loader = new TextureLoader();
+
+ for (FSFile file : files.getFiles())
+ {
+ TextureDefinition texture = loader.load(file.getFileId(), file.getContents());
+ textures.add(texture);
+ }
+ }
+
+ public List getTextures()
+ {
+ return textures;
+ }
+
+ public TextureDefinition findTexture(int id)
+ {
+ for (TextureDefinition td : textures)
+ {
+ if (td.getId() == id)
+ {
+ return td;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public TextureDefinition[] provide()
+ {
+ return textures.toArray(new TextureDefinition[textures.size()]);
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/UnderlayManager.java b/cache/src/main/java/net/runelite/cache/UnderlayManager.java
new file mode 100644
index 0000000000..3bba2230a4
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/UnderlayManager.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018, 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.cache;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import net.runelite.cache.definitions.UnderlayDefinition;
+import net.runelite.cache.definitions.loaders.UnderlayLoader;
+import net.runelite.cache.definitions.providers.UnderlayProvider;
+import net.runelite.cache.fs.Archive;
+import net.runelite.cache.fs.ArchiveFiles;
+import net.runelite.cache.fs.FSFile;
+import net.runelite.cache.fs.Index;
+import net.runelite.cache.fs.Storage;
+import net.runelite.cache.fs.Store;
+
+public class UnderlayManager implements UnderlayProvider
+{
+ private final Store store;
+ private final Map underlays = new HashMap<>();
+
+ public UnderlayManager(Store store)
+ {
+ this.store = store;
+ }
+
+ public void load() throws IOException
+ {
+ Storage storage = store.getStorage();
+ Index index = store.getIndex(IndexType.CONFIGS);
+ Archive archive = index.getArchive(ConfigType.UNDERLAY.getId());
+
+ byte[] archiveData = storage.loadArchive(archive);
+ ArchiveFiles files = archive.getFiles(archiveData);
+
+ for (FSFile file : files.getFiles())
+ {
+ UnderlayLoader loader = new UnderlayLoader();
+ UnderlayDefinition underlay = loader.load(file.getFileId(), file.getContents());
+
+ underlays.put(underlay.getId(), underlay);
+ }
+ }
+
+ public Collection getUnderlays()
+ {
+ return Collections.unmodifiableCollection(underlays.values());
+ }
+
+ @Override
+ public UnderlayDefinition provide(int underlayId)
+ {
+ return underlays.get(underlayId);
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/AreaDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/AreaDefinition.java
new file mode 100644
index 0000000000..7abdbdfddd
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/AreaDefinition.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class AreaDefinition
+{
+ public int id;
+ public int[] field3292;
+ public int spriteId = -1;
+ public int field3294 = -1;
+ public String name;
+ public int field3296;
+ public int field3297 = -1;
+ public String[] field3298 = new String[5];
+ public int[] field3300;
+ public String field3308;
+ public byte[] field3309;
+ public int field3310;
+
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/ClientScript1Instruction.java b/cache/src/main/java/net/runelite/cache/definitions/ClientScript1Instruction.java
new file mode 100644
index 0000000000..b56c0a42d1
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/ClientScript1Instruction.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Abex
+ * 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.cache.definitions;
+
+import lombok.Data;
+import lombok.RequiredArgsConstructor;
+
+@Data
+public class ClientScript1Instruction
+{
+ @RequiredArgsConstructor
+ public enum Opcode
+ {
+ RETURN(0),
+ BOOSTED_SKILL_LEVELS(1),
+ REAL_SKILL_LEVELS(1),
+ SKILL_EXPERIENCE(1),
+ WIDGET_CONTAINS_ITEM_GET_QUANTITY(3),
+ VARP(1),
+ EXPERIENCE_AT_LEVEL_FOR_SKILL(1),
+ VARP_TIMES_469(1),
+ COMBAT_LEVEL(1),
+ TOTAL_LEVEL(0),
+ WIDGET_CONTAINS_ITEM_STAR(3),
+ RUN_ENERGY(0),
+ WEIGHT(0),
+ VARP_TESTBIT(2),
+ VARBIT(1),
+ MINUS(0),
+ DIV(0),
+ MUL(0),
+ WORLD_X(0),
+ WORLD_Y(1),
+ CONSTANT(1);
+
+ public final int argumentCount;
+ }
+
+ public Opcode opcode;
+ public int[] operands;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/EnumDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/EnumDefinition.java
new file mode 100644
index 0000000000..e9f1c11b02
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/EnumDefinition.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions;
+
+import lombok.Data;
+import net.runelite.cache.util.ScriptVarType;
+
+@Data
+public class EnumDefinition
+{
+ private int id;
+ private int[] intVals;
+ private ScriptVarType keyType;
+ private ScriptVarType valType;
+ private String defaultString = "null";
+ private int defaultInt;
+ private int size;
+ private int[] keys;
+ private String[] stringVals;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/FrameDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/FrameDefinition.java
new file mode 100644
index 0000000000..c31f0330ac
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/FrameDefinition.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class FrameDefinition
+{
+ public int id; // file id
+ public FramemapDefinition framemap;
+ public int[] translator_x;
+ public int[] translator_y;
+ public int[] translator_z;
+ public int translatorCount = -1;
+ public int[] indexFrameIds;
+ public boolean showing;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/FramemapDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/FramemapDefinition.java
new file mode 100644
index 0000000000..00669d6690
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/FramemapDefinition.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class FramemapDefinition
+{
+ public int id;
+ public int[] types;
+ public int[][] frameMaps;
+ public int length;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/InterfaceDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/InterfaceDefinition.java
new file mode 100644
index 0000000000..aede6d6d7b
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/InterfaceDefinition.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class InterfaceDefinition
+{
+ public int id = -1;
+ public boolean isIf3 = false;
+ public int type;
+ public int contentType;
+ public int originalX;
+ public int originalY;
+ public int originalWidth;
+ public int originalHeight;
+ public int widthMode;
+ public int heightMode;
+ public int xPositionMode;
+ public int yPositionMode;
+ public int parentId = -1;
+ public boolean isHidden;
+ public int scrollWidth;
+ public int scrollHeight;
+ public boolean noClickThrough;
+ public int spriteId;
+ public int textureId;
+ public boolean spriteTiling;
+ public int opacity;
+ public int borderType;
+ public int shadowColor;
+ public boolean flippedVertically;
+ public boolean flippedHorizontally;
+ public int modelType;
+ public int modelId;
+ public int offsetX2d;
+ public int offsetY2d;
+ public int rotationX;
+ public int rotationY;
+ public int rotationZ;
+ public int modelZoom;
+ public int animation;
+ public boolean orthogonal;
+ public int modelHeightOverride;
+ public int fontId;
+ public String text;
+ public int lineHeight;
+ public int xTextAlignment;
+ public int yTextAlignment;
+ public boolean textShadowed;
+ public int textColor;
+ public boolean filled;
+ public int lineWidth;
+ public boolean lineDirection;
+ public int clickMask;
+ public String name;
+ public String[] actions;
+ public int dragDeadZone;
+ public int dragDeadTime;
+ public boolean dragRenderBehavior;
+ public String targetVerb;
+ public Object[] onLoadListener;
+ public Object[] onMouseOverListener;
+ public Object[] onMouseLeaveListener;
+ public Object[] onTargetLeaveListener;
+ public Object[] onTargetEnterListener;
+ public Object[] onVarTransmitListener;
+ public Object[] onInvTransmitListener;
+ public Object[] onStatTransmitListener;
+ public Object[] onTimerListener;
+ public Object[] onOpListener;
+ public Object[] onMouseRepeatListener;
+ public Object[] onClickListener;
+ public Object[] onClickRepeatListener;
+ public Object[] onReleaseListener;
+ public Object[] onHoldListener;
+ public Object[] onDragListener;
+ public Object[] onDragCompleteListener;
+ public Object[] onScrollWheelListener;
+ public int[] varTransmitTriggers;
+ public int[] invTransmitTriggers;
+ public int[] statTransmitTriggers;
+ public boolean hasListener;
+
+ public int menuType;
+ // This is set to a siblings' child id when that widget should get a hover effect when this one is hovered
+ public int hoveredSiblingId;
+ public int[] alternateOperators;
+ public int[] alternateRhs;
+ public ClientScript1Instruction[][] clientScripts;
+ public int[] itemIds;
+ public int[] itemQuantities;
+ public int xPitch;
+ public int yPitch;
+ public int[] xOffsets;
+ public int[] yOffsets;
+ public int[] sprites;
+ public String[] configActions;
+ public String alternateText;
+ public int alternateTextColor;
+ public int hoveredTextColor;
+ public int alternateHoveredTextColor;
+ public int alternateSpriteId;
+ public int alternateModelId;
+ public int alternateAnimation;
+ public String spellName;
+ public String tooltip;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/InventoryDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/InventoryDefinition.java
new file mode 100644
index 0000000000..5239f5c093
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/InventoryDefinition.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class InventoryDefinition
+{
+ public int id;
+ public int size;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/ItemDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/ItemDefinition.java
new file mode 100644
index 0000000000..8f67622b24
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/ItemDefinition.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions;
+
+import java.util.Map;
+import lombok.Data;
+
+@Data
+public class ItemDefinition
+{
+ public final int id;
+
+ public String name = "null";
+
+ public int resizeX = 128;
+ public int resizeY = 128;
+ public int resizeZ = 128;
+
+ public int xan2d = 0;
+ public int yan2d = 0;
+ public int zan2d = 0;
+
+ public int cost = 1;
+ public boolean isTradeable;
+ public int stackable = 0;
+ public int inventoryModel;
+ public boolean members = false;
+
+ public short[] colorFind;
+ public short[] colorReplace;
+ public short[] textureFind;
+ public short[] textureReplace;
+
+ public int zoom2d = 2000;
+ public int xOffset2d = 0;
+ public int yOffset2d = 0;
+
+ public int ambient;
+ public int contrast;
+
+ public int[] countCo;
+ public int[] countObj;
+
+ public String[] options = new String[]
+ {
+ null, null, "Take", null, null
+ };
+
+ public String[] interfaceOptions = new String[]
+ {
+ null, null, null, null, "Drop"
+ };
+
+ public int maleModel0 = -1;
+ public int maleModel1 = -1;
+ public int maleModel2 = -1;
+ public int maleOffset;
+ public int maleHeadModel = -1;
+ public int maleHeadModel2 = -1;
+
+ public int femaleModel0 = -1;
+ public int femaleModel1 = -1;
+ public int femaleModel2 = -1;
+ public int femaleOffset;
+ public int femaleHeadModel = -1;
+ public int femaleHeadModel2 = -1;
+
+ public int notedID = -1;
+ public int notedTemplate = -1;
+
+ public int team;
+
+ public int shiftClickDropIndex = -2;
+
+ public int boughtId = -1;
+ public int boughtTemplateId = -1;
+
+ public int placeholderId = -1;
+ public int placeholderTemplateId = -1;
+
+ public Map params = null;
+
+ public void updateNote(ItemDefinition notedItem, ItemDefinition unnotedItem)
+ {
+ this.inventoryModel = notedItem.inventoryModel;
+ this.zoom2d = notedItem.zoom2d;
+ this.xan2d = notedItem.xan2d;
+ this.yan2d = notedItem.yan2d;
+ this.zan2d = notedItem.zan2d;
+ this.xOffset2d = notedItem.xOffset2d;
+ this.yOffset2d = notedItem.yOffset2d;
+ this.colorFind = notedItem.colorFind;
+ this.colorReplace = notedItem.colorReplace;
+ this.textureFind = notedItem.textureFind;
+ this.textureReplace = notedItem.textureReplace;
+ this.name = unnotedItem.name;
+ this.members = unnotedItem.members;
+ this.cost = unnotedItem.cost;
+ this.stackable = 1;
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/KitDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/KitDefinition.java
new file mode 100644
index 0000000000..bd2ee535f5
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/KitDefinition.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class KitDefinition
+{
+ private final int id;
+ public short[] recolorToReplace;
+ public short[] recolorToFind;
+ public short[] retextureToFind;
+ public short[] retextureToReplace;
+ public int bodyPartId = -1;
+ public int[] modelIds;
+ public int[] models = new int[]
+ {
+ -1, -1, -1, -1, -1
+ };
+ public boolean nonSelectable = false;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/LocationsDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/LocationsDefinition.java
new file mode 100644
index 0000000000..435cdd4746
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/LocationsDefinition.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import java.util.ArrayList;
+import java.util.List;
+import lombok.Data;
+import net.runelite.cache.region.Location;
+
+@Data
+public class LocationsDefinition
+{
+ private int regionX;
+ private int regionY;
+ private List locations = new ArrayList<>();
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/MapDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/MapDefinition.java
new file mode 100644
index 0000000000..b695b24cbe
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/MapDefinition.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class MapDefinition
+{
+ public static final int X = 64;
+ public static final int Y = 64;
+ public static final int Z = 4;
+
+ @Data
+ public static class Tile
+ {
+ public Integer height;
+ public int attrOpcode;
+ public byte settings;
+ public byte overlayId;
+ public byte overlayPath;
+ public byte overlayRotation;
+ public byte underlayId;
+ }
+
+ private int regionX;
+ private int regionY;
+ private Tile[][][] tiles = new Tile[Z][X][Y];
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java
new file mode 100644
index 0000000000..2259026a4d
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/ModelDefinition.java
@@ -0,0 +1,635 @@
+package net.runelite.cache.definitions;
+
+import java.util.Arrays;
+import lombok.Data;
+import net.runelite.cache.models.CircularAngle;
+import net.runelite.cache.models.FaceNormal;
+import net.runelite.cache.models.VertexNormal;
+
+@Data
+public class ModelDefinition
+{
+ public int id;
+
+ public int vertexCount = 0;
+ public int[] vertexPositionsX;
+ public int[] vertexPositionsY;
+ public int[] vertexPositionsZ;
+ public transient VertexNormal[] vertexNormals;
+
+ public int faceCount;
+ public int[] faceVertexIndices1;
+ public int[] faceVertexIndices2;
+ public int[] faceVertexIndices3;
+ public byte[] faceAlphas;
+ public short[] faceColors;
+ public byte[] faceRenderPriorities;
+ public byte[] faceRenderTypes;
+ public transient FaceNormal[] faceNormals;
+
+ public int textureTriangleCount;
+ public short[] textureTriangleVertexIndices1;
+ public short[] textureTriangleVertexIndices2;
+ public short[] textureTriangleVertexIndices3;
+ public transient float[][] faceTextureUCoordinates;
+ public transient float[][] faceTextureVCoordinates;
+ public short[] texturePrimaryColors;
+ public short[] faceTextures;
+ public byte[] textureCoordinates;
+ public byte[] textureRenderTypes;
+
+ public int[] vertexSkins;
+ public int[] faceSkins;
+
+ public byte priority;
+
+ public short[] aShortArray2574;
+ public short[] aShortArray2575;
+ public short[] aShortArray2577;
+ public short[] aShortArray2578;
+ public byte[] aByteArray2580;
+ public short[] aShortArray2586;
+
+ private transient int[][] vertexGroups;
+
+ private transient int[] origVX;
+ private transient int[] origVY;
+ private transient int[] origVZ;
+
+ public transient int maxPriority;
+
+ public static transient int animOffsetX, animOffsetY, animOffsetZ;
+
+ public void computeNormals()
+ {
+ if (this.vertexNormals != null)
+ {
+ return;
+ }
+
+ this.vertexNormals = new VertexNormal[this.vertexCount];
+
+ int var1;
+ for (var1 = 0; var1 < this.vertexCount; ++var1)
+ {
+ this.vertexNormals[var1] = new VertexNormal();
+ }
+
+ for (var1 = 0; var1 < this.faceCount; ++var1)
+ {
+ int vertexA = this.faceVertexIndices1[var1];
+ int vertexB = this.faceVertexIndices2[var1];
+ int vertexC = this.faceVertexIndices3[var1];
+
+ int xA = this.vertexPositionsX[vertexB] - this.vertexPositionsX[vertexA];
+ int yA = this.vertexPositionsY[vertexB] - this.vertexPositionsY[vertexA];
+ int zA = this.vertexPositionsZ[vertexB] - this.vertexPositionsZ[vertexA];
+
+ int xB = this.vertexPositionsX[vertexC] - this.vertexPositionsX[vertexA];
+ int yB = this.vertexPositionsY[vertexC] - this.vertexPositionsY[vertexA];
+ int zB = this.vertexPositionsZ[vertexC] - this.vertexPositionsZ[vertexA];
+
+ // Compute cross product
+ int var11 = yA * zB - yB * zA;
+ int var12 = zA * xB - zB * xA;
+ int var13 = xA * yB - xB * yA;
+
+ while (var11 > 8192 || var12 > 8192 || var13 > 8192 || var11 < -8192 || var12 < -8192 || var13 < -8192)
+ {
+ var11 >>= 1;
+ var12 >>= 1;
+ var13 >>= 1;
+ }
+
+ int length = (int) Math.sqrt((double) (var11 * var11 + var12 * var12 + var13 * var13));
+ if (length <= 0)
+ {
+ length = 1;
+ }
+
+ var11 = var11 * 256 / length;
+ var12 = var12 * 256 / length;
+ var13 = var13 * 256 / length;
+
+ byte var15;
+ if (this.faceRenderTypes == null)
+ {
+ var15 = 0;
+ }
+ else
+ {
+ var15 = this.faceRenderTypes[var1];
+ }
+
+ if (var15 == 0)
+ {
+ VertexNormal var16 = this.vertexNormals[vertexA];
+ var16.x += var11;
+ var16.y += var12;
+ var16.z += var13;
+ ++var16.magnitude;
+
+ var16 = this.vertexNormals[vertexB];
+ var16.x += var11;
+ var16.y += var12;
+ var16.z += var13;
+ ++var16.magnitude;
+
+ var16 = this.vertexNormals[vertexC];
+ var16.x += var11;
+ var16.y += var12;
+ var16.z += var13;
+ ++var16.magnitude;
+ }
+ else if (var15 == 1)
+ {
+ if (this.faceNormals == null)
+ {
+ this.faceNormals = new FaceNormal[this.faceCount];
+ }
+
+ FaceNormal var17 = this.faceNormals[var1] = new FaceNormal();
+ var17.x = var11;
+ var17.y = var12;
+ var17.z = var13;
+ }
+ }
+ }
+
+ /**
+ * Computes the UV coordinates for every three-vertex face that has a
+ * texture.
+ */
+ public void computeTextureUVCoordinates()
+ {
+ this.faceTextureUCoordinates = new float[faceCount][];
+ this.faceTextureVCoordinates = new float[faceCount][];
+
+ for (int i = 0; i < faceCount; i++)
+ {
+ int textureCoordinate;
+ if (textureCoordinates == null)
+ {
+ textureCoordinate = -1;
+ }
+ else
+ {
+ textureCoordinate = textureCoordinates[i];
+ }
+
+ int textureIdx;
+ if (faceTextures == null)
+ {
+ textureIdx = -1;
+ }
+ else
+ {
+ textureIdx = faceTextures[i] & 0xFFFF;
+ }
+
+ if (textureIdx != -1)
+ {
+ float[] u = new float[3];
+ float[] v = new float[3];
+
+ if (textureCoordinate == -1)
+ {
+ u[0] = 0.0F;
+ v[0] = 1.0F;
+
+ u[1] = 1.0F;
+ v[1] = 1.0F;
+
+ u[2] = 0.0F;
+ v[2] = 0.0F;
+ }
+ else
+ {
+ textureCoordinate &= 0xFF;
+
+ byte textureRenderType = 0;
+ if (textureRenderTypes != null)
+ {
+ textureRenderType = textureRenderTypes[textureCoordinate];
+ }
+
+ if (textureRenderType == 0)
+ {
+ int faceVertexIdx1 = faceVertexIndices1[i];
+ int faceVertexIdx2 = faceVertexIndices2[i];
+ int faceVertexIdx3 = faceVertexIndices3[i];
+
+ short triangleVertexIdx1 = textureTriangleVertexIndices1[textureCoordinate];
+ short triangleVertexIdx2 = textureTriangleVertexIndices2[textureCoordinate];
+ short triangleVertexIdx3 = textureTriangleVertexIndices3[textureCoordinate];
+
+ float triangleX = (float) vertexPositionsX[triangleVertexIdx1];
+ float triangleY = (float) vertexPositionsY[triangleVertexIdx1];
+ float triangleZ = (float) vertexPositionsZ[triangleVertexIdx1];
+
+ float f_882_ = (float) vertexPositionsX[triangleVertexIdx2] - triangleX;
+ float f_883_ = (float) vertexPositionsY[triangleVertexIdx2] - triangleY;
+ float f_884_ = (float) vertexPositionsZ[triangleVertexIdx2] - triangleZ;
+ float f_885_ = (float) vertexPositionsX[triangleVertexIdx3] - triangleX;
+ float f_886_ = (float) vertexPositionsY[triangleVertexIdx3] - triangleY;
+ float f_887_ = (float) vertexPositionsZ[triangleVertexIdx3] - triangleZ;
+ float f_888_ = (float) vertexPositionsX[faceVertexIdx1] - triangleX;
+ float f_889_ = (float) vertexPositionsY[faceVertexIdx1] - triangleY;
+ float f_890_ = (float) vertexPositionsZ[faceVertexIdx1] - triangleZ;
+ float f_891_ = (float) vertexPositionsX[faceVertexIdx2] - triangleX;
+ float f_892_ = (float) vertexPositionsY[faceVertexIdx2] - triangleY;
+ float f_893_ = (float) vertexPositionsZ[faceVertexIdx2] - triangleZ;
+ float f_894_ = (float) vertexPositionsX[faceVertexIdx3] - triangleX;
+ float f_895_ = (float) vertexPositionsY[faceVertexIdx3] - triangleY;
+ float f_896_ = (float) vertexPositionsZ[faceVertexIdx3] - triangleZ;
+
+ float f_897_ = f_883_ * f_887_ - f_884_ * f_886_;
+ float f_898_ = f_884_ * f_885_ - f_882_ * f_887_;
+ float f_899_ = f_882_ * f_886_ - f_883_ * f_885_;
+ float f_900_ = f_886_ * f_899_ - f_887_ * f_898_;
+ float f_901_ = f_887_ * f_897_ - f_885_ * f_899_;
+ float f_902_ = f_885_ * f_898_ - f_886_ * f_897_;
+ float f_903_ = 1.0F / (f_900_ * f_882_ + f_901_ * f_883_ + f_902_ * f_884_);
+
+ u[0] = (f_900_ * f_888_ + f_901_ * f_889_ + f_902_ * f_890_) * f_903_;
+ u[1] = (f_900_ * f_891_ + f_901_ * f_892_ + f_902_ * f_893_) * f_903_;
+ u[2] = (f_900_ * f_894_ + f_901_ * f_895_ + f_902_ * f_896_) * f_903_;
+
+ f_900_ = f_883_ * f_899_ - f_884_ * f_898_;
+ f_901_ = f_884_ * f_897_ - f_882_ * f_899_;
+ f_902_ = f_882_ * f_898_ - f_883_ * f_897_;
+ f_903_ = 1.0F / (f_900_ * f_885_ + f_901_ * f_886_ + f_902_ * f_887_);
+
+ v[0] = (f_900_ * f_888_ + f_901_ * f_889_ + f_902_ * f_890_) * f_903_;
+ v[1] = (f_900_ * f_891_ + f_901_ * f_892_ + f_902_ * f_893_) * f_903_;
+ v[2] = (f_900_ * f_894_ + f_901_ * f_895_ + f_902_ * f_896_) * f_903_;
+ }
+ }
+
+ this.faceTextureUCoordinates[i] = u;
+ this.faceTextureVCoordinates[i] = v;
+ }
+ }
+ }
+
+ public void computeAnimationTables()
+ {
+ if (this.vertexSkins != null)
+ {
+ int[] groupCounts = new int[256];
+ int numGroups = 0;
+ int var3, var4;
+
+ for (var3 = 0; var3 < this.vertexCount; ++var3)
+ {
+ var4 = this.vertexSkins[var3];
+ ++groupCounts[var4];
+ if (var4 > numGroups)
+ {
+ numGroups = var4;
+ }
+ }
+
+ this.vertexGroups = new int[numGroups + 1][];
+
+ for (var3 = 0; var3 <= numGroups; ++var3)
+ {
+ this.vertexGroups[var3] = new int[groupCounts[var3]];
+ groupCounts[var3] = 0;
+ }
+
+ for (var3 = 0; var3 < this.vertexCount; this.vertexGroups[var4][groupCounts[var4]++] = var3++)
+ {
+ var4 = this.vertexSkins[var3];
+ }
+
+ this.vertexSkins = null;
+ }
+
+ // triangleSkinValues is here
+ }
+
+ public void rotate(int orientation)
+ {
+ int sin = CircularAngle.SINE[orientation];
+ int cos = CircularAngle.COSINE[orientation];
+
+ assert vertexPositionsX.length == vertexPositionsY.length;
+ assert vertexPositionsY.length == vertexPositionsZ.length;
+
+ for (int i = 0; i < vertexPositionsX.length; ++i)
+ {
+ vertexPositionsX[i] = vertexPositionsX[i] * cos + vertexPositionsZ[i] * sin >> 16;
+ vertexPositionsZ[i] = vertexPositionsZ[i] * cos - vertexPositionsX[i] * sin >> 16;
+ }
+
+ reset();
+ }
+
+ public void resetAnim()
+ {
+ if (origVX == null)
+ {
+ return;
+ }
+
+ System.arraycopy(origVX, 0, vertexPositionsX, 0, origVX.length);
+ System.arraycopy(origVY, 0, vertexPositionsY, 0, origVY.length);
+ System.arraycopy(origVZ, 0, vertexPositionsZ, 0, origVZ.length);
+ }
+
+ public void animate(int type, int[] frameMap, int dx, int dy, int dz)
+ {
+ if (origVX == null)
+ {
+ origVX = Arrays.copyOf(vertexPositionsX, vertexPositionsX.length);
+ origVY = Arrays.copyOf(vertexPositionsY, vertexPositionsY.length);
+ origVZ = Arrays.copyOf(vertexPositionsZ, vertexPositionsZ.length);
+ }
+
+ final int[] verticesX = vertexPositionsX;
+ final int[] verticesY = vertexPositionsY;
+ final int[] verticesZ = vertexPositionsZ;
+ int var6 = frameMap.length;
+ int var7;
+ int var8;
+ int var11;
+ int var12;
+ if (type == 0)
+ {
+ var7 = 0;
+ animOffsetX = 0;
+ animOffsetY = 0;
+ animOffsetZ = 0;
+
+ for (var8 = 0; var8 < var6; ++var8)
+ {
+ int var9 = frameMap[var8];
+ if (var9 < this.vertexGroups.length)
+ {
+ int[] var10 = this.vertexGroups[var9];
+
+ for (var11 = 0; var11 < var10.length; ++var11)
+ {
+ var12 = var10[var11];
+ animOffsetX += verticesX[var12];
+ animOffsetY += verticesY[var12];
+ animOffsetZ += verticesZ[var12];
+ ++var7;
+ }
+ }
+ }
+
+ if (var7 > 0)
+ {
+ animOffsetX = dx + animOffsetX / var7;
+ animOffsetY = dy + animOffsetY / var7;
+ animOffsetZ = dz + animOffsetZ / var7;
+ }
+ else
+ {
+ animOffsetX = dx;
+ animOffsetY = dy;
+ animOffsetZ = dz;
+ }
+
+ }
+ else
+ {
+ int[] var18;
+ int var19;
+ if (type == 1)
+ {
+ for (var7 = 0; var7 < var6; ++var7)
+ {
+ var8 = frameMap[var7];
+ if (var8 < this.vertexGroups.length)
+ {
+ var18 = this.vertexGroups[var8];
+
+ for (var19 = 0; var19 < var18.length; ++var19)
+ {
+ var11 = var18[var19];
+ verticesX[var11] += dx;
+ verticesY[var11] += dy;
+ verticesZ[var11] += dz;
+ }
+ }
+ }
+
+ }
+ else if (type == 2)
+ {
+ for (var7 = 0; var7 < var6; ++var7)
+ {
+ var8 = frameMap[var7];
+ if (var8 < this.vertexGroups.length)
+ {
+ var18 = this.vertexGroups[var8];
+
+ for (var19 = 0; var19 < var18.length; ++var19)
+ {
+ var11 = var18[var19];
+ verticesX[var11] -= animOffsetX;
+ verticesY[var11] -= animOffsetY;
+ verticesZ[var11] -= animOffsetZ;
+ var12 = (dx & 255) * 8;
+ int var13 = (dy & 255) * 8;
+ int var14 = (dz & 255) * 8;
+ int var15;
+ int var16;
+ int var17;
+ if (var14 != 0)
+ {
+ var15 = CircularAngle.SINE[var14];
+ var16 = CircularAngle.COSINE[var14];
+ var17 = var15 * verticesY[var11] + var16 * verticesX[var11] >> 16;
+ verticesY[var11] = var16 * verticesY[var11] - var15 * verticesX[var11] >> 16;
+ verticesX[var11] = var17;
+ }
+
+ if (var12 != 0)
+ {
+ var15 = CircularAngle.SINE[var12];
+ var16 = CircularAngle.COSINE[var12];
+ var17 = var16 * verticesY[var11] - var15 * verticesZ[var11] >> 16;
+ verticesZ[var11] = var15 * verticesY[var11] + var16 * verticesZ[var11] >> 16;
+ verticesY[var11] = var17;
+ }
+
+ if (var13 != 0)
+ {
+ var15 = CircularAngle.SINE[var13];
+ var16 = CircularAngle.COSINE[var13];
+ var17 = var15 * verticesZ[var11] + var16 * verticesX[var11] >> 16;
+ verticesZ[var11] = var16 * verticesZ[var11] - var15 * verticesX[var11] >> 16;
+ verticesX[var11] = var17;
+ }
+
+ verticesX[var11] += animOffsetX;
+ verticesY[var11] += animOffsetY;
+ verticesZ[var11] += animOffsetZ;
+ }
+ }
+ }
+
+ }
+ else if (type == 3)
+ {
+ for (var7 = 0; var7 < var6; ++var7)
+ {
+ var8 = frameMap[var7];
+ if (var8 < this.vertexGroups.length)
+ {
+ var18 = this.vertexGroups[var8];
+
+ for (var19 = 0; var19 < var18.length; ++var19)
+ {
+ var11 = var18[var19];
+ verticesX[var11] -= animOffsetX;
+ verticesY[var11] -= animOffsetY;
+ verticesZ[var11] -= animOffsetZ;
+ verticesX[var11] = dx * verticesX[var11] / 128;
+ verticesY[var11] = dy * verticesY[var11] / 128;
+ verticesZ[var11] = dz * verticesZ[var11] / 128;
+ verticesX[var11] += animOffsetX;
+ verticesY[var11] += animOffsetY;
+ verticesZ[var11] += animOffsetZ;
+ }
+ }
+ }
+
+ }
+ else if (type == 5)
+ {
+ // alpha animation
+ }
+ }
+ }
+
+ public void method1493()
+ {
+ int var1;
+ for (var1 = 0; var1 < this.vertexCount; ++var1)
+ {
+ this.vertexPositionsZ[var1] = -this.vertexPositionsZ[var1];
+ }
+
+ for (var1 = 0; var1 < this.faceCount; ++var1)
+ {
+ int var2 = this.faceVertexIndices1[var1];
+ this.faceVertexIndices1[var1] = this.faceVertexIndices3[var1];
+ this.faceVertexIndices3[var1] = var2;
+ }
+
+ reset();
+ }
+
+ public void rotate1()
+ {
+ for (int var1 = 0; var1 < this.vertexCount; ++var1)
+ {
+ int var2 = this.vertexPositionsX[var1];
+ this.vertexPositionsX[var1] = this.vertexPositionsZ[var1];
+ this.vertexPositionsZ[var1] = -var2;
+ }
+
+ reset();
+ }
+
+ public void rotate2()
+ {
+ for (int var1 = 0; var1 < this.vertexCount; ++var1)
+ {
+ this.vertexPositionsX[var1] = -this.vertexPositionsX[var1];
+ this.vertexPositionsZ[var1] = -this.vertexPositionsZ[var1];
+ }
+
+ reset();
+ }
+
+ public void rotate3()
+ {
+ for (int var1 = 0; var1 < this.vertexCount; ++var1)
+ {
+ int var2 = this.vertexPositionsZ[var1];
+ this.vertexPositionsZ[var1] = this.vertexPositionsX[var1];
+ this.vertexPositionsX[var1] = -var2;
+ }
+
+ reset();
+ }
+
+ private void reset()
+ {
+ vertexNormals = null;
+ faceNormals = null;
+ faceTextureUCoordinates = faceTextureVCoordinates = null;
+ }
+
+ public void resize(int var1, int var2, int var3)
+ {
+ for (int var4 = 0; var4 < this.vertexCount; ++var4)
+ {
+ this.vertexPositionsX[var4] = this.vertexPositionsX[var4] * var1 / 128;
+ this.vertexPositionsY[var4] = var2 * this.vertexPositionsY[var4] / 128;
+ this.vertexPositionsZ[var4] = var3 * this.vertexPositionsZ[var4] / 128;
+ }
+
+ reset();
+ }
+
+ public void recolor(short var1, short var2)
+ {
+ for (int var3 = 0; var3 < this.faceCount; ++var3)
+ {
+ if (this.faceColors[var3] == var1)
+ {
+ this.faceColors[var3] = var2;
+ }
+ }
+
+ }
+
+ public void retexture(short var1, short var2)
+ {
+ if (this.faceTextures != null)
+ {
+ for (int var3 = 0; var3 < this.faceCount; ++var3)
+ {
+ if (this.faceTextures[var3] == var1)
+ {
+ this.faceTextures[var3] = var2;
+ }
+ }
+
+ }
+ }
+
+ public void move(int xOffset, int yOffset, int zOffset)
+ {
+ for (int i = 0; i < this.vertexCount; i++)
+ {
+ this.vertexPositionsX[i] += xOffset;
+ this.vertexPositionsY[i] += yOffset;
+ this.vertexPositionsZ[i] += zOffset;
+ }
+ this.reset();
+ }
+
+ public void computeMaxPriority()
+ {
+ if (faceRenderPriorities == null)
+ {
+ return;
+ }
+
+ for (int i = 0; i < faceCount; ++i)
+ {
+ if (faceRenderPriorities[i] > maxPriority)
+ {
+ maxPriority = faceRenderPriorities[i];
+ }
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/NpcDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/NpcDefinition.java
new file mode 100644
index 0000000000..8ba160c97a
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/NpcDefinition.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions;
+
+import java.util.Map;
+import lombok.Data;
+
+@Data
+public class NpcDefinition
+{
+
+ public final int id;
+ public short[] recolorToFind;
+ public int rotation = 32;
+ public String name = "null";
+ public short[] recolorToReplace;
+ public int[] models;
+ public int[] models_2;
+ public int stanceAnimation = -1;
+ public int anInt2165 = -1;
+ public int tileSpacesOccupied = 1;
+ public int walkAnimation = -1;
+ public short[] retextureToReplace;
+ public int rotate90RightAnimation = -1;
+ public boolean aBool2170 = true;
+ public int resizeX = 128;
+ public int contrast = 0;
+ public int rotate180Animation = -1;
+ public int varbitIndex = -1;
+ public String[] options = new String[5];
+ public boolean renderOnMinimap = true;
+ public int combatLevel = -1;
+ public int rotate90LeftAnimation = -1;
+ public int resizeY = 128;
+ public boolean hasRenderPriority = false;
+ public int ambient = 0;
+ public int headIcon = -1;
+ public int[] configs;
+ public short[] retextureToFind;
+ public int varpIndex = -1;
+ public boolean isClickable = true;
+ public int anInt2189 = -1;
+ public boolean aBool2190 = false;
+ public Map params = null;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/ObjectDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/ObjectDefinition.java
new file mode 100644
index 0000000000..007c9e2ebf
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/ObjectDefinition.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions;
+
+import java.util.Map;
+import lombok.Data;
+
+@Data
+public class ObjectDefinition
+{
+ private int id;
+ private short[] retextureToFind;
+ private int anInt2069 = 16;
+ private boolean isSolid = false;
+ private String name = "null";
+ private int[] objectModels;
+ private int[] objectTypes;
+ private short[] recolorToFind;
+ private int mapAreaId = -1;
+ private short[] textureToReplace;
+ private int sizeX = 1;
+ private int sizeY = 1;
+ private int anInt2083 = 0;
+ private int[] anIntArray2084;
+ private int offsetX = 0;
+ private boolean nonFlatShading = false;
+ private int anInt2088 = -1;
+ private int animationID = -1;
+ private int varbitID = -1;
+ private int ambient = 0;
+ private int contrast = 0;
+ private String[] actions = new String[5];
+ private int interactType = 2;
+ private int mapSceneID = -1;
+ private short[] recolorToReplace;
+ private boolean aBool2097 = true;
+ private int modelSizeX = 128;
+ private int modelSizeHeight = 128;
+ private int modelSizeY = 128;
+ private int objectID;
+ private int offsetHeight = 0;
+ private int offsetY = 0;
+ private boolean aBool2104 = false;
+ private int anInt2105 = -1;
+ private int anInt2106 = -1;
+ private int[] configChangeDest;
+ private boolean isRotated = false;
+ private int varpID = -1;
+ private int anInt2110 = -1;
+ private boolean aBool2111 = false;
+ private int anInt2112 = 0;
+ private int anInt2113 = 0;
+ private boolean blocksProjectile = true;
+ private Map params = null;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/OverlayDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/OverlayDefinition.java
new file mode 100644
index 0000000000..3846e99364
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/OverlayDefinition.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class OverlayDefinition
+{
+ private int id;
+ private int rgbColor = 0;
+ private int texture = -1;
+ private int secondaryRgbColor = -1;
+ private boolean hideUnderlay = true;
+
+ private transient int hue;
+ private transient int saturation;
+ private transient int lightness;
+
+ private transient int otherHue;
+ private transient int otherSaturation;
+ private transient int otherLightness;
+
+ public void calculateHsl()
+ {
+ if (secondaryRgbColor != -1)
+ {
+ calculateHsl(secondaryRgbColor);
+ otherHue = hue;
+ otherSaturation = saturation;
+ otherLightness = lightness;
+ }
+
+ calculateHsl(rgbColor);
+ }
+
+ private void calculateHsl(int var1)
+ {
+ double var2 = (double) (var1 >> 16 & 255) / 256.0D;
+ double var4 = (double) (var1 >> 8 & 255) / 256.0D;
+ double var6 = (double) (var1 & 255) / 256.0D;
+ double var8 = var2;
+ if (var4 < var2)
+ {
+ var8 = var4;
+ }
+
+ if (var6 < var8)
+ {
+ var8 = var6;
+ }
+
+ double var10 = var2;
+ if (var4 > var2)
+ {
+ var10 = var4;
+ }
+
+ if (var6 > var10)
+ {
+ var10 = var6;
+ }
+
+ double var12 = 0.0D;
+ double var14 = 0.0D;
+ double var16 = (var8 + var10) / 2.0D;
+ if (var10 != var8)
+ {
+ if (var16 < 0.5D)
+ {
+ var14 = (var10 - var8) / (var10 + var8);
+ }
+
+ if (var16 >= 0.5D)
+ {
+ var14 = (var10 - var8) / (2.0D - var10 - var8);
+ }
+
+ if (var2 == var10)
+ {
+ var12 = (var4 - var6) / (var10 - var8);
+ }
+ else if (var4 == var10)
+ {
+ var12 = 2.0D + (var6 - var2) / (var10 - var8);
+ }
+ else if (var10 == var6)
+ {
+ var12 = 4.0D + (var2 - var4) / (var10 - var8);
+ }
+ }
+
+ var12 /= 6.0D;
+ this.hue = (int) (256.0D * var12);
+ this.saturation = (int) (var14 * 256.0D);
+ this.lightness = (int) (var16 * 256.0D);
+ if (this.saturation < 0)
+ {
+ this.saturation = 0;
+ }
+ else if (this.saturation > 255)
+ {
+ this.saturation = 255;
+ }
+
+ if (this.lightness < 0)
+ {
+ this.lightness = 0;
+ }
+ else if (this.lightness > 255)
+ {
+ this.lightness = 255;
+ }
+
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/ScriptDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/ScriptDefinition.java
new file mode 100644
index 0000000000..cb57851b8c
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/ScriptDefinition.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions;
+
+import java.util.Map;
+import lombok.Data;
+
+@Data
+public class ScriptDefinition
+{
+ private int id;
+ private int[] instructions;
+ private int[] intOperands;
+ private String[] stringOperands;
+ private int intStackCount;
+ private int stringStackCount;
+ private int localIntCount;
+ private int localStringCount;
+ private Map[] switches;
+}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/barbarianassault/HealerTeam.java b/cache/src/main/java/net/runelite/cache/definitions/SequenceDefinition.java
similarity index 68%
rename from RuneLitePlus/src/main/java/net/runelite/client/plugins/barbarianassault/HealerTeam.java
rename to cache/src/main/java/net/runelite/cache/definitions/SequenceDefinition.java
index c82cb38e1e..3f280f31c2 100644
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/barbarianassault/HealerTeam.java
+++ b/cache/src/main/java/net/runelite/cache/definitions/SequenceDefinition.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, whartd
+ * Copyright (c) 2016-2017, Adam
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -22,23 +22,26 @@
* (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.client.plugins.barbarianassault;
+package net.runelite.cache.definitions;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import api.Point;
-import api.widgets.WidgetInfo;
+import lombok.Data;
-@Getter
-@AllArgsConstructor
-enum HealerTeam
+@Data
+public class SequenceDefinition
{
- TEAMMATE1(WidgetInfo.BA_HEAL_TEAMMATE1, new Point(28, 2), 115),
- TEAMMATE2(WidgetInfo.BA_HEAL_TEAMMATE2, new Point(26, 2), 115),
- TEAMMATE3(WidgetInfo.BA_HEAL_TEAMMATE3, new Point(26, 2), 115),
- TEAMMATE4(WidgetInfo.BA_HEAL_TEAMMATE4, new Point(25, 2), 115);
-
- private WidgetInfo teammate;
- private Point offset;
- private int width;
+ private final int id;
+ public int[] frameIDs; // top 16 bits are FrameDefinition ids
+ public int[] field3048;
+ public int[] frameLenghts;
+ public int rightHandItem = -1;
+ public int[] interleaveLeave;
+ public boolean stretches = false;
+ public int forcedPriority = 5;
+ public int maxLoops = 99;
+ public int[] field3056;
+ public int precedenceAnimating = -1;
+ public int leftHandItem = -1;
+ public int replyMode = 2;
+ public int frameStep = -1;
+ public int priority = -1;
}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/SpotAnimDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/SpotAnimDefinition.java
new file mode 100644
index 0000000000..e85b3918e2
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/SpotAnimDefinition.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class SpotAnimDefinition
+{
+ public int rotaton = 0;
+ public short[] textureToReplace;
+ public int id;
+ public short[] textureToFind;
+ public int resizeY = 128;
+ public int animationId = -1;
+ public short[] recolorToFind;
+ public short[] recolorToReplace;
+ public int resizeX = 128;
+ public int modelId;
+ public int ambient = 0;
+ public int contrast = 0;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/SpriteDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/SpriteDefinition.java
new file mode 100644
index 0000000000..632ea1e4e3
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/SpriteDefinition.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class SpriteDefinition
+{
+ private int id;
+ private int frame;
+ private int offsetX;
+ private int offsetY;
+ private int width;
+ private int height;
+ private int[] pixels;
+ private int maxWidth;
+ private int maxHeight;
+
+ public transient byte[] pixelIdx;
+ public transient int[] palette;
+
+ public void normalize()
+ {
+ if (this.width != this.maxWidth || this.height != this.maxHeight)
+ {
+ byte[] var1 = new byte[this.maxWidth * this.maxHeight];
+ int var2 = 0;
+
+ for (int var3 = 0; var3 < this.height; ++var3)
+ {
+ for (int var4 = 0; var4 < this.width; ++var4)
+ {
+ var1[var4 + (var3 + this.offsetY) * this.maxWidth + this.offsetX] = this.pixelIdx[var2++];
+ }
+ }
+
+ this.pixelIdx = var1;
+ this.width = this.maxWidth;
+ this.height = this.maxHeight;
+ this.offsetX = 0;
+ this.offsetY = 0;
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/StructDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/StructDefinition.java
new file mode 100644
index 0000000000..455ce9ea5e
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/StructDefinition.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018, Joshua Filby
+ * 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.cache.definitions;
+
+import java.util.Map;
+import lombok.Data;
+
+@Data
+public class StructDefinition
+{
+ public final int id;
+ public Map params = null;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/TextureDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/TextureDefinition.java
new file mode 100644
index 0000000000..d34bc5678a
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/TextureDefinition.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions;
+
+import lombok.Data;
+import net.runelite.cache.definitions.providers.SpriteProvider;
+
+@Data
+public class TextureDefinition
+{
+ public int field1777;
+ public boolean field1778;
+ private int id;
+ private int[] fileIds;
+ public int[] field1780;
+ public int[] field1781;
+ public int[] field1786;
+ public int field1782;
+ public int field1783;
+
+ public transient int[] pixels;
+
+ public boolean method2680(double var1, int var3, SpriteProvider spriteProvider)
+ {
+ int var5 = var3 * var3;
+ this.pixels = new int[var5];
+
+ for (int var6 = 0; var6 < this.fileIds.length; ++var6)
+ {
+ SpriteDefinition var7 = spriteProvider.provide(fileIds[var6], 0);
+ var7.normalize();
+ byte[] var8 = var7.pixelIdx;
+ int[] var9 = var7.palette;
+ int var10 = this.field1786[var6];
+
+ int var11;
+ int var12;
+ int var13;
+ int var14;
+ if ((var10 & -16777216) == 50331648)
+ {
+ var11 = var10 & 16711935;
+ var12 = var10 >> 8 & 255;
+
+ for (var13 = 0; var13 < var9.length; ++var13)
+ {
+ var14 = var9[var13];
+ if (var14 >> 8 == (var14 & 65535))
+ {
+ var14 &= 255;
+ var9[var13] = var11 * var14 >> 8 & 16711935 | var12 * var14 & 65280;
+ }
+ }
+ }
+
+ for (var11 = 0; var11 < var9.length; ++var11)
+ {
+ var9[var11] = adjustRGB(var9[var11], var1);
+ }
+
+ if (var6 == 0)
+ {
+ var11 = 0;
+ }
+ else
+ {
+ var11 = this.field1780[var6 - 1];
+ }
+
+ if (var11 == 0)
+ {
+ if (var3 == var7.getMaxWidth())
+ {
+ for (var12 = 0; var12 < var5; ++var12)
+ {
+ this.pixels[var12] = var9[var8[var12] & 255];
+ }
+ }
+ else if (var7.getMaxWidth() == 64 && var3 == 128)
+ {
+ var12 = 0;
+
+ for (var13 = 0; var13 < var3; ++var13)
+ {
+ for (var14 = 0; var14 < var3; ++var14)
+ {
+ this.pixels[var12++] = var9[var8[(var13 >> 1 << 6) + (var14 >> 1)] & 255];
+ }
+ }
+ }
+ else
+ {
+ if (var7.getMaxWidth() != 128 || var3 != 64)
+ {
+ throw new RuntimeException();
+ }
+
+ var12 = 0;
+
+ for (var13 = 0; var13 < var3; ++var13)
+ {
+ for (var14 = 0; var14 < var3; ++var14)
+ {
+ this.pixels[var12++] = var9[var8[(var14 << 1) + (var13 << 1 << 7)] & 255];
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ static int adjustRGB(int var0, double var1)
+ {
+ double var3 = (double) (var0 >> 16) / 256.0D;
+ double var5 = (double) (var0 >> 8 & 255) / 256.0D;
+ double var7 = (double) (var0 & 255) / 256.0D;
+ var3 = Math.pow(var3, var1);
+ var5 = Math.pow(var5, var1);
+ var7 = Math.pow(var7, var1);
+ int var9 = (int) (var3 * 256.0D);
+ int var10 = (int) (var5 * 256.0D);
+ int var11 = (int) (var7 * 256.0D);
+ return var11 + (var10 << 8) + (var9 << 16);
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/TrackDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/TrackDefinition.java
new file mode 100644
index 0000000000..136070e8f9
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/TrackDefinition.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class TrackDefinition
+{
+ public byte[] midi; // midi file contents
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/UnderlayDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/UnderlayDefinition.java
new file mode 100644
index 0000000000..7d3d8c2a47
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/UnderlayDefinition.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class UnderlayDefinition
+{
+ private int id;
+ private int color;
+
+ private transient int hue;
+ private transient int saturation;
+ private transient int lightness;
+ private transient int hueMultiplier;
+
+ public void calculateHsl()
+ {
+ int var1 = color;
+ double var2 = (double) (var1 >> 16 & 255) / 256.0D;
+ double var4 = (double) (var1 >> 8 & 255) / 256.0D;
+ double var6 = (double) (var1 & 255) / 256.0D;
+ double var8 = var2;
+ if (var4 < var2)
+ {
+ var8 = var4;
+ }
+
+ if (var6 < var8)
+ {
+ var8 = var6;
+ }
+
+ double var10 = var2;
+ if (var4 > var2)
+ {
+ var10 = var4;
+ }
+
+ if (var6 > var10)
+ {
+ var10 = var6;
+ }
+
+ double var12 = 0.0D;
+ double var14 = 0.0D;
+ double var16 = (var10 + var8) / 2.0D;
+ if (var8 != var10)
+ {
+ if (var16 < 0.5D)
+ {
+ var14 = (var10 - var8) / (var8 + var10);
+ }
+
+ if (var16 >= 0.5D)
+ {
+ var14 = (var10 - var8) / (2.0D - var10 - var8);
+ }
+
+ if (var2 == var10)
+ {
+ var12 = (var4 - var6) / (var10 - var8);
+ }
+ else if (var10 == var4)
+ {
+ var12 = 2.0D + (var6 - var2) / (var10 - var8);
+ }
+ else if (var10 == var6)
+ {
+ var12 = 4.0D + (var2 - var4) / (var10 - var8);
+ }
+ }
+
+ var12 /= 6.0D;
+ this.saturation = (int) (var14 * 256.0D);
+ this.lightness = (int) (var16 * 256.0D);
+ if (this.saturation < 0)
+ {
+ this.saturation = 0;
+ }
+ else if (this.saturation > 255)
+ {
+ this.saturation = 255;
+ }
+
+ if (this.lightness < 0)
+ {
+ this.lightness = 0;
+ }
+ else if (this.lightness > 255)
+ {
+ this.lightness = 255;
+ }
+
+ if (var16 > 0.5D)
+ {
+ this.hueMultiplier = (int) (var14 * (1.0D - var16) * 512.0D);
+ }
+ else
+ {
+ this.hueMultiplier = (int) (var14 * var16 * 512.0D);
+ }
+
+ if (this.hueMultiplier < 1)
+ {
+ this.hueMultiplier = 1;
+ }
+
+ this.hue = (int) ((double) this.hueMultiplier * var12);
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/VarbitDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/VarbitDefinition.java
new file mode 100644
index 0000000000..f50ae2ddf1
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/VarbitDefinition.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class VarbitDefinition
+{
+ private int id;
+ private int index;
+ private int leastSignificantBit;
+ private int mostSignificantBit;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/WorldMapDefinition.java b/cache/src/main/java/net/runelite/cache/definitions/WorldMapDefinition.java
new file mode 100644
index 0000000000..a8333263e5
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/WorldMapDefinition.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import java.util.List;
+import lombok.Data;
+import net.runelite.cache.region.Position;
+
+@Data
+public class WorldMapDefinition
+{
+ public String name;
+ public int field450;
+ public int field451;
+ public int fileId;
+ public int field453;
+ public int field454;
+ public int field456;
+ public boolean field457;
+ public List field458;
+ public String safeName;
+ public Position position;
+ public int field463;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/WorldMapType0.java b/cache/src/main/java/net/runelite/cache/definitions/WorldMapType0.java
new file mode 100644
index 0000000000..1294d0eb4d
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/WorldMapType0.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class WorldMapType0 implements WorldMapTypeBase
+{
+ public int field600;
+ public int field601;
+ public int field602;
+ public int field603;
+ public int field604;
+ public int field605;
+ public int field606;
+ public int field607;
+ public int field608;
+ public int field609;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/WorldMapType1.java b/cache/src/main/java/net/runelite/cache/definitions/WorldMapType1.java
new file mode 100644
index 0000000000..15a4f3e28d
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/WorldMapType1.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class WorldMapType1 implements WorldMapTypeBase
+{
+ public int field424;
+ public int field425;
+ public int field426;
+ public int field427;
+ public int field428;
+ public int field429;
+ public int field431;
+ public int field433;
+ public int field434;
+ public int field435;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/WorldMapType2.java b/cache/src/main/java/net/runelite/cache/definitions/WorldMapType2.java
new file mode 100644
index 0000000000..7b5326814d
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/WorldMapType2.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class WorldMapType2 implements WorldMapTypeBase
+{
+ public int field510;
+ public int field511;
+ public int field512;
+ public int field514;
+ public int field515;
+ public int field519;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/WorldMapType3.java b/cache/src/main/java/net/runelite/cache/definitions/WorldMapType3.java
new file mode 100644
index 0000000000..433c8a17fa
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/WorldMapType3.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+import lombok.Data;
+
+@Data
+public class WorldMapType3 implements WorldMapTypeBase
+{
+ public int field376;
+ public int field377;
+ public int field378;
+ public int field379;
+ public int field380;
+ public int field381;
+ public int field382;
+ public int field383;
+ public int field384;
+ public int field385;
+ public int field386;
+ public int field387;
+ public int field388;
+ public int field389;
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/WorldMapTypeBase.java b/cache/src/main/java/net/runelite/cache/definitions/WorldMapTypeBase.java
new file mode 100644
index 0000000000..d24d6d63f3
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/WorldMapTypeBase.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions;
+
+public interface WorldMapTypeBase
+{
+
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/exporters/InterfaceExporter.java b/cache/src/main/java/net/runelite/cache/definitions/exporters/InterfaceExporter.java
new file mode 100644
index 0000000000..b1020b9a59
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/exporters/InterfaceExporter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions.exporters;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import net.runelite.cache.definitions.InterfaceDefinition;
+
+public class InterfaceExporter
+{
+ private final InterfaceDefinition item;
+ private final Gson gson;
+
+ public InterfaceExporter(InterfaceDefinition item)
+ {
+ this.item = item;
+
+ GsonBuilder builder = new GsonBuilder()
+ .setPrettyPrinting();
+ gson = builder.create();
+ }
+
+ public String export()
+ {
+ return gson.toJson(item);
+ }
+
+ public void exportTo(File file) throws IOException
+ {
+ try (FileWriter fw = new FileWriter(file))
+ {
+ fw.write(export());
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/exporters/ItemExporter.java b/cache/src/main/java/net/runelite/cache/definitions/exporters/ItemExporter.java
new file mode 100644
index 0000000000..5dddff97ee
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/exporters/ItemExporter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions.exporters;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import net.runelite.cache.definitions.ItemDefinition;
+
+public class ItemExporter
+{
+ private final ItemDefinition item;
+ private final Gson gson;
+
+ public ItemExporter(ItemDefinition item)
+ {
+ this.item = item;
+
+ GsonBuilder builder = new GsonBuilder()
+ .setPrettyPrinting();
+ gson = builder.create();
+ }
+
+ public String export()
+ {
+ return gson.toJson(item);
+ }
+
+ public void exportTo(File file) throws IOException
+ {
+ try (FileWriter fw = new FileWriter(file))
+ {
+ fw.write(export());
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/exporters/NpcExporter.java b/cache/src/main/java/net/runelite/cache/definitions/exporters/NpcExporter.java
new file mode 100644
index 0000000000..eec1be340b
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/exporters/NpcExporter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions.exporters;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import net.runelite.cache.definitions.NpcDefinition;
+
+public class NpcExporter
+{
+ private final NpcDefinition npc;
+ private final Gson gson;
+
+ public NpcExporter(NpcDefinition npc)
+ {
+ this.npc = npc;
+
+ GsonBuilder builder = new GsonBuilder()
+ .setPrettyPrinting();
+ gson = builder.create();
+ }
+
+ public String export()
+ {
+ return gson.toJson(npc);
+ }
+
+ public void exportTo(File file) throws IOException
+ {
+ try (FileWriter fw = new FileWriter(file))
+ {
+ fw.write(export());
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/exporters/ObjectExporter.java b/cache/src/main/java/net/runelite/cache/definitions/exporters/ObjectExporter.java
new file mode 100644
index 0000000000..994bff625f
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/exporters/ObjectExporter.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions.exporters;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import net.runelite.cache.definitions.ObjectDefinition;
+
+public class ObjectExporter
+{
+ private final ObjectDefinition object;
+ private final Gson gson;
+
+ public ObjectExporter(ObjectDefinition object)
+ {
+ this.object = object;
+
+ GsonBuilder builder = new GsonBuilder()
+ .setPrettyPrinting();
+ gson = builder.create();
+ }
+
+ public String export()
+ {
+ return gson.toJson(object);
+ }
+
+ public void exportTo(File file) throws IOException
+ {
+ try (FileWriter fw = new FileWriter(file))
+ {
+ fw.write(export());
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/exporters/SpriteExporter.java b/cache/src/main/java/net/runelite/cache/definitions/exporters/SpriteExporter.java
new file mode 100644
index 0000000000..9c073d5e3a
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/exporters/SpriteExporter.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions.exporters;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import javax.imageio.ImageIO;
+import net.runelite.cache.definitions.SpriteDefinition;
+
+public class SpriteExporter
+{
+ private final SpriteDefinition sprite;
+
+ public SpriteExporter(SpriteDefinition sprite)
+ {
+ this.sprite = sprite;
+ }
+
+ public BufferedImage export()
+ {
+ BufferedImage bi = new BufferedImage(sprite.getWidth(), sprite.getHeight(), BufferedImage.TYPE_INT_ARGB);
+ bi.setRGB(0, 0, sprite.getWidth(), sprite.getHeight(), sprite.getPixels(), 0, sprite.getWidth());
+ return bi;
+ }
+
+ public void exportTo(File file) throws IOException
+ {
+ BufferedImage image = export();
+ ImageIO.write(image, "png", file);
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/AreaLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/AreaLoader.java
new file mode 100644
index 0000000000..7b47358678
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/AreaLoader.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.AreaDefinition;
+import net.runelite.cache.io.InputStream;
+
+public class AreaLoader
+{
+ public AreaDefinition load(byte[] b, int id)
+ {
+ InputStream in = new InputStream(b);
+ AreaDefinition def = new AreaDefinition();
+ def.id = id;
+
+ for (;;)
+ {
+ int opcode = in.readUnsignedByte();
+ if (opcode == 0)
+ {
+ break;
+ }
+
+ processOpcode(def, in, opcode);
+ }
+
+ return def;
+ }
+
+ private void processOpcode(AreaDefinition def, InputStream in, int opcode)
+ {
+ if (opcode == 1)
+ {
+ def.spriteId = in.readBigSmart2();
+ }
+ else if (opcode == 2)
+ {
+ def.field3294 = in.readBigSmart2();
+ }
+ else if (opcode == 3)
+ {
+ def.name = in.readString();
+ }
+ else if (opcode == 4)
+ {
+ def.field3296 = in.read24BitInt();
+ }
+ else if (opcode == 5)
+ {
+ in.read24BitInt();
+ }
+ else if (opcode == 6)
+ {
+ def.field3310 = in.readUnsignedByte();
+ }
+ else if (opcode == 7)
+ {
+ int var3 = in.readUnsignedByte();
+ if ((var3 & 1) == 0)
+ {
+ ;
+ }
+
+ if ((var3 & 2) == 2)
+ {
+ ;
+ }
+ }
+ else if (opcode == 8)
+ {
+ in.readUnsignedByte();
+ }
+ else if (opcode >= 10 && opcode <= 14)
+ {
+ def.field3298[opcode - 10] = in.readString();
+ }
+ else if (opcode == 15)
+ {
+ int var3 = in.readUnsignedByte();
+ def.field3300 = new int[var3 * 2];
+
+ int var4;
+ for (var4 = 0; var4 < var3 * 2; ++var4)
+ {
+ def.field3300[var4] = in.readShort();
+ }
+
+ in.readInt();
+ var4 = in.readUnsignedByte();
+ def.field3292 = new int[var4];
+
+ int var5;
+ for (var5 = 0; var5 < def.field3292.length; ++var5)
+ {
+ def.field3292[var5] = in.readInt();
+ }
+
+ def.field3309 = new byte[var3];
+
+ for (var5 = 0; var5 < var3; ++var5)
+ {
+ def.field3309[var5] = in.readByte();
+ }
+ }
+ else if (opcode == 16)
+ {
+
+ }
+ else if (opcode == 17)
+ {
+ def.field3308 = in.readString();
+ }
+ else if (opcode == 18)
+ {
+ in.readBigSmart2();
+ }
+ else if (opcode == 19)
+ {
+ def.field3297 = in.readUnsignedShort();
+ }
+ else if (opcode == 21)
+ {
+ in.readInt();
+ }
+ else if (opcode == 22)
+ {
+ in.readInt();
+ }
+ else if (opcode == 23)
+ {
+ in.readUnsignedByte();
+ in.readUnsignedByte();
+ in.readUnsignedByte();
+ }
+ else if (opcode == 24)
+ {
+ in.readShort();
+ in.readShort();
+ }
+ else if (opcode == 25)
+ {
+ in.readBigSmart2();
+ }
+ else if (opcode == 28)
+ {
+ in.readUnsignedByte();
+ }
+ else if (opcode == 29)
+ {
+ in.skip(1);
+// class257[] var6 = new class257[]
+// {
+// class257.field3538, class257.field3539, class257.field3540
+// };
+// this.field3299 = (class257) Item.method1751(var6, var1.readUnsignedByte());
+ }
+ else if (opcode == 30)
+ {
+ in.skip(1);
+// class239[] var7 = new class239[]
+// {
+// class239.field3273, class239.field3275, class239.field3271
+// };
+// this.field3306 = (class239) Item.method1751(var7, var1.readUnsignedByte());
+ }
+
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/EnumLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/EnumLoader.java
new file mode 100644
index 0000000000..83542c4fed
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/EnumLoader.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.EnumDefinition;
+import net.runelite.cache.io.InputStream;
+import net.runelite.cache.util.ScriptVarType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EnumLoader
+{
+ private static final Logger logger = LoggerFactory.getLogger(EnumLoader.class);
+
+ public EnumDefinition load(int id, byte[] b)
+ {
+ if (b.length == 1 && b[0] == 0)
+ {
+ return null;
+ }
+
+ EnumDefinition def = new EnumDefinition();
+ InputStream is = new InputStream(b);
+
+ def.setId(id);
+
+ for (;;)
+ {
+ int opcode = is.readUnsignedByte();
+ if (opcode == 0)
+ {
+ break;
+ }
+
+ processOp(opcode, def, is);
+ }
+
+ return def;
+ }
+
+ private void processOp(int opcode, EnumDefinition def, InputStream is)
+ {
+ switch (opcode)
+ {
+ case 1:
+ def.setKeyType(ScriptVarType.forCharKey((char) is.readUnsignedByte()));
+ break;
+ case 2:
+ def.setValType(ScriptVarType.forCharKey((char) is.readUnsignedByte()));
+ break;
+ case 3:
+ def.setDefaultString(is.readString());
+ break;
+ case 4:
+ def.setDefaultInt(is.readInt());
+ break;
+ case 5:
+ {
+ int size = is.readUnsignedShort();
+ int[] keys = new int[size];
+ String[] stringVals = new String[size];
+ for (int index = 0; index < size; ++index)
+ {
+ keys[index] = is.readInt();
+ stringVals[index] = is.readString();
+ }
+ def.setSize(size);
+ def.setKeys(keys);
+ def.setStringVals(stringVals);
+ break;
+ }
+ case 6:
+ {
+ int size = is.readUnsignedShort();
+ int[] keys = new int[size];
+ int[] intVals = new int[size];
+ for (int index = 0; index < size; ++index)
+ {
+ keys[index] = is.readInt();
+ intVals[index] = is.readInt();
+ }
+ def.setSize(size);
+ def.setKeys(keys);
+ def.setIntVals(intVals);
+ break;
+ }
+ default:
+ logger.warn("Unrecognized opcode {}", opcode);
+ break;
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/FrameLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/FrameLoader.java
new file mode 100644
index 0000000000..5ec512d62f
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/FrameLoader.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.FrameDefinition;
+import net.runelite.cache.definitions.FramemapDefinition;
+import net.runelite.cache.io.InputStream;
+
+public class FrameLoader
+{
+ public FrameDefinition load(FramemapDefinition framemap, int id, byte[] b)
+ {
+ FrameDefinition def = new FrameDefinition();
+ InputStream in = new InputStream(b);
+ InputStream data = new InputStream(b);
+
+ def.id = id;
+ def.framemap = framemap;
+
+ int framemapArchiveIndex = in.readUnsignedShort();
+ int length = in.readUnsignedByte();
+
+ data.skip(3 + length); // framemapArchiveIndex + length + data
+
+ int[] indexFrameIds = new int[500];
+ int[] scratchTranslatorX = new int[500];
+ int[] scratchTranslatorY = new int[500];
+ int[] scratchTranslatorZ = new int[500];
+
+ int lastI = -1;
+ int index = 0;
+ for (int i = 0; i < length; ++i)
+ {
+ int var9 = in.readUnsignedByte();
+
+ if (var9 <= 0)
+ {
+ continue;
+ }
+
+ if (def.framemap.types[i] != 0)
+ {
+ for (int var10 = i - 1; var10 > lastI; --var10)
+ {
+ if (def.framemap.types[var10] == 0)
+ {
+ indexFrameIds[index] = var10;
+ scratchTranslatorX[index] = 0;
+ scratchTranslatorY[index] = 0;
+ scratchTranslatorZ[index] = 0;
+ ++index;
+ break;
+ }
+ }
+ }
+
+ indexFrameIds[index] = i;
+ short var11 = 0;
+ if (def.framemap.types[i] == 3)
+ {
+ var11 = 128;
+ }
+
+ if ((var9 & 1) != 0)
+ {
+ scratchTranslatorX[index] = data.readShortSmart();
+ }
+ else
+ {
+ scratchTranslatorX[index] = var11;
+ }
+
+ if ((var9 & 2) != 0)
+ {
+ scratchTranslatorY[index] = data.readShortSmart();
+ }
+ else
+ {
+ scratchTranslatorY[index] = var11;
+ }
+
+ if ((var9 & 4) != 0)
+ {
+ scratchTranslatorZ[index] = data.readShortSmart();
+ }
+ else
+ {
+ scratchTranslatorZ[index] = var11;
+ }
+
+ lastI = i;
+ ++index;
+ if (def.framemap.types[i] == 5)
+ {
+ def.showing = true;
+ }
+ }
+
+ if (data.getOffset() != b.length)
+ {
+ throw new RuntimeException();
+ }
+
+ def.translatorCount = index;
+ def.indexFrameIds = new int[index];
+ def.translator_x = new int[index];
+ def.translator_y = new int[index];
+ def.translator_z = new int[index];
+
+ for (int i = 0; i < index; ++i)
+ {
+ def.indexFrameIds[i] = indexFrameIds[i];
+ def.translator_x[i] = scratchTranslatorX[i];
+ def.translator_y[i] = scratchTranslatorY[i];
+ def.translator_z[i] = scratchTranslatorZ[i];
+ }
+
+ return def;
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/FramemapLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/FramemapLoader.java
new file mode 100644
index 0000000000..b649af8e47
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/FramemapLoader.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.FramemapDefinition;
+import net.runelite.cache.io.InputStream;
+
+public class FramemapLoader
+{
+ public FramemapDefinition load(int id, byte[] b)
+ {
+ FramemapDefinition def = new FramemapDefinition();
+ InputStream in = new InputStream(b);
+
+ def.id = id;
+
+ def.length = in.readUnsignedByte();
+ def.types = new int[def.length];
+ def.frameMaps = new int[def.length][];
+
+ for (int i = 0; i < def.length; ++i)
+ {
+ def.types[i] = in.readUnsignedByte();
+ }
+
+ for (int i = 0; i < def.length; ++i)
+ {
+ def.frameMaps[i] = new int[in.readUnsignedByte()];
+ }
+
+ for (int i = 0; i < def.length; ++i)
+ {
+ for (int j = 0; j < def.frameMaps[i].length; ++j)
+ {
+ def.frameMaps[i][j] = in.readUnsignedByte();
+ }
+ }
+
+ return def;
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/InterfaceLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/InterfaceLoader.java
new file mode 100644
index 0000000000..69db420f9f
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/InterfaceLoader.java
@@ -0,0 +1,572 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions.loaders;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import net.runelite.cache.definitions.ClientScript1Instruction;
+import net.runelite.cache.definitions.InterfaceDefinition;
+import net.runelite.cache.io.InputStream;
+
+public class InterfaceLoader
+{
+ public InterfaceDefinition load(int id, byte[] b)
+ {
+ InterfaceDefinition iface = new InterfaceDefinition();
+ iface.id = id;
+ if (b[0] == -1)
+ {
+ decodeIf3(iface, new InputStream(b));
+ }
+ else
+ {
+ decodeIf1(iface, new InputStream(b));
+ }
+
+ return iface;
+ }
+
+ private void decodeIf1(InterfaceDefinition iface, InputStream var1)
+ {
+ iface.isIf3 = false;
+ iface.type = var1.readUnsignedByte();
+ iface.menuType = var1.readUnsignedByte();
+ iface.contentType = var1.readUnsignedShort();
+ iface.originalX = var1.readShort();
+ iface.originalY = var1.readShort();
+ iface.originalWidth = var1.readUnsignedShort();
+ iface.originalHeight = var1.readUnsignedShort();
+ iface.opacity = var1.readUnsignedByte();
+ iface.parentId = var1.readUnsignedShort();
+ if (iface.parentId == 0xFFFF)
+ {
+ iface.parentId = -1;
+ }
+ else
+ {
+ iface.parentId += iface.id & ~0xFFFF;
+ }
+
+ iface.hoveredSiblingId = var1.readUnsignedShort();
+ if (iface.hoveredSiblingId == 0xFFFF)
+ {
+ iface.hoveredSiblingId = -1;
+ }
+
+ int var2 = var1.readUnsignedByte();
+ int var3;
+ if (var2 > 0)
+ {
+ iface.alternateOperators = new int[var2];
+ iface.alternateRhs = new int[var2];
+
+ for (var3 = 0; var3 < var2; ++var3)
+ {
+ iface.alternateOperators[var3] = var1.readUnsignedByte();
+ iface.alternateRhs[var3] = var1.readUnsignedShort();
+ }
+ }
+
+ var3 = var1.readUnsignedByte();
+ int var4;
+ int var5;
+ int var6;
+ if (var3 > 0)
+ {
+ iface.clientScripts = new ClientScript1Instruction[var3][];
+
+ for (var4 = 0; var4 < var3; ++var4)
+ {
+ var5 = var1.readUnsignedShort();
+ int[] bytecode = new int[var5];
+
+ for (var6 = 0; var6 < var5; ++var6)
+ {
+ bytecode[var6] = var1.readUnsignedShort();
+ if (bytecode[var6] == 0xFFFF)
+ {
+ bytecode[var6] = -1;
+ }
+
+ List instructions = new ArrayList<>();
+ for (int i = 0; i < bytecode.length;)
+ {
+ ClientScript1Instruction ins = new ClientScript1Instruction();
+
+ ins.opcode = ClientScript1Instruction.Opcode.values()[bytecode[i++]];
+
+ int ac = ins.opcode.argumentCount;
+ ins.operands = Arrays.copyOfRange(bytecode, i, i + ac);
+
+ instructions.add(ins);
+ i += ac;
+ }
+ iface.clientScripts[var4] = instructions.toArray(new ClientScript1Instruction[0]);
+ }
+ }
+ }
+
+ if (iface.type == 0)
+ {
+ iface.scrollHeight = var1.readUnsignedShort();
+ iface.isHidden = var1.readUnsignedByte() == 1;
+ }
+
+ if (iface.type == 1)
+ {
+ var1.readUnsignedShort();
+ var1.readUnsignedByte();
+ }
+
+ if (iface.type == 2)
+ {
+ iface.itemIds = new int[iface.originalWidth * iface.originalHeight];
+ iface.itemQuantities = new int[iface.originalHeight * iface.originalWidth];
+ var4 = var1.readUnsignedByte();
+ if (var4 == 1)
+ {
+ iface.clickMask |= 268435456;
+ }
+
+ var5 = var1.readUnsignedByte();
+ if (var5 == 1)
+ {
+ iface.clickMask |= 1073741824;
+ }
+
+ var6 = var1.readUnsignedByte();
+ if (var6 == 1)
+ {
+ iface.clickMask |= Integer.MIN_VALUE;
+ }
+
+ int var7 = var1.readUnsignedByte();
+ if (var7 == 1)
+ {
+ iface.clickMask |= 536870912;
+ }
+
+ iface.xPitch = var1.readUnsignedByte();
+ iface.yPitch = var1.readUnsignedByte();
+ iface.xOffsets = new int[20];
+ iface.yOffsets = new int[20];
+ iface.sprites = new int[20];
+
+ int var8;
+ for (var8 = 0; var8 < 20; ++var8)
+ {
+ int var9 = var1.readUnsignedByte();
+ if (var9 == 1)
+ {
+ iface.xOffsets[var8] = var1.readShort();
+ iface.yOffsets[var8] = var1.readShort();
+ iface.sprites[var8] = var1.readInt();
+ }
+ else
+ {
+ iface.sprites[var8] = -1;
+ }
+ }
+
+ iface.configActions = new String[5];
+
+ for (var8 = 0; var8 < 5; ++var8)
+ {
+ String var11 = var1.readString();
+ if (var11.length() > 0)
+ {
+ iface.configActions[var8] = var11;
+ iface.clickMask |= 1 << var8 + 23;
+ }
+ }
+ }
+
+ if (iface.type == 3)
+ {
+ iface.filled = var1.readUnsignedByte() == 1;
+ }
+
+ if (iface.type == 4 || iface.type == 1)
+ {
+ iface.xTextAlignment = var1.readUnsignedByte();
+ iface.yTextAlignment = var1.readUnsignedByte();
+ iface.lineHeight = var1.readUnsignedByte();
+ iface.fontId = var1.readUnsignedShort();
+ if (iface.fontId == 0xFFFF)
+ {
+ iface.fontId = -1;
+ }
+
+ iface.textShadowed = var1.readUnsignedByte() == 1;
+ }
+
+ if (iface.type == 4)
+ {
+ iface.text = var1.readString();
+ iface.alternateText = var1.readString();
+ }
+
+ if (iface.type == 1 || iface.type == 3 || iface.type == 4)
+ {
+ iface.textColor = var1.readInt();
+ }
+
+ if (iface.type == 3 || iface.type == 4)
+ {
+ iface.alternateTextColor = var1.readInt();
+ iface.hoveredTextColor = var1.readInt();
+ iface.alternateHoveredTextColor = var1.readInt();
+ }
+
+ if (iface.type == 5)
+ {
+ iface.spriteId = var1.readInt();
+ iface.alternateSpriteId = var1.readInt();
+ }
+
+ if (iface.type == 6)
+ {
+ iface.modelType = 1;
+ iface.modelId = var1.readUnsignedShort();
+ if (iface.modelId == 0xFFFF)
+ {
+ iface.modelId = -1;
+ }
+
+ iface.alternateModelId = var1.readUnsignedShort();
+ if (iface.alternateModelId == 0xFFFF)
+ {
+ iface.alternateModelId = -1;
+ }
+
+ iface.animation = var1.readUnsignedShort();
+ if (iface.animation == 0xFFFF)
+ {
+ iface.animation = -1;
+ }
+
+ iface.alternateAnimation = var1.readUnsignedShort();
+ if (iface.alternateAnimation == 0xFFFF)
+ {
+ iface.alternateAnimation = -1;
+ }
+
+ iface.modelZoom = var1.readUnsignedShort();
+ iface.rotationX = var1.readUnsignedShort();
+ iface.rotationZ = var1.readUnsignedShort();
+ }
+
+ if (iface.type == 7)
+ {
+ iface.itemIds = new int[iface.originalWidth * iface.originalHeight];
+ iface.itemQuantities = new int[iface.originalWidth * iface.originalHeight];
+ iface.xTextAlignment = var1.readUnsignedByte();
+ iface.fontId = var1.readUnsignedShort();
+ if (iface.fontId == 0xFFFF)
+ {
+ iface.fontId = -1;
+ }
+
+ iface.textShadowed = var1.readUnsignedByte() == 1;
+ iface.textColor = var1.readInt();
+ iface.xPitch = var1.readShort();
+ iface.yPitch = var1.readShort();
+ var4 = var1.readUnsignedByte();
+ if (var4 == 1)
+ {
+ iface.clickMask |= 1073741824;
+ }
+
+ iface.configActions = new String[5];
+
+ for (var5 = 0; var5 < 5; ++var5)
+ {
+ String var10 = var1.readString();
+ if (var10.length() > 0)
+ {
+ iface.configActions[var5] = var10;
+ iface.clickMask |= 1 << var5 + 23;
+ }
+ }
+ }
+
+ if (iface.type == 8)
+ {
+ iface.text = var1.readString();
+ }
+
+ if (iface.menuType == 2 || iface.type == 2)
+ {
+ iface.targetVerb = var1.readString();
+ iface.spellName = var1.readString();
+ var4 = var1.readUnsignedShort() & 63;
+ iface.clickMask |= var4 << 11;
+ }
+
+ if (iface.menuType == 1 || iface.menuType == 4 || iface.menuType == 5 || iface.menuType == 6)
+ {
+ iface.tooltip = var1.readString();
+ if (iface.tooltip.length() == 0)
+ {
+ if (iface.menuType == 1)
+ {
+ iface.tooltip = "Ok";
+ }
+
+ if (iface.menuType == 4)
+ {
+ iface.tooltip = "Select";
+ }
+
+ if (iface.menuType == 5)
+ {
+ iface.tooltip = "Select";
+ }
+
+ if (iface.menuType == 6)
+ {
+ iface.tooltip = "Continue";
+ }
+ }
+ }
+
+ if (iface.menuType == 1 || iface.menuType == 4 || iface.menuType == 5)
+ {
+ iface.clickMask |= 4194304;
+ }
+
+ if (iface.menuType == 6)
+ {
+ iface.clickMask |= 1;
+ }
+
+ }
+
+ private void decodeIf3(InterfaceDefinition iface, InputStream var1)
+ {
+ var1.readUnsignedByte();
+ iface.isIf3 = true;
+ iface.type = var1.readUnsignedByte();
+ iface.contentType = var1.readUnsignedShort();
+ iface.originalX = var1.readShort();
+ iface.originalY = var1.readShort();
+ iface.originalWidth = var1.readUnsignedShort();
+ if (iface.type == 9)
+ {
+ iface.originalHeight = var1.readShort();
+ }
+ else
+ {
+ iface.originalHeight = var1.readUnsignedShort();
+ }
+
+ iface.widthMode = var1.readByte();
+ iface.heightMode = var1.readByte();
+ iface.xPositionMode = var1.readByte();
+ iface.yPositionMode = var1.readByte();
+ iface.parentId = var1.readUnsignedShort();
+ if (iface.parentId == 0xFFFF)
+ {
+ iface.parentId = -1;
+ }
+ else
+ {
+ iface.parentId += iface.id & ~0xFFFF;
+ }
+
+ iface.isHidden = var1.readUnsignedByte() == 1;
+ if (iface.type == 0)
+ {
+ iface.scrollWidth = var1.readUnsignedShort();
+ iface.scrollHeight = var1.readUnsignedShort();
+ iface.noClickThrough = var1.readUnsignedByte() == 1;
+ }
+
+ if (iface.type == 5)
+ {
+ iface.spriteId = var1.readInt();
+ iface.textureId = var1.readUnsignedShort();
+ iface.spriteTiling = var1.readUnsignedByte() == 1;
+ iface.opacity = var1.readUnsignedByte();
+ iface.borderType = var1.readUnsignedByte();
+ iface.shadowColor = var1.readInt();
+ iface.flippedVertically = var1.readUnsignedByte() == 1;
+ iface.flippedHorizontally = var1.readUnsignedByte() == 1;
+ }
+
+ if (iface.type == 6)
+ {
+ iface.modelType = 1;
+ iface.modelId = var1.readUnsignedShort();
+ if (iface.modelId == 0xFFFF)
+ {
+ iface.modelId = -1;
+ }
+
+ iface.offsetX2d = var1.readShort();
+ iface.offsetY2d = var1.readShort();
+ iface.rotationX = var1.readUnsignedShort();
+ iface.rotationZ = var1.readUnsignedShort();
+ iface.rotationY = var1.readUnsignedShort();
+ iface.modelZoom = var1.readUnsignedShort();
+ iface.animation = var1.readUnsignedShort();
+ if (iface.animation == 0xFFFF)
+ {
+ iface.animation = -1;
+ }
+
+ iface.orthogonal = var1.readUnsignedByte() == 1;
+ var1.readUnsignedShort();
+ if (iface.widthMode != 0)
+ {
+ iface.modelHeightOverride = var1.readUnsignedShort();
+ }
+
+ if (iface.heightMode != 0)
+ {
+ var1.readUnsignedShort();
+ }
+ }
+
+ if (iface.type == 4)
+ {
+ iface.fontId = var1.readUnsignedShort();
+ if (iface.fontId == 0xFFFF)
+ {
+ iface.fontId = -1;
+ }
+
+ iface.text = var1.readString();
+ iface.lineHeight = var1.readUnsignedByte();
+ iface.xTextAlignment = var1.readUnsignedByte();
+ iface.yTextAlignment = var1.readUnsignedByte();
+ iface.textShadowed = var1.readUnsignedByte() == 1;
+ iface.textColor = var1.readInt();
+ }
+
+ if (iface.type == 3)
+ {
+ iface.textColor = var1.readInt();
+ iface.filled = var1.readUnsignedByte() == 1;
+ iface.opacity = var1.readUnsignedByte();
+ }
+
+ if (iface.type == 9)
+ {
+ iface.lineWidth = var1.readUnsignedByte();
+ iface.textColor = var1.readInt();
+ iface.lineDirection = var1.readUnsignedByte() == 1;
+ }
+
+ iface.clickMask = var1.read24BitInt();
+ iface.name = var1.readString();
+ int var2 = var1.readUnsignedByte();
+ if (var2 > 0)
+ {
+ iface.actions = new String[var2];
+
+ for (int var3 = 0; var3 < var2; ++var3)
+ {
+ iface.actions[var3] = var1.readString();
+ }
+ }
+
+ iface.dragDeadZone = var1.readUnsignedByte();
+ iface.dragDeadTime = var1.readUnsignedByte();
+ iface.dragRenderBehavior = var1.readUnsignedByte() == 1;
+ iface.targetVerb = var1.readString();
+ iface.onLoadListener = this.decodeListener(iface, var1);
+ iface.onMouseOverListener = this.decodeListener(iface, var1);
+ iface.onMouseLeaveListener = this.decodeListener(iface, var1);
+ iface.onTargetLeaveListener = this.decodeListener(iface, var1);
+ iface.onTargetEnterListener = this.decodeListener(iface, var1);
+ iface.onVarTransmitListener = this.decodeListener(iface, var1);
+ iface.onInvTransmitListener = this.decodeListener(iface, var1);
+ iface.onStatTransmitListener = this.decodeListener(iface, var1);
+ iface.onTimerListener = this.decodeListener(iface, var1);
+ iface.onOpListener = this.decodeListener(iface, var1);
+ iface.onMouseRepeatListener = this.decodeListener(iface, var1);
+ iface.onClickListener = this.decodeListener(iface, var1);
+ iface.onClickRepeatListener = this.decodeListener(iface, var1);
+ iface.onReleaseListener = this.decodeListener(iface, var1);
+ iface.onHoldListener = this.decodeListener(iface, var1);
+ iface.onDragListener = this.decodeListener(iface, var1);
+ iface.onDragCompleteListener = this.decodeListener(iface, var1);
+ iface.onScrollWheelListener = this.decodeListener(iface, var1);
+ iface.varTransmitTriggers = this.decodeTriggers(var1);
+ iface.invTransmitTriggers = this.decodeTriggers(var1);
+ iface.statTransmitTriggers = this.decodeTriggers(var1);
+ }
+
+ private Object[] decodeListener(InterfaceDefinition iface, InputStream var1)
+ {
+ int var2 = var1.readUnsignedByte();
+ if (var2 == 0)
+ {
+ return null;
+ }
+ else
+ {
+ Object[] var3 = new Object[var2];
+
+ for (int var4 = 0; var4 < var2; ++var4)
+ {
+ int var5 = var1.readUnsignedByte();
+ if (var5 == 0)
+ {
+ var3[var4] = new Integer(var1.readInt());
+ }
+ else if (var5 == 1)
+ {
+ var3[var4] = var1.readString();
+ }
+ }
+
+ iface.hasListener = true;
+ return var3;
+ }
+ }
+
+ private int[] decodeTriggers(InputStream var1)
+ {
+ int var2 = var1.readUnsignedByte();
+ if (var2 == 0)
+ {
+ return null;
+ }
+ else
+ {
+ int[] var3 = new int[var2];
+
+ for (int var4 = 0; var4 < var2; ++var4)
+ {
+ var3[var4] = var1.readInt();
+ }
+
+ return var3;
+ }
+ }
+}
diff --git a/RuneLitePlus/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/InventoryLoader.java
similarity index 70%
rename from RuneLitePlus/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java
rename to cache/src/main/java/net/runelite/cache/definitions/loaders/InventoryLoader.java
index bf80dac615..b93cac48c0 100644
--- a/RuneLitePlus/src/main/java/net/runelite/client/plugins/rememberclan/RememberClanConfig.java
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/InventoryLoader.java
@@ -1,7 +1,5 @@
/*
- * Copyright (c) 2018, Infinitay
- * Copyright (c) 2018, Shaun Dreclin
- *
+ * Copyright (c) 2017, Adam
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -24,25 +22,33 @@
* (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.client.plugins.rememberclan;
+package net.runelite.cache.definitions.loaders;
-import net.runelite.client.config.Config;
-import net.runelite.client.config.ConfigGroup;
-import net.runelite.client.config.ConfigItem;
+import net.runelite.cache.definitions.InventoryDefinition;
+import net.runelite.cache.io.InputStream;
-@ConfigGroup("rememberclan")
-public interface RememberClanConfig extends Config
+public class InventoryLoader
{
- @ConfigItem(
- position = 1,
- keyName = "clanname",
- name = "Clan Name",
- description = "Clanname to always remember"
- )
- default String clanname()
+ public InventoryDefinition load(int id, byte[] b)
{
- return "";
+ InventoryDefinition def = new InventoryDefinition();
+ def.id = id;
+ InputStream is = new InputStream(b);
+
+ while (true)
+ {
+ int opcode = is.readUnsignedByte();
+ if (opcode == 0)
+ {
+ break;
+ }
+
+ if (opcode == 2)
+ {
+ def.size = is.readUnsignedShort();
+ }
+ }
+
+ return def;
}
-
-
}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/ItemLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/ItemLoader.java
new file mode 100644
index 0000000000..6cb6c9bd41
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/ItemLoader.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.ItemDefinition;
+import net.runelite.cache.io.InputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+
+public class ItemLoader
+{
+ private static final Logger logger = LoggerFactory.getLogger(ItemLoader.class);
+
+ public ItemDefinition load(int id, byte[] b)
+ {
+ ItemDefinition def = new ItemDefinition(id);
+ InputStream is = new InputStream(b);
+
+ while (true)
+ {
+ int opcode = is.readUnsignedByte();
+ if (opcode == 0)
+ {
+ break;
+ }
+
+ this.decodeValues(opcode, def, is);
+ }
+
+ return def;
+ }
+
+ private void decodeValues(int opcode, ItemDefinition def, InputStream stream)
+ {
+ if (opcode == 1)
+ {
+ def.inventoryModel = stream.readUnsignedShort();
+ }
+ else if (opcode == 2)
+ {
+ def.name = stream.readString();
+ }
+ else if (opcode == 4)
+ {
+ def.zoom2d = stream.readUnsignedShort();
+ }
+ else if (opcode == 5)
+ {
+ def.xan2d = stream.readUnsignedShort();
+ }
+ else if (opcode == 6)
+ {
+ def.yan2d = stream.readUnsignedShort();
+ }
+ else if (opcode == 7)
+ {
+ def.xOffset2d = stream.readUnsignedShort();
+ if (def.xOffset2d > 32767)
+ {
+ def.xOffset2d -= 65536;
+ }
+ }
+ else if (opcode == 8)
+ {
+ def.yOffset2d = stream.readUnsignedShort();
+ if (def.yOffset2d > 32767)
+ {
+ def.yOffset2d -= 65536;
+ }
+ }
+ else if (opcode == 11)
+ {
+ def.stackable = 1;
+ }
+ else if (opcode == 12)
+ {
+ def.cost = stream.readInt();
+ }
+ else if (opcode == 16)
+ {
+ def.members = true;
+ }
+ else if (opcode == 23)
+ {
+ def.maleModel0 = stream.readUnsignedShort();
+ def.maleOffset = stream.readUnsignedByte();
+ }
+ else if (opcode == 24)
+ {
+ def.maleModel1 = stream.readUnsignedShort();
+ }
+ else if (opcode == 25)
+ {
+ def.femaleModel0 = stream.readUnsignedShort();
+ def.femaleOffset = stream.readUnsignedByte();
+ }
+ else if (opcode == 26)
+ {
+ def.femaleModel1 = stream.readUnsignedShort();
+ }
+ else if (opcode >= 30 && opcode < 35)
+ {
+ def.options[opcode - 30] = stream.readString();
+ if (def.options[opcode - 30].equalsIgnoreCase("Hidden"))
+ {
+ def.options[opcode - 30] = null;
+ }
+ }
+ else if (opcode >= 35 && opcode < 40)
+ {
+ def.interfaceOptions[opcode - 35] = stream.readString();
+ }
+ else if (opcode == 40)
+ {
+ int var5 = stream.readUnsignedByte();
+ def.colorFind = new short[var5];
+ def.colorReplace = new short[var5];
+
+ for (int var4 = 0; var4 < var5; ++var4)
+ {
+ def.colorFind[var4] = (short) stream.readUnsignedShort();
+ def.colorReplace[var4] = (short) stream.readUnsignedShort();
+ }
+
+ }
+ else if (opcode == 41)
+ {
+ int var5 = stream.readUnsignedByte();
+ def.textureFind = new short[var5];
+ def.textureReplace = new short[var5];
+
+ for (int var4 = 0; var4 < var5; ++var4)
+ {
+ def.textureFind[var4] = (short) stream.readUnsignedShort();
+ def.textureReplace[var4] = (short) stream.readUnsignedShort();
+ }
+
+ }
+ else if (opcode == 42)
+ {
+ def.shiftClickDropIndex = stream.readByte();
+ }
+ else if (opcode == 65)
+ {
+ def.isTradeable = true;
+ }
+ else if (opcode == 78)
+ {
+ def.maleModel2 = stream.readUnsignedShort();
+ }
+ else if (opcode == 79)
+ {
+ def.femaleModel2 = stream.readUnsignedShort();
+ }
+ else if (opcode == 90)
+ {
+ def.maleHeadModel = stream.readUnsignedShort();
+ }
+ else if (opcode == 91)
+ {
+ def.femaleHeadModel = stream.readUnsignedShort();
+ }
+ else if (opcode == 92)
+ {
+ def.maleHeadModel2 = stream.readUnsignedShort();
+ }
+ else if (opcode == 93)
+ {
+ def.femaleHeadModel2 = stream.readUnsignedShort();
+ }
+ else if (opcode == 95)
+ {
+ def.zan2d = stream.readUnsignedShort();
+ }
+ else if (opcode == 97)
+ {
+ def.notedID = stream.readUnsignedShort();
+ }
+ else if (opcode == 98)
+ {
+ def.notedTemplate = stream.readUnsignedShort();
+ }
+ else if (opcode >= 100 && opcode < 110)
+ {
+ if (def.countObj == null)
+ {
+ def.countObj = new int[10];
+ def.countCo = new int[10];
+ }
+
+ def.countObj[opcode - 100] = stream.readUnsignedShort();
+ def.countCo[opcode - 100] = stream.readUnsignedShort();
+ }
+ else if (opcode == 110)
+ {
+ def.resizeX = stream.readUnsignedShort();
+ }
+ else if (opcode == 111)
+ {
+ def.resizeY = stream.readUnsignedShort();
+ }
+ else if (opcode == 112)
+ {
+ def.resizeZ = stream.readUnsignedShort();
+ }
+ else if (opcode == 113)
+ {
+ def.ambient = stream.readByte();
+ }
+ else if (opcode == 114)
+ {
+ def.contrast = stream.readByte();
+ }
+ else if (opcode == 115)
+ {
+ def.team = stream.readUnsignedByte();
+ }
+ else if (opcode == 139)
+ {
+ def.boughtId = stream.readUnsignedShort();
+ }
+ else if (opcode == 140)
+ {
+ def.boughtTemplateId = stream.readUnsignedShort();
+ }
+ else if (opcode == 148)
+ {
+ def.placeholderId = stream.readUnsignedShort();
+ }
+ else if (opcode == 149)
+ {
+ def.placeholderTemplateId = stream.readUnsignedShort();
+ }
+ else if (opcode == 249)
+ {
+ int length = stream.readUnsignedByte();
+
+ def.params = new HashMap<>(length);
+
+ for (int i = 0; i < length; i++)
+ {
+ boolean isString = stream.readUnsignedByte() == 1;
+ int key = stream.read24BitInt();
+ Object value;
+
+ if (isString)
+ {
+ value = stream.readString();
+ }
+
+ else
+ {
+ value = stream.readInt();
+ }
+
+ def.params.put(key, value);
+ }
+ }
+ else
+ {
+ logger.warn("Unrecognized opcode {}", opcode);
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/KitLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/KitLoader.java
new file mode 100644
index 0000000000..9bd3f89a2f
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/KitLoader.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.KitDefinition;
+import net.runelite.cache.io.InputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class KitLoader
+{
+ private static final Logger logger = LoggerFactory.getLogger(KitLoader.class);
+
+ public KitDefinition load(int id, byte[] b)
+ {
+ KitDefinition def = new KitDefinition(id);
+ InputStream is = new InputStream(b);
+
+ for (;;)
+ {
+ int opcode = is.readUnsignedByte();
+ if (opcode == 0)
+ {
+ break;
+ }
+
+ if (opcode == 1)
+ {
+ def.bodyPartId = is.readUnsignedByte();
+ }
+ else if (opcode == 2)
+ {
+ int length = is.readUnsignedByte();
+ def.modelIds = new int[length];
+
+ for (int index = 0; index < length; ++index)
+ {
+ def.modelIds[index] = is.readUnsignedShort();
+ }
+ }
+ else if (opcode == 3)
+ {
+ def.nonSelectable = true;
+ }
+ else if (opcode == 40)
+ {
+ int length = is.readUnsignedByte();
+ def.recolorToFind = new short[length];
+ def.recolorToReplace = new short[length];
+
+ for (int index = 0; index < length; ++index)
+ {
+ def.recolorToFind[index] = is.readShort();
+ def.recolorToReplace[index] = is.readShort();
+ }
+ }
+ else if (opcode == 41)
+ {
+ int length = is.readUnsignedByte();
+ def.retextureToFind = new short[length];
+ def.retextureToReplace = new short[length];
+
+ for (int index = 0; index < length; ++index)
+ {
+ def.retextureToFind[index] = is.readShort();
+ def.retextureToReplace[index] = is.readShort();
+ }
+ }
+ else if (opcode >= 60 && opcode < 70)
+ {
+ def.models[opcode - 60] = is.readShort();
+ }
+ }
+
+ return def;
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/LocationsLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/LocationsLoader.java
new file mode 100644
index 0000000000..4dab72cf77
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/LocationsLoader.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.LocationsDefinition;
+import net.runelite.cache.io.InputStream;
+import net.runelite.cache.region.Location;
+import net.runelite.cache.region.Position;
+
+public class LocationsLoader
+{
+ public LocationsDefinition load(int regionX, int regionY, byte[] b)
+ {
+ LocationsDefinition loc = new LocationsDefinition();
+ loc.setRegionX(regionX);
+ loc.setRegionY(regionY);
+ loadLocations(loc, b);
+ return loc;
+ }
+
+ private void loadLocations(LocationsDefinition loc, byte[] b)
+ {
+ InputStream buf = new InputStream(b);
+
+ int id = -1;
+ int idOffset;
+
+ while ((idOffset = buf.readUnsignedIntSmartShortCompat()) != 0)
+ {
+ id += idOffset;
+
+ int position = 0;
+ int positionOffset;
+
+ while ((positionOffset = buf.readUnsignedShortSmart()) != 0)
+ {
+ position += positionOffset - 1;
+
+ int localY = position & 0x3F;
+ int localX = position >> 6 & 0x3F;
+ int height = position >> 12 & 0x3;
+
+ int attributes = buf.readUnsignedByte();
+ int type = attributes >> 2;
+ int orientation = attributes & 0x3;
+
+ loc.getLocations().add(new Location(id, type, orientation, new Position(localX, localY, height)));
+ }
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/MapLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/MapLoader.java
new file mode 100644
index 0000000000..3224536388
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/MapLoader.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017, 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.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.MapDefinition;
+import net.runelite.cache.definitions.MapDefinition.Tile;
+import net.runelite.cache.io.InputStream;
+import static net.runelite.cache.region.Region.X;
+import static net.runelite.cache.region.Region.Y;
+import static net.runelite.cache.region.Region.Z;
+
+public class MapLoader
+{
+ public MapDefinition load(int regionX, int regionY, byte[] b)
+ {
+ MapDefinition map = new MapDefinition();
+ map.setRegionX(regionX);
+ map.setRegionY(regionY);
+ loadTerrain(map, b);
+ return map;
+ }
+
+ private void loadTerrain(MapDefinition map, byte[] buf)
+ {
+ Tile[][][] tiles = map.getTiles();
+
+ InputStream in = new InputStream(buf);
+
+ for (int z = 0; z < Z; z++)
+ {
+ for (int x = 0; x < X; x++)
+ {
+ for (int y = 0; y < Y; y++)
+ {
+ Tile tile = tiles[z][x][y] = new Tile();
+ while (true)
+ {
+ int attribute = in.readUnsignedByte();
+ if (attribute == 0)
+ {
+ break;
+ }
+ else if (attribute == 1)
+ {
+ int height = in.readUnsignedByte();
+ tile.height = height;
+ break;
+ }
+ else if (attribute <= 49)
+ {
+ tile.attrOpcode = attribute;
+ tile.overlayId = in.readByte();
+ tile.overlayPath = (byte) ((attribute - 2) / 4);
+ tile.overlayRotation = (byte) (attribute - 2 & 3);
+ }
+ else if (attribute <= 81)
+ {
+ tile.settings = (byte) (attribute - 49);
+ }
+ else
+ {
+ tile.underlayId = (byte) (attribute - 81);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java
new file mode 100644
index 0000000000..4529f8a069
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/ModelLoader.java
@@ -0,0 +1,750 @@
+package net.runelite.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.ModelDefinition;
+import net.runelite.cache.io.InputStream;
+
+public class ModelLoader
+{
+ public ModelDefinition load(int modelId, byte[] b)
+ {
+ ModelDefinition def = new ModelDefinition();
+ def.id = modelId;
+
+ if (b[b.length - 1] == -1 && b[b.length - 2] == -1)
+ {
+ this.load1(def, b);
+ }
+ else
+ {
+ this.load2(def, b);
+ }
+
+ def.computeNormals();
+ def.computeTextureUVCoordinates();
+ def.computeAnimationTables();
+
+ return def;
+ }
+
+ private void load1(ModelDefinition model, byte[] var1)
+ {
+ InputStream var2 = new InputStream(var1);
+ InputStream var24 = new InputStream(var1);
+ InputStream var3 = new InputStream(var1);
+ InputStream var28 = new InputStream(var1);
+ InputStream var6 = new InputStream(var1);
+ InputStream var55 = new InputStream(var1);
+ InputStream var51 = new InputStream(var1);
+ var2.setOffset(var1.length - 23);
+ int verticeCount = var2.readUnsignedShort();
+ int triangleCount = var2.readUnsignedShort();
+ int textureTriangleCount = var2.readUnsignedByte();
+ int var13 = var2.readUnsignedByte();
+ int modelPriority = var2.readUnsignedByte();
+ int var50 = var2.readUnsignedByte();
+ int var17 = var2.readUnsignedByte();
+ int modelTexture = var2.readUnsignedByte();
+ int modelVertexSkins = var2.readUnsignedByte();
+ int var20 = var2.readUnsignedShort();
+ int var21 = var2.readUnsignedShort();
+ int var42 = var2.readUnsignedShort();
+ int var22 = var2.readUnsignedShort();
+ int var38 = var2.readUnsignedShort();
+ int textureAmount = 0;
+ int var7 = 0;
+ int var29 = 0;
+ int position;
+ if (textureTriangleCount > 0)
+ {
+ model.textureRenderTypes = new byte[textureTriangleCount];
+ var2.setOffset(0);
+
+ for (position = 0; position < textureTriangleCount; ++position)
+ {
+ byte renderType = model.textureRenderTypes[position] = var2.readByte();
+ if (renderType == 0)
+ {
+ ++textureAmount;
+ }
+
+ if (renderType >= 1 && renderType <= 3)
+ {
+ ++var7;
+ }
+
+ if (renderType == 2)
+ {
+ ++var29;
+ }
+ }
+ }
+
+ position = textureTriangleCount + verticeCount;
+ int renderTypePos = position;
+ if (var13 == 1)
+ {
+ position += triangleCount;
+ }
+
+ int var49 = position;
+ position += triangleCount;
+ int priorityPos = position;
+ if (modelPriority == 255)
+ {
+ position += triangleCount;
+ }
+
+ int triangleSkinPos = position;
+ if (var17 == 1)
+ {
+ position += triangleCount;
+ }
+
+ int var35 = position;
+ if (modelVertexSkins == 1)
+ {
+ position += verticeCount;
+ }
+
+ int alphaPos = position;
+ if (var50 == 1)
+ {
+ position += triangleCount;
+ }
+
+ int var11 = position;
+ position += var22;
+ int texturePos = position;
+ if (modelTexture == 1)
+ {
+ position += triangleCount * 2;
+ }
+
+ int textureCoordPos = position;
+ position += var38;
+ int colorPos = position;
+ position += triangleCount * 2;
+ int var40 = position;
+ position += var20;
+ int var41 = position;
+ position += var21;
+ int var8 = position;
+ position += var42;
+ int var43 = position;
+ position += textureAmount * 6;
+ int var37 = position;
+ position += var7 * 6;
+ int var48 = position;
+ position += var7 * 6;
+ int var56 = position;
+ position += var7 * 2;
+ int var45 = position;
+ position += var7;
+ int var46 = position;
+ position += var7 * 2 + var29 * 2;
+ model.vertexCount = verticeCount;
+ model.faceCount = triangleCount;
+ model.textureTriangleCount = textureTriangleCount;
+ model.vertexPositionsX = new int[verticeCount];
+ model.vertexPositionsY = new int[verticeCount];
+ model.vertexPositionsZ = new int[verticeCount];
+ model.faceVertexIndices1 = new int[triangleCount];
+ model.faceVertexIndices2 = new int[triangleCount];
+ model.faceVertexIndices3 = new int[triangleCount];
+ if (modelVertexSkins == 1)
+ {
+ model.vertexSkins = new int[verticeCount];
+ }
+
+ if (var13 == 1)
+ {
+ model.faceRenderTypes = new byte[triangleCount];
+ }
+
+ if (modelPriority == 255)
+ {
+ model.faceRenderPriorities = new byte[triangleCount];
+ }
+ else
+ {
+ model.priority = (byte) modelPriority;
+ }
+
+ if (var50 == 1)
+ {
+ model.faceAlphas = new byte[triangleCount];
+ }
+
+ if (var17 == 1)
+ {
+ model.faceSkins = new int[triangleCount];
+ }
+
+ if (modelTexture == 1)
+ {
+ model.faceTextures = new short[triangleCount];
+ }
+
+ if (modelTexture == 1 && textureTriangleCount > 0)
+ {
+ model.textureCoordinates = new byte[triangleCount];
+ }
+
+ model.faceColors = new short[triangleCount];
+ if (textureTriangleCount > 0)
+ {
+ model.textureTriangleVertexIndices1 = new short[textureTriangleCount];
+ model.textureTriangleVertexIndices2 = new short[textureTriangleCount];
+ model.textureTriangleVertexIndices3 = new short[textureTriangleCount];
+ if (var7 > 0)
+ {
+ model.aShortArray2574 = new short[var7];
+ model.aShortArray2575 = new short[var7];
+ model.aShortArray2586 = new short[var7];
+ model.aShortArray2577 = new short[var7];
+ model.aByteArray2580 = new byte[var7];
+ model.aShortArray2578 = new short[var7];
+ }
+
+ if (var29 > 0)
+ {
+ model.texturePrimaryColors = new short[var29];
+ }
+ }
+
+ var2.setOffset(textureTriangleCount);
+ var24.setOffset(var40);
+ var3.setOffset(var41);
+ var28.setOffset(var8);
+ var6.setOffset(var35);
+ int vX = 0;
+ int vY = 0;
+ int vZ = 0;
+
+ int vertexZOffset;
+ int var10;
+ int vertexYOffset;
+ int var15;
+ int point;
+ for (point = 0; point < verticeCount; ++point)
+ {
+ int vertexFlags = var2.readUnsignedByte();
+ int vertexXOffset = 0;
+ if ((vertexFlags & 1) != 0)
+ {
+ vertexXOffset = var24.readShortSmart();
+ }
+
+ vertexYOffset = 0;
+ if ((vertexFlags & 2) != 0)
+ {
+ vertexYOffset = var3.readShortSmart();
+ }
+
+ vertexZOffset = 0;
+ if ((vertexFlags & 4) != 0)
+ {
+ vertexZOffset = var28.readShortSmart();
+ }
+
+ model.vertexPositionsX[point] = vX + vertexXOffset;
+ model.vertexPositionsY[point] = vY + vertexYOffset;
+ model.vertexPositionsZ[point] = vZ + vertexZOffset;
+ vX = model.vertexPositionsX[point];
+ vY = model.vertexPositionsY[point];
+ vZ = model.vertexPositionsZ[point];
+ if (modelVertexSkins == 1)
+ {
+ model.vertexSkins[point] = var6.readUnsignedByte();
+ }
+ }
+
+ var2.setOffset(colorPos);
+ var24.setOffset(renderTypePos);
+ var3.setOffset(priorityPos);
+ var28.setOffset(alphaPos);
+ var6.setOffset(triangleSkinPos);
+ var55.setOffset(texturePos);
+ var51.setOffset(textureCoordPos);
+
+ for (point = 0; point < triangleCount; ++point)
+ {
+ model.faceColors[point] = (short) var2.readUnsignedShort();
+ if (var13 == 1)
+ {
+ model.faceRenderTypes[point] = var24.readByte();
+ }
+
+ if (modelPriority == 255)
+ {
+ model.faceRenderPriorities[point] = var3.readByte();
+ }
+
+ if (var50 == 1)
+ {
+ model.faceAlphas[point] = var28.readByte();
+ }
+
+ if (var17 == 1)
+ {
+ model.faceSkins[point] = var6.readUnsignedByte();
+ }
+
+ if (modelTexture == 1)
+ {
+ model.faceTextures[point] = (short) (var55.readUnsignedShort() - 1);
+ }
+
+ if (model.textureCoordinates != null && model.faceTextures[point] != -1)
+ {
+ model.textureCoordinates[point] = (byte) (var51.readUnsignedByte() - 1);
+ }
+ }
+
+ var2.setOffset(var11);
+ var24.setOffset(var49);
+ int trianglePointX = 0;
+ int trianglePointY = 0;
+ int trianglePointZ = 0;
+ vertexYOffset = 0;
+
+ int var16;
+ for (vertexZOffset = 0; vertexZOffset < triangleCount; ++vertexZOffset)
+ {
+ int numFaces = var24.readUnsignedByte();
+ if (numFaces == 1)
+ {
+ trianglePointX = var2.readShortSmart() + vertexYOffset;
+ trianglePointY = var2.readShortSmart() + trianglePointX;
+ trianglePointZ = var2.readShortSmart() + trianglePointY;
+ vertexYOffset = trianglePointZ;
+ model.faceVertexIndices1[vertexZOffset] = trianglePointX;
+ model.faceVertexIndices2[vertexZOffset] = trianglePointY;
+ model.faceVertexIndices3[vertexZOffset] = trianglePointZ;
+ }
+
+ if (numFaces == 2)
+ {
+ trianglePointY = trianglePointZ;
+ trianglePointZ = var2.readShortSmart() + vertexYOffset;
+ vertexYOffset = trianglePointZ;
+ model.faceVertexIndices1[vertexZOffset] = trianglePointX;
+ model.faceVertexIndices2[vertexZOffset] = trianglePointY;
+ model.faceVertexIndices3[vertexZOffset] = trianglePointZ;
+ }
+
+ if (numFaces == 3)
+ {
+ trianglePointX = trianglePointZ;
+ trianglePointZ = var2.readShortSmart() + vertexYOffset;
+ vertexYOffset = trianglePointZ;
+ model.faceVertexIndices1[vertexZOffset] = trianglePointX;
+ model.faceVertexIndices2[vertexZOffset] = trianglePointY;
+ model.faceVertexIndices3[vertexZOffset] = trianglePointZ;
+ }
+
+ if (numFaces == 4)
+ {
+ int var57 = trianglePointX;
+ trianglePointX = trianglePointY;
+ trianglePointY = var57;
+ trianglePointZ = var2.readShortSmart() + vertexYOffset;
+ vertexYOffset = trianglePointZ;
+ model.faceVertexIndices1[vertexZOffset] = trianglePointX;
+ model.faceVertexIndices2[vertexZOffset] = var57;
+ model.faceVertexIndices3[vertexZOffset] = trianglePointZ;
+ }
+ }
+
+ var2.setOffset(var43);
+ var24.setOffset(var37);
+ var3.setOffset(var48);
+ var28.setOffset(var56);
+ var6.setOffset(var45);
+ var55.setOffset(var46);
+
+ for (int texIndex = 0; texIndex < textureTriangleCount; ++texIndex)
+ {
+ int type = model.textureRenderTypes[texIndex] & 255;
+ if (type == 0)
+ {
+ model.textureTriangleVertexIndices1[texIndex] = (short) var2.readUnsignedShort();
+ model.textureTriangleVertexIndices2[texIndex] = (short) var2.readUnsignedShort();
+ model.textureTriangleVertexIndices3[texIndex] = (short) var2.readUnsignedShort();
+ }
+
+ if (type == 1)
+ {
+ model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort();
+ model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort();
+ model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort();
+ model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort();
+ model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort();
+ model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort();
+ model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort();
+ model.aByteArray2580[texIndex] = var6.readByte();
+ model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort();
+ }
+
+ if (type == 2)
+ {
+ model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort();
+ model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort();
+ model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort();
+ model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort();
+ model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort();
+ model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort();
+ model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort();
+ model.aByteArray2580[texIndex] = var6.readByte();
+ model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort();
+ model.texturePrimaryColors[texIndex] = (short) var55.readUnsignedShort();
+ }
+
+ if (type == 3)
+ {
+ model.textureTriangleVertexIndices1[texIndex] = (short) var24.readUnsignedShort();
+ model.textureTriangleVertexIndices2[texIndex] = (short) var24.readUnsignedShort();
+ model.textureTriangleVertexIndices3[texIndex] = (short) var24.readUnsignedShort();
+ model.aShortArray2574[texIndex] = (short) var3.readUnsignedShort();
+ model.aShortArray2575[texIndex] = (short) var3.readUnsignedShort();
+ model.aShortArray2586[texIndex] = (short) var3.readUnsignedShort();
+ model.aShortArray2577[texIndex] = (short) var28.readUnsignedShort();
+ model.aByteArray2580[texIndex] = var6.readByte();
+ model.aShortArray2578[texIndex] = (short) var55.readUnsignedShort();
+ }
+ }
+
+ var2.setOffset(position);
+ vertexZOffset = var2.readUnsignedByte();
+ if (vertexZOffset != 0)
+ {
+ //new Class41();
+ var2.readUnsignedShort();
+ var2.readUnsignedShort();
+ var2.readUnsignedShort();
+ var2.readInt();
+ }
+ }
+
+ private void load2(ModelDefinition model, byte[] var1)
+ {
+ boolean var2 = false;
+ boolean var43 = false;
+ InputStream var5 = new InputStream(var1);
+ InputStream var39 = new InputStream(var1);
+ InputStream var26 = new InputStream(var1);
+ InputStream var9 = new InputStream(var1);
+ InputStream var3 = new InputStream(var1);
+ var5.setOffset(var1.length - 18);
+ int var10 = var5.readUnsignedShort();
+ int var11 = var5.readUnsignedShort();
+ int var12 = var5.readUnsignedByte();
+ int var13 = var5.readUnsignedByte();
+ int var14 = var5.readUnsignedByte();
+ int var30 = var5.readUnsignedByte();
+ int var15 = var5.readUnsignedByte();
+ int var28 = var5.readUnsignedByte();
+ int var27 = var5.readUnsignedShort();
+ int var20 = var5.readUnsignedShort();
+ int var36 = var5.readUnsignedShort();
+ int var23 = var5.readUnsignedShort();
+ byte var16 = 0;
+ int var46 = var16 + var10;
+ int var24 = var46;
+ var46 += var11;
+ int var25 = var46;
+ if (var14 == 255)
+ {
+ var46 += var11;
+ }
+
+ int var4 = var46;
+ if (var15 == 1)
+ {
+ var46 += var11;
+ }
+
+ int var42 = var46;
+ if (var13 == 1)
+ {
+ var46 += var11;
+ }
+
+ int var37 = var46;
+ if (var28 == 1)
+ {
+ var46 += var10;
+ }
+
+ int var29 = var46;
+ if (var30 == 1)
+ {
+ var46 += var11;
+ }
+
+ int var44 = var46;
+ var46 += var23;
+ int var17 = var46;
+ var46 += var11 * 2;
+ int var32 = var46;
+ var46 += var12 * 6;
+ int var34 = var46;
+ var46 += var27;
+ int var35 = var46;
+ var46 += var20;
+ int var10000 = var46 + var36;
+ model.vertexCount = var10;
+ model.faceCount = var11;
+ model.textureTriangleCount = var12;
+ model.vertexPositionsX = new int[var10];
+ model.vertexPositionsY = new int[var10];
+ model.vertexPositionsZ = new int[var10];
+ model.faceVertexIndices1 = new int[var11];
+ model.faceVertexIndices2 = new int[var11];
+ model.faceVertexIndices3 = new int[var11];
+ if (var12 > 0)
+ {
+ model.textureRenderTypes = new byte[var12];
+ model.textureTriangleVertexIndices1 = new short[var12];
+ model.textureTriangleVertexIndices2 = new short[var12];
+ model.textureTriangleVertexIndices3 = new short[var12];
+ }
+
+ if (var28 == 1)
+ {
+ model.vertexSkins = new int[var10];
+ }
+
+ if (var13 == 1)
+ {
+ model.faceRenderTypes = new byte[var11];
+ model.textureCoordinates = new byte[var11];
+ model.faceTextures = new short[var11];
+ }
+
+ if (var14 == 255)
+ {
+ model.faceRenderPriorities = new byte[var11];
+ }
+ else
+ {
+ model.priority = (byte) var14;
+ }
+
+ if (var30 == 1)
+ {
+ model.faceAlphas = new byte[var11];
+ }
+
+ if (var15 == 1)
+ {
+ model.faceSkins = new int[var11];
+ }
+
+ model.faceColors = new short[var11];
+ var5.setOffset(var16);
+ var39.setOffset(var34);
+ var26.setOffset(var35);
+ var9.setOffset(var46);
+ var3.setOffset(var37);
+ int var41 = 0;
+ int var33 = 0;
+ int var19 = 0;
+
+ int var6;
+ int var7;
+ int var8;
+ int var18;
+ int var31;
+ for (var18 = 0; var18 < var10; ++var18)
+ {
+ var8 = var5.readUnsignedByte();
+ var31 = 0;
+ if ((var8 & 1) != 0)
+ {
+ var31 = var39.readShortSmart();
+ }
+
+ var6 = 0;
+ if ((var8 & 2) != 0)
+ {
+ var6 = var26.readShortSmart();
+ }
+
+ var7 = 0;
+ if ((var8 & 4) != 0)
+ {
+ var7 = var9.readShortSmart();
+ }
+
+ model.vertexPositionsX[var18] = var41 + var31;
+ model.vertexPositionsY[var18] = var33 + var6;
+ model.vertexPositionsZ[var18] = var19 + var7;
+ var41 = model.vertexPositionsX[var18];
+ var33 = model.vertexPositionsY[var18];
+ var19 = model.vertexPositionsZ[var18];
+ if (var28 == 1)
+ {
+ model.vertexSkins[var18] = var3.readUnsignedByte();
+ }
+ }
+
+ var5.setOffset(var17);
+ var39.setOffset(var42);
+ var26.setOffset(var25);
+ var9.setOffset(var29);
+ var3.setOffset(var4);
+
+ for (var18 = 0; var18 < var11; ++var18)
+ {
+ model.faceColors[var18] = (short) var5.readUnsignedShort();
+ if (var13 == 1)
+ {
+ var8 = var39.readUnsignedByte();
+ if ((var8 & 1) == 1)
+ {
+ model.faceRenderTypes[var18] = 1;
+ var2 = true;
+ }
+ else
+ {
+ model.faceRenderTypes[var18] = 0;
+ }
+
+ if ((var8 & 2) == 2)
+ {
+ model.textureCoordinates[var18] = (byte) (var8 >> 2);
+ model.faceTextures[var18] = model.faceColors[var18];
+ model.faceColors[var18] = 127;
+ if (model.faceTextures[var18] != -1)
+ {
+ var43 = true;
+ }
+ }
+ else
+ {
+ model.textureCoordinates[var18] = -1;
+ model.faceTextures[var18] = -1;
+ }
+ }
+
+ if (var14 == 255)
+ {
+ model.faceRenderPriorities[var18] = var26.readByte();
+ }
+
+ if (var30 == 1)
+ {
+ model.faceAlphas[var18] = var9.readByte();
+ }
+
+ if (var15 == 1)
+ {
+ model.faceSkins[var18] = var3.readUnsignedByte();
+ }
+ }
+
+ var5.setOffset(var44);
+ var39.setOffset(var24);
+ var18 = 0;
+ var8 = 0;
+ var31 = 0;
+ var6 = 0;
+
+ int var21;
+ int var22;
+ for (var7 = 0; var7 < var11; ++var7)
+ {
+ var22 = var39.readUnsignedByte();
+ if (var22 == 1)
+ {
+ var18 = var5.readShortSmart() + var6;
+ var8 = var5.readShortSmart() + var18;
+ var31 = var5.readShortSmart() + var8;
+ var6 = var31;
+ model.faceVertexIndices1[var7] = var18;
+ model.faceVertexIndices2[var7] = var8;
+ model.faceVertexIndices3[var7] = var31;
+ }
+
+ if (var22 == 2)
+ {
+ var8 = var31;
+ var31 = var5.readShortSmart() + var6;
+ var6 = var31;
+ model.faceVertexIndices1[var7] = var18;
+ model.faceVertexIndices2[var7] = var8;
+ model.faceVertexIndices3[var7] = var31;
+ }
+
+ if (var22 == 3)
+ {
+ var18 = var31;
+ var31 = var5.readShortSmart() + var6;
+ var6 = var31;
+ model.faceVertexIndices1[var7] = var18;
+ model.faceVertexIndices2[var7] = var8;
+ model.faceVertexIndices3[var7] = var31;
+ }
+
+ if (var22 == 4)
+ {
+ var21 = var18;
+ var18 = var8;
+ var8 = var21;
+ var31 = var5.readShortSmart() + var6;
+ var6 = var31;
+ model.faceVertexIndices1[var7] = var18;
+ model.faceVertexIndices2[var7] = var21;
+ model.faceVertexIndices3[var7] = var31;
+ }
+ }
+
+ var5.setOffset(var32);
+
+ for (var7 = 0; var7 < var12; ++var7)
+ {
+ model.textureRenderTypes[var7] = 0;
+ model.textureTriangleVertexIndices1[var7] = (short) var5.readUnsignedShort();
+ model.textureTriangleVertexIndices2[var7] = (short) var5.readUnsignedShort();
+ model.textureTriangleVertexIndices3[var7] = (short) var5.readUnsignedShort();
+ }
+
+ if (model.textureCoordinates != null)
+ {
+ boolean var45 = false;
+
+ for (var22 = 0; var22 < var11; ++var22)
+ {
+ var21 = model.textureCoordinates[var22] & 255;
+ if (var21 != 255)
+ {
+ if ((model.textureTriangleVertexIndices1[var21] & '\uffff') == model.faceVertexIndices1[var22] && (model.textureTriangleVertexIndices2[var21] & '\uffff') == model.faceVertexIndices2[var22] && (model.textureTriangleVertexIndices3[var21] & '\uffff') == model.faceVertexIndices3[var22])
+ {
+ model.textureCoordinates[var22] = -1;
+ }
+ else
+ {
+ var45 = true;
+ }
+ }
+ }
+
+ if (!var45)
+ {
+ model.textureCoordinates = null;
+ }
+ }
+
+ if (!var43)
+ {
+ model.faceTextures = null;
+ }
+
+ if (!var2)
+ {
+ model.faceRenderTypes = null;
+ }
+ }
+
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/NpcLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/NpcLoader.java
new file mode 100644
index 0000000000..478ef2660a
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/NpcLoader.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.NpcDefinition;
+import net.runelite.cache.io.InputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+
+public class NpcLoader
+{
+ private static final Logger logger = LoggerFactory.getLogger(NpcLoader.class);
+
+ public NpcDefinition load(int id, byte[] b)
+ {
+ NpcDefinition def = new NpcDefinition(id);
+ InputStream is = new InputStream(b);
+
+ while (true)
+ {
+ int opcode = is.readUnsignedByte();
+ if (opcode == 0)
+ {
+ break;
+ }
+
+ this.decodeValues(opcode, def, is);
+ }
+
+ return def;
+ }
+
+ private void decodeValues(int opcode, NpcDefinition def, InputStream stream)
+ {
+ int length;
+ int index;
+ if (opcode == 1)
+ {
+ length = stream.readUnsignedByte();
+ def.models = new int[length];
+
+ for (index = 0; index < length; ++index)
+ {
+ def.models[index] = stream.readUnsignedShort();
+ }
+
+ }
+ else if (opcode == 2)
+ {
+ def.name = stream.readString();
+ }
+ else if (opcode == 12)
+ {
+ def.tileSpacesOccupied = stream.readUnsignedByte();
+ }
+ else if (opcode == 13)
+ {
+ def.stanceAnimation = stream.readUnsignedShort();
+ }
+ else if (opcode == 14)
+ {
+ def.walkAnimation = stream.readUnsignedShort();
+ }
+ else if (opcode == 15)
+ {
+ def.anInt2165 = stream.readUnsignedShort();
+ }
+ else if (opcode == 16)
+ {
+ def.anInt2189 = stream.readUnsignedShort();
+ }
+ else if (opcode == 17)
+ {
+ def.walkAnimation = stream.readUnsignedShort();
+ def.rotate180Animation = stream.readUnsignedShort();
+ def.rotate90RightAnimation = stream.readUnsignedShort();
+ def.rotate90LeftAnimation = stream.readUnsignedShort();
+ }
+ else if (opcode >= 30 && opcode < 35)
+ {
+ def.options[opcode - 30] = stream.readString();
+ if (def.options[opcode - 30].equalsIgnoreCase("Hidden"))
+ {
+ def.options[opcode - 30] = null;
+ }
+ }
+ else if (opcode == 40)
+ {
+ length = stream.readUnsignedByte();
+ def.recolorToFind = new short[length];
+ def.recolorToReplace = new short[length];
+
+ for (index = 0; index < length; ++index)
+ {
+ def.recolorToFind[index] = (short) stream.readUnsignedShort();
+ def.recolorToReplace[index] = (short) stream.readUnsignedShort();
+ }
+
+ }
+ else if (opcode == 41)
+ {
+ length = stream.readUnsignedByte();
+ def.retextureToFind = new short[length];
+ def.retextureToReplace = new short[length];
+
+ for (index = 0; index < length; ++index)
+ {
+ def.retextureToFind[index] = (short) stream.readUnsignedShort();
+ def.retextureToReplace[index] = (short) stream.readUnsignedShort();
+ }
+
+ }
+ else if (opcode == 60)
+ {
+ length = stream.readUnsignedByte();
+ def.models_2 = new int[length];
+
+ for (index = 0; index < length; ++index)
+ {
+ def.models_2[index] = stream.readUnsignedShort();
+ }
+
+ }
+ else if (opcode == 93)
+ {
+ def.renderOnMinimap = false;
+ }
+ else if (opcode == 95)
+ {
+ def.combatLevel = stream.readUnsignedShort();
+ }
+ else if (opcode == 97)
+ {
+ def.resizeX = stream.readUnsignedShort();
+ }
+ else if (opcode == 98)
+ {
+ def.resizeY = stream.readUnsignedShort();
+ }
+ else if (opcode == 99)
+ {
+ def.hasRenderPriority = true;
+ }
+ else if (opcode == 100)
+ {
+ def.ambient = stream.readByte();
+ }
+ else if (opcode == 101)
+ {
+ def.contrast = stream.readByte();
+ }
+ else if (opcode == 102)
+ {
+ def.headIcon = stream.readUnsignedShort();
+ }
+ else if (opcode == 103)
+ {
+ def.rotation = stream.readUnsignedShort();
+ }
+ else if (opcode == 106)
+ {
+ def.varbitIndex = stream.readUnsignedShort();
+ if ('\uffff' == def.varbitIndex)
+ {
+ def.varbitIndex = -1;
+ }
+
+ def.varpIndex = stream.readUnsignedShort();
+ if ('\uffff' == def.varpIndex)
+ {
+ def.varpIndex = -1;
+ }
+
+ length = stream.readUnsignedByte();
+ def.configs = new int[length + 2];
+
+ for (index = 0; index <= length; ++index)
+ {
+ def.configs[index] = stream.readUnsignedShort();
+ if (def.configs[index] == '\uffff')
+ {
+ def.configs[index] = -1;
+ }
+ }
+
+ def.configs[length + 1] = -1;
+
+ }
+ else if (opcode == 107)
+ {
+ def.isClickable = false;
+ }
+ else if (opcode == 109)
+ {
+ def.aBool2170 = false;
+ }
+ else if (opcode == 111)
+ {
+ def.aBool2190 = true;
+ }
+ else if (opcode == 118)
+ {
+ def.varbitIndex = stream.readUnsignedShort();
+ if ('\uffff' == def.varbitIndex)
+ {
+ def.varbitIndex = -1;
+ }
+
+ def.varpIndex = stream.readUnsignedShort();
+ if ('\uffff' == def.varpIndex)
+ {
+ def.varpIndex = -1;
+ }
+
+ int var = stream.readUnsignedShort();
+ if (var == 0xFFFF)
+ {
+ var = -1;
+ }
+
+ length = stream.readUnsignedByte();
+ def.configs = new int[length + 2];
+
+ for (index = 0; index <= length; ++index)
+ {
+ def.configs[index] = stream.readUnsignedShort();
+ if (def.configs[index] == '\uffff')
+ {
+ def.configs[index] = -1;
+ }
+ }
+
+ def.configs[length + 1] = var;
+ }
+ else if (opcode == 249)
+ {
+ length = stream.readUnsignedByte();
+
+ def.params = new HashMap<>(length);
+
+ for (int i = 0; i < length; i++)
+ {
+ boolean isString = stream.readUnsignedByte() == 1;
+ int key = stream.read24BitInt();
+ Object value;
+
+ if (isString)
+ {
+ value = stream.readString();
+ }
+
+ else
+ {
+ value = stream.readInt();
+ }
+
+ def.params.put(key, value);
+ }
+ }
+ else
+ {
+ logger.warn("Unrecognized opcode {}", opcode);
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/ObjectLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/ObjectLoader.java
new file mode 100644
index 0000000000..13a3eab754
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/ObjectLoader.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions.loaders;
+
+import java.util.HashMap;
+import java.util.Map;
+import net.runelite.cache.definitions.ObjectDefinition;
+import net.runelite.cache.io.InputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ObjectLoader
+{
+ private static final Logger logger = LoggerFactory.getLogger(ObjectLoader.class);
+
+ public ObjectDefinition load(int id, byte[] b)
+ {
+ ObjectDefinition def = new ObjectDefinition();
+ InputStream is = new InputStream(b);
+
+ def.setId(id);
+
+ for (;;)
+ {
+ int opcode = is.readUnsignedByte();
+ if (opcode == 0)
+ {
+ break;
+ }
+
+ processOp(opcode, def, is);
+ }
+
+ post(def);
+
+ return def;
+ }
+
+ private void processOp(int opcode, ObjectDefinition def, InputStream is)
+ {
+ if (opcode == 1)
+ {
+ int length = is.readUnsignedByte();
+ if (length > 0)
+ {
+ int[] objectTypes = new int[length];
+ int[] objectModels = new int[length];
+
+ for (int index = 0; index < length; ++index)
+ {
+ objectModels[index] = is.readUnsignedShort();
+ objectTypes[index] = is.readUnsignedByte();
+ }
+
+ def.setObjectTypes(objectTypes);
+ def.setObjectModels(objectModels);
+ }
+ }
+ else if (opcode == 2)
+ {
+ def.setName(is.readString());
+ }
+ else if (opcode == 5)
+ {
+ int length = is.readUnsignedByte();
+ if (length > 0)
+ {
+ def.setObjectTypes(null);
+ int[] objectModels = new int[length];
+
+ for (int index = 0; index < length; ++index)
+ {
+ objectModels[index] = is.readUnsignedShort();
+ }
+
+ def.setObjectModels(objectModels);
+ }
+ }
+ else if (opcode == 14)
+ {
+ def.setSizeX(is.readUnsignedByte());
+ }
+ else if (opcode == 15)
+ {
+ def.setSizeY(is.readUnsignedByte());
+ }
+ else if (opcode == 17)
+ {
+ def.setInteractType(0);
+ def.setBlocksProjectile(false);
+ }
+ else if (opcode == 18)
+ {
+ def.setBlocksProjectile(false);
+ }
+ else if (opcode == 19)
+ {
+ def.setAnInt2088(is.readUnsignedByte());
+ }
+ else if (opcode == 21)
+ {
+ def.setAnInt2105(0);
+ }
+ else if (opcode == 22)
+ {
+ def.setNonFlatShading(false);
+ }
+ else if (opcode == 23)
+ {
+ def.setABool2111(true);
+ }
+ else if (opcode == 24)
+ {
+ def.setAnimationID(is.readUnsignedShort());
+ if (def.getAnimationID() == 0xFFFF)
+ {
+ def.setAnimationID(-1);
+ }
+ }
+ else if (opcode == 27)
+ {
+ def.setInteractType(1);
+ }
+ else if (opcode == 28)
+ {
+ def.setAnInt2069(is.readUnsignedByte());
+ }
+ else if (opcode == 29)
+ {
+ def.setAmbient(is.readByte());
+ }
+ else if (opcode == 39)
+ {
+ def.setContrast(is.readByte());
+ }
+ else if (opcode >= 30 && opcode < 35)
+ {
+ String[] actions = def.getActions();
+ actions[opcode - 30] = is.readString();
+ if (actions[opcode - 30].equalsIgnoreCase("Hidden"))
+ {
+ actions[opcode - 30] = null;
+ }
+ }
+ else if (opcode == 40)
+ {
+ int length = is.readUnsignedByte();
+ short[] recolorToFind = new short[length];
+ short[] recolorToReplace = new short[length];
+
+ for (int index = 0; index < length; ++index)
+ {
+ recolorToFind[index] = is.readShort();
+ recolorToReplace[index] = is.readShort();
+ }
+
+ def.setRecolorToFind(recolorToFind);
+ def.setRecolorToReplace(recolorToReplace);
+ }
+ else if (opcode == 41)
+ {
+ int length = is.readUnsignedByte();
+ short[] retextureToFind = new short[length];
+ short[] textureToReplace = new short[length];
+
+ for (int index = 0; index < length; ++index)
+ {
+ retextureToFind[index] = is.readShort();
+ textureToReplace[index] = is.readShort();
+ }
+
+ def.setRetextureToFind(retextureToFind);
+ def.setTextureToReplace(textureToReplace);
+ }
+ else if (opcode == 62)
+ {
+ def.setRotated(true);
+ }
+ else if (opcode == 64)
+ {
+ def.setABool2097(false);
+ }
+ else if (opcode == 65)
+ {
+ def.setModelSizeX(is.readUnsignedShort());
+ }
+ else if (opcode == 66)
+ {
+ def.setModelSizeHeight(is.readUnsignedShort());
+ }
+ else if (opcode == 67)
+ {
+ def.setModelSizeY(is.readUnsignedShort());
+ }
+ else if (opcode == 68)
+ {
+ def.setMapSceneID(is.readUnsignedShort());
+ }
+ else if (opcode == 69)
+ {
+ is.readByte();
+ }
+ else if (opcode == 70)
+ {
+ def.setOffsetX(is.readUnsignedShort());
+ }
+ else if (opcode == 71)
+ {
+ def.setOffsetHeight(is.readUnsignedShort());
+ }
+ else if (opcode == 72)
+ {
+ def.setOffsetY(is.readUnsignedShort());
+ }
+ else if (opcode == 73)
+ {
+ def.setABool2104(true);
+ }
+ else if (opcode == 74)
+ {
+ def.setSolid(true);
+ }
+ else if (opcode == 75)
+ {
+ def.setAnInt2106(is.readUnsignedByte());
+ }
+ else if (opcode == 77)
+ {
+ int varpID = is.readUnsignedShort();
+ if (varpID == 0xFFFF)
+ {
+ varpID = -1;
+ }
+ def.setVarbitID(varpID);
+
+ int configId = is.readUnsignedShort();
+ if (configId == 0xFFFF)
+ {
+ configId = -1;
+ }
+ def.setVarpID(configId);
+
+ int length = is.readUnsignedByte();
+ int[] configChangeDest = new int[length + 2];
+
+ for (int index = 0; index <= length; ++index)
+ {
+ configChangeDest[index] = is.readUnsignedShort();
+ if (0xFFFF == configChangeDest[index])
+ {
+ configChangeDest[index] = -1;
+ }
+ }
+
+ configChangeDest[length + 1] = -1;
+
+ def.setConfigChangeDest(configChangeDest);
+ }
+ else if (opcode == 78)
+ {
+ def.setAnInt2110(is.readUnsignedShort());
+ def.setAnInt2083(is.readUnsignedByte());
+ }
+ else if (opcode == 79)
+ {
+ def.setAnInt2112(is.readUnsignedShort());
+ def.setAnInt2113(is.readUnsignedShort());
+ def.setAnInt2083(is.readUnsignedByte());
+ int length = is.readUnsignedByte();
+ int[] anIntArray2084 = new int[length];
+
+ for (int index = 0; index < length; ++index)
+ {
+ anIntArray2084[index] = is.readUnsignedShort();
+ }
+
+ def.setAnIntArray2084(anIntArray2084);
+ }
+ else if (opcode == 81)
+ {
+ def.setAnInt2105(is.readUnsignedByte() * 256);
+ }
+ else if (opcode == 82)
+ {
+ def.setMapAreaId(is.readUnsignedShort());
+ }
+ else if (opcode == 92)
+ {
+ int varpID = is.readUnsignedShort();
+ if (varpID == 0xFFFF)
+ {
+ varpID = -1;
+ }
+ def.setVarbitID(varpID);
+
+ int configId = is.readUnsignedShort();
+ if (configId == 0xFFFF)
+ {
+ configId = -1;
+ }
+ def.setVarpID(configId);
+
+
+ int var = is.readUnsignedShort();
+ if (var == 0xFFFF)
+ {
+ var = -1;
+ }
+
+ int length = is.readUnsignedByte();
+ int[] configChangeDest = new int[length + 2];
+
+ for (int index = 0; index <= length; ++index)
+ {
+ configChangeDest[index] = is.readUnsignedShort();
+ if (0xFFFF == configChangeDest[index])
+ {
+ configChangeDest[index] = -1;
+ }
+ }
+
+ configChangeDest[length + 1] = var;
+
+ def.setConfigChangeDest(configChangeDest);
+ }
+ else if (opcode == 249)
+ {
+ int length = is.readUnsignedByte();
+
+ Map params = new HashMap<>(length);
+ for (int i = 0; i < length; i++)
+ {
+ boolean isString = is.readUnsignedByte() == 1;
+ int key = is.read24BitInt();
+ Object value;
+
+ if (isString)
+ {
+ value = is.readString();
+ }
+
+ else
+ {
+ value = is.readInt();
+ }
+
+ params.put(key, value);
+ }
+
+ def.setParams(params);
+ }
+ else
+ {
+ logger.warn("Unrecognized opcode {}", opcode);
+ }
+ }
+
+
+ private void post(ObjectDefinition def)
+ {
+ if (def.getAnInt2088() == -1)
+ {
+ def.setAnInt2088(0);
+ if (def.getObjectModels() != null && (def.getObjectTypes() == null || def.getObjectTypes()[0] == 10))
+ {
+ def.setAnInt2088(1);
+ }
+
+ for (int var1 = 0; var1 < 5; ++var1)
+ {
+ if (def.getActions()[var1] != null)
+ {
+ def.setAnInt2088(1);
+ }
+ }
+ }
+
+ if (def.getAnInt2106() == -1)
+ {
+ def.setAnInt2106(def.getInteractType() != 0 ? 1 : 0);
+ }
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/OverlayLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/OverlayLoader.java
new file mode 100644
index 0000000000..1b01c07c87
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/OverlayLoader.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.OverlayDefinition;
+import net.runelite.cache.io.InputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OverlayLoader
+{
+ private static final Logger logger = LoggerFactory.getLogger(OverlayLoader.class);
+
+ public OverlayDefinition load(int id, byte[] b)
+ {
+ OverlayDefinition def = new OverlayDefinition();
+ InputStream is = new InputStream(b);
+
+ def.setId(id);
+
+ for (;;)
+ {
+ int opcode = is.readUnsignedByte();
+ if (opcode == 0)
+ {
+ break;
+ }
+
+ if (opcode == 1)
+ {
+ int color = is.read24BitInt();
+ def.setRgbColor(color);
+ }
+ else if (opcode == 2)
+ {
+ int texture = is.readUnsignedByte();
+ def.setTexture(texture);
+ }
+ else if (opcode == 5)
+ {
+ def.setHideUnderlay(false);
+ }
+ else if (opcode == 7)
+ {
+ int secondaryColor = is.read24BitInt();
+ def.setSecondaryRgbColor(secondaryColor);
+ }
+ }
+
+ def.calculateHsl();
+
+ return def;
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/ScriptLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/ScriptLoader.java
new file mode 100644
index 0000000000..e77964a5ca
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/ScriptLoader.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions.loaders;
+
+import java.util.HashMap;
+import java.util.Map;
+import net.runelite.cache.definitions.ScriptDefinition;
+import net.runelite.cache.io.InputStream;
+import static net.runelite.cache.script.Opcodes.SCONST;
+import static net.runelite.cache.script.Opcodes.POP_INT;
+import static net.runelite.cache.script.Opcodes.POP_STRING;
+import static net.runelite.cache.script.Opcodes.RETURN;
+
+public class ScriptLoader
+{
+ public ScriptDefinition load(int id, byte[] b)
+ {
+ ScriptDefinition def = new ScriptDefinition();
+ def.setId(id);
+ InputStream in = new InputStream(b);
+
+ in.setOffset(in.getLength() - 2);
+ int switchLength = in.readUnsignedShort();
+
+ // 2 for switchLength + the switch data + 12 for the param/vars/stack data
+ int endIdx = in.getLength() - 2 - switchLength - 12;
+ in.setOffset(endIdx);
+ int numOpcodes = in.readInt();
+ int localIntCount = in.readUnsignedShort();
+ int localStringCount = in.readUnsignedShort();
+ int intStackCount = in.readUnsignedShort();
+ int stringStackCount = in.readUnsignedShort();
+
+ int numSwitches = in.readUnsignedByte();
+ if (numSwitches > 0)
+ {
+ Map[] switches = new Map[numSwitches];
+ def.setSwitches(switches);
+
+ for (int i = 0; i < numSwitches; ++i)
+ {
+ switches[i] = new HashMap<>();
+
+ int count = in.readUnsignedShort();
+ while (count-- > 0)
+ {
+ int key = in.readInt(); // int from stack is compared to this
+ int pcOffset = in.readInt(); // pc jumps by this
+
+ switches[i].put(key, pcOffset);
+ }
+ }
+ }
+
+ def.setLocalIntCount(localIntCount);
+ def.setLocalStringCount(localStringCount);
+ def.setIntStackCount(intStackCount);
+ def.setStringStackCount(stringStackCount);
+
+ in.setOffset(0);
+ in.readStringOrNull();
+
+ int[] instructions = new int[numOpcodes];
+ int[] intOperands = new int[numOpcodes];
+ String[] stringOperands = new String[numOpcodes];
+
+ def.setInstructions(instructions);
+ def.setIntOperands(intOperands);
+ def.setStringOperands(stringOperands);
+
+ int opcode;
+ for (int i = 0; in.getOffset() < endIdx; instructions[i++] = opcode)
+ {
+ opcode = in.readUnsignedShort();
+ if (opcode == SCONST)
+ {
+ stringOperands[i] = in.readString();
+ }
+ else if (opcode < 100 && opcode != RETURN && opcode != POP_INT && opcode != POP_STRING)
+ {
+ intOperands[i] = in.readInt();
+ }
+ else
+ {
+ intOperands[i] = in.readUnsignedByte();
+ }
+ }
+
+ return def;
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/SequenceLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/SequenceLoader.java
new file mode 100644
index 0000000000..987cbd4204
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/SequenceLoader.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2016-2017, 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.cache.definitions.loaders;
+
+import net.runelite.cache.definitions.SequenceDefinition;
+import net.runelite.cache.io.InputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SequenceLoader
+{
+ private static final Logger logger = LoggerFactory.getLogger(SequenceLoader.class);
+
+ public SequenceDefinition load(int id, byte[] b)
+ {
+ SequenceDefinition def = new SequenceDefinition(id);
+ InputStream is = new InputStream(b);
+
+ while (true)
+ {
+ int opcode = is.readUnsignedByte();
+ if (opcode == 0)
+ {
+ break;
+ }
+
+ this.decodeValues(opcode, def, is);
+ }
+
+ return def;
+ }
+
+ private void decodeValues(int opcode, SequenceDefinition def, InputStream stream)
+ {
+ int var3;
+ int var4;
+ if (opcode == 1)
+ {
+ var3 = stream.readUnsignedShort();
+ def.frameLenghts = new int[var3];
+
+ for (var4 = 0; var4 < var3; ++var4)
+ {
+ def.frameLenghts[var4] = stream.readUnsignedShort();
+ }
+
+ def.frameIDs = new int[var3];
+
+ for (var4 = 0; var4 < var3; ++var4)
+ {
+ def.frameIDs[var4] = stream.readUnsignedShort();
+ }
+
+ for (var4 = 0; var4 < var3; ++var4)
+ {
+ def.frameIDs[var4] += stream.readUnsignedShort() << 16;
+ }
+ }
+ else if (opcode == 2)
+ {
+ def.frameStep = stream.readUnsignedShort();
+ }
+ else if (opcode == 3)
+ {
+ var3 = stream.readUnsignedByte();
+ def.interleaveLeave = new int[1 + var3];
+
+ for (var4 = 0; var4 < var3; ++var4)
+ {
+ def.interleaveLeave[var4] = stream.readUnsignedByte();
+ }
+
+ def.interleaveLeave[var3] = 9999999;
+ }
+ else if (opcode == 4)
+ {
+ def.stretches = true;
+ }
+ else if (opcode == 5)
+ {
+ def.forcedPriority = stream.readUnsignedByte();
+ }
+ else if (opcode == 6)
+ {
+ def.leftHandItem = stream.readUnsignedShort();
+ }
+ else if (opcode == 7)
+ {
+ def.rightHandItem = stream.readUnsignedShort();
+ }
+ else if (opcode == 8)
+ {
+ def.maxLoops = stream.readUnsignedByte();
+ }
+ else if (opcode == 9)
+ {
+ def.precedenceAnimating = stream.readUnsignedByte();
+ }
+ else if (opcode == 10)
+ {
+ def.priority = stream.readUnsignedByte();
+ }
+ else if (opcode == 11)
+ {
+ def.replyMode = stream.readUnsignedByte();
+ }
+ else if (opcode == 12)
+ {
+ var3 = stream.readUnsignedByte();
+ def.field3048 = new int[var3];
+
+ for (var4 = 0; var4 < var3; ++var4)
+ {
+ def.field3048[var4] = stream.readUnsignedShort();
+ }
+
+ for (var4 = 0; var4 < var3; ++var4)
+ {
+ def.field3048[var4] += stream.readUnsignedShort() << 16;
+ }
+ }
+ else if (opcode == 13)
+ {
+ var3 = stream.readUnsignedByte();
+ def.field3056 = new int[var3];
+
+ for (var4 = 0; var4 < var3; ++var4)
+ {
+ def.field3056[var4] = stream.read24BitInt();
+ }
+ }
+
+ }
+}
diff --git a/cache/src/main/java/net/runelite/cache/definitions/loaders/SpotAnimLoader.java b/cache/src/main/java/net/runelite/cache/definitions/loaders/SpotAnimLoader.java
new file mode 100644
index 0000000000..20f2be2d24
--- /dev/null
+++ b/cache/src/main/java/net/runelite/cache/definitions/loaders/SpotAnimLoader.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2017, Adam