Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): Expand the supported resource pack operations for 1.20.3 #1005

Merged
merged 12 commits into from
Dec 17, 2023
Merged
108 changes: 101 additions & 7 deletions api/src/main/java/net/kyori/adventure/audience/Audience.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
package net.kyori.adventure.audience;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collector;
Expand All @@ -36,6 +38,8 @@
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.pointer.Pointered;
import net.kyori.adventure.resource.ResourcePackInfo;
import net.kyori.adventure.resource.ResourcePackInfoLike;
import net.kyori.adventure.resource.ResourcePackRequest;
import net.kyori.adventure.resource.ResourcePackRequestLike;
import net.kyori.adventure.sound.Sound;
Expand Down Expand Up @@ -708,24 +712,114 @@ default void openBook(final @NotNull Book book) {
// ------------------------

/**
* Sends a resource pack request to this audience.
* Sends a request to apply resource packs to this audience.
*
* <p>Multiple resource packs are only supported since 1.20.3. On older versions, all requests behave as if {@link ResourcePackRequest#replace()} is set to {@code true}.</p>
zml2008 marked this conversation as resolved.
Show resolved Hide resolved
*
* @param first the resource pack info
* @param others the other pack infos
* @see ResourcePackRequest#addingRequest(ResourcePackInfoLike, ResourcePackInfoLike...)
* @since 4.15.0
*/
@ForwardingAudienceOverrideNotRequired
default void sendResourcePacks(final @NotNull ResourcePackInfoLike first, final @NotNull ResourcePackInfoLike... others) {
this.sendResourcePacks(ResourcePackRequest.addingRequest(first, others));
}

/**
* Sends a request to apply resource packs to this audience.
*
* <p>Multiple resource packs are only supported since 1.20.3. On older versions, all requests behave as if {@link ResourcePackRequest#replace()} is set to {@code true}.</p>
*
* @param request the resource pack request
* @see ResourcePackRequest
* @see ResourcePackInfo
* @since 4.15.0
*/
@ForwardingAudienceOverrideNotRequired
default void sendResourcePack(final @NotNull ResourcePackRequestLike request) {
this.sendResourcePack(request.asResourcePackRequest());
default void sendResourcePacks(final @NotNull ResourcePackRequestLike request) {
this.sendResourcePacks(request.asResourcePackRequest());
}

/**
* Sends a resource pack request to this audience.
* Sends a request to apply resource packs to this audience.
*
* <p>Multiple resource packs are only supported since 1.20.3. On older versions, all requests behave as if {@link ResourcePackRequest#replace()} is set to {@code true}.</p>
*
* @param request the resource pack request
* @see ResourcePackRequest
* @see ResourcePackInfo
* @since 4.15.0
*/
default void sendResourcePacks(final @NotNull ResourcePackRequest request) {
}

/**
* Clear resource packs with the IDs used in the provided requests if they are present.
*
* @param request the request used to originally apply the packs
* @since 4.15.0
* @sinceMinecraft 1.20.3
*/
@ForwardingAudienceOverrideNotRequired
default void removeResourcePacks(final @NotNull ResourcePackRequestLike request) {
this.removeResourcePacks(request.asResourcePackRequest());
}

/**
* Clear resource packs with the IDs used in the provided requests if they are present.
*
* @param request the request used to originally apply the packs
* @since 4.15.0
* @sinceMinecraft 1.20.3
*/
@ForwardingAudienceOverrideNotRequired
default void removeResourcePacks(final @NotNull ResourcePackRequest request) {
final List<ResourcePackInfo> infos = request.packs();
if (infos.size() == 1) {
this.removeResourcePacks(infos.get(0).id());
} else if (infos.isEmpty()) {
return;
}

final UUID[] otherReqs = new UUID[infos.size() - 1];
for (int i = 0; i < otherReqs.length; i++) {
otherReqs[i] = infos.get(i + 1).id();
}
this.removeResourcePacks(infos.get(0).id(), otherReqs);
}

/**
* Clear resource packs with the IDs used in the provided requests if they are present.
*
* @param request the first request used to originally apply the pack
* @param others requests for other packs that should be removed
* @since 4.15.0
* @sinceMinecraft 1.20.3
*/
@ForwardingAudienceOverrideNotRequired
default void removeResourcePacks(final @NotNull ResourcePackInfoLike request, final @NotNull ResourcePackInfoLike @NotNull... others) {
final UUID[] otherReqs = new UUID[others.length];
for (int i = 0; i < others.length; i++) {
otherReqs[i] = others[i].asResourcePackInfo().id();
}
this.removeResourcePacks(request.asResourcePackInfo().id(), otherReqs);
}

/**
* Clear resource packs with the provided ids if they are present.
*
* @param id the id
* @param others the ids of any additional resource packs
* @since 4.15.0
* @sinceMinecraft 1.20.3
*/
default void removeResourcePacks(final @NotNull UUID id, final @NotNull UUID@NotNull... others) {
}

/**
* Clear all server-provided resource packs that have been sent to this user.
*
* @since 4.15.0
*/
default void sendResourcePack(final @NotNull ResourcePackRequest request) {
default void clearResourcePacks() {
}
}
9 changes: 9 additions & 0 deletions api/src/main/java/net/kyori/adventure/audience/Audiences.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.function.Consumer;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import net.kyori.adventure.resource.ResourcePackCallback;
import net.kyori.adventure.text.ComponentLike;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -55,4 +56,12 @@ private Audiences() {
public static @NotNull Consumer<? super Audience> sendingMessage(final @NotNull ComponentLike message) {
return audience -> audience.sendMessage(message);
}

static @NotNull ResourcePackCallback unwrapCallback(final Audience forwarding, final Audience dest, final @NotNull ResourcePackCallback cb) {
if (cb == ResourcePackCallback.noOp()) return cb;

return (uuid, status, audience) -> {
cb.packEventReceived(uuid, status, audience == dest ? forwarding : audience);
};
}
}
13 changes: 11 additions & 2 deletions api/src/main/java/net/kyori/adventure/audience/EmptyAudience.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.pointer.Pointer;
import net.kyori.adventure.resource.ResourcePackRequestLike;
import net.kyori.adventure.resource.ResourcePackInfoLike;
import net.kyori.adventure.resource.ResourcePackRequest;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import org.jetbrains.annotations.Contract;
Expand Down Expand Up @@ -120,7 +121,15 @@ public void openBook(final Book.@NotNull Builder book) {
}

@Override
public void sendResourcePack(final @NotNull ResourcePackRequestLike request) {
public void sendResourcePacks(final @NotNull ResourcePackInfoLike request, final @NotNull ResourcePackInfoLike@NotNull... others) {
}

@Override
public void removeResourcePacks(final @NotNull ResourcePackRequest request) {
}

@Override
public void removeResourcePacks(final @NotNull ResourcePackInfoLike request, final @NotNull ResourcePackInfoLike@NotNull... others) {
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
Expand Down Expand Up @@ -201,8 +202,18 @@ default void openBook(final @NotNull Book book) {
}

@Override
default void sendResourcePack(final @NotNull ResourcePackRequest request) {
for (final Audience audience : this.audiences()) audience.sendResourcePack(request);
default void sendResourcePacks(final @NotNull ResourcePackRequest request) {
for (final Audience audience : this.audiences()) audience.sendResourcePacks(request);
}

@Override
default void removeResourcePacks(final @NotNull UUID id, final @NotNull UUID @NotNull ... others) {
for (final Audience audience : this.audiences()) audience.removeResourcePacks(id, others);
}

@Override
default void clearResourcePacks() {
for (final Audience audience : this.audiences()) audience.clearResourcePacks();
}

/**
Expand Down Expand Up @@ -369,8 +380,18 @@ default void openBook(final @NotNull Book book) {
}

@Override
default void sendResourcePack(final @NotNull ResourcePackRequest request) {
this.audience().sendResourcePack(request);
default void sendResourcePacks(final @NotNull ResourcePackRequest request) {
this.audience().sendResourcePacks(request.callback(Audiences.unwrapCallback(this, this.audience(), request.callback())));
}

@Override
default void removeResourcePacks(final @NotNull UUID id, final @NotNull UUID @NotNull ... others) {
this.audience().removeResourcePacks(id, others);
}

@Override
default void clearResourcePacks() {
this.audience().clearResourcePacks();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2023 KyoriPowered
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.kyori.adventure.resource;

import java.util.UUID;
import java.util.function.BiConsumer;
import net.kyori.adventure.audience.Audience;
import org.jetbrains.annotations.NotNull;

/**
* A callback for a resource pack application operation.
*
* @since 4.15.0
*/
@FunctionalInterface
public interface ResourcePackCallback {
/**
* Create a pack callback that performs no operation.
*
* <p>Multiple calls to this method are guaranteed to return callback functions with equal identity.</p>
*
* @return the no-op callback
* @since 4.15.0
*/
static @NotNull ResourcePackCallback noOp() {
return ResourcePackCallbacks.NO_OP;
}

/**
* Create a pack callback that will only execute the provided functions when the pack application has completed, discarding all intermediate events.
*
* @param success the success callback
* @param failure the failure callback
* @return the created callback
* @since 4.15.0
*/
static @NotNull ResourcePackCallback onTerminal(final @NotNull BiConsumer<UUID, Audience> success, final @NotNull BiConsumer<UUID, Audience> failure) {
return (uuid, status, audience) -> {
if (status == ResourcePackStatus.SUCCESSFULLY_LOADED) {
success.accept(uuid, audience);
} else if (!status.intermediate()) {
failure.accept(uuid, audience);
}
};
}

/**
* Called when a pack event has been received.
*
* <p>If the pack apply action was executed on a group audience, {@code audience} will referer to the
* individual member audiences the action is executed on. Forwarding audiences may wrap callbacks to ensure they receive the appropriate wrapped audience.</p>
*
* @param uuid the uuid of the pack that has been applied.
* @param status the current pack status
* @param audience the audience the pack is being applied to
* @since 4.15.0
*/
void packEventReceived(final @NotNull UUID uuid, final @NotNull ResourcePackStatus status, final @NotNull Audience audience);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2023 KyoriPowered
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.kyori.adventure.resource;

final class ResourcePackCallbacks {
private ResourcePackCallbacks() {
}

static final ResourcePackCallback NO_OP = (uuid, status, audience) -> {};
}
Loading