3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-12-27 16:40:14 +01:00

Fix NPE in console when a sound was missing and clean up nesting

Dieser Commit ist enthalten in:
RednedEpic 2020-04-25 18:23:01 -05:00
Commit 497825dd96
24 geänderte Dateien mit 346 neuen und 90 gelöschten Zeilen

Datei anzeigen

@ -31,10 +31,10 @@ assignees: ''
<!--- Give us the exact output from /version. Saying "latest" does not help us at all. --> <!--- Give us the exact output from /version. Saying "latest" does not help us at all. -->
**Geyser Version** **Geyser Version**
<!--- Give us the exact build number as well as branch if applicable. Saying "latest" does not help us at all. --> <!--- Give us the exact build number as well as branch if applicable. Saying "latest" does not help us at all. Please also include if you are running the standalone version, or specify which plugin version you are using. If your issue is a connection problem, please specify if you are using the Floodgate plugin. -->
**Minecraft: Bedrock Edition Version** **Minecraft: Bedrock Edition Version**
<!-- The version of your Minecraft: Bedrock Edition client you tested with. --> <!-- The version of your Minecraft: Bedrock Edition client you tested with. -->
**Additional Context** **Additional Context**
<!--- Add any other context about the problem here. ---> <!--- Add any other context about the problem here. Include any plugins on the Minecraft server that may cause problems. --->

Datei anzeigen

@ -33,7 +33,7 @@
<dependency> <dependency>
<groupId>com.nukkitx.protocol</groupId> <groupId>com.nukkitx.protocol</groupId>
<artifactId>bedrock-v390</artifactId> <artifactId>bedrock-v390</artifactId>
<version>2.5.5-SNAPSHOT</version> <version>2.5.6-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>
@ -117,7 +117,7 @@
<dependency> <dependency>
<groupId>com.github.steveice10</groupId> <groupId>com.github.steveice10</groupId>
<artifactId>mcauthlib</artifactId> <artifactId>mcauthlib</artifactId>
<version>1.1-SNAPSHOT</version> <version>1.3-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -145,5 +145,23 @@
<artifactId>reflections</artifactId> <artifactId>reflections</artifactId>
<version>0.9.12</version> <version>0.9.12</version>
</dependency> </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> </dependencies>
</project> </project>

Datei anzeigen

@ -28,10 +28,7 @@ package org.geysermc.connector.command;
import lombok.Getter; import lombok.Getter;
import org.geysermc.common.command.ICommandManager; import org.geysermc.common.command.ICommandManager;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.defaults.HelpCommand; import org.geysermc.connector.command.defaults.*;
import org.geysermc.connector.command.defaults.ListCommand;
import org.geysermc.connector.command.defaults.ReloadCommand;
import org.geysermc.connector.command.defaults.StopCommand;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; 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 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 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 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) { public void registerCommand(GeyserCommand command) {

Datei anzeigen

@ -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);
}
}
}

Datei anzeigen

@ -48,7 +48,7 @@ public class ReloadCommand extends GeyserCommand {
} }
sender.sendMessage(ChatColor.YELLOW + "Reloading Geyser configurations... all connected bedrock clients will be kicked."); sender.sendMessage(ChatColor.YELLOW + "Reloading Geyser configurations... all connected bedrock clients will be kicked.");
for (GeyserSession session : connector.getPlayers().values()) { 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(); connector.reload();
} }

Datei anzeigen

