Skip to content

Commit

Permalink
Merge pull request #47 from elian1203/fix-nbt-parse
Browse files Browse the repository at this point in the history
Fix exception from MiniMessage when item has colors in name/lore
  • Loading branch information
elian1203 authored Oct 9, 2023
2 parents 265b4a6 + 9440c9d commit e96fb32
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import com.google.inject.Singleton;
import me.elian.ezauctions.Logger;
import me.elian.ezauctions.model.*;
import net.kyori.adventure.nbt.api.BinaryTagHolder;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Formatter;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
Expand Down Expand Up @@ -177,6 +179,7 @@ private Component getAuctionComponent(String rawMessage, AuctionData data, @Null
Component parsed;
try {
parsed = MiniMessage.miniMessage().deserialize(message, mergedResolvers);
parsed = reconstructAuctionComponentRecursive(parsed, data);
} catch (Exception e) {
logger.severe("Error parsing message! Auction broadcast will not work correctly!\n" + rawMessage, e);
parsed = LegacyComponentSerializer.legacyAmpersand().deserialize(message);
Expand All @@ -185,6 +188,33 @@ private Component getAuctionComponent(String rawMessage, AuctionData data, @Null
return parsed;
}

private Component reconstructAuctionComponentRecursive(Component component, AuctionData data) {
Component returnComponent = component;

List<Component> childrenUnmodifiable = component.children();
if (!childrenUnmodifiable.isEmpty()) {
List<Component> children = new ArrayList<>(childrenUnmodifiable.size());
for (Component child : childrenUnmodifiable) {
children.add(reconstructAuctionComponentRecursive(child, data));
}

returnComponent = returnComponent.children(children);
}

HoverEvent<?> hoverEvent = component.hoverEvent();
if (hoverEvent != null && hoverEvent.action().type() == HoverEvent.ShowItem.class) {
HoverEvent.ShowItem showItem = (HoverEvent.ShowItem) hoverEvent.value();
if (showItem.item().compareTo(data.getItemKey()) == 0
&& (showItem.nbt() == null || showItem.nbt().string().isEmpty())) {
HoverEvent<HoverEvent.ShowItem> newHoverEvent = HoverEvent.showItem(data.getItemKey(),
data.getAmount(), BinaryTagHolder.binaryTagHolder(data.getItemNbt()));
returnComponent = returnComponent.hoverEvent(newHoverEvent);
}
}

return returnComponent;
}

private TagResolver[] getAuctionTagResolvers(AuctionData data, BidList bidList, int remainingSeconds) {
ItemStack item = data.getItem();

Expand Down Expand Up @@ -216,7 +246,6 @@ private TagResolver[] getAuctionTagResolvers(AuctionData data, BidList bidList,
Placeholder.unparsed("minecraftname", data.getMinecraftName()),
Placeholder.unparsed("customname", data.getCustomName()),
Placeholder.unparsed("materialtype", item.getType().toString().toLowerCase()),
Placeholder.unparsed("itemnbt", data.getItemNbt()),
Formatter.number("startingprice", data.getStartingPrice()),
Formatter.number("highestbidamount", highestBidAmount),
Placeholder.unparsed("highestbidder", highestBidderName),
Expand Down Expand Up @@ -281,7 +310,7 @@ private String replaceAuctionPatterns(String raw, AuctionData data) {
replaced = replaced.replace("<itemamount>", Integer.toString(data.getAmount()));
replaced = replaced.replace("<minecraftname>", data.getMinecraftName());
replaced = replaced.replace("<customname>", data.getCustomName());
replaced = replaced.replace("<itemnbt>", data.getItemNbt());
replaced = replaced.replace("<itemnbt>", "");
return replaced;
}

Expand Down
6 changes: 5 additions & 1 deletion src/main/java/me/elian/ezauctions/model/Auction.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,11 @@ public void run() {

private void cancelRepeatingTask() {
running = false;
repeatingTask.cancel();

if (repeatingTask != null) {
repeatingTask.cancel();
}

scoreboard.remove();
completedRunnable.run();
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/me/elian/ezauctions/model/AuctionData.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
import me.elian.ezauctions.controller.MessageController;
import me.elian.ezauctions.helper.ItemHelper;
import me.elian.ezauctions.scheduler.TaskScheduler;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Formatter;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
Expand All @@ -36,6 +38,7 @@ public final class AuctionData {
private String itemNbt;
private String minecraftName;
private String customName;
private Key itemKey;

public AuctionData(AuctionPlayer auctioneer, ItemStack item, String amountString, int startingAuctionTime,
double startingPrice, double incrementPrice, double autoBuyPrice, boolean isSealed,
Expand Down Expand Up @@ -107,6 +110,10 @@ public String getCustomName() {
return customName;
}

public Key getItemKey() {
return itemKey;
}

public void gatherAdditionalData(Logger logger) {
if (item == null || item.getType() == Material.AIR)
return;
Expand All @@ -129,6 +136,9 @@ public void gatherAdditionalData(Logger logger) {
logger.severe("Could not get item NBT! Item hover will not work correctly!", e);
}

NamespacedKey typeKey = item.getType().getKey();
itemKey = Key.key(typeKey.getNamespace(), typeKey.getKey());

minecraftName = ItemHelper.getMinecraftName(item);
customName = minecraftName;
if (meta != null && !meta.getDisplayName().isBlank()) {
Expand Down
5 changes: 2 additions & 3 deletions src/main/resources/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ command.auction.queue.list={prefix} <blue>Auction Queue:
command.auction.queue.empty=<aqua>No auctions in the queue!
# the same values that are in the auction paramater block are available here
# <position> is the position in the queue
command.auction.queue.item=<aqua><position>. <green><itemamount> <aqua><hover:show_item:<materialtype>:<itemamount>:"<itemnbt>"><hascustomname><i><customname></i></hascustomname><nocustomname><lang:<minecraftname>></nocustomname><skull> <green>(Head of <white><skullowner></white>)<green></skull></hover> <blue>starting at <gold><startingprice> <blue>by <yellow><hover:show_entity:player:"<auctioneeruuid>"><auctioneer></hover>
command.auction.queue.item=<aqua><position>. <green><itemamount> <aqua><hover:show_item:<materialtype>:<itemamount>:""><hascustomname><i><customname></i></hascustomname><nocustomname><lang:<minecraftname>></nocustomname><skull> <green>(Head of <white><skullowner></white>)<green></skull></hover> <blue>starting at <gold><startingprice> <blue>by <yellow><hover:show_entity:player:"<auctioneeruuid>"><auctioneer></hover>

command.auction.end.help=<hover:show_text:"/auction end"><click:suggest_command:"/auction end"><aqua>/auction end <dark_blue>: <blue>Forcefully end the current auction.</click></hover>
command.auction.end.attempt-others={prefix}<dark_red>You do not have permission to end other players' auctions!
Expand All @@ -119,7 +119,6 @@ command.bid.help=<hover:show_text:"/bid"><click:suggest_command:"/bid "><aqua>/b
# <minecraftname> is the translatable minecraft name of the item being auctioned
# <customname> is the custom name (translatable minecraft name if no custom name specified) of the item being auctioned
# <materialtype> is material type of the item being auctioned
# <itemnbt> is the nbt of the item being auctioned
# <startingprice> is the starting price
# <highestbidamount> is the highest bid (starting price if no bids or sealed auction)
# <highestbidder> is the highest bidder name (blank if no bids or sealed auction)
Expand All @@ -137,7 +136,7 @@ command.bid.help=<hover:show_text:"/bid"><click:suggest_command:"/bid "><aqua>/b
# <sealed></sealed> -> everything inside will be blank if the auction is not sealed
# <repair></repair> -> everything inside will be blank if the item does not have a work penalty
# <unrepairable></unrepairable> -> everything inside will be blank if the item is not repairable
auction.info={prefix}<yellow><hover:show_entity:player:"<auctioneeruuid>"><auctioneer></hover> <blue>is auctioning <green><itemamount> <aqua><hover:show_item:<materialtype>:<itemamount>:"<itemnbt>"><hascustomname><i><customname></i></hascustomname><nocustomname><lang:<minecraftname>></nocustomname><skull> <green>(Head of <white><skullowner></white>)<green></skull></hover> <blue>for <gold>$<highestbidamount> <blue>at an increment of <gold>$<increment> <blue>for <green><remainingtime> <blue>seconds.\
auction.info={prefix}<yellow><hover:show_entity:player:"<auctioneeruuid>"><auctioneer></hover> <blue>is auctioning <green><itemamount> <aqua><hover:show_item:<materialtype>:<itemamount>:""><hascustomname><i><customname></i></hascustomname><nocustomname><lang:<minecraftname>></nocustomname><skull> <green>(Head of <white><skullowner></white>)<green></skull></hover> <blue>for <gold>$<highestbidamount> <blue>at an increment of <gold>$<increment> <blue>for <green><remainingtime> <blue>seconds.\
<unrepairable><newline><blue>This item cannot be repaired.</unrepairable><repair><newLine><blue>This item has a prior work penalty of <green><repairprice><blue> levels.</repair>\
<autobuy><newline><blue>The auto-buy of this auction is set at <gold>$<autobuy><blue></autobuy>\
<sealed><newline><blue>This is a sealed auction. Bids will not be disclosed.</sealed>
Expand Down

0 comments on commit e96fb32

Please sign in to comment.