Cannot modify merchant recipes in OPEN_WINDOW_MERCHANT packet
bo3tools opened this issue ยท 2 comments
Describe the bug
Changes on List<MerchantRecipe>
provided by PacketContainer.getMerchantRecipeLists().read()
are not reflected in-game.
To Reproduce
Use minimal reproducible example:
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
PacketAdapter.AdapterParameteters params = PacketAdapter.params().plugin(this)
.listenerPriority(ListenerPriority.NORMAL)
.types(PacketType.Play.Server.OPEN_WINDOW_MERCHANT);
// Modify merchant recipes (normal priority)
protocolManager.addPacketListener(new PacketAdapter(params) {
@Override
public void onPacketSending(PacketEvent event) {
PacketContainer packet = event.getPacket();
// Set result of each trade to the coal item
List<MerchantRecipe> merchantRecipes = packet.getMerchantRecipeLists().read(0);
for (MerchantRecipe merchantRecipe: merchantRecipes) {
merchantRecipe.getResult().setType(Material.COAL);
}
// Set merchant level to 3 and experience to 100
packet.getIntegers().write(1, 3);
packet.getIntegers().write(2, 100);
event.setPacket(packet);
}
});
// Log the changed packet (highest priority)
protocolManager.addPacketListener(new PacketAdapter(params.listenerPriority(ListenerPriority.HIGHEST)) {
@Override
public void onPacketSending(PacketEvent event) {
PacketContainer packet = event.getPacket();
int windowId = packet.getIntegers().read(0);
int villagerLevel = packet.getIntegers().read(1);
int villagerExperience = packet.getIntegers().read(2);
boolean isRegularVillager = packet.getBooleans().read(0);
boolean canRestock = packet.getBooleans().read(1);
List<MerchantRecipe> merchantRecipes = packet.getMerchantRecipeLists().read(0);
String tradeList = merchantRecipes.stream()
.map((MerchantRecipe recipe) -> recipe.getIngredients().stream()
.map((ItemStack itemStack) -> itemStack.getType().toString().toLowerCase())
.collect(Collectors.joining(" + ")) + " => " + recipe.getResult().getType().toString().toLowerCase())
.collect(Collectors.joining(", "));
event.getPlayer().sendMessage("TradeList(Window=" + windowId +
", Lvl=" + villagerLevel + ", Exp=" + villagerExperience + ", CanRestock=" + canRestock +
", IsRegular=" + isRegularVillager + ", Trades=[" + tradeList + "]");
}
});
Expected behavior
Merchant recipe to be modified.
Screenshots
Opening the merchant window. Merchant level and experience were changed, while trade results are unaffected.
Verifying the contents of the packet using a second packet listener with higher priority, result is indicated as coal.
Version Info
https://pastebin.com/xDcLAry6
Additional context
Add any other context about the problem here.
You probably have to write the list back to the packet:
packet.getMerchantRecipeLists().write(0, list)