@ -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.EntityMetadata;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType; 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.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.math.vector.Vector3f;
import com.nukkitx.protocol.bedrock.data.EntityData; import com.nukkitx.protocol.bedrock.data.*;
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.packet.*; import com.nukkitx.protocol.bedrock.packet.*;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet; 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.attribute.AttributeType;
import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.entity.type.EntityType;
import org.geysermc.connector.network.session.GeyserSession; 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.AttributeUtils;
import org.geysermc.connector.utils.MessageUtils; 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.SPRINTING, (xd & 0x08) == 0x08);
metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10); metadata.getFlags().setFlag(EntityFlag.SWIMMING, (xd & 0x10) == 0x10);
metadata.getFlags().setFlag(EntityFlag.GLIDING, (xd & 0x80) == 0x80); 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); // metadata.getFlags().setFlag(EntityFlag.INVISIBLE, (xd & 0x20) == 0x20);
if ((xd & 0x20) == 0x20) if ((xd & 0x20) == 0x20)
metadata.put(EntityData.SCALE, 0.0f); metadata.put(EntityData.SCALE, 0.0f);
@ -221,6 +247,12 @@ public class Entity {
case 5: // no gravity case 5: // no gravity
metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue()); metadata.getFlags().setFlag(EntityFlag.HAS_GRAVITY, !(boolean) entityMetadata.getValue());
break; 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); updateBedrockMetadata(session);

Datei anzeigen

@ -47,10 +47,10 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
@Override @Override
public boolean handle(LoginPacket loginPacket) { public boolean handle(LoginPacket loginPacket) {
if (loginPacket.getProtocolVersion() > GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) { 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; return true;
} else if (loginPacket.getProtocolVersion() < GeyserConnector.BEDROCK_PACKET_CODEC.getProtocolVersion()) { } 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; return true;
} }
@ -80,7 +80,7 @@ public class UpstreamPacketHandler extends LoggingPacketHandler {
session.getUpstream().sendPacket(stack); session.getUpstream().sendPacket(stack);
break; break;
default: default:
session.getUpstream().disconnect("disconnectionScreen.resourcePack"); session.disconnect("disconnectionScreen.resourcePack");
break; break;
} }

Datei anzeigen

@ -340,10 +340,16 @@ public class GeyserSession implements CommandSender {
downstream.getSession().disconnect(reason); downstream.getSession().disconnect(reason);
} }
if (upstream != null && !upstream.isClosed()) { if (upstream != null && !upstream.isClosed()) {
connector.getPlayers().remove(this.upstream.getAddress());
upstream.disconnect(reason); upstream.disconnect(reason);
} }
} }
this.entityCache.getEntities().clear();
this.scoreboardCache.removeScoreboard();
this.inventoryCache.getInventories().clear();
this.windowCache.getWindows().clear();
closed = true; closed = true;
} }

Datei anzeigen

