diff --git a/src/main/java/org/dragonet/proxy/data/inventory/ContainerId.java b/src/main/java/org/dragonet/proxy/data/inventory/ContainerId.java
index b082459a3..51793d91f 100644
--- a/src/main/java/org/dragonet/proxy/data/inventory/ContainerId.java
+++ b/src/main/java/org/dragonet/proxy/data/inventory/ContainerId.java
@@ -4,6 +4,7 @@
* Created on 2017/10/21.
*/
public enum ContainerId {
+
NONE(1),
INVENTORY(0),
FIRST(1),
diff --git a/src/main/java/org/dragonet/proxy/data/inventory/PEWindowConstantID.java b/src/main/java/org/dragonet/proxy/data/inventory/PEWindowConstantID.java
deleted file mode 100644
index 0207bbc83..000000000
--- a/src/main/java/org/dragonet/proxy/data/inventory/PEWindowConstantID.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * GNU LESSER GENERAL PUBLIC LICENSE
- * Version 3, 29 June 2007
- *
- * Copyright (C) 2007 Free Software Foundation, Inc.
- * Everyone is permitted to copy and distribute verbatim copies
- * of this license document, but changing it is not allowed.
- *
- * You can view LICENCE file for details.
- *
- * @author The Dragonet Team
- */
-package org.dragonet.proxy.data.inventory;
-
-public enum PEWindowConstantID {
- PLAYER_INVENTORY(0x00),
- PLAYER_ARMOR(0x78),
- PLAYER_CREATIVE(0x79);
-
- private final byte id;
-
- PEWindowConstantID(int id) {
- this.id = (byte) id;
- }
-
- public byte getId() {
- return id;
- }
-}
diff --git a/src/main/java/org/dragonet/proxy/network/InventoryTranslatorRegister.java b/src/main/java/org/dragonet/proxy/network/InventoryTranslatorRegister.java
index 4a8ff3c8f..0784415a5 100644
--- a/src/main/java/org/dragonet/proxy/network/InventoryTranslatorRegister.java
+++ b/src/main/java/org/dragonet/proxy/network/InventoryTranslatorRegister.java
@@ -21,7 +21,7 @@
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 org.dragonet.proxy.data.inventory.PEWindowConstantID;
+import org.dragonet.proxy.data.inventory.ContainerId;
import org.dragonet.proxy.network.cache.CachedWindow;
import org.dragonet.proxy.network.translator.ItemBlockTranslator;
import org.dragonet.proxy.network.translator.inv.ChestWindowTranslator;
@@ -44,7 +44,7 @@ public static PEPacket[] sendPlayerInventory(UpstreamSession session) {
CachedWindow win = session.getWindowCache().getPlayerInventory();
// Translate and send
InventoryContentPacket ret = new InventoryContentPacket();
- ret.windowId = PEWindowConstantID.PLAYER_INVENTORY.getId();
+ ret.windowId = ContainerId.INVENTORY.getId();
ret.items = new Slot[40];
// hotbar
for (int i = 36; i < 45; i++) {
@@ -66,7 +66,7 @@ public static PEPacket[] sendPlayerInventory(UpstreamSession session) {
public static void open(UpstreamSession session, ServerOpenWindowPacket win) {
closeOpened(session, true);
if (TRANSLATORS.containsKey(win.getType())) {
- CachedWindow cached = new CachedWindow(win.getWindowId(), win.getType(), win.getSlots());
+ CachedWindow cached = new CachedWindow(win.getWindowId(), win.getType(), win.getSlots() + 36/* player inventory */);
session.getWindowCache().cacheWindow(cached);
TRANSLATORS.get(win.getType()).open(session, cached);
com.github.steveice10.packetlib.packet.Packet[] items = session.getWindowCache().getCachedPackets(win.getWindowId());
@@ -79,7 +79,6 @@ public static void open(UpstreamSession session, ServerOpenWindowPacket win) {
}
}
}
- System.out.println("Window " + win.getWindowId() + " opened !");
} else {
// Not supported
session.getDownstream().send(new ClientCloseWindowPacket(win.getWindowId()));
@@ -90,7 +89,6 @@ public static void closeOpened(UpstreamSession session, boolean byServer) {
if (session.getDataCache().containsKey(CacheKey.WINDOW_OPENED_ID)) {
// There is already a window opened
int id = (int) session.getDataCache().remove(CacheKey.WINDOW_OPENED_ID);
- System.out.println("Window " + id + " closed !");
if (byServer) {
session.sendPacket(new ContainerClosePacket(id), true);
} else {
@@ -150,7 +148,6 @@ public static void updateSlot(UpstreamSession session, ServerSetSlotPacket packe
return;
}
CachedWindow win = session.getWindowCache().get(openedId);
- System.out.println("WIN=" + win.slots.length + ", REQ_SLOT=" + packet.getSlot());
if (win.size <= packet.getSlot()) {
session.getDownstream().send(new ClientCloseWindowPacket(packet.getWindowId()));
return;
diff --git a/src/main/java/org/dragonet/proxy/network/cache/CachedWindow.java b/src/main/java/org/dragonet/proxy/network/cache/CachedWindow.java
index ebcca7db7..44bfbde70 100644
--- a/src/main/java/org/dragonet/proxy/network/cache/CachedWindow.java
+++ b/src/main/java/org/dragonet/proxy/network/cache/CachedWindow.java
@@ -20,27 +20,21 @@
import java.util.Map;
public class CachedWindow {
- // vars
- public final int windowId;
- /**
- * The type of this window on remote side, -1 for player inventory.
- */
- public final WindowType pcType;
- public final int size;
- public String title = "Window";
- public final Map properties = Collections.synchronizedMap(new HashMap());
- public ItemStack[] slots;
- // constructor
- public CachedWindow(int windowId, WindowType pcType, int size) {
- this.windowId = windowId;
- this.pcType = pcType;
- this.size = size + 36; //add player inventory slots
- slots = new ItemStack[this.size];
- }
-
- // public
-
- // private
+ public final int windowId;
+ /**
+ * The type of this window on remote side, -1 for player inventory.
+ */
+ public final WindowType pcType;
+ public final int size;
+ public String title = "Window";
+ public final Map properties = Collections.synchronizedMap(new HashMap());
+ public ItemStack[] slots;
+ public CachedWindow(int windowId, WindowType pcType, int size) {
+ this.windowId = windowId;
+ this.pcType = pcType;
+ this.size = size;
+ slots = new ItemStack[this.size];
+ }
}
diff --git a/src/main/java/org/dragonet/proxy/network/cache/WindowCache.java b/src/main/java/org/dragonet/proxy/network/cache/WindowCache.java
index a3986dcc7..abbb41af9 100644
--- a/src/main/java/org/dragonet/proxy/network/cache/WindowCache.java
+++ b/src/main/java/org/dragonet/proxy/network/cache/WindowCache.java
@@ -19,71 +19,70 @@
import java.util.Map;
import com.github.steveice10.packetlib.packet.Packet;
+import java.util.concurrent.atomic.AtomicInteger;
import org.dragonet.proxy.network.UpstreamSession;
public final class WindowCache {
- // vars
- private final UpstreamSession upstream;
- private final Map windows = Collections
- .synchronizedMap(new HashMap());
- private final Map> cachedItems = Collections
- .synchronizedMap(new HashMap>());
- // constructor
- public WindowCache(UpstreamSession upstream) {
- this.upstream = upstream;
+ private final UpstreamSession upstream;
+ private final Map windows = Collections
+ .synchronizedMap(new HashMap());
+ private final Map> cachedItems = Collections
+ .synchronizedMap(new HashMap>());
+
+ public AtomicInteger currentTransactionId = new AtomicInteger();
- CachedWindow inv = new CachedWindow(0, null, 45);
- windows.put(0, inv);
- }
+ public WindowCache(UpstreamSession upstream) {
+ this.upstream = upstream;
- // public
- public UpstreamSession getUpstream() {
- return upstream;
- }
+ CachedWindow inv = new CachedWindow(0, null, 45);
+ windows.put(0, inv);
+ }
- public CachedWindow getPlayerInventory() {
- return windows.get(0);
- }
+ // public
+ public UpstreamSession getUpstream() {
+ return upstream;
+ }
- // We do not do translations here, do it in InventoryTranslatorRegister
- public void cacheWindow(CachedWindow win) {
- windows.put(win.windowId, win);
- }
+ public CachedWindow getPlayerInventory() {
+ return windows.get(0);
+ }
- public CachedWindow removeWindow(int id) {
- return windows.remove(id);
- }
+ // We do not do translations here, do it in InventoryTranslatorRegister
+ public void cacheWindow(CachedWindow win) {
+ windows.put(win.windowId, win);
+ }
- public CachedWindow get(int id) {
- return windows.get(id);
- }
+ public CachedWindow removeWindow(int id) {
+ return windows.remove(id);
+ }
- public boolean hasWindow(int id) {
- return windows.containsKey(id);
- }
+ public CachedWindow get(int id) {
+ return windows.get(id);
+ }
- public void newCachedPacket(int windowId, Packet packet) {
- List packets = null;
- synchronized (cachedItems) {
- packets = cachedItems.get(windowId);
- if (packets == null) {
- packets = new ArrayList<>();
- cachedItems.put(windowId, packets);
- }
- }
- packets.add(packet);
- }
+ public boolean hasWindow(int id) {
+ return windows.containsKey(id);
+ }
- public Packet[] getCachedPackets(int windowId) {
- List packets = null;
- packets = cachedItems.remove(windowId);
- if (packets == null) {
- return null;
- }
- return packets.toArray(new Packet[0]);
- }
-
- // private
+ public void newCachedPacket(int windowId, Packet packet) {
+ List packets = null;
+ synchronized (cachedItems) {
+ packets = cachedItems.get(windowId);
+ if (packets == null) {
+ packets = new ArrayList<>();
+ cachedItems.put(windowId, packets);
+ }
+ }
+ packets.add(packet);
+ }
+ public Packet[] getCachedPackets(int windowId) {
+ List packets = null;
+ packets = cachedItems.remove(windowId);
+ if (packets == null) {
+ return null;
+ }
+ return packets.toArray(new Packet[0]);
+ }
}
diff --git a/src/main/java/org/dragonet/proxy/network/translator/ItemBlockTranslator.java b/src/main/java/org/dragonet/proxy/network/translator/ItemBlockTranslator.java
index c67bad216..148c69b89 100644
--- a/src/main/java/org/dragonet/proxy/network/translator/ItemBlockTranslator.java
+++ b/src/main/java/org/dragonet/proxy/network/translator/ItemBlockTranslator.java
@@ -100,6 +100,7 @@ public class ItemBlockTranslator {
swap(255, 252); //structure_block
//ITEMS
+ toPEOverride(343, 342); //minecart_furnace (unavailable on PE)
swap(416, 425); //armor_stand horsearmorleather
toPCOverride(425, 417); //horsearmorleather horsearmoriron (unavailable on PC)
@@ -111,7 +112,8 @@ public class ItemBlockTranslator {
swap(447, new ItemEntry(333, 4)); //acacia_boat
swap(448, new ItemEntry(333, 5)); //dark_oak_boat
- swap(449, 450); //totem shulker_shell
+ swap(449, 450); //totem
+ swap(450, 445); //shulker_shell
swap(2256, 500); //record_13
swap(2257, 501); //record_cat
@@ -338,18 +340,8 @@ public static org.dragonet.proxy.data.nbt.tag.CompoundTag translateBlockEntityTo
}
public static ItemStack translateToPC(Slot slot) {
- ItemStack item;
- org.dragonet.proxy.data.nbt.tag.CompoundTag tag = slot.tag;
- if (tag != null && tag.contains(DRAGONET_COMPOUND)) {
- item = new ItemStack(tag.getCompound(DRAGONET_COMPOUND).getShort("id"),
- tag.getCompound(DRAGONET_COMPOUND).getShort("amount"),
- tag.getCompound(DRAGONET_COMPOUND).getShort("data"));
- } else {
- ItemEntry entry = translateToPC(slot.id, slot.damage);
- item = new ItemStack(entry.id, slot.count, entry.damage != null ? entry.damage : slot.damage);
- }
-
- return item;
+ ItemEntry entry = translateToPC(slot.id, slot.damage);
+ return new ItemStack(entry.id, slot.count, entry.damage != null ? entry.damage : slot.damage); //TODO NBT
}
public static BlockFace translateToPC(int face) {
@@ -381,8 +373,8 @@ private static void toPEOverride(int fromPc, ItemEntry toPe) {
PC_TO_PE_OVERRIDE.put(fromPc, toPe);
}
- private static void toPCOverride(int fromEc, int toPc) {
- PE_TO_PC_OVERRIDE.put(fromEc, new ItemEntry(toPc));
+ private static void toPCOverride(int fromPc, int toPc) {
+ PE_TO_PC_OVERRIDE.put(fromPc, new ItemEntry(toPc));
}
private static void toPCOverride(int fromPc, ItemEntry toPe) {
diff --git a/src/main/java/org/dragonet/proxy/network/translator/inv/ChestWindowTranslator.java b/src/main/java/org/dragonet/proxy/network/translator/inv/ChestWindowTranslator.java
index 6d1828d70..fe8723ec0 100644
--- a/src/main/java/org/dragonet/proxy/network/translator/inv/ChestWindowTranslator.java
+++ b/src/main/java/org/dragonet/proxy/network/translator/inv/ChestWindowTranslator.java
@@ -12,7 +12,6 @@
*/
package org.dragonet.proxy.network.translator.inv;
-import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.dragonet.proxy.data.inventory.InventoryType;
import org.dragonet.proxy.network.CacheKey;
import org.dragonet.proxy.network.UpstreamSession;
@@ -61,8 +60,6 @@ public void updateSlot(UpstreamSession session, CachedWindow win, int slotIndex)
pk.slotId = slotIndex;
pk.windowId = win.windowId;
session.sendPacket(pk, true);
- System.out.println("update window " + + win.windowId + " slot " + slotIndex);
-// sendContent(session, window);// TOO LAZY LOL
}
private void sendContent(UpstreamSession session, CachedWindow win) {
@@ -73,6 +70,5 @@ private void sendContent(UpstreamSession session, CachedWindow win) {
pk.items[i] = ItemBlockTranslator.translateSlotToPE(win.slots[i]);
}
session.sendPacket(pk, true);
- System.out.println("update window " + + win.windowId + " set all content");
}
}
diff --git a/src/main/java/org/dragonet/proxy/network/translator/pe/PEInventoryTransactionPacketTranslator.java b/src/main/java/org/dragonet/proxy/network/translator/pe/PEInventoryTransactionPacketTranslator.java
index 8f7a5f696..5f5fee620 100644
--- a/src/main/java/org/dragonet/proxy/network/translator/pe/PEInventoryTransactionPacketTranslator.java
+++ b/src/main/java/org/dragonet/proxy/network/translator/pe/PEInventoryTransactionPacketTranslator.java
@@ -4,9 +4,11 @@
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.InteractAction;
+import com.github.steveice10.mc.protocol.data.game.window.ClickItemParam;
import com.github.steveice10.mc.protocol.data.game.window.DropItemParam;
import com.github.steveice10.mc.protocol.data.game.window.WindowAction;
import com.github.steveice10.mc.protocol.data.game.window.WindowActionParam;
+import com.github.steveice10.mc.protocol.data.game.window.WindowType;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerActionPacket;
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerInteractEntityPacket;
@@ -17,13 +19,16 @@
import com.github.steveice10.packetlib.packet.Packet;
import java.util.ArrayList;
import java.util.List;
+
+import org.dragonet.proxy.data.inventory.ContainerId;
import org.dragonet.proxy.network.CacheKey;
import org.dragonet.proxy.network.UpstreamSession;
import org.dragonet.proxy.network.cache.CachedEntity;
+import org.dragonet.proxy.network.cache.CachedWindow;
+import org.dragonet.proxy.network.cache.WindowCache;
import org.dragonet.proxy.network.translator.IPEPacketTranslator;
import org.dragonet.proxy.network.translator.ItemBlockTranslator;
import org.dragonet.proxy.protocol.packets.InventoryTransactionPacket;
-import static org.dragonet.proxy.protocol.packets.InventoryTransactionPacket.*;
import org.dragonet.proxy.protocol.type.InventoryTransactionAction;
import org.dragonet.proxy.protocol.type.Slot;
import org.dragonet.proxy.protocol.type.transaction.data.ReleaseItemData;
@@ -42,31 +47,77 @@ public class PEInventoryTransactionPacketTranslator implements IPEPacketTranslat
@Override
public Packet[] translate(UpstreamSession session, InventoryTransactionPacket packet) {
//debug
-// System.out.println("InventoryTransactionPacket type : " + DebugTools.getAllFields(packet));
-// for(InventoryTransactionAction action : packet.actions) {
-// System.out.println(DebugTools.getAllFields(action));
+// if (packet.transactionType == InventoryTransactionPacket.TYPE_NORMAL) {
+// System.out.println(">>>>============================");
+//// System.out.println("InventoryTransactionPacket type: \n" + DebugTools.getAllFields(packet));
+//// System.out.println("-------------");
+// for (InventoryTransactionAction action : packet.actions) {
+// System.out.println(DebugTools.getAllFields(action));
+// }
+// System.out.println("<<<<============================");
// }
+ // /!\ THIS IS A SIMPLE HANDLING WITHOUT JAVA DENY TRANSACTION
switch (packet.transactionType) {
- case TYPE_NORMAL: //0
+ case InventoryTransactionPacket.TYPE_NORMAL: //0 INVENTORY & CHEST
System.out.println("TYPE_NORMAL");
- List packets = new ArrayList();
+ Slot cursor = null;
+ if (packet.actions.length <= 2 && packet.actions[0].sourceType == InventoryTransactionAction.SOURCE_WORLD && packet.actions[1].containerId == ContainerId.INVENTORY.getId()) //main inventory
+ {
+ // drop item
+ ClientPlayerActionPacket act = new ClientPlayerActionPacket(
+ com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction.DROP_ITEM,
+ new Position(0, 0, 0),
+ BlockFace.DOWN);
+ return new Packet[]{act};
+ }
+ if (packet.actions.length == 2 && packet.actions[0].sourceType == InventoryTransactionAction.SOURCE_CONTAINER && packet.actions[1].containerId == ContainerId.CURSOR.getId()) {
+ // desktop version: click on an item (maybe pick/place/merge/swap)
- for (InventoryTransactionAction action : packet.actions) {
- if (action.sourceType == InventoryTransactionAction.SOURCE_WORLD) //main inventory
- {
- ClientPlayerActionPacket act = new ClientPlayerActionPacket(
- com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction.DROP_ITEM,
- new Position(0, 0, 0),
- BlockFace.DOWN);
- packets.add(act);
+ cursor = packet.actions[1].newItem; //set the cursor
+ int container = packet.actions[0].containerId;
+ int slot = packet.actions[0].slotId;
+ if (container == 0) { // if 0, source is player inv
+ if (slot > 5 && slot <= 9) {
+ System.out.println("interact in player inventory (stuff)");
+ }
+ if (slot > 9 && slot <= 36) {
+ System.out.println("interact in player inventory (inventory)");
+ }
+ if (slot > 36 && slot <= 45) {
+ System.out.println("interact in player inventory (hotbar)");
+ }
+ container = (int) session.getDataCache().get(CacheKey.WINDOW_OPENED_ID);
+ slot += 18; //normal chest 0 -> 26 + inv 27 -> 62
}
+ System.out.println("interact in chest (" + container + ") slot " + slot);
+
+ // send action to server
+ ClientWindowActionPacket windowActionPacket = new ClientWindowActionPacket(
+ container, //window id
+ session.getWindowCache().currentTransactionId.incrementAndGet(), //transaction id
+ slot, //slot
+ ItemBlockTranslator.translateToPC(cursor),
+ WindowAction.CLICK_ITEM,
+ (WindowActionParam) ClickItemParam.LEFT_CLICK
+ );
+ session.getDownstream().send(windowActionPacket);
+
+ // after the previous one, we can detect SHIFT click or move items on mobile devices
+ if (packet.actions.length == 2 && packet.actions[0].sourceType == InventoryTransactionAction.SOURCE_CONTAINER && packet.actions[1].sourceType == InventoryTransactionAction.SOURCE_CONTAINER) {
+ // mobile version: move item
+ // desktop version: SHIFT-click item
+ System.out.println("Move item from " + packet.actions[0].containerId + " slot " + packet.actions[0].slotId
+ + " to " + packet.actions[1].containerId + " slot " + packet.actions[1].slotId);
+ }
+
+ System.out.println("Cursor set to " + cursor);
}
- return packets.toArray(new Packet[]{});
- case TYPE_MISMATCH: //1
+ return null; // it's okay to return null
+ case InventoryTransactionPacket.TYPE_MISMATCH: //1
System.out.println("TYPE_MISMATCH");
break;
- case TYPE_USE_ITEM: //2
+ case InventoryTransactionPacket.TYPE_USE_ITEM: //2
System.out.println("TYPE_USE_ITEM");
UseItemData useItemData = (UseItemData) packet.transactionData;
if (useItemData.blockPos.equals(new BlockPosition(0, 0, 0))) {
@@ -97,7 +148,7 @@ public Packet[] translate(UpstreamSession session, InventoryTransactionPacket pa
}
}
- case TYPE_USE_ITEM_ON_ENTITY: //3
+ case InventoryTransactionPacket.TYPE_USE_ITEM_ON_ENTITY: //3
System.out.println("TYPE_USE_ITEM_ON_ENTITY");
UseItemOnEntityData useItemOnEntityData = (UseItemOnEntityData) packet.transactionData;
CachedEntity cachedEntity = session.getEntityCache().getByLocalEID(useItemOnEntityData.entityRuntimeId);
@@ -113,7 +164,7 @@ public Packet[] translate(UpstreamSession session, InventoryTransactionPacket pa
interractAction
);
return new Packet[]{interractPacket};
- case TYPE_RELEASE_ITEM: //4
+ case InventoryTransactionPacket.TYPE_RELEASE_ITEM: //4
System.out.println("TYPE_RELEASE_ITEM");
ReleaseItemData releaseItemData = (ReleaseItemData) packet.transactionData;
// ClientPlayerActionPacket act = new ClientPlayerActionPacket(
diff --git a/src/main/java/org/dragonet/proxy/protocol/type/Slot.java b/src/main/java/org/dragonet/proxy/protocol/type/Slot.java
index 48b0520d4..5d3f66410 100644
--- a/src/main/java/org/dragonet/proxy/protocol/type/Slot.java
+++ b/src/main/java/org/dragonet/proxy/protocol/type/Slot.java
@@ -42,4 +42,16 @@ public Slot(int id, int damage, int count, CompoundTag tag) {
public Slot clone() {
return new Slot(id, damage, count, tag);
}
+
+ public String toString()
+ {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Slot{");
+ buffer.append("id=" + id);
+ buffer.append(", damage=" + damage);
+ buffer.append(", count=" + count);
+ buffer.append(", tag=" + tag);
+ buffer.append("}");
+ return buffer.toString();
+ }
}