forked from GeyserMC/Geyser
Fix NPE in console when a sound was missing and clean up nesting
This commit is contained in:
commit
497825dd96
24 changed files with 346 additions and 90 deletions
|
@ -33,7 +33,7 @@
|
|||
<dependency>
|
||||
<groupId>com.nukkitx.protocol</groupId>
|
||||
<artifactId>bedrock-v390</artifactId>
|
||||
<version>2.5.5-SNAPSHOT</version>
|
||||
<version>2.5.6-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
|
@ -117,7 +117,7 @@
|
|||
<dependency>
|
||||
<groupId>com.github.steveice10</groupId>
|
||||
<artifactId>mcauthlib</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<version>1.3-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -145,5 +145,23 @@
|
|||
<artifactId>reflections</artifactId>
|
||||
<version>0.9.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>text-api</artifactId>
|
||||
<version>3.0.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>text-serializer-gson</artifactId>
|
||||
<version>3.0.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>text-serializer-legacy</artifactId>
|
||||
<version>3.0.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -28,10 +28,7 @@ package org.geysermc.connector.command;
|
|||
import lombok.Getter;
|
||||
import org.geysermc.common.command.ICommandManager;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.defaults.HelpCommand;
|
||||
import org.geysermc.connector.command.defaults.ListCommand;
|
||||
import org.geysermc.connector.command.defaults.ReloadCommand;
|
||||
import org.geysermc.connector.command.defaults.StopCommand;
|
||||
import org.geysermc.connector.command.defaults.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -51,6 +48,7 @@ public abstract class CommandManager implements ICommandManager {
|
|||
registerCommand(new ListCommand(connector, "list", "List all players connected through Geyser.", "geyser.command.list"));
|
||||
registerCommand(new ReloadCommand(connector, "reload", "Reloads the Geyser configurations. Kicks all players when used!", "geyser.command.reload"));
|
||||
registerCommand(new StopCommand(connector, "stop", "Shuts down Geyser.", "geyser.command.stop"));
|
||||
registerCommand(new OffhandCommand(connector, "offhand", "Puts an items in your offhand.", "geyser.command.offhand"));
|
||||
}
|
||||
|
||||
public void registerCommand(GeyserCommand command) {
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 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.connector.command.defaults;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
|
||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.command.CommandSender;
|
||||
import org.geysermc.connector.command.GeyserCommand;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
||||
public class OffhandCommand extends GeyserCommand {
|
||||
|
||||
private GeyserConnector connector;
|
||||
|
||||
public OffhandCommand(GeyserConnector connector, String name, String description, String permission) {
|
||||
super(name, description, permission);
|
||||
|
||||
this.connector = connector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if (sender.isConsole()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the sender is a Bedrock edition client
|
||||
if (sender instanceof GeyserSession) {
|
||||
GeyserSession session = (GeyserSession) sender;
|
||||
ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.SWAP_HANDS, new Position(0,0,0),
|
||||
BlockFace.DOWN);
|
||||
session.getDownstream().getSession().send(releaseItemPacket);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -48,7 +48,7 @@ public class ReloadCommand extends GeyserCommand {
|
|||
}
|
||||
sender.sendMessage(ChatColor.YELLOW + "Reloading Geyser configurations... all connected bedrock clients will be kicked.");
|
||||
for (GeyserSession session : connector.getPlayers().values()) {
|
||||
session.getUpstream().disconnect("Geyser has been reloaded... sorry for the inconvenience!");
|
||||
session.disconnect("Geyser has been reloaded... sorry for the inconvenience!");
|
||||
}
|
||||
connector.reload();
|
||||
}
|
||||
|
|
|
@ -27,12 +27,15 @@ package org.geysermc.connector.entity;
|
|||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
|
||||
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
|
||||
import com.github.steveice10.mc.protocol.data.message.TextMessage;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerUseItemPacket;
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityData;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityDataMap;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
||||
import com.nukkitx.protocol.bedrock.data.EntityFlags;
|
||||
import com.nukkitx.protocol.bedrock.data.*;
|
||||
import com.nukkitx.protocol.bedrock.packet.*;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
|
@ -45,6 +48,7 @@ import org.geysermc.connector.entity.attribute.Attribute;
|
|||
import org.geysermc.connector.entity.attribute.AttributeType;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
import org.geysermc.connector.utils.AttributeUtils;
|
||||
import org.geysermc.connector.utils.MessageUtils;
|
||||
|
||||
|
@ -199,6 +203,28 @@ public class Entity {
|
|||
metadata.getFlags().setFlag(EntityFlag.SPRINTING, (xd & 0x08) == 0x08);
|
||||
metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10);
|
||||
metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80);
|
||||
|
||||
// Shield code
|
||||
if (session.getPlayerEntity().getEntityId() == entityId && metadata.getFlags().getFlag(EntityFlag.SNEAKING)) {
|
||||
if ((session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) ||
|
||||
(session.getInventoryCache().getPlayerInventory().getItem(45) != null && session.getInventoryCache().getPlayerInventory().getItem(45).getId() == ItemTranslator.SHIELD)) {
|
||||
ClientPlayerUseItemPacket useItemPacket;
|
||||
metadata.getFlags().setFlag(EntityFlag.BLOCKING, true);
|
||||
if (session.getInventory().getItemInHand() != null && session.getInventory().getItemInHand().getId() == ItemTranslator.SHIELD) {
|
||||
useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
|
||||
}
|
||||
// Else we just assume it's the offhand, to simplify logic and to assure the packet gets sent
|
||||
else {
|
||||
useItemPacket = new ClientPlayerUseItemPacket(Hand.OFF_HAND);
|
||||
}
|
||||
session.getDownstream().getSession().send(useItemPacket);
|
||||
}
|
||||
} else if (session.getPlayerEntity().getEntityId() == entityId && !metadata.getFlags().getFlag(EntityFlag.SNEAKING) && metadata.getFlags().getFlag(EntityFlag.BLOCKING)) {
|
||||
metadata.getFlags().setFlag(EntityFlag.BLOCKING, false);
|
||||
metadata.getFlags().setFlag(EntityFlag.DISABLE_BLOCKING, true);
|
||||
ClientPlayerActionPacket releaseItemPacket = new ClientPlayerActionPacket(PlayerAction.RELEASE_USE_ITEM, new Position(0,0,0), BlockFace.DOWN);
|
||||
session.getDownstream().getSession().send(releaseItemPacket);
|
||||
}
|
||||
// metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20);
|
||||
if ((xd & 0x20) == 0x20)
|
||||
metadata.put(EntityData.SCALE, 0.0f);
|
||||
|
@ -221,6 +247,12 @@ public class Entity {
|
|||
case 5: // no gravity
|
||||
metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue());
|
||||
break;
|
||||
case 7: // blocking
|
||||
if (entityMetadata.getType() == MetadataType.BYTE) {
|
||||
byte xd = (byte) entityMetadata.getValue();
|
||||
metadata.getFlags().setFlag(EntityFlag.BLOCKING, (xd & 0x01) == 0x01);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
updateBedrockMetadata(session);
|
||||
|
|
|
@ -47,10 +47,10 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||
@Override
|
||||
public boolean handle(LoginPacket loginPacket) {
|
||||
if (loginPacket.getProtocolVersion() > GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) {
|
||||
session.getUpstream().disconnect("Outdated Geyser proxy! I'm still on " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion());
|
||||
session.disconnect("Outdated Geyser proxy! I'm still on " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion());
|
||||
return true;
|
||||
} else if (loginPacket.getProtocolVersion() < GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) {
|
||||
session.getUpstream().disconnect("Outdated Bedrock client! Please use " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion());
|
||||
session.disconnect("Outdated Bedrock client! Please use " + GeyserConnector.BEDROCK_PACKET_CODEC.getMinecraftVersion());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
|
|||
session.getUpstream().sendPacket(stack);
|
||||
break;
|
||||
default:
|
||||
session.getUpstream().disconnect("disconnectionScreen.resourcePack");
|
||||
session.disconnect("disconnectionScreen.resourcePack");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -340,10 +340,16 @@ public class GeyserSession implements CommandSender {
|
|||
downstream.getSession().disconnect(reason);
|
||||
}
|
||||
if (upstream != null && !upstream.isClosed()) {
|
||||
connector.getPlayers().remove(this.upstream.getAddress());
|
||||
upstream.disconnect(reason);
|
||||
}
|
||||
}
|
||||
|
||||
this.entityCache.getEntities().clear();
|
||||
this.scoreboardCache.removeScoreboard();
|
||||
this.inventoryCache.getInventories().clear();
|
||||
this.windowCache.getWindows().clear();
|
||||
|
||||
closed = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,14 +25,13 @@
|
|||
|
||||
package org.geysermc.connector.network.session.cache;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class InventoryCache {
|
||||
|
||||
private GeyserSession session;
|
||||
|
@ -42,7 +41,7 @@ public class InventoryCache {
|
|||
private Inventory openInventory;
|
||||
|
||||
@Getter
|
||||
private Map<Integer, Inventory> inventories = new HashMap<Integer, Inventory>();
|
||||
private Int2ObjectMap<Inventory> inventories = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
public InventoryCache(GeyserSession session) {
|
||||
this.session = session;
|
||||
|
|
|
@ -34,6 +34,7 @@ import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
|||
import com.github.steveice10.mc.protocol.data.game.entity.player.InteractAction;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.InteractPacket;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
|
||||
@Translator(packet = InteractPacket.class)
|
||||
public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> {
|
||||
|
@ -46,6 +47,9 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
|
|||
|
||||
switch (packet.getAction()) {
|
||||
case INTERACT:
|
||||
if (session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36).getId() == ItemTranslator.SHIELD) {
|
||||
break;
|
||||
}
|
||||
ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),
|
||||
InteractAction.INTERACT, Hand.MAIN_HAND);
|
||||
session.getDownstream().getSession().send(interactPacket);
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.geysermc.connector.network.translators.PacketTranslator;
|
|||
import org.geysermc.connector.network.translators.Translator;
|
||||
import org.geysermc.connector.network.translators.Translators;
|
||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||
import org.geysermc.connector.utils.InventoryUtils;
|
||||
|
||||
@Translator(packet = InventoryTransactionPacket.class)
|
||||
|
@ -104,6 +105,9 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
|
|||
}
|
||||
break;
|
||||
case 1:
|
||||
if (session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36).getId() == ItemTranslator.SHIELD) {
|
||||
break;
|
||||
} // Handled in Entity.java
|
||||
ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
|
||||
session.getDownstream().getSession().send(useItemPacket);
|
||||
break;
|
||||
|
|
|
@ -67,8 +67,10 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
|
|||
|
||||
double javaY = packet.getPosition().getY() - EntityType.PLAYER.getOffset();
|
||||
if (packet.isOnGround()) javaY = Math.ceil(javaY * 2) / 2;
|
||||
// We need to parse the float as a string since casting a float to a double causes us to
|
||||
// lose precision and thus, causes players to get stuck when walking near walls
|
||||
ClientPlayerPositionRotationPacket playerPositionRotationPacket = new ClientPlayerPositionRotationPacket(
|
||||
packet.isOnGround(), GenericMath.round(packet.getPosition().getX(), 4), javaY, GenericMath.round(packet.getPosition().getZ(), 4), packet.getRotation().getY(), packet.getRotation().getX()
|
||||
packet.isOnGround(), Double.parseDouble(Float.toString(packet.getPosition().getX())), javaY, Double.parseDouble(Float.toString(packet.getPosition().getZ())), packet.getRotation().getY(), packet.getRotation().getX()
|
||||
);
|
||||
|
||||
// head yaw, pitch, head yaw
|
||||
|
|
|
@ -28,32 +28,33 @@ package org.geysermc.connector.network.translators.inventory;
|
|||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientCreativeInventoryActionPacket;
|
||||
import com.nukkitx.protocol.bedrock.data.*;
|
||||
import com.nukkitx.protocol.bedrock.data.ContainerId;
|
||||
import com.nukkitx.protocol.bedrock.data.InventoryActionData;
|
||||
import com.nukkitx.protocol.bedrock.data.InventorySource;
|
||||
import com.nukkitx.protocol.bedrock.data.ItemData;
|
||||
import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
|
||||
import it.unimi.dsi.fastutil.longs.LongArraySet;
|
||||
import org.geysermc.connector.inventory.Inventory;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.Translators;
|
||||
import org.geysermc.connector.network.translators.inventory.action.InventoryActionDataTranslator;
|
||||
import org.geysermc.connector.utils.InventoryUtils;
|
||||
import org.geysermc.connector.utils.Toolbox;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PlayerInventoryTranslator extends InventoryTranslator {
|
||||
|
||||
private static final LongArraySet HAS_RECEIVED_MESSAGE = new LongArraySet();
|
||||
|
||||
public PlayerInventoryTranslator() {
|
||||
super(46);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateInventory(GeyserSession session, Inventory inventory) {
|
||||
// Crafting grid
|
||||
for (int i = 1; i < 5; i++) {
|
||||
InventorySlotPacket slotPacket = new InventorySlotPacket();
|
||||
slotPacket.setContainerId(ContainerId.CURSOR);
|
||||
slotPacket.setSlot(i + 27);
|
||||
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)));
|
||||
session.getUpstream().sendPacket(slotPacket);
|
||||
}
|
||||
updateCraftingGrid(session, inventory);
|
||||
|
||||
InventoryContentPacket inventoryContentPacket = new InventoryContentPacket();
|
||||
inventoryContentPacket.setContainerId(ContainerId.INVENTORY);
|
||||
|
@ -86,6 +87,28 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
|||
session.getUpstream().sendPacket(offhandPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the crafting grid for the player to hide/show the barriers in the creative inventory
|
||||
* @param session Session of the player
|
||||
* @param inventory Inventory of the player
|
||||
*/
|
||||
public static void updateCraftingGrid(GeyserSession session, Inventory inventory) {
|
||||
// Crafting grid
|
||||
for (int i = 1; i < 5; i++) {
|
||||
InventorySlotPacket slotPacket = new InventorySlotPacket();
|
||||
slotPacket.setContainerId(ContainerId.CURSOR);
|
||||
slotPacket.setSlot(i + 27);
|
||||
|
||||
if (session.getGameMode() == GameMode.CREATIVE) {
|
||||
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, new ItemStack(Toolbox.BARRIER_INDEX)));
|
||||
}else{
|
||||
slotPacket.setItem(Translators.getItemTranslator().translateToBedrock(session, inventory.getItem(i)));
|
||||
}
|
||||
|
||||
session.getUpstream().sendPacket(slotPacket);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSlot(GeyserSession session, Inventory inventory, int slot) {
|
||||
if (slot >= 1 && slot <= 44) {
|
||||
|
@ -164,6 +187,11 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
|
|||
//crafting grid is not visible in creative mode in java edition
|
||||
for (InventoryActionData action : actions) {
|
||||
if (action.getSource().getContainerId() == ContainerId.CURSOR && (action.getSlot() >= 28 && 31 >= action.getSlot())) {
|
||||
if (!HAS_RECEIVED_MESSAGE.contains(session.getPlayerEntity().getEntityId())) {
|
||||
// TODO: Allow the crafting table to be used with non-standalone versions
|
||||
session.sendMessage("The creative crafting table cannot be used as it's incompatible with Minecraft: Java Edition.");
|
||||
HAS_RECEIVED_MESSAGE.add(session.getPlayerEntity().getEntityId());
|
||||
}
|
||||
updateInventory(session, inventory);
|
||||
InventoryUtils.updateCursor(session);
|
||||
return;
|
||||
|
|
|
@ -45,6 +45,9 @@ public class ItemTranslator {
|
|||
private Int2ObjectMap<ItemStackTranslator> itemTranslators = new Int2ObjectOpenHashMap();
|
||||
private List<NbtItemStackTranslator> nbtItemTranslators;
|
||||
private Map<String, ItemEntry> javaIdentifierMap = new HashMap<>();
|
||||
|
||||
// Shield ID, used in Entity.java
|
||||
public static final int SHIELD = 829;
|
||||
|
||||
public void init() {
|
||||
Reflections ref = new Reflections("org.geysermc.connector.network.translators.item");
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 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.connector.network.translators.item.translators.nbt;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import org.geysermc.connector.network.translators.ItemRemapper;
|
||||
import org.geysermc.connector.network.translators.NbtItemStackTranslator;
|
||||
import org.geysermc.connector.network.translators.item.ItemEntry;
|
||||
import org.geysermc.connector.utils.MessageUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ItemRemapper
|
||||
public class BookPagesTranslator extends NbtItemStackTranslator {
|
||||
|
||||
@Override
|
||||
public void translateToBedrock(CompoundTag itemTag, ItemEntry itemEntry) {
|
||||
if (itemTag.contains("pages")) {
|
||||
List<Tag> pages = new ArrayList<>();
|
||||
ListTag pagesTag = itemTag.get("pages");
|
||||
for (Tag tag : pagesTag.getValue()) {
|
||||
if (!(tag instanceof StringTag))
|
||||
continue;
|
||||
|
||||
StringTag textTag = (StringTag) tag;
|
||||
|
||||
CompoundTag pageTag = new CompoundTag("");
|
||||
pageTag.put(new StringTag("photoname", ""));
|
||||
pageTag.put(new StringTag("text", MessageUtils.getBedrockMessage(textTag.getValue())));
|
||||
pages.add(pageTag);
|
||||
}
|
||||
|
||||
itemTag.remove("pages");
|
||||
itemTag.put(new ListTag("pages", pages));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateToJava(CompoundTag itemTag, ItemEntry itemEntry) {
|
||||
if (itemTag.contains("pages")) {
|
||||
List<Tag> pages = new ArrayList<>();
|
||||
ListTag pagesTag = itemTag.get("pages");
|
||||
for (Tag tag : pagesTag.getValue()) {
|
||||
if (!(tag instanceof CompoundTag))
|
||||
continue;
|
||||
|
||||
CompoundTag pageTag = (CompoundTag) tag;
|
||||
|
||||
StringTag textTag = pageTag.get("text");
|
||||
pages.add(new StringTag(MessageUtils.getJavaMessage(textTag.getValue())));
|
||||
}
|
||||
|
||||
itemTag.remove("pages");
|
||||
itemTag.put(new ListTag("pages", pages));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -58,8 +58,10 @@ public class EnchantmentTranslator extends NbtItemStackTranslator {
|
|||
if (!(tag instanceof CompoundTag)) continue;
|
||||
|
||||
CompoundTag bedrockTag = remapEnchantment((CompoundTag) tag);
|
||||
bedrockTag.put(new ShortTag("GeyserStoredEnchantment", (short) 0));
|
||||
newTags.add(bedrockTag);
|
||||
if (bedrockTag != null) {
|
||||
bedrockTag.put(new ShortTag("GeyserStoredEnchantment", (short) 0));
|
||||
newTags.add(bedrockTag);
|
||||
}
|
||||
}
|
||||
itemTag.remove("StoredEnchantments");
|
||||
}
|
||||
|
@ -117,11 +119,11 @@ public class EnchantmentTranslator extends NbtItemStackTranslator {
|
|||
|
||||
|
||||
private CompoundTag remapEnchantment(CompoundTag tag) {
|
||||
Tag javaEnchLvl = ((CompoundTag) tag).get("lvl");
|
||||
Tag javaEnchLvl = tag.get("lvl");
|
||||
if (!(javaEnchLvl instanceof ShortTag))
|
||||
return null;
|
||||
|
||||
Tag javaEnchId = ((CompoundTag) tag).get("id");
|
||||
Tag javaEnchId = tag.get("id");
|
||||
if (!(javaEnchId instanceof StringTag))
|
||||
return null;
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ import com.nukkitx.protocol.bedrock.data.CommandData;
|
|||
import com.nukkitx.protocol.bedrock.data.CommandEnumData;
|
||||
import com.nukkitx.protocol.bedrock.data.CommandParamData;
|
||||
import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
@ -45,8 +47,8 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator<Server
|
|||
@Override
|
||||
public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) {
|
||||
List<CommandData> commandData = new ArrayList<>();
|
||||
Map<Integer, String> commands = new HashMap<>();
|
||||
Map<Integer, List<CommandNode>> commandArgs = new HashMap<>();
|
||||
Int2ObjectMap<String> commands = new Int2ObjectOpenHashMap<>();
|
||||
Int2ObjectMap<List<CommandNode>> commandArgs = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
// Get the first node, it should be a root node
|
||||
CommandNode rootNode = packet.getNodes()[packet.getFirstNodeIndex()];
|
||||
|
|
|
@ -51,13 +51,12 @@ public class JavaMapDataTranslator extends PacketTranslator<ServerMapDataPacket>
|
|||
mapItemDataPacket.setWidth(data.getColumns());
|
||||
mapItemDataPacket.setHeight(data.getRows());
|
||||
|
||||
// Every int entry is an ARGB color
|
||||
// Every int entry is an ABGR color
|
||||
int[] colors = new int[data.getData().length];
|
||||
|
||||
int idx = 0;
|
||||
for (byte colorId : data.getData()) {
|
||||
colors[idx] = MapColor.fromId(colorId).toARGB();
|
||||
idx++;
|
||||
colors[idx++] = MapColor.fromId(colorId & 0xFF).toABGR();
|
||||
}
|
||||
|
||||
mapItemDataPacket.setColors(colors);
|
||||
|
|
|
@ -25,14 +25,6 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.java.world;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.ClientRequest;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
|
||||
import com.github.steveice10.mc.protocol.data.game.world.notify.EnterCreditsValue;
|
||||
|
@ -43,13 +35,16 @@ import com.nukkitx.protocol.bedrock.data.EntityDataMap;
|
|||
import com.nukkitx.protocol.bedrock.data.EntityFlag;
|
||||
import com.nukkitx.protocol.bedrock.data.LevelEventType;
|
||||
import com.nukkitx.protocol.bedrock.data.PlayerPermission;
|
||||
import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.LevelEventPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.SetPlayerGameTypePacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.ShowCreditsPacket;
|
||||
|
||||
import com.nukkitx.protocol.bedrock.packet.*;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.geysermc.connector.entity.Entity;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
import org.geysermc.connector.network.translators.inventory.PlayerInventoryTranslator;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@Translator(packet = ServerNotifyClientPacket.class)
|
||||
public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyClientPacket> {
|
||||
|
@ -110,6 +105,10 @@ public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyCli
|
|||
entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
|
||||
entityDataPacket.getMetadata().putAll(metadata);
|
||||
session.getUpstream().sendPacket(entityDataPacket);
|
||||
|
||||
// Update the crafting grid to add/remove barriers for creative inventory
|
||||
PlayerInventoryTranslator.updateCraftingGrid(session, session.getInventory());
|
||||
|
||||
break;
|
||||
case ENTER_CREDITS:
|
||||
switch ((EnterCreditsValue) packet.getValue()) {
|
||||
|
|
|
@ -42,32 +42,29 @@ public class JavaPlayBuiltinSoundTranslator extends PacketTranslator<ServerPlayB
|
|||
String packetSound = packet.getSound().getName();
|
||||
|
||||
SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound);
|
||||
session.getConnector().getLogger()
|
||||
.debug("[Builtin] Sound mapping " + packetSound + " -> "
|
||||
session.getConnector().getLogger().debug("[Builtin] Sound mapping " + packetSound + " -> "
|
||||
+ soundMapping + (soundMapping == null ? "[not found]" : "")
|
||||
+ " - " + packet.toString());
|
||||
if(soundMapping == null) {
|
||||
if (soundMapping == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LevelSoundEventPacket soundPacket = new LevelSoundEventPacket();
|
||||
SoundEvent sound = SoundUtils.toSoundEvent(soundMapping.getBedrock());
|
||||
if(sound == null) {
|
||||
if (sound == null) {
|
||||
sound = SoundUtils.toSoundEvent(soundMapping.getBedrock());
|
||||
if(sound == null) {
|
||||
sound = SoundUtils.toSoundEvent(packetSound);
|
||||
if(sound == null) {
|
||||
session.getConnector().getLogger()
|
||||
.debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket
|
||||
+ " was not a playable level sound, or has yet to be mapped to an enum in " +
|
||||
"NukkitX SoundEvent ");
|
||||
} else {
|
||||
session.getConnector().getLogger()
|
||||
.debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket
|
||||
+ " was not found in NukkitX SoundEvent, but original packet sound name was.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (sound == null) {
|
||||
sound = SoundUtils.toSoundEvent(packetSound);
|
||||
}
|
||||
if (sound == null) {
|
||||
session.getConnector().getLogger().debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket
|
||||
+ " was not a playable level sound, or has yet to be mapped to an enum in "
|
||||
+ "NukkitX SoundEvent ");
|
||||
|
||||
} else {
|
||||
session.getConnector().getLogger().debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket
|
||||
+ " was not found in NukkitX SoundEvent, but original packet sound name was.");
|
||||
}
|
||||
|
||||
soundPacket.setSound(sound);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package org.geysermc.connector.utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public enum MapColor {
|
||||
COLOR_0(-1, -1, -1),
|
||||
COLOR_1(-1, -1, -1),
|
||||
|
@ -212,6 +210,8 @@ public enum MapColor {
|
|||
COLOR_206(37, 22, 16),
|
||||
COLOR_207(19, 11, 8);
|
||||
|
||||
private static final MapColor[] VALUES = values();
|
||||
|
||||
private final int red;
|
||||
private final int green;
|
||||
private final int blue;
|
||||
|
@ -222,23 +222,18 @@ public enum MapColor {
|
|||
this.blue = blue;
|
||||
}
|
||||
|
||||
int getId() {
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
public static MapColor fromId(int id) {
|
||||
return Arrays.stream(values()).filter(color -> color.getId() == id).findFirst().orElse(COLOR_0);
|
||||
return id >= 0 && id < VALUES.length ? VALUES[id] : COLOR_0;
|
||||
}
|
||||
|
||||
public int toARGB() {
|
||||
public int toABGR() {
|
||||
int alpha = 255;
|
||||
if (red == -1 && green == -1 && blue == -1)
|
||||
alpha = 0; // transparent
|
||||
|
||||
long result = red & 0xff;
|
||||
result |= (green & 0xff) << 8;
|
||||
result |= (blue & 0xff) << 16;
|
||||
result |= (alpha & 0xff) << 24;
|
||||
return (int) (result & 0xFFFFFFFFL);
|
||||
return ((alpha & 0xFF) << 24) |
|
||||
((blue & 0xFF) << 16) |
|
||||
((green & 0xFF) << 8) |
|
||||
((red & 0xFF) << 0);
|
||||
}
|
||||
}
|
|
@ -32,6 +32,9 @@ import com.google.gson.JsonElement;
|
|||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import net.kyori.text.Component;
|
||||
import net.kyori.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -62,7 +65,7 @@ public class MessageUtils {
|
|||
List<String> furtherParams = getTranslationParams(translation.getTranslationParams(), locale);
|
||||
if (locale != null) {
|
||||
strings.add(insertParams(LocaleUtils.getLocaleString(translation.getTranslationKey(), locale), furtherParams));
|
||||
}else{
|
||||
} else {
|
||||
strings.addAll(furtherParams);
|
||||
}
|
||||
} else {
|
||||
|
@ -118,14 +121,30 @@ public class MessageUtils {
|
|||
}
|
||||
|
||||
public static String getBedrockMessage(Message message) {
|
||||
return getTranslatedBedrockMessage(message, null, false);
|
||||
Component component;
|
||||
if (isMessage(message.getText())) {
|
||||
component = GsonComponentSerializer.INSTANCE.deserialize(message.getText());
|
||||
} else {
|
||||
component = GsonComponentSerializer.INSTANCE.deserialize(message.toJsonString());
|
||||
}
|
||||
return LegacyComponentSerializer.legacy().serialize(component);
|
||||
}
|
||||
|
||||
public static String getBedrockMessage(String message) {
|
||||
Component component = GsonComponentSerializer.INSTANCE.deserialize(message);
|
||||
return LegacyComponentSerializer.legacy().serialize(component);
|
||||
}
|
||||
|
||||
public static String getJavaMessage(String message) {
|
||||
Component component = LegacyComponentSerializer.legacy().deserialize(message);
|
||||
return GsonComponentSerializer.INSTANCE.serialize(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the given parameters into the given message both in sequence and as requested
|
||||
*
|
||||
* @param message Message containing possible parameter replacement strings
|
||||
* @param params A list of parameter strings
|
||||
* @param params A list of parameter strings
|
||||
* @return Parsed message with all params inserted as needed
|
||||
*/
|
||||
public static String insertParams(String message, List<String> params) {
|
||||
|
@ -135,7 +154,7 @@ public class MessageUtils {
|
|||
Matcher m = p.matcher(message);
|
||||
while (m.find()) {
|
||||
try {
|
||||
newMessage = newMessage.replaceFirst("%" + m.group(1) + "\\$s" , params.get(Integer.parseInt(m.group(1)) - 1));
|
||||
newMessage = newMessage.replaceFirst("%" + m.group(1) + "\\$s", params.get(Integer.parseInt(m.group(1)) - 1));
|
||||
} catch (Exception e) {
|
||||
// Couldn't find the param to replace
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ public class SoundUtils {
|
|||
public static SoundEvent toSoundEvent(String sound) {
|
||||
try {
|
||||
return SoundEvent.valueOf(sound.toUpperCase().replaceAll("\\.", "_"));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
} catch (Exception ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ public class Toolbox {
|
|||
|
||||
public static final Int2ObjectMap<ItemEntry> ITEM_ENTRIES = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
public static final Map<String, Map<String, String>> LOCALE_MAPPINGS = new HashMap<>();
|
||||
public static int BARRIER_INDEX = 0;
|
||||
|
||||
static {
|
||||
/* Load biomes */
|
||||
|
@ -129,6 +129,10 @@ public class Toolbox {
|
|||
entry.getValue().get("bedrock_data").intValue(),
|
||||
entry.getValue().get("is_block").booleanValue()));
|
||||
}
|
||||
if (entry.getKey().equals("minecraft:barrier")) {
|
||||
BARRIER_INDEX = itemIndex;
|
||||
}
|
||||
|
||||
itemIndex++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue