Add swap support for creative mode; start on cartography table

This commit is contained in:
Camotoy 2020-12-24 20:43:24 -05:00
parent 3d0b0a1076
commit c7fade295e
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
3 changed files with 145 additions and 11 deletions

View file

@ -82,6 +82,7 @@ public abstract class InventoryTranslator {
put(WindowType.ANVIL, new AnvilInventoryTranslator());
put(WindowType.BEACON, new BeaconInventoryTranslator());
put(WindowType.BREWING_STAND, new BrewingInventoryTranslator());
put(WindowType.CARTOGRAPHY, new CartographyInventoryTranslator());
put(WindowType.CRAFTING, new CraftingInventoryTranslator());
put(WindowType.ENCHANTMENT, new EnchantingInventoryTranslator());
put(WindowType.GRINDSTONE, new GrindstoneInventoryTranslator());
@ -96,7 +97,6 @@ public abstract class InventoryTranslator {
put(WindowType.HOPPER, new GenericBlockInventoryTranslator(5, "minecraft:hopper[enabled=false,facing=down]", ContainerType.HOPPER));
/* todo */
//put(WindowType.CARTOGRAPHY
// horse
}
};
@ -122,9 +122,11 @@ public abstract class InventoryTranslator {
* Should be overwritten in cases where specific inventories should reject an item being in a specific spot.
* For examples, looms use this to reject items that are dyes in Bedrock but not in Java.
*
* javaSourceSlot will be -1 if the cursor is the source
*
* @return true if this transfer should be rejected
*/
public boolean shouldRejectItemPlace(GeyserSession session, Inventory inventory, int javaDestinationSlot) {
public boolean shouldRejectItemPlace(GeyserSession session, Inventory inventory, int javaSourceSlot, int javaDestinationSlot) {
return false;
}
@ -188,9 +190,10 @@ public abstract class InventoryTranslator {
return rejectRequest(request);
}
int sourceSlot = bedrockSlotToJava(transferAction.getSource());
int destSlot = bedrockSlotToJava(transferAction.getDestination());
if (shouldRejectItemPlace(session, inventory, destSlot)) {
if (shouldRejectItemPlace(session, inventory, isCursor(transferAction.getSource()) ? -1 :sourceSlot, destSlot)) {
// This item would not be here in Java
return rejectRequest(request, false);
}
@ -199,7 +202,6 @@ public abstract class InventoryTranslator {
return rejectRequest(request);
} else if (session.getGameMode().equals(GameMode.CREATIVE) && inventory instanceof PlayerInventory) { // TODO: does the Java server use this stuff all the time in creative?
// Creative acts a little differently because it just edits slots
int sourceSlot = bedrockSlotToJava(transferAction.getSource());
boolean sourceIsCursor = isCursor(transferAction.getSource());
boolean destIsCursor = isCursor(transferAction.getDestination());
@ -228,6 +230,15 @@ public abstract class InventoryTranslator {
affectedSlots.add(destSlot);
break;
}
} else {
// Delete the source since we're moving it
inventory.setItem(sourceSlot, GeyserItemStack.EMPTY);
ClientCreativeInventoryActionPacket creativeActionPacket = new ClientCreativeInventoryActionPacket(
sourceSlot,
new ItemStack(0)
);
session.sendDownstreamPacket(creativeActionPacket);
affectedSlots.add(sourceSlot);
}
// Update the item count with however much the client took
newItem.setAmount(transferAction.getCount());
@ -273,7 +284,6 @@ public abstract class InventoryTranslator {
}
}
} else if (isCursor(transferAction.getDestination())) { //picking up into cursor
int sourceSlot = bedrockSlotToJava(transferAction.getSource());
GeyserItemStack sourceItem = plan.getItem(sourceSlot);
int sourceAmount = sourceItem.getAmount();
if (cursor.isEmpty()) { //picking up into empty cursor
@ -303,7 +313,6 @@ public abstract class InventoryTranslator {
if (!cursor.isEmpty()) { //TODO: handle slot transfer when cursor is already in use (temp slot)
return rejectRequest(request);
}
int sourceSlot = bedrockSlotToJava(transferAction.getSource());
int sourceAmount = plan.getItem(sourceSlot).getAmount();
if (transferAction.getCount() == sourceAmount) { //transfer all
plan.add(Click.LEFT, sourceSlot); //pickup source
@ -339,7 +348,37 @@ public abstract class InventoryTranslator {
if (!(checkNetId(session, inventory, swapAction.getSource()) && checkNetId(session, inventory, swapAction.getDestination())))
return rejectRequest(request);
if (isCursor(swapAction.getSource()) && isCursor(swapAction.getDestination())) { //???
if (session.getGameMode().equals(GameMode.CREATIVE) && inventory instanceof PlayerInventory) {
int destSlot = bedrockSlotToJava(swapAction.getDestination());
GeyserItemStack oldSourceItem;
GeyserItemStack oldDestinationItem = inventory.getItem(destSlot);
if (isCursor(swapAction.getSource())) {
oldSourceItem = session.getPlayerInventory().getCursor();
session.getPlayerInventory().setCursor(oldDestinationItem);
} else {
int sourceSlot = bedrockSlotToJava(swapAction.getSource());
oldSourceItem = inventory.getItem(sourceSlot);
ClientCreativeInventoryActionPacket creativeActionPacket = new ClientCreativeInventoryActionPacket(
sourceSlot,
oldDestinationItem.isEmpty() ? new ItemStack(0) : oldDestinationItem.getItemStack() // isEmpty check... just in case
);
System.out.println(creativeActionPacket);
session.sendDownstreamPacket(creativeActionPacket);
inventory.setItem(sourceSlot, oldDestinationItem);
}
if (isCursor(swapAction.getDestination())) {
session.getPlayerInventory().setCursor(oldSourceItem);
} else {
ClientCreativeInventoryActionPacket creativeActionPacket = new ClientCreativeInventoryActionPacket(
destSlot,
oldSourceItem.isEmpty() ? new ItemStack(0) : oldSourceItem.getItemStack()
);
System.out.println(creativeActionPacket);
session.sendDownstreamPacket(creativeActionPacket);
inventory.setItem(destSlot, oldSourceItem);
}
} else if (isCursor(swapAction.getSource()) && isCursor(swapAction.getDestination())) { //???
return rejectRequest(request);
} else if (isCursor(swapAction.getSource())) { //swap cursor
int destSlot = bedrockSlotToJava(swapAction.getDestination());

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2019-2020 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.connector.network.translators.inventory.translators;
import com.nukkitx.protocol.bedrock.data.inventory.ContainerSlotType;
import com.nukkitx.protocol.bedrock.data.inventory.ContainerType;
import com.nukkitx.protocol.bedrock.data.inventory.StackRequestSlotInfoData;
import org.geysermc.connector.inventory.GeyserItemStack;
import org.geysermc.connector.inventory.Inventory;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.inventory.BedrockContainerSlot;
import org.geysermc.connector.network.translators.inventory.updater.UIInventoryUpdater;
import org.geysermc.connector.network.translators.item.ItemRegistry;
public class CartographyInventoryTranslator extends AbstractBlockInventoryTranslator {
public CartographyInventoryTranslator() {
super(3, "minecraft:cartography_table", ContainerType.CARTOGRAPHY, UIInventoryUpdater.INSTANCE);
}
@Override
public boolean shouldRejectItemPlace(GeyserSession session, Inventory inventory, int javaSourceSlot, int javaDestinationSlot) {
if (javaDestinationSlot == 1) {
// Bedrock Edition can use a compass to create locator maps in the ADDITIONAL slot
GeyserItemStack itemStack = javaSourceSlot == -1 ? session.getPlayerInventory().getCursor() : inventory.getItem(javaSourceSlot);
return ItemRegistry.getItem(itemStack.getItemStack()).getJavaIdentifier().equals("minecraft:compass");
} else if (javaSourceSlot == 2) {
// Java doesn't allow an item to be renamed; this is why CARTOGRAPHY_ADDITIONAL could remain empty for Bedrock
return inventory.getItem(1).isEmpty();
}
return false;
}
@Override
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
if (slotInfoData.getContainer() == ContainerSlotType.CARTOGRAPHY_INPUT) {
return 0;
}
if (slotInfoData.getContainer() == ContainerSlotType.CARTOGRAPHY_ADDITIONAL) {
return 1;
}
if (slotInfoData.getContainer() == ContainerSlotType.CARTOGRAPHY_RESULT || slotInfoData.getContainer() == ContainerSlotType.CREATIVE_OUTPUT) {
return 2;
}
return super.bedrockSlotToJava(slotInfoData);
}
@Override
public BedrockContainerSlot javaSlotToBedrockContainer(int slot) {
switch (slot) {
case 0:
return new BedrockContainerSlot(ContainerSlotType.CARTOGRAPHY_INPUT, 12);
case 1:
return new BedrockContainerSlot(ContainerSlotType.CARTOGRAPHY_ADDITIONAL, 13);
case 2:
return new BedrockContainerSlot(ContainerSlotType.CARTOGRAPHY_RESULT, 50);
}
return super.javaSlotToBedrockContainer(slot);
}
@Override
public int javaSlotToBedrock(int slot) {
switch (slot) {
case 0:
return 12;
case 1:
return 13;
case 2:
return 50;
}
return super.javaSlotToBedrock(slot);
}
}

View file

@ -101,11 +101,11 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
}
@Override
public boolean shouldRejectItemPlace(GeyserSession session, Inventory inventory, int javaDestinationSlot) {
public boolean shouldRejectItemPlace(GeyserSession session, Inventory inventory, int javaSourceSlot, int javaDestinationSlot) {
if (javaDestinationSlot != 1) {
return false;
}
GeyserItemStack itemStack = session.getPlayerInventory().getCursor();
GeyserItemStack itemStack = javaSourceSlot == -1 ? session.getPlayerInventory().getCursor() : inventory.getItem(javaSourceSlot);
if (itemStack.isEmpty()) {
return false;
}
@ -129,9 +129,9 @@ public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
}
CraftResultsDeprecatedStackRequestActionData craftData = (CraftResultsDeprecatedStackRequestActionData) data;
// Get the patterns compound tag
List<NbtMap> newblockEntityTag = craftData.getResultItems()[0].getTag().getList("Patterns", NbtType.COMPOUND);
List<NbtMap> newBlockEntityTag = craftData.getResultItems()[0].getTag().getList("Patterns", NbtType.COMPOUND);
// Get the pattern that the Bedrock client requests - the last pattern in the Patterns list
NbtMap pattern = newblockEntityTag.get(newblockEntityTag.size() - 1);
NbtMap pattern = newBlockEntityTag.get(newBlockEntityTag.size() - 1);
// Get the Java index of this pattern
int index = PATTERN_TO_INDEX.getOrDefault(pattern.getString("Pattern"), -1);
if (index == -1) {