Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-20 06:50:09 +01:00
Refactor TagCache to be extensible
Previously, for any new tag, we would have to add a field, add the line to load it, add the line to clear it, and make a method for that tag. Now, you just add an enum.
Dieser Commit ist enthalten in:
Ursprung
c48428daf0
Commit
b81408820b
@ -31,6 +31,7 @@ import org.cloudburstmc.math.vector.Vector3f;
|
|||||||
import org.geysermc.geyser.entity.EntityDefinition;
|
import org.geysermc.geyser.entity.EntityDefinition;
|
||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||||
import org.geysermc.geyser.util.InteractionResult;
|
import org.geysermc.geyser.util.InteractionResult;
|
||||||
import org.geysermc.geyser.util.InteractiveTag;
|
import org.geysermc.geyser.util.InteractiveTag;
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ public class DolphinEntity extends WaterEntity {
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||||
if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) {
|
if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) {
|
||||||
return InteractiveTag.FEED;
|
return InteractiveTag.FEED;
|
||||||
}
|
}
|
||||||
return super.testMobInteraction(hand, itemInHand);
|
return super.testMobInteraction(hand, itemInHand);
|
||||||
@ -58,7 +59,7 @@ public class DolphinEntity extends WaterEntity {
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||||
if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) {
|
if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) {
|
||||||
// Feed
|
// Feed
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ import org.geysermc.geyser.entity.EntityDefinition;
|
|||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.item.type.Item;
|
import org.geysermc.geyser.item.type.Item;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||||
import org.geysermc.geyser.util.EntityUtils;
|
import org.geysermc.geyser.util.EntityUtils;
|
||||||
import org.geysermc.geyser.util.InteractionResult;
|
import org.geysermc.geyser.util.InteractionResult;
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ public class AxolotlEntity extends AnimalEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canEat(Item item) {
|
public boolean canEat(Item item) {
|
||||||
return session.getTagCache().isAxolotlFood(item);
|
return session.getTagCache().is(ItemTag.AXOLOTL_FOOD, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
|||||||
import org.geysermc.geyser.entity.EntityDefinition;
|
import org.geysermc.geyser.entity.EntityDefinition;
|
||||||
import org.geysermc.geyser.item.type.Item;
|
import org.geysermc.geyser.item.type.Item;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -67,6 +68,6 @@ public class BeeEntity extends AnimalEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canEat(Item item) {
|
public boolean canEat(Item item) {
|
||||||
return session.getTagCache().isFlower(item);
|
return session.getTagCache().is(ItemTag.FLOWERS, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||||||
import org.geysermc.geyser.entity.EntityDefinition;
|
import org.geysermc.geyser.entity.EntityDefinition;
|
||||||
import org.geysermc.geyser.item.type.Item;
|
import org.geysermc.geyser.item.type.Item;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -56,6 +57,6 @@ public class FoxEntity extends AnimalEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canEat(Item item) {
|
public boolean canEat(Item item) {
|
||||||
return session.getTagCache().isFoxFood(item);
|
return session.getTagCache().is(ItemTag.FOX_FOOD, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
|||||||
import org.geysermc.geyser.entity.EntityDefinition;
|
import org.geysermc.geyser.entity.EntityDefinition;
|
||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.item.Items;
|
import org.geysermc.geyser.item.Items;
|
||||||
import org.geysermc.geyser.item.type.FlowerItem;
|
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||||
import org.geysermc.geyser.util.InteractionResult;
|
import org.geysermc.geyser.util.InteractionResult;
|
||||||
import org.geysermc.geyser.util.InteractiveTag;
|
import org.geysermc.geyser.util.InteractiveTag;
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ public class MooshroomEntity extends AnimalEntity {
|
|||||||
} else if (!isBaby && isAlive() && itemInHand.asItem() == Items.SHEARS) {
|
} else if (!isBaby && isAlive() && itemInHand.asItem() == Items.SHEARS) {
|
||||||
// Shear items
|
// Shear items
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS;
|
||||||
} else if (isBrown && session.getTagCache().isSmallFlower(itemInHand) && itemInHand.asItem() instanceof FlowerItem) {
|
} else if (isBrown && session.getTagCache().is(ItemTag.SMALL_FLOWERS, itemInHand)) {
|
||||||
// ?
|
// ?
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ import org.geysermc.geyser.entity.EntityDefinitions;
|
|||||||
import org.geysermc.geyser.entity.type.Tickable;
|
import org.geysermc.geyser.entity.type.Tickable;
|
||||||
import org.geysermc.geyser.item.type.Item;
|
import org.geysermc.geyser.item.type.Item;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ public class SnifferEntity extends AnimalEntity implements Tickable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canEat(Item item) {
|
public boolean canEat(Item item) {
|
||||||
return session.getTagCache().isSnifferFood(item);
|
return session.getTagCache().is(ItemTag.SNIFFER_FOOD, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSnifferState(ObjectEntityMetadata<SnifferState> entityMetadata) {
|
public void setSnifferState(ObjectEntityMetadata<SnifferState> entityMetadata) {
|
||||||
|
@ -35,6 +35,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||||||
import org.geysermc.geyser.entity.EntityDefinition;
|
import org.geysermc.geyser.entity.EntityDefinition;
|
||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||||
import org.geysermc.geyser.util.InteractionResult;
|
import org.geysermc.geyser.util.InteractionResult;
|
||||||
import org.geysermc.geyser.util.InteractiveTag;
|
import org.geysermc.geyser.util.InteractiveTag;
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ public class CreeperEntity extends MonsterEntity {
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||||
if (session.getTagCache().isCreeperIgniter(itemInHand.asItem())) {
|
if (session.getTagCache().is(ItemTag.CREEPER_IGNITERS, itemInHand)) {
|
||||||
return InteractiveTag.IGNITE_CREEPER;
|
return InteractiveTag.IGNITE_CREEPER;
|
||||||
} else {
|
} else {
|
||||||
return super.testMobInteraction(hand, itemInHand);
|
return super.testMobInteraction(hand, itemInHand);
|
||||||
@ -75,7 +76,7 @@ public class CreeperEntity extends MonsterEntity {
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||||
if (session.getTagCache().isCreeperIgniter(itemInHand.asItem())) {
|
if (session.getTagCache().is(ItemTag.CREEPER_IGNITERS, itemInHand)) {
|
||||||
// Ignite creeper - as of 1.19.3
|
// Ignite creeper - as of 1.19.3
|
||||||
session.playSoundEvent(SoundEvent.IGNITE, position);
|
session.playSoundEvent(SoundEvent.IGNITE, position);
|
||||||
return InteractionResult.SUCCESS;
|
return InteractionResult.SUCCESS;
|
||||||
|
@ -35,6 +35,7 @@ import org.geysermc.geyser.entity.EntityDefinition;
|
|||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.item.Items;
|
import org.geysermc.geyser.item.Items;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||||
import org.geysermc.geyser.util.InteractionResult;
|
import org.geysermc.geyser.util.InteractionResult;
|
||||||
import org.geysermc.geyser.util.InteractiveTag;
|
import org.geysermc.geyser.util.InteractiveTag;
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ public class PiglinEntity extends BasePiglinEntity {
|
|||||||
@Override
|
@Override
|
||||||
public void updateOffHand(GeyserSession session) {
|
public void updateOffHand(GeyserSession session) {
|
||||||
// Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates
|
// Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates
|
||||||
setFlag(EntityFlag.ADMIRING, session.getTagCache().shouldPiglinAdmire(session.getItemMappings().getMapping(this.offHand).getJavaItem()));
|
setFlag(EntityFlag.ADMIRING, session.getTagCache().is(ItemTag.PIGLIN_LOVED, session.getItemMappings().getMapping(this.offHand).getJavaItem()));
|
||||||
super.updateBedrockMetadata();
|
super.updateBedrockMetadata();
|
||||||
|
|
||||||
super.updateOffHand(session);
|
super.updateOffHand(session);
|
||||||
|
@ -57,7 +57,7 @@ import java.util.function.ToIntFunction;
|
|||||||
* Stores any information sent via Java registries. May not contain all data in a given registry - we'll strip what's
|
* Stores any information sent via Java registries. May not contain all data in a given registry - we'll strip what's
|
||||||
* unneeded.
|
* unneeded.
|
||||||
*
|
*
|
||||||
* Crafted as of 1.20.5 for easy "add new registry" in the future.
|
* Crafted as of 1.20.5 for easy "add new registry" functionality in the future.
|
||||||
*/
|
*/
|
||||||
@Accessors(fluent = true)
|
@Accessors(fluent = true)
|
||||||
@Getter
|
@Getter
|
||||||
@ -118,6 +118,7 @@ public final class RegistryCache {
|
|||||||
REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> {
|
REGISTRIES.put("minecraft:" + registry, (registryCache, entries) -> {
|
||||||
Int2ObjectMap<T> localCache = localCacheFunction.apply(registryCache);
|
Int2ObjectMap<T> localCache = localCacheFunction.apply(registryCache);
|
||||||
// Clear each local cache every time a new registry entry is given to us
|
// Clear each local cache every time a new registry entry is given to us
|
||||||
|
// (e.g. proxy server switches)
|
||||||
localCache.clear();
|
localCache.clear();
|
||||||
for (int i = 0; i < entries.size(); i++) {
|
for (int i = 0; i < entries.size(); i++) {
|
||||||
RegistryEntry entry = entries.get(i);
|
RegistryEntry entry = entries.get(i);
|
||||||
|
@ -27,64 +27,45 @@ package org.geysermc.geyser.session.cache;
|
|||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket;
|
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import it.unimi.dsi.fastutil.ints.IntLists;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
||||||
import org.geysermc.geyser.GeyserLogger;
|
import org.geysermc.geyser.GeyserLogger;
|
||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.item.type.Item;
|
import org.geysermc.geyser.item.type.Item;
|
||||||
import org.geysermc.geyser.registry.type.BlockMapping;
|
import org.geysermc.geyser.registry.type.BlockMapping;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.session.cache.tags.BlockTag;
|
||||||
|
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages information sent from the {@link ClientboundUpdateTagsPacket}. If that packet is not sent, all lists here
|
* Manages information sent from the {@link ClientboundUpdateTagsPacket}. If that packet is not sent, all lists here
|
||||||
* will remain empty, matching Java Edition behavior.
|
* 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
|
@ParametersAreNonnullByDefault
|
||||||
public class TagCache {
|
public final class TagCache {
|
||||||
/* Blocks */
|
// Put these here so the enums can load without a static map
|
||||||
private IntList leaves;
|
public static final Map<String, BlockTag> ALL_BLOCK_TAGS = new HashMap<>();
|
||||||
private IntList wool;
|
public static final Map<String, ItemTag> ALL_ITEM_TAGS = new HashMap<>();
|
||||||
|
|
||||||
private IntList axeEffective;
|
private final Map<BlockTag, IntList> blocks = new EnumMap<>(BlockTag.class);
|
||||||
private IntList hoeEffective;
|
private final Map<ItemTag, IntList> items = new EnumMap<>(ItemTag.class);
|
||||||
private IntList pickaxeEffective;
|
|
||||||
private IntList shovelEffective;
|
|
||||||
|
|
||||||
private IntList requiresStoneTool;
|
|
||||||
private IntList requiresIronTool;
|
|
||||||
private IntList requiresDiamondTool;
|
|
||||||
|
|
||||||
/* Items */
|
|
||||||
private IntList axolotlFood;
|
|
||||||
private IntList creeperIgniters;
|
|
||||||
private IntList fishes;
|
|
||||||
private IntList flowers;
|
|
||||||
private IntList foxFood;
|
|
||||||
private IntList piglinLoved;
|
|
||||||
private IntList smallFlowers;
|
|
||||||
private IntList snifferFood;
|
|
||||||
|
|
||||||
public TagCache() {
|
|
||||||
// Ensure all lists are non-null
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadPacket(GeyserSession session, ClientboundUpdateTagsPacket packet) {
|
public void loadPacket(GeyserSession session, ClientboundUpdateTagsPacket packet) {
|
||||||
Map<String, int[]> blockTags = packet.getTags().get("minecraft:block");
|
Map<String, int[]> blockTags = packet.getTags().get("minecraft:block");
|
||||||
this.leaves = IntList.of(blockTags.get("minecraft:leaves"));
|
this.blocks.clear();
|
||||||
this.wool = IntList.of(blockTags.get("minecraft:wool"));
|
ALL_BLOCK_TAGS.forEach((location, tag) -> {
|
||||||
|
int[] values = blockTags.get(location);
|
||||||
this.axeEffective = IntList.of(blockTags.get("minecraft:mineable/axe"));
|
if (values != null) {
|
||||||
this.hoeEffective = IntList.of(blockTags.get("minecraft:mineable/hoe"));
|
this.blocks.put(tag, IntList.of(values));
|
||||||
this.pickaxeEffective = IntList.of(blockTags.get("minecraft:mineable/pickaxe"));
|
} else {
|
||||||
this.shovelEffective = IntList.of(blockTags.get("minecraft:mineable/shovel"));
|
session.getGeyser().getLogger().debug("Block tag not found from server: " + location);
|
||||||
|
}
|
||||||
this.requiresStoneTool = IntList.of(blockTags.get("minecraft:needs_stone_tool"));
|
});
|
||||||
this.requiresIronTool = IntList.of(blockTags.get("minecraft:needs_iron_tool"));
|
|
||||||
this.requiresDiamondTool = IntList.of(blockTags.get("minecraft:needs_diamond_tool"));
|
|
||||||
|
|
||||||
// Hack btw
|
// Hack btw
|
||||||
GeyserLogger logger = session.getGeyser().getLogger();
|
GeyserLogger logger = session.getGeyser().getLogger();
|
||||||
@ -96,14 +77,15 @@ public class TagCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Map<String, int[]> itemTags = packet.getTags().get("minecraft:item");
|
Map<String, int[]> itemTags = packet.getTags().get("minecraft:item");
|
||||||
this.axolotlFood = IntList.of(itemTags.get("minecraft:axolotl_food"));
|
this.items.clear();
|
||||||
this.creeperIgniters = load(itemTags.get("minecraft:creeper_igniters"));
|
ALL_ITEM_TAGS.forEach((location, tag) -> {
|
||||||
this.fishes = IntList.of(itemTags.get("minecraft:fishes"));
|
int[] values = itemTags.get(location);
|
||||||
this.flowers = IntList.of(itemTags.get("minecraft:flowers"));
|
if (values != null) {
|
||||||
this.foxFood = IntList.of(itemTags.get("minecraft:fox_food"));
|
this.items.put(tag, IntList.of(values));
|
||||||
this.piglinLoved = IntList.of(itemTags.get("minecraft:piglin_loved"));
|
} else {
|
||||||
this.smallFlowers = IntList.of(itemTags.get("minecraft:small_flowers"));
|
session.getGeyser().getLogger().debug("Item tag not found from server: " + location);
|
||||||
this.snifferFood = load(itemTags.get("minecraft:sniffer_food"));
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Hack btw
|
// Hack btw
|
||||||
boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1;
|
boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1;
|
||||||
@ -113,98 +95,32 @@ public class TagCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IntList load(int @Nullable[] tags) {
|
/**
|
||||||
if (tags == null) {
|
* @return true if the block tag is present and contains this block mapping's Java ID.
|
||||||
return IntLists.EMPTY_LIST;
|
*/
|
||||||
|
public boolean is(BlockTag tag, BlockMapping mapping) {
|
||||||
|
IntList values = this.blocks.get(tag);
|
||||||
|
if (values != null) {
|
||||||
|
return values.contains(mapping.getJavaBlockId());
|
||||||
}
|
}
|
||||||
return IntList.of(tags);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
/**
|
||||||
this.leaves = IntLists.emptyList();
|
* @return true if the item tag is present and contains this item stack's Java ID.
|
||||||
this.wool = IntLists.emptyList();
|
*/
|
||||||
|
public boolean is(ItemTag tag, GeyserItemStack itemStack) {
|
||||||
this.axeEffective = IntLists.emptyList();
|
return is(tag, itemStack.asItem());
|
||||||
this.hoeEffective = IntLists.emptyList();
|
|
||||||
this.pickaxeEffective = IntLists.emptyList();
|
|
||||||
this.shovelEffective = IntLists.emptyList();
|
|
||||||
|
|
||||||
this.requiresStoneTool = IntLists.emptyList();
|
|
||||||
this.requiresIronTool = IntLists.emptyList();
|
|
||||||
this.requiresDiamondTool = IntLists.emptyList();
|
|
||||||
|
|
||||||
this.axolotlFood = IntLists.emptyList();
|
|
||||||
this.creeperIgniters = IntLists.emptyList();
|
|
||||||
this.fishes = IntLists.emptyList();
|
|
||||||
this.flowers = IntLists.emptyList();
|
|
||||||
this.foxFood = IntLists.emptyList();
|
|
||||||
this.piglinLoved = IntLists.emptyList();
|
|
||||||
this.smallFlowers = IntLists.emptyList();
|
|
||||||
this.snifferFood = IntLists.emptyList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAxolotlFood(Item item) {
|
/**
|
||||||
return axolotlFood.contains(item.javaId());
|
* @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());
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
public boolean isCreeperIgniter(Item item) {
|
|
||||||
return creeperIgniters.contains(item.javaId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFish(GeyserItemStack itemStack) {
|
|
||||||
return fishes.contains(itemStack.getJavaId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFlower(Item item) {
|
|
||||||
return flowers.contains(item.javaId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFoxFood(Item item) {
|
|
||||||
return foxFood.contains(item.javaId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldPiglinAdmire(Item item) {
|
|
||||||
return piglinLoved.contains(item.javaId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSmallFlower(GeyserItemStack itemStack) {
|
|
||||||
return smallFlowers.contains(itemStack.getJavaId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSnifferFood(Item item) {
|
|
||||||
return snifferFood.contains(item.javaId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAxeEffective(BlockMapping blockMapping) {
|
|
||||||
return axeEffective.contains(blockMapping.getJavaBlockId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isHoeEffective(BlockMapping blockMapping) {
|
|
||||||
return hoeEffective.contains(blockMapping.getJavaBlockId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPickaxeEffective(BlockMapping blockMapping) {
|
|
||||||
return pickaxeEffective.contains(blockMapping.getJavaBlockId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isShovelEffective(BlockMapping blockMapping) {
|
|
||||||
return shovelEffective.contains(blockMapping.getJavaBlockId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isShearsEffective(BlockMapping blockMapping) {
|
|
||||||
int javaBlockId = blockMapping.getJavaBlockId();
|
|
||||||
return leaves.contains(javaBlockId) || wool.contains(javaBlockId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean requiresStoneTool(BlockMapping blockMapping) {
|
|
||||||
return requiresStoneTool.contains(blockMapping.getJavaBlockId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean requiresIronTool(BlockMapping blockMapping) {
|
|
||||||
return requiresIronTool.contains(blockMapping.getJavaBlockId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean requiresDiamondTool(BlockMapping blockMapping) {
|
|
||||||
return requiresDiamondTool.contains(blockMapping.getJavaBlockId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
48
core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java
vendored
Normale Datei
48
core/src/main/java/org/geysermc/geyser/session/cache/tags/BlockTag.java
vendored
Normale Datei
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-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.session.cache.TagCache;
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
BlockTag(String identifier) {
|
||||||
|
register(identifier, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void register(String name, BlockTag tag) {
|
||||||
|
TagCache.ALL_BLOCK_TAGS.put("minecraft:" + name, tag);
|
||||||
|
}
|
||||||
|
}
|
47
core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java
vendored
Normale Datei
47
core/src/main/java/org/geysermc/geyser/session/cache/tags/ItemTag.java
vendored
Normale Datei
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019-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.session.cache.TagCache;
|
||||||
|
|
||||||
|
public enum ItemTag {
|
||||||
|
AXOLOTL_FOOD("axolotl_food"),
|
||||||
|
CREEPER_IGNITERS("creeper_igniters"),
|
||||||
|
FISHES("fishes"),
|
||||||
|
FLOWERS("flowers"),
|
||||||
|
FOX_FOOD("fox_food"),
|
||||||
|
PIGLIN_LOVED("piglin_loved"),
|
||||||
|
SMALL_FLOWERS("small_flowers"),
|
||||||
|
SNIFFER_FOOD("sniffer_food");
|
||||||
|
|
||||||
|
ItemTag(String identifier) {
|
||||||
|
register(identifier, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void register(String name, ItemTag tag) {
|
||||||
|
TagCache.ALL_ITEM_TAGS.put("minecraft:" + name, tag);
|
||||||
|
}
|
||||||
|
}
|
@ -47,10 +47,6 @@ public class BiomeTranslator {
|
|||||||
public static int loadServerBiome(RegistryEntry entry) {
|
public static int loadServerBiome(RegistryEntry entry) {
|
||||||
String javaIdentifier = entry.getId();
|
String javaIdentifier = entry.getId();
|
||||||
return Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0);
|
return Registries.BIOME_IDENTIFIERS.get().getOrDefault(javaIdentifier, 0);
|
||||||
// if (javaId == 0) {
|
|
||||||
// // Matches Java behavior when it sees an invalid biome - it just replaces it with ID 0
|
|
||||||
// biomeTranslations.defaultReturnValue(bedrockId);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockStorage toNewBedrockBiome(GeyserSession session, DataPalette biomeData) {
|
public static BlockStorage toNewBedrockBiome(GeyserSession session, DataPalette biomeData) {
|
||||||
|
@ -36,17 +36,18 @@ import org.geysermc.geyser.registry.BlockRegistries;
|
|||||||
import org.geysermc.geyser.registry.type.BlockMapping;
|
import org.geysermc.geyser.registry.type.BlockMapping;
|
||||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.session.cache.tags.BlockTag;
|
||||||
import org.geysermc.geyser.translator.collision.BlockCollision;
|
import org.geysermc.geyser.translator.collision.BlockCollision;
|
||||||
|
|
||||||
public final class BlockUtils {
|
public final class BlockUtils {
|
||||||
|
|
||||||
private static boolean correctTool(GeyserSession session, BlockMapping blockMapping, String itemToolType) {
|
private static boolean correctTool(GeyserSession session, BlockMapping blockMapping, String itemToolType) {
|
||||||
return switch (itemToolType) {
|
return switch (itemToolType) {
|
||||||
case "axe" -> session.getTagCache().isAxeEffective(blockMapping);
|
case "axe" -> session.getTagCache().is(BlockTag.AXE_EFFECTIVE, blockMapping);
|
||||||
case "hoe" -> session.getTagCache().isHoeEffective(blockMapping);
|
case "hoe" -> session.getTagCache().is(BlockTag.HOE_EFFECTIVE, blockMapping);
|
||||||
case "pickaxe" -> session.getTagCache().isPickaxeEffective(blockMapping);
|
case "pickaxe" -> session.getTagCache().is(BlockTag.PICKAXE_EFFECTIVE, blockMapping);
|
||||||
case "shears" -> session.getTagCache().isShearsEffective(blockMapping);
|
case "shears" -> session.getTagCache().is(BlockTag.LEAVES, blockMapping) || session.getTagCache().is(BlockTag.WOOL, blockMapping);
|
||||||
case "shovel" -> session.getTagCache().isShovelEffective(blockMapping);
|
case "shovel" -> session.getTagCache().is(BlockTag.SHOVEL_EFFECTIVE, blockMapping);
|
||||||
case "sword" -> blockMapping.getJavaBlockId() == BlockStateValues.JAVA_COBWEB_ID;
|
case "sword" -> blockMapping.getJavaBlockId() == BlockStateValues.JAVA_COBWEB_ID;
|
||||||
default -> {
|
default -> {
|
||||||
session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType);
|
session.getGeyser().getLogger().warning("Unknown tool type: " + itemToolType);
|
||||||
@ -79,15 +80,15 @@ public final class BlockUtils {
|
|||||||
switch (toolTier) {
|
switch (toolTier) {
|
||||||
// Use intentional fall-throughs to check each tier with this block
|
// Use intentional fall-throughs to check each tier with this block
|
||||||
default:
|
default:
|
||||||
if (session.getTagCache().requiresStoneTool(blockMapping)) {
|
if (session.getTagCache().is(BlockTag.NEEDS_STONE_TOOL, blockMapping)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case "stone":
|
case "stone":
|
||||||
if (session.getTagCache().requiresIronTool(blockMapping)) {
|
if (session.getTagCache().is(BlockTag.NEEDS_IRON_TOOL, blockMapping)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case "iron":
|
case "iron":
|
||||||
if (session.getTagCache().requiresDiamondTool(blockMapping)) {
|
if (session.getTagCache().is(BlockTag.NEEDS_DIAMOND_TOOL, blockMapping)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,7 +132,7 @@ public final class BlockUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) {
|
public static double getBreakTime(GeyserSession session, BlockMapping blockMapping, ItemMapping item, @Nullable DataComponents components, boolean isSessionPlayer) {
|
||||||
boolean isShearsEffective = session.getTagCache().isShearsEffective(blockMapping); //TODO called twice
|
boolean isShearsEffective = session.getTagCache().is(BlockTag.LEAVES, blockMapping) || session.getTagCache().is(BlockTag.WOOL, blockMapping); //TODO called twice
|
||||||
boolean canHarvestWithHand = blockMapping.isCanBreakWithHand();
|
boolean canHarvestWithHand = blockMapping.isCanBreakWithHand();
|
||||||
String toolType = "";
|
String toolType = "";
|
||||||
String toolTier = "";
|
String toolTier = "";
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren