Merge remote-tracking branch 'runelite/master'

This commit is contained in:
Owain van Brakel
2022-06-12 01:48:45 +02:00
65 changed files with 1985 additions and 513 deletions
@@ -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.
* <p>
* 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<String> names);
/**
* Get the list of NPC indices that are currently hidden
*
* @return all of the current hidden NPC Indices
*/
List<Integer> getHiddenNpcIndices();
/**
* If an NPC index is in this List then do not render it
*
* @param npcIndices the npc indices to hide
*/
void setHiddenNpcIndices(List<Integer> 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<Integer> blacklist);
/**
* Adds a custom clientscript to the list of available clientscripts.
*
@@ -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. */
}
@@ -33,6 +33,13 @@ public interface NameableContainer<T extends Nameable>
*/
int getCount();
/**
* Get the maximum size of the container.
*
* @return
*/
int getSize();
/**
* Get the members in this container
*
@@ -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;
@@ -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. */
}
@@ -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;
@@ -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. */
}
@@ -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. */
}
@@ -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),
@@ -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);
}
/**
* 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);
}
@@ -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
@@ -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);
@@ -35,5 +35,5 @@ public class AccountSession
{
private final UUID uuid;
private final Instant created;
private String username;
private final String username;
}
@@ -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;
}
}
@@ -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<RenderableDrawListener> 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;
}
}
@@ -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;
@@ -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<PartyMember> 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 <T extends PartyMessage> 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
@@ -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))
@@ -0,0 +1,88 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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<Class<? extends WebsocketMessage>> MESSAGES;
static
{
final List<Class<? extends WebsocketMessage>> 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<WebsocketMessage> factory(final Collection<Class<? extends WebsocketMessage>> messages)
{
final RuntimeTypeAdapterFactory<WebsocketMessage> 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<WebsocketMessage> factory)
{
return RuneLiteAPI.GSON.newBuilder()
.registerTypeAdapterFactory(factory)
.create();
}
public static Gson build()
{
return build(factory(Collections.emptyList()));
}
}
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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;
}
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* 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;
}
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* 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
{
}
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2019, Tomas Slusny <slusnucky@gmail.com>
* 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;
}
@@ -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;
}
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* 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;
}
}
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* 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;
}
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* 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;
}
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
* 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
{
}
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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;
}
}
@@ -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<Integer> 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)
@@ -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)
@@ -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("<lt>", "<")
.replaceAll("<gt>", ">");
String strippedAccents = stripAccents(strippedMessage);
assert strippedMessage.length() == strippedAccents.length();
@@ -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);
}
}
}
@@ -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)
@@ -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)
@@ -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
{
@@ -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)
@@ -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;
}
}
@@ -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();
@@ -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;
@@ -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
{
@@ -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
{
@@ -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);
}
}
@@ -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
{
@@ -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
@@ -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
@@ -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)
@@ -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
@@ -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)
@@ -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);
}
}
@@ -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",
@@ -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())
@@ -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)
@@ -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),
@@ -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:
* <pre> {@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;
* }
* }</pre>
* <p>Without additional type information, the serialized JSON is ambiguous. Is
* the bottom shape in this drawing a rectangle or a diamond? <pre> {@code
* {
* "bottomShape": {
* "width": 10,
* "height": 5,
* "x": 0,
* "y": 0
* },
* "topShape": {
* "radius": 2,
* "x": 4,
* "y": 1
* }
* }}</pre>
* This class addresses this problem by adding type information to the
* serialized JSON and honoring that type information when the JSON is
* deserialized: <pre> {@code
* {
* "bottomShape": {
* "type": "Diamond",
* "width": 10,
* "height": 5,
* "x": 0,
* "y": 0
* },
* "topShape": {
* "type": "Circle",
* "radius": 2,
* "x": 4,
* "y": 1
* }
* }}</pre>
* Both the type field name ({@code "type"}) and the type labels ({@code
* "Rectangle"}) are configurable.
*
* <h3>Registering Types</h3>
* 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. <pre> {@code
* RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory
* = RuntimeTypeAdapterFactory.of(Shape.class, "type");
* }</pre>
* 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.
* <pre> {@code
* shapeAdapter.registerSubtype(Rectangle.class, "Rectangle");
* shapeAdapter.registerSubtype(Circle.class, "Circle");
* shapeAdapter.registerSubtype(Diamond.class, "Diamond");
* }</pre>
* Finally, register the type adapter factory in your application's GSON builder:
* <pre> {@code
* Gson gson = new GsonBuilder()
* .registerTypeAdapterFactory(shapeAdapterFactory)
* .create();
* }</pre>
* Like {@code GsonBuilder}, this API supports chaining: <pre> {@code
* RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory = RuntimeTypeAdapterFactory.of(Shape.class)
* .registerSubtype(Rectangle.class)
* .registerSubtype(Circle.class)
* .registerSubtype(Diamond.class);
* }</pre>
*/
public final class RuntimeTypeAdapterFactory<T> implements TypeAdapterFactory {
private final Class<?> baseType;
private final String typeFieldName;
private final Map<String, Class<?>> labelToSubtype = new LinkedHashMap<String, Class<?>>();
private final Map<Class<?>, String> subtypeToLabel = new LinkedHashMap<Class<?>, 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 <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName) {
return new RuntimeTypeAdapterFactory<T>(baseType, typeFieldName);
}
/**
* Creates a new runtime type adapter for {@code baseType} using {@code "type"} as
* the type field name.
*/
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType) {
return new RuntimeTypeAdapterFactory<T>(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<T> 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<T> registerSubtype(Class<? extends T> type) {
return registerSubtype(type, type.getSimpleName());
}
public <R> TypeAdapter<R> create(Gson gson, TypeToken<R> type) {
if (type.getRawType() != baseType) {
return null;
}
final Map<String, TypeAdapter<?>> labelToDelegate
= new LinkedHashMap<String, TypeAdapter<?>>();
final Map<Class<?>, TypeAdapter<?>> subtypeToDelegate
= new LinkedHashMap<Class<?>, TypeAdapter<?>>();
for (Map.Entry<String, Class<?>> 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<R>() {
@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<R> delegate = (TypeAdapter<R>) 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<R> delegate = (TypeAdapter<R>) 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<String, JsonElement> e : jsonObject.entrySet()) {
clone.add(e.getKey(), e.getValue());
}
Streams.write(clone, out);
}
}.nullSafe();
}
}
@@ -10687,5 +10687,9 @@
"ensouled hellhound head": [
26996,
26997
],
"smiths gloves": [
27029,
27031
]
}
@@ -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
runelite.osrstwitter.link=https://twitter.com/OldSchoolRS
runelite.oauth.redirect=https://runelite.net/logged-in
@@ -0,0 +1,152 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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]);
}
}
}
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2017, Adam <Adam@sigterm.info>
* 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;
}
}
@@ -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.<br>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!");
}
}
@@ -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("f<ilte>r");
chatFilterPlugin.updateFilteredPatterns();
String message = chatFilterPlugin.censorMessage("Adam", "start f<lt>ilte<gt>r end");
assertEquals("start ******** end", message);
}
}
@@ -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;
@@ -0,0 +1,242 @@
/*
* Copyright (c) 2022, Adam <Adam@sigterm.info>
* 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<Ignore> 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));
}
}
@@ -0,0 +1,156 @@
/*
* Copyright (c) 2019, Alexsuperfly <github.com/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());
}
}
@@ -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));