party: use passphrases for party ids

These are easier to type and share than uuids.
This commit is contained in:
Adam
2022-05-25 20:13:37 -04:00
parent ff210a6b42
commit eb0cbd5f49
4 changed files with 105 additions and 47 deletions

View File

@@ -30,5 +30,6 @@ import lombok.Value;
@Value
public class PartyChanged
{
private final String passphrase;
private final UUID partyId;
}

View File

@@ -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!<br/>" +
"Your party passphrase is: " + party.getPartyPassphrase() + ".");
add(partyEmptyPanel);
}
}

View File

@@ -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())
{

View File

@@ -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<PartyMember> 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()
);
}
}