diff --git a/runelite-api/src/main/java/net/runelite/api/Client.java b/runelite-api/src/main/java/net/runelite/api/Client.java index 4a234ed84a..18f2bb6052 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -138,6 +138,8 @@ public interface Client extends GameEngine HashTable getComponentTable(); + GrandExchangeOffer[] getGrandExchangeOffers(); + boolean isPrayerActive(Prayer prayer); int getSkillExperience(Skill skill); diff --git a/runelite-api/src/main/java/net/runelite/api/GrandExchangeOffer.java b/runelite-api/src/main/java/net/runelite/api/GrandExchangeOffer.java new file mode 100644 index 0000000000..639908a1fe --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/GrandExchangeOffer.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.api; + +public interface GrandExchangeOffer +{ + int getQuantitySold(); + + int getItemId(); + + int getTotalQuantity(); + + int getPrice(); + + int getSpent(); + + GrandExchangeOfferState getState(); +} diff --git a/runelite-api/src/main/java/net/runelite/api/GrandExchangeOfferState.java b/runelite-api/src/main/java/net/runelite/api/GrandExchangeOfferState.java new file mode 100644 index 0000000000..0c68e493ba --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/GrandExchangeOfferState.java @@ -0,0 +1,57 @@ +/* + * 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.api; + +/** + * Describes the state of a Grand Exchange offer + */ +public enum GrandExchangeOfferState +{ + /** + * An empty slot. + */ + EMPTY, + /** + * Any offer that's been cancelled + */ + CANCELLED, + /** + * A buy offer that is currently in progress. + */ + BUYING, + /** + * A buy offer that has completed. + */ + BOUGHT, + /** + * A sell offer that is currently in progress. + */ + SELLING, + /** + * A sell offer that has completed. + */ + SOLD; +} diff --git a/runelite-api/src/main/java/net/runelite/api/events/GrandExchangeOfferChanged.java b/runelite-api/src/main/java/net/runelite/api/events/GrandExchangeOfferChanged.java new file mode 100644 index 0000000000..72db3b901d --- /dev/null +++ b/runelite-api/src/main/java/net/runelite/api/events/GrandExchangeOfferChanged.java @@ -0,0 +1,35 @@ +/* + * 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.api.events; + +import lombok.Data; +import net.runelite.api.GrandExchangeOffer; + +@Data +public class GrandExchangeOfferChanged +{ + private GrandExchangeOffer offer; + private int slot; +} diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java index 93d07ca64e..98a2dc5918 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSClientMixin.java @@ -29,6 +29,7 @@ import java.util.List; import net.runelite.api.ChatMessageType; import net.runelite.api.ClanMember; import net.runelite.api.GameState; +import net.runelite.api.GrandExchangeOffer; import net.runelite.api.IndexedSprite; import net.runelite.api.InventoryID; import net.runelite.api.MenuAction; @@ -44,6 +45,7 @@ import net.runelite.api.Skill; import net.runelite.api.Varbits; import net.runelite.api.events.ExperienceChanged; import net.runelite.api.events.GameStateChanged; +import net.runelite.api.events.GrandExchangeOfferChanged; import net.runelite.api.events.MapRegionChanged; import net.runelite.api.events.PlayerMenuOptionsChanged; import net.runelite.api.events.ResizeableChanged; @@ -483,6 +485,28 @@ public abstract class RSClientMixin implements RSClient eventBus.post(gameStateChange); } + @Inject + @FieldHook("grandExchangeOffers") + public static void onGrandExchangeOffersChanged(int idx) + { + if (idx == -1) + { + return; + } + + GrandExchangeOffer internalOffer = client.getGrandExchangeOffers()[idx]; + + if (internalOffer == null) + { + return; + } + + GrandExchangeOfferChanged offerChangedEvent = new GrandExchangeOfferChanged(); + offerChangedEvent.setOffer(internalOffer); + offerChangedEvent.setSlot(idx); + eventBus.post(offerChangedEvent); + } + @FieldHook("settings") @Inject public static void settingsChanged(int idx) diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSGrandExchangeOfferMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSGrandExchangeOfferMixin.java new file mode 100644 index 0000000000..f132e84ab4 --- /dev/null +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSGrandExchangeOfferMixin.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2018, SomeoneWithAnInternetConnection + * 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.mixins; + +import net.runelite.api.GrandExchangeOfferState; +import static net.runelite.api.GrandExchangeOfferState.BOUGHT; +import static net.runelite.api.GrandExchangeOfferState.BUYING; +import static net.runelite.api.GrandExchangeOfferState.CANCELLED; +import static net.runelite.api.GrandExchangeOfferState.EMPTY; +import static net.runelite.api.GrandExchangeOfferState.SELLING; +import static net.runelite.api.GrandExchangeOfferState.SOLD; +import net.runelite.api.mixins.Inject; +import net.runelite.api.mixins.Mixin; +import net.runelite.rs.api.RSGrandExchangeOffer; + +@Mixin(RSGrandExchangeOffer.class) +public abstract class RSGrandExchangeOfferMixin implements RSGrandExchangeOffer +{ + + /* + Internally a GrandExchangeOffer's state is represented as 4 flags + packed into the lower half of a byte. They are: + */ + + //Set for sell offers, unset for buy offers + private static final int IS_SELLING = 1 << 3; // 0b1000 + + + /* + Set for offers that have finished, either because they've + been filled, or because they were cancelled + */ + private static final int COMPLETED = 1 << 2; // 0b0100 + + /* + Set for offers that are actually live + NB: Insta-buy/sell offers will be simultaneously LIVE and LOCAL + */ + private static final int LIVE = 1 << 1; // 0b0010 + + //True for just-made, just-cancelled, completely cancelled, and completed offers + private static final int LOCAL = 1; + + @Inject + @Override + public GrandExchangeOfferState getState() + { + byte code = getRSState(); + boolean isSelling = (code & IS_SELLING) == IS_SELLING; + boolean isFinished = (code & COMPLETED) == COMPLETED; + + + if (code == 0) + { + return EMPTY; + } + else if (isFinished && getQuantitySold() < getTotalQuantity()) + { + return CANCELLED; + } + else if (isSelling) + { + if (isFinished) + { + return SOLD; + } + else // if isUnfinished + { + return SELLING; + } + } + else // if isBuying + { + if (isFinished) + { + return BOUGHT; + } + else // if isUnfinished + { + return BUYING; + } + } + } +} diff --git a/runescape-api/src/main/java/net/runelite/rs/api/RSGrandExchangeOffer.java b/runescape-api/src/main/java/net/runelite/rs/api/RSGrandExchangeOffer.java index eb505f9367..d88e582ef7 100644 --- a/runescape-api/src/main/java/net/runelite/rs/api/RSGrandExchangeOffer.java +++ b/runescape-api/src/main/java/net/runelite/rs/api/RSGrandExchangeOffer.java @@ -24,26 +24,33 @@ */ package net.runelite.rs.api; +import net.runelite.api.GrandExchangeOffer; import net.runelite.mapping.Import; -public interface RSGrandExchangeOffer +public interface RSGrandExchangeOffer extends GrandExchangeOffer { @Import("quantitySold") + @Override int getQuantitySold(); @Import("itemId") + @Override int getItemId(); @Import("totalQuantity") + @Override int getTotalQuantity(); @Import("price") + @Override int getPrice(); @Import("spent") + @Override int getSpent(); @Import("state") byte getRSState(); + }