Full banner loom support

This commit is contained in:
Camotoy 2020-12-23 22:53:54 -05:00
parent 94febd6a2f
commit 6ae81cce52
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
4 changed files with 99 additions and 7 deletions

View file

@ -85,6 +85,7 @@ public abstract class InventoryTranslator {
put(WindowType.CRAFTING, new CraftingInventoryTranslator());
put(WindowType.ENCHANTMENT, new EnchantingInventoryTranslator());
put(WindowType.GRINDSTONE, new GrindstoneInventoryTranslator());
put(WindowType.LOOM, new LoomInventoryTranslator());
put(WindowType.MERCHANT, new MerchantInventoryTranslator());
put(WindowType.SHULKER_BOX, new ShulkerInventoryTranslator());
put(WindowType.SMITHING, new SmithingInventoryTranslator());
@ -93,10 +94,9 @@ public abstract class InventoryTranslator {
put(WindowType.GENERIC_3X3, new GenericBlockInventoryTranslator(9, "minecraft:dispenser[facing=north,triggered=false]", ContainerType.DISPENSER));
put(WindowType.HOPPER, new GenericBlockInventoryTranslator(5, "minecraft:hopper[enabled=false,facing=down]", ContainerType.HOPPER));
/* Workstations */
/* todo */
//put(WindowType.CARTOGRAPHY
//put(WindowType.STONECUTTER
put(WindowType.LOOM, new LoomInventoryTranslator());
//put(WindowType.
}
};
@ -122,12 +122,12 @@ public abstract class InventoryTranslator {
* Should be overrided if this request matches a certain criteria and shouldn't be treated normally.
* E.G. anvil renaming or enchanting
*/
public boolean shouldHandleRequestFirst(StackRequestActionData action) {
public boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
return false;
}
/**
* If {@link #shouldHandleRequestFirst(StackRequestActionData)} returns true, this will be called
* If {@link #shouldHandleRequestFirst(StackRequestActionData, Inventory)} returns true, this will be called
*/
public ItemStackResponsePacket.Response translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequestPacket.Request request) {
return null;
@ -138,7 +138,7 @@ public abstract class InventoryTranslator {
for (ItemStackRequestPacket.Request request : requests) {
if (request.getActions().length > 0) {
StackRequestActionData firstAction = request.getActions()[0];
if (shouldHandleRequestFirst(firstAction)) {
if (shouldHandleRequestFirst(firstAction, inventory)) {
// Some special request that shouldn't be processed normally
responsePacket.getEntries().add(translateSpecialRequest(session, inventory, request));
} else if (firstAction.getType() == StackRequestActionType.CRAFT_RECIPE || firstAction.getType() == StackRequestActionType.CRAFT_RECIPE_AUTO) {

View file

@ -89,7 +89,7 @@ public class BeaconInventoryTranslator extends AbstractBlockInventoryTranslator
}
@Override
public boolean shouldHandleRequestFirst(StackRequestActionData action) {
public boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
return action.getType() == StackRequestActionType.BEACON_PAYMENT;
}

View file

@ -105,7 +105,7 @@ public class EnchantingInventoryTranslator extends AbstractBlockInventoryTransla
}
@Override
public boolean shouldHandleRequestFirst(StackRequestActionData action) {
public boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
return action.getType() == StackRequestActionType.CRAFT_RECIPE;
}

View file

@ -25,17 +25,109 @@
package org.geysermc.connector.network.translators.inventory.translators;
import com.github.steveice10.mc.protocol.packet.ingame.client.window.ClientClickWindowButtonPacket;
import com.nukkitx.nbt.NbtMap;
import com.nukkitx.nbt.NbtType;
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 com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.CraftResultsDeprecatedStackRequestActionData;
import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionData;
import com.nukkitx.protocol.bedrock.data.inventory.stackrequestactions.StackRequestActionType;
import com.nukkitx.protocol.bedrock.packet.ItemStackRequestPacket;
import com.nukkitx.protocol.bedrock.packet.ItemStackResponsePacket;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
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 java.util.List;
public class LoomInventoryTranslator extends AbstractBlockInventoryTranslator {
/**
* A map of Bedrock patterns to Java index. Used to request for a specific banner pattern.
*/
private static final Object2IntMap<String> PATTERN_TO_INDEX = new Object2IntOpenHashMap<>();
static {
// Added from left-to-right then up-to-down in the order Java presents it
int index = 1;
PATTERN_TO_INDEX.put("bl", index++);
PATTERN_TO_INDEX.put("br", index++);
PATTERN_TO_INDEX.put("tl", index++);
PATTERN_TO_INDEX.put("tr", index++);
PATTERN_TO_INDEX.put("bs", index++);
PATTERN_TO_INDEX.put("ts", index++);
PATTERN_TO_INDEX.put("ls", index++);
PATTERN_TO_INDEX.put("rs", index++);
PATTERN_TO_INDEX.put("cs", index++);
PATTERN_TO_INDEX.put("ms", index++);
PATTERN_TO_INDEX.put("drs", index++);
PATTERN_TO_INDEX.put("dls", index++);
PATTERN_TO_INDEX.put("ss", index++);
PATTERN_TO_INDEX.put("cr", index++);
PATTERN_TO_INDEX.put("sc", index++);
PATTERN_TO_INDEX.put("bt", index++);
PATTERN_TO_INDEX.put("tt", index++);
PATTERN_TO_INDEX.put("bts", index++);
PATTERN_TO_INDEX.put("tts", index++);
PATTERN_TO_INDEX.put("ld", index++);
PATTERN_TO_INDEX.put("rd", index++);
PATTERN_TO_INDEX.put("lud", index++);
PATTERN_TO_INDEX.put("rud", index++);
PATTERN_TO_INDEX.put("mc", index++);
PATTERN_TO_INDEX.put("mr", index++);
PATTERN_TO_INDEX.put("vh", index++);
PATTERN_TO_INDEX.put("hh", index++);
PATTERN_TO_INDEX.put("vhr", index++);
PATTERN_TO_INDEX.put("hhb", index++);
PATTERN_TO_INDEX.put("bo", index++);
index++; // Bordure indented, does not appear to exist in Bedrock?
PATTERN_TO_INDEX.put("gra", index++);
PATTERN_TO_INDEX.put("gru", index);
// Bricks do not appear to be a pattern on Bedrock, either
}
public LoomInventoryTranslator() {
super(4, "minecraft:loom[facing=north]", ContainerType.LOOM, UIInventoryUpdater.INSTANCE);
}
@Override
public boolean shouldHandleRequestFirst(StackRequestActionData action, Inventory inventory) {
// If the LOOM_MATERIAL slot is not empty, we are crafting a pattern that does not come from an item
return action.getType() == StackRequestActionType.CRAFT_NON_IMPLEMENTED_DEPRECATED && inventory.getItem(2).isEmpty();
}
@Override
public ItemStackResponsePacket.Response translateSpecialRequest(GeyserSession session, Inventory inventory, ItemStackRequestPacket.Request request) {
// TODO: I anticipate this will be changed in the future to use something non-deprecated. Keep an eye out.
// Also TODO: Shift-clicking doesn't work here.
StackRequestActionData data = request.getActions()[1];
if (!(data instanceof CraftResultsDeprecatedStackRequestActionData)) {
return rejectRequest(request);
}
CraftResultsDeprecatedStackRequestActionData craftData = (CraftResultsDeprecatedStackRequestActionData) data;
// Get the patterns compound tag
List<NbtMap> blockEntityTag = craftData.getResultItems()[0].getTag().getList("Patterns", NbtType.COMPOUND);
// Get the pattern that the Bedrock client requests - the last pattern in the Patterns list
String pattern = blockEntityTag.get(blockEntityTag.size() - 1).getString("Pattern");
// Get the Java index of this pattern
int index = PATTERN_TO_INDEX.getOrDefault(pattern, -1);
if (index == -1) {
return rejectRequest(request);
}
// Java's formula: 4 * row + col
// And the Java loom window has a fixed row/width of four
// So... Number / 4 = row (so we don't have to bother there), and number % 4 is our column, which leads us back to our index. :)
ClientClickWindowButtonPacket packet = new ClientClickWindowButtonPacket(inventory.getId(), index);
System.out.println(packet);
session.sendDownstreamPacket(packet);
return translateRequest(session, inventory, request);
}
@Override
public int bedrockSlotToJava(StackRequestSlotInfoData slotInfoData) {
if (slotInfoData.getContainer() == ContainerSlotType.LOOM_INPUT) {