Merge remote-tracking branch 'runelite/master'
This commit is contained in:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user