mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Adapt for new enchantment changes
This commit is contained in:
parent
8ad10f8a9e
commit
6c245a66e2
23 changed files with 775 additions and 338 deletions
|
@ -33,8 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.enchantment.EnchantmentComponent;
|
||||
import org.geysermc.geyser.item.type.DyeItem;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
|
@ -123,7 +123,7 @@ public class WolfEntity extends TameableEntity {
|
|||
@Override
|
||||
public void setChestplate(ItemStack stack) {
|
||||
super.setChestplate(stack);
|
||||
isCurseOfBinding = ItemUtils.getEnchantmentLevel(stack.getDataComponents(), Enchantment.JavaEnchantment.BINDING_CURSE) > 0;
|
||||
isCurseOfBinding = ItemUtils.hasEffect(session, stack.getDataComponents(), EnchantmentComponent.PREVENT_ARMOR_CHANGE); // TODO test
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,12 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.inventory;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.EnchantOptionData;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -44,13 +43,13 @@ public class GeyserEnchantOption {
|
|||
* is controlled by the server.
|
||||
* So, of course, we have to throw in some easter eggs. ;)
|
||||
*/
|
||||
private static final List<String> ENCHANT_NAMES = Arrays.asList("tougher armor", "lukeeey", "fall better",
|
||||
"explode less", "camo toy", "breathe better", "rtm five one six", "armor stab", "water walk", "you are elsa",
|
||||
"tim two zero three", "fast walk nether", "davchoo", "oof ouch owie", "enemy on fire", "spider sad", "aj ferguson", "redned",
|
||||
"more items thx", "long sword reach", "fast tool", "give me block", "less breaky break", "cube craft",
|
||||
"strong arrow", "fist arrow", "spicy arrow", "many many arrows", "geyser", "come here fish", "i like this",
|
||||
"stabby stab", "supreme mortal", "avatar i guess", "more arrows", "fly finder seventeen", "in and out",
|
||||
"xp heals tools", "dragon proxy waz here");
|
||||
private static final List<String> ENCHANT_NAMES = List.of("tougher armor", "lukeeey", "fall better",
|
||||
"explode less", "camo toy", "armor stab", "breathe better", "water walk", "rtm five one six", "oof ouch owie",
|
||||
"enemy on fire", "spider sad", "aj ferguson", "redned", "more items thx", "fast tool", "give me block",
|
||||
"less breaky break", "cube craft", "strong arrow", "fist arrow", "spicy arrow", "many many arrows", "geyser",
|
||||
"come here fish", "you are elsa", "xp heals tools", "tim two zero three", "dragon proxy waz here",
|
||||
"stabby stab", "supreme mortal", "i like this", "avatar i guess", "more arrows", "in and out",
|
||||
"fly finder seventeen", "fast walk nether", "davchoo", "onechris", "death bringer thirteen", "kastle");
|
||||
|
||||
@Getter
|
||||
private final int javaIndex;
|
||||
|
@ -62,7 +61,6 @@ public class GeyserEnchantOption {
|
|||
private boolean hasChanged;
|
||||
|
||||
private int xpCost = 0;
|
||||
private int javaEnchantIndex = -1;
|
||||
private int bedrockEnchantIndex = -1;
|
||||
private int enchantLevel = -1;
|
||||
|
||||
|
@ -74,7 +72,7 @@ public class GeyserEnchantOption {
|
|||
this.hasChanged = false;
|
||||
return new EnchantOptionData(xpCost, javaIndex + 16, EMPTY,
|
||||
enchantLevel == -1 ? EMPTY : Collections.singletonList(new EnchantData(bedrockEnchantIndex, enchantLevel)), EMPTY,
|
||||
javaEnchantIndex == -1 ? "unknown" : ENCHANT_NAMES.get(javaEnchantIndex), enchantLevel == -1 ? 0 : session.getNextItemNetId());
|
||||
bedrockEnchantIndex == -1 ? "unknown" : ENCHANT_NAMES.get(bedrockEnchantIndex), enchantLevel == -1 ? 0 : session.getNextItemNetId());
|
||||
}
|
||||
|
||||
public boolean hasChanged() {
|
||||
|
@ -88,10 +86,9 @@ public class GeyserEnchantOption {
|
|||
}
|
||||
}
|
||||
|
||||
public void setEnchantIndex(int javaEnchantIndex, int bedrockEnchantIndex) {
|
||||
if (this.javaEnchantIndex != javaEnchantIndex) {
|
||||
public void setEnchantIndex(int bedrockEnchantIndex) {
|
||||
if (this.bedrockEnchantIndex != bedrockEnchantIndex) {
|
||||
hasChanged = true;
|
||||
this.javaEnchantIndex = javaEnchantIndex;
|
||||
this.bedrockEnchantIndex = bedrockEnchantIndex;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,13 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.inventory.item;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@Getter
|
||||
public enum Enchantment {
|
||||
public enum BedrockEnchantment {
|
||||
PROTECTION,
|
||||
FIRE_PROTECTION,
|
||||
FEATHER_FALLING,
|
||||
|
@ -69,18 +67,21 @@ public enum Enchantment {
|
|||
PIERCING,
|
||||
QUICK_CHARGE,
|
||||
SOUL_SPEED,
|
||||
SWIFT_SNEAK;
|
||||
SWIFT_SNEAK,
|
||||
WIND_BURST,
|
||||
DENSITY,
|
||||
BREACH;
|
||||
|
||||
private static final Enchantment[] VALUES = values();
|
||||
private static final BedrockEnchantment[] VALUES = values();
|
||||
|
||||
private final String javaIdentifier;
|
||||
|
||||
Enchantment() {
|
||||
BedrockEnchantment() {
|
||||
this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
public static @Nullable Enchantment getByJavaIdentifier(String javaIdentifier) {
|
||||
for (Enchantment enchantment : VALUES) {
|
||||
public static @Nullable BedrockEnchantment getByJavaIdentifier(String javaIdentifier) {
|
||||
for (BedrockEnchantment enchantment : VALUES) {
|
||||
if (enchantment.javaIdentifier.equals(javaIdentifier) || enchantment.name().toLowerCase(Locale.ENGLISH).equalsIgnoreCase(javaIdentifier)) {
|
||||
return enchantment;
|
||||
}
|
||||
|
@ -88,7 +89,7 @@ public enum Enchantment {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static @Nullable Enchantment getByBedrockId(int bedrockId) {
|
||||
public static @Nullable BedrockEnchantment getByBedrockId(int bedrockId) {
|
||||
if (bedrockId >= 0 && bedrockId < VALUES.length) {
|
||||
return VALUES[bedrockId];
|
||||
}
|
||||
|
@ -141,35 +142,5 @@ public enum Enchantment {
|
|||
WIND_BURST,
|
||||
MENDING,
|
||||
VANISHING_CURSE;
|
||||
|
||||
private static final JavaEnchantment[] VALUES = JavaEnchantment.values();
|
||||
|
||||
public static JavaEnchantment of(int index) {
|
||||
return VALUES[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of all enchantment Java identifiers for use with command suggestions.
|
||||
*/
|
||||
public static final String[] ALL_JAVA_IDENTIFIERS;
|
||||
|
||||
public static @Nullable JavaEnchantment getByJavaIdentifier(String javaIdentifier) {
|
||||
if (!javaIdentifier.startsWith("minecraft:")) {
|
||||
javaIdentifier = "minecraft:" + javaIdentifier;
|
||||
}
|
||||
for (int i = 0; i < ALL_JAVA_IDENTIFIERS.length; i++) {
|
||||
if (ALL_JAVA_IDENTIFIERS[i].equalsIgnoreCase(javaIdentifier)) {
|
||||
return VALUES[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static {
|
||||
ALL_JAVA_IDENTIFIERS = new String[VALUES.length];
|
||||
for (int i = 0; i < ALL_JAVA_IDENTIFIERS.length; i++) {
|
||||
ALL_JAVA_IDENTIFIERS[i] = "minecraft:" + VALUES[i].name().toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,7 +26,6 @@
|
|||
package org.geysermc.geyser.inventory.updater;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
@ -38,10 +37,9 @@ import org.geysermc.geyser.GeyserImpl;
|
|||
import org.geysermc.geyser.inventory.AnvilContainer;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.Inventory;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment;
|
||||
import org.geysermc.geyser.inventory.item.BedrockEnchantment;
|
||||
import org.geysermc.geyser.item.enchantment.Enchantment;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.EnchantmentData;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
|
@ -307,18 +305,17 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
|
|||
*/
|
||||
private int calcMergeEnchantmentCost(GeyserSession session, GeyserItemStack input, GeyserItemStack material, boolean bedrock) {
|
||||
boolean hasCompatible = false;
|
||||
Object2IntMap<JavaEnchantment> combinedEnchantments = getEnchantments(input);
|
||||
Object2IntMap<Enchantment> combinedEnchantments = getEnchantments(session, input);
|
||||
int cost = 0;
|
||||
for (Object2IntMap.Entry<JavaEnchantment> entry : getEnchantments(material).object2IntEntrySet()) {
|
||||
JavaEnchantment enchantment = entry.getKey();
|
||||
EnchantmentData data = Registries.ENCHANTMENTS.get(enchantment);
|
||||
if (data == null) {
|
||||
GeyserImpl.getInstance().getLogger().debug("Java enchantment not in registry: " + enchantment);
|
||||
continue;
|
||||
}
|
||||
for (Object2IntMap.Entry<Enchantment> entry : getEnchantments(session, material).object2IntEntrySet()) {
|
||||
Enchantment enchantment = entry.getKey();
|
||||
|
||||
boolean canApply = isEnchantedBook(input) || data.validItems().contains(input.getJavaId());
|
||||
for (JavaEnchantment incompatible : data.incompatibleEnchantments()) {
|
||||
boolean canApply = isEnchantedBook(input) || session.getTagCache().is(enchantment.supportedItems(), input);
|
||||
var exclusiveSet = enchantment.exclusiveSet();
|
||||
if (exclusiveSet != null) {
|
||||
int[] incompatibleEnchantments = session.getTagCache().get(exclusiveSet);
|
||||
for (int i : incompatibleEnchantments) {
|
||||
Enchantment incompatible = session.getRegistryCache().enchantments().byId(i);
|
||||
if (combinedEnchantments.containsKey(incompatible)) {
|
||||
canApply = false;
|
||||
if (!bedrock) {
|
||||
|
@ -326,6 +323,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (canApply || (!bedrock && session.getGameMode() == GameMode.CREATIVE)) {
|
||||
int currentLevel = combinedEnchantments.getOrDefault(enchantment, 0);
|
||||
|
@ -334,12 +332,12 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
|
|||
newLevel++;
|
||||
}
|
||||
newLevel = Math.max(currentLevel, newLevel);
|
||||
if (newLevel > data.maxLevel()) {
|
||||
newLevel = data.maxLevel();
|
||||
if (newLevel > enchantment.maxLevel()) {
|
||||
newLevel = enchantment.maxLevel();
|
||||
}
|
||||
combinedEnchantments.put(enchantment, newLevel);
|
||||
|
||||
int rarityMultiplier = data.rarityMultiplier();
|
||||
int rarityMultiplier = enchantment.anvilCost();
|
||||
if (isEnchantedBook(material) && rarityMultiplier > 1) {
|
||||
rarityMultiplier /= 2;
|
||||
}
|
||||
|
@ -347,11 +345,11 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
|
|||
if (newLevel > currentLevel) {
|
||||
hasCompatible = true;
|
||||
}
|
||||
if (enchantment == JavaEnchantment.IMPALING) {
|
||||
if (enchantment.bedrockEnchantment() == BedrockEnchantment.IMPALING) {
|
||||
// Multiplier is halved on Bedrock for some reason
|
||||
rarityMultiplier /= 2;
|
||||
} else if (enchantment == JavaEnchantment.SWEEPING_EDGE) {
|
||||
// Doesn't exist on Bedrock
|
||||
} else if (enchantment.bedrockEnchantment() == null) {
|
||||
// Whatever this is, doesn't exist on Bedrock
|
||||
rarityMultiplier = 0;
|
||||
}
|
||||
cost += rarityMultiplier * (newLevel - currentLevel);
|
||||
|
@ -368,7 +366,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
|
|||
return cost;
|
||||
}
|
||||
|
||||
private Object2IntMap<JavaEnchantment> getEnchantments(GeyserItemStack itemStack) {
|
||||
private Object2IntMap<Enchantment> getEnchantments(GeyserSession session, GeyserItemStack itemStack) {
|
||||
ItemEnchantments enchantmentComponent;
|
||||
if (isEnchantedBook(itemStack)) {
|
||||
enchantmentComponent = itemStack.getComponent(DataComponentType.STORED_ENCHANTMENTS);
|
||||
|
@ -376,9 +374,9 @@ public class AnvilInventoryUpdater extends InventoryUpdater {
|
|||
enchantmentComponent = itemStack.getComponent(DataComponentType.ENCHANTMENTS);
|
||||
}
|
||||
if (enchantmentComponent != null) {
|
||||
Object2IntMap<JavaEnchantment> enchantments = new Object2IntOpenHashMap<>();
|
||||
Object2IntMap<Enchantment> enchantments = new Object2IntOpenHashMap<>();
|
||||
for (Map.Entry<Integer, Integer> entry : enchantmentComponent.getEnchantments().entrySet()) {
|
||||
JavaEnchantment enchantment = JavaEnchantment.of(entry.getKey());
|
||||
Enchantment enchantment = session.getRegistryCache().enchantments().byId(entry.getKey());
|
||||
if (enchantment == null) {
|
||||
GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment in anvil: " + entry.getKey());
|
||||
continue;
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* 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.item.enchantment;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.item.BedrockEnchantment;
|
||||
import org.geysermc.geyser.session.cache.tags.EnchantmentTag;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @param description only populated if {@link #bedrockEnchantment()} is not null.
|
||||
* @param anvilCost also as a rarity multiplier
|
||||
*/
|
||||
public record Enchantment(String identifier,
|
||||
Set<EnchantmentComponent> effects,
|
||||
ItemTag supportedItems,
|
||||
int maxLevel,
|
||||
String description,
|
||||
int anvilCost,
|
||||
@Nullable EnchantmentTag exclusiveSet,
|
||||
@Nullable BedrockEnchantment bedrockEnchantment) {
|
||||
|
||||
// Implementation note: I have a feeling the tags can be a list of items, because in vanilla they're HolderSet classes.
|
||||
// I'm not sure how that's wired over the network, so we'll put it off.
|
||||
public static Enchantment read(RegistryEntry entry) {
|
||||
NbtMap data = entry.getData();
|
||||
Set<EnchantmentComponent> effects = readEnchantmentComponents(data.getCompound("effects"));
|
||||
String supportedItems = data.getString("supported_items").substring(1); // Remove '#' at beginning that indicates tag
|
||||
int maxLevel = data.getInt("max_level");
|
||||
int anvilCost = data.getInt("anvil_cost");
|
||||
String exclusiveSet = data.getString("exclusive_set", null);
|
||||
EnchantmentTag exclusiveSetTag = exclusiveSet == null ? null : EnchantmentTag.ALL_ENCHANTMENT_TAGS.get(exclusiveSet.substring(1));
|
||||
BedrockEnchantment bedrockEnchantment = BedrockEnchantment.getByJavaIdentifier(entry.getId());
|
||||
String description = bedrockEnchantment == null ? readDescription(data) : null;
|
||||
|
||||
return new Enchantment(entry.getId(), effects, ItemTag.ALL_ITEM_TAGS.get(supportedItems), maxLevel,
|
||||
description, anvilCost, exclusiveSetTag, bedrockEnchantment);
|
||||
}
|
||||
|
||||
private static Set<EnchantmentComponent> readEnchantmentComponents(NbtMap effects) {
|
||||
if (effects.isEmpty()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<EnchantmentComponent> components = new HashSet<>();
|
||||
for (Map.Entry<String, Object> entry : effects.entrySet()) {
|
||||
switch (entry.getKey()) {
|
||||
case "minecraft:prevent_armor_change" -> components.add(EnchantmentComponent.PREVENT_ARMOR_CHANGE);
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
private static String readDescription(NbtMap tag) {
|
||||
NbtMap description = tag.getCompound("description");
|
||||
String translate = description.getString("translate", null);
|
||||
if (translate == null) {
|
||||
GeyserImpl.getInstance().getLogger().debug("Don't know how to read description! " + tag);
|
||||
return "";
|
||||
}
|
||||
return translate;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.item.enchantment;
|
||||
|
||||
public class EnchantmentComponent {
|
||||
/**
|
||||
* Singleton with no additional data
|
||||
*/
|
||||
public static final EnchantmentComponent PREVENT_ARMOR_CHANGE = new EnchantmentComponent();
|
||||
}
|
|
@ -31,7 +31,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.inventory.item.BedrockEnchantment;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
|
@ -78,11 +78,11 @@ public class EnchantedBookItem extends Item {
|
|||
for (NbtMap bedrockEnchantment : enchantmentTag) {
|
||||
short bedrockId = bedrockEnchantment.getShort("id");
|
||||
|
||||
Enchantment enchantment = Enchantment.getByBedrockId(bedrockId);
|
||||
BedrockEnchantment enchantment = BedrockEnchantment.getByBedrockId(bedrockId);
|
||||
if (enchantment != null) {
|
||||
int level = bedrockEnchantment.getShort("lvl", (short) 1);
|
||||
// TODO
|
||||
javaEnchantments.put(Enchantment.JavaEnchantment.valueOf(enchantment.name()).ordinal(), level);
|
||||
//javaEnchantments.put(BedrockEnchantment.JavaEnchantment.valueOf(enchantment.name()).ordinal(), level);
|
||||
} else {
|
||||
GeyserImpl.getInstance().getLogger().debug("Unknown bedrock enchantment: " + bedrockId);
|
||||
}
|
||||
|
|
|
@ -33,8 +33,9 @@ import org.cloudburstmc.nbt.NbtType;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.inventory.item.BedrockEnchantment;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.enchantment.Enchantment;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
|
@ -201,7 +202,7 @@ public class Item {
|
|||
// ShortTag bedrockId = tagValue.get("id");
|
||||
// if (bedrockId == null) continue;
|
||||
//
|
||||
// Enchantment enchantment = Enchantment.getByBedrockId(bedrockId.getValue());
|
||||
// BedrockEnchantment enchantment = BedrockEnchantment.getByBedrockId(bedrockId.getValue());
|
||||
// if (enchantment != null) {
|
||||
// CompoundTag javaTag = new CompoundTag("");
|
||||
// Map<String, Tag> javaValue = javaTag.getValue();
|
||||
|
@ -226,33 +227,22 @@ public class Item {
|
|||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a map from Java-only enchantments to their translation keys so that we can
|
||||
* map these enchantments to Bedrock clients, since they don't actually exist there.
|
||||
*/
|
||||
private static final Map<Enchantment.JavaEnchantment, String> ENCHANTMENT_TRANSLATION_KEYS = Map.of(
|
||||
Enchantment.JavaEnchantment.SWEEPING_EDGE, "enchantment.minecraft.sweeping",
|
||||
Enchantment.JavaEnchantment.DENSITY, "enchantment.minecraft.density",
|
||||
Enchantment.JavaEnchantment.BREACH, "enchantment.minecraft.breach",
|
||||
Enchantment.JavaEnchantment.WIND_BURST, "enchantment.minecraft.wind_burst");
|
||||
|
||||
protected final @Nullable NbtMap remapEnchantment(GeyserSession session, int enchantId, int level, BedrockItemBuilder builder) {
|
||||
// TODO verify
|
||||
// TODO streamline Enchantment process
|
||||
Enchantment.JavaEnchantment enchantment = Enchantment.JavaEnchantment.of(enchantId);
|
||||
String translationKey = ENCHANTMENT_TRANSLATION_KEYS.get(enchantment);
|
||||
if (translationKey != null) {
|
||||
String enchantmentTranslation = MinecraftLocale.getLocaleString(translationKey, session.locale());
|
||||
addJavaOnlyEnchantment(session, builder, enchantmentTranslation, level);
|
||||
return null;
|
||||
}
|
||||
Enchantment enchantment = session.getRegistryCache().enchantments().byId(enchantId);
|
||||
if (enchantment == null) {
|
||||
GeyserImpl.getInstance().getLogger().debug("Unknown Java enchantment while NBT item translating: " + enchantId);
|
||||
return null;
|
||||
}
|
||||
|
||||
BedrockEnchantment bedrockEnchantment = enchantment.bedrockEnchantment();
|
||||
if (bedrockEnchantment == null) {
|
||||
String enchantmentTranslation = MinecraftLocale.getLocaleString(enchantment.description(), session.locale());
|
||||
addJavaOnlyEnchantment(session, builder, enchantmentTranslation, level);
|
||||
return null;
|
||||
}
|
||||
|
||||
return NbtMap.builder()
|
||||
.putShort("id", (short) Enchantment.valueOf(enchantment.name()).ordinal())
|
||||
.putShort("id", (short) bedrockEnchantment.ordinal())
|
||||
.putShort("lvl", (short) level)
|
||||
.build();
|
||||
}
|
||||
|
@ -260,7 +250,7 @@ public class Item {
|
|||
private void addJavaOnlyEnchantment(GeyserSession session, BedrockItemBuilder builder, String enchantmentName, int level) {
|
||||
String lvlTranslation = MinecraftLocale.getLocaleString("enchantment.level." + level, session.locale());
|
||||
|
||||
builder.getOrCreateLore().add(ChatColor.RESET + ChatColor.GRAY + enchantmentName + " " + lvlTranslation);
|
||||
builder.getOrCreateLore().add(0, ChatColor.RESET + ChatColor.GRAY + enchantmentName + " " + lvlTranslation);
|
||||
}
|
||||
|
||||
/* Translation methods end */
|
||||
|
|
|
@ -25,12 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.registry;
|
||||
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
|
@ -43,7 +37,6 @@ import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
|||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.pack.ResourcePack;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment;
|
||||
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.loader.*;
|
||||
|
@ -51,7 +44,6 @@ import org.geysermc.geyser.registry.populator.ItemRegistryPopulator;
|
|||
import org.geysermc.geyser.registry.populator.PacketRegistryPopulator;
|
||||
import org.geysermc.geyser.registry.populator.RecipeRegistryPopulator;
|
||||
import org.geysermc.geyser.registry.provider.ProviderSupplier;
|
||||
import org.geysermc.geyser.registry.type.EnchantmentData;
|
||||
import org.geysermc.geyser.registry.type.ItemMappings;
|
||||
import org.geysermc.geyser.registry.type.ParticleMapping;
|
||||
import org.geysermc.geyser.registry.type.SoundMapping;
|
||||
|
@ -59,6 +51,12 @@ import org.geysermc.geyser.translator.level.block.entity.BlockEntityTranslator;
|
|||
import org.geysermc.geyser.translator.level.event.LevelEventTranslator;
|
||||
import org.geysermc.geyser.translator.sound.SoundInteractionTranslator;
|
||||
import org.geysermc.geyser.translator.sound.SoundTranslator;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.block.BlockEntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -102,11 +100,6 @@ public final class Registries {
|
|||
*/
|
||||
public static final VersionedRegistry<Map<RecipeType, List<RecipeData>>> CRAFTING_DATA = VersionedRegistry.create(RegistryLoaders.empty(Int2ObjectOpenHashMap::new));
|
||||
|
||||
/**
|
||||
* A registry holding data of all the known enchantments.
|
||||
*/
|
||||
public static final SimpleMappedRegistry<JavaEnchantment, EnchantmentData> ENCHANTMENTS;
|
||||
|
||||
/**
|
||||
* A map containing all entity types and their respective Geyser definitions
|
||||
*/
|
||||
|
@ -127,7 +120,10 @@ public final class Registries {
|
|||
*/
|
||||
public static final PacketTranslatorRegistry<Packet> JAVA_PACKET_TRANSLATORS = PacketTranslatorRegistry.create();
|
||||
|
||||
public static final SimpleRegistry<List<Item>> JAVA_ITEMS = SimpleRegistry.create(RegistryLoaders.empty(ArrayList::new));
|
||||
/**
|
||||
* A registry containing all Java items ordered by their network ID.
|
||||
*/
|
||||
public static final ListRegistry<Item> JAVA_ITEMS = ListRegistry.create(RegistryLoaders.empty(ArrayList::new));
|
||||
|
||||
public static final SimpleMappedRegistry<String, Item> JAVA_ITEM_IDENTIFIERS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new));
|
||||
|
||||
|
@ -190,7 +186,6 @@ public final class Registries {
|
|||
|
||||
// Create registries that require other registries to load first
|
||||
POTION_MIXES = VersionedRegistry.create(PotionMixRegistryLoader::new);
|
||||
ENCHANTMENTS = SimpleMappedRegistry.create("mappings/enchantments.json", EnchantmentRegistryLoader::new);
|
||||
|
||||
// Remove unneeded client generation data from NbtMapBuilder
|
||||
NbtMapBuilder biomesNbt = NbtMap.builder();
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2022 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.registry.loader;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.EnchantmentData;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class EnchantmentRegistryLoader implements RegistryLoader<String, Map<JavaEnchantment, EnchantmentData>> {
|
||||
@Override
|
||||
public Map<JavaEnchantment, EnchantmentData> load(String input) {
|
||||
JsonNode enchantmentsNode;
|
||||
try (InputStream enchantmentsStream = GeyserImpl.getInstance().getBootstrap().getResourceOrThrow(input)) {
|
||||
enchantmentsNode = GeyserImpl.JSON_MAPPER.readTree(enchantmentsStream);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Unable to load enchantment data", e);
|
||||
}
|
||||
|
||||
Map<JavaEnchantment, EnchantmentData> enchantments = new EnumMap<>(JavaEnchantment.class);
|
||||
Iterator<Map.Entry<String, JsonNode>> it = enchantmentsNode.fields();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<String, JsonNode> entry = it.next();
|
||||
JavaEnchantment key = JavaEnchantment.getByJavaIdentifier(entry.getKey());
|
||||
JsonNode node = entry.getValue();
|
||||
int rarityMultiplier = node.get("anvil_cost").asInt();
|
||||
int maxLevel = node.get("max_level").asInt();
|
||||
|
||||
EnumSet<JavaEnchantment> incompatibleEnchantments = EnumSet.noneOf(JavaEnchantment.class);
|
||||
JsonNode incompatibleEnchantmentsNode = node.get("incompatible_enchantments");
|
||||
if (incompatibleEnchantmentsNode != null) {
|
||||
for (JsonNode incompatibleNode : incompatibleEnchantmentsNode) {
|
||||
incompatibleEnchantments.add(JavaEnchantment.getByJavaIdentifier(incompatibleNode.textValue()));
|
||||
}
|
||||
}
|
||||
|
||||
IntSet validItems = new IntOpenHashSet();
|
||||
for (JsonNode itemNode : node.get("valid_items")) {
|
||||
String javaIdentifier = itemNode.textValue();
|
||||
Item item = Registries.JAVA_ITEM_IDENTIFIERS.get(javaIdentifier);
|
||||
if (item != null) {
|
||||
validItems.add(item.javaId());
|
||||
} else {
|
||||
throw new NullPointerException("No item entry exists for java identifier: " + javaIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
EnchantmentData enchantmentData = new EnchantmentData(rarityMultiplier, maxLevel, incompatibleEnchantments, validItems);
|
||||
enchantments.put(key, enchantmentData);
|
||||
}
|
||||
return enchantments;
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@
|
|||
package org.geysermc.geyser.registry.type;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment.JavaEnchantment;
|
||||
import org.geysermc.geyser.inventory.item.BedrockEnchantment.JavaEnchantment;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
|
|
@ -1307,7 +1307,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||
*/
|
||||
public void useItem(Hand hand) {
|
||||
sendDownstreamGamePacket(new ServerboundUseItemPacket(
|
||||
hand, worldCache.nextPredictionSequence(), playerEntity.getPitch(), playerEntity.getYaw()));
|
||||
hand, worldCache.nextPredictionSequence(), playerEntity.getYaw(), playerEntity.getPitch()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -38,7 +38,7 @@ import org.geysermc.geyser.GeyserImpl;
|
|||
import org.geysermc.geyser.entity.type.living.animal.tameable.WolfEntity;
|
||||
import org.geysermc.geyser.inventory.item.BannerPattern;
|
||||
import org.geysermc.geyser.inventory.recipe.TrimRecipe;
|
||||
import org.geysermc.geyser.item.Enchantment;
|
||||
import org.geysermc.geyser.item.enchantment.Enchantment;
|
||||
import org.geysermc.geyser.level.JavaDimension;
|
||||
import org.geysermc.geyser.level.PaintingType;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
|
|
@ -25,47 +25,40 @@
|
|||
|
||||
package org.geysermc.geyser.session.cache;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrays;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.GeyserLogger;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.BlockTag;
|
||||
import org.geysermc.geyser.session.cache.tags.EnchantmentTag;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.Ordered;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.geysermc.geyser.session.cache.tags.BlockTag.ALL_BLOCK_TAGS;
|
||||
import static org.geysermc.geyser.session.cache.tags.EnchantmentTag.ALL_ENCHANTMENT_TAGS;
|
||||
import static org.geysermc.geyser.session.cache.tags.ItemTag.ALL_ITEM_TAGS;
|
||||
|
||||
/**
|
||||
* Manages information sent from the {@link ClientboundUpdateTagsPacket}. If that packet is not sent, all lists here
|
||||
* will remain empty, matching Java Edition behavior.
|
||||
*
|
||||
* This system is designed for easy extensibility - just add an enum to {@link BlockTag} or {@link ItemTag}.
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
public final class TagCache {
|
||||
// Put these here so the enums can load without a static map
|
||||
public static final Map<String, BlockTag> ALL_BLOCK_TAGS = new HashMap<>();
|
||||
public static final Map<String, ItemTag> ALL_ITEM_TAGS = new HashMap<>();
|
||||
|
||||
private final Map<BlockTag, IntList> blocks = new EnumMap<>(BlockTag.class);
|
||||
private final Map<ItemTag, IntList> items = new EnumMap<>(ItemTag.class);
|
||||
private final int[][] blocks = new int[ALL_BLOCK_TAGS.size()][];
|
||||
private final int[][] items = new int[ALL_ITEM_TAGS.size()][];
|
||||
private final int[][] enchantments = new int[ALL_ENCHANTMENT_TAGS.size()][];
|
||||
|
||||
public void loadPacket(GeyserSession session, ClientboundUpdateTagsPacket packet) {
|
||||
Map<String, int[]> blockTags = packet.getTags().get("minecraft:block");
|
||||
this.blocks.clear();
|
||||
ALL_BLOCK_TAGS.forEach((location, tag) -> {
|
||||
int[] values = blockTags.get(location);
|
||||
if (values != null) {
|
||||
this.blocks.put(tag, IntList.of(values));
|
||||
} else {
|
||||
session.getGeyser().getLogger().debug("Block tag not found from server: " + location);
|
||||
}
|
||||
});
|
||||
loadTags("Block", blockTags, ALL_BLOCK_TAGS, this.blocks);
|
||||
|
||||
// Hack btw
|
||||
GeyserLogger logger = session.getGeyser().getLogger();
|
||||
|
@ -77,15 +70,7 @@ public final class TagCache {
|
|||
}
|
||||
|
||||
Map<String, int[]> itemTags = packet.getTags().get("minecraft:item");
|
||||
this.items.clear();
|
||||
ALL_ITEM_TAGS.forEach((location, tag) -> {
|
||||
int[] values = itemTags.get(location);
|
||||
if (values != null) {
|
||||
this.items.put(tag, IntList.of(values));
|
||||
} else {
|
||||
session.getGeyser().getLogger().debug("Item tag not found from server: " + location);
|
||||
}
|
||||
});
|
||||
loadTags("Item", itemTags, ALL_ITEM_TAGS, this.items);
|
||||
|
||||
// Hack btw
|
||||
boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1;
|
||||
|
@ -93,17 +78,31 @@ public final class TagCache {
|
|||
if (logger.isDebug()) {
|
||||
logger.debug("Emulating post 1.13 villager logic for " + session.bedrockUsername() + "? " + emulatePost1_13Logic);
|
||||
}
|
||||
|
||||
Map<String, int[]> enchantmentTags = packet.getTags().get("minecraft:enchantment");
|
||||
loadTags("Enchantment", enchantmentTags, ALL_ENCHANTMENT_TAGS, this.enchantments);
|
||||
}
|
||||
|
||||
private <T extends Ordered> void loadTags(String type, Map<String, int[]> packetTags, Map<String, T> allTags, int[][] localValues) {
|
||||
Arrays.fill(localValues, IntArrays.EMPTY_ARRAY);
|
||||
allTags.forEach((location, tag) -> {
|
||||
int[] values = packetTags.get(location);
|
||||
if (values != null) {
|
||||
if (values.length != 0) {
|
||||
localValues[tag.ordinal()] = values;
|
||||
}
|
||||
} else {
|
||||
GeyserImpl.getInstance().getLogger().debug(type + " tag not found from server: " + location);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the block tag is present and contains this block mapping's Java ID.
|
||||
*/
|
||||
public boolean is(BlockTag tag, Block block) {
|
||||
IntList values = this.blocks.get(tag);
|
||||
if (values != null) {
|
||||
return values.contains(block.javaId());
|
||||
}
|
||||
return false;
|
||||
int[] values = this.blocks[tag.ordinal()];
|
||||
return contains(values, block.javaId());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,9 +116,19 @@ public final class TagCache {
|
|||
* @return true if the item tag is present and contains this item's Java ID.
|
||||
*/
|
||||
public boolean is(ItemTag tag, Item item) {
|
||||
IntList values = this.items.get(tag);
|
||||
if (values != null) {
|
||||
return values.contains(item.javaId());
|
||||
int[] values = this.items[tag.ordinal()];
|
||||
return contains(values, item.javaId());
|
||||
}
|
||||
|
||||
public int[] get(EnchantmentTag tag) {
|
||||
return this.enchantments[tag.ordinal()];
|
||||
}
|
||||
|
||||
private static boolean contains(int[] array, int i) {
|
||||
for (int item : array) {
|
||||
if (item == i) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -25,24 +25,212 @@
|
|||
|
||||
package org.geysermc.geyser.session.cache.tags;
|
||||
|
||||
import org.geysermc.geyser.session.cache.TagCache;
|
||||
import org.geysermc.geyser.util.Ordered;
|
||||
|
||||
public enum BlockTag {
|
||||
LEAVES("leaves"),
|
||||
WOOL("wool"),
|
||||
AXE_EFFECTIVE("mineable/axe"),
|
||||
HOE_EFFECTIVE("mineable/hoe"),
|
||||
PICKAXE_EFFECTIVE("mineable/pickaxe"),
|
||||
SHOVEL_EFFECTIVE("mineable/shovel"),
|
||||
NEEDS_STONE_TOOL("needs_stone_tool"),
|
||||
NEEDS_IRON_TOOL("needs_iron_tool"),
|
||||
NEEDS_DIAMOND_TOOL("needs_diamond_tool");
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
BlockTag(String identifier) {
|
||||
@SuppressWarnings("unused")
|
||||
public final class BlockTag implements Ordered {
|
||||
public static final Map<String, BlockTag> ALL_BLOCK_TAGS = new HashMap<>();
|
||||
|
||||
public static final BlockTag WOOL = new BlockTag("wool");
|
||||
public static final BlockTag PLANKS = new BlockTag("planks");
|
||||
public static final BlockTag STONE_BRICKS = new BlockTag("stone_bricks");
|
||||
public static final BlockTag WOODEN_BUTTONS = new BlockTag("wooden_buttons");
|
||||
public static final BlockTag STONE_BUTTONS = new BlockTag("stone_buttons");
|
||||
public static final BlockTag BUTTONS = new BlockTag("buttons");
|
||||
public static final BlockTag WOOL_CARPETS = new BlockTag("wool_carpets");
|
||||
public static final BlockTag WOODEN_DOORS = new BlockTag("wooden_doors");
|
||||
public static final BlockTag WOODEN_STAIRS = new BlockTag("wooden_stairs");
|
||||
public static final BlockTag WOODEN_SLABS = new BlockTag("wooden_slabs");
|
||||
public static final BlockTag WOODEN_FENCES = new BlockTag("wooden_fences");
|
||||
public static final BlockTag PRESSURE_PLATES = new BlockTag("pressure_plates");
|
||||
public static final BlockTag WOODEN_PRESSURE_PLATES = new BlockTag("wooden_pressure_plates");
|
||||
public static final BlockTag STONE_PRESSURE_PLATES = new BlockTag("stone_pressure_plates");
|
||||
public static final BlockTag WOODEN_TRAPDOORS = new BlockTag("wooden_trapdoors");
|
||||
public static final BlockTag DOORS = new BlockTag("doors");
|
||||
public static final BlockTag SAPLINGS = new BlockTag("saplings");
|
||||
public static final BlockTag LOGS_THAT_BURN = new BlockTag("logs_that_burn");
|
||||
public static final BlockTag OVERWORLD_NATURAL_LOGS = new BlockTag("overworld_natural_logs");
|
||||
public static final BlockTag LOGS = new BlockTag("logs");
|
||||
public static final BlockTag DARK_OAK_LOGS = new BlockTag("dark_oak_logs");
|
||||
public static final BlockTag OAK_LOGS = new BlockTag("oak_logs");
|
||||
public static final BlockTag BIRCH_LOGS = new BlockTag("birch_logs");
|
||||
public static final BlockTag ACACIA_LOGS = new BlockTag("acacia_logs");
|
||||
public static final BlockTag CHERRY_LOGS = new BlockTag("cherry_logs");
|
||||
public static final BlockTag JUNGLE_LOGS = new BlockTag("jungle_logs");
|
||||
public static final BlockTag SPRUCE_LOGS = new BlockTag("spruce_logs");
|
||||
public static final BlockTag MANGROVE_LOGS = new BlockTag("mangrove_logs");
|
||||
public static final BlockTag CRIMSON_STEMS = new BlockTag("crimson_stems");
|
||||
public static final BlockTag WARPED_STEMS = new BlockTag("warped_stems");
|
||||
public static final BlockTag BAMBOO_BLOCKS = new BlockTag("bamboo_blocks");
|
||||
public static final BlockTag WART_BLOCKS = new BlockTag("wart_blocks");
|
||||
public static final BlockTag BANNERS = new BlockTag("banners");
|
||||
public static final BlockTag SAND = new BlockTag("sand");
|
||||
public static final BlockTag SMELTS_TO_GLASS = new BlockTag("smelts_to_glass");
|
||||
public static final BlockTag STAIRS = new BlockTag("stairs");
|
||||
public static final BlockTag SLABS = new BlockTag("slabs");
|
||||
public static final BlockTag WALLS = new BlockTag("walls");
|
||||
public static final BlockTag ANVIL = new BlockTag("anvil");
|
||||
public static final BlockTag RAILS = new BlockTag("rails");
|
||||
public static final BlockTag LEAVES = new BlockTag("leaves");
|
||||
public static final BlockTag TRAPDOORS = new BlockTag("trapdoors");
|
||||
public static final BlockTag SMALL_FLOWERS = new BlockTag("small_flowers");
|
||||
public static final BlockTag BEDS = new BlockTag("beds");
|
||||
public static final BlockTag FENCES = new BlockTag("fences");
|
||||
public static final BlockTag TALL_FLOWERS = new BlockTag("tall_flowers");
|
||||
public static final BlockTag FLOWERS = new BlockTag("flowers");
|
||||
public static final BlockTag PIGLIN_REPELLENTS = new BlockTag("piglin_repellents");
|
||||
public static final BlockTag GOLD_ORES = new BlockTag("gold_ores");
|
||||
public static final BlockTag IRON_ORES = new BlockTag("iron_ores");
|
||||
public static final BlockTag DIAMOND_ORES = new BlockTag("diamond_ores");
|
||||
public static final BlockTag REDSTONE_ORES = new BlockTag("redstone_ores");
|
||||
public static final BlockTag LAPIS_ORES = new BlockTag("lapis_ores");
|
||||
public static final BlockTag COAL_ORES = new BlockTag("coal_ores");
|
||||
public static final BlockTag EMERALD_ORES = new BlockTag("emerald_ores");
|
||||
public static final BlockTag COPPER_ORES = new BlockTag("copper_ores");
|
||||
public static final BlockTag CANDLES = new BlockTag("candles");
|
||||
public static final BlockTag DIRT = new BlockTag("dirt");
|
||||
public static final BlockTag TERRACOTTA = new BlockTag("terracotta");
|
||||
public static final BlockTag BADLANDS_TERRACOTTA = new BlockTag("badlands_terracotta");
|
||||
public static final BlockTag CONCRETE_POWDER = new BlockTag("concrete_powder");
|
||||
public static final BlockTag COMPLETES_FIND_TREE_TUTORIAL = new BlockTag("completes_find_tree_tutorial");
|
||||
public static final BlockTag FLOWER_POTS = new BlockTag("flower_pots");
|
||||
public static final BlockTag ENDERMAN_HOLDABLE = new BlockTag("enderman_holdable");
|
||||
public static final BlockTag ICE = new BlockTag("ice");
|
||||
public static final BlockTag VALID_SPAWN = new BlockTag("valid_spawn");
|
||||
public static final BlockTag IMPERMEABLE = new BlockTag("impermeable");
|
||||
public static final BlockTag UNDERWATER_BONEMEALS = new BlockTag("underwater_bonemeals");
|
||||
public static final BlockTag CORAL_BLOCKS = new BlockTag("coral_blocks");
|
||||
public static final BlockTag WALL_CORALS = new BlockTag("wall_corals");
|
||||
public static final BlockTag CORAL_PLANTS = new BlockTag("coral_plants");
|
||||
public static final BlockTag CORALS = new BlockTag("corals");
|
||||
public static final BlockTag BAMBOO_PLANTABLE_ON = new BlockTag("bamboo_plantable_on");
|
||||
public static final BlockTag STANDING_SIGNS = new BlockTag("standing_signs");
|
||||
public static final BlockTag WALL_SIGNS = new BlockTag("wall_signs");
|
||||
public static final BlockTag SIGNS = new BlockTag("signs");
|
||||
public static final BlockTag CEILING_HANGING_SIGNS = new BlockTag("ceiling_hanging_signs");
|
||||
public static final BlockTag WALL_HANGING_SIGNS = new BlockTag("wall_hanging_signs");
|
||||
public static final BlockTag ALL_HANGING_SIGNS = new BlockTag("all_hanging_signs");
|
||||
public static final BlockTag ALL_SIGNS = new BlockTag("all_signs");
|
||||
public static final BlockTag DRAGON_IMMUNE = new BlockTag("dragon_immune");
|
||||
public static final BlockTag DRAGON_TRANSPARENT = new BlockTag("dragon_transparent");
|
||||
public static final BlockTag WITHER_IMMUNE = new BlockTag("wither_immune");
|
||||
public static final BlockTag WITHER_SUMMON_BASE_BLOCKS = new BlockTag("wither_summon_base_blocks");
|
||||
public static final BlockTag BEEHIVES = new BlockTag("beehives");
|
||||
public static final BlockTag CROPS = new BlockTag("crops");
|
||||
public static final BlockTag BEE_GROWABLES = new BlockTag("bee_growables");
|
||||
public static final BlockTag PORTALS = new BlockTag("portals");
|
||||
public static final BlockTag FIRE = new BlockTag("fire");
|
||||
public static final BlockTag NYLIUM = new BlockTag("nylium");
|
||||
public static final BlockTag BEACON_BASE_BLOCKS = new BlockTag("beacon_base_blocks");
|
||||
public static final BlockTag SOUL_SPEED_BLOCKS = new BlockTag("soul_speed_blocks");
|
||||
public static final BlockTag WALL_POST_OVERRIDE = new BlockTag("wall_post_override");
|
||||
public static final BlockTag CLIMBABLE = new BlockTag("climbable");
|
||||
public static final BlockTag FALL_DAMAGE_RESETTING = new BlockTag("fall_damage_resetting");
|
||||
public static final BlockTag SHULKER_BOXES = new BlockTag("shulker_boxes");
|
||||
public static final BlockTag HOGLIN_REPELLENTS = new BlockTag("hoglin_repellents");
|
||||
public static final BlockTag SOUL_FIRE_BASE_BLOCKS = new BlockTag("soul_fire_base_blocks");
|
||||
public static final BlockTag STRIDER_WARM_BLOCKS = new BlockTag("strider_warm_blocks");
|
||||
public static final BlockTag CAMPFIRES = new BlockTag("campfires");
|
||||
public static final BlockTag GUARDED_BY_PIGLINS = new BlockTag("guarded_by_piglins");
|
||||
public static final BlockTag PREVENT_MOB_SPAWNING_INSIDE = new BlockTag("prevent_mob_spawning_inside");
|
||||
public static final BlockTag FENCE_GATES = new BlockTag("fence_gates");
|
||||
public static final BlockTag UNSTABLE_BOTTOM_CENTER = new BlockTag("unstable_bottom_center");
|
||||
public static final BlockTag MUSHROOM_GROW_BLOCK = new BlockTag("mushroom_grow_block");
|
||||
public static final BlockTag INFINIBURN_OVERWORLD = new BlockTag("infiniburn_overworld");
|
||||
public static final BlockTag INFINIBURN_NETHER = new BlockTag("infiniburn_nether");
|
||||
public static final BlockTag INFINIBURN_END = new BlockTag("infiniburn_end");
|
||||
public static final BlockTag BASE_STONE_OVERWORLD = new BlockTag("base_stone_overworld");
|
||||
public static final BlockTag STONE_ORE_REPLACEABLES = new BlockTag("stone_ore_replaceables");
|
||||
public static final BlockTag DEEPSLATE_ORE_REPLACEABLES = new BlockTag("deepslate_ore_replaceables");
|
||||
public static final BlockTag BASE_STONE_NETHER = new BlockTag("base_stone_nether");
|
||||
public static final BlockTag OVERWORLD_CARVER_REPLACEABLES = new BlockTag("overworld_carver_replaceables");
|
||||
public static final BlockTag NETHER_CARVER_REPLACEABLES = new BlockTag("nether_carver_replaceables");
|
||||
public static final BlockTag CANDLE_CAKES = new BlockTag("candle_cakes");
|
||||
public static final BlockTag CAULDRONS = new BlockTag("cauldrons");
|
||||
public static final BlockTag CRYSTAL_SOUND_BLOCKS = new BlockTag("crystal_sound_blocks");
|
||||
public static final BlockTag INSIDE_STEP_SOUND_BLOCKS = new BlockTag("inside_step_sound_blocks");
|
||||
public static final BlockTag COMBINATION_STEP_SOUND_BLOCKS = new BlockTag("combination_step_sound_blocks");
|
||||
public static final BlockTag CAMEL_SAND_STEP_SOUND_BLOCKS = new BlockTag("camel_sand_step_sound_blocks");
|
||||
public static final BlockTag OCCLUDES_VIBRATION_SIGNALS = new BlockTag("occludes_vibration_signals");
|
||||
public static final BlockTag DAMPENS_VIBRATIONS = new BlockTag("dampens_vibrations");
|
||||
public static final BlockTag DRIPSTONE_REPLACEABLE_BLOCKS = new BlockTag("dripstone_replaceable_blocks");
|
||||
public static final BlockTag CAVE_VINES = new BlockTag("cave_vines");
|
||||
public static final BlockTag MOSS_REPLACEABLE = new BlockTag("moss_replaceable");
|
||||
public static final BlockTag LUSH_GROUND_REPLACEABLE = new BlockTag("lush_ground_replaceable");
|
||||
public static final BlockTag AZALEA_ROOT_REPLACEABLE = new BlockTag("azalea_root_replaceable");
|
||||
public static final BlockTag SMALL_DRIPLEAF_PLACEABLE = new BlockTag("small_dripleaf_placeable");
|
||||
public static final BlockTag BIG_DRIPLEAF_PLACEABLE = new BlockTag("big_dripleaf_placeable");
|
||||
public static final BlockTag SNOW = new BlockTag("snow");
|
||||
public static final BlockTag MINEABLE_AXE = new BlockTag("mineable/axe");
|
||||
public static final BlockTag MINEABLE_HOE = new BlockTag("mineable/hoe");
|
||||
public static final BlockTag MINEABLE_PICKAXE = new BlockTag("mineable/pickaxe");
|
||||
public static final BlockTag MINEABLE_SHOVEL = new BlockTag("mineable/shovel");
|
||||
public static final BlockTag SWORD_EFFICIENT = new BlockTag("sword_efficient");
|
||||
public static final BlockTag NEEDS_DIAMOND_TOOL = new BlockTag("needs_diamond_tool");
|
||||
public static final BlockTag NEEDS_IRON_TOOL = new BlockTag("needs_iron_tool");
|
||||
public static final BlockTag NEEDS_STONE_TOOL = new BlockTag("needs_stone_tool");
|
||||
public static final BlockTag INCORRECT_FOR_NETHERITE_TOOL = new BlockTag("incorrect_for_netherite_tool");
|
||||
public static final BlockTag INCORRECT_FOR_DIAMOND_TOOL = new BlockTag("incorrect_for_diamond_tool");
|
||||
public static final BlockTag INCORRECT_FOR_IRON_TOOL = new BlockTag("incorrect_for_iron_tool");
|
||||
public static final BlockTag INCORRECT_FOR_STONE_TOOL = new BlockTag("incorrect_for_stone_tool");
|
||||
public static final BlockTag INCORRECT_FOR_GOLD_TOOL = new BlockTag("incorrect_for_gold_tool");
|
||||
public static final BlockTag INCORRECT_FOR_WOODEN_TOOL = new BlockTag("incorrect_for_wooden_tool");
|
||||
public static final BlockTag FEATURES_CANNOT_REPLACE = new BlockTag("features_cannot_replace");
|
||||
public static final BlockTag LAVA_POOL_STONE_CANNOT_REPLACE = new BlockTag("lava_pool_stone_cannot_replace");
|
||||
public static final BlockTag GEODE_INVALID_BLOCKS = new BlockTag("geode_invalid_blocks");
|
||||
public static final BlockTag FROG_PREFER_JUMP_TO = new BlockTag("frog_prefer_jump_to");
|
||||
public static final BlockTag SCULK_REPLACEABLE = new BlockTag("sculk_replaceable");
|
||||
public static final BlockTag SCULK_REPLACEABLE_WORLD_GEN = new BlockTag("sculk_replaceable_world_gen");
|
||||
public static final BlockTag ANCIENT_CITY_REPLACEABLE = new BlockTag("ancient_city_replaceable");
|
||||
public static final BlockTag VIBRATION_RESONATORS = new BlockTag("vibration_resonators");
|
||||
public static final BlockTag ANIMALS_SPAWNABLE_ON = new BlockTag("animals_spawnable_on");
|
||||
public static final BlockTag ARMADILLO_SPAWNABLE_ON = new BlockTag("armadillo_spawnable_on");
|
||||
public static final BlockTag AXOLOTLS_SPAWNABLE_ON = new BlockTag("axolotls_spawnable_on");
|
||||
public static final BlockTag GOATS_SPAWNABLE_ON = new BlockTag("goats_spawnable_on");
|
||||
public static final BlockTag MOOSHROOMS_SPAWNABLE_ON = new BlockTag("mooshrooms_spawnable_on");
|
||||
public static final BlockTag PARROTS_SPAWNABLE_ON = new BlockTag("parrots_spawnable_on");
|
||||
public static final BlockTag POLAR_BEARS_SPAWNABLE_ON_ALTERNATE = new BlockTag("polar_bears_spawnable_on_alternate");
|
||||
public static final BlockTag RABBITS_SPAWNABLE_ON = new BlockTag("rabbits_spawnable_on");
|
||||
public static final BlockTag FOXES_SPAWNABLE_ON = new BlockTag("foxes_spawnable_on");
|
||||
public static final BlockTag WOLVES_SPAWNABLE_ON = new BlockTag("wolves_spawnable_on");
|
||||
public static final BlockTag FROGS_SPAWNABLE_ON = new BlockTag("frogs_spawnable_on");
|
||||
public static final BlockTag AZALEA_GROWS_ON = new BlockTag("azalea_grows_on");
|
||||
public static final BlockTag CONVERTABLE_TO_MUD = new BlockTag("convertable_to_mud");
|
||||
public static final BlockTag MANGROVE_LOGS_CAN_GROW_THROUGH = new BlockTag("mangrove_logs_can_grow_through");
|
||||
public static final BlockTag MANGROVE_ROOTS_CAN_GROW_THROUGH = new BlockTag("mangrove_roots_can_grow_through");
|
||||
public static final BlockTag DEAD_BUSH_MAY_PLACE_ON = new BlockTag("dead_bush_may_place_on");
|
||||
public static final BlockTag SNAPS_GOAT_HORN = new BlockTag("snaps_goat_horn");
|
||||
public static final BlockTag REPLACEABLE_BY_TREES = new BlockTag("replaceable_by_trees");
|
||||
public static final BlockTag SNOW_LAYER_CANNOT_SURVIVE_ON = new BlockTag("snow_layer_cannot_survive_on");
|
||||
public static final BlockTag SNOW_LAYER_CAN_SURVIVE_ON = new BlockTag("snow_layer_can_survive_on");
|
||||
public static final BlockTag INVALID_SPAWN_INSIDE = new BlockTag("invalid_spawn_inside");
|
||||
public static final BlockTag SNIFFER_DIGGABLE_BLOCK = new BlockTag("sniffer_diggable_block");
|
||||
public static final BlockTag SNIFFER_EGG_HATCH_BOOST = new BlockTag("sniffer_egg_hatch_boost");
|
||||
public static final BlockTag TRAIL_RUINS_REPLACEABLE = new BlockTag("trail_ruins_replaceable");
|
||||
public static final BlockTag REPLACEABLE = new BlockTag("replaceable");
|
||||
public static final BlockTag ENCHANTMENT_POWER_PROVIDER = new BlockTag("enchantment_power_provider");
|
||||
public static final BlockTag ENCHANTMENT_POWER_TRANSMITTER = new BlockTag("enchantment_power_transmitter");
|
||||
public static final BlockTag MAINTAINS_FARMLAND = new BlockTag("maintains_farmland");
|
||||
public static final BlockTag BLOCKS_WIND_CHARGE_EXPLOSIONS = new BlockTag("blocks_wind_charge_explosions");
|
||||
public static final BlockTag DOES_NOT_BLOCK_HOPPERS = new BlockTag("does_not_block_hoppers");
|
||||
public static final BlockTag AIR = new BlockTag("air");
|
||||
|
||||
private final int id;
|
||||
|
||||
private BlockTag(String identifier) {
|
||||
this.id = ALL_BLOCK_TAGS.size();
|
||||
register(identifier, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return id;
|
||||
}
|
||||
|
||||
private static void register(String name, BlockTag tag) {
|
||||
TagCache.ALL_BLOCK_TAGS.put("minecraft:" + name, tag);
|
||||
ALL_BLOCK_TAGS.put(("minecraft:" + name).intern(), tag);
|
||||
}
|
||||
}
|
||||
|
|
89
core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java
vendored
Normal file
89
core/src/main/java/org/geysermc/geyser/session/cache/tags/EnchantmentTag.java
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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.session.cache.tags;
|
||||
|
||||
import org.geysermc.geyser.util.Ordered;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class EnchantmentTag implements Ordered {
|
||||
public static final Map<String, EnchantmentTag> ALL_ENCHANTMENT_TAGS = new HashMap<>();
|
||||
|
||||
public static final EnchantmentTag TOOLTIP_ORDER = new EnchantmentTag("tooltip_order");
|
||||
public static final EnchantmentTag EXCLUSIVE_SET_ARMOR = new EnchantmentTag("exclusive_set/armor");
|
||||
public static final EnchantmentTag EXCLUSIVE_SET_BOOTS = new EnchantmentTag("exclusive_set/boots");
|
||||
public static final EnchantmentTag EXCLUSIVE_SET_BOW = new EnchantmentTag("exclusive_set/bow");
|
||||
public static final EnchantmentTag EXCLUSIVE_SET_CROSSBOW = new EnchantmentTag("exclusive_set/crossbow");
|
||||
public static final EnchantmentTag EXCLUSIVE_SET_DAMAGE = new EnchantmentTag("exclusive_set/damage");
|
||||
public static final EnchantmentTag EXCLUSIVE_SET_MINING = new EnchantmentTag("exclusive_set/mining");
|
||||
public static final EnchantmentTag EXCLUSIVE_SET_RIPTIDE = new EnchantmentTag("exclusive_set/riptide");
|
||||
public static final EnchantmentTag TRADEABLE = new EnchantmentTag("tradeable");
|
||||
public static final EnchantmentTag DOUBLE_TRADE_PRICE = new EnchantmentTag("double_trade_price");
|
||||
public static final EnchantmentTag IN_ENCHANTING_TABLE = new EnchantmentTag("in_enchanting_table");
|
||||
public static final EnchantmentTag ON_MOB_SPAWN_EQUIPMENT = new EnchantmentTag("on_mob_spawn_equipment");
|
||||
public static final EnchantmentTag ON_TRADED_EQUIPMENT = new EnchantmentTag("on_traded_equipment");
|
||||
public static final EnchantmentTag ON_RANDOM_LOOT = new EnchantmentTag("on_random_loot");
|
||||
public static final EnchantmentTag CURSE = new EnchantmentTag("curse");
|
||||
public static final EnchantmentTag SMELTS_LOOT = new EnchantmentTag("smelts_loot");
|
||||
public static final EnchantmentTag PREVENTS_BEE_SPAWNS_WHEN_MINING = new EnchantmentTag("prevents_bee_spawns_when_mining");
|
||||
public static final EnchantmentTag PREVENTS_DECORATED_POT_SHATTERING = new EnchantmentTag("prevents_decorated_pot_shattering");
|
||||
public static final EnchantmentTag PREVENTS_ICE_MELTING = new EnchantmentTag("prevents_ice_melting");
|
||||
public static final EnchantmentTag PREVENTS_INFESTED_SPAWNS = new EnchantmentTag("prevents_infested_spawns");
|
||||
public static final EnchantmentTag TREASURE = new EnchantmentTag("treasure");
|
||||
public static final EnchantmentTag NON_TREASURE = new EnchantmentTag("non_treasure");
|
||||
public static final EnchantmentTag TRADES_DESERT_COMMON = new EnchantmentTag("trades/desert_common");
|
||||
public static final EnchantmentTag TRADES_JUNGLE_COMMON = new EnchantmentTag("trades/jungle_common");
|
||||
public static final EnchantmentTag TRADES_PLAINS_COMMON = new EnchantmentTag("trades/plains_common");
|
||||
public static final EnchantmentTag TRADES_SAVANNA_COMMON = new EnchantmentTag("trades/savanna_common");
|
||||
public static final EnchantmentTag TRADES_SNOW_COMMON = new EnchantmentTag("trades/snow_common");
|
||||
public static final EnchantmentTag TRADES_SWAMP_COMMON = new EnchantmentTag("trades/swamp_common");
|
||||
public static final EnchantmentTag TRADES_TAIGA_COMMON = new EnchantmentTag("trades/taiga_common");
|
||||
public static final EnchantmentTag TRADES_DESERT_SPECIAL = new EnchantmentTag("trades/desert_special");
|
||||
public static final EnchantmentTag TRADES_JUNGLE_SPECIAL = new EnchantmentTag("trades/jungle_special");
|
||||
public static final EnchantmentTag TRADES_PLAINS_SPECIAL = new EnchantmentTag("trades/plains_special");
|
||||
public static final EnchantmentTag TRADES_SAVANNA_SPECIAL = new EnchantmentTag("trades/savanna_special");
|
||||
public static final EnchantmentTag TRADES_SNOW_SPECIAL = new EnchantmentTag("trades/snow_special");
|
||||
public static final EnchantmentTag TRADES_SWAMP_SPECIAL = new EnchantmentTag("trades/swamp_special");
|
||||
public static final EnchantmentTag TRADES_TAIGA_SPECIAL = new EnchantmentTag("trades/taiga_special");
|
||||
|
||||
private final int id;
|
||||
|
||||
private EnchantmentTag(String identifier) {
|
||||
this.id = ALL_ENCHANTMENT_TAGS.size();
|
||||
register(identifier, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return id;
|
||||
}
|
||||
|
||||
private static void register(String name, EnchantmentTag tag) {
|
||||
ALL_ENCHANTMENT_TAGS.put(("minecraft:" + name).intern(), tag);
|
||||
}
|
||||
}
|
|
@ -25,44 +25,176 @@
|
|||
|
||||
package org.geysermc.geyser.session.cache.tags;
|
||||
|
||||
import org.geysermc.geyser.session.cache.TagCache;
|
||||
import org.geysermc.geyser.util.Ordered;
|
||||
|
||||
public enum ItemTag {
|
||||
AXOLOTL_FOOD("axolotl_food"),
|
||||
CREEPER_IGNITERS("creeper_igniters"),
|
||||
FISHES("fishes"),
|
||||
FOX_FOOD("fox_food"),
|
||||
PIGLIN_LOVED("piglin_loved"),
|
||||
SMALL_FLOWERS("small_flowers"),
|
||||
SNIFFER_FOOD("sniffer_food"),
|
||||
PIGLIN_FOOD("piglin_food"),
|
||||
COW_FOOD("cow_food"),
|
||||
GOAT_FOOD("goat_food"),
|
||||
SHEEP_FOOD("sheep_food"),
|
||||
WOLF_FOOD("wolf_food"),
|
||||
CAT_FOOD("cat_food"),
|
||||
HORSE_FOOD("horse_food"),
|
||||
CAMEL_FOOD("camel_food"),
|
||||
ARMADILLO_FOOD("armadillo_food"),
|
||||
BEE_FOOD("bee_food"),
|
||||
CHICKEN_FOOD("chicken_food"),
|
||||
FROG_FOOD("frog_food"),
|
||||
HOGLIN_FOOD("hoglin_food"),
|
||||
LLAMA_FOOD("llama_food"),
|
||||
OCELOT_FOOD("ocelot_food"),
|
||||
PANDA_FOOD("panda_food"),
|
||||
PIG_FOOD("pig_food"),
|
||||
RABBIT_FOOD("rabbit_food"),
|
||||
STRIDER_FOOD("strider_food"),
|
||||
TURTLE_FOOD("turtle_food"),
|
||||
PARROT_FOOD("parrot_food"),
|
||||
PARROT_POISONOUS_FOOD("parrot_poisonous_food");
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
ItemTag(String identifier) {
|
||||
@SuppressWarnings("unused")
|
||||
public final class ItemTag implements Ordered {
|
||||
public static final Map<String, ItemTag> ALL_ITEM_TAGS = new HashMap<>();
|
||||
|
||||
public static final ItemTag WOOL = new ItemTag("wool");
|
||||
public static final ItemTag PLANKS = new ItemTag("planks");
|
||||
public static final ItemTag STONE_BRICKS = new ItemTag("stone_bricks");
|
||||
public static final ItemTag WOODEN_BUTTONS = new ItemTag("wooden_buttons");
|
||||
public static final ItemTag STONE_BUTTONS = new ItemTag("stone_buttons");
|
||||
public static final ItemTag BUTTONS = new ItemTag("buttons");
|
||||
public static final ItemTag WOOL_CARPETS = new ItemTag("wool_carpets");
|
||||
public static final ItemTag WOODEN_DOORS = new ItemTag("wooden_doors");
|
||||
public static final ItemTag WOODEN_STAIRS = new ItemTag("wooden_stairs");
|
||||
public static final ItemTag WOODEN_SLABS = new ItemTag("wooden_slabs");
|
||||
public static final ItemTag WOODEN_FENCES = new ItemTag("wooden_fences");
|
||||
public static final ItemTag FENCE_GATES = new ItemTag("fence_gates");
|
||||
public static final ItemTag WOODEN_PRESSURE_PLATES = new ItemTag("wooden_pressure_plates");
|
||||
public static final ItemTag WOODEN_TRAPDOORS = new ItemTag("wooden_trapdoors");
|
||||
public static final ItemTag DOORS = new ItemTag("doors");
|
||||
public static final ItemTag SAPLINGS = new ItemTag("saplings");
|
||||
public static final ItemTag LOGS_THAT_BURN = new ItemTag("logs_that_burn");
|
||||
public static final ItemTag LOGS = new ItemTag("logs");
|
||||
public static final ItemTag DARK_OAK_LOGS = new ItemTag("dark_oak_logs");
|
||||
public static final ItemTag OAK_LOGS = new ItemTag("oak_logs");
|
||||
public static final ItemTag BIRCH_LOGS = new ItemTag("birch_logs");
|
||||
public static final ItemTag ACACIA_LOGS = new ItemTag("acacia_logs");
|
||||
public static final ItemTag CHERRY_LOGS = new ItemTag("cherry_logs");
|
||||
public static final ItemTag JUNGLE_LOGS = new ItemTag("jungle_logs");
|
||||
public static final ItemTag SPRUCE_LOGS = new ItemTag("spruce_logs");
|
||||
public static final ItemTag MANGROVE_LOGS = new ItemTag("mangrove_logs");
|
||||
public static final ItemTag CRIMSON_STEMS = new ItemTag("crimson_stems");
|
||||
public static final ItemTag WARPED_STEMS = new ItemTag("warped_stems");
|
||||
public static final ItemTag BAMBOO_BLOCKS = new ItemTag("bamboo_blocks");
|
||||
public static final ItemTag WART_BLOCKS = new ItemTag("wart_blocks");
|
||||
public static final ItemTag BANNERS = new ItemTag("banners");
|
||||
public static final ItemTag SAND = new ItemTag("sand");
|
||||
public static final ItemTag SMELTS_TO_GLASS = new ItemTag("smelts_to_glass");
|
||||
public static final ItemTag STAIRS = new ItemTag("stairs");
|
||||
public static final ItemTag SLABS = new ItemTag("slabs");
|
||||
public static final ItemTag WALLS = new ItemTag("walls");
|
||||
public static final ItemTag ANVIL = new ItemTag("anvil");
|
||||
public static final ItemTag RAILS = new ItemTag("rails");
|
||||
public static final ItemTag LEAVES = new ItemTag("leaves");
|
||||
public static final ItemTag TRAPDOORS = new ItemTag("trapdoors");
|
||||
public static final ItemTag SMALL_FLOWERS = new ItemTag("small_flowers");
|
||||
public static final ItemTag BEDS = new ItemTag("beds");
|
||||
public static final ItemTag FENCES = new ItemTag("fences");
|
||||
public static final ItemTag TALL_FLOWERS = new ItemTag("tall_flowers");
|
||||
public static final ItemTag FLOWERS = new ItemTag("flowers");
|
||||
public static final ItemTag PIGLIN_REPELLENTS = new ItemTag("piglin_repellents");
|
||||
public static final ItemTag PIGLIN_LOVED = new ItemTag("piglin_loved");
|
||||
public static final ItemTag IGNORED_BY_PIGLIN_BABIES = new ItemTag("ignored_by_piglin_babies");
|
||||
public static final ItemTag MEAT = new ItemTag("meat");
|
||||
public static final ItemTag SNIFFER_FOOD = new ItemTag("sniffer_food");
|
||||
public static final ItemTag PIGLIN_FOOD = new ItemTag("piglin_food");
|
||||
public static final ItemTag FOX_FOOD = new ItemTag("fox_food");
|
||||
public static final ItemTag COW_FOOD = new ItemTag("cow_food");
|
||||
public static final ItemTag GOAT_FOOD = new ItemTag("goat_food");
|
||||
public static final ItemTag SHEEP_FOOD = new ItemTag("sheep_food");
|
||||
public static final ItemTag WOLF_FOOD = new ItemTag("wolf_food");
|
||||
public static final ItemTag CAT_FOOD = new ItemTag("cat_food");
|
||||
public static final ItemTag HORSE_FOOD = new ItemTag("horse_food");
|
||||
public static final ItemTag HORSE_TEMPT_ITEMS = new ItemTag("horse_tempt_items");
|
||||
public static final ItemTag CAMEL_FOOD = new ItemTag("camel_food");
|
||||
public static final ItemTag ARMADILLO_FOOD = new ItemTag("armadillo_food");
|
||||
public static final ItemTag BEE_FOOD = new ItemTag("bee_food");
|
||||
public static final ItemTag CHICKEN_FOOD = new ItemTag("chicken_food");
|
||||
public static final ItemTag FROG_FOOD = new ItemTag("frog_food");
|
||||
public static final ItemTag HOGLIN_FOOD = new ItemTag("hoglin_food");
|
||||
public static final ItemTag LLAMA_FOOD = new ItemTag("llama_food");
|
||||
public static final ItemTag LLAMA_TEMPT_ITEMS = new ItemTag("llama_tempt_items");
|
||||
public static final ItemTag OCELOT_FOOD = new ItemTag("ocelot_food");
|
||||
public static final ItemTag PANDA_FOOD = new ItemTag("panda_food");
|
||||
public static final ItemTag PIG_FOOD = new ItemTag("pig_food");
|
||||
public static final ItemTag RABBIT_FOOD = new ItemTag("rabbit_food");
|
||||
public static final ItemTag STRIDER_FOOD = new ItemTag("strider_food");
|
||||
public static final ItemTag STRIDER_TEMPT_ITEMS = new ItemTag("strider_tempt_items");
|
||||
public static final ItemTag TURTLE_FOOD = new ItemTag("turtle_food");
|
||||
public static final ItemTag PARROT_FOOD = new ItemTag("parrot_food");
|
||||
public static final ItemTag PARROT_POISONOUS_FOOD = new ItemTag("parrot_poisonous_food");
|
||||
public static final ItemTag AXOLOTL_FOOD = new ItemTag("axolotl_food");
|
||||
public static final ItemTag GOLD_ORES = new ItemTag("gold_ores");
|
||||
public static final ItemTag IRON_ORES = new ItemTag("iron_ores");
|
||||
public static final ItemTag DIAMOND_ORES = new ItemTag("diamond_ores");
|
||||
public static final ItemTag REDSTONE_ORES = new ItemTag("redstone_ores");
|
||||
public static final ItemTag LAPIS_ORES = new ItemTag("lapis_ores");
|
||||
public static final ItemTag COAL_ORES = new ItemTag("coal_ores");
|
||||
public static final ItemTag EMERALD_ORES = new ItemTag("emerald_ores");
|
||||
public static final ItemTag COPPER_ORES = new ItemTag("copper_ores");
|
||||
public static final ItemTag NON_FLAMMABLE_WOOD = new ItemTag("non_flammable_wood");
|
||||
public static final ItemTag SOUL_FIRE_BASE_BLOCKS = new ItemTag("soul_fire_base_blocks");
|
||||
public static final ItemTag CANDLES = new ItemTag("candles");
|
||||
public static final ItemTag DIRT = new ItemTag("dirt");
|
||||
public static final ItemTag TERRACOTTA = new ItemTag("terracotta");
|
||||
public static final ItemTag COMPLETES_FIND_TREE_TUTORIAL = new ItemTag("completes_find_tree_tutorial");
|
||||
public static final ItemTag BOATS = new ItemTag("boats");
|
||||
public static final ItemTag CHEST_BOATS = new ItemTag("chest_boats");
|
||||
public static final ItemTag FISHES = new ItemTag("fishes");
|
||||
public static final ItemTag SIGNS = new ItemTag("signs");
|
||||
public static final ItemTag CREEPER_DROP_MUSIC_DISCS = new ItemTag("creeper_drop_music_discs");
|
||||
public static final ItemTag COALS = new ItemTag("coals");
|
||||
public static final ItemTag ARROWS = new ItemTag("arrows");
|
||||
public static final ItemTag LECTERN_BOOKS = new ItemTag("lectern_books");
|
||||
public static final ItemTag BOOKSHELF_BOOKS = new ItemTag("bookshelf_books");
|
||||
public static final ItemTag BEACON_PAYMENT_ITEMS = new ItemTag("beacon_payment_items");
|
||||
public static final ItemTag STONE_TOOL_MATERIALS = new ItemTag("stone_tool_materials");
|
||||
public static final ItemTag STONE_CRAFTING_MATERIALS = new ItemTag("stone_crafting_materials");
|
||||
public static final ItemTag FREEZE_IMMUNE_WEARABLES = new ItemTag("freeze_immune_wearables");
|
||||
public static final ItemTag DAMPENS_VIBRATIONS = new ItemTag("dampens_vibrations");
|
||||
public static final ItemTag CLUSTER_MAX_HARVESTABLES = new ItemTag("cluster_max_harvestables");
|
||||
public static final ItemTag COMPASSES = new ItemTag("compasses");
|
||||
public static final ItemTag HANGING_SIGNS = new ItemTag("hanging_signs");
|
||||
public static final ItemTag CREEPER_IGNITERS = new ItemTag("creeper_igniters");
|
||||
public static final ItemTag NOTEBLOCK_TOP_INSTRUMENTS = new ItemTag("noteblock_top_instruments");
|
||||
public static final ItemTag FOOT_ARMOR = new ItemTag("foot_armor");
|
||||
public static final ItemTag LEG_ARMOR = new ItemTag("leg_armor");
|
||||
public static final ItemTag CHEST_ARMOR = new ItemTag("chest_armor");
|
||||
public static final ItemTag HEAD_ARMOR = new ItemTag("head_armor");
|
||||
public static final ItemTag SKULLS = new ItemTag("skulls");
|
||||
public static final ItemTag TRIMMABLE_ARMOR = new ItemTag("trimmable_armor");
|
||||
public static final ItemTag TRIM_MATERIALS = new ItemTag("trim_materials");
|
||||
public static final ItemTag TRIM_TEMPLATES = new ItemTag("trim_templates");
|
||||
public static final ItemTag DECORATED_POT_SHERDS = new ItemTag("decorated_pot_sherds");
|
||||
public static final ItemTag DECORATED_POT_INGREDIENTS = new ItemTag("decorated_pot_ingredients");
|
||||
public static final ItemTag SWORDS = new ItemTag("swords");
|
||||
public static final ItemTag AXES = new ItemTag("axes");
|
||||
public static final ItemTag HOES = new ItemTag("hoes");
|
||||
public static final ItemTag PICKAXES = new ItemTag("pickaxes");
|
||||
public static final ItemTag SHOVELS = new ItemTag("shovels");
|
||||
public static final ItemTag BREAKS_DECORATED_POTS = new ItemTag("breaks_decorated_pots");
|
||||
public static final ItemTag VILLAGER_PLANTABLE_SEEDS = new ItemTag("villager_plantable_seeds");
|
||||
public static final ItemTag DYEABLE = new ItemTag("dyeable");
|
||||
public static final ItemTag ENCHANTABLE_FOOT_ARMOR = new ItemTag("enchantable/foot_armor");
|
||||
public static final ItemTag ENCHANTABLE_LEG_ARMOR = new ItemTag("enchantable/leg_armor");
|
||||
public static final ItemTag ENCHANTABLE_CHEST_ARMOR = new ItemTag("enchantable/chest_armor");
|
||||
public static final ItemTag ENCHANTABLE_HEAD_ARMOR = new ItemTag("enchantable/head_armor");
|
||||
public static final ItemTag ENCHANTABLE_ARMOR = new ItemTag("enchantable/armor");
|
||||
public static final ItemTag ENCHANTABLE_SWORD = new ItemTag("enchantable/sword");
|
||||
public static final ItemTag ENCHANTABLE_FIRE_ASPECT = new ItemTag("enchantable/fire_aspect");
|
||||
public static final ItemTag ENCHANTABLE_SHARP_WEAPON = new ItemTag("enchantable/sharp_weapon");
|
||||
public static final ItemTag ENCHANTABLE_WEAPON = new ItemTag("enchantable/weapon");
|
||||
public static final ItemTag ENCHANTABLE_MINING = new ItemTag("enchantable/mining");
|
||||
public static final ItemTag ENCHANTABLE_MINING_LOOT = new ItemTag("enchantable/mining_loot");
|
||||
public static final ItemTag ENCHANTABLE_FISHING = new ItemTag("enchantable/fishing");
|
||||
public static final ItemTag ENCHANTABLE_TRIDENT = new ItemTag("enchantable/trident");
|
||||
public static final ItemTag ENCHANTABLE_DURABILITY = new ItemTag("enchantable/durability");
|
||||
public static final ItemTag ENCHANTABLE_BOW = new ItemTag("enchantable/bow");
|
||||
public static final ItemTag ENCHANTABLE_EQUIPPABLE = new ItemTag("enchantable/equippable");
|
||||
public static final ItemTag ENCHANTABLE_CROSSBOW = new ItemTag("enchantable/crossbow");
|
||||
public static final ItemTag ENCHANTABLE_VANISHING = new ItemTag("enchantable/vanishing");
|
||||
public static final ItemTag ENCHANTABLE_MACE = new ItemTag("enchantable/mace");
|
||||
|
||||
private final int id;
|
||||
|
||||
private ItemTag(String identifier) {
|
||||
this.id = ALL_ITEM_TAGS.size();
|
||||
register(identifier, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int ordinal() {
|
||||
return id;
|
||||
}
|
||||
|
||||
private static void register(String name, ItemTag tag) {
|
||||
TagCache.ALL_ITEM_TAGS.put("minecraft:" + name, tag);
|
||||
ALL_ITEM_TAGS.put(("minecraft:" + name).intern(), tag);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,15 +36,14 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.request.action
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.itemstack.response.ItemStackResponse;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerEnchantOptionsPacket;
|
||||
import org.geysermc.geyser.inventory.*;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
||||
import org.geysermc.geyser.item.enchantment.Enchantment;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.inventory.ContainerType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.inventory.ServerboundContainerButtonClickPacket;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
public class EnchantingInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||
public EnchantingInventoryTranslator() {
|
||||
|
@ -73,16 +72,16 @@ public class EnchantingInventoryTranslator extends AbstractBlockInventoryTransla
|
|||
// The Bedrock index might need changed, so let's look it up and see.
|
||||
int bedrockIndex = value;
|
||||
if (bedrockIndex != -1) {
|
||||
Enchantment enchantment = Enchantment.getByJavaIdentifier("minecraft:" + Enchantment.JavaEnchantment.of(bedrockIndex).name().toLowerCase(Locale.ROOT));
|
||||
if (enchantment != null) {
|
||||
Enchantment enchantment = session.getRegistryCache().enchantments().byId(value);
|
||||
if (enchantment != null && enchantment.bedrockEnchantment() != null) {
|
||||
// Convert the Java enchantment index to Bedrock's
|
||||
bedrockIndex = enchantment.ordinal();
|
||||
bedrockIndex = enchantment.bedrockEnchantment().ordinal();
|
||||
} else {
|
||||
// There is no Bedrock enchantment equivalent
|
||||
bedrockIndex = -1;
|
||||
}
|
||||
}
|
||||
enchantingInventory.getGeyserEnchantOptions()[slotToUpdate].setEnchantIndex(value, bedrockIndex);
|
||||
enchantingInventory.getGeyserEnchantOptions()[slotToUpdate].setEnchantIndex(bedrockIndex);
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
|
|
|
@ -26,11 +26,6 @@
|
|||
package org.geysermc.geyser.translator.protocol.java;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.command.CommandNode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.command.CommandParser;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.command.properties.ResourceProperties;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCommandsPacket;
|
||||
import it.unimi.dsi.fastutil.Hash;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
@ -46,13 +41,18 @@ import org.cloudburstmc.protocol.bedrock.packet.AvailableCommandsPacket;
|
|||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.event.java.ServerDefineCommandsEvent;
|
||||
import org.geysermc.geyser.command.GeyserCommandManager;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.item.enchantment.Enchantment;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||
import org.geysermc.geyser.translator.protocol.Translator;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.command.CommandNode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.command.CommandParser;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.command.properties.ResourceProperties;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.ClientboundCommandsPacket;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -267,7 +267,7 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
|
|||
private static Object handleResource(CommandBuilderContext context, String resource, boolean tags) {
|
||||
return switch (resource) {
|
||||
case "minecraft:attribute" -> ATTRIBUTES;
|
||||
case "minecraft:enchantment" -> Enchantment.JavaEnchantment.ALL_JAVA_IDENTIFIERS;
|
||||
case "minecraft:enchantment" -> context.getEnchantments();
|
||||
case "minecraft:entity_type" -> context.getEntityTypes();
|
||||
case "minecraft:mob_effect" -> ALL_EFFECT_IDENTIFIERS;
|
||||
case "minecraft:worldgen/biome" -> tags ? context.getBiomesWithTags() : context.getBiomes();
|
||||
|
@ -292,6 +292,7 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
|
|||
private final GeyserSession session;
|
||||
private Object biomesWithTags;
|
||||
private Object biomesNoTags;
|
||||
private String[] enchantments;
|
||||
private String[] entityTypes;
|
||||
private String[] itemNames;
|
||||
private CommandEnumData teams;
|
||||
|
@ -318,6 +319,14 @@ public class JavaCommandsTranslator extends PacketTranslator<ClientboundCommands
|
|||
return (biomesWithTags = identifiers != null ? identifiers : CommandParam.STRING);
|
||||
}
|
||||
|
||||
private String[] getEnchantments() {
|
||||
if (enchantments != null) {
|
||||
return enchantments;
|
||||
}
|
||||
return (enchantments = session.getRegistryCache().enchantments().values().stream()
|
||||
.map(Enchantment::identifier).toArray(String[]::new));
|
||||
}
|
||||
|
||||
private String[] getEntityTypes() {
|
||||
if (entityTypes != null) {
|
||||
return entityTypes;
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.inventory.item.BedrockEnchantment;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
|
@ -43,11 +43,11 @@ public final class BlockUtils {
|
|||
|
||||
private static boolean correctTool(GeyserSession session, Block block, String itemToolType) {
|
||||
return switch (itemToolType) {
|
||||
case "axe" -> session.getTagCache().is(BlockTag.AXE_EFFECTIVE, block);
|
||||
case "hoe" -> session.getTagCache().is(BlockTag.HOE_EFFECTIVE, block);
|
||||
case "pickaxe" -> session.getTagCache().is(BlockTag.PICKAXE_EFFECTIVE, block);
|
||||
case "axe" -> session.getTagCache().is(BlockTag.MINEABLE_AXE, block);
|
||||
case "hoe" -> session.getTagCache().is(BlockTag.MINEABLE_HOE, block);
|
||||
case "pickaxe" -> session.getTagCache().is(BlockTag.MINEABLE_PICKAXE, block);
|
||||
case "shears" -> session.getTagCache().is(BlockTag.LEAVES, block) || session.getTagCache().is(BlockTag.WOOL, block);
|
||||
case "shovel" -> session.getTagCache().is(BlockTag.SHOVEL_EFFECTIVE, block);
|
||||
case "shovel" -> session.getTagCache().is(BlockTag.MINEABLE_SHOVEL, block);
|
||||
case "sword" -> block == Blocks.COBWEB;
|
||||
default -> {
|
||||
session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType);
|
||||
|
@ -145,7 +145,7 @@ public final class BlockUtils {
|
|||
toolCanBreak = canToolTierBreakBlock(session, block, toolTier);
|
||||
}
|
||||
|
||||
int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(components, Enchantment.JavaEnchantment.EFFICIENCY);
|
||||
int toolEfficiencyLevel = ItemUtils.getEnchantmentLevel(session, components, BedrockEnchantment.EFFICIENCY);
|
||||
int hasteLevel = 0;
|
||||
int miningFatigueLevel = 0;
|
||||
|
||||
|
@ -160,7 +160,7 @@ public final class BlockUtils {
|
|||
|
||||
boolean waterInEyes = session.getCollisionManager().isWaterInEyes();
|
||||
boolean insideOfWaterWithoutAquaAffinity = waterInEyes &&
|
||||
ItemUtils.getEnchantmentLevel(session.getPlayerInventory().getItem(5).getComponents(), Enchantment.JavaEnchantment.AQUA_AFFINITY) < 1;
|
||||
ItemUtils.getEnchantmentLevel(session, session.getPlayerInventory().getItem(5).getComponents(), BedrockEnchantment.AQUA_AFFINITY) < 1;
|
||||
|
||||
return calculateBreakTime(block.destroyTime(), toolTier, canHarvestWithHand, correctTool, toolCanBreak, toolType, isShearsEffective,
|
||||
toolEfficiencyLevel, hasteLevel, miningFatigueLevel, insideOfWaterWithoutAquaAffinity, session.getPlayerEntity().isOnGround());
|
||||
|
|
|
@ -27,17 +27,26 @@ package org.geysermc.geyser.util;
|
|||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.inventory.item.BedrockEnchantment;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.enchantment.Enchantment;
|
||||
import org.geysermc.geyser.item.enchantment.EnchantmentComponent;
|
||||
import org.geysermc.geyser.item.type.FishingRodItem;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemEnchantments;
|
||||
|
||||
public class ItemUtils {
|
||||
import java.util.Map;
|
||||
|
||||
public static int getEnchantmentLevel(@Nullable DataComponents components, Enchantment.JavaEnchantment enchantment) {
|
||||
public final class ItemUtils {
|
||||
|
||||
/**
|
||||
* Cheap hack. Proper solution is to read the enchantment effects.
|
||||
*/
|
||||
@Deprecated
|
||||
public static int getEnchantmentLevel(GeyserSession session, @Nullable DataComponents components, BedrockEnchantment bedrockEnchantment) {
|
||||
if (components == null) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -47,7 +56,32 @@ public class ItemUtils {
|
|||
return 0;
|
||||
}
|
||||
|
||||
return enchantmentData.getEnchantments().getOrDefault(enchantment.ordinal(), 0);
|
||||
for (Map.Entry<Integer, Integer> entry : enchantmentData.getEnchantments().entrySet()) {
|
||||
Enchantment enchantment = session.getRegistryCache().enchantments().byId(entry.getKey());
|
||||
if (enchantment.bedrockEnchantment() == bedrockEnchantment) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static boolean hasEffect(GeyserSession session, @Nullable DataComponents components, EnchantmentComponent component) {
|
||||
if (components == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemEnchantments enchantmentData = components.get(DataComponentType.ENCHANTMENTS);
|
||||
if (enchantmentData == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (Integer id : enchantmentData.getEnchantments().keySet()) {
|
||||
Enchantment enchantment = session.getRegistryCache().enchantments().byId(id);
|
||||
if (enchantment.effects().contains(component)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,4 +107,7 @@ public class ItemUtils {
|
|||
}
|
||||
return components.get(DataComponentType.CUSTOM_NAME);
|
||||
}
|
||||
|
||||
private ItemUtils() {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,25 +23,11 @@
|
|||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.item;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.RegistryEntry;
|
||||
package org.geysermc.geyser.util;
|
||||
|
||||
/**
|
||||
* @param anvilCost also as a rarity multiplier
|
||||
* Represents anything that could be tracked like a enum, without also creating a name and enum-wide array.
|
||||
*/
|
||||
public record Enchantment(String supportedItemsTag, int maxLevel, int anvilCost, @Nullable String exclusiveSetTag) {
|
||||
|
||||
// Implementation note: I have a feeling the tags can be a list of items, because in vanilla they're HolderSet classes.
|
||||
// I'm not sure how that's wired over the network, so we'll put it off.
|
||||
public static Enchantment read(RegistryEntry entry) {
|
||||
NbtMap data = entry.getData();
|
||||
String supportedItems = data.getString("supported_items");
|
||||
int maxLevel = data.getInt("max_level");
|
||||
int anvilCost = data.getInt("anvil_cost");
|
||||
String exclusiveSet = data.getString("exclusive_set", null);
|
||||
return new Enchantment(supportedItems, maxLevel, anvilCost, exclusiveSet);
|
||||
}
|
||||
public interface Ordered {
|
||||
int ordinal();
|
||||
}
|
|
@ -1 +1 @@
|
|||
Subproject commit 88e50df1008916c266428ac11f76f07dc24638c5
|
||||
Subproject commit 1f1d5ce8c482dac142f13e95e19368e3f36de144
|
Loading…
Reference in a new issue