3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-10-03 16:31:14 +02:00

Attempt at making a proper builder for resource pack options (content key, default subpack), and a ResourcePackOption system to register packs with further options

Dieser Commit ist enthalten in:
onebeastchris 2024-08-12 20:02:57 +02:00
Ursprung 87829c9d0a
Commit 033d2d6d8c
15 geänderte Dateien mit 478 neuen und 71 gelöschten Zeilen

Datei anzeigen

@ -29,7 +29,9 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.api.connection.GeyserConnection;
import org.geysermc.geyser.api.event.connection.ConnectionEvent;
import org.geysermc.geyser.api.pack.ResourcePack;
import org.geysermc.geyser.api.pack.option.ResourcePackOption;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
@ -57,6 +59,34 @@ public abstract class SessionLoadResourcePacksEvent extends ConnectionEvent {
*/
public abstract boolean register(@NonNull ResourcePack resourcePack);
/**
* Registers a {@link ResourcePack} to be sent to the client, but alongside
* specific options.
*
* @param resourcePack a resource pack that will be sent to the client.
* @return true if the resource pack was added successfully,
* or false if already present
*/
public abstract boolean register(@NonNull ResourcePack resourcePack, ResourcePackOption... resourcePackOptions);
/**
* Returns the subpack options set for a specific resource pack.
*
* @param resourcePack the resourcePack for which the options are set
* @return a list of {@link ResourcePackOption}
*/
Collection<ResourcePackOption> options(ResourcePack resourcePack) {
return options(resourcePack.manifest().header().uuid());
}
/**
* Returns the subpack options set for a specific resource pack uuid.
*
* @param resourcePack the resourcePack for which the options are set
* @return a list of {@link ResourcePackOption}
*/
public abstract Collection<ResourcePackOption> options(UUID resourcePack);
/**
* Unregisters a resource pack from being sent to the client.
*
@ -64,4 +94,5 @@ public abstract class SessionLoadResourcePacksEvent extends ConnectionEvent {
* @return true whether the resource pack was removed from the list of resource packs.
*/
public abstract boolean unregister(@NonNull UUID uuid);
}

Datei anzeigen

@ -53,13 +53,21 @@ public abstract class PackCodec {
public abstract long size();
/**
* Serializes the given resource pack into a byte buffer.
* Use {@link #serialize()} instead.
*/
@Deprecated
@NonNull
public SeekableByteChannel serialize(@NonNull ResourcePack resourcePack) throws IOException {
return serialize();
};
/**
* Serializes the given codec into a byte buffer.
*
* @param resourcePack the resource pack to serialize
* @return the serialized resource pack
*/
@NonNull
public abstract SeekableByteChannel serialize(@NonNull ResourcePack resourcePack) throws IOException;
public abstract SeekableByteChannel serialize() throws IOException;
/**
* Creates a new resource pack from this codec.
@ -69,6 +77,13 @@ public abstract class PackCodec {
@NonNull
protected abstract ResourcePack create();
/**
* Creates a new resource pack builder from this codec.
*
* @return the new resource pack builder
*/
protected abstract ResourcePack.@NonNull Builder createBuilder();
/**
* Creates a new pack provider from the given path.
*

Datei anzeigen

@ -26,7 +26,7 @@
package org.geysermc.geyser.api.pack;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.api.GeyserApi;
/**
* Represents a resource pack sent to Bedrock clients
@ -63,23 +63,12 @@ public interface ResourcePack {
String contentKey();
/**
* Sets the content key of the resource pack. Lack of a content key can be represented by an empty string.
*/
void contentKey(@NonNull String contentKey);
/**
* The subpack to tell Bedrock clients to load. Lack of a subpack to load is represented by an empty string.
* The default subpack to tell Bedrock clients to load. Lack of a subpack to load is represented by an empty string.
*
* @return the subpack name, or an empty string if not set.
*/
@NonNull
String subpackName();
/**
* Sets the subpack name that clients should load.
* It must match one of the subpacks that can be found in the manifest.
*/
void subpackName(@Nullable String subpackName);
String defaultSubpackName();
/**
* Creates a resource pack with the given {@link PackCodec}.
@ -91,4 +80,36 @@ public interface ResourcePack {
static ResourcePack create(@NonNull PackCodec codec) {
return codec.create();
}
/**
* Returns a {@link Builder} for a resource pack.
* It can be used to set a content key, or a default subpack.
*
* @param codec the {@link PackCodec} to base the builder on
* @return a {@link Builder} to build a resource pack.
*/
static Builder builder(@NonNull PackCodec codec) {
return GeyserApi.api().provider(Builder.class, codec);
}
/**
* A builder for a resource pack. It allows providing a content key manually, or
* setting a default subpack.
*/
interface Builder {
ResourcePackManifest manifest();
PackCodec codec();
String contentKey();
String defaultSubpackName();
Builder contentKey(@NonNull String contentKey);
Builder defaultSubpackName(@NonNull String subpackName);
ResourcePack build();
}
}

