Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-16 21:10:30 +01:00
Do not apply a resource pack that has already been applied (#1236)
* Do not apply a resource pack that has already been applied * Throw IllegalStateException in case of applying a resource pack already applied from the API * Updated some dependencies * Added support for ServerResourcePackSendEvent resource pack modification
Dieser Commit ist enthalten in:
Ursprung
15897c5258
Commit
ef861819e3
@ -54,8 +54,7 @@ public interface ResourcePackInfo extends ResourcePackRequestLike {
|
|||||||
*
|
*
|
||||||
* @return the hash if present or null otherwise
|
* @return the hash if present or null otherwise
|
||||||
*/
|
*/
|
||||||
@Nullable
|
byte @Nullable [] getHash();
|
||||||
byte[] getHash();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link Origin} of this resource-pack.
|
* Gets the {@link Origin} of this resource-pack.
|
||||||
|
@ -2,26 +2,26 @@
|
|||||||
configurate3 = "3.7.3"
|
configurate3 = "3.7.3"
|
||||||
configurate4 = "4.1.2"
|
configurate4 = "4.1.2"
|
||||||
flare = "2.0.1"
|
flare = "2.0.1"
|
||||||
log4j = "2.20.0"
|
log4j = "2.22.1"
|
||||||
netty = "4.1.106.Final"
|
netty = "4.1.106.Final"
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
indra-publishing = "net.kyori.indra.publishing:2.0.6"
|
indra-publishing = "net.kyori.indra.publishing:2.0.6"
|
||||||
shadow = "com.github.johnrengelman.shadow:8.1.0"
|
shadow = "com.github.johnrengelman.shadow:8.1.1"
|
||||||
spotless = "com.diffplug.spotless:6.12.0"
|
spotless = "com.diffplug.spotless:6.12.0"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
adventure-bom = "net.kyori:adventure-bom:4.15.0"
|
adventure-bom = "net.kyori:adventure-bom:4.15.0"
|
||||||
adventure-facet = "net.kyori:adventure-platform-facet:4.3.0"
|
adventure-facet = "net.kyori:adventure-platform-facet:4.3.2"
|
||||||
asm = "org.ow2.asm:asm:9.5"
|
asm = "org.ow2.asm:asm:9.6"
|
||||||
auto-service = "com.google.auto.service:auto-service:1.0.1"
|
auto-service = "com.google.auto.service:auto-service:1.0.1"
|
||||||
auto-service-annotations = "com.google.auto.service:auto-service-annotations:1.0.1"
|
auto-service-annotations = "com.google.auto.service:auto-service-annotations:1.0.1"
|
||||||
brigadier = "com.velocitypowered:velocity-brigadier:1.0.0-SNAPSHOT"
|
brigadier = "com.velocitypowered:velocity-brigadier:1.0.0-SNAPSHOT"
|
||||||
bstats = "org.bstats:bstats-base:3.0.1"
|
bstats = "org.bstats:bstats-base:3.0.2"
|
||||||
caffeine = "com.github.ben-manes.caffeine:caffeine:3.1.5"
|
caffeine = "com.github.ben-manes.caffeine:caffeine:3.1.5"
|
||||||
checker-qual = "org.checkerframework:checker-qual:3.28.0"
|
checker-qual = "org.checkerframework:checker-qual:3.42.0"
|
||||||
checkstyle = "com.puppycrawl.tools:checkstyle:10.9.3"
|
checkstyle = "com.puppycrawl.tools:checkstyle:10.9.3"
|
||||||
completablefutures = "com.spotify:completable-futures:0.3.5"
|
completablefutures = "com.spotify:completable-futures:0.3.6"
|
||||||
configurate3-hocon = { module = "org.spongepowered:configurate-hocon", version.ref = "configurate3" }
|
configurate3-hocon = { module = "org.spongepowered:configurate-hocon", version.ref = "configurate3" }
|
||||||
configurate3-yaml = { module = "org.spongepowered:configurate-yaml", version.ref = "configurate3" }
|
configurate3-yaml = { module = "org.spongepowered:configurate-yaml", version.ref = "configurate3" }
|
||||||
configurate3-gson = { module = "org.spongepowered:configurate-gson", version.ref = "configurate3" }
|
configurate3-gson = { module = "org.spongepowered:configurate-gson", version.ref = "configurate3" }
|
||||||
@ -34,7 +34,7 @@ flare-core = { module = "space.vectrix.flare:flare", version.ref = "flare" }
|
|||||||
flare-fastutil = { module = "space.vectrix.flare:flare-fastutil", version.ref = "flare" }
|
flare-fastutil = { module = "space.vectrix.flare:flare-fastutil", version.ref = "flare" }
|
||||||
jline = "org.jline:jline-terminal-jansi:3.23.0"
|
jline = "org.jline:jline-terminal-jansi:3.23.0"
|
||||||
jopt = "net.sf.jopt-simple:jopt-simple:5.0.4"
|
jopt = "net.sf.jopt-simple:jopt-simple:5.0.4"
|
||||||
junit = "org.junit.jupiter:junit-jupiter:5.9.0"
|
junit = "org.junit.jupiter:junit-jupiter:5.10.2"
|
||||||
jspecify = "org.jspecify:jspecify:0.3.0"
|
jspecify = "org.jspecify:jspecify:0.3.0"
|
||||||
kyori-ansi = "net.kyori:ansi:1.0.3"
|
kyori-ansi = "net.kyori:ansi:1.0.3"
|
||||||
guava = "com.google.guava:guava:25.1-jre"
|
guava = "com.google.guava:guava:25.1-jre"
|
||||||
@ -46,7 +46,7 @@ log4j-core = { module = "org.apache.logging.log4j:log4j-core", version.ref = "lo
|
|||||||
log4j-slf4j-impl = { module = "org.apache.logging.log4j:log4j-slf4j2-impl", version.ref = "log4j" }
|
log4j-slf4j-impl = { module = "org.apache.logging.log4j:log4j-slf4j2-impl", version.ref = "log4j" }
|
||||||
log4j-iostreams = { module = "org.apache.logging.log4j:log4j-iostreams", version.ref = "log4j" }
|
log4j-iostreams = { module = "org.apache.logging.log4j:log4j-iostreams", version.ref = "log4j" }
|
||||||
log4j-jul = { module = "org.apache.logging.log4j:log4j-jul", version.ref = "log4j" }
|
log4j-jul = { module = "org.apache.logging.log4j:log4j-jul", version.ref = "log4j" }
|
||||||
mockito = "org.mockito:mockito-core:5.2.0"
|
mockito = "org.mockito:mockito-core:5.10.0"
|
||||||
netty-codec = { module = "io.netty:netty-codec", version.ref = "netty" }
|
netty-codec = { module = "io.netty:netty-codec", version.ref = "netty" }
|
||||||
netty-codec-haproxy = { module = "io.netty:netty-codec-haproxy", version.ref = "netty" }
|
netty-codec-haproxy = { module = "io.netty:netty-codec-haproxy", version.ref = "netty" }
|
||||||
netty-codec-http = { module = "io.netty:netty-codec-http", version.ref = "netty" }
|
netty-codec-http = { module = "io.netty:netty-codec-http", version.ref = "netty" }
|
||||||
@ -54,7 +54,7 @@ netty-handler = { module = "io.netty:netty-handler", version.ref = "netty" }
|
|||||||
netty-transport-native-epoll = { module = "io.netty:netty-transport-native-epoll", version.ref = "netty" }
|
netty-transport-native-epoll = { module = "io.netty:netty-transport-native-epoll", version.ref = "netty" }
|
||||||
netty-transport-native-kqueue = { module = "io.netty:netty-transport-native-kqueue", version.ref = "netty" }
|
netty-transport-native-kqueue = { module = "io.netty:netty-transport-native-kqueue", version.ref = "netty" }
|
||||||
nightconfig = "com.electronwill.night-config:toml:3.6.7"
|
nightconfig = "com.electronwill.night-config:toml:3.6.7"
|
||||||
slf4j = "org.slf4j:slf4j-api:2.0.7"
|
slf4j = "org.slf4j:slf4j-api:2.0.12"
|
||||||
snakeyaml = "org.yaml:snakeyaml:1.33"
|
snakeyaml = "org.yaml:snakeyaml:1.33"
|
||||||
spotbugs-annotations = "com.github.spotbugs:spotbugs-annotations:4.7.3"
|
spotbugs-annotations = "com.github.spotbugs:spotbugs-annotations:4.7.3"
|
||||||
terminalconsoleappender = "net.minecrell:terminalconsoleappender:1.3.0"
|
terminalconsoleappender = "net.minecrell:terminalconsoleappender:1.3.0"
|
||||||
|
@ -174,36 +174,49 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(ResourcePackRequestPacket packet) {
|
public boolean handle(final ResourcePackRequestPacket packet) {
|
||||||
ResourcePackInfo.Builder builder = new VelocityResourcePackInfo.BuilderImpl(
|
final ResourcePackInfo.Builder builder = new VelocityResourcePackInfo.BuilderImpl(
|
||||||
Preconditions.checkNotNull(packet.getUrl()))
|
Preconditions.checkNotNull(packet.getUrl()))
|
||||||
.setId(packet.getId())
|
.setId(packet.getId())
|
||||||
.setPrompt(packet.getPrompt() == null ? null : packet.getPrompt().getComponent())
|
.setPrompt(packet.getPrompt() == null ? null : packet.getPrompt().getComponent())
|
||||||
.setShouldForce(packet.isRequired())
|
.setShouldForce(packet.isRequired())
|
||||||
.setOrigin(ResourcePackInfo.Origin.DOWNSTREAM_SERVER);
|
.setOrigin(ResourcePackInfo.Origin.DOWNSTREAM_SERVER);
|
||||||
|
|
||||||
String hash = packet.getHash();
|
final String hash = packet.getHash();
|
||||||
if (hash != null && !hash.isEmpty()) {
|
if (hash != null && !hash.isEmpty()) {
|
||||||
if (PLAUSIBLE_SHA1_HASH.matcher(hash).matches()) {
|
if (PLAUSIBLE_SHA1_HASH.matcher(hash).matches()) {
|
||||||
builder.setHash(ByteBufUtil.decodeHexDump(hash));
|
builder.setHash(ByteBufUtil.decodeHexDump(hash));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerResourcePackSendEvent event = new ServerResourcePackSendEvent(
|
final ResourcePackInfo resourcePackInfo = builder.build();
|
||||||
builder.build(), this.serverConn);
|
final ServerResourcePackSendEvent event = new ServerResourcePackSendEvent(
|
||||||
|
resourcePackInfo, this.serverConn);
|
||||||
server.getEventManager().fire(event).thenAcceptAsync(serverResourcePackSendEvent -> {
|
server.getEventManager().fire(event).thenAcceptAsync(serverResourcePackSendEvent -> {
|
||||||
if (playerConnection.isClosed()) {
|
if (playerConnection.isClosed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (serverResourcePackSendEvent.getResult().isAllowed()) {
|
if (serverResourcePackSendEvent.getResult().isAllowed()) {
|
||||||
final ResourcePackInfo toSend = serverResourcePackSendEvent.getProvidedResourcePack();
|
final ResourcePackInfo toSend = serverResourcePackSendEvent.getProvidedResourcePack();
|
||||||
|
boolean modifiedPack = false;
|
||||||
if (toSend != serverResourcePackSendEvent.getReceivedResourcePack()) {
|
if (toSend != serverResourcePackSendEvent.getReceivedResourcePack()) {
|
||||||
((VelocityResourcePackInfo) toSend)
|
((VelocityResourcePackInfo) toSend)
|
||||||
.setOriginalOrigin(ResourcePackInfo.Origin.DOWNSTREAM_SERVER);
|
.setOriginalOrigin(ResourcePackInfo.Origin.DOWNSTREAM_SERVER);
|
||||||
|
modifiedPack = true;
|
||||||
}
|
}
|
||||||
|
if (serverConn.getPlayer().resourcePackHandler().hasPackAppliedByHash(toSend.getHash())) {
|
||||||
|
// Do not apply a resource pack that has already been applied
|
||||||
|
if (serverConn.getConnection() != null) {
|
||||||
|
serverConn.getConnection().write(new ResourcePackResponsePacket(
|
||||||
|
packet.getId(), packet.getHash(), PlayerResourcePackStatusEvent.Status.ACCEPTED));
|
||||||
|
}
|
||||||
|
if (modifiedPack) {
|
||||||
|
logger.warn("A plugin has tried to modify a ResourcePack provided by the backend server "
|
||||||
|
+ "with a ResourcePack already applied, the applying of the resource pack will be skipped.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
serverConn.getPlayer().resourcePackHandler().queueResourcePack(toSend);
|
serverConn.getPlayer().resourcePackHandler().queueResourcePack(toSend);
|
||||||
|
}
|
||||||
} else if (serverConn.getConnection() != null) {
|
} else if (serverConn.getConnection() != null) {
|
||||||
serverConn.getConnection().write(new ResourcePackResponsePacket(
|
serverConn.getConnection().write(new ResourcePackResponsePacket(
|
||||||
packet.getId(),
|
packet.getId(),
|
||||||
|
@ -45,7 +45,6 @@ import com.velocitypowered.proxy.protocol.packet.config.TagsUpdatePacket;
|
|||||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
@ -54,8 +53,6 @@ import org.apache.logging.log4j.Logger;
|
|||||||
* 1.20.2+ switching. Yes, some of this is exceptionally stupid.
|
* 1.20.2+ switching. Yes, some of this is exceptionally stupid.
|
||||||
*/
|
*/
|
||||||
public class ConfigSessionHandler implements MinecraftSessionHandler {
|
public class ConfigSessionHandler implements MinecraftSessionHandler {
|
||||||
|
|
||||||
private static final Pattern PLAUSIBLE_SHA1_HASH = Pattern.compile("^[a-z0-9]{40}$");
|
|
||||||
private static final Logger logger = LogManager.getLogger(ConfigSessionHandler.class);
|
private static final Logger logger = LogManager.getLogger(ConfigSessionHandler.class);
|
||||||
private final VelocityServer server;
|
private final VelocityServer server;
|
||||||
private final VelocityServerConnection serverConn;
|
private final VelocityServerConnection serverConn;
|
||||||
@ -118,25 +115,39 @@ public class ConfigSessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(ResourcePackRequestPacket packet) {
|
public boolean handle(final ResourcePackRequestPacket packet) {
|
||||||
final MinecraftConnection playerConnection = serverConn.getPlayer().getConnection();
|
final MinecraftConnection playerConnection = serverConn.getPlayer().getConnection();
|
||||||
|
|
||||||
ServerResourcePackSendEvent event =
|
final ResourcePackInfo resourcePackInfo = packet.toServerPromptedPack();
|
||||||
new ServerResourcePackSendEvent(packet.toServerPromptedPack(), this.serverConn);
|
final ServerResourcePackSendEvent event =
|
||||||
|
new ServerResourcePackSendEvent(resourcePackInfo, this.serverConn);
|
||||||
|
|
||||||
server.getEventManager().fire(event).thenAcceptAsync(serverResourcePackSendEvent -> {
|
server.getEventManager().fire(event).thenAcceptAsync(serverResourcePackSendEvent -> {
|
||||||
if (playerConnection.isClosed()) {
|
if (playerConnection.isClosed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (serverResourcePackSendEvent.getResult().isAllowed()) {
|
if (serverResourcePackSendEvent.getResult().isAllowed()) {
|
||||||
ResourcePackInfo toSend = serverResourcePackSendEvent.getProvidedResourcePack();
|
final ResourcePackInfo toSend = serverResourcePackSendEvent.getProvidedResourcePack();
|
||||||
|
boolean modifiedPack = false;
|
||||||
if (toSend != serverResourcePackSendEvent.getReceivedResourcePack()) {
|
if (toSend != serverResourcePackSendEvent.getReceivedResourcePack()) {
|
||||||
((VelocityResourcePackInfo) toSend).setOriginalOrigin(
|
((VelocityResourcePackInfo) toSend).setOriginalOrigin(
|
||||||
ResourcePackInfo.Origin.DOWNSTREAM_SERVER);
|
ResourcePackInfo.Origin.DOWNSTREAM_SERVER);
|
||||||
|
modifiedPack = true;
|
||||||
}
|
}
|
||||||
|
if (serverConn.getPlayer().resourcePackHandler().hasPackAppliedByHash(toSend.getHash())) {
|
||||||
|
// Do not apply a resource pack that has already been applied
|
||||||
|
if (serverConn.getConnection() != null) {
|
||||||
|
serverConn.getConnection().write(new ResourcePackResponsePacket(
|
||||||
|
packet.getId(), packet.getHash(), PlayerResourcePackStatusEvent.Status.ACCEPTED));
|
||||||
|
}
|
||||||
|
if (modifiedPack) {
|
||||||
|
logger.warn("A plugin has tried to modify a ResourcePack provided by the backend server "
|
||||||
|
+ "with a ResourcePack already applied, the applying of the resource pack will be skipped.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
resourcePackToApply = null;
|
resourcePackToApply = null;
|
||||||
serverConn.getPlayer().resourcePackHandler().queueResourcePack(toSend);
|
serverConn.getPlayer().resourcePackHandler().queueResourcePack(toSend);
|
||||||
|
}
|
||||||
} else if (serverConn.getConnection() != null) {
|
} else if (serverConn.getConnection() != null) {
|
||||||
serverConn.getConnection().write(new ResourcePackResponsePacket(
|
serverConn.getConnection().write(new ResourcePackResponsePacket(
|
||||||
packet.getId(), packet.getHash(), PlayerResourcePackStatusEvent.Status.DECLINED));
|
packet.getId(), packet.getHash(), PlayerResourcePackStatusEvent.Status.DECLINED));
|
||||||
|
@ -1027,6 +1027,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResourcePackOffer(ResourcePackInfo packInfo) {
|
public void sendResourcePackOffer(ResourcePackInfo packInfo) {
|
||||||
|
this.resourcePackHandler.checkAlreadyAppliedPack(packInfo.getHash());
|
||||||
if (this.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_1_8)) {
|
if (this.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_1_8)) {
|
||||||
Preconditions.checkNotNull(packInfo, "packInfo");
|
Preconditions.checkNotNull(packInfo, "packInfo");
|
||||||
this.resourcePackHandler.queueResourcePack(packInfo);
|
this.resourcePackHandler.queueResourcePack(packInfo);
|
||||||
|
@ -23,6 +23,7 @@ import com.velocitypowered.api.proxy.player.ResourcePackInfo;
|
|||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
@ -169,6 +170,12 @@ public sealed class LegacyResourcePackHandler extends ResourcePackHandler
|
|||||||
return handleResponseResult(queued, bundle);
|
return handleResponseResult(queued, bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPackAppliedByHash(final byte[] hash) {
|
||||||
|
return this.appliedResourcePack != null
|
||||||
|
&& Arrays.equals(this.appliedResourcePack.getHash(), hash);
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean shouldDisconnectForForcePack(final PlayerResourcePackStatusEvent event) {
|
protected boolean shouldDisconnectForForcePack(final PlayerResourcePackStatusEvent event) {
|
||||||
return event.getStatus() == PlayerResourcePackStatusEvent.Status.DECLINED
|
return event.getStatus() == PlayerResourcePackStatusEvent.Status.DECLINED
|
||||||
&& event.getPackInfo() != null && event.getPackInfo().getShouldForce();
|
&& event.getPackInfo() != null && event.getPackInfo().getShouldForce();
|
||||||
|
@ -23,6 +23,7 @@ import com.velocitypowered.api.event.player.PlayerResourcePackStatusEvent;
|
|||||||
import com.velocitypowered.api.proxy.player.ResourcePackInfo;
|
import com.velocitypowered.api.proxy.player.ResourcePackInfo;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -167,4 +168,17 @@ public final class ModernResourcePackHandler extends ResourcePackHandler {
|
|||||||
|
|
||||||
return handleResponseResult(queued, bundle);
|
return handleResponseResult(queued, bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPackAppliedByHash(final byte[] hash) {
|
||||||
|
if (hash == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (final Map.Entry<UUID, ResourcePackInfo> appliedPack : appliedResourcePacks.entrySet()) {
|
||||||
|
if (Arrays.equals(appliedPack.getValue().getHash(), hash)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,9 @@ public abstract sealed class ResourcePackHandler
|
|||||||
*/
|
*/
|
||||||
public void queueResourcePack(final @NotNull ResourcePackRequest request) {
|
public void queueResourcePack(final @NotNull ResourcePackRequest request) {
|
||||||
for (final net.kyori.adventure.resource.ResourcePackInfo pack : request.packs()) {
|
for (final net.kyori.adventure.resource.ResourcePackInfo pack : request.packs()) {
|
||||||
queueResourcePack(VelocityResourcePackInfo.fromAdventureRequest(request, pack));
|
final ResourcePackInfo resourcePackInfo = VelocityResourcePackInfo.fromAdventureRequest(request, pack);
|
||||||
|
this.checkAlreadyAppliedPack(resourcePackInfo.getHash());
|
||||||
|
queueResourcePack(resourcePackInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,4 +158,18 @@ public abstract sealed class ResourcePackHandler
|
|||||||
}
|
}
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a pack has already been applied.
|
||||||
|
*
|
||||||
|
* @param hash the resource pack hash
|
||||||
|
*/
|
||||||
|
public abstract boolean hasPackAppliedByHash(final byte[] hash);
|
||||||
|
|
||||||
|
@SuppressWarnings("checkstyle:MissingJavadocMethod")
|
||||||
|
public void checkAlreadyAppliedPack(final byte[] hash) {
|
||||||
|
if (this.hasPackAppliedByHash(hash)) {
|
||||||
|
throw new IllegalStateException("Cannot apply a resource pack already applied");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ pluginManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("org.gradle.toolchains.foojay-resolver-convention") version "0.4.0"
|
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
rootProject.name = "velocity"
|
rootProject.name = "velocity"
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren