Merge branch 'server-inventory' of https://github.com/GeyserMC/Geyser into server-inventory

This commit is contained in:
Camotoy 2021-01-01 14:22:44 -05:00
commit 7a82852134
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
8 changed files with 38 additions and 25 deletions

View file

@ -42,7 +42,6 @@ public class GeyserItemStack {
private int amount; private int amount;
private CompoundTag nbt; private CompoundTag nbt;
private int netId; private int netId;
private boolean netIdWasUpdated;
public GeyserItemStack(int javaId) { public GeyserItemStack(int javaId) {
this(javaId, 1); this(javaId, 1);
@ -61,7 +60,6 @@ public class GeyserItemStack {
this.amount = amount; this.amount = amount;
this.nbt = nbt; this.nbt = nbt;
this.netId = netId; this.netId = netId;
this.netIdWasUpdated = !this.isEmpty();
} }
public int getJavaId() { public int getJavaId() {
@ -78,7 +76,6 @@ public class GeyserItemStack {
public void setNetId(int netId) { public void setNetId(int netId) {
this.netId = netId; this.netId = netId;
this.netIdWasUpdated = true;
} }
public int getNetId() { public int getNetId() {

View file

@ -79,6 +79,11 @@ public class Inventory {
public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) { public void setItem(int slot, @NonNull GeyserItemStack newItem, GeyserSession session) {
GeyserItemStack oldItem = items[slot]; GeyserItemStack oldItem = items[slot];
updateItemNetId(oldItem, newItem, session);
items[slot] = newItem;
}
protected static void updateItemNetId(GeyserItemStack oldItem, GeyserItemStack newItem, GeyserSession session) {
if (!newItem.isEmpty()) { if (!newItem.isEmpty()) {
if (newItem.getItemData(session).equals(oldItem.getItemData(session), false, false, false)) { if (newItem.getItemData(session).equals(oldItem.getItemData(session), false, false, false)) {
newItem.setNetId(oldItem.getNetId()); newItem.setNetId(oldItem.getNetId());
@ -86,7 +91,6 @@ public class Inventory {
newItem.setNetId(session.getNextItemNetId()); newItem.setNetId(session.getNextItemNetId());
} }
} }
items[slot] = newItem;
} }
public short getNextTransactionId() { public short getNextTransactionId() {

View file

@ -28,6 +28,7 @@ package org.geysermc.connector.inventory;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.Setter; import lombok.Setter;
import org.geysermc.connector.network.session.GeyserSession;
public class PlayerInventory extends Inventory { public class PlayerInventory extends Inventory {
@ -40,7 +41,6 @@ public class PlayerInventory extends Inventory {
private int heldItemSlot; private int heldItemSlot;
@Getter @Getter
@Setter
@NonNull @NonNull
private GeyserItemStack cursor = GeyserItemStack.EMPTY; private GeyserItemStack cursor = GeyserItemStack.EMPTY;
@ -49,6 +49,11 @@ public class PlayerInventory extends Inventory {
heldItemSlot = 0; heldItemSlot = 0;
} }
public void setCursor(@NonNull GeyserItemStack newCursor, GeyserSession session) {
updateItemNetId(cursor, newCursor, session);
cursor = newCursor;
}
public GeyserItemStack getItemInHand() { public GeyserItemStack getItemInHand() {
return items[36 + heldItemSlot]; return items[36 + heldItemSlot];
} }

View file

@ -223,7 +223,7 @@ public abstract class InventoryTranslator {
} else { } else {
// Cursor will be emptied // Cursor will be emptied
destItem.setAmount(itemsLeftOver); destItem.setAmount(itemsLeftOver);
session.getPlayerInventory().setCursor(GeyserItemStack.EMPTY); session.getPlayerInventory().setCursor(GeyserItemStack.EMPTY, session);
} }
ClientCreativeInventoryActionPacket creativeActionPacket = new ClientCreativeInventoryActionPacket( ClientCreativeInventoryActionPacket creativeActionPacket = new ClientCreativeInventoryActionPacket(
destSlot, destSlot,
@ -250,13 +250,13 @@ public abstract class InventoryTranslator {
if (sourceItem.isEmpty()) { if (sourceItem.isEmpty()) {
// Item is basically deleted // Item is basically deleted
if (sourceIsCursor) { if (sourceIsCursor) {
session.getPlayerInventory().setCursor(GeyserItemStack.EMPTY); session.getPlayerInventory().setCursor(GeyserItemStack.EMPTY, session);
} else { } else {
inventory.setItem(sourceSlot, GeyserItemStack.EMPTY, session); inventory.setItem(sourceSlot, GeyserItemStack.EMPTY, session);
} }
} }
if (destIsCursor) { if (destIsCursor) {
session.getPlayerInventory().setCursor(newItem); session.getPlayerInventory().setCursor(newItem, session);
} else { } else {
inventory.setItem(destSlot, newItem, session); inventory.setItem(destSlot, newItem, session);
} }
@ -340,7 +340,7 @@ public abstract class InventoryTranslator {
//try to transfer items with least clicks possible //try to transfer items with least clicks possible
int halfSource = sourceAmount - (sourceAmount / 2); //larger half int halfSource = sourceAmount - (sourceAmount / 2); //larger half
int holding; int holding;
if (transferAction.getCount() <= halfSource) { //faster to take only half if (plan.getCursor().isEmpty() && transferAction.getCount() <= halfSource) { //faster to take only half. CURSOR MUST BE EMPTY
plan.add(Click.RIGHT, sourceSlot); plan.add(Click.RIGHT, sourceSlot);
holding = halfSource; holding = halfSource;
} else { //need all } else { //need all
@ -376,7 +376,7 @@ public abstract class InventoryTranslator {
GeyserItemStack oldDestinationItem = inventory.getItem(destSlot); GeyserItemStack oldDestinationItem = inventory.getItem(destSlot);
if (isCursor(swapAction.getSource())) { if (isCursor(swapAction.getSource())) {
oldSourceItem = session.getPlayerInventory().getCursor(); oldSourceItem = session.getPlayerInventory().getCursor();
session.getPlayerInventory().setCursor(oldDestinationItem); session.getPlayerInventory().setCursor(oldDestinationItem, session);
} else { } else {
int sourceSlot = bedrockSlotToJava(swapAction.getSource()); int sourceSlot = bedrockSlotToJava(swapAction.getSource());
oldSourceItem = inventory.getItem(sourceSlot); oldSourceItem = inventory.getItem(sourceSlot);
@ -389,7 +389,7 @@ public abstract class InventoryTranslator {
inventory.setItem(sourceSlot, oldDestinationItem, session); inventory.setItem(sourceSlot, oldDestinationItem, session);
} }
if (isCursor(swapAction.getDestination())) { if (isCursor(swapAction.getDestination())) {
session.getPlayerInventory().setCursor(oldSourceItem); session.getPlayerInventory().setCursor(oldSourceItem, session);
} else { } else {
ClientCreativeInventoryActionPacket creativeActionPacket = new ClientCreativeInventoryActionPacket( ClientCreativeInventoryActionPacket creativeActionPacket = new ClientCreativeInventoryActionPacket(
destSlot, destSlot,
@ -445,7 +445,7 @@ public abstract class InventoryTranslator {
cursorItem.setAmount(cursorItem.getAmount() - dropAction.getCount()); cursorItem.setAmount(cursorItem.getAmount() - dropAction.getCount());
if (cursorItem.isEmpty()) { if (cursorItem.isEmpty()) {
// Cursor item no longer exists // Cursor item no longer exists
session.getPlayerInventory().setCursor(GeyserItemStack.EMPTY); session.getPlayerInventory().setCursor(GeyserItemStack.EMPTY, session);
} }
droppingItem.setAmount(dropAction.getCount()); droppingItem.setAmount(dropAction.getCount());
ClientCreativeInventoryActionPacket packet = new ClientCreativeInventoryActionPacket( ClientCreativeInventoryActionPacket packet = new ClientCreativeInventoryActionPacket(
@ -503,7 +503,7 @@ public abstract class InventoryTranslator {
affectedSlots.add(javaSlot); affectedSlots.add(javaSlot);
} else { } else {
// Just sync up the item on our end, since the server doesn't care what's in our cursor // Just sync up the item on our end, since the server doesn't care what's in our cursor
session.getPlayerInventory().setCursor(GeyserItemStack.EMPTY); session.getPlayerInventory().setCursor(GeyserItemStack.EMPTY, session);
} }
break; break;
} }
@ -715,7 +715,7 @@ public abstract class InventoryTranslator {
ItemStack javaCreativeItem = ItemTranslator.translateToJava(creativeItem); ItemStack javaCreativeItem = ItemTranslator.translateToJava(creativeItem);
if (isCursor(transferAction.getDestination())) { if (isCursor(transferAction.getDestination())) {
session.getPlayerInventory().setCursor(GeyserItemStack.from(javaCreativeItem, session.getNextItemNetId())); session.getPlayerInventory().setCursor(GeyserItemStack.from(javaCreativeItem, session.getNextItemNetId()), session);
return acceptRequest(request, Collections.singletonList( return acceptRequest(request, Collections.singletonList(
new ItemStackResponsePacket.ContainerEntry(ContainerSlotType.CURSOR, new ItemStackResponsePacket.ContainerEntry(ContainerSlotType.CURSOR,
Collections.singletonList(makeItemEntry(0, session.getPlayerInventory().getCursor()))))); Collections.singletonList(makeItemEntry(0, session.getPlayerInventory().getCursor())))));

View file

@ -63,6 +63,11 @@ public class ClickPlan {
this.simulating = true; this.simulating = true;
} }
private void resetSimulation() {
this.simulatedItems.clear();
this.simulatedCursor = session.getPlayerInventory().getCursor().copy();
}
public void add(Click click, int slot) { public void add(Click click, int slot) {
if (!simulating) if (!simulating)
throw new UnsupportedOperationException("ClickPlan already executed"); throw new UnsupportedOperationException("ClickPlan already executed");
@ -77,7 +82,8 @@ public class ClickPlan {
} }
public void execute(boolean refresh) { public void execute(boolean refresh) {
simulating = false; //update geyser inventory after simulation to avoid net id desync
resetSimulation();
ListIterator<ClickAction> planIter = plan.listIterator(); ListIterator<ClickAction> planIter = plan.listIterator();
while (planIter.hasNext()) { while (planIter.hasNext()) {
ClickAction action = planIter.next(); ClickAction action = planIter.next();
@ -92,7 +98,7 @@ public class ClickPlan {
} else if (action.click.windowAction == WindowAction.DROP_ITEM || action.slot == Click.OUTSIDE_SLOT) { } else if (action.click.windowAction == WindowAction.DROP_ITEM || action.slot == Click.OUTSIDE_SLOT) {
clickedItemStack = null; clickedItemStack = null;
} else { } else {
clickedItemStack = inventory.getItem(action.slot).getItemStack(); clickedItemStack = getItem(action.slot).getItemStack();
} }
short actionId = inventory.getNextTransactionId(); short actionId = inventory.getNextTransactionId();
@ -113,6 +119,12 @@ public class ClickPlan {
} }
System.out.println(clickPacket); System.out.println(clickPacket);
} }
session.getPlayerInventory().setCursor(simulatedCursor, session);
for (Int2ObjectMap.Entry<GeyserItemStack> simulatedSlot : simulatedItems.int2ObjectEntrySet()) {
inventory.setItem(simulatedSlot.getIntKey(), simulatedSlot.getValue(), session);
}
simulating = false;
} }
public GeyserItemStack getItem(int slot) { public GeyserItemStack getItem(int slot) {
@ -135,7 +147,7 @@ public class ClickPlan {
if (simulating) { if (simulating) {
simulatedCursor = item; simulatedCursor = item;
} else { } else {
session.getPlayerInventory().setCursor(item); session.getPlayerInventory().setCursor(item, session);
} }
} }

View file

@ -41,6 +41,7 @@ public class JavaConfirmTransactionTranslator extends PacketTranslator<ServerCon
if (!packet.isAccepted()) { if (!packet.isAccepted()) {
ClientConfirmTransactionPacket confirmPacket = new ClientConfirmTransactionPacket(packet.getWindowId(), packet.getActionId(), true); ClientConfirmTransactionPacket confirmPacket = new ClientConfirmTransactionPacket(packet.getWindowId(), packet.getActionId(), true);
session.sendDownstreamPacket(confirmPacket); session.sendDownstreamPacket(confirmPacket);
System.out.println(packet);
} }
}); });
} }

View file

@ -43,13 +43,7 @@ public class JavaSetSlotTranslator extends PacketTranslator<ServerSetSlotPacket>
session.addInventoryTask(() -> { session.addInventoryTask(() -> {
if (packet.getWindowId() == 255) { //cursor if (packet.getWindowId() == 255) { //cursor
GeyserItemStack newItem = GeyserItemStack.from(packet.getItem()); GeyserItemStack newItem = GeyserItemStack.from(packet.getItem());
GeyserItemStack oldItem = session.getPlayerInventory().getCursor(); session.getPlayerInventory().setCursor(newItem, session);
if (newItem.getItemData(session).equals(oldItem.getItemData(session))) {
newItem.setNetId(oldItem.getNetId());
} else {
newItem.setNetId(session.getNextItemNetId());
}
session.getPlayerInventory().setCursor(newItem);
InventoryUtils.updateCursor(session); InventoryUtils.updateCursor(session);
return; return;
} }

View file

@ -79,7 +79,7 @@ public class InventoryUtils {
} }
public static void closeInventory(GeyserSession session, int windowId) { public static void closeInventory(GeyserSession session, int windowId) {
session.getPlayerInventory().setCursor(GeyserItemStack.EMPTY); session.getPlayerInventory().setCursor(GeyserItemStack.EMPTY, session);
updateCursor(session); updateCursor(session);
Inventory inventory = getInventory(session, windowId); Inventory inventory = getInventory(session, windowId);