Datei anzeigen

@ -0,0 +1,44 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* 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.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.api.pack.option;
import org.geysermc.geyser.api.GeyserApi;
public interface PriorityOption extends ResourcePackOption {
PriorityOption HIGH = PriorityOption.priority(10);
PriorityOption NORMAL = PriorityOption.priority(5);
PriorityOption LOW = PriorityOption.priority(0);
int priority();
static PriorityOption priority(int priority) {
if (priority < 0 || priority > 10) {
throw new IllegalArgumentException("Priority must be between 0 and 10 inclusive!");
}
return GeyserApi.api().provider(PriorityOption.class, priority);
}
}

Datei anzeigen

@ -0,0 +1,48 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* 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.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.api.pack.option;
import org.geysermc.geyser.api.pack.ResourcePack;
/**
* Represents a resource pack option that can be used to specify how a resource
* pack is sent to Bedrock clients.
*/
public interface ResourcePackOption {
Type type();
void validate(ResourcePack pack);
enum Type {
SUBPACK("subpack"),
PRIORITY("priority");
Type(String name) {
}
}
}

Datei anzeigen

@ -0,0 +1,61 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* 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.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.api.pack.option;
import org.geysermc.geyser.api.GeyserApi;
import org.geysermc.geyser.api.pack.ResourcePackManifest;
/**
* Can be used to specify which subpack from a resource pack a player should load.
* Available subpacks can be seen in a resource pack manifest {@link ResourcePackManifest#subpacks()}
*/
public interface SubpackOption extends ResourcePackOption {
/**
* Creates a subpack option based on a {@link ResourcePackManifest.Subpack}
*
* @param subpack the chosen subpack
* @return a subpack option specifying that subpack
*/
static SubpackOption subpack(ResourcePackManifest.Subpack subpack) {
return named(subpack.name());
}
/**
* Creates a subpack option based on a subpack name.
*
* @param subpackName the name of the subpack
* @return a subpack option specifying a subpack with that name
*/
static SubpackOption named(String subpackName) {
return GeyserApi.api().provider(SubpackOption.class, subpackName);
}
/**
* @return the subpack name of the chosen subpack.
*/
String subpackName();
}

Datei anzeigen

@ -25,11 +25,18 @@
package org.geysermc.geyser.event.type;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.api.event.bedrock.SessionLoadResourcePacksEvent;
import org.geysermc.geyser.api.pack.ResourcePack;
import org.geysermc.geyser.api.pack.option.PriorityOption;
import org.geysermc.geyser.api.pack.option.ResourcePackOption;
import org.geysermc.geyser.registry.Registries;
import org.geysermc.geyser.session.GeyserSession;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -37,10 +44,12 @@ import java.util.UUID;
public class SessionLoadResourcePacksEventImpl extends SessionLoadResourcePacksEvent {
private final Map<String, ResourcePack> packs;
private final Map<String, Collection<ResourcePackOption>> options;
public SessionLoadResourcePacksEventImpl(GeyserSession session, Map<String, ResourcePack> packMap) {
public SessionLoadResourcePacksEventImpl(GeyserSession session) {
super(session);
this.packs = packMap;
this.packs = new Object2ObjectLinkedOpenHashMap<>(Registries.RESOURCE_PACKS.get());
this.options = new HashMap<>();
}
public @NonNull Map<String, ResourcePack> getPacks() {
@ -54,16 +63,35 @@ public class SessionLoadResourcePacksEventImpl extends SessionLoadResourcePacksE
@Override
public boolean register(@NonNull ResourcePack resourcePack) {
return register(resourcePack, PriorityOption.NORMAL);
}
@Override
public boolean register(@NonNull ResourcePack resourcePack, ResourcePackOption... resourcePackOptions) {
for (ResourcePackOption option : resourcePackOptions) {
option.validate(resourcePack);
}
String packID = resourcePack.manifest().header().uuid().toString();
if (packs.containsValue(resourcePack) || packs.containsKey(packID)) {
return false;
}
packs.put(resourcePack.manifest().header().uuid().toString(), resourcePack);
String uuid = resourcePack.manifest().header().uuid().toString();
packs.put(uuid, resourcePack);
options.put(uuid, List.of(resourcePackOptions));
return true;
}
@Override
public Collection<ResourcePackOption> options(UUID resourcePack) {
Collection<ResourcePackOption> packOptions = options.get(resourcePack.toString());
return packOptions == null ? List.of() : Collections.unmodifiableCollection(packOptions);
}
@Override
public boolean unregister(@NonNull UUID uuid) {
options.remove(uuid.toString());
return packs.remove(uuid.toString()) != null;
}
}

Datei anzeigen

@ -75,7 +75,6 @@ import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.OptionalInt;
public class UpstreamPacketHandler extends LoggingPacketHandler {
@ -200,7 +199,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
geyser.getSessionManager().addPendingSession(session);
this.resourcePackLoadEvent = new SessionLoadResourcePacksEventImpl(session, new HashMap<>(Registries.RESOURCE_PACKS.get()));
this.resourcePackLoadEvent = new SessionLoadResourcePacksEventImpl(session);
this.geyser.eventBus().fire(this.resourcePackLoadEvent);
ResourcePacksInfoPacket resourcePacksInfo = new ResourcePacksInfoPacket();
@ -208,7 +207,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
ResourcePackManifest.Header header = pack.manifest().header();
resourcePacksInfo.getResourcePackInfos().add(new ResourcePacksInfoPacket.Entry(
header.uuid().toString(), header.version().toString(), pack.codec().size(), pack.contentKey(),
pack.subpackName(), header.uuid().toString(), false, false));
pack.defaultSubpackName(), header.uuid().toString(), false, false));
}
resourcePacksInfo.setForcedToAccept(GeyserImpl.getInstance().getConfig().isForceResourcePacks());
session.sendUpstreamPacket(resourcePacksInfo);

