diff --git a/runelite-client/src/main/java/net/runelite/client/events/PartyChanged.java b/runelite-client/src/main/java/net/runelite/client/events/PartyChanged.java
index 0cb8a94c3e..be8bd63a9b 100644
--- a/runelite-client/src/main/java/net/runelite/client/events/PartyChanged.java
+++ b/runelite-client/src/main/java/net/runelite/client/events/PartyChanged.java
@@ -30,5 +30,6 @@ import lombok.Value;
@Value
public class PartyChanged
{
+ private final String passphrase;
private final UUID partyId;
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java
index 590424eaf8..2affaf1214 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPanel.java
@@ -41,6 +41,7 @@ import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
+import net.runelite.client.callback.ClientThread;
import net.runelite.client.plugins.party.data.PartyData;
import net.runelite.client.ui.ColorScheme;
import net.runelite.client.ui.PluginPanel;
@@ -51,7 +52,7 @@ import net.runelite.client.ws.PartyService;
class PartyPanel extends PluginPanel
{
private static final String BTN_CREATE_TEXT = "Create party";
- private static final String BTN_LEAVE_TEXT = "Leave party";
+ private static final String BTN_LEAVE_TEXT = "Leave";
private final PartyPlugin plugin;
private final PartyService party;
@@ -69,7 +70,7 @@ class PartyPanel extends PluginPanel
private final JComponent memberBoxPanel = new DragAndDropReorderPane();
@Inject
- PartyPanel(final PartyPlugin plugin, final PartyConfig config, final PartyService party)
+ PartyPanel(final ClientThread clientThread, final PartyPlugin plugin, final PartyConfig config, final PartyService party)
{
this.plugin = plugin;
this.party = party;
@@ -122,7 +123,7 @@ class PartyPanel extends PluginPanel
rejoinPartyButton.setText("Join previous party");
rejoinPartyButton.setFocusable(false);
- copyPartyIdButton.setText("Copy party id");
+ copyPartyIdButton.setText("Copy passphrase");
copyPartyIdButton.setFocusable(false);
startButton.addActionListener(e ->
@@ -143,7 +144,7 @@ class PartyPanel extends PluginPanel
else
{
// Create party
- party.changeParty(party.getLocalPartyId());
+ clientThread.invokeLater(() -> party.changeParty(party.generatePasspharse()));
}
});
@@ -153,8 +154,8 @@ class PartyPanel extends PluginPanel
{
String s = (String) JOptionPane.showInputDialog(
joinPartyButton,
- "Please enter the party id:",
- "Party Id",
+ "Please enter the party passphrase:",
+ "Party Passphrase",
JOptionPane.PLAIN_MESSAGE,
null,
null,
@@ -165,15 +166,7 @@ class PartyPanel extends PluginPanel
return;
}
- try
- {
- party.changeParty(UUID.fromString(s));
- }
- catch (IllegalArgumentException ex)
- {
- JOptionPane.showMessageDialog(joinPartyButton, "You have entered an invalid party id.", "Invalid Party Id",
- JOptionPane.ERROR_MESSAGE);
- }
+ party.changeParty(s);
}
});
@@ -181,17 +174,7 @@ class PartyPanel extends PluginPanel
{
if (!party.isInParty())
{
- try
- {
- party.changeParty(UUID.fromString(config.previousPartyId()));
- }
- catch (IllegalArgumentException ex)
- {
- JOptionPane.showMessageDialog(rejoinPartyButton,
- "Failed to join your previous party, create a new party or join a new one.",
- "Failed to Join Party",
- JOptionPane.ERROR_MESSAGE);
- }
+ party.changeParty(config.previousPartyId());
}
});
@@ -200,12 +183,11 @@ class PartyPanel extends PluginPanel
if (party.isInParty())
{
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
- clipboard.setContents(new StringSelection(String.valueOf(party.getPartyId())), null);
+ clipboard.setContents(new StringSelection(party.getPartyPassphrase()), null);
}
});
noPartyPanel.setContent("Not in a party", "Create a party to begin.");
- partyEmptyPanel.setContent("Party created", "You can now invite friends!");
updateParty();
}
@@ -226,6 +208,8 @@ class PartyPanel extends PluginPanel
}
else if (plugin.getPartyDataMap().size() <= 1)
{
+ partyEmptyPanel.setContent("Party created", "You can now invite friends!
" +
+ "Your party passphrase is: " + party.getPartyPassphrase() + ".");
add(partyEmptyPanel);
}
}
diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java
index c833be1e98..38fdba6e23 100644
--- a/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java
+++ b/runelite-client/src/main/java/net/runelite/client/plugins/party/PartyPlugin.java
@@ -493,7 +493,7 @@ public class PartyPlugin extends Plugin
if (event.getPartyId() != null)
{
- config.setPreviousPartyId(String.valueOf(event.getPartyId()));
+ config.setPreviousPartyId(event.getPassphrase());
}
SwingUtilities.invokeLater(panel::removeAllMembers);
@@ -507,8 +507,7 @@ public class PartyPlugin extends Plugin
return;
}
- chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Party " + party.getPartyId()).build());
- chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Local Party " + party.getLocalPartyId()).build());
+ chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Party " + party.getPartyPassphrase() + " ID " + party.getPartyId()).build());
chatMessageManager.queue(QueuedMessage.builder().type(ChatMessageType.GAMEMESSAGE).value("Local ID " + party.getLocalMember().getMemberId()).build());
for (PartyMember partyMember : party.getMembers())
{
diff --git a/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java b/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java
index d9f82836e0..123a172a0b 100644
--- a/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java
+++ b/runelite-client/src/main/java/net/runelite/client/ws/PartyService.java
@@ -25,10 +25,14 @@
*/
package net.runelite.client.ws;
+import com.google.common.base.CharMatcher;
+import com.google.common.hash.Hashing;
import java.awt.image.BufferedImage;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Locale;
import java.util.Random;
import java.util.UUID;
import javax.annotation.Nullable;
@@ -37,6 +41,9 @@ import javax.inject.Singleton;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
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;
@@ -61,22 +68,24 @@ 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;
private final WSClient wsClient;
private final SessionManager sessionManager;
private final EventBus eventBus;
private final ChatMessageManager chat;
private final List members = new ArrayList<>();
- @Getter
- private UUID localPartyId = UUID.randomUUID();
-
@Getter
private UUID partyId; // secret party id
+ @Getter
+ private String partyPassphrase;
@Inject
- private PartyService(final WSClient wsClient, final SessionManager sessionManager, final EventBus eventBus, final ChatMessageManager chat)
+ private PartyService(final Client client, final WSClient wsClient, final SessionManager sessionManager, final EventBus eventBus, final ChatMessageManager chat)
{
+ this.client = client;
this.wsClient = wsClient;
this.sessionManager = sessionManager;
this.eventBus = eventBus;
@@ -84,28 +93,89 @@ public class PartyService
eventBus.register(this);
}
- public void changeParty(@Nullable UUID newParty)
+ public String generatePasspharse()
+ {
+ assert client.isClientThread();
+
+ Random r = new Random();
+ StringBuilder sb = new StringBuilder();
+
+ if (client.getGameState().getState() >= GameState.LOGIN_SCREEN.getState())
+ {
+ int len = 0;
+ final CharMatcher matcher = CharMatcher.javaLetter();
+ do
+ {
+ final int itemId = r.nextInt(client.getItemCount());
+ final ItemComposition def = client.getItemDefinition(itemId);
+ final String name = def.getName();
+ if (name == null || name.isEmpty() || name.equals("null"))
+ {
+ continue;
+ }
+
+ final String[] split = name.split(" ");
+ final String token = split[r.nextInt(split.length)];
+ if (!matcher.matchesAllOf(token) || token.length() <= 2)
+ {
+ continue;
+ }
+
+ if (sb.length() > 0)
+ {
+ sb.append('-');
+ }
+ sb.append(token.toLowerCase(Locale.US));
+ ++len;
+ }
+ while (len < 4);
+ }
+ else
+ {
+ int len = 0;
+ do
+ {
+ if (sb.length() > 0)
+ {
+ sb.append('-');
+ }
+ for (int i = 0; i < 5; ++i)
+ {
+ sb.append(ALPHABET.charAt(r.nextInt(ALPHABET.length())));
+ }
+ ++len;
+ }
+ while (len < 4);
+ }
+
+ String partyPassphrase = sb.toString();
+ log.debug("Generated party passpharse {}", partyPassphrase);
+ return partyPassphrase;
+ }
+
+ public void changeParty(@Nullable String passphrase)
{
if (wsClient.sessionExists())
{
wsClient.send(new Part());
}
- log.debug("Party change to {}", newParty);
+ UUID id = passphrase != null ? passphraseToId(passphrase) : null;
+
+ log.debug("Party change to {} (id {})", passphrase, id);
members.clear();
- partyId = newParty;
+ partyId = id;
+ partyPassphrase = passphrase;
if (partyId == null)
{
- localPartyId = UUID.randomUUID(); // cycle local party id so that a new party is created now
-
// close the websocket if the session id isn't for an account
if (sessionManager.getAccountSession() == null)
{
wsClient.changeSession(null);
}
- eventBus.post(new PartyChanged(partyId));
+ eventBus.post(new PartyChanged(partyPassphrase, partyId));
return;
}
@@ -118,7 +188,7 @@ public class PartyService
wsClient.changeSession(uuid);
}
- eventBus.post(new PartyChanged(partyId));
+ eventBus.post(new PartyChanged(partyPassphrase, partyId));
wsClient.send(new Join(partyId, USERNAME));
}
@@ -221,11 +291,6 @@ public class PartyService
return partyId != null;
}
- public boolean isPartyOwner()
- {
- return localPartyId.equals(partyId);
- }
-
public void setPartyMemberAvatar(UUID memberID, BufferedImage image)
{
final PartyMember memberById = getMemberById(memberID);
@@ -246,4 +311,13 @@ public class PartyService
}
return s;
}
+
+ private static UUID passphraseToId(String passphrase)
+ {
+ return UUID.nameUUIDFromBytes(
+ Hashing.sha256().hashBytes(
+ passphrase.getBytes(StandardCharsets.UTF_8)
+ ).asBytes()
+ );
+ }
}