Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d85028e81 | ||
|
|
f40afbd4a4 | ||
|
|
5ae4b03d30 | ||
|
|
543912b8a1 | ||
|
|
b1ca462de9 | ||
|
|
1a47411f3b | ||
|
|
7e193edd13 | ||
|
|
c214807fdd | ||
|
|
c3e63a7475 | ||
|
|
bac11ea028 | ||
|
|
c37165e2c5 | ||
|
|
ddc4f21868 | ||
|
|
7070e2cf38 | ||
|
|
0560fdfd5d | ||
|
|
5726b86bd5 | ||
|
|
aca097a8b1 | ||
|
|
193c614cc6 | ||
|
|
7dd394e5be | ||
|
|
5525065d62 | ||
|
|
86b595a196 | ||
|
|
8030220ffb | ||
|
|
2a7645effc | ||
|
|
ff7e8156ff | ||
|
|
37e88c913c | ||
|
|
babfe91ef1 | ||
|
|
2d10ab8eb6 | ||
|
|
efa90b8101 | ||
|
|
eb41781b3c | ||
|
|
7cfda08d39 | ||
|
|
a84b72071a | ||
|
|
7cb97e7c1d |
No files matched your search
@@ -5,10 +5,13 @@ PlayerBounties-OG is a hard fork of [PlayerBountiesPlus](https://github.com/Tech
|
||||
|
||||
## Features
|
||||
- Clan-aware bounty system that prevents teammates from claiming each other's bounties.
|
||||
- Integrates with [DiamondBank-OG](https://github.com/true-og/DiamondBank-OG) and supports [SimpleClans](https://github.com/true-og/SimpleClans) for team detection.
|
||||
- Inventory GUI for viewing bounties.
|
||||
- Customizable odds for receiving player head from bounty victim.
|
||||
- Localized messages in multiple languages.
|
||||
- Uses [LuckPerms](https://github.com/true-og/LuckPerms) for player name formatting.
|
||||
- Integrates [CoreProtect-OG](https://github.com/true-og/CoreProtect-OG) for player head rollback injection.
|
||||
- Integrates [DiamondBank-OG](https://github.com/true-og/DiamondBank-OG) for currency.
|
||||
- Integrates [LuckPerms](https://github.com/true-og/LuckPerms) for player name and rank formatting.
|
||||
- Integrates [SimpleClans](https://github.com/true-og/SimpleClans) for team detection.
|
||||
|
||||
## Commands
|
||||
- `/bounty set <player> <amount>` – set a bounty on a player
|
||||
|
||||
@@ -66,6 +66,7 @@ repositories {
|
||||
maven { url = uri("https://repo.glaremasters.me/repository/towny/") }
|
||||
maven { url = uri("https://repo.extendedclip.com/releases/") }
|
||||
maven { url = uri("https://repo.tcoded.com/public/") }
|
||||
maven { url = uri("https://maven.playpro.com") }
|
||||
}
|
||||
|
||||
/* ---------------------- Java project deps ---------------------------- */
|
||||
@@ -73,6 +74,7 @@ dependencies {
|
||||
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") // Declare Purpur API version to be packaged.
|
||||
compileOnly("net.sacredlabyrinth.phaed.simpleclans:SimpleClans:2.15.2")
|
||||
compileOnly("net.luckperms:api:5.5") // Import LuckPerms API.
|
||||
compileOnly("net.coreprotect:coreprotect:23.1")
|
||||
compileOnlyApi(project(":libs:Utilities-OG")) // Import TrueOG Network Utilities-OG Java API (from source).
|
||||
compileOnlyApi(project(":libs:GxUI-OG")) // Import TrueOG Network GxUI-OG Java API (from source).
|
||||
compileOnlyApi(project(":libs:DiamondBank-OG")) {
|
||||
|
||||
+1
-1
Submodule libs/GxUI-OG updated: ebd8df041e...cbcf14f0ab.
@@ -16,9 +16,12 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.tcoded.playerbountiesplus.command.BountyCommand;
|
||||
import com.tcoded.playerbountiesplus.command.PlayerBountiesPlusAdminCmd;
|
||||
import com.tcoded.playerbountiesplus.hook.currency.DiamondBankOGHook;
|
||||
import com.tcoded.playerbountiesplus.hook.logging.CoreProtectHook;
|
||||
import com.tcoded.playerbountiesplus.hook.currency.EconomyHook;
|
||||
import com.tcoded.playerbountiesplus.hook.team.TeamHook;
|
||||
import com.tcoded.playerbountiesplus.listener.BountyHeadListener;
|
||||
import com.tcoded.playerbountiesplus.listener.DeathListener;
|
||||
import com.tcoded.playerbountiesplus.listener.GuiProtectionListener;
|
||||
import com.tcoded.playerbountiesplus.manager.BountyDataManager;
|
||||
import com.tcoded.playerbountiesplus.util.LangUtil;
|
||||
|
||||
@@ -59,6 +62,9 @@ public final class PlayerBountiesOG extends JavaPlugin {
|
||||
// LuckPerms API hook.
|
||||
private LuckPerms luckPerms;
|
||||
|
||||
// CoreProtect API hook.
|
||||
private CoreProtectHook coreProtectHook;
|
||||
|
||||
public PlayerBountiesOG() {
|
||||
|
||||
instance = this;
|
||||
@@ -86,6 +92,14 @@ public final class PlayerBountiesOG extends JavaPlugin {
|
||||
|
||||
}
|
||||
|
||||
this.coreProtectHook = new CoreProtectHook(this);
|
||||
if (!this.coreProtectHook.isEnabled()) {
|
||||
|
||||
getLogger().warning(
|
||||
"CoreProtect API v11+ not found - custom bounty head metadata may not rollback correctly.");
|
||||
|
||||
}
|
||||
|
||||
// Initialize the DiamondBank-OG API.
|
||||
final RegisteredServiceProvider<DiamondBankAPIJava> provider = getServer().getServicesManager()
|
||||
.getRegistration(DiamondBankAPIJava.class);
|
||||
@@ -143,6 +157,9 @@ public final class PlayerBountiesOG extends JavaPlugin {
|
||||
// Listeners.
|
||||
this.getServer().getPluginManager().registerEvents(new DeathListener(this, this.diamondBankAPI, this.luckPerms),
|
||||
this);
|
||||
this.getServer().getPluginManager().registerEvents(
|
||||
new BountyHeadListener(this, this.diamondBankAPI, this.luckPerms, this.coreProtectHook), this);
|
||||
this.getServer().getPluginManager().registerEvents(new GuiProtectionListener(this), this);
|
||||
|
||||
final List<Plugin> plugins = ImmutableList.copyOf(this.getServer().getPluginManager().getPlugins());
|
||||
findPluginWithQuery(plugins, "team");
|
||||
@@ -201,6 +218,18 @@ public final class PlayerBountiesOG extends JavaPlugin {
|
||||
|
||||
}
|
||||
|
||||
public LuckPerms getLuckPerms() {
|
||||
|
||||
return this.luckPerms;
|
||||
|
||||
}
|
||||
|
||||
public CoreProtectHook getCoreProtectHook() {
|
||||
|
||||
return this.coreProtectHook;
|
||||
|
||||
}
|
||||
|
||||
// Utilities.
|
||||
private static void findPluginWithQuery(List<Plugin> plugins, String pluginNameQuery, String... excludeStrings) {
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -36,27 +37,30 @@ public class BountyCommand implements CommandExecutor, TabCompleter {
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String cmdName, String[] args) {
|
||||
|
||||
final Player player;
|
||||
if (!(sender instanceof Player)) {
|
||||
|
||||
UtilitiesOG.logToConsole(PlayerBountiesOG.getPrefix(), "&cERROR: Only players can use this command.");
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
player = (Player) sender;
|
||||
|
||||
}
|
||||
|
||||
if (args.length < 1) {
|
||||
|
||||
UtilitiesOG.trueogMessage(player, plugin.getLang().getColored("command.bounty.no-action"));
|
||||
if (StringUtils.equalsIgnoreCase(cmdName, "bounties")) {
|
||||
|
||||
return BountyTopCmd.handleCmd(plugin, diamondBankAPI, sender, cmd, cmdName, args);
|
||||
|
||||
}
|
||||
|
||||
final String noAction = plugin.getLang().getColored("command.bounty.no-action");
|
||||
UtilitiesOG.trueogMessage((Player) sender, noAction);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
final String action = args[0].toLowerCase();
|
||||
final String action = StringUtils.lowerCase(args[0]);
|
||||
switch (action) {
|
||||
|
||||
case "set" -> {
|
||||
@@ -76,7 +80,6 @@ public class BountyCommand implements CommandExecutor, TabCompleter {
|
||||
return BountyCheckCmd.handleCmd(plugin, sender, cmd, cmdName, args);
|
||||
|
||||
}
|
||||
|
||||
default -> {
|
||||
|
||||
// If "/bounty" is run without a valid subcommand, treat it as "/bounty top".
|
||||
@@ -97,18 +100,21 @@ public class BountyCommand implements CommandExecutor, TabCompleter {
|
||||
if (args.length == 1) {
|
||||
|
||||
return Lists.newArrayList("set", "top", "check").stream()
|
||||
.filter(action -> action.startsWith(args[0].toLowerCase())).collect(Collectors.toList());
|
||||
.filter(action -> StringUtils.startsWith(action, StringUtils.lowerCase(args[0])))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
} else if (args.length > 1) {
|
||||
|
||||
final String subCommand = args[0].toLowerCase();
|
||||
final String subCommand = StringUtils.lowerCase(args[0]);
|
||||
return switch (subCommand) {
|
||||
|
||||
case "set" -> BountySetCmd.onTabComplete(sender, args).stream()
|
||||
.filter(suggestion -> suggestion.toLowerCase().startsWith(args[1].toLowerCase()))
|
||||
case "set" -> BountySetCmd
|
||||
.onTabComplete(sender, args).stream().filter(suggestion -> StringUtils
|
||||
.startsWith(StringUtils.lowerCase(suggestion), StringUtils.lowerCase(args[1])))
|
||||
.collect(Collectors.toList());
|
||||
case "check" -> BountyCheckCmd.onTabComplete(sender, args).stream()
|
||||
.filter(suggestion -> suggestion.toLowerCase().startsWith(args[1].toLowerCase()))
|
||||
case "check" -> BountyCheckCmd
|
||||
.onTabComplete(sender, args).stream().filter(suggestion -> StringUtils
|
||||
.startsWith(StringUtils.lowerCase(suggestion), StringUtils.lowerCase(args[1])))
|
||||
.collect(Collectors.toList());
|
||||
case "top" -> Collections.emptyList();
|
||||
default -> Collections.emptyList();
|
||||
@@ -121,4 +127,4 @@ public class BountyCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -45,7 +46,7 @@ public class PlayerBountiesPlusAdminCmd implements CommandExecutor, TabCompleter
|
||||
|
||||
}
|
||||
|
||||
final String arg0Lower = args[0].toLowerCase();
|
||||
final String arg0Lower = StringUtils.lowerCase(args[0]);
|
||||
return switch (arg0Lower) {
|
||||
|
||||
case "reload" -> PlayerBountiesPlusReloadCmd.handleCmd(plugin, sender, command, label, args);
|
||||
@@ -96,12 +97,13 @@ public class PlayerBountiesPlusAdminCmd implements CommandExecutor, TabCompleter
|
||||
|
||||
if (args.length == 1) {
|
||||
|
||||
return completions.stream().filter(s -> s.toLowerCase().startsWith(args[0].toLowerCase()))
|
||||
return completions.stream()
|
||||
.filter(s -> StringUtils.startsWith(StringUtils.lowerCase(s), StringUtils.lowerCase(args[0])))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
} else if (args.length > 1) {
|
||||
|
||||
final String subCommand = args[0].toLowerCase();
|
||||
final String subCommand = StringUtils.lowerCase(args[0]);
|
||||
return switch (subCommand) {
|
||||
|
||||
case "bounty" -> AdminBountyCmd.onTabComplete(sender, args);
|
||||
|
||||
+14
-2
@@ -64,10 +64,10 @@ public class AdminBountyAddCmd {
|
||||
}
|
||||
|
||||
final String playerName = args[2];
|
||||
final int amount;
|
||||
final double amount;
|
||||
try {
|
||||
|
||||
amount = Integer.parseInt(args[3]);
|
||||
amount = parseAmount(args[3]);
|
||||
|
||||
} catch (NumberFormatException numberFormatException) {
|
||||
|
||||
@@ -131,6 +131,18 @@ public class AdminBountyAddCmd {
|
||||
|
||||
}
|
||||
|
||||
private static double parseAmount(String amountInput) {
|
||||
|
||||
if (!amountInput.matches("^\\d+(?:\\.\\d)?$")) {
|
||||
|
||||
throw new NumberFormatException("Invalid amount format");
|
||||
|
||||
}
|
||||
|
||||
return Double.parseDouble(amountInput);
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
|
||||
@NotNull String label, @NotNull String[] args)
|
||||
|
||||
+6
-4
@@ -5,6 +5,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -36,7 +37,7 @@ public class AdminBountyCmd {
|
||||
|
||||
}
|
||||
|
||||
final String action = args[1].toLowerCase();
|
||||
final String action = StringUtils.lowerCase(args[1]);
|
||||
return switch (action) {
|
||||
|
||||
case "set" -> AdminBountySetCmd.handleCmd(plugin, sender, cmd, label, args);
|
||||
@@ -75,7 +76,7 @@ public class AdminBountyCmd {
|
||||
|
||||
} else if (args.length > 2) {
|
||||
|
||||
final String sub = args[1].toLowerCase();
|
||||
final String sub = StringUtils.lowerCase(args[1]);
|
||||
switch (sub) {
|
||||
|
||||
case "add" -> suggestions = AdminBountyAddCmd.onTabComplete(sender, null, null, args);
|
||||
@@ -88,8 +89,9 @@ public class AdminBountyCmd {
|
||||
|
||||
}
|
||||
|
||||
final String input = args[args.length - 1].toLowerCase();
|
||||
return suggestions.stream().filter(opt -> opt.toLowerCase().startsWith(input)).collect(Collectors.toList());
|
||||
final String input = StringUtils.lowerCase(args[args.length - 1]);
|
||||
return suggestions.stream().filter(opt -> StringUtils.startsWith(StringUtils.lowerCase(opt), input))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
}
|
||||
|
||||
|
||||
+14
-2
@@ -63,10 +63,10 @@ public class AdminBountyRemoveCmd {
|
||||
}
|
||||
|
||||
final String playerName = args[2];
|
||||
final int amount;
|
||||
final double amount;
|
||||
try {
|
||||
|
||||
amount = Integer.parseInt(args[3]);
|
||||
amount = parseAmount(args[3]);
|
||||
|
||||
} catch (NumberFormatException numberFormatException) {
|
||||
|
||||
@@ -139,6 +139,18 @@ public class AdminBountyRemoveCmd {
|
||||
|
||||
}
|
||||
|
||||
private static double parseAmount(String amountInput) {
|
||||
|
||||
if (!amountInput.matches("^\\d+(?:\\.\\d)?$")) {
|
||||
|
||||
throw new NumberFormatException("Invalid amount format");
|
||||
|
||||
}
|
||||
|
||||
return Double.parseDouble(amountInput);
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
|
||||
@NotNull String label, @NotNull String[] args)
|
||||
|
||||
+14
-2
@@ -62,10 +62,10 @@ public class AdminBountySetCmd {
|
||||
}
|
||||
|
||||
final String playerName = args[2];
|
||||
final int amount;
|
||||
final double amount;
|
||||
try {
|
||||
|
||||
amount = Integer.parseInt(args[3]);
|
||||
amount = parseAmount(args[3]);
|
||||
|
||||
} catch (NumberFormatException numberFormatException) {
|
||||
|
||||
@@ -125,6 +125,18 @@ public class AdminBountySetCmd {
|
||||
|
||||
}
|
||||
|
||||
private static double parseAmount(String amountInput) {
|
||||
|
||||
if (!amountInput.matches("^\\d+(?:\\.\\d)?$")) {
|
||||
|
||||
throw new NumberFormatException("Invalid amount format");
|
||||
|
||||
}
|
||||
|
||||
return Double.parseDouble(amountInput);
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
|
||||
@NotNull String label, @NotNull String[] args)
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -109,7 +110,8 @@ public class BountyCheckCmd {
|
||||
|
||||
// Suggest online player names for the username.
|
||||
return sender.getServer().getOnlinePlayers().stream().map(Player::getName)
|
||||
.filter(name -> name.toLowerCase().startsWith(args[1].toLowerCase())).collect(Collectors.toList());
|
||||
.filter(name -> StringUtils.startsWith(StringUtils.lowerCase(name), StringUtils.lowerCase(args[1])))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,12 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -16,6 +18,10 @@ import com.tcoded.playerbountiesplus.PlayerBountiesOG;
|
||||
import com.tcoded.playerbountiesplus.event.BountySetEvent;
|
||||
import com.tcoded.playerbountiesplus.manager.BountyDataManager;
|
||||
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.cacheddata.CachedMetaData;
|
||||
import net.luckperms.api.model.user.User;
|
||||
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class BountySetCmd {
|
||||
@@ -65,7 +71,7 @@ public class BountySetCmd {
|
||||
final double parsedAmount;
|
||||
try {
|
||||
|
||||
parsedAmount = Integer.parseInt(args[2]);
|
||||
parsedAmount = parseAmount(args[2]);
|
||||
|
||||
} catch (NumberFormatException numberFormatException) {
|
||||
|
||||
@@ -215,47 +221,41 @@ public class BountySetCmd {
|
||||
|
||||
// Calculate total bounty including previous bounties.
|
||||
final BountyDataManager bountyDataManager = plugin.getBountyDataManager();
|
||||
final double bountyAlreadyPresent = bountyDataManager.getBounty(playerUUID);
|
||||
final double chargeAndBountyAmount = (int) amount;
|
||||
final double totalBounty = chargeAndBountyAmount + bountyAlreadyPresent;
|
||||
final DiamondBankAPIJava diamondBankAPI = resolveDiamondBankApi(plugin);
|
||||
final long newBountyShards = diamondBankAPI.diamondsToShards(amount);
|
||||
final long existingBountyShards = diamondBankAPI
|
||||
.diamondsToShards((float) bountyDataManager.getBounty(playerUUID));
|
||||
final long totalBountyShards = newBountyShards + existingBountyShards;
|
||||
final double totalBounty = Double.parseDouble(diamondBankAPI.shardsToDiamonds(totalBountyShards));
|
||||
bountyDataManager.setBounty(playerUUID, totalBounty);
|
||||
|
||||
// Confirmation.
|
||||
final String bountySetSuccessMessage = plugin.getLang().getColored("command.bounty.set.success")
|
||||
.replace("{bounty}", String.valueOf(chargeAndBountyAmount))
|
||||
.replace("{total}", String.valueOf(totalBounty)).replace("{target}", target.getName())
|
||||
.replace("{player}", sender.getName());
|
||||
if (!(sender instanceof Player)) {
|
||||
|
||||
UtilitiesOG.logToConsole(PlayerBountiesOG.getPrefix(), bountySetSuccessMessage);
|
||||
|
||||
} else {
|
||||
|
||||
UtilitiesOG.trueogMessage((Player) sender, bountySetSuccessMessage);
|
||||
|
||||
}
|
||||
|
||||
// Announcement.
|
||||
final String extra;
|
||||
if (bountyAlreadyPresent == 0) {
|
||||
if (existingBountyShards == 0L) {
|
||||
|
||||
extra = "";
|
||||
|
||||
} else {
|
||||
|
||||
extra = plugin.getLang().getColored("command.bounty.set.announce-extra").replace("{total}",
|
||||
String.valueOf(totalBounty));
|
||||
diamondBankAPI.shardsToDiamonds(totalBountyShards));
|
||||
|
||||
}
|
||||
|
||||
if (plugin.getConfig().getBoolean("bounty-placed-announce", true)) {
|
||||
|
||||
final LuckPerms luckPerms = resolveLuckPerms(plugin);
|
||||
final String setterDisplay = sender instanceof Player player ? formatLuckPermsDisplay(luckPerms, player)
|
||||
: sender.getName();
|
||||
final String targetDisplay = formatLuckPermsDisplay(luckPerms, target);
|
||||
final String bountyDisplay = diamondBankAPI.shardsToDiamonds(newBountyShards);
|
||||
|
||||
Bukkit.getOnlinePlayers()
|
||||
.forEach((Player player) -> UtilitiesOG.trueogMessage(player,
|
||||
plugin.getLang().getColored("command.bounty.set.announce")
|
||||
.replace("{bounty}", String.valueOf(chargeAndBountyAmount))
|
||||
.replace("{target}", target.getName()).replace("{player}", sender.getName())
|
||||
.replace("{extra}", extra)));
|
||||
PlayerBountiesOG.getPrefix() + "&a"
|
||||
+ plugin.getLang().getColored("command.bounty.set.announce")
|
||||
.replace("{bounty}", bountyDisplay).replace("{target}", targetDisplay)
|
||||
.replace("{player}", setterDisplay).replace("{extra}", extra)));
|
||||
|
||||
}
|
||||
|
||||
@@ -265,6 +265,148 @@ public class BountySetCmd {
|
||||
|
||||
}
|
||||
|
||||
private static double parseAmount(String amountInput) {
|
||||
|
||||
if (!amountInput.matches("^\\d+(?:\\.\\d)?$")) {
|
||||
|
||||
throw new NumberFormatException("Invalid amount format");
|
||||
|
||||
}
|
||||
|
||||
return Double.parseDouble(amountInput);
|
||||
|
||||
}
|
||||
|
||||
private static DiamondBankAPIJava resolveDiamondBankApi(PlayerBountiesOG plugin) {
|
||||
|
||||
final RegisteredServiceProvider<DiamondBankAPIJava> provider = plugin.getServer().getServicesManager()
|
||||
.getRegistration(DiamondBankAPIJava.class);
|
||||
|
||||
if (provider == null) {
|
||||
|
||||
throw new IllegalStateException("DiamondBank-OG API is null");
|
||||
|
||||
}
|
||||
|
||||
return provider.getProvider();
|
||||
|
||||
}
|
||||
|
||||
private static LuckPerms resolveLuckPerms(PlayerBountiesOG plugin) {
|
||||
|
||||
final RegisteredServiceProvider<LuckPerms> provider = plugin.getServer().getServicesManager()
|
||||
.getRegistration(LuckPerms.class);
|
||||
|
||||
if (provider == null) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
return provider.getProvider();
|
||||
|
||||
}
|
||||
|
||||
private static String formatLuckPermsDisplay(LuckPerms luckPerms, Player player) {
|
||||
|
||||
final String prefix = stripLeadingReset(stripTrailingReset(getLuckPermsPrefixLegacy(luckPerms, player)));
|
||||
final String leadingColorCodes = extractLeadingColorCodes(prefix);
|
||||
|
||||
if (prefix.isBlank()) {
|
||||
|
||||
return player.getName();
|
||||
|
||||
}
|
||||
|
||||
if (leadingColorCodes.isBlank()) {
|
||||
|
||||
return prefix + " " + player.getName();
|
||||
|
||||
}
|
||||
|
||||
return prefix + " " + leadingColorCodes + player.getName();
|
||||
|
||||
}
|
||||
|
||||
private static String getLuckPermsPrefixLegacy(LuckPerms luckPerms, Player player) {
|
||||
|
||||
if (luckPerms == null) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
final User user = luckPerms.getUserManager().getUser(player.getUniqueId());
|
||||
if (user == null) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
final CachedMetaData meta = user.getCachedData().getMetaData();
|
||||
final String prefix = meta.getPrefix();
|
||||
|
||||
if (prefix == null || prefix.isBlank()) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
return StringUtils.trim(prefix).replace('§', '&');
|
||||
|
||||
}
|
||||
|
||||
private static String stripTrailingReset(String input) {
|
||||
|
||||
if (input == null || input.isBlank()) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
return StringUtils.trim(input.replaceAll("(?i)(?:\\s*(?:<reset>|[&§]r))+$", ""));
|
||||
|
||||
}
|
||||
|
||||
private static String stripLeadingReset(String input) {
|
||||
|
||||
if (input == null || input.isBlank()) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
return StringUtils.trim(input.replaceFirst("(?i)^(?:\\s*(?:<reset>|[&§]r))+", ""));
|
||||
|
||||
}
|
||||
|
||||
private static String extractLeadingColorCodes(String input) {
|
||||
|
||||
if (input == null || input.length() < 2) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
final StringBuilder out = new StringBuilder();
|
||||
for (int i = 0; i < input.length() - 1; i++) {
|
||||
|
||||
final char current = input.charAt(i);
|
||||
if (current != '&' && current != '§') {
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
out.append(current).append(input.charAt(i + 1));
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
return out.toString();
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static List<String> onTabComplete(@NotNull CommandSender sender, @NotNull String[] args) {
|
||||
|
||||
@@ -272,7 +414,8 @@ public class BountySetCmd {
|
||||
|
||||
// Suggest online player names for the username.
|
||||
return sender.getServer().getOnlinePlayers().stream().map(Player::getName)
|
||||
.filter(name -> name.toLowerCase().startsWith(args[1].toLowerCase())).collect(Collectors.toList());
|
||||
.filter(name -> StringUtils.startsWith(StringUtils.lowerCase(name), StringUtils.lowerCase(args[1])))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
} else if (args.length == 3) {
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@ package com.tcoded.playerbountiesplus.command.bounty;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -14,6 +16,9 @@ import org.bukkit.entity.Player;
|
||||
import com.tcoded.playerbountiesplus.PlayerBountiesOG;
|
||||
import com.tcoded.playerbountiesplus.gui.MainBountyGui;
|
||||
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.cacheddata.CachedMetaData;
|
||||
import net.luckperms.api.model.user.User;
|
||||
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
@@ -25,7 +30,8 @@ public class BountyTopCmd {
|
||||
|
||||
if (sender instanceof Player player) {
|
||||
|
||||
new MainBountyGui(plugin, player, () -> buildGuiEntries(plugin), diamondBankAPI).open();
|
||||
final List<MainBountyGui.BountyGuiEntry> entries = buildGuiEntries(plugin);
|
||||
new MainBountyGui(plugin, player, () -> entries, diamondBankAPI).open();
|
||||
|
||||
return true;
|
||||
|
||||
@@ -62,7 +68,9 @@ public class BountyTopCmd {
|
||||
|
||||
}
|
||||
|
||||
entries.add(new MainBountyGui.BountyGuiEntry(entry.getKey(), targetName, entry.getValue()));
|
||||
final String displayName = resolveLuckPermsDisplayName(plugin.getLuckPerms(), entry.getKey(), targetName);
|
||||
|
||||
entries.add(new MainBountyGui.BountyGuiEntry(entry.getKey(), targetName, displayName, entry.getValue()));
|
||||
|
||||
}
|
||||
|
||||
@@ -70,6 +78,92 @@ public class BountyTopCmd {
|
||||
|
||||
}
|
||||
|
||||
private static String resolveLuckPermsDisplayName(LuckPerms luckPerms, UUID playerId, String playerName) {
|
||||
|
||||
final String safeName = StringUtils.defaultIfBlank(playerName, "Unknown Player");
|
||||
if (luckPerms == null) {
|
||||
|
||||
return "&f" + safeName;
|
||||
|
||||
}
|
||||
|
||||
final User user = luckPerms.getUserManager().getUser(playerId);
|
||||
if (user == null) {
|
||||
|
||||
return "&f" + safeName;
|
||||
|
||||
}
|
||||
|
||||
final CachedMetaData meta = user.getCachedData().getMetaData();
|
||||
final String prefix = StringUtils.trim(StringUtils.defaultString(meta.getPrefix()).replace('§', '&'));
|
||||
final String suffix = StringUtils.trim(StringUtils.defaultString(meta.getSuffix()).replace('§', '&'));
|
||||
final boolean metaContainsName = containsVisibleName(prefix, safeName) || containsVisibleName(suffix, safeName);
|
||||
|
||||
final StringBuilder out = new StringBuilder();
|
||||
if (!prefix.isBlank()) {
|
||||
|
||||
out.append(prefix).append(' ');
|
||||
|
||||
}
|
||||
|
||||
if (!metaContainsName) {
|
||||
|
||||
out.append(safeName);
|
||||
|
||||
}
|
||||
|
||||
if (!suffix.isBlank()) {
|
||||
|
||||
out.append(' ').append(suffix);
|
||||
|
||||
}
|
||||
|
||||
return sanitizeDisplay(out.toString(), safeName);
|
||||
|
||||
}
|
||||
|
||||
private static String sanitizeDisplay(String formatted, String fallbackName) {
|
||||
|
||||
final String cleaned = StringUtils.trimToEmpty(formatted).replaceAll("(?i)(?:\\s*(?:<reset>|[&§]r))+$", "")
|
||||
.replaceAll("\\s+>", " >").replaceAll("\\s*>$", "");
|
||||
|
||||
if (cleaned.isBlank()) {
|
||||
|
||||
return fallbackName;
|
||||
|
||||
}
|
||||
|
||||
return cleaned;
|
||||
|
||||
}
|
||||
|
||||
private static boolean containsVisibleName(String text, String playerName) {
|
||||
|
||||
if (text == null || playerName == null || playerName.isBlank()) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
final String normalizedText = stripFormatting(text).toLowerCase(Locale.ROOT);
|
||||
final String normalizedName = playerName.toLowerCase(Locale.ROOT);
|
||||
|
||||
return normalizedText.contains(normalizedName);
|
||||
|
||||
}
|
||||
|
||||
private static String stripFormatting(String input) {
|
||||
|
||||
if (input == null || input.isBlank()) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
return input.replaceAll("(?i)[&§][0-9A-FK-ORX]", "").replaceAll("<[^>]+>", "").trim();
|
||||
|
||||
}
|
||||
|
||||
private static void sendTextTopList(PlayerBountiesOG plugin, DiamondBankAPIJava diamondBankAPI,
|
||||
CommandSender sender)
|
||||
{
|
||||
@@ -102,9 +196,13 @@ public class BountyTopCmd {
|
||||
.shardsToDiamonds(diamondBankAPI.diamondsToShards(entry.getValue()));
|
||||
|
||||
strb.append("&7 - ");
|
||||
strb.append(targetName);
|
||||
strb.append(": ");
|
||||
final String displayName = resolveLuckPermsDisplayName(plugin.getLuckPerms(), entry.getKey(),
|
||||
targetName);
|
||||
|
||||
strb.append(displayName);
|
||||
strb.append(": &b");
|
||||
strb.append(formattedBounty);
|
||||
strb.append(" &bDiamonds");
|
||||
strb.append('\n');
|
||||
|
||||
}
|
||||
@@ -116,7 +214,7 @@ public class BountyTopCmd {
|
||||
}
|
||||
|
||||
String message = strb.toString();
|
||||
message = message.substring(0, message.length() - 1);
|
||||
message = StringUtils.substring(message, 0, message.length() - 1);
|
||||
|
||||
if (!(sender instanceof Player)) {
|
||||
|
||||
@@ -130,4 +228,4 @@ public class BountyTopCmd {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -28,8 +27,6 @@ public class MainBountyGui extends GUIBase {
|
||||
private static final int NEXT_PAGE_SLOT = 51;
|
||||
private static final int CLOSE_SLOT = 53;
|
||||
|
||||
private static final Pattern MINECRAFT_USERNAME_PATTERN = Pattern.compile("^[A-Za-z0-9_]{1,16}$");
|
||||
|
||||
private final PlayerBountiesOG plugin;
|
||||
private final Player viewer;
|
||||
private final Supplier<List<BountyGuiEntry>> bountySupplier;
|
||||
@@ -76,9 +73,9 @@ public class MainBountyGui extends GUIBase {
|
||||
if (sortedBounties.isEmpty()) {
|
||||
|
||||
addItem(22,
|
||||
createStaticItem(Material.WRITABLE_BOOK, "&e&lNo Active Bounties",
|
||||
createStaticItem(Material.WRITABLE_BOOK, "&6&lNo Active Bounties",
|
||||
List.of("&7Nobody currently has a bounty.", "&7Place one with your bounty command to get",
|
||||
"&7this leaderboard moving again.")));
|
||||
"&7this leaderboard populated again.")));
|
||||
return;
|
||||
|
||||
}
|
||||
@@ -145,10 +142,8 @@ public class MainBountyGui extends GUIBase {
|
||||
|
||||
}
|
||||
|
||||
addItem(PAGE_INFO_SLOT,
|
||||
createStaticItem(Material.BOOK, "&e&lPage " + (currentPage + 1) + "/" + (maxPage + 1),
|
||||
List.of("&7Active bounties: &f" + totalBounties, "&7Shown per page: &f" + PYRAMID_SLOTS.size(),
|
||||
"&7Sorted from highest to lowest.")));
|
||||
addItem(PAGE_INFO_SLOT, createStaticItem(Material.BOOK, "&3&lPage " + (currentPage + 1) + "/" + (maxPage + 1),
|
||||
List.of("&6Active bounties: &c" + totalBounties)));
|
||||
|
||||
if (currentPage < maxPage) {
|
||||
|
||||
@@ -247,23 +242,21 @@ public class MainBountyGui extends GUIBase {
|
||||
|
||||
private GUIItem createBountyItem(BountyGuiEntry entry, int rank) {
|
||||
|
||||
final String targetName = safeName(entry.targetName());
|
||||
final String displayName = safeDisplayName(entry.displayName());
|
||||
final ArrayList<String> lore = new ArrayList<>();
|
||||
|
||||
lore.add("&7Rank: &f#" + rank);
|
||||
lore.add("&7Target: &f" + targetName);
|
||||
lore.add("&7Bounty: &6" + formatBounty(entry.bountyDiamonds()));
|
||||
lore.add("&eBounty: &b" + formatBounty(entry.bountyDiamonds()));
|
||||
lore.add("");
|
||||
lore.add("&8Highest bounty sits at the top.");
|
||||
lore.add("&6Claiming the bounty will give you a 50% chance of beheading your victim!");
|
||||
|
||||
final GUIItem item;
|
||||
if (isUsableHeadName(targetName)) {
|
||||
if (entry.targetName() != null && !entry.targetName().isBlank()) {
|
||||
|
||||
item = new GUIItem(Material.PLAYER_HEAD, 1, "&6&l#" + rank + " &f" + targetName, targetName);
|
||||
item = new GUIItem(Material.PLAYER_HEAD, 1, " &f#" + rank + " " + displayName, entry.targetName());
|
||||
|
||||
} else {
|
||||
|
||||
item = new GUIItem(Material.PAPER, 1, "&6&l#" + rank + " &f" + targetName);
|
||||
item = new GUIItem(Material.PAPER, 1, "&6&l#" + rank + " " + displayName);
|
||||
|
||||
}
|
||||
|
||||
@@ -278,7 +271,7 @@ public class MainBountyGui extends GUIBase {
|
||||
|
||||
final long shards = diamondBankAPI.diamondsToShards(bountyDiamonds);
|
||||
|
||||
return diamondBankAPI.shardsToDiamonds(shards);
|
||||
return diamondBankAPI.shardsToDiamonds(shards) + " Diamonds";
|
||||
|
||||
}
|
||||
|
||||
@@ -345,14 +338,19 @@ public class MainBountyGui extends GUIBase {
|
||||
|
||||
}
|
||||
|
||||
private boolean isUsableHeadName(String name) {
|
||||
private String safeDisplayName(String displayName) {
|
||||
|
||||
return name != null && !name.isBlank() && !"Unknown Player".equals(name)
|
||||
&& MINECRAFT_USERNAME_PATTERN.matcher(name).matches();
|
||||
if (displayName == null || displayName.isBlank()) {
|
||||
|
||||
return "&fUnknown Player";
|
||||
|
||||
}
|
||||
|
||||
return displayName;
|
||||
|
||||
}
|
||||
|
||||
public static record BountyGuiEntry(UUID targetUuid, String targetName, double bountyDiamonds) {
|
||||
public static record BountyGuiEntry(UUID targetUuid, String targetName, String displayName, double bountyDiamonds) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.tcoded.playerbountiesplus.hook.logging;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import net.coreprotect.CoreProtect;
|
||||
import net.coreprotect.CoreProtectAPI;
|
||||
|
||||
public class CoreProtectHook {
|
||||
|
||||
private final CoreProtectAPI coreProtectAPI;
|
||||
|
||||
public CoreProtectHook(Plugin plugin) {
|
||||
|
||||
this.coreProtectAPI = findCoreProtect(plugin);
|
||||
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
|
||||
return this.coreProtectAPI != null;
|
||||
|
||||
}
|
||||
|
||||
public boolean logPlacement(String user, BlockState blockState) {
|
||||
|
||||
if (this.coreProtectAPI == null || user == null || blockState == null) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return this.coreProtectAPI.logPlacement(user, blockState.getLocation(), blockState.getType(),
|
||||
blockState.getBlockData());
|
||||
|
||||
}
|
||||
|
||||
public boolean logRemoval(String user, BlockState blockState) {
|
||||
|
||||
if (this.coreProtectAPI == null || user == null || blockState == null) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return this.coreProtectAPI.logRemoval(user, blockState.getLocation(), blockState.getType(),
|
||||
blockState.getBlockData());
|
||||
|
||||
}
|
||||
|
||||
public boolean logContainerTransaction(String user, Location location) {
|
||||
|
||||
if (this.coreProtectAPI == null || user == null || location == null) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return this.coreProtectAPI.logContainerTransaction(user, location);
|
||||
|
||||
}
|
||||
|
||||
public boolean logInteraction(String user, Location location) {
|
||||
|
||||
if (this.coreProtectAPI == null || user == null || location == null) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return this.coreProtectAPI.logInteraction(user, location);
|
||||
|
||||
}
|
||||
|
||||
public boolean hasPlaced(String user, Block block, int time, int offset) {
|
||||
|
||||
if (this.coreProtectAPI == null || user == null || block == null) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return this.coreProtectAPI.hasPlaced(user, block, time, offset);
|
||||
|
||||
}
|
||||
|
||||
private static CoreProtectAPI findCoreProtect(Plugin plugin) {
|
||||
|
||||
if (plugin == null) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
final Plugin coreProtectPlugin = plugin.getServer().getPluginManager().getPlugin("CoreProtect");
|
||||
if (!(coreProtectPlugin instanceof CoreProtect coreProtect)) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
final CoreProtectAPI api = coreProtect.getAPI();
|
||||
if (api == null || !api.isEnabled() || api.APIVersion() < 11) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
return api;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,364 @@
|
||||
package com.tcoded.playerbountiesplus.listener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Skull;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import com.tcoded.playerbountiesplus.PlayerBountiesOG;
|
||||
import com.tcoded.playerbountiesplus.hook.logging.CoreProtectHook;
|
||||
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.cacheddata.CachedMetaData;
|
||||
import net.luckperms.api.model.user.User;
|
||||
import net.trueog.diamondbankog.api.DiamondBankAPIJava;
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class BountyHeadListener implements Listener {
|
||||
|
||||
private final DiamondBankAPIJava diamondBankAPI;
|
||||
private final NamespacedKey targetKey;
|
||||
private final NamespacedKey targetUuidKey;
|
||||
private final NamespacedKey amountKey;
|
||||
private final LuckPerms luckPerms;
|
||||
private final CoreProtectHook coreProtectHook;
|
||||
|
||||
public BountyHeadListener(PlayerBountiesOG plugin, DiamondBankAPIJava diamondBankAPI, LuckPerms luckPerms,
|
||||
CoreProtectHook coreProtectHook)
|
||||
{
|
||||
|
||||
this.diamondBankAPI = diamondBankAPI;
|
||||
this.targetKey = new NamespacedKey(plugin, DeathListener.BOUNTY_HEAD_NAME_KEY);
|
||||
this.targetUuidKey = new NamespacedKey(plugin, DeathListener.BOUNTY_HEAD_UUID_KEY);
|
||||
this.amountKey = new NamespacedKey(plugin, DeathListener.BOUNTY_HEAD_AMOUNT_KEY);
|
||||
this.luckPerms = luckPerms;
|
||||
this.coreProtectHook = coreProtectHook;
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onPlace(BlockPlaceEvent event) {
|
||||
|
||||
if (!isHeadMaterial(event.getBlockPlaced().getType())) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final ItemMeta itemMeta = event.getItemInHand().getItemMeta();
|
||||
if (itemMeta == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final String targetName = itemMeta.getPersistentDataContainer().get(targetKey, PersistentDataType.STRING);
|
||||
final String targetUuid = itemMeta.getPersistentDataContainer().get(targetUuidKey, PersistentDataType.STRING);
|
||||
final Double bountyAmount = itemMeta.getPersistentDataContainer().get(amountKey, PersistentDataType.DOUBLE);
|
||||
|
||||
if (targetName == null || targetUuid == null || bountyAmount == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final BlockState state = event.getBlockPlaced().getState();
|
||||
if (!(state instanceof Skull skull)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final PersistentDataContainer blockData = skull.getPersistentDataContainer();
|
||||
blockData.set(targetKey, PersistentDataType.STRING, targetName);
|
||||
blockData.set(targetUuidKey, PersistentDataType.STRING, targetUuid);
|
||||
blockData.set(amountKey, PersistentDataType.DOUBLE, bountyAmount);
|
||||
skull.update(true, false);
|
||||
|
||||
if (this.coreProtectHook != null) {
|
||||
|
||||
this.coreProtectHook.logPlacement(event.getPlayer().getName(), skull);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onBreak(BlockBreakEvent event) {
|
||||
|
||||
if (!isHeadMaterial(event.getBlock().getType())) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final BlockState state = event.getBlock().getState();
|
||||
final BlockState snapshot = state;
|
||||
if (!(state instanceof Skull skull)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final String targetName = skull.getPersistentDataContainer().get(targetKey, PersistentDataType.STRING);
|
||||
final String targetUuid = skull.getPersistentDataContainer().get(targetUuidKey, PersistentDataType.STRING);
|
||||
final Double bountyAmount = skull.getPersistentDataContainer().get(amountKey, PersistentDataType.DOUBLE);
|
||||
|
||||
if (targetName == null || targetUuid == null || bountyAmount == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final ItemStack drop = new ItemStack(Material.PLAYER_HEAD, 1);
|
||||
final SkullMeta meta = (SkullMeta) drop.getItemMeta();
|
||||
|
||||
meta.setPlayerProfile(skull.getPlayerProfile());
|
||||
|
||||
applyBountyData(meta, targetName, targetUuid, bountyAmount);
|
||||
|
||||
drop.setItemMeta(meta);
|
||||
|
||||
if (this.coreProtectHook != null) {
|
||||
|
||||
this.coreProtectHook.logRemoval(event.getPlayer().getName(), snapshot);
|
||||
|
||||
}
|
||||
|
||||
event.setDropItems(false);
|
||||
event.getBlock().setType(Material.AIR, false);
|
||||
event.getBlock().getWorld().dropItemNaturally(event.getBlock().getLocation(), drop);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onRightClick(PlayerInteractEvent event) {
|
||||
|
||||
if (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final ItemStack item = event.getItem();
|
||||
if (item != null && isHeadMaterial(item.getType())) {
|
||||
|
||||
sendBountyHeadActionbar(event.getPlayer(), item.getItemMeta());
|
||||
|
||||
}
|
||||
|
||||
if (event.getClickedBlock() == null || !isHeadMaterial(event.getClickedBlock().getType())) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final BlockState state = event.getClickedBlock().getState();
|
||||
if (!(state instanceof Skull skull)) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
sendBountyHeadActionbar(event.getPlayer(), skull.getPersistentDataContainer());
|
||||
|
||||
}
|
||||
|
||||
private void sendBountyHeadActionbar(Player player, ItemMeta itemMeta) {
|
||||
|
||||
if (itemMeta == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
sendBountyHeadActionbar(player, itemMeta.getPersistentDataContainer());
|
||||
|
||||
}
|
||||
|
||||
private void sendBountyHeadActionbar(Player player, PersistentDataContainer dataContainer) {
|
||||
|
||||
final String targetName = dataContainer.get(targetKey, PersistentDataType.STRING);
|
||||
final String targetUuid = dataContainer.get(targetUuidKey, PersistentDataType.STRING);
|
||||
final Double bountyAmount = dataContainer.get(amountKey, PersistentDataType.DOUBLE);
|
||||
|
||||
if (targetName == null || targetUuid == null || bountyAmount == null) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final UUID uuid = parseUuid(targetUuid);
|
||||
final String playerDisplay = formatLuckPermsDisplay(uuid, targetName);
|
||||
final String diamonds = formatDiamonds(bountyAmount);
|
||||
player.sendActionBar(
|
||||
UtilitiesOG.trueogColorize("&cBounty Head: " + playerDisplay + " &7- &b" + diamonds + " &bDiamonds"));
|
||||
|
||||
}
|
||||
|
||||
private void applyBountyData(SkullMeta meta, String targetName, String targetUuid, double bountyAmount) {
|
||||
|
||||
meta.displayName(UtilitiesOG.trueogColorize("&c" + targetName + "'s Bounty Head"));
|
||||
|
||||
final UUID uuid = parseUuid(targetUuid);
|
||||
final String playerDisplay = formatLuckPermsDisplay(uuid, targetName);
|
||||
|
||||
final List<TextComponent> lore = new ArrayList<>();
|
||||
lore.add(UtilitiesOG.trueogColorize("&6Player: " + playerDisplay));
|
||||
lore.add(UtilitiesOG.trueogColorize("&cBeheaded for: &b" + formatDiamonds(bountyAmount) + " &bDiamonds"));
|
||||
meta.lore(lore);
|
||||
|
||||
meta.getPersistentDataContainer().set(targetKey, PersistentDataType.STRING, targetName);
|
||||
meta.getPersistentDataContainer().set(targetUuidKey, PersistentDataType.STRING, targetUuid);
|
||||
meta.getPersistentDataContainer().set(amountKey, PersistentDataType.DOUBLE, bountyAmount);
|
||||
|
||||
}
|
||||
|
||||
private UUID parseUuid(String uuidString) {
|
||||
|
||||
if (uuidString == null || uuidString.isBlank()) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
return UUID.fromString(uuidString);
|
||||
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String formatLuckPermsDisplay(UUID targetUuid, String fallbackName) {
|
||||
|
||||
final String playerName = StringUtils.defaultIfBlank(fallbackName, "Unknown Player");
|
||||
if (targetUuid == null || luckPerms == null) {
|
||||
|
||||
return "&f" + playerName;
|
||||
|
||||
}
|
||||
|
||||
final User user = luckPerms.getUserManager().getUser(targetUuid);
|
||||
if (user == null) {
|
||||
|
||||
return "&f" + playerName;
|
||||
|
||||
}
|
||||
|
||||
final CachedMetaData meta = user.getCachedData().getMetaData();
|
||||
final String prefix = StringUtils.trim(StringUtils.defaultString(meta.getPrefix()).replace('§', '&'));
|
||||
final String suffix = StringUtils.trim(StringUtils.defaultString(meta.getSuffix()).replace('§', '&'));
|
||||
final boolean metaContainsName = containsVisibleName(prefix, playerName)
|
||||
|| containsVisibleName(suffix, playerName);
|
||||
|
||||
final StringBuilder out = new StringBuilder();
|
||||
if (!prefix.isBlank()) {
|
||||
|
||||
out.append(prefix).append(' ');
|
||||
|
||||
}
|
||||
|
||||
if (!metaContainsName) {
|
||||
|
||||
out.append(playerName);
|
||||
|
||||
}
|
||||
|
||||
if (!suffix.isBlank()) {
|
||||
|
||||
out.append(' ').append(suffix);
|
||||
|
||||
}
|
||||
|
||||
return sanitizeDisplay(out.toString(), playerName);
|
||||
|
||||
}
|
||||
|
||||
private static String sanitizeDisplay(String formatted, String fallbackName) {
|
||||
|
||||
final String cleaned = StringUtils.trimToEmpty(formatted).replaceAll("(?i)(?:\\s*(?:<reset>|[&§]r))+$", "")
|
||||
.replaceAll("\\s*>$", "");
|
||||
|
||||
if (cleaned.isBlank()) {
|
||||
|
||||
return fallbackName;
|
||||
|
||||
}
|
||||
|
||||
return cleaned;
|
||||
|
||||
}
|
||||
|
||||
private static boolean containsVisibleName(String text, String playerName) {
|
||||
|
||||
if (text == null || playerName == null || playerName.isBlank()) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
final String normalizedText = stripFormatting(text).toLowerCase(Locale.ROOT);
|
||||
final String normalizedName = playerName.toLowerCase(Locale.ROOT);
|
||||
|
||||
return normalizedText.contains(normalizedName);
|
||||
|
||||
}
|
||||
|
||||
private static String stripFormatting(String input) {
|
||||
|
||||
if (input == null || input.isBlank()) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
return input.replaceAll("(?i)[&§][0-9A-FK-ORX]", "").replaceAll("<[^>]+>", "").trim();
|
||||
|
||||
}
|
||||
|
||||
private String formatDiamonds(double diamonds) {
|
||||
|
||||
try {
|
||||
|
||||
return diamondBankAPI.shardsToDiamonds(diamondBankAPI.diamondsToShards(diamonds));
|
||||
|
||||
} catch (RuntimeException runtimeException) {
|
||||
|
||||
return String.valueOf(diamonds);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean isHeadMaterial(Material material) {
|
||||
|
||||
return material == Material.PLAYER_HEAD || material == Material.PLAYER_WALL_HEAD;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +1,31 @@
|
||||
package com.tcoded.playerbountiesplus.listener;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import com.tcoded.playerbountiesplus.PlayerBountiesOG;
|
||||
import com.tcoded.playerbountiesplus.event.BountyClaimEvent;
|
||||
import com.tcoded.playerbountiesplus.hook.team.TeamHook;
|
||||
import com.tcoded.playerbountiesplus.manager.BountyDataManager;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.cacheddata.CachedMetaData;
|
||||
import net.luckperms.api.model.user.User;
|
||||
@@ -23,6 +34,10 @@ import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class DeathListener implements Listener {
|
||||
|
||||
public static final String BOUNTY_HEAD_NAME_KEY = "bounty_head_target";
|
||||
public static final String BOUNTY_HEAD_UUID_KEY = "bounty_head_target_uuid";
|
||||
public static final String BOUNTY_HEAD_AMOUNT_KEY = "bounty_head_diamonds";
|
||||
|
||||
private final PlayerBountiesOG plugin;
|
||||
private final DiamondBankAPIJava diamondBankAPI;
|
||||
private final LuckPerms luckPerms;
|
||||
@@ -113,10 +128,26 @@ public class DeathListener implements Listener {
|
||||
|
||||
}
|
||||
|
||||
if (plugin.getConfig().getBoolean("bounty-claimed-announce", true)) {
|
||||
// Suppress the normal Minecraft death message because this death is being
|
||||
// handled as a bounty claim.
|
||||
event.deathMessage(null);
|
||||
|
||||
final String killerDisplay = formatLuckPermsDisplay(killer);
|
||||
final String victimDisplay = formatLuckPermsDisplay(victim);
|
||||
|
||||
final boolean beheaded = maybeDropPlayerHead(event, victim, bounty);
|
||||
|
||||
if (beheaded) {
|
||||
|
||||
final String bountyDisplay = formatDiamonds(bounty);
|
||||
final String beheadedMessage = killerDisplay + "&r &abeheaded " + victimDisplay + "&r &afor &b"
|
||||
+ bountyDisplay + " &bDiamonds&a!";
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach(player -> UtilitiesOG.trueogMessage(player, beheadedMessage));
|
||||
playGlobalCelebrationEffects(killer, victim);
|
||||
|
||||
} else if (plugin.getConfig().getBoolean("bounty-claimed-announce", true)) {
|
||||
|
||||
final String killerDisplay = formatLuckPermsDisplay(killer);
|
||||
final String victimDisplay = formatLuckPermsDisplay(victim);
|
||||
final String bountyDisplay = formatDiamonds(bounty);
|
||||
final String awardedDisplay = formatDiamonds(awardedAmount);
|
||||
|
||||
@@ -125,24 +156,25 @@ public class DeathListener implements Listener {
|
||||
|
||||
if (Double.compare(awardedAmount, bounty) == 0) {
|
||||
|
||||
message = killerDisplay + " &akilled " + victimDisplay + " &aand earned the &b" + awardedDisplay
|
||||
+ " &abounty!";
|
||||
message = killerDisplay + "&r &akilled " + victimDisplay + "&r &aand earned &b" + awardedDisplay
|
||||
+ " &bDiamonds &afor the bounty!";
|
||||
|
||||
} else {
|
||||
|
||||
message = killerDisplay + " &akilled " + victimDisplay + " &aand claimed the &b" + bountyDisplay
|
||||
+ " &abounty for &b" + awardedDisplay + "&a!";
|
||||
message = killerDisplay + "&r &akilled " + victimDisplay + "&r &aand claimed &b" + bountyDisplay
|
||||
+ " &bDiamonds &afor &b" + awardedDisplay + " &bDiamonds&a!";
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
message = killerDisplay + " &akilled " + victimDisplay + " &aand claimed the &b" + bountyDisplay
|
||||
+ " &abounty!";
|
||||
message = killerDisplay + "&r &akilled " + victimDisplay + "&r &aand claimed &b" + bountyDisplay
|
||||
+ " &bDiamonds &abounty!";
|
||||
|
||||
}
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach(player -> UtilitiesOG.trueogMessage(player, message));
|
||||
playGlobalCelebrationEffects(killer, victim);
|
||||
|
||||
}
|
||||
|
||||
@@ -151,6 +183,35 @@ public class DeathListener implements Listener {
|
||||
|
||||
}
|
||||
|
||||
private void playGlobalCelebrationEffects(Player killer, Player victim) {
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
|
||||
player.playSound(player.getLocation(), Sound.UI_TOAST_CHALLENGE_COMPLETE, 1.0F, 1.0F);
|
||||
|
||||
final Particle fireworkParticle = resolveFireworkParticle();
|
||||
player.spawnParticle(fireworkParticle, killer.getLocation().add(0D, 1D, 0D), 40, 0.6D, 0.8D, 0.6D, 0.01D);
|
||||
player.spawnParticle(fireworkParticle, victim.getLocation().add(0D, 1D, 0D), 40, 0.6D, 0.8D, 0.6D, 0.01D);
|
||||
player.spawnParticle(Particle.TOTEM, killer.getLocation().add(0D, 1D, 0D), 20, 0.5D, 0.7D, 0.5D, 0.01D);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private Particle resolveFireworkParticle() {
|
||||
|
||||
try {
|
||||
|
||||
return Particle.valueOf("FIREWORK");
|
||||
|
||||
} catch (IllegalArgumentException exception) {
|
||||
|
||||
return Particle.FIREWORKS_SPARK;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String formatDiamonds(double diamonds) {
|
||||
|
||||
try {
|
||||
@@ -167,22 +228,99 @@ public class DeathListener implements Listener {
|
||||
|
||||
private String formatLuckPermsDisplay(Player player) {
|
||||
|
||||
final String playerName = player.getName();
|
||||
final String prefix = stripLeadingReset(stripTrailingReset(getLuckPermsPrefixLegacy(player)));
|
||||
final String suffix = stripLeadingReset(stripTrailingReset(getLuckPermsSuffixLegacy(player)));
|
||||
final String leadingColorCodes = extractLeadingColorCodes(prefix);
|
||||
|
||||
if (prefix.isBlank()) {
|
||||
final StringBuilder out = new StringBuilder();
|
||||
if (!prefix.isBlank()) {
|
||||
|
||||
return player.getName();
|
||||
out.append(prefix).append(" ");
|
||||
|
||||
}
|
||||
|
||||
if (leadingColorCodes.isBlank()) {
|
||||
|
||||
return prefix + " " + player.getName();
|
||||
out.append(playerName);
|
||||
|
||||
} else {
|
||||
|
||||
out.append(leadingColorCodes).append(playerName);
|
||||
|
||||
}
|
||||
|
||||
return prefix + " " + leadingColorCodes + player.getName();
|
||||
if (!suffix.isBlank()) {
|
||||
|
||||
out.append(" ").append(suffix);
|
||||
|
||||
}
|
||||
|
||||
return out.toString();
|
||||
|
||||
}
|
||||
|
||||
private boolean maybeDropPlayerHead(PlayerDeathEvent event, Player victim, double bounty) {
|
||||
|
||||
final double dropChance = Math.max(0D,
|
||||
Math.min(100D, plugin.getConfig().getDouble("bounty-head-drop-chance", 50D)));
|
||||
if (ThreadLocalRandom.current().nextDouble(100D) >= dropChance) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
final ItemStack head = new ItemStack(Material.PLAYER_HEAD, 1);
|
||||
final SkullMeta headMeta = (SkullMeta) head.getItemMeta();
|
||||
|
||||
final PlayerProfile profile = Bukkit.createProfile(victim.getUniqueId());
|
||||
headMeta.setPlayerProfile(profile);
|
||||
headMeta.displayName(UtilitiesOG.trueogColorize("&c" + victim.getName() + "'s Bounty Head"));
|
||||
final String bountyDisplay = formatDiamonds(bounty);
|
||||
headMeta.lore(java.util.List.of(
|
||||
Component.text("Target: ", NamedTextColor.GRAY)
|
||||
.append(Component.text(victim.getName(), NamedTextColor.WHITE)),
|
||||
Component.text("Beheaded for: ", NamedTextColor.GRAY)
|
||||
.append(Component.text(bountyDisplay + " Diamonds", NamedTextColor.AQUA))));
|
||||
headMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, BOUNTY_HEAD_NAME_KEY),
|
||||
PersistentDataType.STRING, victim.getName());
|
||||
headMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, BOUNTY_HEAD_UUID_KEY),
|
||||
PersistentDataType.STRING, victim.getUniqueId().toString());
|
||||
headMeta.getPersistentDataContainer().set(new NamespacedKey(plugin, BOUNTY_HEAD_AMOUNT_KEY),
|
||||
PersistentDataType.DOUBLE, bounty);
|
||||
head.setItemMeta(headMeta);
|
||||
|
||||
event.getDrops().add(head);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private String getLuckPermsSuffixLegacy(Player player) {
|
||||
|
||||
if (luckPerms == null) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
final User user = luckPerms.getUserManager().getUser(player.getUniqueId());
|
||||
if (user == null) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
final CachedMetaData meta = user.getCachedData().getMetaData();
|
||||
final String suffix = meta.getSuffix();
|
||||
|
||||
if (suffix == null || suffix.isBlank()) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
return StringUtils.trim(suffix).replace('§', '&');
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.tcoded.playerbountiesplus.listener;
|
||||
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
|
||||
import com.tcoded.playerbountiesplus.PlayerBountiesOG;
|
||||
|
||||
import net.trueog.utilitiesog.UtilitiesOG;
|
||||
|
||||
public class GuiProtectionListener implements Listener {
|
||||
|
||||
private final PlayerBountiesOG plugin;
|
||||
|
||||
public GuiProtectionListener(PlayerBountiesOG plugin) {
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
|
||||
if (!isMainBountyGui(event.getView())) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (event.getRawSlot() < event.getView().getTopInventory().getSize()) {
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onInventoryDrag(InventoryDragEvent event) {
|
||||
|
||||
if (!isMainBountyGui(event.getView())) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
final int topInventorySize = event.getView().getTopInventory().getSize();
|
||||
for (int rawSlot : event.getRawSlots()) {
|
||||
|
||||
if (rawSlot < topInventorySize) {
|
||||
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isMainBountyGui(InventoryView view) {
|
||||
|
||||
final HumanEntity player = view.getPlayer();
|
||||
if (player == null) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return UtilitiesOG.stripFormatting(view.title().examinableName())
|
||||
.equals(UtilitiesOG.stripFormatting(plugin.getLang().getColored("gui.main.title")));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
@@ -40,7 +41,7 @@ public class LangUtil {
|
||||
|
||||
for (SupportedLang lang : SupportedLang.values()) {
|
||||
|
||||
if (lang.name().equalsIgnoreCase(name)) {
|
||||
if (StringUtils.equalsIgnoreCase(lang.name(), name)) {
|
||||
|
||||
return lang;
|
||||
|
||||
@@ -54,7 +55,7 @@ public class LangUtil {
|
||||
|
||||
public String fileName() {
|
||||
|
||||
return this.name().toLowerCase(Locale.ROOT) + ".yml";
|
||||
return StringUtils.lowerCase(this.name(), Locale.ROOT) + ".yml";
|
||||
|
||||
}
|
||||
|
||||
@@ -66,7 +67,7 @@ public class LangUtil {
|
||||
this.logger = plugin.getLogger();
|
||||
|
||||
final SupportedLang resolvedLang = resolveSupportedLang(configuredLang);
|
||||
this.lang = resolvedLang.name().toLowerCase(Locale.ROOT);
|
||||
this.lang = StringUtils.lowerCase(resolvedLang.name(), Locale.ROOT);
|
||||
|
||||
final String englishFilePath = "lang/" + SupportedLang.EN_US.fileName();
|
||||
final String langFilePath = "lang/" + resolvedLang.fileName();
|
||||
@@ -102,7 +103,7 @@ public class LangUtil {
|
||||
private SupportedLang resolveSupportedLang(String configuredLang) {
|
||||
|
||||
final String normalized = configuredLang == null ? DEFAULT_LANG_CODE
|
||||
: configuredLang.trim().toUpperCase(Locale.ROOT);
|
||||
: StringUtils.upperCase(StringUtils.trim(configuredLang), Locale.ROOT);
|
||||
|
||||
final SupportedLang supportedLang = SupportedLang.find(normalized);
|
||||
|
||||
@@ -217,4 +218,4 @@ public class LangUtil {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -36,9 +36,12 @@ bounty-claim-multiplier: 1.0
|
||||
# If we should announce that the bounty was claimed
|
||||
bounty-claimed-announce: true
|
||||
|
||||
# Chance (0-100) that claiming a bounty drops the victim's player head.
|
||||
bounty-head-drop-chance: 50.0
|
||||
|
||||
# If we should announce that the bounty was placed
|
||||
bounty-placed-announce: true
|
||||
|
||||
# Should the bounty money be taken from the player who dies?
|
||||
# This can reduce same-team killing (or the use of alts) to claim the bounty from themselves
|
||||
bounty-take-from-victim: false
|
||||
bounty-take-from-victim: false
|
||||
@@ -47,7 +47,7 @@ command:
|
||||
not-enough-money: "&cYou don't have enough money for that!"
|
||||
internal-invalid-value: "&cAn invalid value was reached during internal processing. Please report this to an administrator!"
|
||||
success: "&cYou placed a bounty of {bounty} on {target}'s head!"
|
||||
announce: "\nA bounty of {bounty} was placed on {target}'s head by {player}!{extra}\n"
|
||||
announce: "\nA bounty of {bounty} was placed on {target}'s &ahead by&r {player}!{extra}\n"
|
||||
announce-extra: " (Total: {total})"
|
||||
check:
|
||||
no-player-specified: "&cYou need to specify a player! /bounty check <player>"
|
||||
|
||||
@@ -10,6 +10,7 @@ folia-supported: false
|
||||
depend:
|
||||
- DiamondBank-OG
|
||||
softdepend:
|
||||
- CoreProtect-OG
|
||||
- SimpleClans
|
||||
- LuckPerms
|
||||
|
||||
|
||||
Reference in new issue
Block a user