Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-27 08:30:12 +01:00
Merge branch 'server-inventory' of https://github.com/AJ-Ferguson/Geyser into server-inventory
Dieser Commit ist enthalten in:
Commit
f4b1d470c3
@ -304,25 +304,41 @@ public abstract class InventoryTranslator {
|
|||||||
if (!InventoryUtils.canStack(cursor, plan.getItem(sourceSlot))) { //doesn't make sense, reject
|
if (!InventoryUtils.canStack(cursor, plan.getItem(sourceSlot))) { //doesn't make sense, reject
|
||||||
return rejectRequest(request);
|
return rejectRequest(request);
|
||||||
}
|
}
|
||||||
if (transferAction.getCount() != sourceAmount) { //TODO: handle partially picking up into non-empty cursor (temp slot)
|
if (transferAction.getCount() != sourceAmount) {
|
||||||
|
int tempSlot = findTempSlot(inventory, cursor, false, sourceSlot);
|
||||||
|
if (tempSlot == -1) {
|
||||||
return rejectRequest(request);
|
return rejectRequest(request);
|
||||||
}
|
}
|
||||||
|
plan.add(Click.LEFT, tempSlot); //place cursor into temp slot
|
||||||
|
plan.add(Click.LEFT, sourceSlot); //pickup source items into cursor
|
||||||
|
for (int i = 0; i < transferAction.getCount(); i++) {
|
||||||
|
plan.add(Click.RIGHT, tempSlot); //partially transfer source items into temp slot (original cursor)
|
||||||
|
}
|
||||||
|
plan.add(Click.LEFT, sourceSlot); //return remaining source items
|
||||||
|
plan.add(Click.LEFT, tempSlot); //retrieve original cursor items from temp slot
|
||||||
|
} else {
|
||||||
if (getSlotType(sourceSlot).equals(SlotType.NORMAL)) {
|
if (getSlotType(sourceSlot).equals(SlotType.NORMAL)) {
|
||||||
plan.add(Click.LEFT, sourceSlot); //release cursor onto source slot
|
plan.add(Click.LEFT, sourceSlot); //release cursor onto source slot
|
||||||
}
|
}
|
||||||
plan.add(Click.LEFT, sourceSlot); //pickup combined cursor and source
|
plan.add(Click.LEFT, sourceSlot); //pickup combined cursor and source
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else { //transfer from one slot to another
|
} else { //transfer from one slot to another
|
||||||
if (!cursor.isEmpty()) { //TODO: handle slot transfer when cursor is already in use (temp slot)
|
int tempSlot = -1;
|
||||||
|
if (!cursor.isEmpty()) {
|
||||||
|
tempSlot = findTempSlot(inventory, cursor, false, sourceSlot, destSlot);
|
||||||
|
if (tempSlot == -1) {
|
||||||
return rejectRequest(request);
|
return rejectRequest(request);
|
||||||
}
|
}
|
||||||
|
plan.add(Click.LEFT, tempSlot); //place cursor into temp slot
|
||||||
|
}
|
||||||
int sourceAmount = plan.getItem(sourceSlot).getAmount();
|
int sourceAmount = plan.getItem(sourceSlot).getAmount();
|
||||||
if (transferAction.getCount() == sourceAmount) { //transfer all
|
if (transferAction.getCount() == sourceAmount) { //transfer all
|
||||||
plan.add(Click.LEFT, sourceSlot); //pickup source
|
plan.add(Click.LEFT, sourceSlot); //pickup source
|
||||||
plan.add(Click.LEFT, destSlot); //let go of all items and done
|
plan.add(Click.LEFT, destSlot); //let go of all items and done
|
||||||
} else { //transfer some
|
} else { //transfer some
|
||||||
//try to transfer items with least clicks possible
|
//try to transfer items with least clicks possible
|
||||||
int halfSource = sourceAmount / 2; //smaller half
|
int halfSource = sourceAmount - (sourceAmount / 2); //larger half
|
||||||
int holding;
|
int holding;
|
||||||
if (transferAction.getCount() <= halfSource) { //faster to take only half
|
if (transferAction.getCount() <= halfSource) { //faster to take only half
|
||||||
plan.add(Click.RIGHT, sourceSlot);
|
plan.add(Click.RIGHT, sourceSlot);
|
||||||
@ -343,6 +359,9 @@ public abstract class InventoryTranslator {
|
|||||||
plan.add(Click.LEFT, sourceSlot); //return extra items to source slot
|
plan.add(Click.LEFT, sourceSlot); //return extra items to source slot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (tempSlot != -1) {
|
||||||
|
plan.add(Click.LEFT, tempSlot); //retrieve original cursor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -746,11 +765,62 @@ public abstract class InventoryTranslator {
|
|||||||
public boolean checkNetId(GeyserSession session, Inventory inventory, StackRequestSlotInfoData slotInfoData) {
|
public boolean checkNetId(GeyserSession session, Inventory inventory, StackRequestSlotInfoData slotInfoData) {
|
||||||
if (slotInfoData.getStackNetworkId() < 0)
|
if (slotInfoData.getStackNetworkId() < 0)
|
||||||
return true;
|
return true;
|
||||||
|
if (slotInfoData.getContainer() == ContainerSlotType.CURSOR) //TODO: temporary
|
||||||
|
return true;
|
||||||
|
|
||||||
GeyserItemStack currentItem = isCursor(slotInfoData) ? session.getPlayerInventory().getCursor() : inventory.getItem(bedrockSlotToJava(slotInfoData));
|
GeyserItemStack currentItem = isCursor(slotInfoData) ? session.getPlayerInventory().getCursor() : inventory.getItem(bedrockSlotToJava(slotInfoData));
|
||||||
return currentItem.getNetId() == slotInfoData.getStackNetworkId();
|
return currentItem.getNetId() == slotInfoData.getStackNetworkId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to find a slot that can temporarily store the given item.
|
||||||
|
* Only looks in the main inventory and hotbar (excluding offhand).
|
||||||
|
* Only slots that are empty or contain a different type of item are valid.
|
||||||
|
*
|
||||||
|
* @return java id for the temporary slot, or -1 if no viable slot was found
|
||||||
|
*/
|
||||||
|
//TODO: compatibility for simulated inventory (ClickPlan)
|
||||||
|
private static int findTempSlot(Inventory inventory, GeyserItemStack item, boolean emptyOnly, int... slotBlacklist) {
|
||||||
|
int offset = inventory.getId() == 0 ? 1 : 0; //offhand is not a viable temp slot
|
||||||
|
HashSet<GeyserItemStack> itemBlacklist = new HashSet<>(slotBlacklist.length + 1);
|
||||||
|
itemBlacklist.add(item);
|
||||||
|
|
||||||
|
IntSet potentialSlots = new IntOpenHashSet(36);
|
||||||
|
for (int i = inventory.getSize() - (36 + offset); i < inventory.getSize() - offset; i++) {
|
||||||
|
potentialSlots.add(i);
|
||||||
|
}
|
||||||
|
for (int i : slotBlacklist) {
|
||||||
|
potentialSlots.remove(i);
|
||||||
|
GeyserItemStack blacklistedItem = inventory.getItem(i);
|
||||||
|
if (!blacklistedItem.isEmpty()) {
|
||||||
|
itemBlacklist.add(blacklistedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i : potentialSlots) {
|
||||||
|
GeyserItemStack testItem = inventory.getItem(i);
|
||||||
|
if ((emptyOnly && !testItem.isEmpty())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean viable = true;
|
||||||
|
for (GeyserItemStack blacklistedItem : itemBlacklist) {
|
||||||
|
if (InventoryUtils.canStack(testItem, blacklistedItem)) {
|
||||||
|
viable = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!viable) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("TEMP SLOT CHOSEN: " + i + " => " + inventory.getItem(i));
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
//could not find a viable temp slot
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
public List<ItemStackResponsePacket.ContainerEntry> makeContainerEntries(GeyserSession session, Inventory inventory, Set<Integer> affectedSlots) {
|
public List<ItemStackResponsePacket.ContainerEntry> makeContainerEntries(GeyserSession session, Inventory inventory, Set<Integer> affectedSlots) {
|
||||||
Map<ContainerSlotType, List<ItemStackResponsePacket.ItemEntry>> containerMap = new HashMap<>();
|
Map<ContainerSlotType, List<ItemStackResponsePacket.ItemEntry>> containerMap = new HashMap<>();
|
||||||
for (int slot : affectedSlots) {
|
for (int slot : affectedSlots) {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren