2828import java .util .Objects ;
2929import java .util .concurrent .TimeUnit ;
3030
31+ import static dev .qixils .crowdcontrol .util .StringUtils .repr ;
32+
3133/**
3234 * An outgoing packet to the Crowd Control TCP server carrying the result of executing
3335 * a {@link Request requested} effect.
@@ -50,9 +52,9 @@ public class Response implements JsonObject {
5052 private String message ;
5153 @ Nullable
5254 private Duration timeRemaining ; // millis
55+ private String @ Nullable [] ids ;
5356 @ Nullable
54- @ SerializedName ("code" )
55- private String effect ;
57+ private IdType idType ;
5658 @ Nullable
5759 private String method ;
5860 @ Nullable
@@ -89,7 +91,6 @@ public class Response implements JsonObject {
8991 throw new IllegalArgumentException ("timeRemaining must be positive or null" );
9092
9193 this .originatingSocket = builder .originatingSocket ;
92- this .effect = builder .effect ;
9394 this .method = builder .method ;
9495 if (!builder .args .isEmpty ())
9596 this .args = builder .args .toArray ();
@@ -110,8 +111,8 @@ public class Response implements JsonObject {
110111 throw new IllegalArgumentException ("type must be a status if packetType is EFFECT_STATUS" );
111112 if (this .packetType != PacketType .EFFECT_STATUS && this .type != null && this .type .isStatus ())
112113 throw new IllegalArgumentException ("type must not be a status if packetType is not EFFECT_STATUS" );
113- if (this .packetType == PacketType .EFFECT_STATUS && this . effect == null )
114- throw new IllegalArgumentException ("effect cannot be null if packetType is EFFECT_STATUS" );
114+ if (this .packetType == PacketType .EFFECT_STATUS && builder . ids . isEmpty () )
115+ throw new IllegalArgumentException ("ids cannot be empty if packetType is EFFECT_STATUS" );
115116 if (this .packetType != PacketType .EFFECT_RESULT && this .id != 0 )
116117 throw new IllegalArgumentException ("id must be 0 if packetType is not EFFECT_RESULT" );
117118 if (this .packetType == PacketType .EFFECT_RESULT && this .id == 0 )
@@ -128,6 +129,10 @@ public class Response implements JsonObject {
128129 this .message = builder .message ;
129130 if (this .message == null && this .packetType .isMessageRequired ())
130131 throw new IllegalArgumentException ("message cannot be null if packetType requires a message" );
132+
133+ // set IDs
134+ this .ids = this .packetType != PacketType .EFFECT_STATUS ? null : builder .ids .toArray (new String [0 ]);
135+ this .idType = this .ids == null ? null : ExceptionUtil .validateNotNullElse (builder .idType , IdType .EFFECT );
131136 }
132137
133138 /**
@@ -259,16 +264,29 @@ public Duration getTimeRemaining() {
259264 }
260265
261266 /**
262- * Gets the effect that was referenced by the request .
267+ * Gets the IDs receiving a status update .
263268 *
264- * @return effect code
265- * @since 3.5.2
269+ * @return effect IDs
270+ * @since 3.7.0
266271 */
267- @ ApiStatus .AvailableSince ("3.5.2" )
272+ @ ApiStatus .AvailableSince ("3.7.0" )
273+ @ CheckReturnValue
274+ public String @ Nullable [] getIds () {
275+ if (ids == null ) return null ;
276+ return Arrays .copyOf (ids , ids .length );
277+ }
278+
279+ /**
280+ * Gets the type of effect receiving a status update.
281+ *
282+ * @return effect type
283+ * @since 3.7.0
284+ */
285+ @ ApiStatus .AvailableSince ("3.7.0" )
268286 @ CheckReturnValue
269287 @ Nullable
270- public String getEffect () {
271- return effect ;
288+ public IdType getIdType () {
289+ return idType ;
272290 }
273291
274292 /**
@@ -392,7 +410,8 @@ public boolean equals(@Nullable Object o) {
392410 && packetType == response .packetType
393411 && type == response .type
394412 && Objects .equals (message , response .message )
395- && Objects .equals (effect , response .effect )
413+ && Arrays .equals (ids , response .ids )
414+ && Objects .equals (idType , response .idType )
396415 && Objects .equals (method , response .method )
397416 && Arrays .equals (args , response .args )
398417 && Objects .equals (data , response .data )
@@ -403,11 +422,31 @@ public boolean equals(@Nullable Object o) {
403422
404423 @ Override
405424 public int hashCode () {
406- int result = Objects .hash (packetType , originatingSocket , id , type , message , timeRemaining , effect , method , eventType , internal , data );
425+ int result = Objects .hash (packetType , originatingSocket , id , type , message , timeRemaining , idType , method , eventType , internal , data );
426+ result = 31 * result + Arrays .hashCode (ids );
407427 result = 31 * result + Arrays .hashCode (args );
408428 return result ;
409429 }
410430
431+ @ Override
432+ public String toString () {
433+ return "Response{" +
434+ "packetType=" + packetType +
435+ ", originatingSocket=" + originatingSocket +
436+ ", id=" + id +
437+ ", type=" + type +
438+ ", message=" + repr (message ) +
439+ ", timeRemaining=" + timeRemaining +
440+ ", ids=" + Arrays .toString (ids ) +
441+ ", idType=" + idType +
442+ ", method=" + repr (method ) +
443+ ", args=" + Arrays .toString (args ) +
444+ ", data=" + data +
445+ ", eventType=" + repr (eventType ) +
446+ ", internal=" + internal +
447+ '}' ;
448+ }
449+
411450 /**
412451 * Determines if the {@link Request} that originated this {@link Response} is known.
413452 * If not, {@link #send()} will throw an {@link IllegalStateException}.
@@ -467,7 +506,7 @@ public enum PacketType implements ByteObject {
467506 @ ApiStatus .AvailableSince ("3.0.0" )
468507 EFFECT_RESULT (false , true ), // 0
469508 /**
470- * The packet is updating the status of an effect .
509+ * The packet is updating the status of effects .
471510 * This should be used with an {@link Builder#id(int) id} of 0.
472511 *
473512 * @since 3.5.2
@@ -799,7 +838,8 @@ public static class Builder implements Cloneable {
799838 private String message ;
800839 private Duration timeRemaining ;
801840 private PacketType packetType ;
802- private String effect ;
841+ private final List <String > ids = new ArrayList <>();
842+ private IdType idType ;
803843 private String method ;
804844 private final List <Object > args = new ArrayList <>();
805845 private final Map <String , Object > data = new HashMap <>();
@@ -831,7 +871,9 @@ protected Builder(@NotNull Response source) {
831871 this .type = source .type ;
832872 this .timeRemaining = source .timeRemaining ;
833873 this .packetType = source .packetType ;
834- this .effect = source .effect ;
874+ if (source .ids != null )
875+ Collections .addAll (this .ids , source .ids );
876+ this .idType = source .idType ;
835877 this .method = source .method ;
836878 if (source .args != null )
837879 Collections .addAll (this .args , source .args );
@@ -855,7 +897,8 @@ protected Builder(@NotNull Response source) {
855897 protected Builder (@ NotNull Request request ) {
856898 this .id = request .getId ();
857899 this .originatingSocket = request .getOriginatingSocket ();
858- this .effect = request .getEffect ();
900+ if (request .getEffect () != null )
901+ this .ids .add (request .getEffect ());
859902 }
860903
861904 /**
@@ -873,7 +916,8 @@ protected Builder(@NotNull Builder builder) {
873916 this .message = builder .message ;
874917 this .timeRemaining = builder .timeRemaining ;
875918 this .packetType = builder .packetType ;
876- this .effect = builder .effect ;
919+ this .ids .addAll (builder .ids );
920+ this .idType = builder .idType ;
877921 this .method = builder .method ;
878922 this .args .addAll (builder .args );
879923 this .data .putAll (builder .data );
@@ -1071,12 +1115,68 @@ public Builder packetType(@Nullable PacketType packetType) {
10711115 * @param effect effect code
10721116 * @return this builder
10731117 * @since 3.5.2
1118+ * @deprecated Replaced by {@link #ids(String...)}.
10741119 */
10751120 @ ApiStatus .AvailableSince ("3.5.2" )
10761121 @ NotNull
10771122 @ Contract ("_ -> this" )
10781123 public Builder effect (@ Nullable String effect ) {
1079- this .effect = effect ;
1124+ this .ids .clear ();
1125+ if (effect != null )
1126+ this .ids .add (effect );
1127+ return this ;
1128+ }
1129+
1130+ /**
1131+ * Adds effects whose status is being reported on.
1132+ *
1133+ * @param effects effects codes
1134+ * @return this builder
1135+ * @since 3.7.0
1136+ */
1137+ @ ApiStatus .AvailableSince ("3.7.0" )
1138+ @ NotNull
1139+ @ Contract ("_ -> this" )
1140+ public Builder ids (String @ NotNull ... effects ) {
1141+ for (String effect : effects ) {
1142+ if (effect != null ) {
1143+ this .ids .add (effect );
1144+ }
1145+ }
1146+ return this ;
1147+ }
1148+
1149+ /**
1150+ * Adds effects whose status is being reported on.
1151+ *
1152+ * @param effects effects codes
1153+ * @return this builder
1154+ * @since 3.7.0
1155+ */
1156+ @ ApiStatus .AvailableSince ("3.7.0" )
1157+ @ NotNull
1158+ @ Contract ("_ -> this" )
1159+ public Builder ids (@ NotNull Iterable <String > effects ) {
1160+ for (String effect : effects ) {
1161+ if (effect != null ) {
1162+ this .ids .add (effect );
1163+ }
1164+ }
1165+ return this ;
1166+ }
1167+
1168+ /**
1169+ * Sets the type of ID which is being reported on.
1170+ *
1171+ * @param idType type of ID
1172+ * @return this builder
1173+ * @since 3.7.0
1174+ */
1175+ @ ApiStatus .AvailableSince ("3.7.0" )
1176+ @ NotNull
1177+ @ Contract ("_ -> this" )
1178+ public Builder idType (@ Nullable IdType idType ) {
1179+ this .idType = idType ;
10801180 return this ;
10811181 }
10821182
@@ -1259,16 +1359,29 @@ public PacketType packetType() {
12591359 }
12601360
12611361 /**
1262- * Gets the effect that was referenced by the request .
1362+ * Gets the effects whose status is being reported on .
12631363 *
1264- * @return effect code
1265- * @since 3.5.2
1364+ * @return effect codes
1365+ * @since 3.7.0
12661366 */
1267- @ ApiStatus .AvailableSince ("3.5.2" )
1367+ @ ApiStatus .AvailableSince ("3.7.0" )
1368+ @ Nullable
1369+ @ CheckReturnValue
1370+ public List <String > ids () {
1371+ return ids ;
1372+ }
1373+
1374+ /**
1375+ * Gets the type of ID whose status is being reported on.
1376+ *
1377+ * @return ID type
1378+ * @since 3.7.0
1379+ */
1380+ @ ApiStatus .AvailableSince ("3.7.0" )
12681381 @ Nullable
12691382 @ CheckReturnValue
1270- public String effect () {
1271- return effect ;
1383+ public IdType idType () {
1384+ return idType ;
12721385 }
12731386
12741387 /**
@@ -1285,7 +1398,7 @@ public String method() {
12851398 }
12861399
12871400 /**
1288- * Gets a view of the arguments to be passed to the remote function.
1401+ * Gets the arguments to be passed to the remote function.
12891402 *
12901403 * @return arguments to pass
12911404 * @since 3.6.0
@@ -1294,11 +1407,11 @@ public String method() {
12941407 @ NotNull
12951408 @ CheckReturnValue
12961409 public List <Object > arguments () {
1297- return Collections . unmodifiableList ( args ) ;
1410+ return args ;
12981411 }
12991412
13001413 /**
1301- * Gets a view of the data to be passed in this event.
1414+ * Gets the data to be passed in this event.
13021415 * To be used with {@link PacketType#GENERIC_EVENT}.
13031416 *
13041417 * @return data to pass
@@ -1308,7 +1421,7 @@ public List<Object> arguments() {
13081421 @ NotNull
13091422 @ CheckReturnValue
13101423 public Map <String , Object > data () {
1311- return Collections . unmodifiableMap ( data ) ;
1424+ return data ;
13121425 }
13131426
13141427 /**
0 commit comments