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 extends WebsocketMessage> 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 extends WebsocketMessage> message : MESSAGES)
+ {
+ factory.registerSubtype(message);
+ }
+
+ for (Class extends WebsocketMessage> 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 extends T> 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 extends T> 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));