From a89202e2305fd583a91050bfb4b39cb1d436fd60 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 22 Aug 2020 20:32:43 -0400 Subject: [PATCH] party service: prioritize user join handler over plugins The Discord invites requires the party size to be >0 for invites to work. Previously this was not updating the presence with the 1 (local) member after joining due to the plugin event handler running prior to the service adding the member to the party. This also changes the party id to always be null when not in a party instead of set to the special local party id. This simplifies the checks in the plugins trying to differentiate being in your own party vs not being in a party. --- .../client/plugins/discord/DiscordPlugin.java | 11 ++++++----- .../client/plugins/discord/DiscordState.java | 11 ++++++----- .../java/net/runelite/client/ws/PartyService.java | 14 +++++++++----- .../client/plugins/discord/DiscordStateTest.java | 2 ++ 4 files changed, 23 insertions(+), 15 deletions(-) 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