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 9d64865601..14936153d7 100644 --- a/runelite-api/src/main/java/net/runelite/api/Client.java +++ b/runelite-api/src/main/java/net/runelite/api/Client.java @@ -434,6 +434,13 @@ public interface Client extends OAuthApi, GameEngine @Nonnull ItemComposition getItemComposition(int id); + /** + * Get the local player's follower, such as a pet + * @return + */ + @Nullable + NPC getFollower(); + /** * Gets the item composition corresponding to an items ID. * @@ -1748,162 +1755,6 @@ public interface Client extends OAuthApi, GameEngine */ int getItemPressedDuration(); - /** - * Sets whether the client is hiding entities. - *

- * This method does not itself hide any entities. It behaves as a master - * switch for whether or not any of the related entities are hidden or - * shown. If this method is set to false, changing the configurations for - * specific entities will have no effect. - * - * @param state new entity hiding state - */ - void setIsHidingEntities(boolean state); - - /** - * Sets whether or not other players are hidden. - * - * @param state the new player hidden state - */ - void setOthersHidden(boolean state); - - /** - * Sets whether 2D sprites related to the other players are hidden. - * (ie. overhead prayers, PK skull) - * - * @param state the new player 2D hidden state - */ - void setOthersHidden2D(boolean state); - - /** - * Sets whether or not friends are hidden. - * - * @param state the new friends hidden state - */ - void setFriendsHidden(boolean state); - - /** - * Sets whether or not friends chat members are hidden. - * - * @param state the new friends chat member hidden state - */ - void setFriendsChatMembersHidden(boolean state); - - /** - * Sets whether or not clan members are hidden. - * - * @param state the new clan chat member hidden state - */ - void setClanChatMembersHidden(boolean state); - - /** - * Sets whether or not ignored players are hidden. - * - * @param state the new ignored player hidden state - */ - void setIgnoresHidden(boolean state); - - /** - * Sets whether the local player is hidden. - * - * @param state new local player hidden state - */ - void setLocalPlayerHidden(boolean state); - - /** - * Sets whether 2D sprites related to the local player are hidden. - * (ie. overhead prayers, PK skull) - * - * @param state new local player 2D hidden state - */ - void setLocalPlayerHidden2D(boolean state); - - /** - * Sets whether NPCs are hidden. - * - * @param state new NPC hidden state - */ - void setNPCsHidden(boolean state); - - /** - * Sets whether 2D sprites (ie. overhead prayers) related to - * the NPCs are hidden. - * - * @param state new NPC 2D hidden state - */ - void setNPCsHidden2D(boolean state); - - /** - * Sets whether Pets from other players are hidden. - * - * @param state new pet hidden state - */ - void setPetsHidden(boolean state); - - /** - * Sets whether attacking players or NPCs are hidden. - * - * @param state new attacker hidden state - */ - void setAttackersHidden(boolean state); - - /** - * Hides players input here. - * - * @param names the names of the players - */ - void setHideSpecificPlayers(List names); - - /** - * Get the list of NPC indices that are currently hidden - * - * @return all of the current hidden NPC Indices - */ - List getHiddenNpcIndices(); - - /** - * If an NPC index is in this List then do not render it - * - * @param npcIndices the npc indices to hide - */ - void setHiddenNpcIndices(List npcIndices); - - /** - * Increments the counter for how many times this npc has been selected to be hidden - * - * @param name npc name - */ - void addHiddenNpcName(String name); - - /** - * Decrements the counter for how many times this npc has been selected to be hidden - * - * @param name npc name - */ - void removeHiddenNpcName(String name); - - /** - * Sets whether projectiles are hidden. - * - * @param state new projectile hidden state - */ - void setProjectilesHidden(boolean state); - - /** - * Sets whether dead NPCs are hidden. - * - * @param state new NPC hidden state - */ - void setDeadNPCsHidden(boolean state); - - /** - * The provided ids will not be hidden when the - * entity-hider attempts to hide dead {@link NPC}'s. - * - * @param blacklist set of npc ids. - */ - void setBlacklistDeadNpcs(Set blacklist); - /** * Adds a custom clientscript to the list of available clientscripts. * diff --git a/runelite-api/src/main/java/net/runelite/api/ItemID.java b/runelite-api/src/main/java/net/runelite/api/ItemID.java index 68f1e81882..b3597895b8 100644 --- a/runelite-api/src/main/java/net/runelite/api/ItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/ItemID.java @@ -12677,5 +12677,17 @@ public final class ItemID public static final int VOID_MELEE_HELM_LOR = 27007; public static final int DRAGON_DEFENDER_LT = 27008; public static final int RUNE_DEFENDER_LT = 27009; + public static final int PREFORM = 27010; + public static final int DOUBLE_AMMO_MOULD = 27012; + public static final int KOVACS_GROG = 27014; + public static final int SMITHING_CATALYST = 27017; + public static final int ORE_PACK = 27019; + public static final int COLOSSAL_BLADE = 27021; + public static final int SMITHS_TUNIC = 27023; + public static final int SMITHS_TROUSERS = 27025; + public static final int SMITHS_BOOTS = 27027; + public static final int SMITHS_GLOVES = 27029; + public static final int SMITHS_GLOVES_I = 27031; + public static final int GIANTS_FOUNDRY_TESTER = 27033; /* This file is automatically generated. Do not edit. */ } \ No newline at end of file diff --git a/runelite-api/src/main/java/net/runelite/api/NameableContainer.java b/runelite-api/src/main/java/net/runelite/api/NameableContainer.java index 6e62050d7a..847c18e393 100644 --- a/runelite-api/src/main/java/net/runelite/api/NameableContainer.java +++ b/runelite-api/src/main/java/net/runelite/api/NameableContainer.java @@ -33,6 +33,13 @@ public interface NameableContainer */ int getCount(); + /** + * Get the maximum size of the container. + * + * @return + */ + int getSize(); + /** * Get the members in this container * diff --git a/runelite-api/src/main/java/net/runelite/api/NpcID.java b/runelite-api/src/main/java/net/runelite/api/NpcID.java index 0dc00a80d1..70fddc4af5 100644 --- a/runelite-api/src/main/java/net/runelite/api/NpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NpcID.java @@ -9650,6 +9650,12 @@ public final class NpcID public static final int REANIMATED_HELLHOUND = 11463; public static final int APPRENTICE_TAMARA_11464 = 11464; public static final int APPRENTICE_TAMARA_11465 = 11465; + public static final int SMITHING_CATALYST = 11466; + public static final int HILL_GIANT_11467 = 11467; + public static final int KOVAC = 11468; + public static final int KOVAC_11469 = 11469; + public static final int KOVAC_11470 = 11470; + public static final int KOVAC_11472 = 11472; public static final int TARIK_11473 = 11473; public static final int MAISA_11474 = 11474; public static final int MAISA_11475 = 11475; diff --git a/runelite-api/src/main/java/net/runelite/api/NullItemID.java b/runelite-api/src/main/java/net/runelite/api/NullItemID.java index 97ac498d04..96ffcad99b 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullItemID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullItemID.java @@ -14122,5 +14122,18 @@ public final class NullItemID public static final int NULL_26995 = 26995; public static final int NULL_26998 = 26998; public static final int NULL_26999 = 26999; + public static final int NULL_27011 = 27011; + public static final int NULL_27013 = 27013; + public static final int NULL_27015 = 27015; + public static final int NULL_27016 = 27016; + public static final int NULL_27018 = 27018; + public static final int NULL_27020 = 27020; + public static final int NULL_27022 = 27022; + public static final int NULL_27024 = 27024; + public static final int NULL_27026 = 27026; + public static final int NULL_27028 = 27028; + public static final int NULL_27030 = 27030; + public static final int NULL_27032 = 27032; + public static final int NULL_27034 = 27034; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java index 217962287b..60bb2d45c5 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullNpcID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullNpcID.java @@ -1801,8 +1801,10 @@ public final class NullNpcID public static final int NULL_11461 = 11461; public static final int NULL_11471 = 11471; public static final int NULL_11488 = 11488; + public static final int NULL_11494 = 11494; public static final int NULL_11512 = 11512; public static final int NULL_11559 = 11559; + public static final int NULL_11560 = 11560; public static final int NULL_11567 = 11567; public static final int NULL_11568 = 11568; public static final int NULL_11611 = 11611; diff --git a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java index fe126902af..fe12690901 100644 --- a/runelite-api/src/main/java/net/runelite/api/NullObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/NullObjectID.java @@ -21643,6 +21643,10 @@ public final class NullObjectID public static final int NULL_43851 = 43851; public static final int NULL_43852 = 43852; public static final int NULL_43853 = 43853; + public static final int NULL_43854 = 43854; + public static final int NULL_43855 = 43855; + public static final int NULL_43856 = 43856; + public static final int NULL_43859 = 43859; public static final int NULL_43871 = 43871; public static final int NULL_43872 = 43872; public static final int NULL_43874 = 43874; @@ -22154,5 +22158,139 @@ public final class NullObjectID public static final int NULL_44598 = 44598; public static final int NULL_44599 = 44599; public static final int NULL_44600 = 44600; + public static final int NULL_44603 = 44603; + public static final int NULL_44618 = 44618; + public static final int NULL_44639 = 44639; + public static final int NULL_44640 = 44640; + public static final int NULL_44641 = 44641; + public static final int NULL_44642 = 44642; + public static final int NULL_44643 = 44643; + public static final int NULL_44644 = 44644; + public static final int NULL_44645 = 44645; + public static final int NULL_44646 = 44646; + public static final int NULL_44647 = 44647; + public static final int NULL_44648 = 44648; + public static final int NULL_44649 = 44649; + public static final int NULL_44650 = 44650; + public static final int NULL_44651 = 44651; + public static final int NULL_44652 = 44652; + public static final int NULL_44653 = 44653; + public static final int NULL_44654 = 44654; + public static final int NULL_44655 = 44655; + public static final int NULL_44656 = 44656; + public static final int NULL_44657 = 44657; + public static final int NULL_44658 = 44658; + public static final int NULL_44659 = 44659; + public static final int NULL_44660 = 44660; + public static final int NULL_44661 = 44661; + public static final int NULL_44662 = 44662; + public static final int NULL_44664 = 44664; + public static final int NULL_44665 = 44665; + public static final int NULL_44666 = 44666; + public static final int NULL_44667 = 44667; + public static final int NULL_44668 = 44668; + public static final int NULL_44669 = 44669; + public static final int NULL_44670 = 44670; + public static final int NULL_44671 = 44671; + public static final int NULL_44672 = 44672; + public static final int NULL_44673 = 44673; + public static final int NULL_44674 = 44674; + public static final int NULL_44675 = 44675; + public static final int NULL_44676 = 44676; + public static final int NULL_44677 = 44677; + public static final int NULL_44678 = 44678; + public static final int NULL_44679 = 44679; + public static final int NULL_44680 = 44680; + public static final int NULL_44681 = 44681; + public static final int NULL_44682 = 44682; + public static final int NULL_44684 = 44684; + public static final int NULL_44685 = 44685; + public static final int NULL_44686 = 44686; + public static final int NULL_44687 = 44687; + public static final int NULL_44688 = 44688; + public static final int NULL_44689 = 44689; + public static final int NULL_44690 = 44690; + public static final int NULL_44691 = 44691; + public static final int NULL_44692 = 44692; + public static final int NULL_44693 = 44693; + public static final int NULL_44694 = 44694; + public static final int NULL_44695 = 44695; + public static final int NULL_44696 = 44696; + public static final int NULL_44697 = 44697; + public static final int NULL_44698 = 44698; + public static final int NULL_44699 = 44699; + public static final int NULL_44700 = 44700; + public static final int NULL_44701 = 44701; + public static final int NULL_44702 = 44702; + public static final int NULL_44703 = 44703; + public static final int NULL_44704 = 44704; + public static final int NULL_44705 = 44705; + public static final int NULL_44706 = 44706; + public static final int NULL_44707 = 44707; + public static final int NULL_44708 = 44708; + public static final int NULL_44709 = 44709; + public static final int NULL_44710 = 44710; + public static final int NULL_44711 = 44711; + public static final int NULL_44712 = 44712; + public static final int NULL_44713 = 44713; + public static final int NULL_44714 = 44714; + public static final int NULL_44715 = 44715; + public static final int NULL_44716 = 44716; + public static final int NULL_44717 = 44717; + public static final int NULL_44718 = 44718; + public static final int NULL_44719 = 44719; + public static final int NULL_44720 = 44720; + public static final int NULL_44721 = 44721; + public static final int NULL_44722 = 44722; + public static final int NULL_44723 = 44723; + public static final int NULL_44724 = 44724; + public static final int NULL_44725 = 44725; + public static final int NULL_44729 = 44729; + public static final int NULL_44730 = 44730; + public static final int NULL_44731 = 44731; + public static final int NULL_44732 = 44732; + public static final int NULL_44733 = 44733; + public static final int NULL_44734 = 44734; + public static final int NULL_44735 = 44735; + public static final int NULL_44736 = 44736; + public static final int NULL_44737 = 44737; + public static final int NULL_44738 = 44738; + public static final int NULL_44739 = 44739; + public static final int NULL_44740 = 44740; + public static final int NULL_44741 = 44741; + public static final int NULL_44742 = 44742; + public static final int NULL_44743 = 44743; + public static final int NULL_44744 = 44744; + public static final int NULL_44745 = 44745; + public static final int NULL_44746 = 44746; + public static final int NULL_44747 = 44747; + public static final int NULL_44748 = 44748; + public static final int NULL_44749 = 44749; + public static final int NULL_44750 = 44750; + public static final int NULL_44751 = 44751; + public static final int NULL_44752 = 44752; + public static final int NULL_44753 = 44753; + public static final int NULL_44754 = 44754; + public static final int NULL_44755 = 44755; + public static final int NULL_44756 = 44756; + public static final int NULL_44757 = 44757; + public static final int NULL_44758 = 44758; + public static final int NULL_44759 = 44759; + public static final int NULL_44760 = 44760; + public static final int NULL_44764 = 44764; + public static final int NULL_44765 = 44765; + public static final int NULL_44766 = 44766; + public static final int NULL_44767 = 44767; + public static final int NULL_44768 = 44768; + public static final int NULL_44769 = 44769; + public static final int NULL_44770 = 44770; + public static final int NULL_44771 = 44771; + public static final int NULL_44773 = 44773; + public static final int NULL_44774 = 44774; + public static final int NULL_44775 = 44775; + public static final int NULL_44776 = 44776; + public static final int NULL_44777 = 44777; + public static final int NULL_44778 = 44778; + public static final int NULL_44779 = 44779; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/ObjectID.java b/runelite-api/src/main/java/net/runelite/api/ObjectID.java index 2133546b01..79b28f50e0 100644 --- a/runelite-api/src/main/java/net/runelite/api/ObjectID.java +++ b/runelite-api/src/main/java/net/runelite/api/ObjectID.java @@ -17473,7 +17473,7 @@ public final class ObjectID public static final int OLD_MANS_COFFIN = 33265; public static final int OLD_SHRINE = 33307; public static final int BARREL_OF_WATER = 33308; - public static final int BUCKETS = 33309; + public static final int PILE_OF_BUCKETS = 33309; public static final int FIRE_PIT_33310 = 33310; public static final int FIRE_33311 = 33311; public static final int LITTLE_BOULDER = 33312; @@ -20915,7 +20915,7 @@ public final class ObjectID public static final int MOUNTED_HARPOONFISH = 40963; public static final int HAMMERS_40964 = 40964; public static final int ROPES = 40965; - public static final int BUCKETS_40966 = 40966; + public static final int BUCKETS = 40966; public static final int HARPOONS = 40967; public static final int CRATE_40993 = 40993; public static final int BARREL_40994 = 40994; @@ -22197,6 +22197,15 @@ public final class ObjectID public static final int BLOOD_RIFT_43825 = 43825; public static final int PLANT_43827 = 43827; public static final int BARRIER_43849 = 43849; + public static final int BROKEN_TRIP_HAMMER = 43857; + public static final int REPAIRED_TRIP_HAMMER = 43858; + public static final int BROKEN_GRINDSTONE = 43860; + public static final int REPAIRED_GRINDSTONE = 43861; + public static final int BROKEN_POLISHING_WHEEL = 43862; + public static final int REPAIRED_POLISHING_WHEEL = 43863; + public static final int CRUCIBLE = 43864; + public static final int MOULD_JIG = 43865; + public static final int BIG_CHEST_43866 = 43866; public static final int RUBBLE_43867 = 43867; public static final int STAIRS_43868 = 43868; public static final int SCIMITAR = 43869; @@ -22419,5 +22428,49 @@ public final class ObjectID public static final int LION_GUARD = 44584; public static final int WARP = 44585; public static final int WARP_44586 = 44586; + public static final int LAVA_POOL = 44601; + public static final int WATERFALL_44602 = 44602; + public static final int PREFORM_STORAGE = 44604; + public static final int CRATE_44605 = 44605; + public static final int BELT_SYSTEM = 44606; + public static final int BROKEN_TRIP_HAMMER_44607 = 44607; + public static final int BROKEN_GRINDSTONE_44608 = 44608; + public static final int BROKEN_POLISHING_WHEEL_44609 = 44609; + public static final int EXIT_44610 = 44610; + public static final int CRUCIBLE_44611 = 44611; + public static final int MOULD_JIG_44612 = 44612; + public static final int BIG_CHEST_44613 = 44613; + public static final int LAVA_POOL_44614 = 44614; + public static final int WATERFALL_44615 = 44615; + public static final int PREFORM_STORAGE_44616 = 44616; + public static final int CRATE_44617 = 44617; + public static final int TRIP_HAMMER = 44619; + public static final int GRINDSTONE = 44620; + public static final int POLISHING_WHEEL = 44621; + public static final int CRUCIBLE_EMPTY = 44622; + public static final int CRUCIBLE_PARTIALLY_FULL = 44623; + public static final int CRUCIBLE_FULL = 44624; + public static final int MOULD_JIG_EMPTY = 44625; + public static final int MOULD_JIG_SETUP = 44626; + public static final int MOULD_JIG_POURED_METAL = 44627; + public static final int MOULD_JIG_COOLING_METAL = 44628; + public static final int MOULD_JIG_COOLED_METAL = 44629; + public static final int BANK_CHEST_44630 = 44630; + public static final int LAVA_POOL_44631 = 44631; + public static final int WATERFALL_44632 = 44632; + public static final int PREFORM_STORAGE_44633 = 44633; + public static final int PREFORM_STORAGE_44634 = 44634; + public static final int CAVE_44635 = 44635; + public static final int EXIT_44636 = 44636; + public static final int CRATE_44637 = 44637; + public static final int CRATE_44638 = 44638; + public static final int WATERFALL_44663 = 44663; + public static final int MOULDS = 44683; + public static final int CHEST_44726 = 44726; + public static final int HAMMER_44727 = 44727; + public static final int WHEELBARROW_44728 = 44728; + public static final int WATERWHEEL = 44761; + public static final int BELT_SYSTEM_44762 = 44762; + public static final int BELT_SYSTEM_44763 = 44763; /* This file is automatically generated. Do not edit. */ } diff --git a/runelite-api/src/main/java/net/runelite/api/VarPlayer.java b/runelite-api/src/main/java/net/runelite/api/VarPlayer.java index 8250c85ae6..c3eaa4bea0 100644 --- a/runelite-api/src/main/java/net/runelite/api/VarPlayer.java +++ b/runelite-api/src/main/java/net/runelite/api/VarPlayer.java @@ -41,6 +41,7 @@ public enum VarPlayer { POUCH_STATUS(261), DUEL_PENDING(286), + CANNON_AMMO(3), ATTACK_STYLE(43), QUEST_POINTS(101), IS_POISONED(102), diff --git a/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java b/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java index 0b33edbd38..bf2c40b82b 100644 --- a/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java +++ b/runelite-api/src/main/java/net/runelite/api/hooks/Callbacks.java @@ -30,6 +30,7 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.util.List; import net.runelite.api.MainBufferProvider; +import net.runelite.api.Renderable; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetItem; @@ -185,4 +186,12 @@ public interface Callbacks * @param keyEvent the key event */ void keyTyped(KeyEvent keyEvent); -} \ No newline at end of file + + /** + * Called to test if a renderable should be drawn this frame + * @param renderable the renderable + * @param drawingUi if this is the 2d ui, such as hp bars or hitsplats + * @return false to prevent drawing + */ + boolean draw(Renderable renderable, boolean drawingUi); +} diff --git a/runelite-client/src/main/java/net/runelite/client/RuneLite.java b/runelite-client/src/main/java/net/runelite/client/RuneLite.java index 8110daa3a2..259b6c7ed8 100644 --- a/runelite-client/src/main/java/net/runelite/client/RuneLite.java +++ b/runelite-client/src/main/java/net/runelite/client/RuneLite.java @@ -360,6 +360,7 @@ public class RuneLite // Client size must be set prior to init applet.setSize(Constants.GAME_FIXED_SIZE); + System.setProperty("jagex.disableBouncyCastle", "true"); // Change user.home so the client places jagexcache in the .runelite directory String oldHome = System.setProperty("user.home", RUNELITE_DIR.getAbsolutePath()); try diff --git a/runelite-client/src/main/java/net/runelite/client/account/AccountClient.java b/runelite-client/src/main/java/net/runelite/client/account/AccountClient.java index 4c26a60170..6cacaafccc 100644 --- a/runelite-client/src/main/java/net/runelite/client/account/AccountClient.java +++ b/runelite-client/src/main/java/net/runelite/client/account/AccountClient.java @@ -57,12 +57,12 @@ public class AccountClient this.apiBase = apiBase; } - public OAuthResponse login() throws IOException + public OAuthResponse login(int port) throws IOException { HttpUrl url = apiBase.newBuilder() .addPathSegment("account") .addPathSegment("login") - .addQueryParameter("uuid", uuid.toString()) + .addQueryParameter("port", Integer.toString(port)) .build(); log.debug("Built URI: {}", url); diff --git a/runelite-client/src/main/java/net/runelite/client/account/AccountSession.java b/runelite-client/src/main/java/net/runelite/client/account/AccountSession.java index dc1534ab94..c50b5720f4 100644 --- a/runelite-client/src/main/java/net/runelite/client/account/AccountSession.java +++ b/runelite-client/src/main/java/net/runelite/client/account/AccountSession.java @@ -35,5 +35,5 @@ public class AccountSession { private final UUID uuid; private final Instant created; - private String username; + private final String username; } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java index 411c79eb15..0a687f02c5 100644 --- a/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java +++ b/runelite-client/src/main/java/net/runelite/client/account/SessionManager.java @@ -25,12 +25,14 @@ package net.runelite.client.account; import com.google.gson.Gson; +import com.sun.net.httpserver.HttpServer; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Writer; +import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.time.Instant; @@ -42,13 +44,11 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.EventBus; -import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.SessionClose; import net.runelite.client.events.SessionOpen; import net.runelite.client.util.LinkBrowser; -import net.runelite.client.ws.WSClient; import net.runelite.http.api.account.OAuthResponse; -import net.runelite.http.api.ws.messages.LoginResponse; +import okhttp3.HttpUrl; @Singleton @Slf4j @@ -59,26 +59,29 @@ public class SessionManager private final EventBus eventBus; private final ConfigManager configManager; - private final WSClient wsClient; private final File sessionFile; private final AccountClient accountClient; private final Gson gson; + private final String oauthRedirect; + + private HttpServer server; @Inject private SessionManager( @Named("sessionfile") File sessionfile, ConfigManager configManager, EventBus eventBus, - WSClient wsClient, AccountClient accountClient, - Gson gson) + Gson gson, + @Named("runelite.oauth.redirect") String oauthRedirect + ) { this.configManager = configManager; this.eventBus = eventBus; - this.wsClient = wsClient; this.sessionFile = sessionfile; this.accountClient = accountClient; this.gson = gson; + this.oauthRedirect = oauthRedirect; eventBus.register(this); } @@ -113,7 +116,7 @@ public class SessionManager return; } - openSession(session, false); + openSession(session); } private void saveSession() @@ -141,19 +144,12 @@ public class SessionManager } /** - * Set the given session as the active session and open a socket to the - * server with the given session + * Set the given session as the active session * * @param session session */ - private void openSession(AccountSession session, boolean openSocket) + private void openSession(AccountSession session) { - // Change session on the websocket - if (openSocket) - { - wsClient.changeSession(session.getUuid()); - } - accountSession = session; if (session.getUsername() != null) @@ -170,8 +166,6 @@ public class SessionManager private void closeSession() { - wsClient.changeSession(null); - if (accountSession == null) { return; @@ -199,49 +193,85 @@ public class SessionManager public void login() { - // If a session is already open, use that id. Otherwise generate a new id. - UUID uuid = wsClient.getSessionId() != null ? wsClient.getSessionId() : UUID.randomUUID(); - accountClient.setUuid(uuid); + if (server == null) + { + try + { + startServer(); + } + catch (IOException ex) + { + log.error("Unable to start http server", ex); + return; + } + } final OAuthResponse login; try { - login = accountClient.login(); + login = accountClient.login(server.getAddress().getPort()); } catch (IOException ex) { - log.warn("Unable to get oauth url", ex); + log.error("Unable to get oauth url", ex); return; } - // Create new session - openSession(new AccountSession(login.getUid(), Instant.now()), true); - // Navigate to login link LinkBrowser.browse(login.getOauthUrl()); } - @Subscribe - public void onLoginResponse(LoginResponse loginResponse) - { - log.debug("Now signed in as {}", loginResponse.getUsername()); - - AccountSession session = getAccountSession(); - session.setUsername(loginResponse.getUsername()); - - // Open session, again, now that we have a username - // This triggers onSessionOpen - // The socket is already opened here anyway so we pass true for openSocket - openSession(session, true); - - // Save session to disk - saveSession(); - } - public void logout() { closeSession(); deleteSession(); } + + private void startServer() throws IOException + { + server = HttpServer.create(new InetSocketAddress("localhost", 0), 1); + server.createContext("/oauth", req -> + { + try + { + final HttpUrl url = HttpUrl.get("http://localhost" + req.getRequestURI()); + final String username = url.queryParameter("username"); + final UUID sessionId = UUID.fromString(url.queryParameter("sessionId")); + + log.debug("Now signed in as {}", username); + + // open the session, which triggers the sessonopen event + AccountSession session = new AccountSession(sessionId, Instant.now(), username); + openSession(session); + + // Save session to disk + saveSession(); + + req.getResponseHeaders().set("Location", oauthRedirect); + req.sendResponseHeaders(302, 0); + } + catch (Exception e) + { + log.warn("failure serving oauth response", e); + req.sendResponseHeaders(400, 0); + req.getResponseBody().write(e.getMessage().getBytes(StandardCharsets.UTF_8)); + } + finally + { + req.close(); + stopServer(); + } + }); + + log.debug("Starting server {}", server); + server.start(); + } + + private void stopServer() + { + log.debug("Stopping server {}", server); + server.stop(0); + server = null; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java index bf163a985b..6eca66d2c3 100644 --- a/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java +++ b/runelite-client/src/main/java/net/runelite/client/callback/Hooks.java @@ -36,6 +36,7 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.image.BufferedImage; import java.awt.image.VolatileImage; +import java.util.ArrayList; import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; @@ -112,6 +113,14 @@ public class Hooks implements Callbacks private static MainBufferProvider lastMainBufferProvider; private static Graphics2D lastGraphics; + @FunctionalInterface + public interface RenderableDrawListener + { + boolean draw(Renderable renderable, boolean ui); + } + + private final List renderableDrawListeners = new ArrayList<>(); + /** * Get the Graphics2D for the MainBufferProvider image * This caches the Graphics2D instance so it can be reused @@ -219,7 +228,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("error during main loop tasks", ex); + log.error("error during main loop tasks", ex); } } @@ -344,7 +353,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("Error during overlay rendering", ex); + log.error("Error during overlay rendering", ex); } notifier.processFlash(graphics2d); @@ -439,7 +448,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("Error during overlay rendering", ex); + log.error("Error during overlay rendering", ex); } } @@ -455,7 +464,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("Error during overlay rendering", ex); + log.error("Error during overlay rendering", ex); } } @@ -507,7 +516,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("Error during overlay rendering", ex); + log.error("Error during overlay rendering", ex); } } @@ -523,7 +532,7 @@ public class Hooks implements Callbacks } catch (Exception ex) { - log.warn("Error during overlay rendering", ex); + log.error("Error during overlay rendering", ex); } } @@ -549,7 +558,16 @@ public class Hooks implements Callbacks eventBus.post(fakeXpDrop); } - + public void registerRenderableDrawListener(RenderableDrawListener listener) + { + renderableDrawListeners.add(listener); + } + + public void unregisterRenderableDrawListener(RenderableDrawListener listener) + { + renderableDrawListeners.remove(listener); + } + public static void clearColorBuffer(int x, int y, int width, int height, int color) { BufferProvider bp = client.getBufferProvider(); @@ -588,4 +606,24 @@ public class Hooks implements Callbacks client.getCallbacks().post(event); return event.isConsumed(); } + + @Override + public boolean draw(Renderable renderable, boolean drawingUi) + { + try + { + for (RenderableDrawListener renderableDrawListener : renderableDrawListeners) + { + if (!renderableDrawListener.draw(renderable, drawingUi)) + { + return false; + } + } + } + catch (Exception ex) + { + log.error("exception from renderable draw listener", ex); + } + return true; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/ws/PartyMember.java b/runelite-client/src/main/java/net/runelite/client/party/PartyMember.java similarity index 97% rename from runelite-client/src/main/java/net/runelite/client/ws/PartyMember.java rename to runelite-client/src/main/java/net/runelite/client/party/PartyMember.java index cdc6ac1033..70789f58f5 100644 --- a/runelite-client/src/main/java/net/runelite/client/ws/PartyMember.java +++ b/runelite-client/src/main/java/net/runelite/client/party/PartyMember.java @@ -22,7 +22,7 @@ * (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.ws; +package net.runelite.client.party; import java.awt.image.BufferedImage; import java.util.UUID; diff --git a/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java b/runelite-client/src/main/java/net/runelite/client/party/PartyService.java similarity index 85% rename from runelite-client/src/main/java/net/runelite/client/ws/PartyService.java rename to runelite-client/src/main/java/net/runelite/client/party/PartyService.java index 123a172a0b..ebd9371d0f 100644 --- a/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java +++ b/runelite-client/src/main/java/net/runelite/client/party/PartyService.java @@ -23,7 +23,7 @@ * (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.ws; +package net.runelite.client.party; import com.google.common.base.CharMatcher; import com.google.common.hash.Hashing; @@ -44,22 +44,21 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameState; import net.runelite.api.ItemComposition; -import net.runelite.client.account.AccountSession; -import net.runelite.client.account.SessionManager; import net.runelite.client.chat.ChatMessageManager; import net.runelite.client.chat.QueuedMessage; import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.PartyChanged; import net.runelite.client.events.PartyMemberAvatar; +import net.runelite.client.party.messages.Join; +import net.runelite.client.party.messages.Part; +import net.runelite.client.party.messages.PartyChatMessage; +import net.runelite.client.party.messages.PartyMessage; +import net.runelite.client.party.messages.UserJoin; +import net.runelite.client.party.messages.UserPart; +import net.runelite.client.party.messages.UserSync; import net.runelite.client.util.Text; import static net.runelite.client.util.Text.JAGEX_PRINTABLE_CHAR_MATCHER; -import net.runelite.http.api.ws.messages.party.Join; -import net.runelite.http.api.ws.messages.party.Part; -import net.runelite.http.api.ws.messages.party.PartyChatMessage; -import net.runelite.http.api.ws.messages.party.UserJoin; -import net.runelite.http.api.ws.messages.party.UserPart; -import net.runelite.http.api.ws.messages.party.UserSync; @Slf4j @Singleton @@ -72,7 +71,6 @@ public class PartyService private final Client client; private final WSClient wsClient; - private final SessionManager sessionManager; private final EventBus eventBus; private final ChatMessageManager chat; private final List members = new ArrayList<>(); @@ -83,11 +81,10 @@ public class PartyService private String partyPassphrase; @Inject - private PartyService(final Client client, final WSClient wsClient, final SessionManager sessionManager, final EventBus eventBus, final ChatMessageManager chat) + private PartyService(final Client client, final WSClient wsClient, final EventBus eventBus, final ChatMessageManager chat) { this.client = client; this.wsClient = wsClient; - this.sessionManager = sessionManager; this.eventBus = eventBus; this.chat = chat; eventBus.register(this); @@ -169,12 +166,7 @@ public class PartyService if (partyId == null) { - // close the websocket if the session id isn't for an account - if (sessionManager.getAccountSession() == null) - { - wsClient.changeSession(null); - } - + wsClient.changeSession(null); eventBus.post(new PartyChanged(partyPassphrase, partyId)); return; } @@ -182,16 +174,29 @@ public class PartyService // If there isn't already a session open, open one if (!wsClient.sessionExists()) { - AccountSession accountSession = sessionManager.getAccountSession(); - // Use the existing account session, if it exists, otherwise generate a new session id - UUID uuid = accountSession != null ? accountSession.getUuid() : UUID.randomUUID(); - wsClient.changeSession(uuid); + wsClient.changeSession(UUID.randomUUID()); } eventBus.post(new PartyChanged(partyPassphrase, partyId)); wsClient.send(new Join(partyId, USERNAME)); } + public void send(T message) + { + if (!wsClient.isOpen()) + { + log.debug("Reconnecting to server"); + + PartyMember local = getLocalMember(); + members.removeIf(m -> m != local); + + wsClient.connect(); + wsClient.send(new Join(partyId, USERNAME)); + } + + wsClient.send(message); + } + @Subscribe(priority = 1) // run prior to plugins so that the member is joined by the time the plugins see it. public void onUserJoin(final UserJoin message) { @@ -202,13 +207,17 @@ public class PartyService return; } - final PartyMember partyMember = new PartyMember(message.getMemberId(), cleanUsername(message.getName())); - members.add(partyMember); + PartyMember partyMember = getMemberById(message.getMemberId()); + if (partyMember == null) + { + partyMember = new PartyMember(message.getMemberId(), cleanUsername(message.getName())); + members.add(partyMember); + log.debug("User {} joins party, {} members", partyMember, members.size()); + } final PartyMember localMember = getLocalMember(); - // Send info to other clients that this user successfully finished joining party - if (localMember != null && message.getMemberId().equals(localMember.getMemberId())) + if (localMember != null && localMember == partyMember) { final UserSync userSync = new UserSync(); userSync.setMemberId(message.getMemberId()); @@ -219,7 +228,10 @@ public class PartyService @Subscribe(priority = 1) // run prior to plugins so that the member is removed by the time the plugins see it. public void onUserPart(final UserPart message) { - members.removeIf(member -> member.getMemberId().equals(message.getMemberId())); + if (members.removeIf(member -> member.getMemberId().equals(message.getMemberId()))) + { + log.debug("User {} leaves party, {} members", message.getMemberId(), members.size()); + } } @Subscribe diff --git a/runelite-client/src/main/java/net/runelite/client/ws/WSClient.java b/runelite-client/src/main/java/net/runelite/client/party/WSClient.java similarity index 94% rename from runelite-client/src/main/java/net/runelite/client/ws/WSClient.java rename to runelite-client/src/main/java/net/runelite/client/party/WSClient.java index ea42605075..302ebcbcc5 100644 --- a/runelite-client/src/main/java/net/runelite/client/ws/WSClient.java +++ b/runelite-client/src/main/java/net/runelite/client/party/WSClient.java @@ -22,7 +22,7 @@ * (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.ws; +package net.runelite.client.party; import com.google.gson.Gson; import com.google.gson.JsonParseException; @@ -37,10 +37,9 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.runelite.client.RuneLite; import net.runelite.client.eventbus.EventBus; -import net.runelite.http.api.ws.WebsocketGsonFactory; -import net.runelite.http.api.ws.WebsocketMessage; -import net.runelite.http.api.ws.messages.Handshake; -import net.runelite.http.api.ws.messages.party.PartyMessage; +import net.runelite.client.party.messages.Handshake; +import net.runelite.client.party.messages.PartyMessage; +import net.runelite.client.party.messages.WebsocketMessage; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -97,7 +96,7 @@ public class WSClient extends WebSocketListener implements AutoCloseable } } - private void connect() + void connect() { if (sessionId == null) { @@ -116,6 +115,11 @@ public class WSClient extends WebSocketListener implements AutoCloseable send(handshake); } + boolean isOpen() + { + return webSocket != null; + } + public void registerMessage(final Class message) { if (messages.add(message)) diff --git a/runelite-client/src/main/java/net/runelite/client/party/WebsocketGsonFactory.java b/runelite-client/src/main/java/net/runelite/client/party/WebsocketGsonFactory.java new file mode 100644 index 0000000000..f88330636c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/WebsocketGsonFactory.java @@ -0,0 +1,88 @@ +/* + * 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.client.party; + +import com.google.gson.Gson; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import net.runelite.client.party.messages.Handshake; +import net.runelite.client.party.messages.Join; +import net.runelite.client.party.messages.Part; +import net.runelite.client.party.messages.PartyChatMessage; +import net.runelite.client.party.messages.UserJoin; +import net.runelite.client.party.messages.UserPart; +import net.runelite.client.party.messages.UserSync; +import net.runelite.client.party.messages.WebsocketMessage; +import net.runelite.client.util.RuntimeTypeAdapterFactory; +import net.runelite.http.api.RuneLiteAPI; + +public class WebsocketGsonFactory +{ + private static final Collection> MESSAGES; + + static + { + final List> messages = new ArrayList<>(); + messages.add(Handshake.class); + messages.add(Join.class); + messages.add(Part.class); + messages.add(UserJoin.class); + messages.add(UserPart.class); + messages.add(UserSync.class); + messages.add(PartyChatMessage.class); + MESSAGES = messages; + } + + public static RuntimeTypeAdapterFactory factory(final Collection> messages) + { + final RuntimeTypeAdapterFactory factory = RuntimeTypeAdapterFactory.of(WebsocketMessage.class); + + for (Class message : MESSAGES) + { + factory.registerSubtype(message); + } + + for (Class message : messages) + { + factory.registerSubtype(message); + } + + return factory; + } + + public static Gson build(final RuntimeTypeAdapterFactory factory) + { + return RuneLiteAPI.GSON.newBuilder() + .registerTypeAdapterFactory(factory) + .create(); + } + + public static Gson build() + { + return build(factory(Collections.emptyList())); + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/Handshake.java b/runelite-client/src/main/java/net/runelite/client/party/messages/Handshake.java new file mode 100644 index 0000000000..ac9f9b9d3c --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/Handshake.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.client.party.messages; + +import java.util.UUID; +import lombok.Data; + +@Data +public class Handshake extends WebsocketMessage +{ + private UUID session; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/Join.java b/runelite-client/src/main/java/net/runelite/client/party/messages/Join.java new file mode 100644 index 0000000000..c63fa3ffae --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/Join.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +import java.util.UUID; +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper = true) +public class Join extends WebsocketMessage +{ + private final UUID partyId; + private final String name; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/Part.java b/runelite-client/src/main/java/net/runelite/client/party/messages/Part.java new file mode 100644 index 0000000000..53f903b160 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/Part.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +public class Part extends WebsocketMessage +{ +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/PartyChatMessage.java b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyChatMessage.java new file mode 100644 index 0000000000..32156a9142 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyChatMessage.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019, Tomas Slusny + * 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.party.messages; + +import lombok.Value; + +@Value +public class PartyChatMessage extends PartyMemberMessage +{ + private final String value; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMemberMessage.java b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMemberMessage.java new file mode 100644 index 0000000000..d706360484 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMemberMessage.java @@ -0,0 +1,12 @@ +package net.runelite.client.party.messages; + +import java.util.UUID; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public abstract class PartyMemberMessage extends PartyMessage +{ + private UUID memberId; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMessage.java b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMessage.java new file mode 100644 index 0000000000..58b2327fb4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/PartyMessage.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +public abstract class PartyMessage extends WebsocketMessage +{ + public PartyMessage() + { + _party = true; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/UserJoin.java b/runelite-client/src/main/java/net/runelite/client/party/messages/UserJoin.java new file mode 100644 index 0000000000..2254f93fae --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/UserJoin.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +import java.util.UUID; +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper = true) +public class UserJoin extends WebsocketMessage +{ + private final UUID memberId; + private final UUID partyId; + private final String name; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/UserPart.java b/runelite-client/src/main/java/net/runelite/client/party/messages/UserPart.java new file mode 100644 index 0000000000..2407db13d4 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/UserPart.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +import java.util.UUID; +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper = true) +public class UserPart extends WebsocketMessage +{ + private final UUID memberId; +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/UserSync.java b/runelite-client/src/main/java/net/runelite/client/party/messages/UserSync.java new file mode 100644 index 0000000000..6d06655e95 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/UserSync.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018, Tomas Slusny + * 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.party.messages; + +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper = true) +public class UserSync extends PartyMemberMessage +{ +} diff --git a/runelite-client/src/main/java/net/runelite/client/party/messages/WebsocketMessage.java b/runelite-client/src/main/java/net/runelite/client/party/messages/WebsocketMessage.java new file mode 100644 index 0000000000..1685b58108 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/party/messages/WebsocketMessage.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.client.party.messages; + +public class WebsocketMessage +{ + protected boolean _party; + + public boolean isParty() + { + return _party; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java index 2c69cef83d..19f5712810 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/cannon/CannonPlugin.java @@ -24,14 +24,10 @@ */ package net.runelite.client.plugins.cannon; -import com.google.common.collect.ImmutableSet; import com.google.inject.Provides; import java.awt.Color; import java.util.ArrayList; import java.util.List; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.inject.Inject; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -40,25 +36,22 @@ import net.runelite.api.ChatMessageType; import net.runelite.api.Client; import net.runelite.api.GameObject; import net.runelite.api.GameState; -import net.runelite.api.GraphicID; import net.runelite.api.InventoryID; import net.runelite.api.Item; -import net.runelite.api.ItemContainer; import net.runelite.api.ItemID; import net.runelite.api.MenuAction; import net.runelite.api.ObjectID; import net.runelite.api.Player; -import net.runelite.api.Projectile; +import net.runelite.api.VarPlayer; import net.runelite.api.coords.LocalPoint; import net.runelite.api.coords.WorldArea; import net.runelite.api.coords.WorldPoint; import net.runelite.api.events.ChatMessage; import net.runelite.api.events.GameObjectSpawned; import net.runelite.api.events.GameStateChanged; -import net.runelite.api.events.GameTick; import net.runelite.api.events.ItemContainerChanged; import net.runelite.api.events.MenuOptionClicked; -import net.runelite.api.events.ProjectileMoved; +import net.runelite.api.events.VarbitChanged; import net.runelite.api.widgets.Widget; import net.runelite.api.widgets.WidgetInfo; import net.runelite.client.Notifier; @@ -80,17 +73,10 @@ import net.runelite.client.ui.overlay.infobox.InfoBoxManager; @Slf4j public class CannonPlugin extends Plugin { - private static final Pattern NUMBER_PATTERN = Pattern.compile("([0-9]+)"); static final int MAX_OVERLAY_DISTANCE = 4100; static final int MAX_CBALLS = 30; - private static final Set CANNONBALL_PROJECTILE_IDS = ImmutableSet.of( - GraphicID.CANNONBALL, GraphicID.GRANITE_CANNONBALL, - GraphicID.CANNONBALL_OR, GraphicID.GRANITE_CANNONBALL_OR - ); - private CannonCounter counter; - private boolean skipProjectileCheckThisTick; private boolean cannonBallNotificationSent; private WorldPoint clickedCannonLocation; private boolean firstCannonLoad; @@ -151,6 +137,7 @@ public class CannonPlugin extends Plugin { overlayManager.add(cannonOverlay); overlayManager.add(cannonSpotOverlay); + clientThread.invoke(() -> cballsLeft = client.getVar(VarPlayer.CANNON_AMMO)); } @Override @@ -165,7 +152,6 @@ public class CannonPlugin extends Plugin cannonBallNotificationSent = false; cballsLeft = 0; removeCounter(); - skipProjectileCheckThisTick = false; spotPoints.clear(); } @@ -278,7 +264,7 @@ public class CannonPlugin extends Plugin } } } - + @Subscribe public void onMenuOptionClicked(MenuOptionClicked event) { @@ -309,32 +295,16 @@ public class CannonPlugin extends Plugin } @Subscribe - public void onProjectileMoved(ProjectileMoved event) + public void onVarbitChanged(VarbitChanged varbitChanged) { - Projectile projectile = event.getProjectile(); - - if (CANNONBALL_PROJECTILE_IDS.contains(projectile.getId()) && cannonPosition != null && cannonWorld == client.getWorld()) + if (varbitChanged.getIndex() == VarPlayer.CANNON_AMMO.getId()) { - WorldPoint projectileLoc = WorldPoint.fromLocal(client, projectile.getX1(), projectile.getY1(), client.getPlane()); + cballsLeft = client.getVar(VarPlayer.CANNON_AMMO); - //Check to see if projectile x,y is 0 else it will continuously decrease while ball is flying. - if (cannonPosition.contains(projectileLoc) && projectile.getX() == 0 && projectile.getY() == 0) + if (config.showCannonNotifications() && !cannonBallNotificationSent && cballsLeft > 0 && config.lowWarningThreshold() >= cballsLeft) { - // When there's a chat message about cannon reloaded/unloaded/out of ammo, - // the message event runs before the projectile event. However they run - // in the opposite order on the server. So if both fires in the same tick, - // we don't want to update the cannonball counter if it was set to a specific - // amount. - if (!skipProjectileCheckThisTick) - { - cballsLeft--; - - if (config.showCannonNotifications() && !cannonBallNotificationSent && cballsLeft > 0 && config.lowWarningThreshold() >= cballsLeft) - { - notifier.notify(String.format("Your cannon has %d cannon balls remaining!", cballsLeft)); - cannonBallNotificationSent = true; - } - } + notifier.notify(String.format("Your cannon has %d cannon balls remaining!", cballsLeft)); + cannonBallNotificationSent = true; } } } @@ -351,32 +321,13 @@ public class CannonPlugin extends Plugin { cannonPlaced = true; addCounter(); - cballsLeft = 0; firstCannonLoad = true; - - final ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY); - if (inventory != null) - { - int invCballs = inventory.count(ItemID.GRANITE_CANNONBALL) > 0 - ? inventory.count(ItemID.GRANITE_CANNONBALL) - : inventory.count(ItemID.CANNONBALL); - // Cannonballs are always forcibly loaded after the furnace is added. If the player has more than - // the max number of cannon balls in their inventory, the cannon will always be fully filled. - // This is preferable to using the proceeding "You load the cannon with x cannon balls" message - // since it will show a lower number of cannon balls if the cannon is already partially-filled - // prior to being placed. - if (invCballs >= MAX_CBALLS) - { - cballsLeft = MAX_CBALLS; - } - } } else if (event.getMessage().contains("You pick up the cannon") || event.getMessage().contains("Your cannon has decayed. Speak to Nulodion to get a new one!") || event.getMessage().contains("Your cannon has been destroyed!")) { cannonPlaced = false; - cballsLeft = 0; removeCounter(); cannonPosition = null; } @@ -410,83 +361,21 @@ public class CannonPlugin extends Plugin clickedCannonLocation = null; } - Matcher m = NUMBER_PATTERN.matcher(event.getMessage()); - if (m.find()) - { - // The cannon will usually refill to MAX_CBALLS, but if the - // player didn't have enough cannonballs in their inventory, - // it could fill up less than that. Filling the cannon to - // cballsLeft + amt is not always accurate though because our - // counter doesn't decrease if the player has been too far away - // from the cannon due to the projectiels not being in memory, - // so our counter can be higher than it is supposed to be. - int amt = Integer.valueOf(m.group()); - if (cballsLeft + amt >= MAX_CBALLS) - { - skipProjectileCheckThisTick = true; - cballsLeft = MAX_CBALLS; - } - else - { - cballsLeft += amt; - } - } - else if (event.getMessage().equals("You load the cannon with one cannonball.")) - { - if (cballsLeft + 1 >= MAX_CBALLS) - { - skipProjectileCheckThisTick = true; - cballsLeft = MAX_CBALLS; - } - else - { - cballsLeft++; - } - } - cannonBallNotificationSent = false; } else if (event.getMessage().contains("Your cannon is out of ammo!")) { - skipProjectileCheckThisTick = true; - - // If the player was out of range of the cannon, some cannonballs - // may have been used without the client knowing, so having this - // extra check is a good idea. - cballsLeft = 0; - if (config.showCannonNotifications()) { notifier.notify("Your cannon is out of ammo!"); } } - else if (event.getMessage().startsWith("Your cannon contains")) - { - Matcher m = NUMBER_PATTERN.matcher(event.getMessage()); - if (m.find()) - { - cballsLeft = Integer.parseInt(m.group()); - } - } - else if (event.getMessage().startsWith("You unload your cannon and receive Cannonball") - || event.getMessage().startsWith("You unload your cannon and receive Granite cannonball")) - { - skipProjectileCheckThisTick = true; - - cballsLeft = 0; - } else if (event.getMessage().equals("This isn't your cannon!") || event.getMessage().equals("This is not your cannon.")) { clickedCannonLocation = null; } } - @Subscribe - public void onGameTick(GameTick event) - { - skipProjectileCheckThisTick = false; - } - Color getStateColor() { if (cballsLeft > 15) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java index 32dd1709d9..94aefa7402 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatchannel/ChatChannelPlugin.java @@ -608,7 +608,7 @@ public class ChatChannelPlugin extends Plugin Widget chatTitle = client.getWidget(WidgetInfo.FRIENDS_CHAT_TITLE); if (friendsChatManager != null && friendsChatManager.getCount() > 0 && chatTitle != null) { - chatTitle.setText(chatTitle.getText() + " (" + friendsChatManager.getCount() + "/100)"); + chatTitle.setText(chatTitle.getText() + " (" + friendsChatManager.getCount() + "/" + friendsChatManager.getSize() + ")"); } } else if (event.getScriptId() == ScriptID.CLAN_SIDEPANEL_DRAW) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java index e5befde35f..8ed1c51fea 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/chatfilter/ChatFilterPlugin.java @@ -320,7 +320,9 @@ public class ChatFilterPlugin extends Plugin String censorMessage(final String username, final String message) { String strippedMessage = jagexPrintableCharMatcher.retainFrom(message) - .replace('\u00A0', ' '); + .replace('\u00A0', ' ') + .replaceAll("", "<") + .replaceAll("", ">"); String strippedAccents = stripAccents(strippedMessage); assert strippedMessage.length() == strippedAccents.length(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java index 58cf1cad70..a7de70a68f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java @@ -51,6 +51,10 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.discord.DiscordService; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; +import net.runelite.client.party.PartyMember; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; +import net.runelite.client.party.messages.UserSync; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.task.Schedule; @@ -58,11 +62,7 @@ import net.runelite.client.ui.ClientToolbar; import net.runelite.client.ui.NavigationButton; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.LinkBrowser; -import net.runelite.client.ws.PartyMember; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; import net.runelite.discord.DiscordUser; -import net.runelite.http.api.ws.messages.party.UserSync; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; @@ -281,7 +281,7 @@ public class DiscordPlugin extends Plugin discordUser.avatar ); userInfo.setMemberId(localMember.getMemberId()); - wsClient.send(userInfo); + partyService.send(userInfo); } } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java index 1f96e67051..0d0c5b6e52 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordUserInfo.java @@ -26,7 +26,7 @@ package net.runelite.client.plugins.discord; import lombok.EqualsAndHashCode; import lombok.Value; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Value @EqualsAndHashCode(callSuper = true) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java index ecd962ce85..5a71ea0da8 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsCounterPlugin.java @@ -47,9 +47,9 @@ import net.runelite.client.events.PartyChanged; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; -import net.runelite.client.ws.PartyMember; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; +import net.runelite.client.party.PartyMember; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; @PluginDescriptor( name = "DPS Counter", @@ -199,7 +199,7 @@ public class DpsCounterPlugin extends Plugin { final DpsUpdate dpsUpdate = new DpsUpdate(hit, isBoss); dpsUpdate.setMemberId(localMember.getMemberId()); - wsClient.send(dpsUpdate); + partyService.send(dpsUpdate); } if (dpsConfig.bossDamage() && !isBoss) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java index ead4ded77e..538a154495 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsOverlay.java @@ -42,7 +42,7 @@ import net.runelite.client.ui.overlay.components.TitleComponent; import net.runelite.client.ui.overlay.tooltip.Tooltip; import net.runelite.client.ui.overlay.tooltip.TooltipManager; import net.runelite.client.util.QuantityFormatter; -import net.runelite.client.ws.PartyService; +import net.runelite.client.party.PartyService; class DpsOverlay extends OverlayPanel { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java index ee1b652c34..ba37b04a44 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/dpscounter/DpsUpdate.java @@ -27,7 +27,7 @@ package net.runelite.client.plugins.dpscounter; import lombok.EqualsAndHashCode; import lombok.Value; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Value @EqualsAndHashCode(callSuper = true) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java index 2d34d5e813..a8754571e4 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/entityhider/EntityHiderPlugin.java @@ -25,9 +25,16 @@ */ package net.runelite.client.plugins.entityhider; +import com.google.common.annotations.VisibleForTesting; import com.google.inject.Provides; import javax.inject.Inject; import net.runelite.api.Client; +import net.runelite.api.NPC; +import net.runelite.api.Player; +import net.runelite.api.Projectile; +import net.runelite.api.Renderable; +import net.runelite.api.Varbits; +import net.runelite.client.callback.Hooks; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; @@ -48,6 +55,25 @@ public class EntityHiderPlugin extends Plugin @Inject private EntityHiderConfig config; + @Inject + private Hooks hooks; + + private boolean hideOthers; + private boolean hideOthers2D; + private boolean hideFriends; + private boolean hideFriendsChatMembers; + private boolean hideClanMembers; + private boolean hideIgnoredPlayers; + private boolean hideLocalPlayer; + private boolean hideLocalPlayer2D; + private boolean hideNPCs; + private boolean hideNPCs2D; + private boolean hidePets; + private boolean hideAttackers; + private boolean hideProjectiles; + + private final Hooks.RenderableDrawListener drawListener = this::shouldDraw; + @Provides EntityHiderConfig provideConfig(ConfigManager configManager) { @@ -58,6 +84,14 @@ public class EntityHiderPlugin extends Plugin protected void startUp() { updateConfig(); + + hooks.registerRenderableDrawListener(drawListener); + } + + @Override + protected void shutDown() + { + hooks.unregisterRenderableDrawListener(drawListener); } @Subscribe @@ -71,52 +105,107 @@ public class EntityHiderPlugin extends Plugin private void updateConfig() { - client.setIsHidingEntities(true); + hideOthers = config.hideOthers(); + hideOthers2D = config.hideOthers2D(); - client.setOthersHidden(config.hideOthers()); - client.setOthersHidden2D(config.hideOthers2D()); + hideFriends = config.hideFriends(); + hideFriendsChatMembers = config.hideFriendsChatMembers(); + hideClanMembers = config.hideClanChatMembers(); + hideIgnoredPlayers = config.hideIgnores(); - client.setFriendsHidden(config.hideFriends()); - client.setFriendsChatMembersHidden(config.hideFriendsChatMembers()); - client.setClanChatMembersHidden(config.hideClanChatMembers()); - client.setIgnoresHidden(config.hideIgnores()); + hideLocalPlayer = config.hideLocalPlayer(); + hideLocalPlayer2D = config.hideLocalPlayer2D(); - client.setLocalPlayerHidden(config.hideLocalPlayer()); - client.setLocalPlayerHidden2D(config.hideLocalPlayer2D()); + hideNPCs = config.hideNPCs(); + hideNPCs2D = config.hideNPCs2D(); - client.setNPCsHidden(config.hideNPCs()); - client.setNPCsHidden2D(config.hideNPCs2D()); + hidePets = config.hidePets(); - client.setPetsHidden(config.hidePets()); + hideAttackers = config.hideAttackers(); - client.setAttackersHidden(config.hideAttackers()); - - client.setProjectilesHidden(config.hideProjectiles()); + hideProjectiles = config.hideProjectiles(); } - @Override - protected void shutDown() throws Exception + @VisibleForTesting + boolean shouldDraw(Renderable renderable, boolean drawingUI) { - client.setIsHidingEntities(false); + if (renderable instanceof Player) + { + Player player = (Player) renderable; + Player local = client.getLocalPlayer(); - client.setOthersHidden(false); - client.setOthersHidden2D(false); + if (player.getName() == null) + { + // player.isFriend() and player.isFriendsChatMember() npe when the player has a null name + return true; + } - client.setFriendsHidden(false); - client.setFriendsChatMembersHidden(false); - client.setClanChatMembersHidden(false); - client.setIgnoresHidden(false); + // Allow hiding local self in pvp, which is an established meta. + // It is more advantageous than renderself due to being able to still render local player 2d + if (player == local) + { + return !(drawingUI ? hideLocalPlayer2D : hideLocalPlayer); + } - client.setLocalPlayerHidden(false); - client.setLocalPlayerHidden2D(false); + final boolean inPvp = client.getVarbitValue(Varbits.PVP_SPEC_ORB) == 1; + if (inPvp) + { + // In PVP we only allow hiding everyone or no one + return !(drawingUI ? hideOthers2D : hideOthers); + } - client.setNPCsHidden(false); - client.setNPCsHidden2D(false); + if (hideAttackers && player.getInteracting() == local) + { + return false; // hide + } - client.setPetsHidden(false); + if (player.isFriend()) + { + return !hideFriends; + } + if (player.isFriendsChatMember()) + { + return !hideFriendsChatMembers; + } + if (player.isClanMember()) + { + return !hideClanMembers; + } + if (client.getIgnoreContainer().findByName(player.getName()) != null) + { + return !hideIgnoredPlayers; + } - client.setAttackersHidden(false); + return !(drawingUI ? hideOthers2D : hideOthers); + } + else if (renderable instanceof NPC) + { + NPC npc = (NPC) renderable; - client.setProjectilesHidden(false); + if (npc.getComposition().isFollower() && npc != client.getFollower()) + { + return !hidePets; + } + + if (npc.getInteracting() == client.getLocalPlayer()) + { + boolean b = hideAttackers; + // Kludge to make hide attackers only affect 2d or 3d if the 2d or 3d hide is on + // This allows hiding 2d for all npcs, including attackers. + if (hideNPCs2D || hideNPCs) + { + b &= drawingUI ? hideNPCs2D : hideNPCs; + } + return !b; + } + + return !(drawingUI ? hideNPCs2D : hideNPCs); + } + else if (renderable instanceof Projectile) + { + return !hideProjectiles; + } + + return true; } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java index 67edf4a1e5..8a55d92c67 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/MiningPlugin.java @@ -41,11 +41,15 @@ import net.runelite.api.GameObject; import net.runelite.api.GameState; import static net.runelite.api.HintArrowType.WORLD_POSITION; import net.runelite.api.MenuAction; +import static net.runelite.api.ObjectID.DEPLETED_VEIN; import static net.runelite.api.ObjectID.DEPLETED_VEIN_26665; import static net.runelite.api.ObjectID.DEPLETED_VEIN_26666; import static net.runelite.api.ObjectID.DEPLETED_VEIN_26667; import static net.runelite.api.ObjectID.DEPLETED_VEIN_26668; import static net.runelite.api.ObjectID.EMPTY_WALL; +import static net.runelite.api.ObjectID.MINERAL_VEIN; +import static net.runelite.api.ObjectID.MINERAL_VEIN_5990; +import static net.runelite.api.ObjectID.MINERAL_VEIN_5991; import static net.runelite.api.ObjectID.ORE_VEIN_26661; import static net.runelite.api.ObjectID.ORE_VEIN_26662; import static net.runelite.api.ObjectID.ORE_VEIN_26663; @@ -355,12 +359,22 @@ public class MiningPlugin extends Plugin respawns.add(rockRespawn); break; } + case DEPLETED_VEIN: // Depleted gold vein + { + Rock rock = Rock.MINERAL_VEIN; + RockRespawn rockRespawn = new RockRespawn(rock, object.getWorldLocation(), Instant.now(), (int) rock.getRespawnTime(region).toMillis(), rock.getZOffset()); + respawns.add(rockRespawn); + break; + } case ORE_VEIN_26661: // Motherlode vein case ORE_VEIN_26662: // Motherlode vein case ORE_VEIN_26663: // Motherlode vein case ORE_VEIN_26664: // Motherlode vein case ROCKS_41547: // Barronite vein case ROCKS_41548: // Barronite vein + case MINERAL_VEIN: // Arzinian gold vein + case MINERAL_VEIN_5990: // Gold vein + case MINERAL_VEIN_5991: // Gold vein { // If the vein respawns before the timer is up, remove it final WorldPoint point = object.getWorldLocation(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java index ac28366b8b..53535ac93d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/mining/Rock.java @@ -98,7 +98,8 @@ enum Rock TE_SALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33256), BASALT(Duration.of(9, GAME_TICKS), 0, ROCKS_33257), DAEYALT_ESSENCE(Duration.of(MiningRocksOverlay.DAEYALT_MAX_RESPAWN_TIME, GAME_TICKS), 0, DAEYALT_ESSENCE_39095), - BARRONITE(Duration.of(89, GAME_TICKS), 140); + BARRONITE(Duration.of(89, GAME_TICKS), 140), + MINERAL_VEIN(Duration.of(100, GAME_TICKS), 150); private static final int WILDERNESS_RESOURCE_AREA = 12605; private static final int MISCELLANIA = 10044; diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyMemberBox.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyMemberBox.java index 832989f5a5..53c6c8aab2 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyMemberBox.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyMemberBox.java @@ -45,7 +45,7 @@ import net.runelite.client.ui.FontManager; import net.runelite.client.ui.components.MouseDragEventForwarder; import net.runelite.client.ui.components.ProgressBar; import net.runelite.client.util.ImageUtil; -import net.runelite.client.ws.PartyMember; +import net.runelite.client.party.PartyMember; class PartyMemberBox extends JPanel { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java index 2affaf1214..32bbab4ebc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java @@ -47,7 +47,7 @@ import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; import net.runelite.client.ui.components.DragAndDropReorderPane; import net.runelite.client.ui.components.PluginErrorPanel; -import net.runelite.client.ws.PartyService; +import net.runelite.client.party.PartyService; class PartyPanel extends PluginPanel { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java index 927f575b9d..068f3e0efc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java @@ -66,6 +66,12 @@ import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.events.PartyChanged; import net.runelite.client.events.PartyMemberAvatar; +import net.runelite.client.party.PartyMember; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; +import net.runelite.client.party.messages.UserJoin; +import net.runelite.client.party.messages.UserPart; +import net.runelite.client.party.messages.UserSync; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.party.data.PartyData; @@ -83,12 +89,6 @@ import net.runelite.client.ui.overlay.worldmap.WorldMapPointManager; import net.runelite.client.util.ColorUtil; import net.runelite.client.util.ImageUtil; import net.runelite.client.util.Text; -import net.runelite.client.ws.PartyMember; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; -import net.runelite.http.api.ws.messages.party.UserJoin; -import net.runelite.http.api.ws.messages.party.UserPart; -import net.runelite.http.api.ws.messages.party.UserSync; @PluginDescriptor( name = "Party", @@ -104,9 +104,6 @@ public class PartyPlugin extends Plugin @Inject private PartyService party; - @Inject - private WSClient ws; - @Inject private OverlayManager overlayManager; @@ -266,7 +263,7 @@ public class PartyPlugin extends Plugin event.consume(); final TilePing tilePing = new TilePing(selectedSceneTile.getWorldLocation()); tilePing.setMemberId(party.getLocalMember().getMemberId()); - wsClient.send(tilePing); + party.send(tilePing); } @Subscribe @@ -326,7 +323,7 @@ public class PartyPlugin extends Plugin final LocationUpdate locationUpdate = new LocationUpdate(location); locationUpdate.setMemberId(localMember.getMemberId()); - wsClient.send(locationUpdate); + party.send(locationUpdate); } @Subscribe @@ -342,7 +339,7 @@ public class PartyPlugin extends Plugin // Request sync final UserSync userSync = new UserSync(); userSync.setMemberId(party.getLocalMember().getMemberId()); - ws.send(userSync); + party.send(userSync); } } @@ -442,21 +439,21 @@ public class PartyPlugin extends Plugin { final SkillUpdate update = new SkillUpdate(Skill.HITPOINTS, currentHealth, realHealth); update.setMemberId(localMember.getMemberId()); - ws.send(update); + party.send(update); } if (forceSend || currentPrayer != lastPray) { final SkillUpdate update = new SkillUpdate(Skill.PRAYER, currentPrayer, realPrayer); update.setMemberId(localMember.getMemberId()); - ws.send(update); + party.send(update); } if (forceSend || !characterName.equals(lastCharacterName)) { final CharacterNameUpdate update = new CharacterNameUpdate(characterName); update.setMemberId(localMember.getMemberId()); - ws.send(update); + party.send(update); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java index e85e32430c..6ee6360e57 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyWorldMapPoint.java @@ -30,7 +30,7 @@ import net.runelite.api.Point; import net.runelite.api.coords.WorldPoint; import net.runelite.client.ui.overlay.worldmap.WorldMapPoint; import net.runelite.client.util.ImageUtil; -import net.runelite.client.ws.PartyMember; +import net.runelite.client.party.PartyMember; class PartyWorldMapPoint extends WorldMapPoint { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/data/PartyData.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/data/PartyData.java index b821420a68..ee6279ce8a 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/data/PartyData.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/data/PartyData.java @@ -31,7 +31,7 @@ import lombok.RequiredArgsConstructor; import lombok.Setter; import net.runelite.client.ui.overlay.components.PanelComponent; import net.runelite.client.ui.overlay.worldmap.WorldMapPoint; -import net.runelite.client.ws.PartyMember; +import net.runelite.client.party.PartyMember; @Setter @Getter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/CharacterNameUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/CharacterNameUpdate.java index aff6c058c9..576f86aca6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/CharacterNameUpdate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/CharacterNameUpdate.java @@ -25,7 +25,7 @@ package net.runelite.client.plugins.party.messages; import lombok.Data; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Data public class CharacterNameUpdate extends PartyMemberMessage diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java index f5bf7131ce..8762b8d726 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/LocationUpdate.java @@ -27,7 +27,7 @@ package net.runelite.client.plugins.party.messages; import lombok.EqualsAndHashCode; import lombok.Value; import net.runelite.api.coords.WorldPoint; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Value @EqualsAndHashCode(callSuper = true) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/SkillUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/SkillUpdate.java index 10f5810b0f..7d9ceb8c64 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/SkillUpdate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/SkillUpdate.java @@ -27,7 +27,7 @@ package net.runelite.client.plugins.party.messages; import lombok.AllArgsConstructor; import lombok.Getter; import net.runelite.api.Skill; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @AllArgsConstructor @Getter diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java index fb4f812a81..487175a0e6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/messages/TilePing.java @@ -27,7 +27,7 @@ package net.runelite.client.plugins.party.messages; import lombok.EqualsAndHashCode; import lombok.Value; import net.runelite.api.coords.WorldPoint; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Value @EqualsAndHashCode(callSuper = true) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java index 382828dfcb..3f47bedc7c 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/raids/RaidsPlugin.java @@ -82,6 +82,9 @@ import net.runelite.client.events.ConfigChanged; import net.runelite.client.events.OverlayMenuClicked; import net.runelite.client.game.SpriteManager; import net.runelite.client.input.KeyManager; +import net.runelite.client.party.PartyMember; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.messages.PartyChatMessage; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.raids.events.RaidReset; @@ -94,11 +97,7 @@ import net.runelite.client.util.HotkeyListener; import net.runelite.client.util.ImageCapture; import net.runelite.client.util.Text; import static net.runelite.client.util.Text.sanitize; -import net.runelite.client.ws.PartyMember; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; import net.runelite.http.api.chat.LayoutRoom; -import net.runelite.http.api.ws.messages.party.PartyChatMessage; @PluginDescriptor( name = "Chambers Of Xeric", @@ -156,9 +155,6 @@ public class RaidsPlugin extends Plugin @Inject private PartyService party; - @Inject - private WSClient ws; - @Inject private ChatCommandManager chatCommandManager; @@ -494,7 +490,7 @@ public class RaidsPlugin extends Plugin { final PartyChatMessage message = new PartyChatMessage(layoutMessage); message.setMemberId(localMember.getMemberId()); - ws.send(message); + party.send(message); } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterConfig.java index 4249fa3be8..9773544618 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterConfig.java @@ -66,6 +66,17 @@ public interface SpecialCounterConfig extends Config return Color.WHITE; } + @ConfigItem( + position = 3, + keyName = "infobox", + name = "Infobox", + description = "Adds an infobox counting special attacks" + ) + default boolean infobox() + { + return true; + } + @ConfigItem( position = 10, keyName = "dragonWarhammerThreshold", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java index 9391d82ee6..7183d2c0d5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterPlugin.java @@ -67,8 +67,8 @@ import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.util.ImageUtil; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; @PluginDescriptor( name = "Special Attack Counter", @@ -293,13 +293,16 @@ public class SpecialCounterPlugin extends Plugin int hit = getHit(specialWeapon, hitsplat); int localPlayerId = client.getLocalPlayer().getId(); - updateCounter(specialWeapon, null, hit); + if (config.infobox()) + { + updateCounter(specialWeapon, null, hit); + } if (!party.getMembers().isEmpty()) { final SpecialCounterUpdate specialCounterUpdate = new SpecialCounterUpdate(interactingId, specialWeapon, hit, client.getWorld(), localPlayerId); specialCounterUpdate.setMemberId(party.getLocalMember().getMemberId()); - wsClient.send(specialCounterUpdate); + party.send(specialCounterUpdate); } playerInfoDrops.add(createSpecInfoDrop(specialWeapon, hit, localPlayerId)); @@ -359,7 +362,10 @@ public class SpecialCounterPlugin extends Plugin // Otherwise we only add the count if it is against a npc we are already tracking if (interactedNpcIds.contains(event.getNpcId())) { - updateCounter(event.getWeapon(), name, event.getHit()); + if (config.infobox()) + { + updateCounter(event.getWeapon(), name, event.getHit()); + } } if (event.getWorld() == client.getWorld()) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterUpdate.java b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterUpdate.java index 2c7bcbe21b..d9416ecdf7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterUpdate.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/specialcounter/SpecialCounterUpdate.java @@ -26,7 +26,7 @@ package net.runelite.client.plugins.specialcounter; import lombok.EqualsAndHashCode; import lombok.Value; -import net.runelite.http.api.ws.messages.party.PartyMemberMessage; +import net.runelite.client.party.messages.PartyMemberMessage; @Value @EqualsAndHashCode(callSuper = true) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java index 6278889dde..fcb177b448 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timers/GameTimer.java @@ -40,7 +40,7 @@ import static net.runelite.client.util.RSTimeUnit.GAME_TICKS; @Getter(AccessLevel.PACKAGE) enum GameTimer { - STAMINA(ItemID.STAMINA_POTION4, GameTimerImageType.ITEM, "Stamina", true), + STAMINA(ItemID.STAMINA_POTION4, GameTimerImageType.ITEM, "Stamina", false), ANTIFIRE(ItemID.ANTIFIRE_POTION4, GameTimerImageType.ITEM, "Antifire", 6, ChronoUnit.MINUTES), EXANTIFIRE(ItemID.EXTENDED_ANTIFIRE4, GameTimerImageType.ITEM, "Extended antifire", 12, ChronoUnit.MINUTES), OVERLOAD(ItemID.OVERLOAD_4, GameTimerImageType.ITEM, "Overload", 5, ChronoUnit.MINUTES, true), diff --git a/runelite-client/src/main/java/net/runelite/client/util/RuntimeTypeAdapterFactory.java b/runelite-client/src/main/java/net/runelite/client/util/RuntimeTypeAdapterFactory.java new file mode 100644 index 0000000000..640b9f2668 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/util/RuntimeTypeAdapterFactory.java @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.runelite.client.util; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.internal.Streams; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Adapts values whose runtime type may differ from their declaration type. This + * is necessary when a field's type is not the same type that GSON should create + * when deserializing that field. For example, consider these types: + *

   {@code
+ *   abstract class Shape {
+ *     int x;
+ *     int y;
+ *   }
+ *   class Circle extends Shape {
+ *     int radius;
+ *   }
+ *   class Rectangle extends Shape {
+ *     int width;
+ *     int height;
+ *   }
+ *   class Diamond extends Shape {
+ *     int width;
+ *     int height;
+ *   }
+ *   class Drawing {
+ *     Shape bottomShape;
+ *     Shape topShape;
+ *   }
+ * }
+ *

