party: switch to protobuf
This switches party and member ids to also be 64bit ints. This uses considerably less data and cpu due to being able to use binary websocket frames, and the server can avoid json deserialization completely. Also hold member ids instead of party member references in the party plugin, since the members can be reset if connection is lost, causing it hold refs to old party members. Encode location update points into a single int, since the updates are so frequent.
This commit is contained in:
@@ -24,12 +24,17 @@
|
||||
*/
|
||||
package net.runelite.client.events;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class PartyChanged
|
||||
{
|
||||
/**
|
||||
* The passphrase used to derive the party id
|
||||
*/
|
||||
private final String passphrase;
|
||||
private final UUID partyId;
|
||||
/**
|
||||
* The new party id, or null if no party
|
||||
*/
|
||||
private final Long partyId;
|
||||
}
|
||||
|
||||
@@ -25,12 +25,11 @@
|
||||
package net.runelite.client.events;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.UUID;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
public class PartyMemberAvatar
|
||||
{
|
||||
private final UUID memberId;
|
||||
private final long memberId;
|
||||
private final BufferedImage image;
|
||||
}
|
||||
|
||||
2888
runelite-client/src/main/java/net/runelite/client/party/Party.java
Normal file
2888
runelite-client/src/main/java/net/runelite/client/party/Party.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -25,14 +25,12 @@
|
||||
package net.runelite.client.party;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.UUID;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PartyMember
|
||||
{
|
||||
private final UUID memberId;
|
||||
private final String name;
|
||||
private final long memberId;
|
||||
private String displayName = "<unknown>";
|
||||
private boolean loggedIn;
|
||||
private BufferedImage avatar;
|
||||
|
||||
@@ -50,14 +50,11 @@ 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.events.UserJoin;
|
||||
import net.runelite.client.party.events.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;
|
||||
|
||||
@Slf4j
|
||||
@@ -65,8 +62,6 @@ import static net.runelite.client.util.Text.JAGEX_PRINTABLE_CHAR_MATCHER;
|
||||
public class PartyService
|
||||
{
|
||||
private static final int MAX_MESSAGE_LEN = 150;
|
||||
private static final int MAX_USERNAME_LEN = 32; // same as Discord
|
||||
private static final String USERNAME = "rluser-" + new Random().nextInt(Integer.MAX_VALUE);
|
||||
private static final String ALPHABET = "bcdfghjklmnpqrstvwxyz";
|
||||
|
||||
private final Client client;
|
||||
@@ -76,7 +71,8 @@ public class PartyService
|
||||
private final List<PartyMember> members = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
private UUID partyId; // secret party id
|
||||
private long partyId; // secret party id
|
||||
private long memberId = randomMemberId();
|
||||
@Getter
|
||||
private String partyPassphrase;
|
||||
|
||||
@@ -146,7 +142,7 @@ public class PartyService
|
||||
}
|
||||
|
||||
String partyPassphrase = sb.toString();
|
||||
log.debug("Generated party passpharse {}", partyPassphrase);
|
||||
log.debug("Generated party passphrase {}", partyPassphrase);
|
||||
return partyPassphrase;
|
||||
}
|
||||
|
||||
@@ -154,20 +150,21 @@ public class PartyService
|
||||
{
|
||||
if (wsClient.sessionExists())
|
||||
{
|
||||
wsClient.send(new Part());
|
||||
wsClient.part();
|
||||
memberId = randomMemberId(); // use a different member id between parties
|
||||
}
|
||||
|
||||
UUID id = passphrase != null ? passphraseToId(passphrase) : null;
|
||||
long id = passphrase != null ? passphraseToId(passphrase) : 0;
|
||||
|
||||
log.debug("Party change to {} (id {})", passphrase, id);
|
||||
members.clear();
|
||||
partyId = id;
|
||||
partyPassphrase = passphrase;
|
||||
|
||||
if (partyId == null)
|
||||
if (passphrase == null)
|
||||
{
|
||||
wsClient.changeSession(null);
|
||||
eventBus.post(new PartyChanged(partyPassphrase, partyId));
|
||||
eventBus.post(new PartyChanged(partyPassphrase, null));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -178,7 +175,7 @@ public class PartyService
|
||||
}
|
||||
|
||||
eventBus.post(new PartyChanged(partyPassphrase, partyId));
|
||||
wsClient.send(new Join(partyId, USERNAME));
|
||||
wsClient.join(partyId, memberId);
|
||||
}
|
||||
|
||||
public <T extends PartyMessage> void send(T message)
|
||||
@@ -187,11 +184,10 @@ public class PartyService
|
||||
{
|
||||
log.debug("Reconnecting to server");
|
||||
|
||||
PartyMember local = getLocalMember();
|
||||
members.removeIf(m -> m != local);
|
||||
members.clear();
|
||||
|
||||
wsClient.connect();
|
||||
wsClient.send(new Join(partyId, USERNAME));
|
||||
wsClient.join(partyId, memberId);
|
||||
}
|
||||
|
||||
wsClient.send(message);
|
||||
@@ -200,7 +196,7 @@ public class PartyService
|
||||
@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)
|
||||
{
|
||||
if (!partyId.equals(message.getPartyId()))
|
||||
if (partyId != message.getPartyId())
|
||||
{
|
||||
// This can happen when a session is resumed server side after the client party
|
||||
// changes when disconnected.
|
||||
@@ -210,7 +206,7 @@ public class PartyService
|
||||
PartyMember partyMember = getMemberById(message.getMemberId());
|
||||
if (partyMember == null)
|
||||
{
|
||||
partyMember = new PartyMember(message.getMemberId(), cleanUsername(message.getName()));
|
||||
partyMember = new PartyMember(message.getMemberId());
|
||||
members.add(partyMember);
|
||||
log.debug("User {} joins party, {} members", partyMember, members.size());
|
||||
}
|
||||
@@ -219,8 +215,8 @@ public class PartyService
|
||||
// Send info to other clients that this user successfully finished joining party
|
||||
if (localMember != null && localMember == partyMember)
|
||||
{
|
||||
log.debug("Requesting sync");
|
||||
final UserSync userSync = new UserSync();
|
||||
userSync.setMemberId(message.getMemberId());
|
||||
wsClient.send(userSync);
|
||||
}
|
||||
}
|
||||
@@ -228,7 +224,7 @@ 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)
|
||||
{
|
||||
if (members.removeIf(member -> member.getMemberId().equals(message.getMemberId())))
|
||||
if (members.removeIf(member -> member.getMemberId() == message.getMemberId()))
|
||||
{
|
||||
log.debug("User {} leaves party, {} members", message.getMemberId(), members.size());
|
||||
}
|
||||
@@ -264,27 +260,14 @@ public class PartyService
|
||||
|
||||
public PartyMember getLocalMember()
|
||||
{
|
||||
return getMemberByName(USERNAME);
|
||||
return getMemberById(memberId);
|
||||
}
|
||||
|
||||
public PartyMember getMemberById(final UUID id)
|
||||
public PartyMember getMemberById(final long id)
|
||||
{
|
||||
for (PartyMember member : members)
|
||||
{
|
||||
if (id.equals(member.getMemberId()))
|
||||
{
|
||||
return member;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public PartyMember getMemberByName(final String name)
|
||||
{
|
||||
for (PartyMember member : members)
|
||||
{
|
||||
if (name.equals(member.getName()))
|
||||
if (id == member.getMemberId())
|
||||
{
|
||||
return member;
|
||||
}
|
||||
@@ -300,10 +283,10 @@ public class PartyService
|
||||
|
||||
public boolean isInParty()
|
||||
{
|
||||
return partyId != null;
|
||||
return partyId != 0;
|
||||
}
|
||||
|
||||
public void setPartyMemberAvatar(UUID memberID, BufferedImage image)
|
||||
public void setPartyMemberAvatar(long memberID, BufferedImage image)
|
||||
{
|
||||
final PartyMember memberById = getMemberById(memberID);
|
||||
|
||||
@@ -314,22 +297,15 @@ public class PartyService
|
||||
}
|
||||
}
|
||||
|
||||
private static String cleanUsername(String username)
|
||||
private static long passphraseToId(String passphrase)
|
||||
{
|
||||
String s = Text.removeTags(JAGEX_PRINTABLE_CHAR_MATCHER.retainFrom(username));
|
||||
if (s.length() >= MAX_USERNAME_LEN)
|
||||
{
|
||||
s = s.substring(0, MAX_USERNAME_LEN);
|
||||
}
|
||||
return s;
|
||||
return Hashing.sha256().hashBytes(
|
||||
passphrase.getBytes(StandardCharsets.UTF_8)
|
||||
).asLong() & Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
private static UUID passphraseToId(String passphrase)
|
||||
private static long randomMemberId()
|
||||
{
|
||||
return UUID.nameUUIDFromBytes(
|
||||
Hashing.sha256().hashBytes(
|
||||
passphrase.getBytes(StandardCharsets.UTF_8)
|
||||
).asBytes()
|
||||
);
|
||||
return new Random().nextLong() & Long.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ package net.runelite.client.party;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
@@ -37,8 +39,9 @@ import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.eventbus.EventBus;
|
||||
import net.runelite.client.party.messages.Handshake;
|
||||
import net.runelite.client.party.messages.PartyMessage;
|
||||
import net.runelite.client.party.events.UserJoin;
|
||||
import net.runelite.client.party.events.UserPart;
|
||||
import net.runelite.client.party.messages.PartyMemberMessage;
|
||||
import net.runelite.client.party.messages.WebsocketMessage;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
@@ -46,6 +49,7 @@ import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.WebSocket;
|
||||
import okhttp3.WebSocketListener;
|
||||
import okio.ByteString;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
@@ -104,15 +108,13 @@ public class WSClient extends WebSocketListener implements AutoCloseable
|
||||
}
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(runeliteWs)
|
||||
.url(runeliteWs.newBuilder()
|
||||
.addQueryParameter("sessionId", sessionId.toString())
|
||||
.build())
|
||||
.header("User-Agent", RuneLite.USER_AGENT)
|
||||
.build();
|
||||
|
||||
webSocket = okHttpClient.newWebSocket(request, this);
|
||||
|
||||
Handshake handshake = new Handshake();
|
||||
handshake.setSession(sessionId);
|
||||
send(handshake);
|
||||
}
|
||||
|
||||
boolean isOpen()
|
||||
@@ -136,7 +138,42 @@ public class WSClient extends WebSocketListener implements AutoCloseable
|
||||
}
|
||||
}
|
||||
|
||||
public void send(WebsocketMessage message)
|
||||
void join(long partyId, long memberId)
|
||||
{
|
||||
final Party.Join join = Party.Join.newBuilder()
|
||||
.setPartyId(partyId)
|
||||
.setMemberId(memberId)
|
||||
.build();
|
||||
final Party.C2S c2s = Party.C2S.newBuilder()
|
||||
.setJoin(join)
|
||||
.build();
|
||||
send(c2s);
|
||||
}
|
||||
|
||||
void part()
|
||||
{
|
||||
final Party.Part part = Party.Part.newBuilder()
|
||||
.build();
|
||||
final Party.C2S c2s = Party.C2S.newBuilder()
|
||||
.setPart(part)
|
||||
.build();
|
||||
send(c2s);
|
||||
}
|
||||
|
||||
void send(WebsocketMessage message)
|
||||
{
|
||||
log.debug("Sending: {}", message);
|
||||
final String json = gson.toJson(message, WebsocketMessage.class);
|
||||
final Party.Data data = Party.Data.newBuilder()
|
||||
.setData(com.google.protobuf.ByteString.copyFromUtf8(json))
|
||||
.build();
|
||||
final Party.C2S c2s = Party.C2S.newBuilder()
|
||||
.setData(data)
|
||||
.build();
|
||||
send(c2s);
|
||||
}
|
||||
|
||||
private void send(Party.C2S message)
|
||||
{
|
||||
if (webSocket == null)
|
||||
{
|
||||
@@ -144,9 +181,7 @@ public class WSClient extends WebSocketListener implements AutoCloseable
|
||||
connect();
|
||||
}
|
||||
|
||||
final String json = gson.toJson(message, WebsocketMessage.class);
|
||||
webSocket.send(json);
|
||||
log.debug("Sent: {}", json);
|
||||
webSocket.send(ByteString.of(message.toByteArray()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,28 +200,55 @@ public class WSClient extends WebSocketListener implements AutoCloseable
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocket webSocket, String text)
|
||||
public void onMessage(WebSocket webSocket, ByteString bytes)
|
||||
{
|
||||
final WebsocketMessage message;
|
||||
|
||||
Party.S2C s2c;
|
||||
try
|
||||
{
|
||||
message = gson.fromJson(text, WebsocketMessage.class);
|
||||
s2c = Party.S2C.parseFrom(bytes.toByteArray());
|
||||
}
|
||||
catch (JsonParseException e)
|
||||
catch (InvalidProtocolBufferException e)
|
||||
{
|
||||
log.debug("Failed to deserialize message", e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.isParty() && !(message instanceof PartyMessage))
|
||||
switch (s2c.getMsgCase())
|
||||
{
|
||||
// spoofed message?
|
||||
return;
|
||||
}
|
||||
case JOIN:
|
||||
Party.UserJoin join = s2c.getJoin();
|
||||
UserJoin userJoin = new UserJoin(join.getPartyId(), join.getMemberId());
|
||||
log.debug("Got: {}", userJoin);
|
||||
eventBus.post(userJoin);
|
||||
break;
|
||||
case PART:
|
||||
Party.UserPart part = s2c.getPart();
|
||||
UserPart userPart = new UserPart(part.getMemberId());
|
||||
log.debug("Got: {}", userPart);
|
||||
eventBus.post(userPart);
|
||||
break;
|
||||
case DATA:
|
||||
Party.PartyData data = s2c.getData();
|
||||
final WebsocketMessage message;
|
||||
|
||||
log.debug("Got: {}", text);
|
||||
eventBus.post(message);
|
||||
try
|
||||
{
|
||||
message = gson.fromJson(new InputStreamReader(data.getData().newInput()), WebsocketMessage.class);
|
||||
}
|
||||
catch (JsonParseException e)
|
||||
{
|
||||
log.debug("Failed to deserialize message", e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (message instanceof PartyMemberMessage)
|
||||
{
|
||||
((PartyMemberMessage) message).setMemberId(data.getMemberId());
|
||||
}
|
||||
|
||||
log.debug("Got: {}", message);
|
||||
eventBus.post(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,29 +29,19 @@ 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
|
||||
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;
|
||||
|
||||
@@ -22,17 +22,13 @@
|
||||
* (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;
|
||||
package net.runelite.client.party.events;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class UserJoin extends WebsocketMessage
|
||||
public class UserJoin
|
||||
{
|
||||
private final UUID memberId;
|
||||
private final UUID partyId;
|
||||
private final String name;
|
||||
long partyId;
|
||||
long memberId;
|
||||
}
|
||||
@@ -22,15 +22,12 @@
|
||||
* (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;
|
||||
package net.runelite.client.party.events;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class UserPart extends WebsocketMessage
|
||||
public class UserPart
|
||||
{
|
||||
private final UUID memberId;
|
||||
long memberId;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package net.runelite.client.party.messages;
|
||||
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@@ -8,5 +7,5 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public abstract class PartyMemberMessage extends PartyMessage
|
||||
{
|
||||
private UUID memberId;
|
||||
private transient long memberId;
|
||||
}
|
||||
|
||||
@@ -26,8 +26,4 @@ package net.runelite.client.party.messages;
|
||||
|
||||
public abstract class PartyMessage extends WebsocketMessage
|
||||
{
|
||||
public PartyMessage()
|
||||
{
|
||||
_party = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,11 +24,6 @@
|
||||
*/
|
||||
package net.runelite.client.party.messages;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class UserSync extends PartyMemberMessage
|
||||
{
|
||||
}
|
||||
|
||||
@@ -24,12 +24,6 @@
|
||||
*/
|
||||
package net.runelite.client.party.messages;
|
||||
|
||||
public class WebsocketMessage
|
||||
public abstract class WebsocketMessage
|
||||
{
|
||||
protected boolean _party;
|
||||
|
||||
public boolean isParty()
|
||||
{
|
||||
return _party;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +280,6 @@ public class DiscordPlugin extends Plugin
|
||||
discordUser.discriminator,
|
||||
discordUser.avatar
|
||||
);
|
||||
userInfo.setMemberId(localMember.getMemberId());
|
||||
partyService.send(userInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +198,6 @@ public class DpsCounterPlugin extends Plugin
|
||||
if (localMember != null)
|
||||
{
|
||||
final DpsUpdate dpsUpdate = new DpsUpdate(hit, isBoss);
|
||||
dpsUpdate.setMemberId(localMember.getMemberId());
|
||||
partyService.send(dpsUpdate);
|
||||
}
|
||||
|
||||
@@ -235,7 +234,7 @@ public class DpsCounterPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onDpsUpdate(DpsUpdate dpsUpdate)
|
||||
{
|
||||
if (partyService.getLocalMember().getMemberId().equals(dpsUpdate.getMemberId()))
|
||||
if (partyService.getLocalMember().getMemberId() == dpsUpdate.getMemberId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import net.runelite.client.party.PartyMember;
|
||||
import net.runelite.client.party.PartyService;
|
||||
import net.runelite.client.plugins.party.data.PartyData;
|
||||
import net.runelite.client.ui.ColorScheme;
|
||||
import net.runelite.client.ui.DynamicGridLayout;
|
||||
@@ -45,7 +47,6 @@ 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.party.PartyMember;
|
||||
|
||||
class PartyMemberBox extends JPanel
|
||||
{
|
||||
@@ -56,6 +57,7 @@ class PartyMemberBox extends JPanel
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final PartyData memberPartyData;
|
||||
private final PartyService partyService;
|
||||
|
||||
private final ProgressBar hpBar = new ProgressBar();
|
||||
private final ProgressBar prayerBar = new ProgressBar();
|
||||
@@ -67,10 +69,12 @@ class PartyMemberBox extends JPanel
|
||||
|
||||
private boolean avatarSet;
|
||||
|
||||
PartyMemberBox(final PartyConfig config, final JComponent panel, final PartyData memberPartyData)
|
||||
PartyMemberBox(final PartyConfig config, final JComponent panel, final PartyData memberPartyData,
|
||||
final PartyService partyService)
|
||||
{
|
||||
this.config = config;
|
||||
this.memberPartyData = memberPartyData;
|
||||
this.partyService = partyService;
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
setBorder(new EmptyBorder(5, 0, 0, 0));
|
||||
@@ -137,7 +141,7 @@ class PartyMemberBox extends JPanel
|
||||
|
||||
void update()
|
||||
{
|
||||
final PartyMember member = memberPartyData.getMember();
|
||||
final PartyMember member = partyService.getMemberById(memberPartyData.getMemberId());
|
||||
|
||||
// Avatar
|
||||
if (!avatarSet && member.getAvatar() != null)
|
||||
|
||||
@@ -34,7 +34,6 @@ import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
@@ -42,12 +41,12 @@ import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.party.PartyService;
|
||||
import net.runelite.client.plugins.party.data.PartyData;
|
||||
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.party.PartyService;
|
||||
|
||||
class PartyPanel extends PluginPanel
|
||||
{
|
||||
@@ -58,7 +57,7 @@ class PartyPanel extends PluginPanel
|
||||
private final PartyService party;
|
||||
private final PartyConfig config;
|
||||
|
||||
private final Map<UUID, PartyMemberBox> memberBoxes = new HashMap<>();
|
||||
private final Map<Long, PartyMemberBox> memberBoxes = new HashMap<>();
|
||||
|
||||
private final JButton startButton = new JButton();
|
||||
private final JButton joinPartyButton = new JButton();
|
||||
@@ -216,10 +215,10 @@ class PartyPanel extends PluginPanel
|
||||
|
||||
void addMember(PartyData partyData)
|
||||
{
|
||||
if (!memberBoxes.containsKey(partyData.getMember().getMemberId()))
|
||||
if (!memberBoxes.containsKey(partyData.getMemberId()))
|
||||
{
|
||||
PartyMemberBox partyMemberBox = new PartyMemberBox(config, memberBoxPanel, partyData);
|
||||
memberBoxes.put(partyData.getMember().getMemberId(), partyMemberBox);
|
||||
PartyMemberBox partyMemberBox = new PartyMemberBox(config, memberBoxPanel, partyData, party);
|
||||
memberBoxes.put(partyData.getMemberId(), partyMemberBox);
|
||||
memberBoxPanel.add(partyMemberBox);
|
||||
memberBoxPanel.revalidate();
|
||||
}
|
||||
@@ -234,7 +233,7 @@ class PartyPanel extends PluginPanel
|
||||
updateParty();
|
||||
}
|
||||
|
||||
void removeMember(UUID memberId)
|
||||
void removeMember(long memberId)
|
||||
{
|
||||
final PartyMemberBox memberBox = memberBoxes.remove(memberId);
|
||||
|
||||
@@ -247,7 +246,7 @@ class PartyPanel extends PluginPanel
|
||||
updateParty();
|
||||
}
|
||||
|
||||
void updateMember(UUID userId)
|
||||
void updateMember(long userId)
|
||||
{
|
||||
final PartyMemberBox memberBox = memberBoxes.get(userId);
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
@@ -70,8 +69,8 @@ import net.runelite.client.input.KeyManager;
|
||||
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.events.UserJoin;
|
||||
import net.runelite.client.party.events.UserPart;
|
||||
import net.runelite.client.party.messages.UserSync;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
@@ -138,7 +137,7 @@ public class PartyPlugin extends Plugin
|
||||
boolean developerMode;
|
||||
|
||||
@Getter
|
||||
private final Map<UUID, PartyData> partyDataMap = Collections.synchronizedMap(new HashMap<>());
|
||||
private final Map<Long, PartyData> partyDataMap = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
@Getter
|
||||
private final List<PartyTilePingData> pendingTilePings = Collections.synchronizedList(new ArrayList<>());
|
||||
@@ -295,7 +294,6 @@ public class PartyPlugin extends Plugin
|
||||
|
||||
event.consume();
|
||||
final TilePing tilePing = new TilePing(selectedSceneTile.getWorldLocation());
|
||||
tilePing.setMemberId(party.getLocalMember().getMemberId());
|
||||
party.send(tilePing);
|
||||
}
|
||||
|
||||
@@ -355,7 +353,6 @@ public class PartyPlugin extends Plugin
|
||||
lastLocation = location;
|
||||
|
||||
final LocationUpdate locationUpdate = new LocationUpdate(location);
|
||||
locationUpdate.setMemberId(localMember.getMemberId());
|
||||
party.send(locationUpdate);
|
||||
}
|
||||
|
||||
@@ -371,7 +368,6 @@ public class PartyPlugin extends Plugin
|
||||
{
|
||||
// Request sync
|
||||
final UserSync userSync = new UserSync();
|
||||
userSync.setMemberId(party.getLocalMember().getMemberId());
|
||||
party.send(userSync);
|
||||
}
|
||||
}
|
||||
@@ -380,28 +376,29 @@ public class PartyPlugin extends Plugin
|
||||
public void onCharacterNameUpdate(final CharacterNameUpdate event)
|
||||
{
|
||||
final PartyData partyData = getPartyData(event.getMemberId());
|
||||
|
||||
if (partyData == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final String name = Text.removeTags(Text.toJagexName(event.getCharacterName()));
|
||||
final PartyMember member = partyData.getMember();
|
||||
|
||||
if (!name.isEmpty())
|
||||
final PartyMember member = party.getMemberById(event.getMemberId());
|
||||
if (member != null)
|
||||
{
|
||||
member.setDisplayName(name);
|
||||
member.setLoggedIn(true);
|
||||
partyData.setColor(ColorUtil.fromObject(name));
|
||||
}
|
||||
else
|
||||
{
|
||||
member.setLoggedIn(false);
|
||||
partyData.setColor(Color.WHITE);
|
||||
final String name = Text.removeTags(Text.toJagexName(event.getCharacterName()));
|
||||
if (!name.isEmpty())
|
||||
{
|
||||
member.setDisplayName(name);
|
||||
member.setLoggedIn(true);
|
||||
partyData.setColor(ColorUtil.fromObject(name));
|
||||
}
|
||||
else
|
||||
{
|
||||
member.setLoggedIn(false);
|
||||
partyData.setColor(Color.WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() -> panel.updateMember(member.getMemberId()));
|
||||
SwingUtilities.invokeLater(() -> panel.updateMember(event.getMemberId()));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -425,7 +422,7 @@ public class PartyPlugin extends Plugin
|
||||
partyData.setMaxPrayer(event.getMax());
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() -> panel.updateMember(partyData.getMember().getMemberId()));
|
||||
SwingUtilities.invokeLater(() -> panel.updateMember(partyData.getMemberId()));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -471,21 +468,18 @@ public class PartyPlugin extends Plugin
|
||||
if (forceSend || currentHealth != lastHp)
|
||||
{
|
||||
final SkillUpdate update = new SkillUpdate(Skill.HITPOINTS, currentHealth, realHealth);
|
||||
update.setMemberId(localMember.getMemberId());
|
||||
party.send(update);
|
||||
}
|
||||
|
||||
if (forceSend || currentPrayer != lastPray)
|
||||
{
|
||||
final SkillUpdate update = new SkillUpdate(Skill.PRAYER, currentPrayer, realPrayer);
|
||||
update.setMemberId(localMember.getMemberId());
|
||||
party.send(update);
|
||||
}
|
||||
|
||||
if (forceSend || !characterName.equals(lastCharacterName))
|
||||
{
|
||||
final CharacterNameUpdate update = new CharacterNameUpdate(characterName);
|
||||
update.setMemberId(localMember.getMemberId());
|
||||
party.send(update);
|
||||
}
|
||||
}
|
||||
@@ -536,7 +530,7 @@ public class PartyPlugin extends Plugin
|
||||
chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Local ID " + party.getLocalMember().getMemberId()).build());
|
||||
for (PartyMember partyMember : party.getMembers())
|
||||
{
|
||||
chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Member " + partyMember.getName() + " " + partyMember.getDisplayName() + " " + partyMember.getMemberId()).build());
|
||||
chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Member " + partyMember.getDisplayName() + " " + partyMember.getMemberId()).build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,7 +541,7 @@ public class PartyPlugin extends Plugin
|
||||
}
|
||||
|
||||
@Nullable
|
||||
PartyData getPartyData(final UUID uuid)
|
||||
PartyData getPartyData(final long uuid)
|
||||
{
|
||||
final PartyMember memberById = party.getMemberById(uuid);
|
||||
|
||||
@@ -573,7 +567,7 @@ public class PartyPlugin extends Plugin
|
||||
worldMapManager.add(worldMapPoint);
|
||||
}
|
||||
|
||||
PartyData partyData = new PartyData(memberById, worldMapPoint);
|
||||
PartyData partyData = new PartyData(uuid, worldMapPoint);
|
||||
|
||||
SwingUtilities.invokeLater(() -> panel.addMember(partyData));
|
||||
return partyData;
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.party;
|
||||
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
import net.runelite.client.plugins.party.data.PartyData;
|
||||
|
||||
@@ -36,5 +35,5 @@ public interface PartyPluginService
|
||||
* @return party data for member
|
||||
*/
|
||||
@Nullable
|
||||
PartyData getPartyData(UUID memberId);
|
||||
PartyData getPartyData(long memberId);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.party;
|
||||
|
||||
import java.util.UUID;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import net.runelite.client.plugins.party.data.PartyData;
|
||||
@@ -42,7 +41,7 @@ public class PartyPluginServiceImpl implements PartyPluginService
|
||||
}
|
||||
|
||||
@Override
|
||||
public PartyData getPartyData(UUID memberId)
|
||||
public PartyData getPartyData(long memberId)
|
||||
{
|
||||
return plugin.getPartyData(memberId);
|
||||
}
|
||||
|
||||
@@ -31,14 +31,13 @@ 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.party.PartyMember;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class PartyData
|
||||
{
|
||||
private final PartyMember member;
|
||||
private final long memberId;
|
||||
private final WorldMapPoint worldMapPoint;
|
||||
private final PanelComponent panel = new PanelComponent();
|
||||
private Color color = Color.WHITE;
|
||||
|
||||
@@ -24,14 +24,27 @@
|
||||
*/
|
||||
package net.runelite.client.plugins.party.messages;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Value;
|
||||
import lombok.ToString;
|
||||
import net.runelite.api.coords.WorldPoint;
|
||||
import net.runelite.client.party.messages.PartyMemberMessage;
|
||||
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(onlyExplicitlyIncluded = true)
|
||||
public class LocationUpdate extends PartyMemberMessage
|
||||
{
|
||||
private final WorldPoint worldPoint;
|
||||
private final int c;
|
||||
|
||||
public LocationUpdate(WorldPoint worldPoint)
|
||||
{
|
||||
c = (worldPoint.getPlane() << 28) | (worldPoint.getX() << 14) | (worldPoint.getY());
|
||||
}
|
||||
|
||||
@ToString.Include
|
||||
public WorldPoint getWorldPoint()
|
||||
{
|
||||
return new WorldPoint(
|
||||
(c >> 14) & 0x3fff,
|
||||
c & 0x3fff,
|
||||
(c >> 28) & 3
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,7 +314,6 @@ public class SpecialCounterPlugin extends Plugin
|
||||
if (!party.getMembers().isEmpty())
|
||||
{
|
||||
final SpecialCounterUpdate specialCounterUpdate = new SpecialCounterUpdate(npcIndex, specialWeapon, hit, client.getWorld(), localPlayerId);
|
||||
specialCounterUpdate.setMemberId(party.getLocalMember().getMemberId());
|
||||
party.send(specialCounterUpdate);
|
||||
}
|
||||
|
||||
@@ -341,7 +340,7 @@ public class SpecialCounterPlugin extends Plugin
|
||||
@Subscribe
|
||||
public void onSpecialCounterUpdate(SpecialCounterUpdate event)
|
||||
{
|
||||
if (party.getLocalMember().getMemberId().equals(event.getMemberId())
|
||||
if (party.getLocalMember().getMemberId() == event.getMemberId()
|
||||
|| event.getWorld() != client.getWorld())
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -18,7 +18,7 @@ runelite.imgur.client.id=30d71e5f6860809
|
||||
runelite.api.base=https://api.runelite.net/runelite-${project.version}
|
||||
runelite.session=https://api.runelite.net/session
|
||||
runelite.static.base=https://static.runelite.net
|
||||
runelite.ws=https://api.runelite.net/ws
|
||||
runelite.ws=https://api.runelite.net/ws2
|
||||
runelite.config=https://static.runelite.net/config.json
|
||||
runelite.osrstwitter.link=https://twitter.com/OldSchoolRS
|
||||
runelite.oauth.redirect=https://runelite.net/logged-in
|
||||
Reference in New Issue
Block a user