Datei anzeigen

@ -25,62 +25,90 @@
package org.geysermc.geyser.pack;
import lombok.RequiredArgsConstructor;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.api.pack.PackCodec;
import org.geysermc.geyser.api.pack.ResourcePack;
import org.geysermc.geyser.api.pack.ResourcePackManifest;
@RequiredArgsConstructor
public class GeyserResourcePack implements ResourcePack {
public record GeyserResourcePack(
PackCodec codec,
ResourcePackManifest manifest,
String contentKey,
String defaultSubpackName
) implements ResourcePack {
/**
* The size of each chunk to use when sending the resource packs to clients in bytes
*/
public static final int CHUNK_SIZE = 102400;
private final PackCodec codec;
private final ResourcePackManifest manifest;
private String contentKey;
private String subpackName;
public GeyserResourcePack(PackCodec codec, ResourcePackManifest manifest, String contentKey) {
this(codec, manifest);
this.contentKey = contentKey;
this(codec, manifest, contentKey, "");
}
@Override
public @NonNull PackCodec codec() {
return this.codec;
}
@Override
public @NonNull ResourcePackManifest manifest() {
return this.manifest;
}
public static class Builder implements ResourcePack.Builder {
@Override
public @NonNull String contentKey() {
return this.contentKey == null ? "" : this.contentKey;
}
public Builder(PackCodec codec, ResourcePackManifest manifest) {
this.codec = codec;
this.manifest = manifest;
}
@Override
public void contentKey(@Nullable String contentKey) {
this.contentKey = contentKey;
}
public Builder(PackCodec codec, ResourcePackManifest manifest, String contentKey) {
this.codec = codec;
this.manifest = manifest;
this.contentKey = contentKey;
}
@Override
public @NonNull String subpackName() {
return this.subpackName == null ? "" : this.subpackName;
}
private final PackCodec codec;
private final ResourcePackManifest manifest;
private String contentKey;
private String defaultSubpackName;
@Override
public void subpackName(@Nullable String subpackName) {
if (manifest.subpacks().stream().anyMatch(subpack -> subpack.name().equals(subpackName))) {
this.subpackName = subpackName;
} else {
throw new IllegalArgumentException("A subpack with the name '" + subpackName + "' does not exist!");
@Override
public ResourcePackManifest manifest() {
return manifest;
}
@Override
public PackCodec codec() {
return codec;
}
@Override
public String contentKey() {
return this.contentKey == null ? "" : this.contentKey;
}
@Override
public String defaultSubpackName() {
return this.defaultSubpackName == null ? "" : this.defaultSubpackName;
}
public Builder contentKey(@Nullable String contentKey) {
this.contentKey = contentKey;
return this;
}
public Builder defaultSubpackName(@Nullable String subpackName) {
if (manifest.subpacks().stream().anyMatch(subpack -> subpack.name().equals(subpackName))) {
this.defaultSubpackName = subpackName;
} else {
throw new IllegalArgumentException("A subpack with the name '" + subpackName + "' does not exist!");
}
return this;
}
public GeyserResourcePack build() {
if (contentKey == null) {
contentKey = "";
}
if (defaultSubpackName == null) {
defaultSubpackName = "";
}
return new GeyserResourcePack(codec, manifest, contentKey, defaultSubpackName);
}
}
}

Datei anzeigen

@ -0,0 +1,57 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* 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.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.pack.option;
import org.geysermc.geyser.api.pack.ResourcePack;
import org.geysermc.geyser.api.pack.option.PriorityOption;
public class GeyserPriorityOption implements PriorityOption {
private final int priority;
public int priority() {
return priority;
}
public GeyserPriorityOption(int priority) {
if (priority < 0 || priority > 10) {
throw new IllegalArgumentException("Priority must be between 0 and 10 inclusive!");
}
this.priority = priority;
}
@Override
public Type type() {
return Type.PRIORITY;
}
@Override
public void validate(ResourcePack pack) {
if (priority <= 10 && priority > 0) {
throw new IllegalArgumentException("Priority must be between 0 and 10 inclusive!");
}
}
}

Datei anzeigen

@ -0,0 +1,60 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* 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.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.pack.option;
import org.geysermc.geyser.api.pack.ResourcePack;
import org.geysermc.geyser.api.pack.ResourcePackManifest;
import org.geysermc.geyser.api.pack.option.SubpackOption;
/**
* Can be used to specify which subpack from a resource pack a player should load.
* Available subpacks can be seen in a resource pack manifest {@link ResourcePackManifest#subpacks()}
*/
public class GeyserSubpackOption implements SubpackOption {
private final String subpackName;
public GeyserSubpackOption(String subpackName) {
this.subpackName = subpackName;
}
@Override
public Type type() {
return Type.SUBPACK;
}
@Override
public void validate(ResourcePack pack) {
if (pack.manifest().subpacks().stream().noneMatch(subpack -> subpack.name().equals(subpackName))) {
throw new IllegalArgumentException("No subpack with the name %s found!".formatted(subpackName));
}
}
@Override
public String subpackName() {
return subpackName;
}
}

Datei anzeigen

@ -79,15 +79,20 @@ public class GeyserPathPackCodec extends PathPackCodec {
}
@Override
public @NonNull SeekableByteChannel serialize(@NonNull ResourcePack resourcePack) throws IOException {
public @NonNull SeekableByteChannel serialize() throws IOException {
return FileChannel.open(this.path);
}
@Override
protected @NonNull ResourcePack create() {
protected ResourcePack.@NonNull Builder createBuilder() {
return ResourcePackLoader.readPack(this.path);
}
@Override
protected @NonNull ResourcePack create() {
return createBuilder().build();
}
private void checkLastModified() {
try {
FileTime lastModified = Files.getLastModifiedTime(this.path);

Datei anzeigen

@ -40,10 +40,12 @@ import org.geysermc.geyser.api.item.custom.CustomItemData;
import org.geysermc.geyser.api.item.custom.CustomItemOptions;
import org.geysermc.geyser.api.item.custom.NonVanillaCustomItemData;
import org.geysermc.geyser.api.pack.PathPackCodec;
import org.geysermc.geyser.impl.camera.GeyserCameraFade;
import org.geysermc.geyser.impl.camera.GeyserCameraPosition;
import org.geysermc.geyser.api.pack.option.PriorityOption;
import org.geysermc.geyser.api.pack.option.SubpackOption;
import org.geysermc.geyser.event.GeyserEventRegistrar;
import org.geysermc.geyser.extension.command.GeyserExtensionCommand;
import org.geysermc.geyser.impl.camera.GeyserCameraFade;
import org.geysermc.geyser.impl.camera.GeyserCameraPosition;
import org.geysermc.geyser.item.GeyserCustomItemData;
import org.geysermc.geyser.item.GeyserCustomItemOptions;
import org.geysermc.geyser.item.GeyserNonVanillaCustomItemData;
@ -53,6 +55,8 @@ import org.geysermc.geyser.level.block.GeyserGeometryComponent;
import org.geysermc.geyser.level.block.GeyserJavaBlockState;
import org.geysermc.geyser.level.block.GeyserMaterialInstance;
import org.geysermc.geyser.level.block.GeyserNonVanillaCustomBlockData;
import org.geysermc.geyser.pack.option.GeyserPriorityOption;
import org.geysermc.geyser.pack.option.GeyserSubpackOption;
import org.geysermc.geyser.pack.path.GeyserPathPackCodec;
import org.geysermc.geyser.registry.provider.ProviderSupplier;
@ -66,9 +70,10 @@ public class ProviderRegistryLoader implements RegistryLoader<Map<Class<?>, Prov
@Override
public Map<Class<?>, ProviderSupplier> load(Map<Class<?>, ProviderSupplier> providers) {
// misc
// commands
providers.put(Command.Builder.class, args -> new GeyserExtensionCommand.Builder<>((Extension) args[0]));
// custom blocks
providers.put(CustomBlockComponents.Builder.class, args -> new GeyserCustomBlockComponents.Builder());
providers.put(CustomBlockData.Builder.class, args -> new GeyserCustomBlockData.Builder());
providers.put(JavaBlockState.Builder.class, args -> new GeyserJavaBlockState.Builder());
@ -76,8 +81,13 @@ public class ProviderRegistryLoader implements RegistryLoader<Map<Class<?>, Prov
providers.put(MaterialInstance.Builder.class, args -> new GeyserMaterialInstance.Builder());
providers.put(GeometryComponent.Builder.class, args -> new GeyserGeometryComponent.Builder());
// misc
providers.put(EventRegistrar.class, args -> new GeyserEventRegistrar(args[0]));
// packs
providers.put(PathPackCodec.class, args -> new GeyserPathPackCodec((Path) args[0]));
providers.put(PriorityOption.class, args -> new GeyserPriorityOption((int) args[0]));
providers.put(SubpackOption.class, args -> new GeyserSubpackOption((String) args[0]));
// items
providers.put(CustomItemData.Builder.class, args -> new GeyserCustomItemData.Builder());

Datei anzeigen

@ -99,7 +99,7 @@ public class ResourcePackLoader implements RegistryLoader<Path, Map<String, Reso
for (Path path : event.resourcePacks()) {
try {
GeyserResourcePack pack = readPack(path);
GeyserResourcePack pack = readPack(path).build();
packMap.put(pack.manifest().header().uuid().toString(), pack);
} catch (Exception e) {
e.printStackTrace();
@ -113,10 +113,10 @@ public class ResourcePackLoader implements RegistryLoader<Path, Map<String, Reso
* but suffixed by ".key", containing the content key. If such file does not exist, no content key is stored.
*
* @param path the file to read from, in ZIP format
* @return a {@link ResourcePack} representation
* @return a {@link ResourcePack.Builder} representation
* @throws IllegalArgumentException if the pack manifest was invalid or there was any processing exception
*/
public static GeyserResourcePack readPack(Path path) throws IllegalArgumentException {
public static GeyserResourcePack.Builder readPack(Path path) throws IllegalArgumentException {
if (!path.getFileName().toString().endsWith(".mcpack") && !path.getFileName().toString().endsWith(".zip")) {
throw new IllegalArgumentException("Resource pack " + path.getFileName() + " must be a .zip or .mcpack file!");
}
@ -155,7 +155,7 @@ public class ResourcePackLoader implements RegistryLoader<Path, Map<String, Reso
Path keyFile = path.resolveSibling(path.getFileName().toString() + ".key");
String contentKey = Files.exists(keyFile) ? Files.readString(keyFile, StandardCharsets.UTF_8) : "";
return new GeyserResourcePack(new GeyserPathPackCodec(path), manifest, contentKey);
return new GeyserResourcePack.Builder(new GeyserPathPackCodec(path), manifest, contentKey);
} catch (Exception e) {
throw new IllegalArgumentException(GeyserLocale.getLocaleStringLog("geyser.resource_pack.broken", path.getFileName()), e);
}

Datei anzeigen

@ -62,7 +62,7 @@ public class ResourcePackLoaderTest {
public void testPack() throws Exception {
// this mcpack only contains a folder, which the manifest is in
Path path = getResource("empty_pack.mcpack");
ResourcePack pack = ResourcePackLoader.readPack(path);
ResourcePack pack = ResourcePackLoader.readPack(path).build();
assertEquals("", pack.contentKey());
// should probably add some more tests here related to the manifest
}
@ -71,7 +71,7 @@ public class ResourcePackLoaderTest {
public void testEncryptedPack() throws Exception {
// this zip only contains a contents.json and manifest.json at the root
Path path = getResource("encrypted_pack.zip");
ResourcePack pack = ResourcePackLoader.readPack(path);
ResourcePack pack = ResourcePackLoader.readPack(path).build();
assertEquals("JAGcSXcXwcODc1YS70GzeWAUKEO172UA", pack.contentKey());
}