@ -25,14 +25,13 @@
package org.geysermc.connector.network.session.cache; 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.Getter;
import lombok.Setter; import lombok.Setter;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import java.util.HashMap;
import java.util.Map;
public class InventoryCache { public class InventoryCache {
private GeyserSession session; private GeyserSession session;
@ -42,7 +41,7 @@ public class InventoryCache {
private Inventory openInventory; private Inventory openInventory;
@Getter @Getter
private Map<Integer, Inventory> inventories = new HashMap<Integer, Inventory>(); private Int2ObjectMap<Inventory> inventories = new Int2ObjectOpenHashMap<>();
public InventoryCache(GeyserSession session) { public InventoryCache(GeyserSession session) {
this.session = session; this.session = session;

Datei anzeigen

@ -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.data.game.entity.player.InteractAction;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket; import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket;
import com.nukkitx.protocol.bedrock.packet.InteractPacket; import com.nukkitx.protocol.bedrock.packet.InteractPacket;
import org.geysermc.connector.network.translators.item.ItemTranslator;
@Translator(packet = InteractPacket.class) @Translator(packet = InteractPacket.class)
public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> { public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> {
@ -46,6 +47,9 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
switch (packet.getAction()) { switch (packet.getAction()) {
case INTERACT: case INTERACT:
if (session.getInventory().getItem(session.getInventory().getHeldItemSlot() + 36).getId() == ItemTranslator.SHIELD) {
break;
}
ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(), ClientPlayerInteractEntityPacket interactPacket = new ClientPlayerInteractEntityPacket((int) entity.getEntityId(),
InteractAction.INTERACT, Hand.MAIN_HAND); InteractAction.INTERACT, Hand.MAIN_HAND);
session.getDownstream().getSession().send(interactPacket); session.getDownstream().getSession().send(interactPacket);

Datei anzeigen

@ -46,6 +46,7 @@ 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.Translators; import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.item.ItemEntry; import org.geysermc.connector.network.translators.item.ItemEntry;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.utils.InventoryUtils; import org.geysermc.connector.utils.InventoryUtils;
@Translator(packet = InventoryTransactionPacket.class) @Translator(packet = InventoryTransactionPacket.class)
@ -104,6 +105,9 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
} }
break; break;
case 1: 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); ClientPlayerUseItemPacket useItemPacket = new ClientPlayerUseItemPacket(Hand.MAIN_HAND);
session.getDownstream().getSession().send(useItemPacket); session.getDownstream().getSession().send(useItemPacket);
break; break;

Datei anzeigen

@ -67,8 +67,10 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
double javaY = packet.getPosition().getY() - EntityType.PLAYER.getOffset(); double javaY = packet.getPosition().getY() - EntityType.PLAYER.getOffset();
if (packet.isOnGround()) javaY = Math.ceil(javaY * 2) / 2; 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( 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 // head yaw, pitch, head yaw

Datei anzeigen

@ -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.metadata.ItemStack;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientCreativeInventoryActionPacket; 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.InventoryContentPacket;
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket; import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import org.geysermc.connector.inventory.Inventory; import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.Translators; import org.geysermc.connector.network.translators.Translators;
import org.geysermc.connector.network.translators.inventory.action.InventoryActionDataTranslator; import org.geysermc.connector.network.translators.inventory.action.InventoryActionDataTranslator;
import org.geysermc.connector.utils.InventoryUtils; import org.geysermc.connector.utils.InventoryUtils;
import org.geysermc.connector.utils.Toolbox;
import java.util.List; import java.util.List;
public class PlayerInventoryTranslator extends InventoryTranslator { public class PlayerInventoryTranslator extends InventoryTranslator {
private static final LongArraySet HAS_RECEIVED_MESSAGE = new LongArraySet();
public PlayerInventoryTranslator() { public PlayerInventoryTranslator() {
super(46); super(46);
} }
@Override @Override
public void updateInventory(GeyserSession session, Inventory inventory) { public void updateInventory(GeyserSession session, Inventory inventory) {
// Crafting grid updateCraftingGrid(session, inventory);
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);
}
InventoryContentPacket inventoryContentPacket = new InventoryContentPacket(); InventoryContentPacket inventoryContentPacket = new InventoryContentPacket();
inventoryContentPacket.setContainerId(ContainerId.INVENTORY); inventoryContentPacket.setContainerId(ContainerId.INVENTORY);
@ -86,6 +87,28 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
session.getUpstream().sendPacket(offhandPacket); 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 @Override
public void updateSlot(GeyserSession session, Inventory inventory, int slot) { public void updateSlot(GeyserSession session, Inventory inventory, int slot) {
if (slot >= 1 && slot <= 44) { 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 //crafting grid is not visible in creative mode in java edition
for (InventoryActionData action : actions) { for (InventoryActionData action : actions) {
if (action.getSource().getContainerId() == ContainerId.CURSOR && (action.getSlot() >= 28 && 31 >= action.getSlot())) { 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); updateInventory(session, inventory);
InventoryUtils.updateCursor(session); InventoryUtils.updateCursor(session);
return; return;

Datei anzeigen

@ -46,6 +46,9 @@ public class ItemTranslator {
private List<NbtItemStackTranslator> nbtItemTranslators; private List<NbtItemStackTranslator> nbtItemTranslators;
private Map<String, ItemEntry> javaIdentifierMap = new HashMap<>(); private Map<String, ItemEntry> javaIdentifierMap = new HashMap<>();
// Shield ID, used in Entity.java
public static final int SHIELD = 829;
public void init() { public void init() {
Reflections ref = new Reflections("org.geysermc.connector.network.translators.item"); Reflections ref = new Reflections("org.geysermc.connector.network.translators.item");

Datei anzeigen

@ -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));
}
}
}

Datei anzeigen

@ -58,8 +58,10 @@ public class EnchantmentTranslator extends NbtItemStackTranslator {
if (!(tag instanceof CompoundTag)) continue; if (!(tag instanceof CompoundTag)) continue;
CompoundTag bedrockTag = remapEnchantment((CompoundTag) tag); CompoundTag bedrockTag = remapEnchantment((CompoundTag) tag);
bedrockTag.put(new ShortTag("GeyserStoredEnchantment", (short) 0)); if (bedrockTag != null) {
newTags.add(bedrockTag); bedrockTag.put(new ShortTag("GeyserStoredEnchantment", (short) 0));
newTags.add(bedrockTag);
}
} }
itemTag.remove("StoredEnchantments"); itemTag.remove("StoredEnchantments");
} }
@ -117,11 +119,11 @@ public class EnchantmentTranslator extends NbtItemStackTranslator {
private CompoundTag remapEnchantment(CompoundTag tag) { private CompoundTag remapEnchantment(CompoundTag tag) {
Tag javaEnchLvl = ((CompoundTag) tag).get("lvl"); Tag javaEnchLvl = tag.get("lvl");
if (!(javaEnchLvl instanceof ShortTag)) if (!(javaEnchLvl instanceof ShortTag))
return null; return null;
Tag javaEnchId = ((CompoundTag) tag).get("id"); Tag javaEnchId = tag.get("id");
if (!(javaEnchId instanceof StringTag)) if (!(javaEnchId instanceof StringTag))
return null; return null;

Datei anzeigen

@ -32,6 +32,8 @@ import com.nukkitx.protocol.bedrock.data.CommandData;
import com.nukkitx.protocol.bedrock.data.CommandEnumData; import com.nukkitx.protocol.bedrock.data.CommandEnumData;
import com.nukkitx.protocol.bedrock.data.CommandParamData; import com.nukkitx.protocol.bedrock.data.CommandParamData;
import com.nukkitx.protocol.bedrock.packet.AvailableCommandsPacket; 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 lombok.Getter;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.session.GeyserSession;
@ -45,8 +47,8 @@ public class JavaServerDeclareCommandsTranslator extends PacketTranslator<Server
@Override @Override
public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) { public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) {
List<CommandData> commandData = new ArrayList<>(); List<CommandData> commandData = new ArrayList<>();
Map<Integer, String> commands = new HashMap<>(); Int2ObjectMap<String> commands = new Int2ObjectOpenHashMap<>();
Map<Integer, List<CommandNode>> commandArgs = new HashMap<>(); Int2ObjectMap<List<CommandNode>> commandArgs = new Int2ObjectOpenHashMap<>();
// Get the first node, it should be a root node // Get the first node, it should be a root node
CommandNode rootNode = packet.getNodes()[packet.getFirstNodeIndex()]; CommandNode rootNode = packet.getNodes()[packet.getFirstNodeIndex()];

Datei anzeigen

@ -51,13 +51,12 @@ public class JavaMapDataTranslator extends PacketTranslator<ServerMapDataPacket>
mapItemDataPacket.setWidth(data.getColumns()); mapItemDataPacket.setWidth(data.getColumns());
mapItemDataPacket.setHeight(data.getRows()); 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[] colors = new int[data.getData().length];
int idx = 0; int idx = 0;
for (byte colorId : data.getData()) { for (byte colorId : data.getData()) {
colors[idx] = MapColor.fromId(colorId).toARGB(); colors[idx++] = MapColor.fromId(colorId & 0xFF).toABGR();
idx++;
} }
mapItemDataPacket.setColors(colors); mapItemDataPacket.setColors(colors);

Datei anzeigen

@ -25,14 +25,6 @@
package org.geysermc.connector.network.translators.java.world; 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.ClientRequest;
import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode; import com.github.steveice10.mc.protocol.data.game.entity.player.GameMode;
import com.github.steveice10.mc.protocol.data.game.world.notify.EnterCreditsValue; 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.EntityFlag;
import com.nukkitx.protocol.bedrock.data.LevelEventType; import com.nukkitx.protocol.bedrock.data.LevelEventType;
import com.nukkitx.protocol.bedrock.data.PlayerPermission; import com.nukkitx.protocol.bedrock.data.PlayerPermission;
import com.nukkitx.protocol.bedrock.packet.AdventureSettingsPacket; import com.nukkitx.protocol.bedrock.packet.*;
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 it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; 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) @Translator(packet = ServerNotifyClientPacket.class)
public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyClientPacket> { public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyClientPacket> {
@ -110,6 +105,10 @@ public class JavaNotifyClientTranslator extends PacketTranslator<ServerNotifyCli
entityDataPacket.setRuntimeEntityId(entity.getGeyserId()); entityDataPacket.setRuntimeEntityId(entity.getGeyserId());
entityDataPacket.getMetadata().putAll(metadata); entityDataPacket.getMetadata().putAll(metadata);
session.getUpstream().sendPacket(entityDataPacket); session.getUpstream().sendPacket(entityDataPacket);
// Update the crafting grid to add/remove barriers for creative inventory
PlayerInventoryTranslator.updateCraftingGrid(session, session.getInventory());
break; break;
case ENTER_CREDITS: case ENTER_CREDITS:
switch ((EnterCreditsValue) packet.getValue()) { switch ((EnterCreditsValue) packet.getValue()) {

Datei anzeigen

@ -42,32 +42,29 @@ public class JavaPlayBuiltinSoundTranslator extends PacketTranslator<ServerPlayB
String packetSound = packet.getSound().getName(); String packetSound = packet.getSound().getName();
SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound); SoundUtils.SoundMapping soundMapping = SoundUtils.fromJava(packetSound);
session.getConnector().getLogger() session.getConnector().getLogger().debug("[Builtin] Sound mapping " + packetSound + " -> "
.debug("[Builtin] Sound mapping " + packetSound + " -> "
+ soundMapping + (soundMapping == null ? "[not found]" : "") + soundMapping + (soundMapping == null ? "[not found]" : "")
+ " - " + packet.toString()); + " - " + packet.toString());
if(soundMapping == null) { if (soundMapping == null) {
return; return;
} }
LevelSoundEventPacket soundPacket = new LevelSoundEventPacket(); LevelSoundEventPacket soundPacket = new LevelSoundEventPacket();
SoundEvent sound = SoundUtils.toSoundEvent(soundMapping.getBedrock()); SoundEvent sound = SoundUtils.toSoundEvent(soundMapping.getBedrock());
if(sound == null) { if (sound == null) {
sound = SoundUtils.toSoundEvent(soundMapping.getBedrock()); sound = SoundUtils.toSoundEvent(soundMapping.getBedrock());
if(sound == null) { }
sound = SoundUtils.toSoundEvent(packetSound); if (sound == null) {
if(sound == null) { sound = SoundUtils.toSoundEvent(packetSound);
session.getConnector().getLogger() }
.debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket if (sound == null) {
+ " was not a playable level sound, or has yet to be mapped to an enum in " + session.getConnector().getLogger().debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket
"NukkitX SoundEvent "); + " was not a playable level sound, or has yet to be mapped to an enum in "
} else { + "NukkitX SoundEvent ");
session.getConnector().getLogger()
.debug("[Builtin] Sound for original " + packetSound + " to mappings " + soundPacket } else {
+ " was not found in NukkitX SoundEvent, but original packet sound name was."); 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;
}
} }
soundPacket.setSound(sound); soundPacket.setSound(sound);

Datei anzeigen

@ -1,7 +1,5 @@
package org.geysermc.connector.utils; package org.geysermc.connector.utils;
import java.util.Arrays;
public enum MapColor { public enum MapColor {
COLOR_0(-1, -1, -1), COLOR_0(-1, -1, -1),
COLOR_1(-1, -1, -1), COLOR_1(-1, -1, -1),
@ -212,6 +210,8 @@ public enum MapColor {
COLOR_206(37, 22, 16), COLOR_206(37, 22, 16),
COLOR_207(19, 11, 8); COLOR_207(19, 11, 8);
private static final MapColor[] VALUES = values();
private final int red; private final int red;
private final int green; private final int green;
private final int blue; private final int blue;
@ -222,23 +222,18 @@ public enum MapColor {
this.blue = blue; this.blue = blue;
} }
int getId() {
return ordinal();
}
public static MapColor fromId(int id) { 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; int alpha = 255;
if (red == -1 && green == -1 && blue == -1) if (red == -1 && green == -1 && blue == -1)
alpha = 0; // transparent alpha = 0; // transparent
long result = red & 0xff; return ((alpha & 0xFF) << 24) |
result |= (green & 0xff) << 8; ((blue & 0xFF) << 16) |
result |= (blue & 0xff) << 16; ((green & 0xFF) << 8) |
result |= (alpha & 0xff) << 24; ((red & 0xFF) << 0);
return (int) (result & 0xFFFFFFFFL);
} }
} }

Datei anzeigen

@ -32,6 +32,9 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive; 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 org.geysermc.connector.network.session.GeyserSession;
import java.util.*; import java.util.*;
@ -62,7 +65,7 @@ public class MessageUtils {
List<String> furtherParams = getTranslationParams(translation.getTranslationParams(), locale); List<String> furtherParams = getTranslationParams(translation.getTranslationParams(), locale);
if (locale != null) { if (locale != null) {
strings.add(insertParams(LocaleUtils.getLocaleString(translation.getTranslationKey(), locale), furtherParams)); strings.add(insertParams(LocaleUtils.getLocaleString(translation.getTranslationKey(), locale), furtherParams));
}else{ } else {
strings.addAll(furtherParams); strings.addAll(furtherParams);
} }
} else { } else {
@ -118,14 +121,30 @@ public class MessageUtils {
} }
public static String getBedrockMessage(Message message) { 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 * Inserts the given parameters into the given message both in sequence and as requested
* *
* @param message Message containing possible parameter replacement strings * @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 * @return Parsed message with all params inserted as needed
*/ */
public static String insertParams(String message, List<String> params) { public static String insertParams(String message, List<String> params) {
@ -135,7 +154,7 @@ public class MessageUtils {
Matcher m = p.matcher(message); Matcher m = p.matcher(message);
while (m.find()) { while (m.find()) {
try { 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) { } catch (Exception e) {
// Couldn't find the param to replace // Couldn't find the param to replace
} }

Datei anzeigen

@ -84,7 +84,7 @@ public class SoundUtils {
public static SoundEvent toSoundEvent(String sound) { public static SoundEvent toSoundEvent(String sound) {
try { try {
return SoundEvent.valueOf(sound.toUpperCase().replaceAll("\\.", "_")); return SoundEvent.valueOf(sound.toUpperCase().replaceAll("\\.", "_"));
} catch (IllegalArgumentException ex) { } catch (Exception ex) {
return null; return null;
} }
} }

Datei anzeigen

@ -55,7 +55,7 @@ public class Toolbox {
public static final Int2ObjectMap<ItemEntry> ITEM_ENTRIES = new Int2ObjectOpenHashMap<>(); 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 { static {
/* Load biomes */ /* Load biomes */
@ -129,6 +129,10 @@ public class Toolbox {
entry.getValue().get("bedrock_data").intValue(), entry.getValue().get("bedrock_data").intValue(),
entry.getValue().get("is_block").booleanValue())); entry.getValue().get("is_block").booleanValue()));
} }
if (entry.getKey().equals("minecraft:barrier")) {
BARRIER_INDEX = itemIndex;
}
itemIndex++; itemIndex++;
} }