Without additional type information, the serialized JSON is ambiguous. Is + * the bottom shape in this drawing a rectangle or a diamond?

   {@code
+ *   {
+ *     "bottomShape": {
+ *       "width": 10,
+ *       "height": 5,
+ *       "x": 0,
+ *       "y": 0
+ *     },
+ *     "topShape": {
+ *       "radius": 2,
+ *       "x": 4,
+ *       "y": 1
+ *     }
+ *   }}
+ * This class addresses this problem by adding type information to the + * serialized JSON and honoring that type information when the JSON is + * deserialized:
   {@code
+ *   {
+ *     "bottomShape": {
+ *       "type": "Diamond",
+ *       "width": 10,
+ *       "height": 5,
+ *       "x": 0,
+ *       "y": 0
+ *     },
+ *     "topShape": {
+ *       "type": "Circle",
+ *       "radius": 2,
+ *       "x": 4,
+ *       "y": 1
+ *     }
+ *   }}
+ * Both the type field name ({@code "type"}) and the type labels ({@code + * "Rectangle"}) are configurable. + * + *

Registering Types

+ * Create a {@code RuntimeTypeAdapterFactory} by passing the base type and type field + * name to the {@link #of} factory method. If you don't supply an explicit type + * field name, {@code "type"} will be used.
   {@code
+ *   RuntimeTypeAdapterFactory shapeAdapterFactory
+ *       = RuntimeTypeAdapterFactory.of(Shape.class, "type");
+ * }
+ * Next register all of your subtypes. Every subtype must be explicitly + * registered. This protects your application from injection attacks. If you + * don't supply an explicit type label, the type's simple name will be used. + *
   {@code
+ *   shapeAdapter.registerSubtype(Rectangle.class, "Rectangle");
+ *   shapeAdapter.registerSubtype(Circle.class, "Circle");
+ *   shapeAdapter.registerSubtype(Diamond.class, "Diamond");
+ * }
+ * Finally, register the type adapter factory in your application's GSON builder: + *
   {@code
+ *   Gson gson = new GsonBuilder()
+ *       .registerTypeAdapterFactory(shapeAdapterFactory)
+ *       .create();
+ * }
+ * Like {@code GsonBuilder}, this API supports chaining:
   {@code
+ *   RuntimeTypeAdapterFactory shapeAdapterFactory = RuntimeTypeAdapterFactory.of(Shape.class)
+ *       .registerSubtype(Rectangle.class)
+ *       .registerSubtype(Circle.class)
+ *       .registerSubtype(Diamond.class);
+ * }
+ */ +public final class RuntimeTypeAdapterFactory implements TypeAdapterFactory { + private final Class baseType; + private final String typeFieldName; + private final Map> labelToSubtype = new LinkedHashMap>(); + private final Map, String> subtypeToLabel = new LinkedHashMap, String>(); + + private RuntimeTypeAdapterFactory(Class baseType, String typeFieldName) { + if (typeFieldName == null || baseType == null) { + throw new NullPointerException(); + } + this.baseType = baseType; + this.typeFieldName = typeFieldName; + } + + /** + * Creates a new runtime type adapter using for {@code baseType} using {@code + * typeFieldName} as the type field name. Type field names are case sensitive. + */ + public static RuntimeTypeAdapterFactory of(Class baseType, String typeFieldName) { + return new RuntimeTypeAdapterFactory(baseType, typeFieldName); + } + + /** + * Creates a new runtime type adapter for {@code baseType} using {@code "type"} as + * the type field name. + */ + public static RuntimeTypeAdapterFactory of(Class baseType) { + return new RuntimeTypeAdapterFactory(baseType, "type"); + } + + /** + * Registers {@code type} identified by {@code label}. Labels are case + * sensitive. + * + * @throws IllegalArgumentException if either {@code type} or {@code label} + * have already been registered on this type adapter. + */ + public RuntimeTypeAdapterFactory registerSubtype(Class type, String label) { + if (type == null || label == null) { + throw new NullPointerException(); + } + if (subtypeToLabel.containsKey(type) || labelToSubtype.containsKey(label)) { + throw new IllegalArgumentException("types and labels must be unique"); + } + labelToSubtype.put(label, type); + subtypeToLabel.put(type, label); + return this; + } + + /** + * Registers {@code type} identified by its {@link Class#getSimpleName simple + * name}. Labels are case sensitive. + * + * @throws IllegalArgumentException if either {@code type} or its simple name + * have already been registered on this type adapter. + */ + public RuntimeTypeAdapterFactory registerSubtype(Class type) { + return registerSubtype(type, type.getSimpleName()); + } + + public TypeAdapter create(Gson gson, TypeToken type) { + if (type.getRawType() != baseType) { + return null; + } + + final Map> labelToDelegate + = new LinkedHashMap>(); + final Map, TypeAdapter> subtypeToDelegate + = new LinkedHashMap, TypeAdapter>(); + for (Map.Entry> entry : labelToSubtype.entrySet()) { + TypeAdapter delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue())); + labelToDelegate.put(entry.getKey(), delegate); + subtypeToDelegate.put(entry.getValue(), delegate); + } + + return new TypeAdapter() { + @Override public R read(JsonReader in) throws IOException { + JsonElement jsonElement = Streams.parse(in); + JsonElement labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName); + if (labelJsonElement == null) { + throw new JsonParseException("cannot deserialize " + baseType + + " because it does not define a field named " + typeFieldName); + } + String label = labelJsonElement.getAsString(); + @SuppressWarnings("unchecked") // registration requires that subtype extends T + TypeAdapter delegate = (TypeAdapter) labelToDelegate.get(label); + if (delegate == null) { + throw new JsonParseException("cannot deserialize " + baseType + " subtype named " + + label + "; did you forget to register a subtype?"); + } + return delegate.fromJsonTree(jsonElement); + } + + @Override public void write(JsonWriter out, R value) throws IOException { + Class srcType = value.getClass(); + String label = subtypeToLabel.get(srcType); + @SuppressWarnings("unchecked") // registration requires that subtype extends T + TypeAdapter delegate = (TypeAdapter) subtypeToDelegate.get(srcType); + if (delegate == null) { + throw new JsonParseException("cannot serialize " + srcType.getName() + + "; did you forget to register a subtype?"); + } + JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject(); + if (jsonObject.has(typeFieldName)) { + throw new JsonParseException("cannot serialize " + srcType.getName() + + " because it already defines a field named " + typeFieldName); + } + JsonObject clone = new JsonObject(); + clone.add(typeFieldName, new JsonPrimitive(label)); + for (Map.Entry e : jsonObject.entrySet()) { + clone.add(e.getKey(), e.getValue()); + } + Streams.write(clone, out); + } + }.nullSafe(); + } +} diff --git a/runelite-client/src/main/resources/item_variations.json b/runelite-client/src/main/resources/item_variations.json index bada1e25f8..97e59fe155 100644 --- a/runelite-client/src/main/resources/item_variations.json +++ b/runelite-client/src/main/resources/item_variations.json @@ -10687,5 +10687,9 @@ "ensouled hellhound head": [ 26996, 26997 + ], + "smiths gloves": [ + 27029, + 27031 ] } \ No newline at end of file diff --git a/runelite-client/src/main/resources/net/runelite/client/runelite.properties b/runelite-client/src/main/resources/net/runelite/client/runelite.properties index 576a15c374..9b53903701 100644 --- a/runelite-client/src/main/resources/net/runelite/client/runelite.properties +++ b/runelite-client/src/main/resources/net/runelite/client/runelite.properties @@ -19,4 +19,5 @@ runelite.session=https://session.openosrs.dev runelite.static.base=https://static.runelite.net runelite.ws=https://api.runelite.net/ws runelite.config=https://static.runelite.net/config.json -runelite.osrstwitter.link=https://twitter.com/OldSchoolRS \ No newline at end of file +runelite.osrstwitter.link=https://twitter.com/OldSchoolRS +runelite.oauth.redirect=https://runelite.net/logged-in \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java b/runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java new file mode 100644 index 0000000000..b6e86871b7 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/config/ConfigManagerTest.java @@ -0,0 +1,152 @@ +/* + * 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.client.config; + +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.ScheduledExecutorService; +import javax.inject.Inject; +import javax.inject.Named; +import net.runelite.api.Client; +import net.runelite.client.RuneLite; +import net.runelite.client.eventbus.EventBus; +import org.junit.Assert; +import static org.junit.Assert.assertNotNull; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class ConfigManagerTest +{ + @Mock + @Bind + EventBus eventBus; + + @Mock + @Bind + ScheduledExecutorService executor; + + @Mock + @Bind + RuneLiteConfig runeliteConfig; + + @Bind + @Named("sessionfile") + File sessionfile = RuneLite.DEFAULT_SESSION_FILE; + + @Bind + @Named("config") + File config = RuneLite.DEFAULT_CONFIG_FILE; + + @Mock + @Bind + Client client; + + @Mock + @Bind + ConfigClient configClient; + + @Inject + ConfigManager manager; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void testGetConfig() throws IOException + { + manager.setConfiguration("test", "key", "moo"); + + TestConfig conf = manager.getConfig(TestConfig.class); + Assert.assertEquals("moo", conf.key()); + } + + @Test + public void testGetConfigDefault() throws IOException + { + TestConfig conf = manager.getConfig(TestConfig.class); + Assert.assertEquals("default", conf.key()); + } + + @Test + public void testSetConfig() throws IOException + { + TestConfig conf = manager.getConfig(TestConfig.class); + conf.key("new value"); + + Assert.assertEquals("new value", conf.key()); + } + + @Test + public void testGetConfigDescriptor() throws IOException + { + TestConfig conf = manager.getConfig(TestConfig.class); + ConfigDescriptor descriptor = manager.getConfigDescriptor(conf); + Assert.assertEquals(2, descriptor.getItems().size()); + } + + @Test + public void testResetNullDefaultConfig() + { + TestConfig conf = manager.getConfig(TestConfig.class); + ConfigDescriptor descriptor = manager.getConfigDescriptor(conf); + conf.nullDefaultKey("new value"); + + manager.unsetConfiguration(descriptor.getGroup().value(), "nullDefaultKey"); + manager.setDefaultConfiguration(conf, false); + Assert.assertNull(conf.nullDefaultKey()); + } + + @Test + public void testKeySplitter() + { + for (String[] test : new String[][] + { + {"rsprofile", "rsprofile.123", "rsprofileThing"}, + {"rsprofile", null, "rsprofileThing"}, + {"foo", "rsprofile.123", "big.bad"}, + {"foo", null, "big.bad"}, + {"foo", "rsprofile.123", "456"}, + {"foo", null, "file.256"}, + }) + { + String whole = ConfigManager.getWholeKey(test[0], test[1], test[2]); + String[] split = ConfigManager.splitKey(whole); + assertNotNull(split); + Assert.assertEquals(split[0], test[0]); + Assert.assertEquals(split[1], test[1]); + Assert.assertEquals(split[2], test[2]); + } + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/config/TestConfig.java b/runelite-client/src/test/java/net/runelite/client/config/TestConfig.java new file mode 100644 index 0000000000..07b0e403d5 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/config/TestConfig.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.client.config; + +@ConfigGroup("test") +public interface TestConfig extends Config +{ + @ConfigItem( + keyName = "key", + name = "Key Name", + description = "value" + ) + default String key() + { + return "default"; + } + + @ConfigItem( + keyName = "key", + name = "Key Name", + description = "value" + ) + void key(String key); + + @ConfigItem( + keyName = "nullDefaultKey", + name = "Key Name", + description = "value" + ) + void nullDefaultKey(String key); + + @ConfigItem( + keyName = "nullDefaultKey", + name = "Key Name", + description = "value" + ) + default String nullDefaultKey() + { + return null; + } +} \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/cannon/CannonPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/cannon/CannonPluginTest.java index 12bc19ead8..a1f602c26d 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/cannon/CannonPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/cannon/CannonPluginTest.java @@ -31,10 +31,9 @@ import com.google.inject.testing.fieldbinder.BoundFieldModule; import javax.inject.Inject; import net.runelite.api.ChatMessageType; import net.runelite.api.Client; -import net.runelite.api.InventoryID; -import net.runelite.api.ItemContainer; -import net.runelite.api.ItemID; +import net.runelite.api.VarPlayer; import net.runelite.api.events.ChatMessage; +import net.runelite.api.events.VarbitChanged; import net.runelite.client.Notifier; import net.runelite.client.game.ItemManager; import net.runelite.client.ui.overlay.OverlayManager; @@ -45,8 +44,11 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import static org.mockito.ArgumentMatchers.any; import org.mockito.Mock; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mockito.junit.MockitoJUnitRunner; @@ -89,13 +91,12 @@ public class CannonPluginTest @Bind private OverlayManager overlayManager; - private static final ChatMessage ADD_FURNACE = new ChatMessage(); + private static final VarbitChanged cannonAmmoChanged = new VarbitChanged(); @BeforeClass - public static void chatMessageSetup() + public static void cannonVarpSetup() { - ADD_FURNACE.setType(ChatMessageType.SPAM); - ADD_FURNACE.setMessage("You add the furnace."); + cannonAmmoChanged.setIndex(VarPlayer.CANNON_AMMO.getId()); } @Before @@ -105,82 +106,92 @@ public class CannonPluginTest } @Test - public void addWrongTypeOfCannonballs() + public void testAmmoCountOnPlace() { - final ChatMessage message = new ChatMessage(); - message.setType(ChatMessageType.GAMEMESSAGE); - message.setMessage("Your cannon contains 20 x Cannonball.
You can only add cannonballs of the same kind."); + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setType(ChatMessageType.SPAM); + chatMessage.setMessage("You add the furnace."); - plugin.onChatMessage(message); - - assertEquals(20, plugin.getCballsLeft()); - } - - @Test - public void addMaxCannonballs() - { - final ItemContainer inventory = mock(ItemContainer.class); - when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(inventory); - when(inventory.count(ItemID.CANNONBALL)).thenReturn(100); - when(inventory.count(ItemID.GRANITE_CANNONBALL)).thenReturn(0); - - plugin.onChatMessage(ADD_FURNACE); + plugin.onChatMessage(chatMessage); assertTrue(plugin.isCannonPlaced()); - assertEquals(30, plugin.getCballsLeft()); + plugin.onVarbitChanged(cannonAmmoChanged); + assertEquals(0, plugin.getCballsLeft()); - plugin.onChatMessage(loadCannonballs(30)); + // Some time passes... + + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(30); + plugin.onVarbitChanged(cannonAmmoChanged); assertEquals(30, plugin.getCballsLeft()); } @Test - public void addNotMaxCannonballs() + public void testCannonInfoBox() { - final ItemContainer inventory = mock(ItemContainer.class); - when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(inventory); - when(inventory.count(ItemID.GRANITE_CANNONBALL)).thenReturn(12); + when(config.showInfobox()).thenReturn(true); - plugin.onChatMessage(ADD_FURNACE); + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setType(ChatMessageType.SPAM); + chatMessage.setMessage("You add the furnace."); + + plugin.onChatMessage(chatMessage); assertTrue(plugin.isCannonPlaced()); assertEquals(0, plugin.getCballsLeft()); - - plugin.onChatMessage(loadCannonballs(12)); - assertEquals(12, plugin.getCballsLeft()); + verify(infoBoxManager).addInfoBox(any(CannonCounter.class)); } @Test - public void addReclaimedCannonballs() + public void testThresholdNotificationShouldNotify() { - final ItemContainer inventory = mock(ItemContainer.class); - when(client.getItemContainer(InventoryID.INVENTORY)).thenReturn(inventory); - when(inventory.count(ItemID.CANNONBALL)).thenReturn(1250); + when(config.showCannonNotifications()).thenReturn(true); + when(config.lowWarningThreshold()).thenReturn(10); - plugin.onChatMessage(ADD_FURNACE); - assertTrue(plugin.isCannonPlaced()); + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(30); + plugin.onVarbitChanged(cannonAmmoChanged); + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(10); + plugin.onVarbitChanged(cannonAmmoChanged); - assertEquals(30, plugin.getCballsLeft()); - - plugin.onChatMessage(loadCannonballs(18)); - assertEquals(30, plugin.getCballsLeft()); + verify(notifier, times(1)).notify("Your cannon has 10 cannon balls remaining!"); } - private static ChatMessage loadCannonballs(final int numCannonballs) + @Test + public void testThresholdNotificationShouldNotifyOnce() { - final ChatMessage message = new ChatMessage(); - message.setType(ChatMessageType.GAMEMESSAGE); + when(config.showCannonNotifications()).thenReturn(true); + when(config.lowWarningThreshold()).thenReturn(10); - // Cannons use the same chat message for loading cannonballs regardless of whether they're normal or granite. - if (numCannonballs == 1) + for (int cballs = 15; cballs >= 8; --cballs) { - message.setMessage("You load the cannon with one cannonball."); - } - else - { - message.setMessage(String.format("You load the cannon with %s cannonballs.", numCannonballs)); + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(cballs); + plugin.onVarbitChanged(cannonAmmoChanged); } - return message; + verify(notifier, times(1)).notify("Your cannon has 10 cannon balls remaining!"); } + @Test + public void testThresholdNotificationsShouldNotNotify() + { + when(config.showCannonNotifications()).thenReturn(true); + when(config.lowWarningThreshold()).thenReturn(0); + + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(30); + plugin.onVarbitChanged(cannonAmmoChanged); + when(client.getVar(VarPlayer.CANNON_AMMO)).thenReturn(10); + plugin.onVarbitChanged(cannonAmmoChanged); + + verify(notifier, never()).notify("Your cannon has 10 cannon balls remaining!"); + } + + @Test + public void testCannonOutOfAmmo() + { + when(config.showCannonNotifications()).thenReturn(true); + ChatMessage cannonOutOfAmmo = new ChatMessage(null, ChatMessageType.GAMEMESSAGE, "", "Your cannon is out of ammo!", "", 0); + + plugin.onChatMessage(cannonOutOfAmmo); + + verify(notifier, times(1)).notify("Your cannon is out of ammo!"); + } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java index 324e3dacdf..318615fc43 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/chatfilter/ChatFilterPluginTest.java @@ -453,4 +453,15 @@ public class ChatFilterPluginTest chatFilterPlugin.onScriptCallbackEvent(event); assertEquals(1, client.getIntStack()[client.getIntStackSize() - 3]); // not filtered } + + @Test + public void testLtGt() + { + when(chatFilterConfig.filteredWords()).thenReturn("fr"); + + chatFilterPlugin.updateFilteredPatterns(); + + String message = chatFilterPlugin.censorMessage("Adam", "start filter end"); + assertEquals("start ******** end", message); + } } \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java index 5213e5e174..0f15ffec4f 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java @@ -32,7 +32,7 @@ import javax.inject.Named; import net.runelite.api.Client; import net.runelite.client.discord.DiscordPresence; import net.runelite.client.discord.DiscordService; -import net.runelite.client.ws.PartyService; +import net.runelite.client.party.PartyService; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/entityhider/EntityHiderPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/entityhider/EntityHiderPluginTest.java new file mode 100644 index 0000000000..834a296498 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/entityhider/EntityHiderPluginTest.java @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2022, 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.client.plugins.entityhider; + +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.Ignore; +import net.runelite.api.NPC; +import net.runelite.api.NPCComposition; +import net.runelite.api.NameableContainer; +import net.runelite.api.Player; +import net.runelite.client.callback.Hooks; +import net.runelite.client.events.ConfigChanged; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class EntityHiderPluginTest +{ + @Inject + EntityHiderPlugin plugin; + + @Mock + @Bind + Client client; + + @Mock + @Bind + EntityHiderConfig config; + + @Mock + @Bind + Hooks hooks; + + @Mock + NameableContainer ignoreNameableContainer; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + + when(client.getIgnoreContainer()).thenReturn(ignoreNameableContainer); + } + + @Test + public void testHideFriendsPositive() + { + when(config.hideOthers()).thenReturn(true); + when(config.hideFriends()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + Player player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriend()).thenReturn(true); + + assertFalse(plugin.shouldDraw(player, false)); + + player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriend()).thenReturn(false); + + assertFalse(plugin.shouldDraw(player, false)); + } + + @Test + public void testHideFriendsNegative() + { + when(config.hideOthers()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + Player player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriend()).thenReturn(false); + + assertFalse(plugin.shouldDraw(player, false)); + + player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriend()).thenReturn(true); + + assertTrue(plugin.shouldDraw(player, false)); + } + + @Test + public void testHideClansPositivie() + { + when(config.hideOthers()).thenReturn(true); + when(config.hideFriendsChatMembers()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + Player player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriendsChatMember()).thenReturn(true); + + assertFalse(plugin.shouldDraw(player, false)); + + player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriendsChatMember()).thenReturn(false); + + assertFalse(plugin.shouldDraw(player, false)); + } + + @Test + public void testHideClansNegative() + { + when(config.hideOthers()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + Player player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriendsChatMember()).thenReturn(false); + + assertFalse(plugin.shouldDraw(player, false)); + + player = mock(Player.class); + when(player.getName()).thenReturn("Adam"); + when(player.isFriendsChatMember()).thenReturn(true); + + assertTrue(plugin.shouldDraw(player, false)); + } + + // hidenpc hideattacker hidden? + // t t t iif attacker would be hidden + // t f f + // f t t + // f f f + @Test + public void testHideAndAttacker() + { + when(config.hideNPCs2D()).thenReturn(true); + when(config.hideAttackers()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + NPCComposition composition = mock(NPCComposition.class); + + NPC npc = mock(NPC.class); + when(npc.getComposition()).thenReturn(composition); + + Player player = mock(Player.class); + when(client.getLocalPlayer()).thenReturn(player); + + when(npc.getInteracting()).thenReturn(player); + + assertFalse(plugin.shouldDraw(npc, true)); + assertTrue(plugin.shouldDraw(npc, false)); + } + + @Test + public void testHideAndNoAttacker() + { + when(config.hideNPCs2D()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + NPCComposition composition = mock(NPCComposition.class); + + NPC npc = mock(NPC.class); + when(npc.getComposition()).thenReturn(composition); + + Player player = mock(Player.class); + when(client.getLocalPlayer()).thenReturn(player); + + when(npc.getInteracting()).thenReturn(player); + + assertTrue(plugin.shouldDraw(npc, true)); + assertTrue(plugin.shouldDraw(npc, false)); + } + + @Test + public void testHideAttacker() + { + when(config.hideAttackers()).thenReturn(true); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup(EntityHiderConfig.GROUP); + plugin.onConfigChanged(configChanged); + + NPCComposition composition = mock(NPCComposition.class); + + NPC npc = mock(NPC.class); + when(npc.getComposition()).thenReturn(composition); + + Player player = mock(Player.class); + when(client.getLocalPlayer()).thenReturn(player); + + when(npc.getInteracting()).thenReturn(player); + + assertFalse(plugin.shouldDraw(npc, true)); + assertFalse(plugin.shouldDraw(npc, false)); + } +} \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java new file mode 100644 index 0000000000..9bab623f62 --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/raids/RaidsPluginTest.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2019, Alexsuperfly + * 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.raids; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.util.concurrent.ScheduledExecutorService; +import net.runelite.api.Client; +import net.runelite.client.Notifier; +import net.runelite.client.chat.ChatClient; +import net.runelite.client.config.ChatColorConfig; +import net.runelite.client.config.RuneLiteConfig; +import net.runelite.client.party.PartyService; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.ui.overlay.infobox.InfoBoxManager; +import net.runelite.client.util.ImageCapture; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class RaidsPluginTest +{ + @Mock + @Bind + Client client; + + @Mock + @Bind + ScheduledExecutorService executor; + + @Mock + @Bind + ChatColorConfig chatColorConfig; + + @Mock + @Bind + RuneLiteConfig runeliteConfig; + + @Mock + @Bind + ImageCapture imageCapture; + + @Mock + @Bind + Notifier notifier; + + @Mock + @Bind + ChatClient chatClient; + + @Mock + @Bind + InfoBoxManager infoBoxManager; + + @Mock + @Bind + PartyService partyService; + + @Mock + @Bind + OverlayManager overlayManager; + + @Mock + @Bind + RaidsConfig raidsConfig; + + @Mock + @Bind + RaidsOverlay raidsOverlay; + + @Inject + RaidsPlugin raidsPlugin; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + when(raidsConfig.whitelistedRooms()).thenReturn(""); + when(raidsConfig.blacklistedRooms()).thenReturn(""); + when(raidsConfig.whitelistedRotations()).thenReturn(""); + when(raidsConfig.whitelistedLayouts()).thenReturn(""); + } + + @Test + public void testRotationWhitelist() + { + when(raidsConfig.whitelistedRotations()).thenReturn("Muttadiles, Tekton, Mystics"); + raidsPlugin.updateLists(); + + final RaidRoom[] raidRooms = new RaidRoom[]{RaidRoom.MUTTADILES, RaidRoom.TEKTON, RaidRoom.MYSTICS}; + Raid raid = mock(Raid.class); + when(raid.getCombatRooms()).thenReturn(raidRooms); + raidsPlugin.setRaid(raid); + + assertTrue(raidsPlugin.getRotationMatches()); + } + + @Test + public void testRotationWhitelistMultiple() + { + when(raidsConfig.whitelistedRotations()).thenReturn("Vanguards, Vespula, Vasa \nMuttadiles, Tekton, Mystics"); + raidsPlugin.updateLists(); + + final RaidRoom[] raidRooms = new RaidRoom[]{RaidRoom.MUTTADILES, RaidRoom.TEKTON, RaidRoom.MYSTICS}; + Raid raid = mock(Raid.class); + when(raid.getCombatRooms()).thenReturn(raidRooms); + raidsPlugin.setRaid(raid); + + assertTrue(raidsPlugin.getRotationMatches()); + } + + @Test + public void testRotationWhitelistBackwards() + { + when(raidsConfig.whitelistedRotations()).thenReturn("muttadiles, tekton, mystics"); + raidsPlugin.updateLists(); + + final RaidRoom[] raidRooms = new RaidRoom[]{RaidRoom.MYSTICS, RaidRoom.TEKTON, RaidRoom.MUTTADILES}; + Raid raid = mock(Raid.class); + when(raid.getCombatRooms()).thenReturn(raidRooms); + raidsPlugin.setRaid(raid); + + assertFalse(raidsPlugin.getRotationMatches()); + } +} diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java index 4846efdd9a..55bfdc6237 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/specialcounter/SpecialCounterPluginTest.java @@ -49,8 +49,8 @@ import net.runelite.client.game.ItemManager; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.ui.overlay.infobox.InfoBoxManager; import net.runelite.client.util.AsyncBufferedImage; -import net.runelite.client.ws.PartyService; -import net.runelite.client.ws.WSClient; +import net.runelite.client.party.PartyService; +import net.runelite.client.party.WSClient; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -115,6 +115,8 @@ public class SpecialCounterPluginTest { Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + when(specialCounterConfig.infobox()).thenReturn(true); + // Set up spec weapon ItemContainer equipment = mock(ItemContainer.class); when(equipment.getItem(EquipmentInventorySlot.WEAPON.getSlotIdx())).thenReturn(new Item(ItemID.BANDOS_GODSWORD, 1));