mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-12 02:37:27 +00:00
Auction Blacklist System
This commit is contained in:
1 parent
b85804af98
commit
fe998ea31c
10 files changed
+756
-240
No files matched your search
@@ -2,9 +2,16 @@ package foxz.command;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @deprecated The /noppes command is deprecated and no longer supported.
|
||||
* Please use the /kam command instead for all CNPC+ operations.
|
||||
*/
|
||||
@Deprecated
|
||||
public class CommandNoppes extends CommandBase {
|
||||
|
||||
public CmdNoppes noppes = new CmdNoppes(this);
|
||||
@@ -21,6 +28,15 @@ public class CommandNoppes extends CommandBase {
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender var1, String[] var2) {
|
||||
// Send deprecation warning
|
||||
var1.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "[DEPRECATED] " +
|
||||
EnumChatFormatting.YELLOW + "The /noppes command is deprecated and no longer supported."));
|
||||
var1.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW +
|
||||
"Please use " + EnumChatFormatting.GREEN + "/kam" + EnumChatFormatting.YELLOW + " commands instead."));
|
||||
var1.addChatMessage(new ChatComponentText(EnumChatFormatting.GRAY +
|
||||
"Type " + EnumChatFormatting.WHITE + "/kam help" + EnumChatFormatting.GRAY + " for available commands."));
|
||||
|
||||
// Still execute the command for backwards compatibility
|
||||
noppes.processCommand(var1, var2);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package kamkeel.npcs.command;
|
||||
|
||||
import kamkeel.npcs.command.auction.BlacklistSubCommand;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import noppes.npcs.NoppesUtilServer;
|
||||
import noppes.npcs.config.ConfigMarket;
|
||||
import noppes.npcs.constants.EnumGuiType;
|
||||
@@ -21,6 +21,11 @@ import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class AuctionCommand extends CommandKamkeelBase {
|
||||
|
||||
public AuctionCommand() {
|
||||
super();
|
||||
registerNestedCommand(new BlacklistSubCommand());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "auction";
|
||||
@@ -158,10 +163,17 @@ public class AuctionCommand extends CommandKamkeelBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List addTabCompletionOptions(ICommandSender par1, String[] args) {
|
||||
public List addTabCompletionOptions(ICommandSender sender, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getListOfStringsMatchingLastWord(args, new String[]{"list", "view", "open"});
|
||||
return getListOfStringsMatchingLastWord(args, getAllSubCommandNames());
|
||||
}
|
||||
|
||||
// Delegate to nested commands for deeper tab completion
|
||||
List nestedCompletions = getNestedTabCompletions(sender, args);
|
||||
if (nestedCompletions != null) {
|
||||
return nestedCompletions;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -11,13 +11,11 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class CommandKamkeelBase extends CommandBase {
|
||||
public Map<String, Method> subcommands = new HashMap<String, Method>();
|
||||
public Map<String, CommandKamkeelBase> nestedCommands = new HashMap<String, CommandKamkeelBase>();
|
||||
|
||||
public CommandKamkeelBase() {
|
||||
for (Method m : this.getClass().getDeclaredMethods()) {
|
||||
@@ -31,6 +29,14 @@ public abstract class CommandKamkeelBase extends CommandBase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a nested command class as a subcommand.
|
||||
* The nested command's getCommandName() becomes the subcommand name.
|
||||
*/
|
||||
public void registerNestedCommand(CommandKamkeelBase command) {
|
||||
nestedCommands.put(command.getCommandName().toLowerCase(), command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
|
||||
@@ -51,7 +57,7 @@ public abstract class CommandKamkeelBase extends CommandBase {
|
||||
}
|
||||
|
||||
public boolean runSubCommands() {
|
||||
return !subcommands.isEmpty();
|
||||
return !subcommands.isEmpty() || !nestedCommands.isEmpty();
|
||||
}
|
||||
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@@ -71,6 +77,22 @@ public abstract class CommandKamkeelBase extends CommandBase {
|
||||
}
|
||||
|
||||
public void processSubCommand(ICommandSender sender, String command, String[] args) throws CommandException {
|
||||
// Check nested commands first
|
||||
CommandKamkeelBase nested = nestedCommands.get(command.toLowerCase());
|
||||
if (nested != null) {
|
||||
if (!canSendNestedCommand(sender, nested)) {
|
||||
throw new CommandException("You are not allowed to use this command: " + command);
|
||||
}
|
||||
|
||||
if (args.length == 0 || !nested.runSubCommands()) {
|
||||
nested.processCommand(sender, args);
|
||||
} else {
|
||||
nested.processSubCommand(sender, args[0], Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Fall back to method subcommands
|
||||
Method m = subcommands.get(command.toLowerCase());
|
||||
if (m == null)
|
||||
throw new CommandException("Unknown subcommand " + command);
|
||||
@@ -132,4 +154,55 @@ public abstract class CommandKamkeelBase extends CommandBase {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canSendNestedCommand(ICommandSender sender, CommandKamkeelBase nested) {
|
||||
int permission = nested.getRequiredPermissionLevel();
|
||||
String subCommand = nested.getCommandName();
|
||||
|
||||
if (sender.canCommandSenderUseCommand(permission, getSubUniversalPermission())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sender.canCommandSenderUseCommand(permission, getSubCommandPermission(subCommand))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sender instanceof EntityPlayer) {
|
||||
return CustomNpcsPermissions.hasCustomPermission((EntityPlayer) sender, getSubCommandPermission(subCommand));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// =========================================
|
||||
// Tab Completion Helpers
|
||||
// =========================================
|
||||
|
||||
/**
|
||||
* Get all subcommand names (both method-based and nested)
|
||||
*/
|
||||
public String[] getAllSubCommandNames() {
|
||||
Set<String> names = new HashSet<>();
|
||||
names.addAll(subcommands.keySet());
|
||||
names.addAll(nestedCommands.keySet());
|
||||
return names.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tab completions for nested command at given depth
|
||||
*/
|
||||
public List getNestedTabCompletions(ICommandSender sender, String[] args) {
|
||||
if (args.length == 0) return null;
|
||||
|
||||
String subCmd = args[0].toLowerCase();
|
||||
CommandKamkeelBase nested = nestedCommands.get(subCmd);
|
||||
|
||||
if (nested != null && args.length > 1) {
|
||||
// Delegate to nested command
|
||||
String[] nestedArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
return nested.addTabCompletionOptions(sender, nestedArgs);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
package kamkeel.npcs.command.auction;
|
||||
|
||||
import kamkeel.npcs.command.CommandKamkeelBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import noppes.npcs.controllers.data.AuctionBlacklist;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static kamkeel.npcs.util.ColorUtil.sendError;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendMessage;
|
||||
import static kamkeel.npcs.util.ColorUtil.sendResult;
|
||||
|
||||
public class BlacklistSubCommand extends CommandKamkeelBase {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "blacklist";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Manage auction item blacklist";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) throws CommandException {
|
||||
// Show help when called with no subcommand
|
||||
sendHelp(sender);
|
||||
}
|
||||
|
||||
private void sendHelp(ICommandSender sender) {
|
||||
sendMessage(sender, "\u00A76=== Auction Blacklist Commands ===");
|
||||
sendMessage(sender, "\u00A7e/cnpc auction blacklist add <item|mod|nbt> <value>");
|
||||
sendMessage(sender, "\u00A7e/cnpc auction blacklist remove <item|mod|nbt> <value>");
|
||||
sendMessage(sender, "\u00A7e/cnpc auction blacklist list [item|mod|nbt]");
|
||||
sendMessage(sender, "\u00A7e/cnpc auction blacklist reload");
|
||||
sendMessage(sender, "\u00A7e/cnpc auction blacklist check \u00A77(checks held item)");
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Add item, mod, or NBT tag to blacklist",
|
||||
usage = "<item|mod|nbt> <value>"
|
||||
)
|
||||
public void add(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (args.length < 2) {
|
||||
sendError(sender, "Usage: /cnpc auction blacklist add <item|mod|nbt> <value>");
|
||||
return;
|
||||
}
|
||||
|
||||
String type = args[0].toLowerCase();
|
||||
String value = args[1];
|
||||
|
||||
switch (type) {
|
||||
case "item":
|
||||
if (AuctionBlacklist.addItem(value)) {
|
||||
sendResult(sender, "Added item to blacklist: " + value);
|
||||
} else {
|
||||
sendError(sender, "Failed to add item to blacklist");
|
||||
}
|
||||
break;
|
||||
case "mod":
|
||||
if (AuctionBlacklist.addMod(value)) {
|
||||
sendResult(sender, "Added mod to blacklist: " + value);
|
||||
} else {
|
||||
sendError(sender, "Failed to add mod to blacklist");
|
||||
}
|
||||
break;
|
||||
case "nbt":
|
||||
if (AuctionBlacklist.addNBTTag(value)) {
|
||||
sendResult(sender, "Added NBT tag to blacklist: " + value);
|
||||
} else {
|
||||
sendError(sender, "Failed to add NBT tag to blacklist");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sendError(sender, "Unknown type: " + type + ". Use: item, mod, or nbt");
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Remove item, mod, or NBT tag from blacklist",
|
||||
usage = "<item|mod|nbt> <value>"
|
||||
)
|
||||
public void remove(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (args.length < 2) {
|
||||
sendError(sender, "Usage: /cnpc auction blacklist remove <item|mod|nbt> <value>");
|
||||
return;
|
||||
}
|
||||
|
||||
String type = args[0].toLowerCase();
|
||||
String value = args[1];
|
||||
|
||||
switch (type) {
|
||||
case "item":
|
||||
if (AuctionBlacklist.removeItem(value)) {
|
||||
sendResult(sender, "Removed item from blacklist: " + value);
|
||||
} else {
|
||||
sendError(sender, "Item not found in blacklist: " + value);
|
||||
}
|
||||
break;
|
||||
case "mod":
|
||||
if (AuctionBlacklist.removeMod(value)) {
|
||||
sendResult(sender, "Removed mod from blacklist: " + value);
|
||||
} else {
|
||||
sendError(sender, "Mod not found in blacklist: " + value);
|
||||
}
|
||||
break;
|
||||
case "nbt":
|
||||
if (AuctionBlacklist.removeNBTTag(value)) {
|
||||
sendResult(sender, "Removed NBT tag from blacklist: " + value);
|
||||
} else {
|
||||
sendError(sender, "NBT tag not found in blacklist: " + value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sendError(sender, "Unknown type: " + type + ". Use: item, mod, or nbt");
|
||||
}
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "List blacklisted items, mods, or NBT tags",
|
||||
usage = "[item|mod|nbt]"
|
||||
)
|
||||
public void list(ICommandSender sender, String[] args) throws CommandException {
|
||||
String filter = args.length > 0 ? args[0].toLowerCase() : "all";
|
||||
|
||||
if (filter.equals("all") || filter.equals("item")) {
|
||||
List<String> items = AuctionBlacklist.getBlacklistedItems();
|
||||
sendMessage(sender, "\u00A76=== Blacklisted Items (" + items.size() + ") ===");
|
||||
if (items.isEmpty()) {
|
||||
sendMessage(sender, "\u00A77 (none)");
|
||||
} else {
|
||||
for (String item : items) {
|
||||
sendMessage(sender, "\u00A7e " + item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (filter.equals("all") || filter.equals("mod")) {
|
||||
List<String> mods = AuctionBlacklist.getBlacklistedMods();
|
||||
sendMessage(sender, "\u00A76=== Blacklisted Mods (" + mods.size() + ") ===");
|
||||
if (mods.isEmpty()) {
|
||||
sendMessage(sender, "\u00A77 (none)");
|
||||
} else {
|
||||
for (String mod : mods) {
|
||||
sendMessage(sender, "\u00A7e " + mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (filter.equals("all") || filter.equals("nbt")) {
|
||||
List<String> tags = AuctionBlacklist.getBlacklistedNBTTags();
|
||||
sendMessage(sender, "\u00A76=== Blacklisted NBT Tags (" + tags.size() + ") ===");
|
||||
if (tags.isEmpty()) {
|
||||
sendMessage(sender, "\u00A77 (none)");
|
||||
} else {
|
||||
for (String tag : tags) {
|
||||
sendMessage(sender, "\u00A7e " + tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendMessage(sender, "\u00A77Note: Soulbound and Profile-Slotbound items are always blocked.");
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Reload blacklist from config"
|
||||
)
|
||||
public void reload(ICommandSender sender, String[] args) throws CommandException {
|
||||
AuctionBlacklist.reload();
|
||||
sendResult(sender, "Blacklist reloaded from config");
|
||||
}
|
||||
|
||||
@SubCommand(
|
||||
desc = "Check if held item is blacklisted",
|
||||
permission = 0
|
||||
)
|
||||
public void check(ICommandSender sender, String[] args) throws CommandException {
|
||||
if (!(sender instanceof EntityPlayer)) {
|
||||
sendError(sender, "This command can only be used by players");
|
||||
return;
|
||||
}
|
||||
|
||||
EntityPlayer player = (EntityPlayer) sender;
|
||||
ItemStack heldItem = player.getHeldItem();
|
||||
|
||||
if (heldItem == null) {
|
||||
sendError(sender, "You are not holding an item");
|
||||
return;
|
||||
}
|
||||
|
||||
String registryName = AuctionBlacklist.getRegistryName(heldItem);
|
||||
sendMessage(sender, "\u00A76=== Blacklist Check ===");
|
||||
sendMessage(sender, "\u00A77Item: \u00A7e" + heldItem.getDisplayName());
|
||||
sendMessage(sender, "\u00A77Registry: \u00A7e" + (registryName != null ? registryName : "unknown"));
|
||||
|
||||
boolean isBlacklisted = AuctionBlacklist.isBlacklisted(heldItem);
|
||||
boolean canBypass = AuctionBlacklist.canBypass(player);
|
||||
|
||||
if (isBlacklisted) {
|
||||
sendMessage(sender, "\u00A7cStatus: BLACKLISTED");
|
||||
if (canBypass) {
|
||||
sendMessage(sender, "\u00A7aYou have bypass permission");
|
||||
}
|
||||
} else {
|
||||
sendMessage(sender, "\u00A7aStatus: ALLOWED");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List addTabCompletionOptions(ICommandSender sender, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getListOfStringsMatchingLastWord(args, getAllSubCommandNames());
|
||||
}
|
||||
if (args.length == 2) {
|
||||
String subCmd = args[0].toLowerCase();
|
||||
if (subCmd.equals("add") || subCmd.equals("remove") || subCmd.equals("list")) {
|
||||
return getListOfStringsMatchingLastWord(args, new String[]{"item", "mod", "nbt"});
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ public class ConfigMarket {
|
||||
|
||||
public final static String CURRENCY = "Market.Currency";
|
||||
public final static String AUCTION = "Market.Auction";
|
||||
public final static String AUCTION_BLACKLIST = "Market.Auction.Blacklist";
|
||||
public final static String AUCTION_LOGGING = "Market.Auction.Logging";
|
||||
|
||||
// Max trades grid = 9x5 = 45 slots
|
||||
@@ -41,6 +42,14 @@ public class ConfigMarket {
|
||||
public static double MinBidIncrementPercent = 0.05;
|
||||
public static double CancellationPenaltyPercent = 0.10;
|
||||
|
||||
// =========================================
|
||||
// Auction Blacklist Settings
|
||||
// =========================================
|
||||
public static boolean BlacklistEnabled = true;
|
||||
public static String[] BlacklistedItems = new String[]{};
|
||||
public static String[] BlacklistedMods = new String[]{};
|
||||
public static String[] BlacklistedNBTTags = new String[]{};
|
||||
|
||||
// =========================================
|
||||
// Auction Logging Settings
|
||||
// =========================================
|
||||
@@ -113,6 +122,45 @@ public class ConfigMarket {
|
||||
CancellationPenaltyPercent = config.get(AUCTION, "Cancellation Penalty Percent", 0.10,
|
||||
"Percentage of current bid taken as penalty when seller cancels an auction with bids (0.10 = 10%)").getDouble(0.10);
|
||||
|
||||
// =========================================
|
||||
// Auction Blacklist Settings
|
||||
// =========================================
|
||||
config.setCategoryComment(AUCTION_BLACKLIST,
|
||||
"Item Blacklist settings for the Auction House.\n" +
|
||||
"Prevents specific items, mods, or items with certain NBT tags from being listed.\n\n" +
|
||||
"ITEM FORMAT: Use 'modid:itemname' format (e.g., 'minecraft:bedrock', 'customnpcs:npcWand')\n" +
|
||||
"WILDCARDS: Use * for wildcards (e.g., 'customnpcs:npc*' blocks all items starting with 'npc')\n" +
|
||||
"MOD FORMAT: Use just the mod ID (e.g., 'projecte' blocks all items from that mod)\n" +
|
||||
"NBT FORMAT: Use the NBT tag key name (e.g., 'AdminOnly' blocks items with that tag)");
|
||||
|
||||
BlacklistEnabled = config.get(AUCTION_BLACKLIST, "Enable Blacklist", true,
|
||||
"Enable item blacklist checking when creating listings").getBoolean(true);
|
||||
|
||||
BlacklistedItems = config.get(AUCTION_BLACKLIST, "Blacklisted Items", new String[]{
|
||||
"minecraft:bedrock",
|
||||
"minecraft:command_block",
|
||||
"customnpcs:npcWand",
|
||||
"customnpcs:npcMobCloner",
|
||||
"customnpcs:npcScripter",
|
||||
"customnpcs:npcMovingPath",
|
||||
"customnpcs:npcMounter",
|
||||
"customnpcs:npcTeleporter",
|
||||
"customnpcs:npcTool",
|
||||
"customnpcs:npcSoulstoneFilled"
|
||||
},
|
||||
"Items that cannot be listed on the Auction House.\n" +
|
||||
"Format: modid:itemname (supports * wildcards)\n" +
|
||||
"Example: 'minecraft:diamond_sword' or 'customnpcs:npc*'").getStringList();
|
||||
|
||||
BlacklistedMods = config.get(AUCTION_BLACKLIST, "Blacklisted Mods", new String[]{},
|
||||
"All items from these mods are blocked from the Auction House.\n" +
|
||||
"Format: modid (e.g., 'projecte', 'thaumcraft')").getStringList();
|
||||
|
||||
BlacklistedNBTTags = config.get(AUCTION_BLACKLIST, "Blacklisted NBT Tags", new String[]{},
|
||||
"Items containing any of these NBT tag keys are blocked.\n" +
|
||||
"Checks the root level of the item's NBT compound.\n" +
|
||||
"Example: 'AdminOnly', 'CreativeMode'").getStringList();
|
||||
|
||||
// =========================================
|
||||
// Auction Logging Settings
|
||||
// =========================================
|
||||
@@ -163,6 +211,13 @@ public class ConfigMarket {
|
||||
"Cancellation Penalty Percent"
|
||||
)));
|
||||
|
||||
config.setCategoryPropertyOrder(AUCTION_BLACKLIST, new ArrayList<>(Arrays.asList(
|
||||
"Enable Blacklist",
|
||||
"Blacklisted Items",
|
||||
"Blacklisted Mods",
|
||||
"Blacklisted NBT Tags"
|
||||
)));
|
||||
|
||||
config.setCategoryPropertyOrder(AUCTION_LOGGING, new ArrayList<>(Arrays.asList(
|
||||
"Enable Auction Logging",
|
||||
"Log Created",
|
||||
|
||||
@@ -21,6 +21,7 @@ import noppes.npcs.constants.EnumAuctionSort;
|
||||
import noppes.npcs.constants.EnumAuctionStatus;
|
||||
import noppes.npcs.constants.EnumClaimType;
|
||||
import noppes.npcs.constants.EnumNotificationType;
|
||||
import noppes.npcs.controllers.data.AuctionBlacklist;
|
||||
import noppes.npcs.controllers.data.AuctionClaim;
|
||||
import noppes.npcs.controllers.data.AuctionFilter;
|
||||
import noppes.npcs.controllers.data.AuctionListing;
|
||||
@@ -86,6 +87,7 @@ public class AuctionController implements IAuctionHandler {
|
||||
|
||||
public AuctionController() {
|
||||
Instance = this;
|
||||
AuctionBlacklist.reload();
|
||||
load();
|
||||
}
|
||||
|
||||
@@ -241,6 +243,11 @@ public class AuctionController implements IAuctionHandler {
|
||||
return "Auction is disabled.";
|
||||
}
|
||||
|
||||
// Check blacklist (with bypass for admins)
|
||||
if (AuctionBlacklist.isBlacklistedForPlayer(item, player)) {
|
||||
return "This item cannot be listed on the Auction House.";
|
||||
}
|
||||
|
||||
// Validate minimum price
|
||||
if (startingPrice < ConfigMarket.MinimumListingPrice) {
|
||||
return "Starting price must be at least " + ConfigMarket.MinimumListingPrice + " " + ConfigMarket.CurrencyName + ".";
|
||||
@@ -1414,4 +1421,18 @@ public class AuctionController implements IAuctionHandler {
|
||||
AuctionListing listing = listings.get(listingId);
|
||||
return listing != null && listing.isSeller(playerUUID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the item blacklist from config.
|
||||
*/
|
||||
public void reloadBlacklist() {
|
||||
AuctionBlacklist.reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an item is blacklisted.
|
||||
*/
|
||||
public boolean isItemBlacklisted(ItemStack item) {
|
||||
return AuctionBlacklist.isBlacklisted(item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package noppes.npcs.controllers.data;
|
||||
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
import kamkeel.npcs.util.AttributeItemUtil;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import noppes.npcs.CustomNpcsPermissions;
|
||||
import noppes.npcs.config.ConfigMarket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AuctionBlacklist {
|
||||
private static Set<String> blacklistedItems = new HashSet<>();
|
||||
private static Set<Pattern> wildcardPatterns = new HashSet<>();
|
||||
private static Set<String> blacklistedMods = new HashSet<>();
|
||||
private static Set<String> blacklistedNBTTags = new HashSet<>();
|
||||
|
||||
// Built-in bound item requirement keys (always blocked)
|
||||
private static final String SOULBIND_KEY = "cnpc_soulbind";
|
||||
private static final String PROFILE_SLOT_KEY = "cnpc_profile_slot";
|
||||
|
||||
// Bypass permission
|
||||
private static final String BYPASS_PERMISSION = "customnpcs.auction.blacklist.bypass";
|
||||
|
||||
public static void reload() {
|
||||
blacklistedItems.clear();
|
||||
wildcardPatterns.clear();
|
||||
blacklistedMods.clear();
|
||||
blacklistedNBTTags.clear();
|
||||
|
||||
// Load blacklisted items
|
||||
for (String item : ConfigMarket.BlacklistedItems) {
|
||||
if (item == null || item.isEmpty()) continue;
|
||||
item = item.toLowerCase().trim();
|
||||
|
||||
if (item.contains("*")) {
|
||||
String regex = "^" + item.replace(".", "\\.").replace("*", ".*") + "$";
|
||||
wildcardPatterns.add(Pattern.compile(regex));
|
||||
} else {
|
||||
blacklistedItems.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
// Load blacklisted mods
|
||||
for (String mod : ConfigMarket.BlacklistedMods) {
|
||||
if (mod == null || mod.isEmpty()) continue;
|
||||
blacklistedMods.add(mod.toLowerCase().trim());
|
||||
}
|
||||
|
||||
// Load blacklisted NBT tags
|
||||
for (String tag : ConfigMarket.BlacklistedNBTTags) {
|
||||
if (tag == null || tag.isEmpty()) continue;
|
||||
blacklistedNBTTags.add(tag.trim());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if player can bypass the blacklist (OP or has permission)
|
||||
*/
|
||||
public static boolean canBypass(EntityPlayer player) {
|
||||
if (player == null) return false;
|
||||
|
||||
// Check OP status
|
||||
if (player.canCommandSenderUseCommand(2, BYPASS_PERMISSION)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check custom permission
|
||||
return CustomNpcsPermissions.hasCustomPermission(player, BYPASS_PERMISSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if item is blacklisted (without bypass check)
|
||||
*/
|
||||
public static boolean isBlacklisted(ItemStack item) {
|
||||
if (!ConfigMarket.BlacklistEnabled) return false;
|
||||
if (item == null || item.getItem() == null) return true;
|
||||
|
||||
// Check bound items (always blocked, even if blacklist is "disabled")
|
||||
if (hasBoundRequirement(item)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get registry name
|
||||
GameRegistry.UniqueIdentifier uid = GameRegistry.findUniqueIdentifierFor(item.getItem());
|
||||
if (uid == null) return true;
|
||||
|
||||
String registryName = (uid.modId + ":" + uid.name).toLowerCase();
|
||||
String modId = uid.modId.toLowerCase();
|
||||
|
||||
// Check exact item match
|
||||
if (blacklistedItems.contains(registryName)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check wildcard patterns
|
||||
for (Pattern pattern : wildcardPatterns) {
|
||||
if (pattern.matcher(registryName).matches()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check mod blacklist
|
||||
if (blacklistedMods.contains(modId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check NBT tags
|
||||
if (item.hasTagCompound() && !blacklistedNBTTags.isEmpty()) {
|
||||
NBTTagCompound tag = item.getTagCompound();
|
||||
for (String nbtKey : blacklistedNBTTags) {
|
||||
if (tag.hasKey(nbtKey)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if item is blacklisted for a specific player (with bypass check)
|
||||
*/
|
||||
public static boolean isBlacklistedForPlayer(ItemStack item, EntityPlayer player) {
|
||||
if (canBypass(player)) return false;
|
||||
return isBlacklisted(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the registry name of an item
|
||||
*/
|
||||
public static String getRegistryName(ItemStack item) {
|
||||
if (item == null || item.getItem() == null) return null;
|
||||
GameRegistry.UniqueIdentifier uid = GameRegistry.findUniqueIdentifierFor(item.getItem());
|
||||
if (uid == null) return null;
|
||||
return uid.modId + ":" + uid.name;
|
||||
}
|
||||
|
||||
// =========================================
|
||||
// Bound Item Checking (RPGCore/Requirements)
|
||||
// =========================================
|
||||
|
||||
/**
|
||||
* Check if item has soulbind or profile slot requirement.
|
||||
* Requirements are stored under: item.stackTagCompound/RPGCore/Requirements
|
||||
*/
|
||||
private static boolean hasBoundRequirement(ItemStack item) {
|
||||
if (item == null || !item.hasTagCompound()) return false;
|
||||
|
||||
NBTTagCompound root = item.getTagCompound();
|
||||
if (!root.hasKey(AttributeItemUtil.TAG_RPGCORE)) return false;
|
||||
|
||||
NBTTagCompound rpgCore = root.getCompoundTag(AttributeItemUtil.TAG_RPGCORE);
|
||||
if (!rpgCore.hasKey(AttributeItemUtil.TAG_REQUIREMENTS)) return false;
|
||||
|
||||
NBTTagCompound requirements = rpgCore.getCompoundTag(AttributeItemUtil.TAG_REQUIREMENTS);
|
||||
return requirements.hasKey(SOULBIND_KEY) || requirements.hasKey(PROFILE_SLOT_KEY);
|
||||
}
|
||||
|
||||
// =========================================
|
||||
// Runtime Blacklist Management
|
||||
// =========================================
|
||||
|
||||
public static boolean addItem(String registryName) {
|
||||
if (registryName == null || registryName.isEmpty()) return false;
|
||||
registryName = registryName.toLowerCase().trim();
|
||||
|
||||
if (registryName.contains("*")) {
|
||||
String regex = "^" + registryName.replace(".", "\\.").replace("*", ".*") + "$";
|
||||
wildcardPatterns.add(Pattern.compile(regex));
|
||||
} else {
|
||||
blacklistedItems.add(registryName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean removeItem(String registryName) {
|
||||
if (registryName == null || registryName.isEmpty()) return false;
|
||||
registryName = registryName.toLowerCase().trim();
|
||||
|
||||
if (registryName.contains("*")) {
|
||||
String regex = "^" + registryName.replace(".", "\\.").replace("*", ".*") + "$";
|
||||
return wildcardPatterns.removeIf(p -> p.pattern().equals(regex));
|
||||
} else {
|
||||
return blacklistedItems.remove(registryName);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean addMod(String modId) {
|
||||
if (modId == null || modId.isEmpty()) return false;
|
||||
return blacklistedMods.add(modId.toLowerCase().trim());
|
||||
}
|
||||
|
||||
public static boolean removeMod(String modId) {
|
||||
if (modId == null || modId.isEmpty()) return false;
|
||||
return blacklistedMods.remove(modId.toLowerCase().trim());
|
||||
}
|
||||
|
||||
public static boolean addNBTTag(String tag) {
|
||||
if (tag == null || tag.isEmpty()) return false;
|
||||
return blacklistedNBTTags.add(tag.trim());
|
||||
}
|
||||
|
||||
public static boolean removeNBTTag(String tag) {
|
||||
if (tag == null || tag.isEmpty()) return false;
|
||||
return blacklistedNBTTags.remove(tag.trim());
|
||||
}
|
||||
|
||||
// =========================================
|
||||
// Getters for listing
|
||||
// =========================================
|
||||
|
||||
public static List<String> getBlacklistedItems() {
|
||||
List<String> result = new ArrayList<>(blacklistedItems);
|
||||
for (Pattern p : wildcardPatterns) {
|
||||
// Convert regex back to wildcard format
|
||||
String pattern = p.pattern();
|
||||
pattern = pattern.substring(1, pattern.length() - 1); // Remove ^ and $
|
||||
pattern = pattern.replace("\\.", ".").replace(".*", "*");
|
||||
result.add(pattern);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<String> getBlacklistedMods() {
|
||||
return new ArrayList<>(blacklistedMods);
|
||||
}
|
||||
|
||||
public static List<String> getBlacklistedNBTTags() {
|
||||
return new ArrayList<>(blacklistedNBTTags);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user