mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Merge branch 'master' of https://github.com/GeyserMC/Geyser into floodgate-2.0
This commit is contained in:
commit
0a1c51bdad
36 changed files with 318 additions and 111 deletions
|
@ -18,7 +18,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t
|
||||||
|
|
||||||
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have now joined us here!
|
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have now joined us here!
|
||||||
|
|
||||||
### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.210 and Minecraft Java v1.16.4 - v1.16.5.
|
### Currently supporting Minecraft Bedrock v1.16.100 - v1.16.220 and Minecraft Java v1.16.4 - v1.16.5.
|
||||||
|
|
||||||
## Setting Up
|
## Setting Up
|
||||||
Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser.
|
Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set up Geyser.
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.CloudburstMC.Protocol</groupId>
|
<groupId>com.github.CloudburstMC.Protocol</groupId>
|
||||||
<artifactId>bedrock-v428</artifactId>
|
<artifactId>bedrock-v431</artifactId>
|
||||||
<version>42da92f</version>
|
<version>f8ecf54</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
|
|
|
@ -208,7 +208,7 @@ public class GeyserConnector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CooldownUtils.setShowCooldown(config.isShowCooldown());
|
CooldownUtils.setShowCooldown(config.getShowCooldown());
|
||||||
DimensionUtils.changeBedrockNetherId(config.isAboveBedrockNetherBuilding()); // Apply End dimension ID workaround to Nether
|
DimensionUtils.changeBedrockNetherId(config.isAboveBedrockNetherBuilding()); // Apply End dimension ID workaround to Nether
|
||||||
SkullBlockEntityTranslator.ALLOW_CUSTOM_SKULLS = config.isAllowCustomSkulls();
|
SkullBlockEntityTranslator.ALLOW_CUSTOM_SKULLS = config.isAllowCustomSkulls();
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ package org.geysermc.connector.command.defaults;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.geysermc.common.PlatformType;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandSender;
|
import org.geysermc.connector.command.CommandSender;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
@ -56,6 +57,12 @@ public class DumpCommand extends GeyserCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(GeyserSession session, CommandSender sender, String[] args) {
|
public void execute(GeyserSession session, CommandSender sender, String[] args) {
|
||||||
|
// Only allow the console to create dumps on Geyser Standalone
|
||||||
|
if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) {
|
||||||
|
sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boolean showSensitive = false;
|
boolean showSensitive = false;
|
||||||
boolean offlineDump = false;
|
boolean offlineDump = false;
|
||||||
if (args.length >= 1) {
|
if (args.length >= 1) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandSender;
|
import org.geysermc.connector.command.CommandSender;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
@ -47,6 +48,7 @@ public class StopCommand extends GeyserCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(GeyserSession session, CommandSender sender, String[] args) {
|
public void execute(GeyserSession session, CommandSender sender, String[] args) {
|
||||||
if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) {
|
if (!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE) {
|
||||||
|
sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", sender.getLocale()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ package org.geysermc.connector.command.defaults;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.MinecraftConstants;
|
import com.github.steveice10.mc.protocol.MinecraftConstants;
|
||||||
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
||||||
|
import org.geysermc.common.PlatformType;
|
||||||
import org.geysermc.connector.GeyserConnector;
|
import org.geysermc.connector.GeyserConnector;
|
||||||
import org.geysermc.connector.command.CommandSender;
|
import org.geysermc.connector.command.CommandSender;
|
||||||
import org.geysermc.connector.command.GeyserCommand;
|
import org.geysermc.connector.command.GeyserCommand;
|
||||||
|
@ -45,8 +46,12 @@ import java.util.Properties;
|
||||||
|
|
||||||
public class VersionCommand extends GeyserCommand {
|
public class VersionCommand extends GeyserCommand {
|
||||||
|
|
||||||
|
private final GeyserConnector connector;
|
||||||
|
|
||||||
public VersionCommand(GeyserConnector connector, String name, String description, String permission) {
|
public VersionCommand(GeyserConnector connector, String name, String description, String permission) {
|
||||||
super(name, description, permission);
|
super(name, description, permission);
|
||||||
|
|
||||||
|
this.connector = connector;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -61,9 +66,9 @@ public class VersionCommand extends GeyserCommand {
|
||||||
|
|
||||||
sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.commands.version.version", sender.getLocale(), GeyserConnector.NAME, GeyserConnector.VERSION, GeyserConnector.MINECRAFT_VERSION, bedrockVersions));
|
sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.commands.version.version", sender.getLocale(), GeyserConnector.NAME, GeyserConnector.VERSION, GeyserConnector.MINECRAFT_VERSION, bedrockVersions));
|
||||||
|
|
||||||
// Disable update checking in dev mode
|
// Disable update checking in dev mode and for players in Geyser Standalone
|
||||||
//noinspection ConstantConditions - changes in production
|
//noinspection ConstantConditions - changes in production
|
||||||
if (!GeyserConnector.VERSION.equals("DEV")) {
|
if (!GeyserConnector.VERSION.equals("DEV") && !(!sender.isConsole() && connector.getPlatformType() == PlatformType.STANDALONE)) {
|
||||||
sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.commands.version.checking", sender.getLocale()));
|
sender.sendMessage(LanguageUtils.getPlayerLocaleString("geyser.commands.version.checking", sender.getLocale()));
|
||||||
try {
|
try {
|
||||||
Properties gitProp = new Properties();
|
Properties gitProp = new Properties();
|
||||||
|
|
|
@ -73,7 +73,7 @@ public interface GeyserConfiguration {
|
||||||
|
|
||||||
boolean isAllowThirdPartyEars();
|
boolean isAllowThirdPartyEars();
|
||||||
|
|
||||||
boolean isShowCooldown();
|
String getShowCooldown();
|
||||||
|
|
||||||
boolean isShowCoordinates();
|
boolean isShowCoordinates();
|
||||||
|
|
||||||
|
@ -81,6 +81,8 @@ public interface GeyserConfiguration {
|
||||||
|
|
||||||
Path getFloodgateKeyPath();
|
Path getFloodgateKeyPath();
|
||||||
|
|
||||||
|
boolean isAddNonBedrockItems();
|
||||||
|
|
||||||
boolean isAboveBedrockNetherBuilding();
|
boolean isAboveBedrockNetherBuilding();
|
||||||
|
|
||||||
boolean isCacheChunks();
|
boolean isCacheChunks();
|
||||||
|
|
|
@ -95,7 +95,7 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
|
||||||
private boolean allowThirdPartyCapes = true;
|
private boolean allowThirdPartyCapes = true;
|
||||||
|
|
||||||
@JsonProperty("show-cooldown")
|
@JsonProperty("show-cooldown")
|
||||||
private boolean showCooldown = true;
|
private String showCooldown = "title";
|
||||||
|
|
||||||
@JsonProperty("show-coordinates")
|
@JsonProperty("show-coordinates")
|
||||||
private boolean showCoordinates = true;
|
private boolean showCoordinates = true;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ public class ItemFrameEntity extends Entity {
|
||||||
if (itemData.getTag() != null) {
|
if (itemData.getTag() != null) {
|
||||||
builder.put("tag", itemData.getTag().toBuilder().build());
|
builder.put("tag", itemData.getTag().toBuilder().build());
|
||||||
}
|
}
|
||||||
builder.putShort("Damage", itemData.getDamage());
|
builder.putShort("Damage", (short) itemData.getDamage());
|
||||||
builder.putString("Name", itemEntry.getBedrockIdentifier());
|
builder.putString("Name", itemEntry.getBedrockIdentifier());
|
||||||
NbtMapBuilder tag = getDefaultTag().toBuilder();
|
NbtMapBuilder tag = getDefaultTag().toBuilder();
|
||||||
tag.put("Item", builder.build());
|
tag.put("Item", builder.build());
|
||||||
|
|
|
@ -56,9 +56,12 @@ public class LlamaEntity extends ChestedHorseEntity {
|
||||||
// -1 means no armor
|
// -1 means no armor
|
||||||
if ((int) entityMetadata.getValue() != -1) {
|
if ((int) entityMetadata.getValue() != -1) {
|
||||||
// The damage value is the dye color that Java sends us
|
// The damage value is the dye color that Java sends us
|
||||||
// Always going to be a carpet so we can hardcode 171 in BlockTranslator
|
// The item is always going to be a carpet
|
||||||
// The int then short conversion is required or we get a ClassCastException
|
equipmentPacket.setChestplate(ItemData.builder()
|
||||||
equipmentPacket.setChestplate(ItemData.of(BlockTranslator.CARPET, (short) ((int) entityMetadata.getValue()), 1));
|
.id(BlockTranslator.CARPET)
|
||||||
|
.damage((int) entityMetadata.getValue())
|
||||||
|
.count(1)
|
||||||
|
.build());
|
||||||
} else {
|
} else {
|
||||||
equipmentPacket.setChestplate(ItemData.AIR);
|
equipmentPacket.setChestplate(ItemData.AIR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,7 @@ public class GeyserItemStack {
|
||||||
public ItemData getItemData(GeyserSession session) {
|
public ItemData getItemData(GeyserSession session) {
|
||||||
ItemData itemData = ItemTranslator.translateToBedrock(session, getItemStack());
|
ItemData itemData = ItemTranslator.translateToBedrock(session, getItemStack());
|
||||||
itemData.setNetId(getNetId());
|
itemData.setNetId(getNetId());
|
||||||
|
itemData.setUsingNetId(true); // Seems silly - this should probably be on the protocol level
|
||||||
return itemData;
|
return itemData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import com.nukkitx.protocol.bedrock.BedrockPacketCodec;
|
||||||
import com.nukkitx.protocol.bedrock.v419.Bedrock_v419;
|
import com.nukkitx.protocol.bedrock.v419.Bedrock_v419;
|
||||||
import com.nukkitx.protocol.bedrock.v422.Bedrock_v422;
|
import com.nukkitx.protocol.bedrock.v422.Bedrock_v422;
|
||||||
import com.nukkitx.protocol.bedrock.v428.Bedrock_v428;
|
import com.nukkitx.protocol.bedrock.v428.Bedrock_v428;
|
||||||
|
import com.nukkitx.protocol.bedrock.v431.Bedrock_v431;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -55,6 +56,7 @@ public class BedrockProtocol {
|
||||||
.minecraftVersion("1.16.200/1.16.201")
|
.minecraftVersion("1.16.200/1.16.201")
|
||||||
.build());
|
.build());
|
||||||
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
|
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
|
||||||
|
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v431.V431_CODEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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.LanguageUtils;
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
|
@ -137,6 +139,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;
|
||||||
|
|
||||||
|
|
|
@ -455,6 +455,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();
|
||||||
|
@ -475,11 +481,10 @@ public class GeyserSession implements CommandSender {
|
||||||
|
|
||||||
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
UpdateAttributesPacket attributesPacket = new UpdateAttributesPacket();
|
||||||
attributesPacket.setRuntimeEntityId(getPlayerEntity().getGeyserId());
|
attributesPacket.setRuntimeEntityId(getPlayerEntity().getGeyserId());
|
||||||
List<AttributeData> attributes = new ArrayList<>();
|
|
||||||
// Default move speed
|
// Default move speed
|
||||||
// Bedrock clients move very fast by default until they get an attribute packet correcting the speed
|
// Bedrock clients move very fast by default until they get an attribute packet correcting the speed
|
||||||
attributes.add(new AttributeData("minecraft:movement", 0.0f, 1024f, 0.1f, 0.1f));
|
attributesPacket.setAttributes(Collections.singletonList(
|
||||||
attributesPacket.setAttributes(attributes);
|
new AttributeData("minecraft:movement", 0.0f, 1024f, 0.1f, 0.1f)));
|
||||||
upstream.sendPacket(attributesPacket);
|
upstream.sendPacket(attributesPacket);
|
||||||
|
|
||||||
GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket();
|
GameRulesChangedPacket gamerulePacket = new GameRulesChangedPacket();
|
||||||
|
@ -1145,7 +1150,7 @@ public class GeyserSession implements CommandSender {
|
||||||
noClip = gameMode == GameMode.SPECTATOR;
|
noClip = gameMode == GameMode.SPECTATOR;
|
||||||
worldImmutable = gameMode == GameMode.ADVENTURE || gameMode == GameMode.SPECTATOR;
|
worldImmutable = gameMode == GameMode.ADVENTURE || gameMode == GameMode.SPECTATOR;
|
||||||
|
|
||||||
Set<AdventureSetting> flags = new HashSet<>();
|
Set<AdventureSetting> flags = adventureSettingsPacket.getSettings();
|
||||||
if (canFly) {
|
if (canFly) {
|
||||||
flags.add(AdventureSetting.MAY_FLY);
|
flags.add(AdventureSetting.MAY_FLY);
|
||||||
}
|
}
|
||||||
|
@ -1164,7 +1169,6 @@ public class GeyserSession implements CommandSender {
|
||||||
|
|
||||||
flags.add(AdventureSetting.AUTO_JUMP);
|
flags.add(AdventureSetting.AUTO_JUMP);
|
||||||
|
|
||||||
adventureSettingsPacket.getSettings().addAll(flags);
|
|
||||||
sendUpstreamPacket(adventureSettingsPacket);
|
sendUpstreamPacket(adventureSettingsPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,23 +28,32 @@ package org.geysermc.connector.network.translators.item;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator1_16_210;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@ToString
|
@ToString
|
||||||
public class ItemEntry {
|
public class ItemEntry {
|
||||||
|
|
||||||
public static ItemEntry AIR = new ItemEntry("minecraft:air", "minecraft:air", 0, 0, 0, false, 64);
|
public static ItemEntry AIR = new ItemEntry("minecraft:air", "minecraft:air", 0, 0, 0,
|
||||||
|
BlockTranslator1_16_210.INSTANCE.getBedrockAirId(), 64);
|
||||||
|
|
||||||
private final String javaIdentifier;
|
private final String javaIdentifier;
|
||||||
private final String bedrockIdentifier;
|
private final String bedrockIdentifier;
|
||||||
private final int javaId;
|
private final int javaId;
|
||||||
private final int bedrockId;
|
private final int bedrockId;
|
||||||
private final int bedrockData;
|
private final int bedrockData;
|
||||||
|
/**
|
||||||
private final boolean block;
|
* The Bedrock block runtime ID to render this item with. The specific state *does* matter in how this item is rendered.
|
||||||
|
* Required since 1.16.220.
|
||||||
|
*/
|
||||||
|
private final int bedrockBlockId;
|
||||||
private final int stackSize;
|
private final int stackSize;
|
||||||
|
|
||||||
|
public boolean isBlock() {
|
||||||
|
return bedrockBlockId != -1;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
return obj == this || (obj instanceof ItemEntry && ((ItemEntry) obj).getBedrockId() == this.getBedrockId() && ((ItemEntry) obj).getJavaIdentifier().equals(this.getJavaIdentifier()));
|
return obj == this || (obj instanceof ItemEntry && ((ItemEntry) obj).getBedrockId() == this.getBedrockId() && ((ItemEntry) obj).getJavaIdentifier().equals(this.getJavaIdentifier()));
|
||||||
|
|
|
@ -28,15 +28,21 @@ 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.network.translators.world.block.BlockTranslator1_16_210;
|
||||||
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 +61,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 +112,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 +160,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) {
|
||||||
|
@ -160,54 +177,64 @@ public class ItemRegistry {
|
||||||
}
|
}
|
||||||
JsonNode stackSizeNode = entry.getValue().get("stack_size");
|
JsonNode stackSizeNode = entry.getValue().get("stack_size");
|
||||||
int stackSize = stackSizeNode == null ? 64 : stackSizeNode.intValue();
|
int stackSize = stackSizeNode == null ? 64 : stackSizeNode.intValue();
|
||||||
|
|
||||||
|
int bedrockBlockId = -1;
|
||||||
|
JsonNode blockRuntimeIdNode = entry.getValue().get("blockRuntimeId");
|
||||||
|
if (blockRuntimeIdNode != null) {
|
||||||
|
bedrockBlockId = BlockTranslator1_16_210.INSTANCE.getBedrockBlockId(blockRuntimeIdNode.intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemEntry itemEntry;
|
||||||
if (entry.getValue().has("tool_type")) {
|
if (entry.getValue().has("tool_type")) {
|
||||||
if (entry.getValue().has("tool_tier")) {
|
if (entry.getValue().has("tool_tier")) {
|
||||||
ITEM_ENTRIES.put(itemIndex, new ToolItemEntry(
|
itemEntry = new ToolItemEntry(
|
||||||
entry.getKey(), bedrockIdentifier, itemIndex, bedrockId,
|
entry.getKey(), bedrockIdentifier, itemIndex, bedrockId,
|
||||||
entry.getValue().get("bedrock_data").intValue(),
|
entry.getValue().get("bedrock_data").intValue(),
|
||||||
entry.getValue().get("tool_type").textValue(),
|
entry.getValue().get("tool_type").textValue(),
|
||||||
entry.getValue().get("tool_tier").textValue(),
|
entry.getValue().get("tool_tier").textValue(),
|
||||||
entry.getValue().get("is_block").booleanValue(),
|
bedrockBlockId,
|
||||||
stackSize));
|
stackSize);
|
||||||
} else {
|
} else {
|
||||||
ITEM_ENTRIES.put(itemIndex, new ToolItemEntry(
|
itemEntry = new ToolItemEntry(
|
||||||
entry.getKey(), bedrockIdentifier, itemIndex, bedrockId,
|
entry.getKey(), bedrockIdentifier, itemIndex, bedrockId,
|
||||||
entry.getValue().get("bedrock_data").intValue(),
|
entry.getValue().get("bedrock_data").intValue(),
|
||||||
entry.getValue().get("tool_type").textValue(),
|
entry.getValue().get("tool_type").textValue(),
|
||||||
"", entry.getValue().get("is_block").booleanValue(),
|
"", bedrockBlockId,
|
||||||
stackSize));
|
stackSize);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ITEM_ENTRIES.put(itemIndex, new ItemEntry(
|
itemEntry = new ItemEntry(
|
||||||
entry.getKey(), bedrockIdentifier, itemIndex, bedrockId,
|
entry.getKey(), bedrockIdentifier, itemIndex, bedrockId,
|
||||||
entry.getValue().get("bedrock_data").intValue(),
|
entry.getValue().get("bedrock_data").intValue(),
|
||||||
entry.getValue().get("is_block").booleanValue(),
|
bedrockBlockId,
|
||||||
stackSize));
|
stackSize);
|
||||||
}
|
}
|
||||||
|
ITEM_ENTRIES.put(itemIndex, itemEntry);
|
||||||
|
|
||||||
switch (entry.getKey()) {
|
switch (entry.getKey()) {
|
||||||
case "minecraft:barrier":
|
case "minecraft:barrier":
|
||||||
BARRIER_INDEX = itemIndex;
|
BARRIER_INDEX = itemIndex;
|
||||||
break;
|
break;
|
||||||
case "minecraft:bamboo":
|
case "minecraft:bamboo":
|
||||||
BAMBOO = ITEM_ENTRIES.get(itemIndex);
|
BAMBOO = itemEntry;
|
||||||
break;
|
break;
|
||||||
case "minecraft:egg":
|
case "minecraft:egg":
|
||||||
EGG = ITEM_ENTRIES.get(itemIndex);
|
EGG = itemEntry;
|
||||||
break;
|
break;
|
||||||
case "minecraft:gold_ingot":
|
case "minecraft:gold_ingot":
|
||||||
GOLD = ITEM_ENTRIES.get(itemIndex);
|
GOLD = itemEntry;
|
||||||
break;
|
break;
|
||||||
case "minecraft:shield":
|
case "minecraft:shield":
|
||||||
SHIELD = ITEM_ENTRIES.get(itemIndex);
|
SHIELD = itemEntry;
|
||||||
break;
|
break;
|
||||||
case "minecraft:milk_bucket":
|
case "minecraft:milk_bucket":
|
||||||
MILK_BUCKET = ITEM_ENTRIES.get(itemIndex);
|
MILK_BUCKET = itemEntry;
|
||||||
break;
|
break;
|
||||||
case "minecraft:wheat":
|
case "minecraft:wheat":
|
||||||
WHEAT = ITEM_ENTRIES.get(itemIndex);
|
WHEAT = itemEntry;
|
||||||
break;
|
break;
|
||||||
case "minecraft:writable_book":
|
case "minecraft:writable_book":
|
||||||
WRITABLE_BOOK = ITEM_ENTRIES.get(itemIndex);
|
WRITABLE_BOOK = itemEntry;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -224,13 +251,16 @@ 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!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the loadstone compass since it doesn't exist on java but we need it for item conversion
|
// Add the loadstone compass since it doesn't exist on java but we need it for item conversion
|
||||||
ITEM_ENTRIES.put(itemIndex, new ItemEntry("minecraft:lodestone_compass", "minecraft:lodestone_compass", itemIndex,
|
ITEM_ENTRIES.put(itemIndex, new ItemEntry("minecraft:lodestone_compass", "minecraft:lodestone_compass", itemIndex,
|
||||||
lodestoneCompassId, 0, false, 1));
|
lodestoneCompassId, 0, -1, 1));
|
||||||
|
|
||||||
/* Load creative items */
|
/* Load creative items */
|
||||||
stream = FileUtils.getResource("bedrock/creative_items.json");
|
stream = FileUtils.getResource("bedrock/creative_items.json");
|
||||||
|
@ -242,12 +272,70 @@ public class ItemRegistry {
|
||||||
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e);
|
throw new AssertionError(LanguageUtils.getLocaleStringLog("geyser.toolbox.fail.creative"), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
int netId = 1;
|
int netId = 1;
|
||||||
List<ItemData> creativeItems = new ArrayList<>();
|
List<ItemData> creativeItems = new ArrayList<>();
|
||||||
for (JsonNode itemNode : creativeItemEntries) {
|
for (JsonNode itemNode : creativeItemEntries) {
|
||||||
ItemData item = getBedrockItemFromJson(itemNode);
|
ItemData.Builder item = getBedrockItemFromJson(itemNode);
|
||||||
creativeItems.add(ItemData.fromNet(netId++, item.getId(), item.getDamage(), item.getCount(), item.getTag()));
|
int bedrockRuntimeId = 0;
|
||||||
|
ItemEntry itemEntry = getItem(item.build()); // please
|
||||||
|
if (itemEntry.isBlock()) {
|
||||||
|
bedrockRuntimeId = itemEntry.getBedrockBlockId();
|
||||||
|
}
|
||||||
|
creativeItems.add(item.netId(netId++).blockRuntimeId(bedrockRuntimeId).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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, -1, 1));
|
||||||
|
creativeItems.add(ItemData.builder()
|
||||||
|
.netId(netId)
|
||||||
|
.id(furnaceMinecartId)
|
||||||
|
.count(1).build());
|
||||||
|
|
||||||
|
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]);
|
||||||
|
@ -307,11 +395,11 @@ public class ItemRegistry {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a Bedrock {@link ItemData} from a {@link JsonNode}
|
* Gets a Bedrock {@link com.nukkitx.protocol.bedrock.data.inventory.ItemData.Builder} from a {@link JsonNode}
|
||||||
* @param itemNode the JSON node that contains ProxyPass-compatible Bedrock item data
|
* @param itemNode the JSON node that contains ProxyPass-compatible Bedrock item data
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ItemData getBedrockItemFromJson(JsonNode itemNode) {
|
public static ItemData.Builder getBedrockItemFromJson(JsonNode itemNode) {
|
||||||
int count = 1;
|
int count = 1;
|
||||||
short damage = 0;
|
short damage = 0;
|
||||||
NbtMap tag = null;
|
NbtMap tag = null;
|
||||||
|
@ -330,6 +418,10 @@ public class ItemRegistry {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ItemData.of(itemNode.get("id").asInt(), damage, count, tag);
|
return ItemData.builder()
|
||||||
|
.id(itemNode.get("id").asInt())
|
||||||
|
.damage(damage)
|
||||||
|
.count(count)
|
||||||
|
.tag(tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,12 +149,15 @@ public abstract class ItemTranslator {
|
||||||
|
|
||||||
translateDisplayProperties(session, nbt);
|
translateDisplayProperties(session, nbt);
|
||||||
|
|
||||||
ItemData itemData;
|
ItemData.Builder builder;
|
||||||
ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId());
|
ItemTranslator itemStackTranslator = ITEM_STACK_TRANSLATORS.get(bedrockItem.getJavaId());
|
||||||
if (itemStackTranslator != null) {
|
if (itemStackTranslator != null) {
|
||||||
itemData = itemStackTranslator.translateToBedrock(itemStack, bedrockItem);
|
builder = itemStackTranslator.translateToBedrock(itemStack, bedrockItem);
|
||||||
} else {
|
} else {
|
||||||
itemData = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem);
|
builder = DEFAULT_TRANSLATOR.translateToBedrock(itemStack, bedrockItem);
|
||||||
|
}
|
||||||
|
if (bedrockItem.isBlock()) {
|
||||||
|
builder.blockRuntimeId(bedrockItem.getBedrockBlockId());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nbt != null) {
|
if (nbt != null) {
|
||||||
|
@ -165,10 +168,11 @@ public abstract class ItemTranslator {
|
||||||
String[] canPlace = new String[0];
|
String[] canPlace = new String[0];
|
||||||
canBreak = getCanModify(session, canDestroy, canBreak);
|
canBreak = getCanModify(session, canDestroy, canBreak);
|
||||||
canPlace = getCanModify(session, canPlaceOn, canPlace);
|
canPlace = getCanModify(session, canPlaceOn, canPlace);
|
||||||
itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), itemData.getTag(), canPlace, canBreak);
|
builder.canBreak(canBreak);
|
||||||
|
builder.canPlace(canPlace);
|
||||||
}
|
}
|
||||||
|
|
||||||
return itemData;
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -202,14 +206,19 @@ public abstract class ItemTranslator {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
|
public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
|
||||||
if (itemStack == null) {
|
if (itemStack == null) {
|
||||||
return ItemData.AIR;
|
// Return, essentially, air
|
||||||
|
return ItemData.builder();
|
||||||
}
|
}
|
||||||
if (itemStack.getNbt() == null) {
|
ItemData.Builder builder = ItemData.builder()
|
||||||
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount());
|
.id(itemEntry.getBedrockId())
|
||||||
|
.damage(itemEntry.getBedrockData())
|
||||||
|
.count(itemStack.getAmount());
|
||||||
|
if (itemStack.getNbt() != null) {
|
||||||
|
builder.tag(this.translateNbtToBedrock(itemStack.getNbt()));
|
||||||
}
|
}
|
||||||
return ItemData.of(itemEntry.getBedrockId(), (short) itemEntry.getBedrockData(), itemStack.getAmount(), this.translateNbtToBedrock(itemStack.getNbt()));
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) {
|
public ItemStack translateToJava(ItemData itemData, ItemEntry itemEntry) {
|
||||||
|
|
|
@ -91,7 +91,7 @@ public enum Potion {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Potion getByBedrockId(short bedrockId) {
|
public static Potion getByBedrockId(int bedrockId) {
|
||||||
for (Potion potion : Potion.values()) {
|
for (Potion potion : Potion.values()) {
|
||||||
if (potion.bedrockId == bedrockId) {
|
if (potion.bedrockId == bedrockId) {
|
||||||
return potion;
|
return potion;
|
||||||
|
|
|
@ -272,7 +272,11 @@ public class RecipeRegistry {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ItemData.of(itemEntry.getBedrockId(), damage, count, tag);
|
return ItemData.builder()
|
||||||
|
.id(itemEntry.getBedrockId())
|
||||||
|
.damage(damage)
|
||||||
|
.count(count)
|
||||||
|
.tag(tag).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
|
|
|
@ -100,7 +100,7 @@ public enum TippedArrowPotion {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TippedArrowPotion getByBedrockId(short bedrockId) {
|
public static TippedArrowPotion getByBedrockId(int bedrockId) {
|
||||||
for (TippedArrowPotion potion : TippedArrowPotion.values()) {
|
for (TippedArrowPotion potion : TippedArrowPotion.values()) {
|
||||||
if (potion.bedrockId == bedrockId) {
|
if (potion.bedrockId == bedrockId) {
|
||||||
return potion;
|
return potion;
|
||||||
|
|
|
@ -32,8 +32,9 @@ public class ToolItemEntry extends ItemEntry {
|
||||||
private final String toolType;
|
private final String toolType;
|
||||||
private final String toolTier;
|
private final String toolTier;
|
||||||
|
|
||||||
public ToolItemEntry(String javaIdentifier, String bedrockIdentifier, int javaId, int bedrockId, int bedrockData, String toolType, String toolTier, boolean isBlock, int stackSize) {
|
public ToolItemEntry(String javaIdentifier, String bedrockIdentifier, int javaId, int bedrockId, int bedrockData,
|
||||||
super(javaIdentifier, bedrockIdentifier, javaId, bedrockId, bedrockData, isBlock, stackSize);
|
String toolType, String toolTier, int bedrockBlockId, int stackSize) {
|
||||||
|
super(javaIdentifier, bedrockIdentifier, javaId, bedrockId, bedrockData, bedrockBlockId, stackSize);
|
||||||
this.toolType = toolType;
|
this.toolType = toolType;
|
||||||
this.toolTier = toolTier;
|
this.toolTier = toolTier;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,30 +153,30 @@ public class BannerTranslator extends ItemTranslator {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
|
public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
|
||||||
if (itemStack.getNbt() == null) {
|
if (itemStack.getNbt() == null) {
|
||||||
return super.translateToBedrock(itemStack, itemEntry);
|
return super.translateToBedrock(itemStack, itemEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemData itemData = super.translateToBedrock(itemStack, itemEntry);
|
ItemData.Builder builder = super.translateToBedrock(itemStack, itemEntry);
|
||||||
|
|
||||||
CompoundTag blockEntityTag = itemStack.getNbt().get("BlockEntityTag");
|
CompoundTag blockEntityTag = itemStack.getNbt().get("BlockEntityTag");
|
||||||
if (blockEntityTag != null && blockEntityTag.contains("Patterns")) {
|
if (blockEntityTag != null && blockEntityTag.contains("Patterns")) {
|
||||||
ListTag patterns = blockEntityTag.get("Patterns");
|
ListTag patterns = blockEntityTag.get("Patterns");
|
||||||
|
|
||||||
NbtMapBuilder builder = itemData.getTag().toBuilder();
|
NbtMapBuilder nbtBuilder = builder.build().getTag().toBuilder(); //TODO fix ugly hack
|
||||||
if (patterns.equals(OMINOUS_BANNER_PATTERN)) {
|
if (patterns.equals(OMINOUS_BANNER_PATTERN)) {
|
||||||
// Remove the current patterns and set the ominous banner type
|
// Remove the current patterns and set the ominous banner type
|
||||||
builder.remove("Patterns");
|
nbtBuilder.remove("Patterns");
|
||||||
builder.putInt("Type", 1);
|
nbtBuilder.putInt("Type", 1);
|
||||||
} else {
|
} else {
|
||||||
builder.put("Patterns", convertBannerPattern(patterns));
|
nbtBuilder.put("Patterns", convertBannerPattern(patterns));
|
||||||
}
|
}
|
||||||
|
|
||||||
itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.build());
|
builder.tag(nbtBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
return itemData;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class CompassTranslator extends ItemTranslator {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
|
public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
|
||||||
if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry);
|
if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry);
|
||||||
|
|
||||||
Tag lodestoneTag = itemStack.getNbt().get("LodestoneTracked");
|
Tag lodestoneTag = itemStack.getNbt().get("LodestoneTracked");
|
||||||
|
@ -75,9 +75,7 @@ public class CompassTranslator extends ItemTranslator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemData itemData = super.translateToBedrock(itemStack, itemEntry);
|
return super.translateToBedrock(itemStack, itemEntry);
|
||||||
|
|
||||||
return itemData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -49,13 +49,17 @@ public class PotionTranslator extends ItemTranslator {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
|
public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
|
||||||
if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry);
|
if (itemStack.getNbt() == null) return super.translateToBedrock(itemStack, itemEntry);
|
||||||
Tag potionTag = itemStack.getNbt().get("Potion");
|
Tag potionTag = itemStack.getNbt().get("Potion");
|
||||||
if (potionTag instanceof StringTag) {
|
if (potionTag instanceof StringTag) {
|
||||||
Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue());
|
Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue());
|
||||||
if (potion != null) {
|
if (potion != null) {
|
||||||
return ItemData.of(itemEntry.getBedrockId(), potion.getBedrockId(), itemStack.getAmount(), translateNbtToBedrock(itemStack.getNbt()));
|
return ItemData.builder()
|
||||||
|
.id(itemEntry.getBedrockId())
|
||||||
|
.damage(potion.getBedrockId())
|
||||||
|
.count(itemStack.getAmount())
|
||||||
|
.tag(translateNbtToBedrock(itemStack.getNbt()));
|
||||||
}
|
}
|
||||||
GeyserConnector.getInstance().getLogger().debug("Unknown Java potion: " + potionTag.getValue());
|
GeyserConnector.getInstance().getLogger().debug("Unknown Java potion: " + potionTag.getValue());
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class TippedArrowTranslator extends ItemTranslator {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemData translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
|
public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemEntry itemEntry) {
|
||||||
if (!itemEntry.getJavaIdentifier().equals("minecraft:tipped_arrow") || itemStack.getNbt() == null) {
|
if (!itemEntry.getJavaIdentifier().equals("minecraft:tipped_arrow") || itemStack.getNbt() == null) {
|
||||||
// We're only concerned about minecraft:arrow when translating Bedrock -> Java
|
// We're only concerned about minecraft:arrow when translating Bedrock -> Java
|
||||||
return super.translateToBedrock(itemStack, itemEntry);
|
return super.translateToBedrock(itemStack, itemEntry);
|
||||||
|
@ -61,7 +61,11 @@ public class TippedArrowTranslator extends ItemTranslator {
|
||||||
if (potionTag instanceof StringTag) {
|
if (potionTag instanceof StringTag) {
|
||||||
TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue());
|
TippedArrowPotion tippedArrowPotion = TippedArrowPotion.getByJavaIdentifier(((StringTag) potionTag).getValue());
|
||||||
if (tippedArrowPotion != null) {
|
if (tippedArrowPotion != null) {
|
||||||
return ItemData.of(itemEntry.getBedrockId(), tippedArrowPotion.getBedrockId(), itemStack.getAmount(), translateNbtToBedrock(itemStack.getNbt()));
|
return ItemData.builder()
|
||||||
|
.id(itemEntry.getBedrockId())
|
||||||
|
.damage(tippedArrowPotion.getBedrockId())
|
||||||
|
.count(itemStack.getAmount())
|
||||||
|
.tag(translateNbtToBedrock(itemStack.getNbt()));
|
||||||
}
|
}
|
||||||
GeyserConnector.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionTag.getValue());
|
GeyserConnector.getInstance().getLogger().debug("Unknown Java potion (tipped arrow): " + potionTag.getValue());
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class CrossbowTranslator extends NbtItemStackTranslator {
|
||||||
newProjectile.put(new ByteTag("Count", (byte) itemData.getCount()));
|
newProjectile.put(new ByteTag("Count", (byte) itemData.getCount()));
|
||||||
newProjectile.put(new StringTag("Name", projectileEntry.getBedrockIdentifier()));
|
newProjectile.put(new StringTag("Name", projectileEntry.getBedrockIdentifier()));
|
||||||
|
|
||||||
newProjectile.put(new ShortTag("Damage", itemData.getDamage()));
|
newProjectile.put(new ShortTag("Damage", (short) itemData.getDamage()));
|
||||||
|
|
||||||
itemTag.put(newProjectile);
|
itemTag.put(newProjectile);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,8 @@ import com.github.steveice10.mc.protocol.data.game.command.CommandParser;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerDeclareCommandsPacket;
|
||||||
import com.nukkitx.protocol.bedrock.data.command.CommandData;
|
import com.nukkitx.protocol.bedrock.data.command.CommandData;
|
||||||
import com.nukkitx.protocol.bedrock.data.command.CommandEnumData;
|
import com.nukkitx.protocol.bedrock.data.command.CommandEnumData;
|
||||||
|
import com.nukkitx.protocol.bedrock.data.command.CommandParam;
|
||||||
import com.nukkitx.protocol.bedrock.data.command.CommandParamData;
|
import com.nukkitx.protocol.bedrock.data.command.CommandParamData;
|
||||||
import com.nukkitx.protocol.bedrock.data.command.CommandParamType;
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket;
|
import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket;
|
||||||
import it.unimi.dsi.fastutil.Hash;
|
import it.unimi.dsi.fastutil.Hash;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
@ -200,47 +200,47 @@ public class JavaDeclareCommandsTranslator extends PacketTranslator<ServerDeclar
|
||||||
*/
|
*/
|
||||||
private static Object mapCommandType(CommandParser parser) {
|
private static Object mapCommandType(CommandParser parser) {
|
||||||
if (parser == null) {
|
if (parser == null) {
|
||||||
return CommandParamType.STRING;
|
return CommandParam.STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (parser) {
|
switch (parser) {
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
case ROTATION:
|
case ROTATION:
|
||||||
case DOUBLE:
|
case DOUBLE:
|
||||||
return CommandParamType.FLOAT;
|
return CommandParam.FLOAT;
|
||||||
|
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
return CommandParamType.INT;
|
return CommandParam.INT;
|
||||||
|
|
||||||
case ENTITY:
|
case ENTITY:
|
||||||
case GAME_PROFILE:
|
case GAME_PROFILE:
|
||||||
return CommandParamType.TARGET;
|
return CommandParam.TARGET;
|
||||||
|
|
||||||
case BLOCK_POS:
|
case BLOCK_POS:
|
||||||
return CommandParamType.BLOCK_POSITION;
|
return CommandParam.BLOCK_POSITION;
|
||||||
|
|
||||||
case COLUMN_POS:
|
case COLUMN_POS:
|
||||||
case VEC3:
|
case VEC3:
|
||||||
return CommandParamType.POSITION;
|
return CommandParam.POSITION;
|
||||||
|
|
||||||
case MESSAGE:
|
case MESSAGE:
|
||||||
return CommandParamType.MESSAGE;
|
return CommandParam.MESSAGE;
|
||||||
|
|
||||||
case NBT:
|
case NBT:
|
||||||
case NBT_COMPOUND_TAG:
|
case NBT_COMPOUND_TAG:
|
||||||
case NBT_TAG:
|
case NBT_TAG:
|
||||||
case NBT_PATH:
|
case NBT_PATH:
|
||||||
return CommandParamType.JSON;
|
return CommandParam.JSON;
|
||||||
|
|
||||||
case RESOURCE_LOCATION:
|
case RESOURCE_LOCATION:
|
||||||
case FUNCTION:
|
case FUNCTION:
|
||||||
return CommandParamType.FILE_PATH;
|
return CommandParam.FILE_PATH;
|
||||||
|
|
||||||
case BOOL:
|
case BOOL:
|
||||||
return ENUM_BOOLEAN;
|
return ENUM_BOOLEAN;
|
||||||
|
|
||||||
case OPERATION: // ">=", "==", etc
|
case OPERATION: // ">=", "==", etc
|
||||||
return CommandParamType.OPERATOR;
|
return CommandParam.OPERATOR;
|
||||||
|
|
||||||
case BLOCK_STATE:
|
case BLOCK_STATE:
|
||||||
return BlockTranslator.getAllBlockIdentifiers();
|
return BlockTranslator.getAllBlockIdentifiers();
|
||||||
|
@ -261,7 +261,7 @@ public class JavaDeclareCommandsTranslator extends PacketTranslator<ServerDeclar
|
||||||
return VALID_SCOREBOARD_SLOTS;
|
return VALID_SCOREBOARD_SLOTS;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return CommandParamType.STRING;
|
return CommandParam.STRING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,11 +324,11 @@ public class JavaDeclareCommandsTranslator extends PacketTranslator<ServerDeclar
|
||||||
// Put the non-enum param into the list
|
// Put the non-enum param into the list
|
||||||
Object mappedType = mapCommandType(paramNode.getParser());
|
Object mappedType = mapCommandType(paramNode.getParser());
|
||||||
CommandEnumData enumData = null;
|
CommandEnumData enumData = null;
|
||||||
CommandParamType type = null;
|
CommandParam type = null;
|
||||||
if (mappedType instanceof String[]) {
|
if (mappedType instanceof String[]) {
|
||||||
enumData = new CommandEnumData(paramNode.getParser().name().toLowerCase(), (String[]) mappedType, false);
|
enumData = new CommandEnumData(paramNode.getParser().name().toLowerCase(), (String[]) mappedType, false);
|
||||||
} else {
|
} else {
|
||||||
type = (CommandParamType) mappedType;
|
type = (CommandParam) mappedType;
|
||||||
}
|
}
|
||||||
// IF enumData != null:
|
// IF enumData != null:
|
||||||
// In game, this will show up like <paramNode.getName(): enumData.getName()>
|
// In game, this will show up like <paramNode.getName(): enumData.getName()>
|
||||||
|
|
|
@ -69,7 +69,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
|
||||||
ShapelessRecipeData shapelessRecipeData = (ShapelessRecipeData) recipe.getData();
|
ShapelessRecipeData shapelessRecipeData = (ShapelessRecipeData) recipe.getData();
|
||||||
ItemData output = ItemTranslator.translateToBedrock(session, shapelessRecipeData.getResult());
|
ItemData output = ItemTranslator.translateToBedrock(session, shapelessRecipeData.getResult());
|
||||||
// Strip NBT - tools won't appear in the recipe book otherwise
|
// Strip NBT - tools won't appear in the recipe book otherwise
|
||||||
output = ItemData.of(output.getId(), output.getDamage(), output.getCount());
|
output = output.toBuilder().tag(null).build();
|
||||||
ItemData[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients());
|
ItemData[][] inputCombinations = combinations(session, shapelessRecipeData.getIngredients());
|
||||||
for (ItemData[] inputs : inputCombinations) {
|
for (ItemData[] inputs : inputCombinations) {
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
|
@ -83,7 +83,7 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
|
||||||
ShapedRecipeData shapedRecipeData = (ShapedRecipeData) recipe.getData();
|
ShapedRecipeData shapedRecipeData = (ShapedRecipeData) recipe.getData();
|
||||||
ItemData output = ItemTranslator.translateToBedrock(session, shapedRecipeData.getResult());
|
ItemData output = ItemTranslator.translateToBedrock(session, shapedRecipeData.getResult());
|
||||||
// See above
|
// See above
|
||||||
output = ItemData.of(output.getId(), output.getDamage(), output.getCount());
|
output = output.toBuilder().tag(null).build();
|
||||||
ItemData[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients());
|
ItemData[][] inputCombinations = combinations(session, shapedRecipeData.getIngredients());
|
||||||
for (ItemData[] inputs : inputCombinations) {
|
for (ItemData[] inputs : inputCombinations) {
|
||||||
UUID uuid = UUID.randomUUID();
|
UUID uuid = UUID.randomUUID();
|
||||||
|
@ -230,7 +230,11 @@ public class JavaDeclareRecipesTranslator extends PacketTranslator<ServerDeclare
|
||||||
if (entry.getValue().size() < idCount) {
|
if (entry.getValue().size() < idCount) {
|
||||||
optionSet.addAll(entry.getValue());
|
optionSet.addAll(entry.getValue());
|
||||||
} else {
|
} else {
|
||||||
optionSet.add(ItemData.of(groupedItem.id, Short.MAX_VALUE, groupedItem.count, groupedItem.tag));
|
optionSet.add(ItemData.builder()
|
||||||
|
.id(groupedItem.id)
|
||||||
|
.damage(Short.MAX_VALUE)
|
||||||
|
.count(groupedItem.count)
|
||||||
|
.tag(groupedItem.tag).build());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ItemData item = entry.getValue().get(0);
|
ItemData item = entry.getValue().get(0);
|
||||||
|
|
|
@ -39,10 +39,10 @@ import org.geysermc.connector.network.translators.PacketTranslator;
|
||||||
import org.geysermc.connector.network.translators.Translator;
|
import org.geysermc.connector.network.translators.Translator;
|
||||||
import org.geysermc.connector.network.translators.effect.Effect;
|
import org.geysermc.connector.network.translators.effect.Effect;
|
||||||
import org.geysermc.connector.network.translators.effect.EffectRegistry;
|
import org.geysermc.connector.network.translators.effect.EffectRegistry;
|
||||||
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
import org.geysermc.connector.utils.LocaleUtils;
|
import org.geysermc.connector.utils.LocaleUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@Translator(packet = ServerPlayEffectPacket.class)
|
@Translator(packet = ServerPlayEffectPacket.class)
|
||||||
|
@ -74,10 +74,8 @@ public class JavaPlayEffectTranslator extends PacketTranslator<ServerPlayEffectP
|
||||||
textPacket.setPlatformChatId("");
|
textPacket.setPlatformChatId("");
|
||||||
textPacket.setSourceName(null);
|
textPacket.setSourceName(null);
|
||||||
textPacket.setMessage("record.nowPlaying");
|
textPacket.setMessage("record.nowPlaying");
|
||||||
List<String> params = new ArrayList<>();
|
|
||||||
String recordString = "%item." + soundEvent.name().toLowerCase(Locale.ROOT) + ".desc";
|
String recordString = "%item." + soundEvent.name().toLowerCase(Locale.ROOT) + ".desc";
|
||||||
params.add(LocaleUtils.getLocaleString(recordString, session.getLocale()));
|
textPacket.setParameters(Collections.singletonList(LocaleUtils.getLocaleString(recordString, session.getLocale())));
|
||||||
textPacket.setParameters(params);
|
|
||||||
session.sendUpstreamPacket(textPacket);
|
session.sendUpstreamPacket(textPacket);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class JavaSpawnParticleTranslator extends PacketTranslator<ServerSpawnPar
|
||||||
ItemStack javaItem = ((ItemParticleData)packet.getParticle().getData()).getItemStack();
|
ItemStack javaItem = ((ItemParticleData)packet.getParticle().getData()).getItemStack();
|
||||||
ItemData bedrockItem = ItemTranslator.translateToBedrock(session, javaItem);
|
ItemData bedrockItem = ItemTranslator.translateToBedrock(session, javaItem);
|
||||||
int id = bedrockItem.getId();
|
int id = bedrockItem.getId();
|
||||||
short damage = bedrockItem.getDamage();
|
int damage = bedrockItem.getDamage();
|
||||||
particle.setType(LevelEventType.PARTICLE_ITEM_BREAK);
|
particle.setType(LevelEventType.PARTICLE_ITEM_BREAK);
|
||||||
particle.setData(id << 16 | damage);
|
particle.setData(id << 16 | damage);
|
||||||
particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ()));
|
particle.setPosition(Vector3f.from(packet.getX(), packet.getY(), packet.getZ()));
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class JavaTradeListTranslator extends PacketTranslator<ServerTradeListPac
|
||||||
|
|
||||||
NbtMapBuilder builder = NbtMap.builder();
|
NbtMapBuilder builder = NbtMap.builder();
|
||||||
builder.putByte("Count", (byte) (Math.max(itemData.getCount() + specialPrice, 1)));
|
builder.putByte("Count", (byte) (Math.max(itemData.getCount() + specialPrice, 1)));
|
||||||
builder.putShort("Damage", itemData.getDamage());
|
builder.putShort("Damage", (short) itemData.getDamage());
|
||||||
builder.putString("Name", itemEntry.getBedrockIdentifier());
|
builder.putString("Name", itemEntry.getBedrockIdentifier());
|
||||||
if (itemData.getTag() != null) {
|
if (itemData.getTag() != null) {
|
||||||
NbtMap tag = itemData.getTag().toBuilder().build();
|
NbtMap tag = itemData.getTag().toBuilder().build();
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
package org.geysermc.connector.utils;
|
package org.geysermc.connector.utils;
|
||||||
|
|
||||||
import com.nukkitx.protocol.bedrock.packet.SetTitlePacket;
|
import com.nukkitx.protocol.bedrock.packet.SetTitlePacket;
|
||||||
|
import lombok.Getter;
|
||||||
import org.geysermc.connector.network.session.GeyserSession;
|
import org.geysermc.connector.network.session.GeyserSession;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -35,10 +36,10 @@ import java.util.concurrent.TimeUnit;
|
||||||
* Much of the work here is from the wonderful folks from ViaRewind: https://github.com/ViaVersion/ViaRewind
|
* Much of the work here is from the wonderful folks from ViaRewind: https://github.com/ViaVersion/ViaRewind
|
||||||
*/
|
*/
|
||||||
public class CooldownUtils {
|
public class CooldownUtils {
|
||||||
private static boolean SHOW_COOLDOWN;
|
private static CooldownType SHOW_COOLDOWN;
|
||||||
|
|
||||||
public static void setShowCooldown(boolean showCooldown) {
|
public static void setShowCooldown(String showCooldown) {
|
||||||
SHOW_COOLDOWN = showCooldown;
|
SHOW_COOLDOWN = CooldownType.getByName(showCooldown);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,7 +47,7 @@ public class CooldownUtils {
|
||||||
* @param session GeyserSession
|
* @param session GeyserSession
|
||||||
*/
|
*/
|
||||||
public static void sendCooldown(GeyserSession session) {
|
public static void sendCooldown(GeyserSession session) {
|
||||||
if (!SHOW_COOLDOWN) return;
|
if (SHOW_COOLDOWN == CooldownType.DISABLED) return;
|
||||||
if (session.getAttackSpeed() == 0.0 || session.getAttackSpeed() > 20) return; // 0.0 usually happens on login and causes issues with visuals; anything above 20 means a plugin like OldCombatMechanics is being used
|
if (session.getAttackSpeed() == 0.0 || session.getAttackSpeed() > 20) return; // 0.0 usually happens on login and causes issues with visuals; anything above 20 means a plugin like OldCombatMechanics is being used
|
||||||
// Needs to be sent or no subtitle packet is recognized by the client
|
// Needs to be sent or no subtitle packet is recognized by the client
|
||||||
SetTitlePacket titlePacket = new SetTitlePacket();
|
SetTitlePacket titlePacket = new SetTitlePacket();
|
||||||
|
@ -67,7 +68,11 @@ public class CooldownUtils {
|
||||||
if (session.isClosed()) return; // Don't run scheduled tasks if the client left
|
if (session.isClosed()) return; // Don't run scheduled tasks if the client left
|
||||||
if (lastHitTime != session.getLastHitTime()) return; // Means another cooldown has started so there's no need to continue this one
|
if (lastHitTime != session.getLastHitTime()) return; // Means another cooldown has started so there's no need to continue this one
|
||||||
SetTitlePacket titlePacket = new SetTitlePacket();
|
SetTitlePacket titlePacket = new SetTitlePacket();
|
||||||
titlePacket.setType(SetTitlePacket.Type.SUBTITLE);
|
if (SHOW_COOLDOWN == CooldownType.ACTIONBAR) {
|
||||||
|
titlePacket.setType(SetTitlePacket.Type.ACTIONBAR);
|
||||||
|
} else {
|
||||||
|
titlePacket.setType(SetTitlePacket.Type.SUBTITLE);
|
||||||
|
}
|
||||||
titlePacket.setText(getTitle(session));
|
titlePacket.setText(getTitle(session));
|
||||||
titlePacket.setFadeInTime(0);
|
titlePacket.setFadeInTime(0);
|
||||||
titlePacket.setFadeOutTime(5);
|
titlePacket.setFadeOutTime(5);
|
||||||
|
@ -77,7 +82,11 @@ public class CooldownUtils {
|
||||||
session.getConnector().getGeneralThreadPool().schedule(() -> computeCooldown(session, lastHitTime), 50, TimeUnit.MILLISECONDS); // Updated per tick. 1000 divided by 20 ticks equals 50
|
session.getConnector().getGeneralThreadPool().schedule(() -> computeCooldown(session, lastHitTime), 50, TimeUnit.MILLISECONDS); // Updated per tick. 1000 divided by 20 ticks equals 50
|
||||||
} else {
|
} else {
|
||||||
SetTitlePacket removeTitlePacket = new SetTitlePacket();
|
SetTitlePacket removeTitlePacket = new SetTitlePacket();
|
||||||
removeTitlePacket.setType(SetTitlePacket.Type.SUBTITLE);
|
if (SHOW_COOLDOWN == CooldownType.ACTIONBAR) {
|
||||||
|
removeTitlePacket.setType(SetTitlePacket.Type.ACTIONBAR);
|
||||||
|
} else {
|
||||||
|
removeTitlePacket.setType(SetTitlePacket.Type.SUBTITLE);
|
||||||
|
}
|
||||||
removeTitlePacket.setText(" ");
|
removeTitlePacket.setText(" ");
|
||||||
session.sendUpstreamPacket(removeTitlePacket);
|
session.sendUpstreamPacket(removeTitlePacket);
|
||||||
}
|
}
|
||||||
|
@ -114,4 +123,33 @@ public class CooldownUtils {
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum CooldownType {
|
||||||
|
TITLE,
|
||||||
|
ACTIONBAR,
|
||||||
|
DISABLED;
|
||||||
|
|
||||||
|
public static final CooldownType[] VALUES = values();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the CooldownType string (from config) to the enum, TITLE on fail
|
||||||
|
*
|
||||||
|
* @param name CooldownType string
|
||||||
|
*
|
||||||
|
* @return The converted CooldownType
|
||||||
|
*/
|
||||||
|
public static CooldownType getByName(String name) {
|
||||||
|
if (name.equalsIgnoreCase("true")) { // Backwards config compatibility
|
||||||
|
return CooldownType.TITLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (CooldownType type : VALUES) {
|
||||||
|
if (type.name().equalsIgnoreCase(name)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DISABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,9 +69,9 @@ public enum FireworkColor {
|
||||||
private static final FireworkColor[] VALUES = values();
|
private static final FireworkColor[] VALUES = values();
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private byte bedrockID;
|
private final byte bedrockID;
|
||||||
@Getter
|
@Getter
|
||||||
private int javaID;
|
private final int javaID;
|
||||||
|
|
||||||
FireworkColor(byte bedrockID, int javaID) {
|
FireworkColor(byte bedrockID, int javaID) {
|
||||||
this.bedrockID = bedrockID;
|
this.bedrockID = bedrockID;
|
||||||
|
|
|
@ -164,7 +164,10 @@ public class InventoryUtils {
|
||||||
display.putList("Lore", NbtType.STRING, Collections.singletonList(ChatColor.RESET + ChatColor.DARK_PURPLE + description));
|
display.putList("Lore", NbtType.STRING, Collections.singletonList(ChatColor.RESET + ChatColor.DARK_PURPLE + description));
|
||||||
|
|
||||||
root.put("display", display.build());
|
root.put("display", display.build());
|
||||||
return ItemData.of(ItemRegistry.ITEM_ENTRIES.get(ItemRegistry.BARRIER_INDEX).getBedrockId(), (short) 0, 1, root.build());
|
return ItemData.builder()
|
||||||
|
.id(ItemRegistry.ITEM_ENTRIES.get(ItemRegistry.BARRIER_INDEX).getBedrockId())
|
||||||
|
.count(1)
|
||||||
|
.tag(root.build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -112,7 +112,8 @@ allow-third-party-capes: true
|
||||||
allow-third-party-ears: false
|
allow-third-party-ears: false
|
||||||
|
|
||||||
# Allow a fake cooldown indicator to be sent. Bedrock players do not see a cooldown as they still use 1.8 combat
|
# Allow a fake cooldown indicator to be sent. Bedrock players do not see a cooldown as they still use 1.8 combat
|
||||||
show-cooldown: true
|
# Can be title, actionbar or false
|
||||||
|
show-cooldown: title
|
||||||
|
|
||||||
# Controls if coordinates are shown to players.
|
# Controls if coordinates are shown to players.
|
||||||
show-coordinates: true
|
show-coordinates: true
|
||||||
|
@ -139,6 +140,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
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 216e9008678a761b3885808f4f3d43000404381b
|
Subproject commit c846b8200eb8ebb37207666f7eddb83f2b636c37
|
Loading…
Reference in a new issue