mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-04 23:47:59 +01:00
feat: conform to Adventure resource pack API, remove Minestom resource pack types
This commit is contained in:
parent
e24cb62583
commit
40ac94d092
@ -1,5 +1,7 @@
|
||||
package net.minestom.demo;
|
||||
|
||||
import net.kyori.adventure.resource.ResourcePackInfo;
|
||||
import net.kyori.adventure.resource.ResourcePackRequest;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.adventure.MinestomAdventure;
|
||||
@ -18,7 +20,10 @@ import net.minestom.server.event.item.ItemDropEvent;
|
||||
import net.minestom.server.event.item.PickupItemEvent;
|
||||
import net.minestom.server.event.player.*;
|
||||
import net.minestom.server.event.server.ServerTickMonitorEvent;
|
||||
import net.minestom.server.instance.*;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.InstanceContainer;
|
||||
import net.minestom.server.instance.InstanceManager;
|
||||
import net.minestom.server.instance.LightingChunk;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.inventory.Inventory;
|
||||
import net.minestom.server.inventory.InventoryType;
|
||||
@ -32,8 +37,11 @@ import net.minestom.server.utils.NamespaceID;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@ -122,10 +130,10 @@ public class PlayerInit {
|
||||
|
||||
event.getPlayer().sendMessage("MESSAGE " + ThreadLocalRandom.current().nextDouble());
|
||||
|
||||
if ("false".equals(block.getProperty("waterlogged")) && itemStack.material().equals(Material.WATER_BUCKET)) {
|
||||
if ("false" .equals(block.getProperty("waterlogged")) && itemStack.material().equals(Material.WATER_BUCKET)) {
|
||||
block = block.withProperty("waterlogged", "true");
|
||||
System.out.println("SET WATERLOGGER");
|
||||
} else if ("true".equals(block.getProperty("waterlogged")) && itemStack.material().equals(Material.BUCKET)) {
|
||||
} else if ("true" .equals(block.getProperty("waterlogged")) && itemStack.material().equals(Material.BUCKET)) {
|
||||
block = block.withProperty("waterlogged", "false");
|
||||
System.out.println("SET NOT WATERLOGGED");
|
||||
} else return;
|
||||
|
@ -8,6 +8,9 @@ import net.kyori.adventure.identity.Identified;
|
||||
import net.kyori.adventure.identity.Identity;
|
||||
import net.kyori.adventure.inventory.Book;
|
||||
import net.kyori.adventure.pointer.Pointers;
|
||||
import net.kyori.adventure.resource.ResourcePackCallback;
|
||||
import net.kyori.adventure.resource.ResourcePackRequest;
|
||||
import net.kyori.adventure.resource.ResourcePackStatus;
|
||||
import net.kyori.adventure.sound.Sound;
|
||||
import net.kyori.adventure.sound.SoundStop;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@ -57,10 +60,7 @@ import net.minestom.server.network.PlayerProvider;
|
||||
import net.minestom.server.network.packet.client.ClientPacket;
|
||||
import net.minestom.server.network.packet.server.SendablePacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.common.DisconnectPacket;
|
||||
import net.minestom.server.network.packet.server.common.KeepAlivePacket;
|
||||
import net.minestom.server.network.packet.server.common.PluginMessagePacket;
|
||||
import net.minestom.server.network.packet.server.common.ResourcePackPushPacket;
|
||||
import net.minestom.server.network.packet.server.common.*;
|
||||
import net.minestom.server.network.packet.server.login.LoginDisconnectPacket;
|
||||
import net.minestom.server.network.packet.server.play.*;
|
||||
import net.minestom.server.network.packet.server.play.data.DeathLocation;
|
||||
@ -69,7 +69,6 @@ import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.network.player.PlayerSocketConnection;
|
||||
import net.minestom.server.recipe.Recipe;
|
||||
import net.minestom.server.recipe.RecipeManager;
|
||||
import net.minestom.server.resourcepack.ResourcePack;
|
||||
import net.minestom.server.scoreboard.BelowNameTag;
|
||||
import net.minestom.server.scoreboard.Team;
|
||||
import net.minestom.server.snapshot.EntitySnapshot;
|
||||
@ -234,6 +233,11 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
private Identity identity;
|
||||
private final Pointers pointers;
|
||||
|
||||
// Resource packs
|
||||
private final Map<UUID, ResourcePackCallback> resourcePackCallbacks = new HashMap<>();
|
||||
// The future is non-null when a resource pack is in-flight, and completed when all statuses have been received.
|
||||
private CompletableFuture<Void> resourcePackFuture = null;
|
||||
|
||||
public Player(@NotNull UUID uuid, @NotNull String username, @NotNull PlayerConnection playerConnection) {
|
||||
super(EntityType.PLAYER, uuid);
|
||||
this.username = username;
|
||||
@ -1269,13 +1273,56 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
return !itemDropEvent.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendResourcePacks(@NotNull ResourcePackRequest request) {
|
||||
if (request.replace()) clearResourcePacks();
|
||||
|
||||
for (var pack : request.packs()) {
|
||||
sendPacket(new ResourcePackPushPacket(pack, request.required(), request.prompt()));
|
||||
resourcePackCallbacks.put(pack.id(), request.callback());
|
||||
if (resourcePackFuture == null) {
|
||||
resourcePackFuture = new CompletableFuture<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeResourcePacks(@NotNull UUID id, @NotNull UUID @NotNull ... others) {
|
||||
sendPacket(new ResourcePackPopPacket(id));
|
||||
for (var other : others) {
|
||||
sendPacket(new ResourcePackPopPacket(other));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearResourcePacks() {
|
||||
sendPacket(new ResourcePackPopPacket((UUID) null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the player resource pack.
|
||||
*
|
||||
* @param resourcePack the resource pack
|
||||
* If there are resource packs in-flight, a future is returned which will be completed when
|
||||
* all resource packs have been responded to by the client. Otherwise null is returned.
|
||||
*/
|
||||
public void setResourcePack(@NotNull ResourcePack resourcePack) {
|
||||
sendPacket(new ResourcePackPushPacket(resourcePack));
|
||||
@ApiStatus.Internal
|
||||
public @Nullable CompletableFuture<Void> getResourcePackFuture() {
|
||||
return resourcePackFuture;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public void onResourcePackStatus(@NotNull UUID id, @NotNull ResourcePackStatus status) {
|
||||
var callback = resourcePackCallbacks.get(id);
|
||||
if (callback == null) return;
|
||||
|
||||
callback.packEventReceived(id, status, this);
|
||||
if (!status.intermediate()) {
|
||||
// Remove the callback and finish the future if relevant
|
||||
resourcePackCallbacks.remove(id);
|
||||
|
||||
if (resourcePackCallbacks.isEmpty() && resourcePackFuture != null) {
|
||||
resourcePackFuture.complete(null);
|
||||
resourcePackFuture = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2133,7 +2180,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
|
||||
@Override
|
||||
public @NotNull HoverEvent<ShowEntity> asHoverEvent(@NotNull UnaryOperator<ShowEntity> op) {
|
||||
return HoverEvent.showEntity(ShowEntity.of(EntityType.PLAYER, this.uuid, this.displayName));
|
||||
return HoverEvent.showEntity(ShowEntity.showEntity(EntityType.PLAYER, this.uuid, this.displayName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.kyori.adventure.resource.ResourcePackStatus;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.trait.PlayerEvent;
|
||||
import net.minestom.server.resourcepack.ResourcePackStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
|
@ -9,5 +9,8 @@ public class ResourcePackListener {
|
||||
|
||||
public static void listener(ClientResourcePackStatusPacket packet, Player player) {
|
||||
EventDispatcher.call(new PlayerResourcePackStatusEvent(player, packet.status()));
|
||||
|
||||
// Run adventure callbacks for the resource pack
|
||||
player.onResourcePackStatus(packet.id(), packet.status());
|
||||
}
|
||||
}
|
||||
|
@ -272,6 +272,10 @@ public final class ConnectionManager {
|
||||
player.sendPacket(TagsPacket.DEFAULT_TAGS);
|
||||
}
|
||||
|
||||
// Wait for pending resource packs if any
|
||||
var packFuture = player.getResourcePackFuture();
|
||||
if (packFuture != null) packFuture.join();
|
||||
|
||||
player.setPendingInstance(spawningInstance);
|
||||
player.sendPacket(new FinishConfigurationPacket());
|
||||
});
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.minestom.server.network.packet.client.common;
|
||||
|
||||
import net.kyori.adventure.resource.ResourcePackStatus;
|
||||
import net.minestom.server.network.NetworkBuffer;
|
||||
import net.minestom.server.network.packet.client.ClientPacket;
|
||||
import net.minestom.server.resourcepack.ResourcePackStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
@ -12,7 +12,7 @@ public record ClientResourcePackStatusPacket(
|
||||
@NotNull ResourcePackStatus status
|
||||
) implements ClientPacket {
|
||||
public ClientResourcePackStatusPacket(@NotNull NetworkBuffer reader) {
|
||||
this(reader.read(NetworkBuffer.UUID), reader.readEnum(ResourcePackStatus.class));
|
||||
this(reader.read(NetworkBuffer.UUID), readStatus(reader));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -20,4 +20,19 @@ public record ClientResourcePackStatusPacket(
|
||||
writer.write(NetworkBuffer.UUID, id);
|
||||
writer.writeEnum(ResourcePackStatus.class, status);
|
||||
}
|
||||
|
||||
private static @NotNull ResourcePackStatus readStatus(@NotNull NetworkBuffer reader) {
|
||||
var ordinal = reader.read(NetworkBuffer.VAR_INT);
|
||||
return switch (ordinal) {
|
||||
case 0 -> ResourcePackStatus.SUCCESSFULLY_LOADED;
|
||||
case 1 -> ResourcePackStatus.DECLINED;
|
||||
case 2 -> ResourcePackStatus.FAILED_DOWNLOAD;
|
||||
case 3 -> ResourcePackStatus.ACCEPTED;
|
||||
case 4 -> ResourcePackStatus.DOWNLOADED;
|
||||
case 5 -> ResourcePackStatus.INVALID_URL;
|
||||
case 6 -> ResourcePackStatus.FAILED_RELOAD;
|
||||
case 7 -> ResourcePackStatus.DISCARDED;
|
||||
default -> throw new IllegalStateException("Unexpected resource pack status: " + ordinal);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
package net.minestom.server.network.packet.server.common;
|
||||
|
||||
import net.kyori.adventure.resource.ResourcePackInfo;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.network.ConnectionState;
|
||||
import net.minestom.server.network.NetworkBuffer;
|
||||
import net.minestom.server.network.packet.server.ComponentHoldingServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.resourcepack.ResourcePack;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -30,9 +30,8 @@ public record ResourcePackPushPacket(
|
||||
reader.read(BOOLEAN), reader.readOptional(COMPONENT));
|
||||
}
|
||||
|
||||
public ResourcePackPushPacket(@NotNull ResourcePack resourcePack) {
|
||||
this(resourcePack.getId(), resourcePack.getUrl(), resourcePack.getHash(),
|
||||
resourcePack.isForced(), resourcePack.getPrompt());
|
||||
public ResourcePackPushPacket(@NotNull ResourcePackInfo resourcePackInfo, boolean required, @Nullable Component prompt) {
|
||||
this(resourcePackInfo.id(), resourcePackInfo.uri().toString(), resourcePackInfo.hash(), required, prompt);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,79 +0,0 @@
|
||||
package net.minestom.server.resourcepack;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Represents a resource pack which can be sent with {@link Player#setResourcePack(ResourcePack)}.
|
||||
*/
|
||||
public class ResourcePack {
|
||||
|
||||
private final UUID id;
|
||||
private final String url;
|
||||
private final String hash;
|
||||
private final boolean forced;
|
||||
private final Component prompt;
|
||||
|
||||
private ResourcePack(@NotNull UUID id, @NotNull String url, @Nullable String hash, boolean forced, @Nullable Component prompt) {
|
||||
this.id = id;
|
||||
this.url = url;
|
||||
// Optional, set to empty if null
|
||||
this.hash = hash == null ? "" : hash;
|
||||
this.forced = forced;
|
||||
this.prompt = prompt;
|
||||
}
|
||||
|
||||
public static ResourcePack optional(@NotNull UUID id, @NotNull String url, @Nullable String hash, @Nullable Component prompt) {
|
||||
return new ResourcePack(id, url, hash, false, prompt);
|
||||
}
|
||||
|
||||
public static ResourcePack optional(@NotNull UUID id, @NotNull String url, @Nullable String hash) {
|
||||
return optional(id, url, hash, null);
|
||||
}
|
||||
|
||||
public static ResourcePack forced(@NotNull UUID id, @NotNull String url, @Nullable String hash, @Nullable Component prompt) {
|
||||
return new ResourcePack(id, url, hash, true, prompt);
|
||||
}
|
||||
|
||||
public static ResourcePack forced(@NotNull UUID id, @NotNull String url, @Nullable String hash) {
|
||||
return forced(id, url, hash, null);
|
||||
}
|
||||
|
||||
public @NotNull UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the resource pack URL.
|
||||
*
|
||||
* @return the resource pack URL
|
||||
*/
|
||||
public @NotNull String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the resource pack hash.
|
||||
* <p>
|
||||
* WARNING: if null or empty, the player will probably waste bandwidth by re-downloading
|
||||
* the resource pack.
|
||||
*
|
||||
* @return the resource pack hash, can be empty
|
||||
*/
|
||||
public @NotNull String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public boolean isForced() {
|
||||
return forced;
|
||||
}
|
||||
|
||||
public @Nullable Component getPrompt() {
|
||||
return prompt;
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package net.minestom.server.resourcepack;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
|
||||
/**
|
||||
* Represents the result of {@link Player#setResourcePack(ResourcePack)} in
|
||||
* {@link net.minestom.server.event.player.PlayerResourcePackStatusEvent}.
|
||||
*/
|
||||
public enum ResourcePackStatus {
|
||||
|
||||
SUCCESSFULLY_LOADED,
|
||||
DECLINED,
|
||||
FAILED_DOWNLOAD,
|
||||
ACCEPTED,
|
||||
DOWNLOADED,
|
||||
INVALID_URL,
|
||||
FAILED_RELOAD,
|
||||
DISCARDED,
|
||||
}
|
Loading…
Reference in New Issue
Block a user