Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
<scope>provided</scope>
</dependency>

<dependency>
<groupId>net.dmulloy2</groupId>
<artifactId>ProtocolLib</artifactId>
<version>5.4.0</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>su.nightexpress.nightcore</groupId>
<artifactId>NightCore</artifactId>
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/yourname/sellplugin/SellPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import com.yourname.sellplugin.command.SellAllCommand;
import com.yourname.sellplugin.command.SellCommand;
import com.yourname.sellplugin.command.FastSellAllCommand;
import com.yourname.sellplugin.command.TopSellCommand;
import com.yourname.sellplugin.economy.EconomyManager;
import com.yourname.sellplugin.gui.GUIListener;
import com.yourname.sellplugin.listener.WorthPacketListener;
import com.yourname.sellplugin.manager.ConfigManager;
import com.yourname.sellplugin.manager.DailyBonusManager;
import com.yourname.sellplugin.manager.MultiplierManager;
Expand All @@ -20,6 +22,7 @@ public class SellPlugin extends JavaPlugin {
private MultiplierManager multiplierManager;
private DailyBonusManager dailyBonusManager;
private SellManager sellManager;
private WorthPacketListener worthPacketListener;

@Override
public void onEnable() {
Expand All @@ -42,9 +45,13 @@ public void onEnable() {

getCommand("sell").setExecutor(new SellCommand(this));
getCommand("sellall").setExecutor(new SellAllCommand(this));
getCommand("fastsellall").setExecutor(new FastSellAllCommand(this));
getCommand("topsell").setExecutor(new TopSellCommand(this));
getServer().getPluginManager().registerEvents(new GUIListener(this), this);

worthPacketListener = new WorthPacketListener(this);
worthPacketListener.register();

getLogger().info("SellPlugin has been enabled successfully.");
}

Expand All @@ -53,6 +60,9 @@ public void onDisable() {
if (multiplierManager != null) {
multiplierManager.saveAll();
}
if (worthPacketListener != null) {
worthPacketListener.unregister();
}
getLogger().info("SellPlugin has been disabled.");
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.yourname.sellplugin.command;

import com.yourname.sellplugin.SellPlugin;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public class FastSellAllCommand implements CommandExecutor {

private final SellPlugin plugin;

public FastSellAllCommand(SellPlugin plugin) {
this.plugin = plugin;
}

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player player)) {
sender.sendMessage("Only players can use this command.");
return true;
}

if (!player.hasPermission("sellplugin.use")) {
player.sendMessage(plugin.getConfigManager().getMessage("no-permission"));
return true;
}

plugin.getSellManager().sellAll(player);
return true;
}
}
21 changes: 9 additions & 12 deletions src/main/java/com/yourname/sellplugin/gui/CategoryItemsGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.yourname.sellplugin.SellPlugin;
import com.yourname.sellplugin.manager.ConfigManager;
import com.yourname.sellplugin.manager.PriceManager;
import com.yourname.sellplugin.util.ItemNameFormatter;
import com.yourname.sellplugin.util.NumberFormatter;
import com.yourname.sellplugin.util.SmallCaps;
import org.bukkit.Bukkit;
Expand Down Expand Up @@ -141,7 +142,7 @@ private void populate() {
int catCount = plugin.getSellManager().countCategoryItems(player, categoryId);
List<String> sellLore = new ArrayList<>();
sellLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("category: ")
+ ChatColor.WHITE + categoryId);
+ ChatColor.WHITE + ChatColor.stripColor(cfg.getCategoryDisplayName(categoryId)));
if (catCount > 0) {
sellLore.add(ChatColor.GRAY + " ▸ " + SmallCaps.convert("items: ")
+ ChatColor.WHITE + NumberFormatter.format(catCount));
Expand All @@ -161,10 +162,11 @@ private void populate() {
private ItemStack buildItemDisplay(String itemKey) {
PriceManager pm = plugin.getPriceManager();
double base = pm.getPrice(itemKey);
double earned = plugin.getMultiplierManager().getMultiplier(player, categoryId);
double daily = plugin.getDailyBonusManager().getDailyBonus(categoryId);
double mult = earned + daily;
double effective = base * mult;
String itemCategory = pm.getCategory(itemKey);
double earned = plugin.getMultiplierManager().getMultiplier(player, itemCategory);
double daily = plugin.getDailyBonusManager().getDailyBonus(itemCategory);
double effectiveMultiplier = plugin.getMultiplierManager().getEffectiveMultiplier(player, itemCategory);
double effective = base * effectiveMultiplier;

// Build correct ItemStack (handles potions with PotionMeta)
ItemStack item = resolveItemStack(itemKey);
Expand All @@ -179,13 +181,13 @@ private ItemStack buildItemDisplay(String itemKey) {
+ ChatColor.GOLD + " (+" + String.format("%.2fx", daily) + " today)");
} else {
lore.add(ChatColor.GRAY + " ▸ " + ChatColor.WHITE + "Mult: "
+ ChatColor.AQUA + String.format("%.2fx", mult));
+ ChatColor.AQUA + String.format("%.2fx", effectiveMultiplier));
}
lore.add(ChatColor.GRAY + " ▸ " + ChatColor.WHITE + "Price: "
+ ChatColor.GREEN + "$" + NumberFormatter.format(effective));
lore.add(ChatColor.DARK_GRAY + "━━━━━━━━━━━━━━━━━━━━━");

String displayName = ChatColor.WHITE + formatItemName(itemKey);
String displayName = ChatColor.WHITE + ItemNameFormatter.formatKey(itemKey);

ItemMeta meta = item.getItemMeta();
if (meta != null) {
Expand Down Expand Up @@ -224,10 +226,6 @@ private ItemStack resolveItemStack(String itemKey) {
return new ItemStack(mat != null ? mat : Material.BARRIER);
}

private String formatItemName(String key) {
return key.replace("_", " ").replace(":", " – ");
}

// ── Item clicked ─────────────────────────────────────────────────────────

/**
Expand Down Expand Up @@ -286,4 +284,3 @@ public int getPage() {
return page;
}
}

9 changes: 7 additions & 2 deletions src/main/java/com/yourname/sellplugin/gui/ConfirmSellGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ public class ConfirmSellGUI implements InventoryHolder {
private final Inventory inv;
private final SellPlugin plugin;
private final String categoryId;
private final int returnPage;

public ConfirmSellGUI(SellPlugin plugin, Player player, String categoryId) {
public ConfirmSellGUI(SellPlugin plugin, Player player, String categoryId, int returnPage) {
this.plugin = plugin;
this.categoryId = categoryId;
this.returnPage = returnPage;

ConfigManager cfg = plugin.getConfigManager();
String title = ChatColor.DARK_GRAY + "" + ChatColor.BOLD
Expand Down Expand Up @@ -113,5 +115,8 @@ public void open(Player p) {
public String getCategoryId() {
return categoryId;
}
}

public int getReturnPage() {
return returnPage;
}
}
10 changes: 4 additions & 6 deletions src/main/java/com/yourname/sellplugin/gui/GUIListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public void onClick(InventoryClickEvent e) {
e.setCancelled(true);
String catId = shopGUI.getCategoryAtSlot(slot);
if (catId != null) {
new CategoryProgressGUI(plugin, player, catId).open(player);
new CategoryItemsGUI(plugin, player, catId, 0).open(player);
}
return;
}
Expand Down Expand Up @@ -130,7 +130,7 @@ public void onClick(InventoryClickEvent e) {
}

if (slot == ConfirmSellGUI.SLOT_CANCEL) {
new CategoryProgressGUI(plugin, player, confirmGUI.getCategoryId()).open(player);
new CategoryItemsGUI(plugin, player, confirmGUI.getCategoryId(), confirmGUI.getReturnPage()).open(player);
return;
}
return;
Expand All @@ -145,7 +145,7 @@ public void onClick(InventoryClickEvent e) {
int slot = e.getSlot();

if (slot == CategoryItemsGUI.SLOT_BACK) {
new CategoryProgressGUI(plugin, player, catItemsGUI.getCategoryId()).open(player);
new ShopMainGUI(plugin, player).open(player);
return;
}

Expand All @@ -160,8 +160,7 @@ public void onClick(InventoryClickEvent e) {
}

if (slot == CategoryItemsGUI.SLOT_SELL_ALL) {
player.closeInventory();
plugin.getSellManager().sellCategory(player, catItemsGUI.getCategoryId());
new ConfirmSellGUI(plugin, player, catItemsGUI.getCategoryId(), catItemsGUI.getPage()).open(player);
return;
}

Expand Down Expand Up @@ -307,4 +306,3 @@ private void returnItem(Player player, ItemStack item) {
}
}
}

2 changes: 1 addition & 1 deletion src/main/java/com/yourname/sellplugin/gui/ShopMainGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private ItemStack buildCategoryButton(String catId) {
+ ChatColor.YELLOW + "+" + String.format("%.2f", dailyBonus) + "x");
}
lore.add(ChatColor.DARK_GRAY + "━━━━━━━━━━━━━━━━━━━");
lore.add(ChatColor.YELLOW + " ✦ " + SmallCaps.convert("click to view progress!"));
lore.add(ChatColor.YELLOW + " ✦ " + SmallCaps.convert("click to view items & prices!"));

List<String> extraLore = cfg.getCategoryLore(catId);
if (!extraLore.isEmpty()) lore.addAll(extraLore);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package com.yourname.sellplugin.listener;

import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener;
import com.yourname.sellplugin.SellPlugin;
import com.yourname.sellplugin.gui.CategoryItemsGUI;
import com.yourname.sellplugin.gui.CategoryProgressGUI;
import com.yourname.sellplugin.gui.ConfirmSellAllGUI;
import com.yourname.sellplugin.gui.ConfirmSellGUI;
import com.yourname.sellplugin.gui.SellAllGUI;
import com.yourname.sellplugin.gui.ShopMainGUI;
import com.yourname.sellplugin.gui.TopSellGUI;
import com.yourname.sellplugin.util.NumberFormatter;
import org.bukkit.block.DoubleChest;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.BlockInventoryHolder;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import java.util.ArrayList;
import java.util.List;

public class WorthPacketListener {

private final SellPlugin plugin;
private PacketListener packetListener;

public WorthPacketListener(SellPlugin plugin) {
this.plugin = plugin;
}

public void register() {
if (plugin.getServer().getPluginManager().getPlugin("ProtocolLib") == null) {
plugin.getLogger().warning("ProtocolLib not found; sell worth tooltips are disabled.");
return;
}

ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
packetListener = new PacketAdapter(plugin, ListenerPriority.NORMAL,
PacketType.Play.Server.SET_SLOT,
PacketType.Play.Server.WINDOW_ITEMS) {

@Override
public void onPacketSending(PacketEvent event) {
if (!WorthPacketListener.this.plugin.getConfigManager().isWorthEnabled()) return;
if (!shouldDecorate(event.getPlayer())) return;

if (event.getPacketType() == PacketType.Play.Server.SET_SLOT) {
if (event.getPacket().getItemModifier().size() <= 0) return;
ItemStack item = event.getPacket().getItemModifier().read(0);
ItemStack updated = addWorthLore(event.getPlayer(), item);
if (updated != item) {
event.getPacket().getItemModifier().write(0, updated);
}
return;
}

if (event.getPacket().getItemListModifier().size() <= 0) return;
List<ItemStack> items = event.getPacket().getItemListModifier().read(0);
if (items == null || items.isEmpty()) return;

boolean changed = false;
List<ItemStack> updatedItems = new ArrayList<>(items.size());
for (ItemStack item : items) {
ItemStack updated = addWorthLore(event.getPlayer(), item);
updatedItems.add(updated);
changed |= updated != item;
}

if (changed) {
event.getPacket().getItemListModifier().write(0, updatedItems);
}
}
};
protocolManager.addPacketListener(packetListener);
}

public void unregister() {
if (packetListener == null) return;
ProtocolLibrary.getProtocolManager().removePacketListener(packetListener);
packetListener = null;
}

private ItemStack addWorthLore(Player player, ItemStack original) {
if (original == null || original.getType().isAir()) return original;

double worth = plugin.getSellManager().calculateItemWorth(player, original);
if (worth <= 0) return original;

ItemStack clone = original.clone();
ItemMeta meta = clone.getItemMeta();
if (meta == null) return original;

List<String> lore = meta.hasLore() ? new ArrayList<>(meta.getLore()) : new ArrayList<>();
if (!lore.isEmpty()) {
lore.add("");
}
lore.add(plugin.getConfigManager().getWorthFormat()
.replace("{worth}", NumberFormatter.format(worth)));
meta.setLore(lore);
clone.setItemMeta(meta);
return clone;
}

private boolean shouldDecorate(Player player) {
Inventory topInventory = player.getOpenInventory().getTopInventory();
InventoryHolder holder = topInventory.getHolder();

if (isPluginGui(holder)) return false;

InventoryType type = topInventory.getType();
if (type == InventoryType.CRAFTING
|| type == InventoryType.CREATIVE
|| type == InventoryType.PLAYER) {
return true;
}

if (holder instanceof BlockInventoryHolder || holder instanceof DoubleChest) {
return true;
}

return switch (type) {
case ANVIL, BEACON, BLAST_FURNACE, BREWING, CARTOGRAPHY, CRAFTER,
ENCHANTING, FURNACE, GRINDSTONE, LOOM, MERCHANT,
SMITHING, SMOKER, STONECUTTER -> true;
default -> false;
};
}

private boolean isPluginGui(InventoryHolder holder) {
return holder instanceof ShopMainGUI
|| holder instanceof CategoryProgressGUI
|| holder instanceof CategoryItemsGUI
|| holder instanceof SellAllGUI
|| holder instanceof ConfirmSellGUI
|| holder instanceof ConfirmSellAllGUI
|| holder instanceof TopSellGUI;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ public Material getFillerBlock() {
return mat != null ? mat : Material.BLACK_STAINED_GLASS_PANE;
}

public boolean isWorthEnabled() {
return plugin.getConfig().getBoolean("worth.enabled", true);
}

public String getWorthFormat() {
return color(plugin.getConfig().getString("worth.format", "&7Worth &a&l${worth}"));
}

// ---- SellAll GUI (simple /sellall GUI) --------------------------------
public String getSellAllGuiTitle() {
return color(plugin.getConfig().getString("sell-all-gui.title", "&8&lSell All Items"));
Expand Down
Loading
Loading