Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-20 15:00:11 +01:00
Check for duplicate options, other fixes
Dieser Commit ist enthalten in:
Ursprung
a868ced1a7
Commit
250a9b43d1
@ -64,6 +64,7 @@ public abstract class SessionLoadResourcePacksEvent extends ConnectionEvent {
|
|||||||
* specific options.
|
* specific options.
|
||||||
*
|
*
|
||||||
* @param resourcePack a resource pack that will be sent to the client.
|
* @param resourcePack a resource pack that will be sent to the client.
|
||||||
|
* @param resourcePackOptions {@link ResourcePackOption}'s that specify how clients load the pack
|
||||||
* @return true if the resource pack was added successfully,
|
* @return true if the resource pack was added successfully,
|
||||||
* or false if already present
|
* or false if already present
|
||||||
*/
|
*/
|
||||||
@ -81,6 +82,7 @@ public abstract class SessionLoadResourcePacksEvent extends ConnectionEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the subpack options set for a specific resource pack uuid.
|
* Returns the subpack options set for a specific resource pack uuid.
|
||||||
|
* These are not modifiable.
|
||||||
*
|
*
|
||||||
* @param resourcePack the resourcePack for which the options are set
|
* @param resourcePack the resourcePack for which the options are set
|
||||||
* @return a list of {@link ResourcePackOption}
|
* @return a list of {@link ResourcePackOption}
|
||||||
@ -94,5 +96,4 @@ public abstract class SessionLoadResourcePacksEvent extends ConnectionEvent {
|
|||||||
* @return true whether the resource pack was removed from the list of resource packs.
|
* @return true whether the resource pack was removed from the list of resource packs.
|
||||||
*/
|
*/
|
||||||
public abstract boolean unregister(@NonNull UUID uuid);
|
public abstract boolean unregister(@NonNull UUID uuid);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,6 @@ import java.util.Collection;
|
|||||||
* <p>
|
* <p>
|
||||||
* This representation of a resource pack only contains what
|
* This representation of a resource pack only contains what
|
||||||
* Geyser requires to send it to the client.
|
* Geyser requires to send it to the client.
|
||||||
* <p>
|
|
||||||
* Optionally, a content key and/or a subpack name to load can be provided.
|
|
||||||
*/
|
*/
|
||||||
public interface ResourcePack {
|
public interface ResourcePack {
|
||||||
|
|
||||||
|
@ -43,54 +43,61 @@ import java.util.AbstractMap;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class SessionLoadResourcePacksEventImpl extends SessionLoadResourcePacksEvent {
|
public class SessionLoadResourcePacksEventImpl extends SessionLoadResourcePacksEvent {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final Map<String, ResourcePack> packs;
|
private final Map<UUID, ResourcePack> packs;
|
||||||
private final Map<String, Collection<ResourcePackOption>> options = new HashMap<>();
|
private final Map<UUID, Collection<ResourcePackOption>> options = new HashMap<>();
|
||||||
|
|
||||||
public SessionLoadResourcePacksEventImpl(GeyserSession session) {
|
public SessionLoadResourcePacksEventImpl(GeyserSession session) {
|
||||||
super(session);
|
super(session);
|
||||||
this.packs = new Object2ObjectLinkedOpenHashMap<>(Registries.RESOURCE_PACKS.get());
|
this.packs = new Object2ObjectLinkedOpenHashMap<>(Registries.RESOURCE_PACKS.get());
|
||||||
this.packs.values().forEach(
|
this.packs.values().forEach(
|
||||||
pack -> options.put(pack.manifest().header().uuid().toString(), pack.defaultOptions())
|
pack -> options.put(pack.manifest().header().uuid(), pack.defaultOptions())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LinkedList<ResourcePackStackPacket.Entry> orderedPacks() {
|
public LinkedList<ResourcePackStackPacket.Entry> orderedPacks() {
|
||||||
return packs.values().stream()
|
TreeSet<Map.Entry<ResourcePack, Integer>> sortedPacks = packs.values().stream()
|
||||||
// Map each ResourcePack to a pair of (ResourcePack, Priority)
|
// Map each ResourcePack to a pair of (ResourcePack, Priority)
|
||||||
.map(pack -> new AbstractMap.SimpleEntry<>(pack, getPriority(pack)))
|
.map(pack -> new AbstractMap.SimpleEntry<>(pack, getPriority(pack)))
|
||||||
// Sort by priority in descending order (higher priority first)
|
// Sort by priority in descending order
|
||||||
.sorted((entry1, entry2) -> Integer.compare(entry2.getValue(), entry1.getValue()))
|
.collect(Collectors.toCollection(() -> new TreeSet<>(Map.Entry.comparingByValue(Comparator.naturalOrder()))));
|
||||||
// Extract the ResourcePack from the sorted entries
|
|
||||||
|
// Convert the sorted entries to a LinkedList of ResourcePackStackPacket.Entry
|
||||||
|
return sortedPacks.stream()
|
||||||
.map(entry -> {
|
.map(entry -> {
|
||||||
ResourcePack pack = entry.getKey();
|
ResourcePackManifest.Header header = entry.getKey().manifest().header();
|
||||||
ResourcePackManifest.Header header = pack.manifest().header();
|
return new ResourcePackStackPacket.Entry(
|
||||||
return new ResourcePackStackPacket.Entry(header.uuid().toString(), header.version().toString(), getSubpackName(header.uuid()));
|
header.uuid().toString(),
|
||||||
|
header.version().toString(),
|
||||||
|
getSubpackName(header.uuid())
|
||||||
|
);
|
||||||
})
|
})
|
||||||
// Collect to a LinkedList
|
|
||||||
.collect(Collectors.toCollection(LinkedList::new));
|
.collect(Collectors.toCollection(LinkedList::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method to get the priority of a ResourcePack
|
// Helper method to get the priority of a ResourcePack
|
||||||
private int getPriority(ResourcePack pack) {
|
private int getPriority(ResourcePack pack) {
|
||||||
return options.get(pack.manifest().header().uuid().toString()).stream()
|
return options.get(pack.manifest().header().uuid()).stream()
|
||||||
// Filter to find the PriorityOption
|
|
||||||
.filter(option -> option instanceof PriorityOption)
|
.filter(option -> option instanceof PriorityOption)
|
||||||
// Map to the priority value
|
|
||||||
.mapToInt(option -> ((PriorityOption) option).priority())
|
.mapToInt(option -> ((PriorityOption) option).priority())
|
||||||
// Get the highest priority (or a default value, if none found)
|
.max()
|
||||||
.max().orElse(PriorityOption.NORMAL.priority());
|
.orElse(PriorityOption.NORMAL.priority());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<ResourcePacksInfoPacket.Entry> infoPacketEntries() {
|
public List<ResourcePacksInfoPacket.Entry> infoPacketEntries() {
|
||||||
List<ResourcePacksInfoPacket.Entry> entries = new ArrayList<>();
|
List<ResourcePacksInfoPacket.Entry> entries = new ArrayList<>();
|
||||||
|
|
||||||
@ -106,14 +113,13 @@ public class SessionLoadResourcePacksEventImpl extends SessionLoadResourcePacksE
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getSubpackName(UUID uuid) {
|
private String getSubpackName(UUID uuid) {
|
||||||
return options.get(uuid.toString()).stream()
|
return options.get(uuid).stream()
|
||||||
.filter(option -> option instanceof SubpackOption)
|
.filter(option -> option instanceof SubpackOption)
|
||||||
.map(option -> ((SubpackOption) option).subpackName())
|
.map(option -> ((SubpackOption) option).subpackName())
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(""); // Return an empty string if none is found
|
.orElse(""); // Return an empty string if none is found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull List<ResourcePack> resourcePacks() {
|
public @NonNull List<ResourcePack> resourcePacks() {
|
||||||
return List.copyOf(packs.values());
|
return List.copyOf(packs.values());
|
||||||
@ -126,16 +132,22 @@ public class SessionLoadResourcePacksEventImpl extends SessionLoadResourcePacksE
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean register(@NonNull ResourcePack resourcePack, ResourcePackOption... resourcePackOptions) {
|
public boolean register(@NonNull ResourcePack resourcePack, ResourcePackOption... resourcePackOptions) {
|
||||||
|
|
||||||
|
// Validate options, check for duplicates
|
||||||
|
Set<ResourcePackOption.Type> types = new HashSet<>();
|
||||||
for (ResourcePackOption option : resourcePackOptions) {
|
for (ResourcePackOption option : resourcePackOptions) {
|
||||||
option.validate(resourcePack);
|
option.validate(resourcePack);
|
||||||
|
if (!types.add(option.type())) {
|
||||||
|
throw new IllegalArgumentException("Duplicate resource pack option " + option + "!");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
types.clear();
|
||||||
|
|
||||||
String packID = resourcePack.manifest().header().uuid().toString();
|
UUID uuid = resourcePack.manifest().header().uuid();
|
||||||
if (packs.containsValue(resourcePack) || packs.containsKey(packID)) {
|
if (packs.containsValue(resourcePack) || packs.containsKey(uuid)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String uuid = resourcePack.manifest().header().uuid().toString();
|
|
||||||
packs.put(uuid, resourcePack);
|
packs.put(uuid, resourcePack);
|
||||||
options.put(uuid, List.of(resourcePackOptions));
|
options.put(uuid, List.of(resourcePackOptions));
|
||||||
return true;
|
return true;
|
||||||
@ -143,12 +155,12 @@ public class SessionLoadResourcePacksEventImpl extends SessionLoadResourcePacksE
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<ResourcePackOption> options(UUID uuid) {
|
public Collection<ResourcePackOption> options(UUID uuid) {
|
||||||
return Collections.unmodifiableCollection(options.get(uuid.toString()));
|
return Collections.unmodifiableCollection(options.get(uuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean unregister(@NonNull UUID uuid) {
|
public boolean unregister(@NonNull UUID uuid) {
|
||||||
options.remove(uuid.toString());
|
options.remove(uuid);
|
||||||
return packs.remove(uuid.toString()) != null;
|
return packs.remove(uuid) != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,6 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
stackPacket.setExperimentsPreviouslyToggled(false);
|
stackPacket.setExperimentsPreviouslyToggled(false);
|
||||||
stackPacket.setForcedToAccept(false); // Leaving this as false allows the player to choose to download or not
|
stackPacket.setForcedToAccept(false); // Leaving this as false allows the player to choose to download or not
|
||||||
stackPacket.setGameVersion(session.getClientData().getGameVersion());
|
stackPacket.setGameVersion(session.getClientData().getGameVersion());
|
||||||
|
|
||||||
stackPacket.getResourcePacks().addAll(this.resourcePackLoadEvent.orderedPacks());
|
stackPacket.getResourcePacks().addAll(this.resourcePackLoadEvent.orderedPacks());
|
||||||
|
|
||||||
if (GeyserImpl.getInstance().getConfig().isAddNonBedrockItems()) {
|
if (GeyserImpl.getInstance().getConfig().isAddNonBedrockItems()) {
|
||||||
|
@ -36,8 +36,10 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public record GeyserResourcePack(
|
public record GeyserResourcePack(
|
||||||
PackCodec codec,
|
PackCodec codec,
|
||||||
@ -105,6 +107,15 @@ public record GeyserResourcePack(
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GeyserResourcePack build() {
|
public GeyserResourcePack build() {
|
||||||
|
// Check for duplicates
|
||||||
|
Set<ResourcePackOption.Type> types = new HashSet<>();
|
||||||
|
for (ResourcePackOption option : defaultOptions) {
|
||||||
|
if (!types.add(option.type())) {
|
||||||
|
throw new IllegalArgumentException("Duplicate resource pack option " + option + "!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
types.clear();
|
||||||
|
|
||||||
GeyserResourcePack pack = new GeyserResourcePack(codec, manifest, contentKey, defaultOptions);
|
GeyserResourcePack pack = new GeyserResourcePack(codec, manifest, contentKey, defaultOptions);
|
||||||
defaultOptions.forEach(option -> option.validate(pack));
|
defaultOptions.forEach(option -> option.validate(pack));
|
||||||
return pack;
|
return pack;
|
||||||
|
@ -145,7 +145,7 @@ public final class Registries {
|
|||||||
/**
|
/**
|
||||||
* A mapped registry holding {@link ResourcePack}'s with the pack uuid as keys.
|
* A mapped registry holding {@link ResourcePack}'s with the pack uuid as keys.
|
||||||
*/
|
*/
|
||||||
public static final DeferredRegistry<Map<String, ResourcePack>> RESOURCE_PACKS = DeferredRegistry.create(GeyserImpl.getInstance().packDirectory(), SimpleMappedRegistry::create, RegistryLoaders.RESOURCE_PACKS);
|
public static final DeferredRegistry<Map<UUID, ResourcePack>> RESOURCE_PACKS = DeferredRegistry.create(GeyserImpl.getInstance().packDirectory(), SimpleMappedRegistry::create, RegistryLoaders.RESOURCE_PACKS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mapped registry holding sound identifiers to their corresponding {@link SoundMapping}.
|
* A mapped registry holding sound identifiers to their corresponding {@link SoundMapping}.
|
||||||
|
@ -45,6 +45,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@ -54,7 +55,7 @@ import java.util.zip.ZipFile;
|
|||||||
/**
|
/**
|
||||||
* Loads {@link ResourcePack}s within a {@link Path} directory, firing the {@link GeyserLoadResourcePacksEvent}.
|
* Loads {@link ResourcePack}s within a {@link Path} directory, firing the {@link GeyserLoadResourcePacksEvent}.
|
||||||
*/
|
*/
|
||||||
public class ResourcePackLoader implements RegistryLoader<Path, Map<String, ResourcePack>> {
|
public class ResourcePackLoader implements RegistryLoader<Path, Map<UUID, ResourcePack>> {
|
||||||
|
|
||||||
static final PathMatcher PACK_MATCHER = FileSystems.getDefault().getPathMatcher("glob:**.{zip,mcpack}");
|
static final PathMatcher PACK_MATCHER = FileSystems.getDefault().getPathMatcher("glob:**.{zip,mcpack}");
|
||||||
|
|
||||||
@ -64,8 +65,8 @@ public class ResourcePackLoader implements RegistryLoader<Path, Map<String, Reso
|
|||||||
* Loop through the packs directory and locate valid resource pack files
|
* Loop through the packs directory and locate valid resource pack files
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String, ResourcePack> load(Path directory) {
|
public Map<UUID, ResourcePack> load(Path directory) {
|
||||||
Map<String, ResourcePack> packMap = new HashMap<>();
|
Map<UUID, ResourcePack> packMap = new HashMap<>();
|
||||||
|
|
||||||
if (!Files.exists(directory)) {
|
if (!Files.exists(directory)) {
|
||||||
try {
|
try {
|
||||||
@ -100,7 +101,7 @@ public class ResourcePackLoader implements RegistryLoader<Path, Map<String, Reso
|
|||||||
for (Path path : event.resourcePacks()) {
|
for (Path path : event.resourcePacks()) {
|
||||||
try {
|
try {
|
||||||
GeyserResourcePack pack = readPack(path).build();
|
GeyserResourcePack pack = readPack(path).build();
|
||||||
packMap.put(pack.manifest().header().uuid().toString(), pack);
|
packMap.put(pack.manifest().header().uuid(), pack);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren