Compare commits

...

29 Commits
5.2.0 ... 5.4.0

Author SHA1 Message Date
Auxilor
007a579f5a Updated to 5.4.0 2021-06-11 11:37:09 +01:00
Auxilor
9b19cd412a Updated to 1.17 and Java 16 2021-06-11 11:36:58 +01:00
Auxilor
08b5cc1612 Added more null checks to fix incompatibility with paper/adventure 2021-05-18 15:41:45 +01:00
Auxilor
47aa61c7b3 Updated to 5.3.7 2021-05-18 15:34:02 +01:00
Auxilor
ef1ee84358 Added checks for null components due to problem with adventure 2021-05-18 15:33:47 +01:00
Auxilor
49a36a4e81 Updated to 5.3.6 2021-05-06 08:47:51 +01:00
Auxilor
bf76dec28e Added emerald ore in TeamUtils 2021-05-06 08:47:41 +01:00
Auxilor
a0f51d79e8 Updated to 5.3.5 2021-04-26 21:24:45 +01:00
Auxilor
9be516e511 Added villager-display-fix to force remove all hideflags 2021-04-26 21:24:28 +01:00
Auxilor
a130935c62 Fixed Villager Trades for the last time 2021-04-25 15:54:50 +01:00
Auxilor
4359bd17ae Updated to 5.3.4 2021-04-25 15:45:26 +01:00
Auxilor
07726959e9 Fixed MerchantRecipe again 2021-04-25 15:45:16 +01:00
Auxilor
13c8187b3b Updated to 5.3.3 2021-04-25 15:18:51 +01:00
Auxilor
be1267ef0c Fixed config default 2021-04-25 15:18:40 +01:00
Auxilor
e61e9bc0a8 Added disable villager display option 2021-04-24 17:05:07 +01:00
Auxilor
ec801cd776 Updated to 5.3.2 2021-04-24 17:02:23 +01:00
Auxilor
a5b5bc6b46 Fixed ChatComponent 2021-04-24 17:01:53 +01:00
Auxilor
f5efb50d71 Updated to 5.3.1 2021-04-23 21:17:13 +01:00
Auxilor
d65c04aaa7 Hopefully fixed Villager Trades again 2021-04-23 21:16:46 +01:00
Auxilor
aa69d2a1a9 Fixed deprecation still being used 2021-04-20 21:41:04 +01:00
Auxilor
685cd5f998 Deprecated finalization system 2021-04-20 21:39:25 +01:00
Auxilor
bae4b567c8 Updated to 5.3.0 2021-04-20 21:31:05 +01:00
Auxilor
0eb3315d61 Updated to 5.2.2 2021-04-20 21:29:28 +01:00
Auxilor
0a42320b78 Fixed villager trade display 2021-04-20 21:29:19 +01:00
Auxilor
6ce0de8db7 Merge remote-tracking branch 'origin/master' 2021-04-20 21:28:04 +01:00
Auxilor
345d4cd1b5 Reworked villager trade display 2021-04-20 20:21:32 +01:00
Auxilor
950c092025 Added EcoSkills to loadbefore 2021-04-17 10:25:38 +01:00
Auxilor
0c6bb8c1b7 Updated to 5.2.1 2021-04-17 10:24:39 +01:00
Auxilor
0f9cb7db7a Items in menus now translate placeholder lore with respect to a player 2021-04-17 10:24:27 +01:00
25 changed files with 567 additions and 95 deletions

View File

@@ -96,4 +96,4 @@ allprojects {
group = 'com.willfp'
archivesBaseName = project.name
version = findProperty("version")
java.sourceCompatibility = JavaVersion.VERSION_1_8
java.sourceCompatibility = JavaVersion.VERSION_16

View File

@@ -78,6 +78,32 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
// Empty rather than abstract as implementations don't need both
}
/**
* The code that should be executed once the packet has been received.
*
* @param packet The packet.
* @param player The player.
* @param event The event.
*/
public void onReceive(@NotNull final PacketContainer packet,
@NotNull final Player player,
@NotNull final PacketEvent event) {
// Empty rather than abstract as implementations don't need both
}
/**
* THe code that should be executed once the packet has been sent.
*
* @param packet The packet.
* @param player The player.
* @param event The event.
*/
public void onSend(@NotNull final PacketContainer packet,
@NotNull final Player player,
@NotNull final PacketEvent event) {
// Empty rather than abstract as implementations don't need both
}
/**
* Boilerplate to assert that the packet is of the specified type.
*
@@ -94,6 +120,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
}
onReceive(event.getPacket(), event.getPlayer());
onReceive(event.getPacket(), event.getPlayer(), event);
}
/**
@@ -112,6 +139,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
}
onSend(event.getPacket(), event.getPlayer());
onSend(event.getPacket(), event.getPlayer(), event);
}
/**

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core;
import com.willfp.eco.core.proxy.ProxyConstants;
import com.willfp.eco.util.ClassUtils;
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
@@ -14,6 +15,7 @@ public class Prerequisite {
* All existing prerequisites are registered on creation.
*/
private static final List<Prerequisite> VALUES = new ArrayList<>();
/**
* Requires the server to be running an implementation of paper.
*/
@@ -22,6 +24,14 @@ public class Prerequisite {
"Requires server to be running paper (or a fork)"
);
/**
* Requires the server to be running 1.17
*/
public static final Prerequisite v1_17 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("17"),
"Requires server to be running 1.17+"
);
/**
* If the necessary prerequisite condition has been met.
*/

View File

@@ -2,11 +2,14 @@ package com.willfp.eco.internal.gui;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.slot.Slot;
import com.willfp.eco.util.StringUtils;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -56,7 +59,17 @@ public class EcoMenu implements Menu {
if (i == rows * 9) {
break;
}
inventory.setItem(i, item.getItemStack());
ItemStack slotItem = item.getItemStack();
ItemMeta meta = slotItem.getItemMeta();
if (meta != null) {
List<String> lore = meta.getLore();
if (lore != null) {
lore.replaceAll(s -> StringUtils.translate(s, player));
meta.setLore(lore);
}
slotItem.setItemMeta(meta);
}
inventory.setItem(i, slotItem);
i++;
}
}

View File

@@ -79,6 +79,7 @@ public class TeamUtils {
MATERIAL_COLORS.forcePut(Material.LAPIS_ORE, ChatColor.BLUE);
MATERIAL_COLORS.forcePut(Material.REDSTONE_ORE, ChatColor.RED);
MATERIAL_COLORS.forcePut(Material.DIAMOND_ORE, ChatColor.AQUA);
MATERIAL_COLORS.forcePut(Material.EMERALD_ORE, ChatColor.GREEN);
MATERIAL_COLORS.forcePut(Material.ANCIENT_DEBRIS, ChatColor.DARK_RED);
}
}

View File

