Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-09-08 20:43:04 +02:00
Add furnace minecart item translation (#2003)
Conveniently enough, the minecart furnace icon still exists in the vanilla Bedrock Edition game (thanks to Kastle for this discovery). With this and the translation string still being present, we can add the item into the game with only minor issues.
Dieser Commit ist enthalten in:
Ursprung
3a4b1e4dc7
Commit
2f42a4c630
@ -81,6 +81,8 @@ public interface GeyserConfiguration {
|
|||||||
|
|
||||||
Path getFloodgateKeyPath();
|
Path getFloodgateKeyPath();
|
||||||
|
|
||||||
|
boolean isAddNonBedrockItems();
|
||||||
|
|
||||||
boolean isAboveBedrockNetherBuilding();
|
boolean isAboveBedrockNetherBuilding();
|
||||||
|
|
||||||
boolean isCacheChunks();
|
boolean isCacheChunks();
|
||||||
|
@ -115,6 +115,9 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
|
|||||||
@JsonProperty("allow-custom-skulls")
|
@JsonProperty("allow-custom-skulls")
|
||||||
private boolean allowCustomSkulls = true;
|
private boolean allowCustomSkulls = true;
|
||||||
|
|
||||||
|
@JsonProperty("add-non-bedrock-items")
|
||||||
|
private boolean addNonBedrockItems = true;
|
||||||
|
|
||||||
@JsonProperty("above-bedrock-nether-building")
|
@JsonProperty("above-bedrock-nether-building")
|
||||||
private boolean aboveBedrockNetherBuilding = false;
|
private boolean aboveBedrockNetherBuilding = false;
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ package org.geysermc.connector.network;
|
|||||||
|
|
||||||
import com.nukkitx.protocol.bedrock.BedrockPacket;
|
import com.nukkitx.protocol.bedrock.BedrockPacket;
|
||||||
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.ExperimentData;
|
||||||
import com.nukkitx.protocol.bedrock.data.ResourcePackType;
|
import com.nukkitx.protocol.bedrock.data.ResourcePackType;
|
||||||
import com.nukkitx.protocol.bedrock.packet.*;
|
import com.nukkitx.protocol.bedrock.packet.*;
|
||||||
import com.nukkitx.protocol.bedrock.v428.Bedrock_v428;
|
import com.nukkitx.protocol.bedrock.v428.Bedrock_v428;
|
||||||
@ -36,6 +37,7 @@ import org.geysermc.connector.configuration.GeyserConfiguration;
|
|||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
import org.geysermc.connector.network.session.cache.AdvancementsCache;
|
import org.geysermc.connector.network.session.cache.AdvancementsCache;
|
||||||
import org.geysermc.connector.network.translators.PacketTranslatorRegistry;
|
import org.geysermc.connector.network.translators.PacketTranslatorRegistry;
|
||||||
|
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_100;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_100;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210;
|
||||||
import org.geysermc.connector.utils.*;
|
import org.geysermc.connector.utils.*;
|
||||||
@ -133,6 +135,11 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||||||
stackPacket.getResourcePacks().add(new ResourcePackStackPacket.Entry(header.getUuid().toString(), header.getVersionString(), ""));
|
stackPacket.getResourcePacks().add(new ResourcePackStackPacket.Entry(header.getUuid().toString(), header.getVersionString(), ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ItemRegistry.FURNACE_MINECART_DATA != null) {
|
||||||
|
// Allow custom items to work
|
||||||
|
stackPacket.getExperiments().add(new ExperimentData("data_driven_items", true));
|
||||||
|
}
|
||||||
|
|
||||||
session.sendUpstreamPacket(stackPacket);
|
session.sendUpstreamPacket(stackPacket);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -464,6 +464,12 @@ public class GeyserSession implements CommandSender {
|
|||||||
// Set the hardcoded shield ID to the ID we just defined in StartGamePacket
|
// Set the hardcoded shield ID to the ID we just defined in StartGamePacket
|
||||||
upstream.getSession().getHardcodedBlockingId().set(ItemRegistry.SHIELD.getBedrockId());
|
upstream.getSession().getHardcodedBlockingId().set(ItemRegistry.SHIELD.getBedrockId());
|
||||||
|
|
||||||
|
if (ItemRegistry.FURNACE_MINECART_DATA != null) {
|
||||||
|
ItemComponentPacket componentPacket = new ItemComponentPacket();
|
||||||
|
componentPacket.getItems().add(ItemRegistry.FURNACE_MINECART_DATA);
|
||||||
|
upstream.sendPacket(componentPacket);
|
||||||
|
}
|
||||||
|
|
||||||
ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false);
|
ChunkUtils.sendEmptyChunks(this, playerEntity.getPosition().toInt(), 0, false);
|
||||||
|
|
||||||
BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket();
|
BiomeDefinitionListPacket biomeDefinitionListPacket = new BiomeDefinitionListPacket();
|
||||||
|
@ -28,14 +28,19 @@ package org.geysermc.connector.network.translators.item;
|
|||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.nukkitx.nbt.NbtMap;
|
import com.nukkitx.nbt.NbtMap;
|
||||||
|
import com.nukkitx.nbt.NbtMapBuilder;
|
||||||
|
import com.nukkitx.nbt.NbtType;
|
||||||
import com.nukkitx.nbt.NbtUtils;
|
import com.nukkitx.nbt.NbtUtils;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.inventory.ComponentItemData;
|
||||||
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
import com.nukkitx.protocol.bedrock.data.inventory.ItemData;
|
||||||
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
|
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.utils.FileUtils;
|
import org.geysermc.connector.utils.FileUtils;
|
||||||
import org.geysermc.connector.utils.LanguageUtils;
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
@ -55,8 +60,7 @@ public class ItemRegistry {
|
|||||||
/**
|
/**
|
||||||
* A list of all identifiers that only exist on Java. Used to prevent creative items from becoming these unintentionally.
|
* A list of all identifiers that only exist on Java. Used to prevent creative items from becoming these unintentionally.
|
||||||
*/
|
*/
|
||||||
private static final List<String> JAVA_ONLY_ITEMS = Arrays.asList("minecraft:spectral_arrow", "minecraft:debug_stick",
|
private static final Set<String> JAVA_ONLY_ITEMS;
|
||||||
"minecraft:knowledge_book", "minecraft:tipped_arrow", "minecraft:furnace_minecart");
|
|
||||||
|
|
||||||
public static final ItemData[] CREATIVE_ITEMS;
|
public static final ItemData[] CREATIVE_ITEMS;
|
||||||
|
|
||||||
@ -107,6 +111,11 @@ public class ItemRegistry {
|
|||||||
|
|
||||||
public static int BARRIER_INDEX = 0;
|
public static int BARRIER_INDEX = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the properties and data of the "custom" furnace minecart item.
|
||||||
|
*/
|
||||||
|
public static final ComponentItemData FURNACE_MINECART_DATA;
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
@ -150,9 +159,16 @@ public class ItemRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int itemIndex = 0;
|
int itemIndex = 0;
|
||||||
|
int javaFurnaceMinecartId = 0;
|
||||||
|
boolean usingFurnaceMinecart = GeyserConnector.getInstance().getConfig().isAddNonBedrockItems();
|
||||||
Iterator<Map.Entry<String, JsonNode>> iterator = items.fields();
|
Iterator<Map.Entry<String, JsonNode>> iterator = items.fields();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
Map.Entry<String, JsonNode> entry = iterator.next();
|
Map.Entry<String, JsonNode> entry = iterator.next();
|
||||||
|
if (usingFurnaceMinecart && entry.getKey().equals("minecraft:furnace_minecart")) {
|
||||||
|
javaFurnaceMinecartId = itemIndex;
|
||||||
|
itemIndex++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
int bedrockId = entry.getValue().get("bedrock_id").intValue();
|
int bedrockId = entry.getValue().get("bedrock_id").intValue();
|
||||||
String bedrockIdentifier = bedrockIdToIdentifier.get(bedrockId);
|
String bedrockIdentifier = bedrockIdToIdentifier.get(bedrockId);
|
||||||
if (bedrockIdentifier == null) {
|
if (bedrockIdentifier == null) {
|
||||||
@ -224,6 +240,9 @@ public class ItemRegistry {
|
|||||||
itemIndex++;
|
itemIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
itemNames.add("minecraft:furnace_minecart");
|
||||||
|
itemNames.add("minecraft:spectral_arrow");
|
||||||
|
|
||||||
if (lodestoneCompassId == 0) {
|
if (lodestoneCompassId == 0) {
|
||||||
throw new RuntimeException("Lodestone compass not found in item palette!");
|
throw new RuntimeException("Lodestone compass not found in item palette!");
|
||||||
}
|
}
|
||||||
@ -248,9 +267,59 @@ public class ItemRegistry {
|
|||||||
ItemData item = getBedrockItemFromJson(itemNode);
|
ItemData item = getBedrockItemFromJson(itemNode);
|
||||||
creativeItems.add(ItemData.fromNet(netId++, item.getId(), item.getDamage(), item.getCount(), item.getTag()));
|
creativeItems.add(ItemData.fromNet(netId++, item.getId(), item.getDamage(), item.getCount(), item.getTag()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (usingFurnaceMinecart) {
|
||||||
|
// Add the furnace minecart as an item
|
||||||
|
int furnaceMinecartId = ITEMS.size() + 1;
|
||||||
|
|
||||||
|
ITEMS.add(new StartGamePacket.ItemEntry("geysermc:furnace_minecart", (short) furnaceMinecartId, true));
|
||||||
|
ITEM_ENTRIES.put(javaFurnaceMinecartId, new ItemEntry("minecraft:furnace_minecart", "geysermc:furnace_minecart", javaFurnaceMinecartId,
|
||||||
|
furnaceMinecartId, 0, false, 1));
|
||||||
|
creativeItems.add(ItemData.fromNet(netId, furnaceMinecartId, (short) 0, 1, null));
|
||||||
|
|
||||||
|
NbtMapBuilder builder = NbtMap.builder();
|
||||||
|
builder.putString("name", "geysermc:furnace_minecart")
|
||||||
|
.putInt("id", furnaceMinecartId);
|
||||||
|
|
||||||
|
NbtMapBuilder componentBuilder = NbtMap.builder();
|
||||||
|
// Conveniently, as of 1.16.200, the furnace minecart has a texture AND translation string already.
|
||||||
|
componentBuilder.putCompound("minecraft:icon", NbtMap.builder().putString("texture", "minecart_furnace").build());
|
||||||
|
componentBuilder.putCompound("minecraft:display_name", NbtMap.builder().putString("value", "item.minecartFurnace.name").build());
|
||||||
|
|
||||||
|
// Indicate that the arm animation should play on rails
|
||||||
|
List<NbtMap> useOnTag = Collections.singletonList(NbtMap.builder().putString("tags", "q.any_tag('rail')").build());
|
||||||
|
componentBuilder.putCompound("minecraft:entity_placer", NbtMap.builder()
|
||||||
|
.putList("dispense_on", NbtType.COMPOUND, useOnTag)
|
||||||
|
.putString("entity", "minecraft:minecart")
|
||||||
|
.putList("use_on", NbtType.COMPOUND, useOnTag)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
NbtMapBuilder itemProperties = NbtMap.builder();
|
||||||
|
// We always want to allow offhand usage when we can - matches Java Edition
|
||||||
|
itemProperties.putBoolean("allow_off_hand", true);
|
||||||
|
itemProperties.putBoolean("hand_equipped", false);
|
||||||
|
itemProperties.putInt("max_stack_size", 1);
|
||||||
|
itemProperties.putString("creative_group", "itemGroup.name.minecart");
|
||||||
|
itemProperties.putInt("creative_category", 4); // 4 - "Items"
|
||||||
|
|
||||||
|
componentBuilder.putCompound("item_properties", itemProperties.build());
|
||||||
|
builder.putCompound("components", componentBuilder.build());
|
||||||
|
FURNACE_MINECART_DATA = new ComponentItemData("geysermc:furnace_minecart", builder.build());
|
||||||
|
} else {
|
||||||
|
FURNACE_MINECART_DATA = null;
|
||||||
|
}
|
||||||
|
|
||||||
CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]);
|
CREATIVE_ITEMS = creativeItems.toArray(new ItemData[0]);
|
||||||
|
|
||||||
ITEM_NAMES = itemNames.toArray(new String[0]);
|
ITEM_NAMES = itemNames.toArray(new String[0]);
|
||||||
|
|
||||||
|
Set<String> javaOnlyItems = new ObjectOpenHashSet<>();
|
||||||
|
Collections.addAll(javaOnlyItems, "minecraft:spectral_arrow", "minecraft:debug_stick",
|
||||||
|
"minecraft:knowledge_book", "minecraft:tipped_arrow");
|
||||||
|
if (!usingFurnaceMinecart) {
|
||||||
|
javaOnlyItems.add("minecraft:furnace_minecart");
|
||||||
|
}
|
||||||
|
JAVA_ONLY_ITEMS = ImmutableSet.copyOf(javaOnlyItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,6 +139,12 @@ cache-images: 0
|
|||||||
# Allows custom skulls to be displayed. Keeping them enabled may cause a performance decrease on older/weaker devices.
|
# Allows custom skulls to be displayed. Keeping them enabled may cause a performance decrease on older/weaker devices.
|
||||||
allow-custom-skulls: true
|
allow-custom-skulls: true
|
||||||
|
|
||||||
|
# Whether to add (at this time, only) the furnace minecart as a separate item in the game, which normally does not exist in Bedrock Edition.
|
||||||
|
# This should only need to be disabled if using a proxy that does not use the "transfer packet" style of server switching.
|
||||||
|
# If this is disabled, furnace minecart items will be mapped to hopper minecart items.
|
||||||
|
# This option requires a restart of Geyser in order to change its setting.
|
||||||
|
add-non-bedrock-items: true
|
||||||
|
|
||||||
# Bedrock prevents building and displaying blocks above Y127 in the Nether -
|
# Bedrock prevents building and displaying blocks above Y127 in the Nether -
|
||||||
# enabling this config option works around that by changing the Nether dimension ID
|
# enabling this config option works around that by changing the Nether dimension ID
|
||||||
# to the End ID. The main downside to this is that the sky will resemble that of
|
# to the End ID. The main downside to this is that the sky will resemble that of
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren