diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java index 3593832fbb..37f92f9cb6 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordPlugin.java @@ -228,19 +228,20 @@ public class DiscordPlugin extends Plugin @Subscribe public void onDiscordJoinRequest(DiscordJoinRequest request) { - log.debug("Got discord join request {}", request); - if (partyService.isOwner() && partyService.getMembers().isEmpty()) + // In order for the "Invite to join" message to work we need to have a valid party in Discord presence. + // We lazily create the party here in order to avoid the (1 of 15) being permanently in the Discord status. + if (!partyService.isInParty()) { - // First join, join also yourself + // Change to my party id, which is advertised in the Discord presence secret. This will open the socket, + // send a join, and cause a UserJoin later for me, which will then update the presence and allow the + // "Invite to join" to continue. partyService.changeParty(partyService.getLocalPartyId()); - updatePresence(); } } @Subscribe public void onDiscordJoinGame(DiscordJoinGame joinGame) { - log.debug("Got discord join game {}", joinGame); UUID partyId = UUID.fromString(joinGame.getJoinSecret()); partyService.changeParty(partyId); updatePresence(); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordState.java b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordState.java index 5df51264a6..0b49445f52 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordState.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/discord/DiscordState.java @@ -46,7 +46,7 @@ import static net.runelite.client.ws.PartyService.PARTY_MAX; class DiscordState { @Data - private class EventWithTime + private static class EventWithTime { private final DiscordGameEventType type; private final Instant start; @@ -97,10 +97,11 @@ class DiscordState .partyMax(lastPresence.getPartyMax()) .partySize(party.getMembers().size()); - if (party.isOwner()) + if (!party.isInParty() || party.isPartyOwner()) { + // This is only used to identify the invites on Discord's side. Our party ids are the secret. presenceBuilder.partyId(partyId.toString()); - presenceBuilder.joinSecret(party.getPartyId().toString()); + presenceBuilder.joinSecret(party.getLocalPartyId().toString()); } discordService.updatePresence(presenceBuilder.build()); @@ -180,10 +181,10 @@ class DiscordState .partyMax(PARTY_MAX) .partySize(party.getMembers().size()); - if (party.isOwner()) + if (!party.isInParty() || party.isPartyOwner()) { presenceBuilder.partyId(partyId.toString()); - presenceBuilder.joinSecret(party.getPartyId().toString()); + presenceBuilder.joinSecret(party.getLocalPartyId().toString()); } final DiscordPresence presence = presenceBuilder.build(); 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 6a6e3aa120..094b1d3de4 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 @@ -66,7 +66,7 @@ public class PartyService private UUID localPartyId = UUID.randomUUID(); @Getter - private UUID partyId = localPartyId; + private UUID partyId; @Setter private String username; @@ -94,7 +94,6 @@ public class PartyService if (partyId == null) { localPartyId = UUID.randomUUID(); // cycle local party id so that a new party is created now - partyId = localPartyId; // close the websocket if the session id isn't for an account if (sessionManager.getAccountSession() == null) @@ -119,7 +118,7 @@ public class PartyService wsClient.send(new Join(partyId, username)); } - @Subscribe + @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())) @@ -206,8 +205,13 @@ public class PartyService return Collections.unmodifiableList(members); } - public boolean isOwner() + public boolean isInParty() { - return partyId == null || localPartyId.equals(partyId); + return partyId != null; + } + + public boolean isPartyOwner() + { + return localPartyId.equals(partyId); } } diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java index 9cfcb1fbbb..1631a84979 100644 --- a/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java +++ b/runelite-client/src/test/java/net/runelite/client/plugins/discord/DiscordStateTest.java @@ -28,6 +28,7 @@ import com.google.inject.Guice; import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; import java.util.List; +import java.util.UUID; import javax.inject.Inject; import net.runelite.api.Client; import net.runelite.client.discord.DiscordPresence; @@ -71,6 +72,7 @@ public class DiscordStateTest public void before() { Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + when(partyService.getLocalPartyId()).thenReturn(UUID.nameUUIDFromBytes("test".getBytes())); } @Test