mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-24 03:25:29 +01:00
Support for MerchantRecipeList (#894)
* Added support for MerchantRecipeList found in OPEN_WINDOW_MERCHANT of MC versions 1.13+
This commit is contained in:
parent
8c51b175c4
commit
80f4c7b9a7
@ -61,6 +61,7 @@ import org.bukkit.WorldType;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@ -938,6 +939,17 @@ public class PacketContainer implements Serializable {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the MerchantRecipeList class.
|
||||
* @return A modifier for MerchantRecipeList fields.
|
||||
*/
|
||||
public StructureModifier<List<MerchantRecipe>> getMerchantRecipeLists() {
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getMinecraftClass("MerchantRecipeList"),
|
||||
BukkitConverters.getMerchantRecipeListConverter()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for ItemSlot/ItemStack pair lists in 1.16+
|
||||
* @return The Structure Modifier
|
||||
|
@ -25,6 +25,7 @@ import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
@ -38,6 +39,7 @@ import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
|
||||
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||
@ -60,6 +62,7 @@ import org.bukkit.advancement.Advancement;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
@ -1237,4 +1240,54 @@ public class BukkitConverters {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static ConstructorAccessor merchantRecipeListConstructor = null;
|
||||
private static MethodAccessor bukkitMerchantRecipeToCraft = null;
|
||||
private static MethodAccessor craftMerchantRecipeToNMS = null;
|
||||
private static MethodAccessor nmsMerchantRecipeToBukkit = null;
|
||||
|
||||
/**
|
||||
* Creates a converter from a MerchantRecipeList (which is just an ArrayList of MerchantRecipe wrapper)
|
||||
* to a {@link List} of {@link MerchantRecipe}. Primarily for the packet OPEN_WINDOW_MERCHANT which is present
|
||||
* in 1.13+.
|
||||
*
|
||||
* @return The MerchantRecipeList converter.
|
||||
*/
|
||||
public static EquivalentConverter<List<MerchantRecipe>> getMerchantRecipeListConverter() {
|
||||
return ignoreNull(new EquivalentConverter<List<MerchantRecipe>>() {
|
||||
|
||||
@Override
|
||||
public Object getGeneric(List<MerchantRecipe> specific) {
|
||||
if (merchantRecipeListConstructor == null) {
|
||||
Class<?> merchantRecipeListClass = MinecraftReflection.getMinecraftClass("MerchantRecipeList");
|
||||
merchantRecipeListConstructor = Accessors.getConstructorAccessor(merchantRecipeListClass);
|
||||
Class<?> craftMerchantRecipeClass = MinecraftReflection.getCraftBukkitClass("inventory.CraftMerchantRecipe");
|
||||
FuzzyReflection reflection = FuzzyReflection.fromClass(craftMerchantRecipeClass, false);
|
||||
bukkitMerchantRecipeToCraft = Accessors.getMethodAccessor(reflection.getMethodByName("fromBukkit"));
|
||||
craftMerchantRecipeToNMS = Accessors.getMethodAccessor(reflection.getMethodByName("toMinecraft"));
|
||||
}
|
||||
return specific.stream().map(recipe -> craftMerchantRecipeToNMS.invoke(bukkitMerchantRecipeToCraft.invoke(null, recipe)))
|
||||
.collect(() -> (List<Object>)merchantRecipeListConstructor.invoke(), List::add, List::addAll);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MerchantRecipe> getSpecific(Object generic) {
|
||||
if (nmsMerchantRecipeToBukkit == null) {
|
||||
Class<?> merchantRecipeClass = MinecraftReflection.getMinecraftClass("MerchantRecipe");
|
||||
FuzzyReflection reflection = FuzzyReflection.fromClass(merchantRecipeClass, false);
|
||||
nmsMerchantRecipeToBukkit = Accessors.getMethodAccessor(reflection.getMethodByName("asBukkit"));
|
||||
}
|
||||
return ((List<Object>)generic).stream().map(o -> (MerchantRecipe)nmsMerchantRecipeToBukkit.invoke(o)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<List<MerchantRecipe>> getSpecificType() {
|
||||
// Damn you Java
|
||||
Class<?> dummy = List.class;
|
||||
return (Class<List<MerchantRecipe>>) dummy;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user