1515import java .util .List ;
1616import java .util .Objects ;
1717import java .util .Set ;
18+ import java .util .UUID ;
1819import java .util .concurrent .CompletableFuture ;
1920import java .util .concurrent .CompletionException ;
2021
@@ -70,7 +71,7 @@ public Sender<P> to(Collection<Platform.ServerTarget> targets) {
7071
7172 @ Override
7273 public Sender <P > toAll () {
73- return new SingleTargetSender ( Platform . BACKEND . target ( "*" ) );
74+ return new BroadcastSender ( );
7475 }
7576
7677 @ Override
@@ -79,9 +80,27 @@ public Subscription listen(MessageListener<P> listener) {
7980 return listenerRegistrar .listen (listener );
8081 }
8182
82- private PluginMessage toPluginMessage (P payload , boolean expectsResponse ) {
83+ private PluginMessage toPluginMessage (P payload , boolean expectsResponse , UUID requirePlayer , UUID whenOnline ) {
8384 return new PluginMessage (payloadType .getName (),
84- Envelope .MAPPER .valueToTree (payload ), expectsResponse );
85+ Envelope .MAPPER .valueToTree (payload ), expectsResponse , requirePlayer , whenOnline , null );
86+ }
87+
88+ private PluginMessage toPluginMessage (P payload , boolean expectsResponse ) {
89+ return toPluginMessage (payload , expectsResponse , null , null );
90+ }
91+
92+ private UUID resolveConditionUuid (P payload , UUID stored , boolean fromPayload ) {
93+ if (!fromPayload ) {
94+ return stored ;
95+ }
96+ if (payload instanceof dev .objz .commandbridge .api .channel .command .CommandPayload cp ) {
97+ UUID uuid = cp .player ();
98+ if (uuid == null ) {
99+ throw new IllegalStateException ("Payload has no player UUID" );
100+ }
101+ return uuid ;
102+ }
103+ throw new IllegalStateException ("No-arg condition requires CommandPayload with a player UUID" );
85104 }
86105
87106 private P toPayload (PluginMessage response ) {
@@ -95,15 +114,26 @@ private P toPayload(PluginMessage response) {
95114 private final class SingleTargetSender implements Sender <P > {
96115
97116 private final Platform .ServerTarget target ;
117+ private UUID requirePlayerUuid ;
118+ private boolean requirePlayerFromPayload ;
119+ private UUID whenOnlineUuid ;
120+ private boolean whenOnlineFromPayload ;
98121
99122 SingleTargetSender (Platform .ServerTarget target ) {
100123 this .target = target ;
101124 }
102125
126+ private boolean hasCondition () {
127+ return requirePlayerUuid != null || requirePlayerFromPayload || whenOnlineUuid != null || whenOnlineFromPayload ;
128+ }
129+
103130 @ Override
104131 public CompletableFuture <Void > send (P payload ) {
105132 Objects .requireNonNull (payload );
106- return sendTransport .send (target , toPluginMessage (payload , false ));
133+ UUID requirePlayer = PluginMessageChannel .this
134+ .resolveConditionUuid (payload , requirePlayerUuid , requirePlayerFromPayload );
135+ UUID whenOnline = PluginMessageChannel .this .resolveConditionUuid (payload , whenOnlineUuid , whenOnlineFromPayload );
136+ return sendTransport .send (target , toPluginMessage (payload , false , requirePlayer , whenOnline ));
107137 }
108138
109139 @ Override
@@ -115,14 +145,65 @@ public CompletableFuture<P> request(P payload) {
115145 public CompletableFuture <P > request (P payload , Duration timeout ) {
116146 Objects .requireNonNull (payload );
117147 Objects .requireNonNull (timeout );
118- return requestTransport .request (target , toPluginMessage (payload , true ), timeout )
148+ if (hasCondition () && (whenOnlineUuid != null || whenOnlineFromPayload )) {
149+ throw new UnsupportedOperationException ("whenOnline is not supported for request" );
150+ }
151+ UUID requirePlayer = PluginMessageChannel .this
152+ .resolveConditionUuid (payload , requirePlayerUuid , requirePlayerFromPayload );
153+ return requestTransport .request (target , toPluginMessage (payload , true , requirePlayer , null ), timeout )
119154 .thenApply (PluginMessageChannel .this ::toPayload );
120155 }
156+
157+ @ Override
158+ public Sender <P > requirePlayer (UUID player ) {
159+ Objects .requireNonNull (player );
160+ if (whenOnlineUuid != null || whenOnlineFromPayload ) {
161+ throw new IllegalStateException ("Cannot combine requirePlayer and whenOnline" );
162+ }
163+ requirePlayerUuid = player ;
164+ requirePlayerFromPayload = false ;
165+ return this ;
166+ }
167+
168+ @ Override
169+ public Sender <P > requirePlayer () {
170+ if (whenOnlineUuid != null || whenOnlineFromPayload ) {
171+ throw new IllegalStateException ("Cannot combine requirePlayer and whenOnline" );
172+ }
173+ requirePlayerFromPayload = true ;
174+ requirePlayerUuid = null ;
175+ return this ;
176+ }
177+
178+ @ Override
179+ public Sender <P > whenOnline (UUID player ) {
180+ Objects .requireNonNull (player );
181+ if (requirePlayerUuid != null || requirePlayerFromPayload ) {
182+ throw new IllegalStateException ("Cannot combine requirePlayer and whenOnline" );
183+ }
184+ whenOnlineUuid = player ;
185+ whenOnlineFromPayload = false ;
186+ return this ;
187+ }
188+
189+ @ Override
190+ public Sender <P > whenOnline () {
191+ if (requirePlayerUuid != null || requirePlayerFromPayload ) {
192+ throw new IllegalStateException ("Cannot combine requirePlayer and whenOnline" );
193+ }
194+ whenOnlineFromPayload = true ;
195+ whenOnlineUuid = null ;
196+ return this ;
197+ }
121198 }
122199
123200 private final class MultiTargetSender implements Sender <P > {
124201
125202 private final Set <Platform .ServerTarget > targets ;
203+ private UUID requirePlayerUuid ;
204+ private boolean requirePlayerFromPayload ;
205+ private UUID whenOnlineUuid ;
206+ private boolean whenOnlineFromPayload ;
126207
127208 MultiTargetSender (Set <Platform .ServerTarget > targets ) {
128209 this .targets = targets ;
@@ -131,7 +212,10 @@ private final class MultiTargetSender implements Sender<P> {
131212 @ Override
132213 public CompletableFuture <Void > send (P payload ) {
133214 Objects .requireNonNull (payload );
134- PluginMessage message = toPluginMessage (payload , false );
215+ UUID requirePlayer = PluginMessageChannel .this
216+ .resolveConditionUuid (payload , requirePlayerUuid , requirePlayerFromPayload );
217+ UUID whenOnline = PluginMessageChannel .this .resolveConditionUuid (payload , whenOnlineUuid , whenOnlineFromPayload );
218+ PluginMessage message = toPluginMessage (payload , false , requirePlayer , whenOnline );
135219 List <CompletableFuture <Void >> futures = new ArrayList <>();
136220 for (Platform .ServerTarget target : targets ) {
137221 futures .add (sendTransport .send (target , message ));
@@ -148,5 +232,86 @@ public CompletableFuture<P> request(P payload) {
148232 public CompletableFuture <P > request (P payload , Duration timeout ) {
149233 throw new UnsupportedOperationException ("Request is only supported for single-target senders" );
150234 }
235+
236+ @ Override
237+ public Sender <P > requirePlayer (UUID player ) {
238+ Objects .requireNonNull (player );
239+ if (whenOnlineUuid != null || whenOnlineFromPayload ) {
240+ throw new IllegalStateException ("Cannot combine requirePlayer and whenOnline" );
241+ }
242+ requirePlayerUuid = player ;
243+ requirePlayerFromPayload = false ;
244+ return this ;
245+ }
246+
247+ @ Override
248+ public Sender <P > requirePlayer () {
249+ if (whenOnlineUuid != null || whenOnlineFromPayload ) {
250+ throw new IllegalStateException ("Cannot combine requirePlayer and whenOnline" );
251+ }
252+ requirePlayerFromPayload = true ;
253+ requirePlayerUuid = null ;
254+ return this ;
255+ }
256+
257+ @ Override
258+ public Sender <P > whenOnline (UUID player ) {
259+ Objects .requireNonNull (player );
260+ if (requirePlayerUuid != null || requirePlayerFromPayload ) {
261+ throw new IllegalStateException ("Cannot combine requirePlayer and whenOnline" );
262+ }
263+ whenOnlineUuid = player ;
264+ whenOnlineFromPayload = false ;
265+ return this ;
266+ }
267+
268+ @ Override
269+ public Sender <P > whenOnline () {
270+ if (requirePlayerUuid != null || requirePlayerFromPayload ) {
271+ throw new IllegalStateException ("Cannot combine requirePlayer and whenOnline" );
272+ }
273+ whenOnlineFromPayload = true ;
274+ whenOnlineUuid = null ;
275+ return this ;
276+ }
277+ }
278+
279+ private final class BroadcastSender implements Sender <P > {
280+
281+ @ Override
282+ public CompletableFuture <Void > send (P payload ) {
283+ Objects .requireNonNull (payload );
284+ return sendTransport .send (Platform .BACKEND .target ("*" ), toPluginMessage (payload , false ));
285+ }
286+
287+ @ Override
288+ public CompletableFuture <P > request (P payload ) {
289+ throw new UnsupportedOperationException ("Request is not supported for broadcast senders" );
290+ }
291+
292+ @ Override
293+ public CompletableFuture <P > request (P payload , Duration timeout ) {
294+ throw new UnsupportedOperationException ("Request is not supported for broadcast senders" );
295+ }
296+
297+ @ Override
298+ public Sender <P > requirePlayer (UUID player ) {
299+ throw new UnsupportedOperationException ("Delivery conditions are not supported for broadcast senders" );
300+ }
301+
302+ @ Override
303+ public Sender <P > requirePlayer () {
304+ throw new UnsupportedOperationException ("Delivery conditions are not supported for broadcast senders" );
305+ }
306+
307+ @ Override
308+ public Sender <P > whenOnline (UUID player ) {
309+ throw new UnsupportedOperationException ("Delivery conditions are not supported for broadcast senders" );
310+ }
311+
312+ @ Override
313+ public Sender <P > whenOnline () {
314+ throw new UnsupportedOperationException ("Delivery conditions are not supported for broadcast senders" );
315+ }
151316 }
152317}
0 commit comments