@@ -27,13 +27,25 @@ public final class ChatComponent implements ChatComponentProxy {
}
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
chatComponent.stream().forEach(this::modifyBaseComponent);
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
if (iChatBaseComponent == null) {
continue;
}
modifyBaseComponent(iChatBaseComponent);
}
return chatComponent;
}
private void modifyBaseComponent(@NotNull final IChatBaseComponent component) {
component.getSiblings().forEach(this::modifyBaseComponent);
for (IChatBaseComponent sibling : component.getSiblings()) {
if (sibling == null) {
continue;
}
modifyBaseComponent(sibling);
}
if (component instanceof ChatMessage) {
Arrays.stream(((ChatMessage) component).getArgs())
.filter(o -> o instanceof IChatBaseComponent)

View File

@@ -1,8 +1,7 @@
package com.willfp.eco.proxy.v1_16_R1;
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
import com.willfp.eco.core.display.Display;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftMerchantRecipe;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantRecipe;
@@ -11,30 +10,56 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public final class VillagerTrade implements VillagerTradeProxy {
@Override
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
/**
* Handle.
*/
private final Field handle;
/**
* Create new Villager Trade.
*/
public VillagerTrade() {
try {
// Bukkit MerchantRecipe result
Field fResult = MerchantRecipe.class.getDeclaredField("result");
fResult.setAccessible(true);
ItemStack result = merchantRecipe.getResult();
Display.displayAndFinalize(result);
fResult.set(merchantRecipe, result);
// Get NMS MerchantRecipe from CraftMerchantRecipe
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
fHandle.setAccessible(true);
net.minecraft.server.v1_16_R1.MerchantRecipe handle = (net.minecraft.server.v1_16_R1.MerchantRecipe) fHandle.get(merchantRecipe); // NMS Recipe
Field fSelling = net.minecraft.server.v1_16_R1.MerchantRecipe.class.getDeclaredField("sellingItem");
fSelling.setAccessible(true);
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
Display.displayAndFinalize(selling);
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
} catch (IllegalAccessException | NoSuchFieldException e) {
handle = CraftMerchantRecipe.class.getDeclaredField("handle");
handle.setAccessible(true);
return;
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
throw new RuntimeException("Error!");
}
@Override
public MerchantRecipe displayTrade(@NotNull final MerchantRecipe recipe) {
CraftMerchantRecipe oldRecipe = (CraftMerchantRecipe) recipe;
CraftMerchantRecipe newRecipe = new CraftMerchantRecipe(
Display.display(recipe.getResult().clone()),
recipe.getUses(),
recipe.getMaxUses(),
recipe.hasExperienceReward(),
recipe.getVillagerExperience(),
recipe.getPriceMultiplier()
);
for (ItemStack ingredient : recipe.getIngredients()) {
newRecipe.addIngredient(Display.display(ingredient.clone()));
}
getHandle(newRecipe).setSpecialPrice(getHandle(oldRecipe).getSpecialPrice());
return newRecipe;
}
@NotNull
private net.minecraft.server.v1_16_R1.MerchantRecipe getHandle(@NotNull final CraftMerchantRecipe recipe) {
try {
return (net.minecraft.server.v1_16_R1.MerchantRecipe) handle.get(recipe);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
throw new IllegalArgumentException("Not CMR");
}
}

View File

@@ -27,13 +27,25 @@ public final class ChatComponent implements ChatComponentProxy {
}
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
chatComponent.stream().forEach(this::modifyBaseComponent);
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
if (iChatBaseComponent == null) {
continue;
}
modifyBaseComponent(iChatBaseComponent);
}
return chatComponent;
}
private void modifyBaseComponent(@NotNull final IChatBaseComponent component) {
component.getSiblings().forEach(this::modifyBaseComponent);
for (IChatBaseComponent sibling : component.getSiblings()) {
if (sibling == null) {
continue;
}
modifyBaseComponent(sibling);
}
if (component instanceof ChatMessage) {
Arrays.stream(((ChatMessage) component).getArgs())
.filter(o -> o instanceof IChatBaseComponent)

View File

@@ -1,8 +1,7 @@
package com.willfp.eco.proxy.v1_16_R2;
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
import com.willfp.eco.core.display.Display;
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftMerchantRecipe;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantRecipe;
@@ -11,30 +10,56 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public final class VillagerTrade implements VillagerTradeProxy {
@Override
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
/**
* Handle.
*/
private final Field handle;
/**
* Create new Villager Trade.
*/
public VillagerTrade() {
try {
// Bukkit MerchantRecipe result
Field fResult = MerchantRecipe.class.getDeclaredField("result");
fResult.setAccessible(true);
ItemStack result = merchantRecipe.getResult();
Display.displayAndFinalize(result);
fResult.set(merchantRecipe, result);
// Get NMS MerchantRecipe from CraftMerchantRecipe
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
fHandle.setAccessible(true);
net.minecraft.server.v1_16_R2.MerchantRecipe handle = (net.minecraft.server.v1_16_R2.MerchantRecipe) fHandle.get(merchantRecipe); // NMS Recipe
Field fSelling = net.minecraft.server.v1_16_R2.MerchantRecipe.class.getDeclaredField("sellingItem");
fSelling.setAccessible(true);
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
Display.displayAndFinalize(selling);
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
} catch (IllegalAccessException | NoSuchFieldException e) {
handle = CraftMerchantRecipe.class.getDeclaredField("handle");
handle.setAccessible(true);
return;
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
throw new RuntimeException("Error!");
}
@Override
public MerchantRecipe displayTrade(@NotNull final MerchantRecipe recipe) {
CraftMerchantRecipe oldRecipe = (CraftMerchantRecipe) recipe;
CraftMerchantRecipe newRecipe = new CraftMerchantRecipe(
Display.display(recipe.getResult().clone()),
recipe.getUses(),
recipe.getMaxUses(),
recipe.hasExperienceReward(),
recipe.getVillagerExperience(),
recipe.getPriceMultiplier()
);
for (ItemStack ingredient : recipe.getIngredients()) {
newRecipe.addIngredient(Display.display(ingredient.clone()));
}
getHandle(newRecipe).setSpecialPrice(getHandle(oldRecipe).getSpecialPrice());
return newRecipe;
}
@NotNull
private net.minecraft.server.v1_16_R2.MerchantRecipe getHandle(@NotNull final CraftMerchantRecipe recipe) {
try {
return (net.minecraft.server.v1_16_R2.MerchantRecipe) handle.get(recipe);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
throw new IllegalArgumentException("Not CMR");
}
}

View File

@@ -27,13 +27,25 @@ public final class ChatComponent implements ChatComponentProxy {
}
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
chatComponent.stream().forEach(this::modifyBaseComponent);
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
if (iChatBaseComponent == null) {
continue;
}
modifyBaseComponent(iChatBaseComponent);
}
return chatComponent;
}
private void modifyBaseComponent(@NotNull final IChatBaseComponent component) {
component.getSiblings().forEach(this::modifyBaseComponent);
for (IChatBaseComponent sibling : component.getSiblings()) {
if (sibling == null) {
continue;
}
modifyBaseComponent(sibling);
}
if (component instanceof ChatMessage) {
Arrays.stream(((ChatMessage) component).getArgs())
.filter(o -> o instanceof IChatBaseComponent)

View File

@@ -1,8 +1,7 @@
package com.willfp.eco.proxy.v1_16_R3;
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
import com.willfp.eco.core.display.Display;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftMerchantRecipe;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantRecipe;
@@ -11,30 +10,56 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public final class VillagerTrade implements VillagerTradeProxy {
@Override
public void displayTrade(@NotNull final MerchantRecipe merchantRecipe) {
/**
* Handle.
*/
private final Field handle;
/**
* Create new Villager Trade.
*/
public VillagerTrade() {
try {
// Bukkit MerchantRecipe result
Field fResult = MerchantRecipe.class.getDeclaredField("result");
fResult.setAccessible(true);
ItemStack result = merchantRecipe.getResult();
Display.displayAndFinalize(result);
fResult.set(merchantRecipe, result);
// Get NMS MerchantRecipe from CraftMerchantRecipe
Field fHandle = CraftMerchantRecipe.class.getDeclaredField("handle");
fHandle.setAccessible(true);
net.minecraft.server.v1_16_R3.MerchantRecipe handle = (net.minecraft.server.v1_16_R3.MerchantRecipe) fHandle.get(merchantRecipe); // NMS RecipeR
Field fSelling = net.minecraft.server.v1_16_R3.MerchantRecipe.class.getDeclaredField("sellingItem");
fSelling.setAccessible(true);
ItemStack selling = CraftItemStack.asBukkitCopy(handle.sellingItem);
Display.displayAndFinalize(selling);
fSelling.set(handle, CraftItemStack.asNMSCopy(selling));
} catch (IllegalAccessException | NoSuchFieldException e) {
handle = CraftMerchantRecipe.class.getDeclaredField("handle");
handle.setAccessible(true);
return;
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
throw new RuntimeException("Error!");
}
@Override
public MerchantRecipe displayTrade(@NotNull final MerchantRecipe recipe) {
CraftMerchantRecipe oldRecipe = (CraftMerchantRecipe) recipe;
CraftMerchantRecipe newRecipe = new CraftMerchantRecipe(
Display.display(recipe.getResult().clone()),
recipe.getUses(),
recipe.getMaxUses(),
recipe.hasExperienceReward(),
recipe.getVillagerExperience(),
recipe.getPriceMultiplier()
);
for (ItemStack ingredient : recipe.getIngredients()) {
newRecipe.addIngredient(Display.display(ingredient.clone()));
}
getHandle(newRecipe).setSpecialPrice(getHandle(oldRecipe).getSpecialPrice());
return newRecipe;
}
@NotNull
private net.minecraft.server.v1_16_R3.MerchantRecipe getHandle(@NotNull final CraftMerchantRecipe recipe) {
try {
return (net.minecraft.server.v1_16_R3.MerchantRecipe) handle.get(recipe);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
throw new IllegalArgumentException("Not CMR");
}
}

View File

@@ -0,0 +1,6 @@
group 'com.willfp'
version rootProject.version
dependencies {
compileOnly 'org.spigotmc:spigot:1.17-R0.1-SNAPSHOT'
}

View File

@@ -0,0 +1,19 @@
package com.willfp.eco.proxy.v1_17_R1;
import com.willfp.eco.proxy.proxies.AutoCraftProxy;
import net.minecraft.network.protocol.game.PacketPlayOutAutoRecipe;
import net.minecraft.resources.MinecraftKey;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public final class AutoCraft implements AutoCraftProxy {
@Override
public void modifyPacket(@NotNull final Object packet) throws NoSuchFieldException, IllegalAccessException {
PacketPlayOutAutoRecipe recipePacket = (PacketPlayOutAutoRecipe) packet;
Field fKey = recipePacket.getClass().getDeclaredField("b");
fKey.setAccessible(true);
MinecraftKey key = (MinecraftKey) fKey.get(recipePacket);
fKey.set(recipePacket, new MinecraftKey(key.getNamespace(), key.getKey() + "_displayed"));
}
}

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.proxy.v1_17_R1;
import com.willfp.eco.proxy.proxies.BlockBreakProxy;
import net.minecraft.core.BlockPosition;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class BlockBreak implements BlockBreakProxy {
@Override
public void breakBlock(@NotNull final Player player,
@NotNull final Block block) {
((CraftPlayer) player).getHandle().d.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()));
}
}

View File

@@ -0,0 +1,116 @@
package com.willfp.eco.proxy.v1_17_R1;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.willfp.eco.proxy.proxies.ChatComponentProxy;
import com.willfp.eco.core.display.Display;
import net.minecraft.nbt.MojangsonParser;
import net.minecraft.network.chat.ChatBaseComponent;
import net.minecraft.network.chat.ChatHoverable;
import net.minecraft.network.chat.ChatMessage;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public final class ChatComponent implements ChatComponentProxy {
@Override
public Object modifyComponent(@NotNull final Object object) {
if (!(object instanceof IChatBaseComponent)) {
return object;
}
IChatBaseComponent chatComponent = (IChatBaseComponent) object;
for (IChatBaseComponent iChatBaseComponent : chatComponent) {
if (iChatBaseComponent == null) {
continue;
}
modifyBaseComponent(iChatBaseComponent);
}
return chatComponent;
}
private void modifyBaseComponent(@NotNull final IChatBaseComponent component) {
for (IChatBaseComponent sibling : component.getSiblings()) {
if (sibling == null) {
continue;
}
modifyBaseComponent(sibling);
}
if (component instanceof ChatMessage) {
Arrays.stream(((ChatMessage) component).getArgs())
.filter(o -> o instanceof IChatBaseComponent)
.map(o -> (IChatBaseComponent) o)
.forEach(this::modifyBaseComponent);
}
ChatHoverable hoverable = component.getChatModifier().getHoverEvent();
if (hoverable == null) {
return;
}
JsonObject jsonObject = hoverable.b();
JsonElement json = hoverable.b().get("contents");
if (json.getAsJsonObject().get("id") == null) {
return;
}
if (json.getAsJsonObject().get("tag") == null) {
return;
}
String id = json.getAsJsonObject().get("id").toString();
String tag = json.getAsJsonObject().get("tag").toString();
ItemStack itemStack = getFromTag(tag, id);
Display.displayAndFinalize(itemStack);
json.getAsJsonObject().remove("tag");
String newTag = toJson(itemStack);
json.getAsJsonObject().add("tag", new JsonPrimitive(newTag));
jsonObject.remove("contents");
jsonObject.add("contents", json);
ChatHoverable newHoverable = ChatHoverable.a(jsonObject);
ChatModifier modifier = component.getChatModifier();
modifier = modifier.setChatHoverable(newHoverable);
((ChatBaseComponent) component).setChatModifier(modifier);
}
private static ItemStack getFromTag(@NotNull final String jsonTag,
@NotNull final String id) {
String processedId = id;
String processedJsonTag = jsonTag;
processedId = processedId.replace("minecraft:", "");
processedId = processedId.toUpperCase();
processedId = processedId.replace("\"", "");
processedJsonTag = processedJsonTag.substring(1, processedJsonTag.length() - 1);
processedJsonTag = processedJsonTag.replace("id:", "\"id\":");
processedJsonTag = processedJsonTag.replace("\\", "");
Material material = Material.getMaterial(processedId);
assert material != null;
ItemStack itemStack = new ItemStack(material);
net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
try {
nmsStack.setTag(MojangsonParser.parse(processedJsonTag));
} catch (CommandSyntaxException e) {
e.printStackTrace();
}
return CraftItemStack.asBukkitCopy(nmsStack);
}
private static String toJson(@NotNull final ItemStack itemStack) {
return CraftItemStack.asNMSCopy(itemStack).getOrCreateTag().toString();
}
}

View File

@@ -0,0 +1,41 @@
package com.willfp.eco.proxy.v1_17_R1;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.willfp.eco.proxy.proxies.SkullProxy;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
public final class Skull implements SkullProxy {
/**
* Cached method to set the gameProfile.
*/
private Method setProfile = null;
@Override
public void setSkullTexture(@NotNull final SkullMeta meta,
@NotNull final String base64) {
try {
if (setProfile == null) {
setProfile = meta.getClass().getDeclaredMethod("setProfile", GameProfile.class);
setProfile.setAccessible(true);
}
UUID uuid = new UUID(
base64.substring(base64.length() - 20).hashCode(),
base64.substring(base64.length() - 10).hashCode()
);
GameProfile profile = new GameProfile(uuid, "talismans");
profile.getProperties().put("textures", new Property("textures", base64));
setProfile.invoke(meta, profile);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,13 @@
package com.willfp.eco.proxy.v1_17_R1;
import com.willfp.eco.proxy.proxies.TridentStackProxy;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
public final class TridentStack implements TridentStackProxy {
@Override
public ItemStack getTridentStack(@NotNull final Trident trident) {
return trident.getItem();
}
}

View File

@@ -0,0 +1,65 @@
package com.willfp.eco.proxy.v1_17_R1;
import com.willfp.eco.core.display.Display;
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftMerchantRecipe;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantRecipe;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public final class VillagerTrade implements VillagerTradeProxy {
/**
* Handle.
*/
private final Field handle;
/**
* Create new Villager Trade.
*/
public VillagerTrade() {
try {
handle = CraftMerchantRecipe.class.getDeclaredField("handle");
handle.setAccessible(true);
return;
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
throw new RuntimeException("Error!");
}
@Override
public MerchantRecipe displayTrade(@NotNull final MerchantRecipe recipe) {
CraftMerchantRecipe oldRecipe = (CraftMerchantRecipe) recipe;
CraftMerchantRecipe newRecipe = new CraftMerchantRecipe(
Display.display(recipe.getResult().clone()),
recipe.getUses(),
recipe.getMaxUses(),
recipe.hasExperienceReward(),
recipe.getVillagerExperience(),
recipe.getPriceMultiplier()
);
for (ItemStack ingredient : recipe.getIngredients()) {
newRecipe.addIngredient(Display.display(ingredient.clone()));
}
getHandle(newRecipe).setSpecialPrice(getHandle(oldRecipe).getSpecialPrice());
return newRecipe;
}
@NotNull
private net.minecraft.world.item.trading.MerchantRecipe getHandle(@NotNull final CraftMerchantRecipe recipe) {
try {
return (net.minecraft.world.item.trading.MerchantRecipe) handle.get(recipe);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
throw new IllegalArgumentException("Not CMR");
}
}

View File

@@ -141,14 +141,19 @@ public class EcoSpigotPlugin extends EcoPlugin {
@Override
public List<AbstractPacketAdapter> getPacketAdapters() {
return Arrays.asList(
List<AbstractPacketAdapter> adapters = new ArrayList<>(Arrays.asList(
new PacketAutoRecipe(this),
new PacketChat(this),
new PacketOpenWindowMerchant(this),
new PacketSetCreativeSlot(this),
new PacketSetSlot(this),
new PacketWindowItems(this)
);
));
if (!this.getConfigYml().getBool("disable-display-on-villagers")) {
adapters.add(new PacketOpenWindowMerchant(this));
}
return adapters;
}
@Override

View File

@@ -1,17 +1,23 @@
package com.willfp.eco.spigot.display;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.willfp.eco.core.AbstractPacketAdapter;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.proxy.proxies.VillagerTradeProxy;
import com.willfp.eco.spigot.InternalProxyUtils;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.AbstractPacketAdapter;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MerchantRecipe;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PacketOpenWindowMerchant extends AbstractPacketAdapter {
/**
@@ -20,16 +26,32 @@ public class PacketOpenWindowMerchant extends AbstractPacketAdapter {
* @param plugin The plugin to listen through.
*/
public PacketOpenWindowMerchant(@NotNull final EcoPlugin plugin) {
super(plugin, PacketType.Play.Server.OPEN_WINDOW_MERCHANT, false);
super(plugin, PacketType.Play.Server.OPEN_WINDOW_MERCHANT, ListenerPriority.MONITOR, true);
}
@Override
public void onSend(@NotNull final PacketContainer packet,
@NotNull final Player player) {
List<MerchantRecipe> recipes = packet.getMerchantRecipeLists().readSafely(0);
@NotNull final Player player,
@NotNull final PacketEvent event) {
List<MerchantRecipe> recipes = new ArrayList<>();
recipes = recipes.stream().peek(merchantRecipe -> InternalProxyUtils.getProxy(VillagerTradeProxy.class).displayTrade(merchantRecipe)).collect(Collectors.toList());
if (((EcoPlugin) this.getPlugin()).getConfigYml().getBool("villager-display-fix")) {
for (MerchantRecipe recipe : packet.getMerchantRecipeLists().read(0)) {
ItemStack result = recipe.getResult();
ItemMeta meta = result.getItemMeta();
if (meta != null) {
meta.removeItemFlags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_POTION_EFFECTS);
meta.getPersistentDataContainer().remove(NamespacedKey.fromString("ecoenchants:ecoenchantlore-skip"));
result.setItemMeta(meta);
}
}
}
packet.getMerchantRecipeLists().writeSafely(0, recipes);
for (MerchantRecipe recipe : packet.getMerchantRecipeLists().read(0)) {
MerchantRecipe newRecipe = InternalProxyUtils.getProxy(VillagerTradeProxy.class).displayTrade(recipe);
recipes.add(newRecipe);
}
packet.getMerchantRecipeLists().write(0, recipes);
}
}

View File

@@ -0,0 +1,2 @@
disable-display-on-villagers: false
villager-display-fix: false

View File

@@ -10,6 +10,7 @@ loadbefore:
- StatTrackers
- EcoArmor
- EcoBosses
- EcoSkills
depend:
- ProtocolLib
softdepend:

View File

@@ -2,12 +2,14 @@ package com.willfp.eco.proxy.proxies;
import com.willfp.eco.core.proxy.AbstractProxy;
import org.bukkit.inventory.MerchantRecipe;
import org.jetbrains.annotations.NotNull;
public interface VillagerTradeProxy extends AbstractProxy {
/**
* Apply enchant display to the result of trades.
* Display a MerchantRecipe.
*
* @param merchantRecipe The recipe to modify.
* @param recipe The recipe.
* @return The new recipe.
*/
void displayTrade(MerchantRecipe merchantRecipe);
MerchantRecipe displayTrade(@NotNull MerchantRecipe recipe);
}

View File

@@ -1,2 +1,2 @@
version = 5.2.0
version = 5.4.0
plugin-name = eco

View File

@@ -7,5 +7,6 @@ include ':eco-core:core-nms'
include ':eco-core:core-nms:v1_16_R1'
include ':eco-core:core-nms:v1_16_R2'
include ':eco-core:core-nms:v1_16_R3'
include ':eco-core:core-nms:v1_17_R1'
include ':eco-core:core-proxy'
include ':eco-core:core-plugin'