Start work on inventory/item translators

This commit is contained in:
RednedEpic 2019-07-29 17:20:48 -05:00
parent 77ea4eda60
commit 635a26dd60
19 changed files with 3706 additions and 5 deletions

View file

@ -29,6 +29,8 @@ import org.geysermc.api.command.CommandMap;
import org.geysermc.api.logger.Logger; import org.geysermc.api.logger.Logger;
import org.geysermc.api.plugin.PluginManager; import org.geysermc.api.plugin.PluginManager;
import java.util.concurrent.ScheduledExecutorService;
public interface Connector { public interface Connector {
/** /**
@ -52,6 +54,13 @@ public interface Connector {
*/ */
PluginManager getPluginManager(); PluginManager getPluginManager();
/**
* Returns the general thread pool
*
* @return the general thread pool
*/
ScheduledExecutorService getGeneralThreadPool();
/** /**
* Shuts down the connector * Shuts down the connector
*/ */

View file

@ -29,6 +29,8 @@ import org.geysermc.api.command.CommandMap;
import org.geysermc.api.logger.Logger; import org.geysermc.api.logger.Logger;
import org.geysermc.api.plugin.PluginManager; import org.geysermc.api.plugin.PluginManager;
import java.util.concurrent.ScheduledExecutorService;
public class Geyser { public class Geyser {
private static Connector connector; private static Connector connector;
@ -77,4 +79,8 @@ public class Geyser {
public static CommandMap getCommandMap() { public static CommandMap getCommandMap() {
return connector.getCommandMap(); return connector.getCommandMap();
} }
public static ScheduledExecutorService getGeneralThreadPool() {
return connector.getGeneralThreadPool();
}
} }

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2019 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.inventory;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.mc.protocol.data.game.window.WindowType;
import lombok.Getter;
import lombok.Setter;
public class Inventory {
@Getter
private int id;
@Getter
@Setter
private boolean open;
@Getter
private WindowType windowType;
@Getter
private int size;
@Getter
@Setter
private String title;
@Getter
@Setter
private ItemStack[] items;
public Inventory(int id, WindowType windowType, int size) {
this.id = id;
this.windowType = windowType;
this.size = size;
this.title = "Inventory";
this.items = new ItemStack[size];
}
}

View file

@ -50,6 +50,7 @@ import org.geysermc.api.RemoteServer;
import org.geysermc.api.session.AuthData; import org.geysermc.api.session.AuthData;
import org.geysermc.api.window.FormWindow; import org.geysermc.api.window.FormWindow;
import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.cache.InventoryCache;
import org.geysermc.connector.network.session.cache.WindowCache; import org.geysermc.connector.network.session.cache.WindowCache;
import org.geysermc.connector.network.translators.Registry; import org.geysermc.connector.network.translators.Registry;
import org.geysermc.connector.utils.Toolbox; import org.geysermc.connector.utils.Toolbox;
@ -70,6 +71,9 @@ public class GeyserSession implements PlayerSession, Player {
@Getter @Getter
private AuthData authenticationData; private AuthData authenticationData;
@Getter
private InventoryCache inventoryCache;
@Getter @Getter
private WindowCache windowCache; private WindowCache windowCache;
@ -82,6 +86,7 @@ public class GeyserSession implements PlayerSession, Player {
this.connector = connector; this.connector = connector;
this.upstream = bedrockServerSession; this.upstream = bedrockServerSession;
this.inventoryCache = new InventoryCache(this);
this.windowCache = new WindowCache(this); this.windowCache = new WindowCache(this);
this.loggedIn = false; this.loggedIn = false;

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2019 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.session.cache;
import com.github.steveice10.packetlib.packet.Packet;
import lombok.Getter;
import lombok.Setter;
import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class InventoryCache {
private GeyserSession session;
@Getter
@Setter
private Inventory openInventory;
@Getter
private Map<Integer, Inventory> inventories = new HashMap<Integer, Inventory>();
@Getter
private Map<Integer, List<Packet>> cachedPackets = new HashMap<Integer, List<Packet>>();
public InventoryCache(GeyserSession session) {
this.session = session;
// This is the player's inventory
inventories.put(0, new Inventory(0, null, 45));
}
public Inventory getPlayerInventory() {
return inventories.get(0);
}
public void cacheInventory(Inventory inventory) {
inventories.put(inventory.getId(), inventory);
}
public void uncacheInventory(int id) {
inventories.remove(id);
}
public void cachePacket(int id, Packet packet) {
List<Packet> packets = cachedPackets.getOrDefault(id, new ArrayList<Packet>());
packets.add(packet);
cachedPackets.put(id, packets);
}
}

View file

@ -1,3 +1,28 @@
/*
* Copyright (c) 2019 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.session.cache; package org.geysermc.connector.network.session.cache;
import com.nukkitx.protocol.bedrock.packet.ModalFormRequestPacket; import com.nukkitx.protocol.bedrock.packet.ModalFormRequestPacket;
@ -12,13 +37,13 @@ public class WindowCache {
private GeyserSession session; private GeyserSession session;
@Getter
private Map<Integer, FormWindow> windows = new HashMap<Integer, FormWindow>();
public WindowCache(GeyserSession session) { public WindowCache(GeyserSession session) {
this.session = session; this.session = session;
} }
@Getter
private Map<Integer, FormWindow> windows = new HashMap<Integer, FormWindow>();
public void addWindow(FormWindow window) { public void addWindow(FormWindow window) {
windows.put(windows.size() + 1, window); windows.put(windows.size() + 1, window);
} }

View file

@ -50,9 +50,12 @@ public class Registry<T> {
public <P extends T> void translate(Class<? extends P> clazz, P packet, GeyserSession session) { public <P extends T> void translate(Class<? extends P> clazz, P packet, GeyserSession session) {
try { try {
if (MAP.containsKey(clazz)) {
((PacketTranslator<P>) MAP.get(clazz)).translate(packet, session); ((PacketTranslator<P>) MAP.get(clazz)).translate(packet, session);
}
} catch (NullPointerException ex) { } catch (NullPointerException ex) {
GeyserLogger.DEFAULT.debug("Could not translate packet " + packet.getClass().getSimpleName()); GeyserLogger.DEFAULT.debug("Could not translate packet " + packet.getClass().getSimpleName());
ex.printStackTrace();
} }
} }
} }

View file

@ -25,6 +25,7 @@
package org.geysermc.connector.network.translators; package org.geysermc.connector.network.translators;
import com.github.steveice10.mc.protocol.data.game.window.WindowType;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerChatPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerChatPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerJoinGamePacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerTitlePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.ServerTitlePacket;
@ -32,6 +33,9 @@ import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntit
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPositionRotationPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityPositionRotationPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityTeleportPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityTeleportPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityVelocityPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.entity.ServerEntityVelocityPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerOpenWindowPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerSetSlotPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerWindowItemsPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerNotifyClientPacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerNotifyClientPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateTimePacket; import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateTimePacket;
import com.nukkitx.nbt.CompoundTagBuilder; import com.nukkitx.nbt.CompoundTagBuilder;
@ -41,9 +45,13 @@ import com.nukkitx.nbt.tag.CompoundTag;
import com.nukkitx.protocol.bedrock.packet.AnimatePacket; import com.nukkitx.protocol.bedrock.packet.AnimatePacket;
import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket; import com.nukkitx.protocol.bedrock.packet.CommandRequestPacket;
import com.nukkitx.protocol.bedrock.packet.TextPacket; import com.nukkitx.protocol.bedrock.packet.TextPacket;
import lombok.Getter;
import org.geysermc.connector.network.translators.bedrock.BedrockAnimateTranslator; import org.geysermc.connector.network.translators.bedrock.BedrockAnimateTranslator;
import org.geysermc.connector.network.translators.bedrock.BedrockCommandRequestTranslator; import org.geysermc.connector.network.translators.bedrock.BedrockCommandRequestTranslator;
import org.geysermc.connector.network.translators.bedrock.BedrockTextTranslator; import org.geysermc.connector.network.translators.bedrock.BedrockTextTranslator;
import org.geysermc.connector.network.translators.inventory.GenericInventoryTranslator;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import org.geysermc.connector.network.translators.item.ItemTranslator;
import org.geysermc.connector.network.translators.java.JavaChatTranslator; import org.geysermc.connector.network.translators.java.JavaChatTranslator;
import org.geysermc.connector.network.translators.java.JavaEntityPositionRotationTranslator; import org.geysermc.connector.network.translators.java.JavaEntityPositionRotationTranslator;
import org.geysermc.connector.network.translators.java.JavaEntityPositionTranslator; import org.geysermc.connector.network.translators.java.JavaEntityPositionTranslator;
@ -51,14 +59,25 @@ import org.geysermc.connector.network.translators.java.JavaEntityTeleportTransla
import org.geysermc.connector.network.translators.java.JavaEntityVelocityTranslator; import org.geysermc.connector.network.translators.java.JavaEntityVelocityTranslator;
import org.geysermc.connector.network.translators.java.JavaJoinGameTranslator; import org.geysermc.connector.network.translators.java.JavaJoinGameTranslator;
import org.geysermc.connector.network.translators.java.JavaNotifyClientTranslator; import org.geysermc.connector.network.translators.java.JavaNotifyClientTranslator;
import org.geysermc.connector.network.translators.java.JavaOpenWindowTranslator;
import org.geysermc.connector.network.translators.java.JavaSetSlotTranslator;
import org.geysermc.connector.network.translators.java.JavaTitleTranslator; import org.geysermc.connector.network.translators.java.JavaTitleTranslator;
import org.geysermc.connector.network.translators.java.JavaUpdateTimeTranslator; import org.geysermc.connector.network.translators.java.JavaUpdateTimeTranslator;
import org.geysermc.connector.network.translators.java.JavaWindowItemsTranslator;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class TranslatorsInit { public class TranslatorsInit {
@Getter
private static ItemTranslator itemTranslator;
@Getter
private static Map<WindowType, InventoryTranslator> inventoryTranslators = new HashMap<WindowType, InventoryTranslator>();
private static final CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag(); private static final CompoundTag EMPTY_TAG = CompoundTagBuilder.builder().buildRootTag();
public static final byte[] EMPTY_LEVEL_CHUNK_DATA; public static final byte[] EMPTY_LEVEL_CHUNK_DATA;
@ -86,9 +105,25 @@ public class TranslatorsInit {
Registry.registerJava(ServerEntityTeleportPacket.class, new JavaEntityTeleportTranslator()); Registry.registerJava(ServerEntityTeleportPacket.class, new JavaEntityTeleportTranslator());
Registry.registerJava(ServerEntityVelocityPacket.class, new JavaEntityVelocityTranslator()); Registry.registerJava(ServerEntityVelocityPacket.class, new JavaEntityVelocityTranslator());
Registry.registerJava(ServerNotifyClientPacket.class, new JavaNotifyClientTranslator()); Registry.registerJava(ServerNotifyClientPacket.class, new JavaNotifyClientTranslator());
Registry.registerJava(ServerWindowItemsPacket.class, new JavaWindowItemsTranslator());
Registry.registerJava(ServerOpenWindowPacket.class, new JavaOpenWindowTranslator());
Registry.registerJava(ServerSetSlotPacket.class, new JavaSetSlotTranslator());
Registry.registerBedrock(AnimatePacket.class, new BedrockAnimateTranslator()); Registry.registerBedrock(AnimatePacket.class, new BedrockAnimateTranslator());
Registry.registerBedrock(CommandRequestPacket.class, new BedrockCommandRequestTranslator()); Registry.registerBedrock(CommandRequestPacket.class, new BedrockCommandRequestTranslator());
Registry.registerBedrock(TextPacket.class, new BedrockTextTranslator()); Registry.registerBedrock(TextPacket.class, new BedrockTextTranslator());
itemTranslator = new ItemTranslator();
registerInventoryTranslators();
}
private static void registerInventoryTranslators() {
inventoryTranslators.put(WindowType.GENERIC_9X1, new GenericInventoryTranslator());
inventoryTranslators.put(WindowType.GENERIC_9X2, new GenericInventoryTranslator());
inventoryTranslators.put(WindowType.GENERIC_9X3, new GenericInventoryTranslator());
inventoryTranslators.put(WindowType.GENERIC_9X4, new GenericInventoryTranslator());
inventoryTranslators.put(WindowType.GENERIC_9X5, new GenericInventoryTranslator());
inventoryTranslators.put(WindowType.GENERIC_9X6, new GenericInventoryTranslator());
} }
} }

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 2019 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.inventory;
import com.flowpowered.math.vector.Vector3i;
import com.nukkitx.protocol.bedrock.data.ContainerId;
import com.nukkitx.protocol.bedrock.data.ItemData;
import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket;
import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket;
import com.nukkitx.protocol.bedrock.packet.InventorySlotPacket;
import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.TranslatorsInit;
import org.geysermc.connector.utils.InventoryUtils;
public class GenericInventoryTranslator extends InventoryTranslator {
@Override
public void prepareInventory(GeyserSession session, Inventory inventory) {
// TODO: Add code here
}
@Override
public void openInventory(GeyserSession session, Inventory inventory) {
ContainerOpenPacket containerOpenPacket = new ContainerOpenPacket();
containerOpenPacket.setWindowId((byte) inventory.getId());
containerOpenPacket.setType((byte) 0);
containerOpenPacket.setBlockPosition(new Vector3i(0, 0, 0));
session.getUpstream().sendPacket(containerOpenPacket);
}
@Override
public void updateInventory(GeyserSession session, Inventory inventory) {
ContainerId containerId = InventoryUtils.getContainerId(inventory.getId());
if (containerId == null)
return;
ItemData[] bedrockItems = new ItemData[inventory.getItems().length];
for (int i = 0; i < bedrockItems.length; i++) {
bedrockItems[i] = TranslatorsInit.getItemTranslator().translateToBedrock(inventory.getItems()[i]);
}
InventoryContentPacket contentPacket = new InventoryContentPacket();
contentPacket.setContainerId(containerId);
contentPacket.setContents(bedrockItems);
session.getUpstream().sendPacket(contentPacket);
}
@Override
public void updateSlot(GeyserSession session, Inventory inventory, int slot) {
ContainerId containerId = InventoryUtils.getContainerId(inventory.getId());
if (containerId == null)
return;
InventorySlotPacket slotPacket = new InventorySlotPacket();
slotPacket.setContainerId(containerId);
slotPacket.setSlot(TranslatorsInit.getItemTranslator().translateToBedrock(inventory.getItems()[slot]));
slotPacket.setInventorySlot(slot);
session.getUpstream().sendPacket(slotPacket);
}
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2019 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.inventory;
import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession;
public abstract class InventoryTranslator {
public abstract void prepareInventory(GeyserSession session, Inventory inventory);
public abstract void openInventory(GeyserSession session, Inventory inventory);
public abstract void updateInventory(GeyserSession session, Inventory inventory);
public abstract void updateSlot(GeyserSession session, Inventory inventory, int slot);
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2019 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;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class BedrockItem {
private String identifier;
private int id;
private int data;
}

View file

@ -0,0 +1,324 @@
/*
* Copyright (c) 2019 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;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.opennbt.tag.builtin.ByteArrayTag;
import com.github.steveice10.opennbt.tag.builtin.ByteTag;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.DoubleTag;
import com.github.steveice10.opennbt.tag.builtin.FloatTag;
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.LongArrayTag;
import com.github.steveice10.opennbt.tag.builtin.LongTag;
import com.github.steveice10.opennbt.tag.builtin.ShortTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.nukkitx.protocol.bedrock.data.ItemData;
import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
import org.geysermc.connector.utils.Toolbox;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ItemTranslator {
private static Map<String, String> identifiers = new HashMap<String, String>();
static {
// Key: java translation
// Value: bedrock translation
identifiers.put("grass_block", "grass");
identifiers.put("granite", "stone:1");
identifiers.put("polished_granite", "stone:2");
identifiers.put("diorite", "stone:3");
identifiers.put("polished_diorite", "stone:4");
identifiers.put("andesite", "stone:5");
identifiers.put("polished_andesite", "stone:6");
identifiers.put("spurce_log", "log:1");
identifiers.put("birch_log", "log:2");
identifiers.put("jungle_log", "log:3");
identifiers.put("acacia_log", "log:4");
identifiers.put("dark_oak_log", "log:5");
}
public ItemStack translateToJava(ItemData data) {
JavaItem javaItem = getJavaItem(data);
if (data.getTag() == null) {
return new ItemStack(javaItem.getId(), data.getCount());
}
return new ItemStack(javaItem.getId(), data.getCount(), translateToJavaNBT(data.getTag()));
}
public ItemData translateToBedrock(ItemStack stack) {
// Most likely air if null
if (stack == null) {
return ItemData.AIR;
}
BedrockItem bedrockItem = getBedrockItem(stack);
if (stack.getNBT() == null) {
return ItemData.of(bedrockItem.getId(), (short) bedrockItem.getData(), stack.getAmount());
}
return ItemData.of(bedrockItem.getId(), (short) bedrockItem.getData(), stack.getAmount(), translateToBedrockNBT(stack.getNBT()));
}
public BedrockItem getBedrockItem(ItemStack stack) {
for (Map.Entry<String, JavaItem> javaItems : Toolbox.JAVA_ITEMS.entrySet()) {
if (javaItems.getValue().getId() != stack.getId())
continue;
JavaItem javaItem = javaItems.getValue();
String identifier = getBedrockIdentifier(javaItem.getIdentifier().replace("minecraft:", ""));
if (!Toolbox.BEDROCK_ITEMS.containsKey(identifier))
continue;
return Toolbox.BEDROCK_ITEMS.get(identifier);
}
return new BedrockItem("minecraft:air", 0, 0);
}
public JavaItem getJavaItem(ItemData data) {
for (Map.Entry<String, BedrockItem> bedrockItems : Toolbox.BEDROCK_ITEMS.entrySet()) {
if (bedrockItems.getValue().getId() != data.getId())
continue;
String identifier = getJavaIdentifier(bedrockItems.getKey().replace("minecraft:", ""));
if (!Toolbox.JAVA_ITEMS.containsKey(identifier))
continue;
return Toolbox.JAVA_ITEMS.get(identifier);
}
return new JavaItem("minecraft:air", 0);
}
public String getBedrockIdentifier(String javaIdentifier) {
if (!identifiers.containsKey(javaIdentifier))
return "minecraft:" + javaIdentifier;
return "minecraft:" + identifiers.get(javaIdentifier);
}
public String getJavaIdentifier(String bedrockIdentifier) {
for (Map.Entry<String, String> entry : identifiers.entrySet()) {
if (entry.getValue().equals(bedrockIdentifier)) {
return "minecraft:" + entry.getKey();
}
}
return "minecraft:" + bedrockIdentifier;
}
private CompoundTag translateToJavaNBT(com.nukkitx.nbt.tag.CompoundTag tag) {
CompoundTag javaTag = new CompoundTag(tag.getName());
Map<String, Tag> javaValue = javaTag.getValue();
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
for (String str : tag.getValue().keySet()) {
com.nukkitx.nbt.tag.Tag bedrockTag = tag.get(str);
Tag translatedTag = translateToJavaNBT(bedrockTag);
if (translatedTag == null)
continue;
javaValue.put(str, translatedTag);
}
}
return javaTag;
}
private Tag translateToJavaNBT(com.nukkitx.nbt.tag.Tag tag) {
if (tag instanceof com.nukkitx.nbt.tag.ByteArrayTag) {
com.nukkitx.nbt.tag.ByteArrayTag byteArrayTag = (com.nukkitx.nbt.tag.ByteArrayTag) tag;
return new ByteArrayTag(byteArrayTag.getName(), byteArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ByteTag) {
com.nukkitx.nbt.tag.ByteTag byteTag = (com.nukkitx.nbt.tag.ByteTag) tag;
return new ByteTag(byteTag.getName(), byteTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.DoubleTag) {
com.nukkitx.nbt.tag.DoubleTag doubleTag = (com.nukkitx.nbt.tag.DoubleTag) tag;
return new DoubleTag(doubleTag.getName(), doubleTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.FloatTag) {
com.nukkitx.nbt.tag.FloatTag floatTag = (com.nukkitx.nbt.tag.FloatTag) tag;
return new FloatTag(floatTag.getName(), floatTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.IntArrayTag) {
com.nukkitx.nbt.tag.IntArrayTag intArrayTag = (com.nukkitx.nbt.tag.IntArrayTag) tag;
return new IntArrayTag(intArrayTag.getName(), intArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.IntTag) {
com.nukkitx.nbt.tag.IntTag intTag = (com.nukkitx.nbt.tag.IntTag) tag;
return new IntTag(intTag.getName(), intTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.LongArrayTag) {
com.nukkitx.nbt.tag.LongArrayTag longArrayTag = (com.nukkitx.nbt.tag.LongArrayTag) tag;
return new LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.LongTag) {
com.nukkitx.nbt.tag.LongTag longTag = (com.nukkitx.nbt.tag.LongTag) tag;
return new LongTag(longTag.getName(), longTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ShortTag) {
com.nukkitx.nbt.tag.ShortTag shortTag = (com.nukkitx.nbt.tag.ShortTag) tag;
return new ShortTag(shortTag.getName(), shortTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.StringTag) {
com.nukkitx.nbt.tag.StringTag stringTag = (com.nukkitx.nbt.tag.StringTag) tag;
return new StringTag(stringTag.getName(), stringTag.getValue());
}
if (tag instanceof com.nukkitx.nbt.tag.ListTag) {
com.nukkitx.nbt.tag.ListTag listTag = (com.nukkitx.nbt.tag.ListTag) tag;
List<Tag> tags = new ArrayList<Tag>();
for (Object value : listTag.getValue()) {
if (!(value instanceof com.nukkitx.nbt.tag.Tag))
continue;
com.nukkitx.nbt.tag.Tag tagValue = (com.nukkitx.nbt.tag.Tag) value;
Tag javaTag = translateToJavaNBT(tagValue);
if (javaTag != null)
tags.add(javaTag);
}
return new ListTag(listTag.getName(), tags);
}
if (tag instanceof com.nukkitx.nbt.tag.CompoundTag) {
return translateToJavaNBT((com.nukkitx.nbt.tag.CompoundTag) tag);
}
return null;
}
private com.nukkitx.nbt.tag.CompoundTag translateToBedrockNBT(CompoundTag tag) {
Map<String, com.nukkitx.nbt.tag.Tag<?>> javaValue = new HashMap<String, com.nukkitx.nbt.tag.Tag<?>>();
if (tag.getValue() != null && !tag.getValue().isEmpty()) {
for (String str : tag.getValue().keySet()) {
Tag javaTag = tag.get(str);
com.nukkitx.nbt.tag.Tag translatedTag = translateToBedrockNBT(javaTag);
if (translatedTag == null)
continue;
javaValue.put(str, translatedTag);
}
}
com.nukkitx.nbt.tag.CompoundTag bedrockTag = new com.nukkitx.nbt.tag.CompoundTag(tag.getName(), javaValue);
return bedrockTag;
}
private com.nukkitx.nbt.tag.Tag translateToBedrockNBT(Tag tag) {
if (tag instanceof ByteArrayTag) {
ByteArrayTag byteArrayTag = (ByteArrayTag) tag;
return new com.nukkitx.nbt.tag.ByteArrayTag(byteArrayTag.getName(), byteArrayTag.getValue());
}
if (tag instanceof ByteTag) {
ByteTag byteTag = (ByteTag) tag;
return new com.nukkitx.nbt.tag.ByteTag(byteTag.getName(), byteTag.getValue());
}
if (tag instanceof DoubleTag) {
DoubleTag doubleTag = (DoubleTag) tag;
return new com.nukkitx.nbt.tag.DoubleTag(doubleTag.getName(), doubleTag.getValue());
}
if (tag instanceof FloatTag) {
FloatTag floatTag = (FloatTag) tag;
return new com.nukkitx.nbt.tag.FloatTag(floatTag.getName(), floatTag.getValue());
}
if (tag instanceof IntArrayTag) {
IntArrayTag intArrayTag = (IntArrayTag) tag;
return new com.nukkitx.nbt.tag.IntArrayTag(intArrayTag.getName(), intArrayTag.getValue());
}
if (tag instanceof IntTag) {
IntTag intTag = (IntTag) tag;
return new com.nukkitx.nbt.tag.IntTag(intTag.getName(), intTag.getValue());
}
if (tag instanceof LongArrayTag) {
LongArrayTag longArrayTag = (LongArrayTag) tag;
return new com.nukkitx.nbt.tag.LongArrayTag(longArrayTag.getName(), longArrayTag.getValue());
}
if (tag instanceof LongTag) {
LongTag longTag = (LongTag) tag;
return new com.nukkitx.nbt.tag.LongTag(longTag.getName(), longTag.getValue());
}
if (tag instanceof ShortTag) {
ShortTag shortTag = (ShortTag) tag;
return new com.nukkitx.nbt.tag.ShortTag(shortTag.getName(), shortTag.getValue());
}
if (tag instanceof StringTag) {
StringTag stringTag = (StringTag) tag;
return new com.nukkitx.nbt.tag.StringTag(stringTag.getName(), stringTag.getValue());
}
if (tag instanceof ListTag) {
ListTag listTag = (ListTag) tag;
List<com.nukkitx.nbt.tag.Tag> tags = new ArrayList<com.nukkitx.nbt.tag.Tag>();
for (Object value : listTag.getValue()) {
if (!(value instanceof Tag))
continue;
Tag tagValue = (Tag) value;
com.nukkitx.nbt.tag.Tag bedrockTag = translateToBedrockNBT(tagValue);
if (bedrockTag != null)
tags.add(bedrockTag);
}
// TODO: Fix unchecked call here
return new com.nukkitx.nbt.tag.ListTag(listTag.getName(), listTag.getElementType(), tags);
}
if (tag instanceof CompoundTag) {
return translateToBedrockNBT((CompoundTag) tag);
}
return null;
}
}

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2019 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;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class JavaItem {
private String identifier;
private int id;
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2019 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.java;
import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerOpenWindowPacket;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.utils.InventoryUtils;
public class JavaOpenWindowTranslator extends PacketTranslator<ServerOpenWindowPacket> {
@Override
public void translate(ServerOpenWindowPacket packet, GeyserSession session) {
InventoryUtils.openInventory(session, packet);
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2019 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.java;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerSetSlotPacket;
import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.session.cache.InventoryCache;
import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.utils.InventoryUtils;
public class JavaSetSlotTranslator extends PacketTranslator<ServerSetSlotPacket> {
@Override
public void translate(ServerSetSlotPacket packet, GeyserSession session) {
InventoryCache inventoryCache = session.getInventoryCache();
if (!inventoryCache.getInventories().containsKey(packet.getWindowId())) {
inventoryCache.cachePacket(packet.getWindowId(), packet);
return;
}
Inventory inventory = inventoryCache.getInventories().get(packet.getWindowId());
if (packet.getWindowId() != 0 && inventory.getWindowType() == null)
return;
// Player inventory
if (packet.getWindowId() == 0) {
if (packet.getSlot() >= inventory.getItems().length)
return; // Most likely not a player inventory
ItemStack[] items = inventory.getItems();
items[packet.getSlot()] = packet.getItem();
inventory.setItems(items);
InventoryUtils.refreshPlayerInventory(session, inventory);
if (inventory.isOpen()) {
InventoryUtils.updateSlot(session, packet);
} else {
inventoryCache.cachePacket(packet.getWindowId(), packet);
}
}
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2019 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.java;
import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerWindowItemsPacket;
import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.session.cache.InventoryCache;
import org.geysermc.connector.network.translators.PacketTranslator;
import org.geysermc.connector.utils.InventoryUtils;
public class JavaWindowItemsTranslator extends PacketTranslator<ServerWindowItemsPacket> {
@Override
public void translate(ServerWindowItemsPacket packet, GeyserSession session) {
InventoryCache inventoryCache = session.getInventoryCache();
if (!inventoryCache.getInventories().containsKey(packet.getWindowId())) {
inventoryCache.cachePacket(packet.getWindowId(), packet);
return;
}
Inventory inventory = inventoryCache.getInventories().get(packet.getWindowId());
// Player inventory
if (packet.getWindowId() == 0) {
inventory.setItems(packet.getItems());
InventoryUtils.refreshPlayerInventory(session, inventory);
return;
}
InventoryUtils.updateInventory(session, packet);
}
}

View file

@ -0,0 +1,122 @@
package org.geysermc.connector.utils;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientCloseWindowPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerOpenWindowPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerSetSlotPacket;
import com.github.steveice10.mc.protocol.packet.ingame.server.window.ServerWindowItemsPacket;
import com.github.steveice10.packetlib.packet.Packet;
import com.nukkitx.protocol.bedrock.data.ContainerId;
import com.nukkitx.protocol.bedrock.data.ItemData;
import com.nukkitx.protocol.bedrock.packet.InventoryContentPacket;
import org.geysermc.api.Geyser;
import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.TranslatorsInit;
import org.geysermc.connector.network.translators.inventory.InventoryTranslator;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class InventoryUtils {
public static void refreshPlayerInventory(GeyserSession session, Inventory inventory) {
InventoryContentPacket inventoryContentPacket = new InventoryContentPacket();
inventoryContentPacket.setContainerId(ContainerId.INVENTORY);
ItemData[] contents = new ItemData[40];
// Inventory
for (int i = 9; i < 36; i++) {
contents[i] = TranslatorsInit.getItemTranslator().translateToBedrock(inventory.getItems()[i]);
}
// Hotbar
for (int i = 36; i < 45; i++) {
contents[i - 36] = TranslatorsInit.getItemTranslator().translateToBedrock(inventory.getItems()[i]);
}
// Armor
for (int i = 5; i < 9; i++) {
contents[i + 31] = TranslatorsInit.getItemTranslator().translateToBedrock(inventory.getItems()[i]);
}
inventoryContentPacket.setContents(contents);
session.getUpstream().sendPacket(inventoryContentPacket);
}
public static void openInventory(GeyserSession session, ServerOpenWindowPacket packet) {
Inventory inventory = new Inventory(packet.getWindowId(), packet.getType(), 45); // TODO: Find a way to set this value
session.getInventoryCache().getInventories().put(packet.getWindowId(), inventory);
session.getInventoryCache().setOpenInventory(inventory);
InventoryTranslator translator = TranslatorsInit.getInventoryTranslators().get(inventory.getWindowType());
translator.prepareInventory(session, inventory);
Geyser.getGeneralThreadPool().schedule(() -> {
List<Packet> packets = session.getInventoryCache().getCachedPackets().get(inventory.getId());
packets.forEach(itemPacket -> {
if (itemPacket != null) {
if (ServerWindowItemsPacket.class.isAssignableFrom(itemPacket.getClass())) {
updateInventory(session, (ServerWindowItemsPacket) itemPacket);
}
}
});
}, 200, TimeUnit.MILLISECONDS);
}
public static void updateInventory(GeyserSession session, ServerWindowItemsPacket packet) {
if (packet.getWindowId() == 0)
return;
if (session.getInventoryCache().getOpenInventory() == null || !session.getInventoryCache().getInventories().containsKey(packet.getWindowId()))
return;
Inventory openInventory = session.getInventoryCache().getOpenInventory();
if (packet.getWindowId() != openInventory.getId())
return;
InventoryTranslator translator = TranslatorsInit.getInventoryTranslators().get(openInventory.getWindowType());
if (translator == null) {
session.getDownstream().getSession().send(new ClientCloseWindowPacket(packet.getWindowId()));
return;
}
openInventory.setItems(packet.getItems());
translator.updateInventory(session, openInventory);
}
public static void updateSlot(GeyserSession session, ServerSetSlotPacket packet) {
if (packet.getWindowId() == 0)
return;
if (session.getInventoryCache().getOpenInventory() == null || !session.getInventoryCache().getInventories().containsKey(packet.getWindowId()))
return;
Inventory openInventory = session.getInventoryCache().getOpenInventory();
if (packet.getWindowId() != openInventory.getId())
return;
InventoryTranslator translator = TranslatorsInit.getInventoryTranslators().get(openInventory.getWindowType());
if (translator == null) {
session.getDownstream().getSession().send(new ClientCloseWindowPacket(packet.getWindowId()));
return;
}
if (packet.getSlot() >= openInventory.getSize()) {
session.getDownstream().getSession().send(new ClientCloseWindowPacket(packet.getWindowId()));
return;
}
ItemStack[] items = openInventory.getItems();
items[packet.getSlot()] = packet.getItem();
translator.updateSlot(session, openInventory, packet.getSlot());
}
public static ContainerId getContainerId(int id) {
for (ContainerId value : ContainerId.values()) {
if (value.id() == id)
return value;
}
return null;
}
}

View file

@ -1,11 +1,14 @@
package org.geysermc.connector.utils; package org.geysermc.connector.utils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.nukkitx.network.VarInts; import com.nukkitx.network.VarInts;
import com.nukkitx.protocol.bedrock.packet.StartGamePacket; import com.nukkitx.protocol.bedrock.packet.StartGamePacket;
import com.nukkitx.protocol.bedrock.v361.BedrockUtils; import com.nukkitx.protocol.bedrock.v361.BedrockUtils;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import org.geysermc.connector.network.translators.item.BedrockItem;
import org.geysermc.connector.network.translators.item.JavaItem;
import java.io.InputStream; import java.io.InputStream;
import java.util.*; import java.util.*;
@ -23,6 +26,16 @@ public class Toolbox {
e.printStackTrace(); e.printStackTrace();
} }
Map<String, BedrockItem> bedrockItems = new HashMap<String, BedrockItem>();
for (Map<String, Object> e : entries) {
BedrockItem bedrockItem = new BedrockItem((String) e.get("name"), (int) e.get("id"), (int) e.get("data"));
if (bedrockItem.getData() != 0) {
bedrockItems.put(bedrockItem.getIdentifier() + ":" + bedrockItem.getData(), bedrockItem);
} else {
bedrockItems.put(bedrockItem.getIdentifier(), bedrockItem);
}
}
ByteBuf b = Unpooled.buffer(); ByteBuf b = Unpooled.buffer();
VarInts.writeUnsignedInt(b, entries.size()); VarInts.writeUnsignedInt(b, entries.size());
for (Map<String, Object> e : entries) { for (Map<String, Object> e : entries) {
@ -46,17 +59,43 @@ public class Toolbox {
e.printStackTrace(); e.printStackTrace();
} }
ArrayList<StartGamePacket.ItemEntry> l = new ArrayList<>(); List<StartGamePacket.ItemEntry> l = new ArrayList<>();
for (HashMap e : s) { for (HashMap e : s) {
l.add(new StartGamePacket.ItemEntry((String) e.get("name"), (short) ((int) e.get("id")))); l.add(new StartGamePacket.ItemEntry((String) e.get("name"), (short) ((int) e.get("id"))));
if (!bedrockItems.containsKey(e.get("name"))) {
BedrockItem bedrockItem = new BedrockItem((String) e.get("name"), ((int) e.get("id")), 0);
bedrockItems.put(bedrockItem.getIdentifier(), bedrockItem);
}
} }
ITEMS = l; ITEMS = l;
BEDROCK_ITEMS = bedrockItems;
InputStream javaItemStream = Toolbox.class.getClassLoader().getResourceAsStream("java_items.json");
ObjectMapper javaItemMapper = new ObjectMapper();
Map<String, HashMap> javaItemList = new HashMap<String, HashMap>();
try {
javaItemList = javaItemMapper.readValue(javaItemStream, new TypeReference<Map<String, HashMap>>(){});
} catch (Exception ex) {
ex.printStackTrace();
}
Map<String, JavaItem> javaItems = new HashMap<String, JavaItem>();
for (String str : javaItemList.keySet()) {
javaItems.put(str, new JavaItem(str, (int) javaItemList.get(str).get("protocol_id")));
}
JAVA_ITEMS = javaItems;
} }
public static final Collection<StartGamePacket.ItemEntry> ITEMS; public static final Collection<StartGamePacket.ItemEntry> ITEMS;
public static final ByteBuf CACHED_PALLETE; public static final ByteBuf CACHED_PALLETE;
public static final Map<String, BedrockItem> BEDROCK_ITEMS;
public static final Map<String, JavaItem> JAVA_ITEMS;
//public static final byte[] EMPTY_CHUNK; //public static final byte[] EMPTY_CHUNK;
} }

File diff suppressed because it is too large Load diff