2019-09-23 14:29:31 +02:00
|
|
|
package net.citizensnpcs.trait;
|
|
|
|
|
2023-03-12 15:29:41 +01:00
|
|
|
import java.time.Duration;
|
2022-07-26 17:50:28 +02:00
|
|
|
import java.util.Collection;
|
2020-06-10 20:24:03 +02:00
|
|
|
import java.util.Collections;
|
2021-01-15 15:06:03 +01:00
|
|
|
import java.util.EnumSet;
|
2022-11-26 17:32:05 +01:00
|
|
|
import java.util.Iterator;
|
2019-09-23 14:29:31 +02:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
2021-01-15 15:06:03 +01:00
|
|
|
import java.util.Set;
|
2022-07-21 17:13:51 +02:00
|
|
|
import java.util.UUID;
|
2021-03-13 15:17:55 +01:00
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
import java.util.function.Function;
|
2019-09-23 14:29:31 +02:00
|
|
|
|
2021-03-13 15:17:55 +01:00
|
|
|
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
|
2019-09-23 14:29:31 +02:00
|
|
|
import org.bukkit.Bukkit;
|
2021-02-01 15:35:28 +01:00
|
|
|
import org.bukkit.Material;
|
2019-09-23 14:29:31 +02:00
|
|
|
import org.bukkit.command.CommandSender;
|
2021-02-01 15:35:28 +01:00
|
|
|
import org.bukkit.entity.HumanEntity;
|
2019-09-23 14:29:31 +02:00
|
|
|
import org.bukkit.entity.Player;
|
2022-07-16 20:28:17 +02:00
|
|
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
2021-02-01 15:35:28 +01:00
|
|
|
import org.bukkit.event.inventory.InventoryType;
|
|
|
|
import org.bukkit.inventory.Inventory;
|
|
|
|
import org.bukkit.inventory.ItemStack;
|
2020-04-30 15:32:38 +02:00
|
|
|
import org.bukkit.permissions.PermissionAttachment;
|
2019-09-23 14:29:31 +02:00
|
|
|
|
2020-04-25 13:10:49 +02:00
|
|
|
import com.google.common.base.Splitter;
|
2020-06-10 20:24:03 +02:00
|
|
|
import com.google.common.collect.Iterables;
|
2019-09-23 14:29:31 +02:00
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
import com.google.common.collect.Maps;
|
2022-07-26 17:50:28 +02:00
|
|
|
import com.google.common.collect.Sets;
|
2020-08-12 17:40:44 +02:00
|
|
|
import com.google.common.io.BaseEncoding;
|
2019-09-23 14:29:31 +02:00
|
|
|
|
2020-10-05 06:18:19 +02:00
|
|
|
import net.citizensnpcs.Settings.Setting;
|
2020-04-15 21:04:42 +02:00
|
|
|
import net.citizensnpcs.api.CitizensAPI;
|
2020-06-30 09:20:02 +02:00
|
|
|
import net.citizensnpcs.api.event.NPCCommandDispatchEvent;
|
2021-02-01 15:35:28 +01:00
|
|
|
import net.citizensnpcs.api.gui.InventoryMenuPage;
|
2022-07-16 20:28:17 +02:00
|
|
|
import net.citizensnpcs.api.gui.InventoryMenuSlot;
|
2021-02-01 15:35:28 +01:00
|
|
|
import net.citizensnpcs.api.gui.Menu;
|
|
|
|
import net.citizensnpcs.api.gui.MenuContext;
|
2019-09-23 14:29:31 +02:00
|
|
|
import net.citizensnpcs.api.npc.NPC;
|
2019-10-01 08:16:00 +02:00
|
|
|
import net.citizensnpcs.api.persistence.DelegatePersistence;
|
2019-09-23 14:29:31 +02:00
|
|
|
import net.citizensnpcs.api.persistence.Persist;
|
|
|
|
import net.citizensnpcs.api.persistence.Persister;
|
|
|
|
import net.citizensnpcs.api.trait.Trait;
|
|
|
|
import net.citizensnpcs.api.trait.TraitName;
|
|
|
|
import net.citizensnpcs.api.util.DataKey;
|
|
|
|
import net.citizensnpcs.api.util.Messaging;
|
2020-10-05 06:18:19 +02:00
|
|
|
import net.citizensnpcs.api.util.Translator;
|
2023-03-16 15:01:04 +01:00
|
|
|
import net.citizensnpcs.trait.shop.ExperienceAction;
|
|
|
|
import net.citizensnpcs.trait.shop.ItemAction;
|
|
|
|
import net.citizensnpcs.trait.shop.MoneyAction;
|
|
|
|
import net.citizensnpcs.trait.shop.NPCShopAction;
|
|
|
|
import net.citizensnpcs.trait.shop.NPCShopAction.Transaction;
|
2019-09-23 14:29:31 +02:00
|
|
|
import net.citizensnpcs.util.Messages;
|
2020-05-01 14:07:22 +02:00
|
|
|
import net.citizensnpcs.util.StringHelper;
|
2020-07-03 16:59:18 +02:00
|
|
|
import net.citizensnpcs.util.Util;
|
2019-09-23 14:29:31 +02:00
|
|
|
|
|
|
|
@TraitName("commandtrait")
|
|
|
|
public class CommandTrait extends Trait {
|
2022-07-21 17:13:51 +02:00
|
|
|
@Persist(keyType = Integer.class)
|
2019-10-01 08:16:00 +02:00
|
|
|
@DelegatePersistence(NPCCommandPersister.class)
|
2022-07-21 17:13:51 +02:00
|
|
|
private final Map<Integer, NPCCommand> commands = Maps.newHashMap();
|
2020-04-30 15:32:38 +02:00
|
|
|
@Persist
|
2020-06-30 09:20:02 +02:00
|
|
|
private double cost = -1;
|
2022-08-21 10:15:40 +02:00
|
|
|
@Persist
|
2022-10-24 16:01:40 +02:00
|
|
|
private final Map<CommandTraitError, String> customErrorMessages = Maps.newEnumMap(CommandTraitError.class);
|
|
|
|
private final Map<String, Set<CommandTraitError>> executionErrors = Maps.newHashMap();
|
2020-06-30 09:20:02 +02:00
|
|
|
@Persist
|
2020-07-03 16:59:18 +02:00
|
|
|
private ExecutionMode executionMode = ExecutionMode.LINEAR;
|
2020-06-10 20:24:03 +02:00
|
|
|
@Persist
|
2023-03-16 15:01:04 +01:00
|
|
|
private int experienceCost = -1;
|
2022-04-29 20:39:26 +02:00
|
|
|
@Persist(valueType = Long.class)
|
2020-12-16 11:12:37 +01:00
|
|
|
private final Map<String, Long> globalCooldowns = Maps.newHashMap();
|
|
|
|
@Persist
|
2021-11-19 16:32:28 +01:00
|
|
|
private boolean hideErrorMessages;
|
|
|
|
@Persist
|
2022-04-29 20:39:26 +02:00
|
|
|
private final List<ItemStack> itemRequirements = Lists.newArrayList();
|
2022-11-28 16:10:50 +01:00
|
|
|
@Persist
|
|
|
|
private boolean persistSequence = false;
|
2022-08-21 10:15:40 +02:00
|
|
|
@Persist(keyType = UUID.class, reify = true, value = "cooldowns")
|
|
|
|
private final Map<UUID, PlayerNPCCommand> playerTracking = Maps.newHashMap();
|
2021-02-01 15:35:28 +01:00
|
|
|
@Persist
|
2020-04-30 15:32:38 +02:00
|
|
|
private final List<String> temporaryPermissions = Lists.newArrayList();
|
2019-09-23 14:29:31 +02:00
|
|
|
|
|
|
|
public CommandTrait() {
|
|
|
|
super("commandtrait");
|
|
|
|
}
|
|
|
|
|
2020-04-30 15:15:24 +02:00
|
|
|
public int addCommand(NPCCommandBuilder builder) {
|
2019-09-23 14:29:31 +02:00
|
|
|
int id = getNewId();
|
2022-07-21 17:13:51 +02:00
|
|
|
commands.put(id, builder.build(id));
|
2019-09-23 14:29:31 +02:00
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2023-03-16 15:01:04 +01:00
|
|
|
private Transaction chargeCommandCosts(Player player, Hand hand) {
|
|
|
|
NPCShopAction action = null;
|
2020-06-30 09:20:02 +02:00
|
|
|
if (cost > 0) {
|
2023-03-16 15:01:04 +01:00
|
|
|
action = new MoneyAction(cost);
|
2023-04-05 20:35:08 +02:00
|
|
|
if (!action.take(player, 1).isPossible()) {
|
2023-03-16 15:01:04 +01:00
|
|
|
sendErrorMessage(player, CommandTraitError.MISSING_MONEY, null, cost);
|
2020-06-30 09:20:02 +02:00
|
|
|
}
|
|
|
|
}
|
2021-11-01 13:56:54 +01:00
|
|
|
if (experienceCost > 0) {
|
2023-03-16 15:01:04 +01:00
|
|
|
action = new ExperienceAction(experienceCost);
|
2023-04-05 20:35:08 +02:00
|
|
|
if (!action.take(player, 1).isPossible()) {
|
2022-10-24 16:01:40 +02:00
|
|
|
sendErrorMessage(player, CommandTraitError.MISSING_EXPERIENCE, null, experienceCost);
|
2021-11-01 13:56:54 +01:00
|
|
|
}
|
|
|
|
}
|
2021-02-01 15:35:28 +01:00
|
|
|
if (itemRequirements.size() > 0) {
|
2023-03-16 15:01:04 +01:00
|
|
|
action = new ItemAction(itemRequirements);
|
2023-04-05 20:35:08 +02:00
|
|
|
if (!action.take(player, 1).isPossible()) {
|
2023-03-16 15:01:04 +01:00
|
|
|
ItemStack stack = itemRequirements.get(0);
|
|
|
|
sendErrorMessage(player, CommandTraitError.MISSING_ITEM, null, Util.prettyEnum(stack.getType()),
|
|
|
|
stack.getAmount());
|
2021-02-01 15:35:28 +01:00
|
|
|
}
|
|
|
|
}
|
2023-04-05 20:35:08 +02:00
|
|
|
return action == null ? Transaction.success() : action.take(player, 1);
|
2020-06-30 09:20:02 +02:00
|
|
|
}
|
|
|
|
|
2023-03-25 14:47:42 +01:00
|
|
|
public void clearHistory(CommandTraitError which, String raw) {
|
|
|
|
if (which == CommandTraitError.ON_GLOBAL_COOLDOWN && raw != null) {
|
|
|
|
globalCooldowns.remove(BaseEncoding.base64().encode(raw.getBytes()));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Player who = null;
|
|
|
|
if (raw != null) {
|
|
|
|
who = Bukkit.getPlayerExact(raw);
|
|
|
|
if (who == null) {
|
|
|
|
who = Bukkit.getPlayer(UUID.fromString(raw));
|
|
|
|
}
|
|
|
|
}
|
2022-10-24 16:01:40 +02:00
|
|
|
Collection<PlayerNPCCommand> toClear = Lists.newArrayList();
|
|
|
|
if (who != null) {
|
|
|
|
toClear.add(playerTracking.get(who.getUniqueId()));
|
|
|
|
} else {
|
|
|
|
toClear.addAll(playerTracking.values());
|
|
|
|
}
|
|
|
|
switch (which) {
|
|
|
|
case MAXIMUM_TIMES_USED:
|
|
|
|
for (PlayerNPCCommand tracked : toClear) {
|
|
|
|
tracked.nUsed.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case ON_COOLDOWN:
|
|
|
|
for (PlayerNPCCommand tracked : toClear) {
|
|
|
|
tracked.lastUsed.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case ON_GLOBAL_COOLDOWN:
|
|
|
|
globalCooldowns.clear();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-23 14:29:31 +02:00
|
|
|
/**
|
2020-02-14 15:48:40 +01:00
|
|
|
* Send a brief description of the current state of the trait to the supplied {@link CommandSender}.
|
2019-09-23 14:29:31 +02:00
|
|
|
*/
|
|
|
|
public void describe(CommandSender sender) {
|
|
|
|
List<NPCCommand> left = Lists.newArrayList();
|
|
|
|
List<NPCCommand> right = Lists.newArrayList();
|
|
|
|
for (NPCCommand command : commands.values()) {
|
2022-11-28 16:10:50 +01:00
|
|
|
if (command.hand == Hand.LEFT || command.hand == Hand.SHIFT_LEFT || command.hand == Hand.BOTH) {
|
2019-09-23 14:29:31 +02:00
|
|
|
left.add(command);
|
2020-01-17 10:11:23 +01:00
|
|
|
}
|
2022-11-28 16:10:50 +01:00
|
|
|
if (command.hand == Hand.RIGHT || command.hand == Hand.SHIFT_RIGHT || command.hand == Hand.BOTH) {
|
2019-09-23 14:29:31 +02:00
|
|
|
right.add(command);
|
|
|
|
}
|
|
|
|
}
|
2022-06-02 14:15:45 +02:00
|
|
|
String output = "";
|
2022-02-19 07:36:45 +01:00
|
|
|
if (cost > 0) {
|
2022-02-19 09:36:31 +01:00
|
|
|
output += "Cost: " + StringHelper.wrap(cost);
|
2022-02-19 07:36:45 +01:00
|
|
|
}
|
|
|
|
if (experienceCost > 0) {
|
|
|
|
output += " XP cost: " + StringHelper.wrap(experienceCost);
|
|
|
|
}
|
2019-09-23 14:29:31 +02:00
|
|
|
if (left.size() > 0) {
|
|
|
|
output += Messaging.tr(Messages.COMMAND_LEFT_HAND_HEADER);
|
|
|
|
for (NPCCommand command : left) {
|
2020-02-22 05:57:03 +01:00
|
|
|
output += describe(command);
|
2019-09-23 14:29:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (right.size() > 0) {
|
|
|
|
output += Messaging.tr(Messages.COMMAND_RIGHT_HAND_HEADER);
|
|
|
|
for (NPCCommand command : right) {
|
2020-02-22 05:57:03 +01:00
|
|
|
output += describe(command);
|
2019-09-23 14:29:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (output.isEmpty()) {
|
|
|
|
output = Messaging.tr(Messages.COMMAND_NO_COMMANDS_ADDED);
|
2022-06-02 14:15:45 +02:00
|
|
|
} else {
|
|
|
|
output = executionMode + " " + output;
|
2019-09-23 14:29:31 +02:00
|
|
|
}
|
2022-06-02 14:15:45 +02:00
|
|
|
|
2019-09-23 14:29:31 +02:00
|
|
|
Messaging.send(sender, output);
|
|
|
|
}
|
|
|
|
|
2020-02-22 05:57:03 +01:00
|
|
|
private String describe(NPCCommand command) {
|
2023-03-12 15:29:41 +01:00
|
|
|
String output = Messaging.tr(Messages.COMMAND_DESCRIBE_TEMPLATE, command.command, StringHelper.wrap(
|
|
|
|
command.cooldown != 0 ? command.cooldown : Setting.NPC_COMMAND_GLOBAL_COMMAND_COOLDOWN.asSeconds()),
|
|
|
|
command.id);
|
2022-02-13 10:33:44 +01:00
|
|
|
if (command.globalCooldown > 0) {
|
|
|
|
output += "[global " + StringHelper.wrap(command.globalCooldown) + "s]";
|
|
|
|
}
|
2023-03-12 15:29:41 +01:00
|
|
|
if (command.delay > 0) {
|
|
|
|
output += "[delay " + StringHelper.wrap(command.delay) + "t]";
|
|
|
|
}
|
|
|
|
if (command.n > 0) {
|
|
|
|
output += "[" + StringHelper.wrap(command.n) + " uses]";
|
|
|
|
}
|
2020-02-22 05:57:03 +01:00
|
|
|
if (command.op) {
|
|
|
|
output += " -o";
|
|
|
|
}
|
|
|
|
if (command.player) {
|
|
|
|
output += " -p";
|
|
|
|
}
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2022-11-28 16:10:50 +01:00
|
|
|
public void dispatch(final Player player, Hand handIn) {
|
|
|
|
final Hand hand = player.isSneaking()
|
|
|
|
? (handIn == CommandTrait.Hand.LEFT ? CommandTrait.Hand.SHIFT_LEFT : CommandTrait.Hand.SHIFT_RIGHT)
|
|
|
|
: handIn;
|
2020-06-30 09:20:02 +02:00
|
|
|
NPCCommandDispatchEvent event = new NPCCommandDispatchEvent(npc, player);
|
|
|
|
Bukkit.getServer().getPluginManager().callEvent(event);
|
|
|
|
if (event.isCancelled()) {
|
|
|
|
return;
|
|
|
|
}
|
2020-04-15 21:04:42 +02:00
|
|
|
Runnable task = new Runnable() {
|
2022-07-16 20:28:17 +02:00
|
|
|
Boolean charged = null;
|
2021-07-16 17:23:57 +02:00
|
|
|
|
2020-04-15 21:04:42 +02:00
|
|
|
@Override
|
|
|
|
public void run() {
|
2022-11-28 16:10:50 +01:00
|
|
|
List<NPCCommand> commandList = Lists.newArrayList(Iterables.filter(commands.values(), command -> {
|
|
|
|
return command.hand == hand || command.hand == Hand.BOTH;
|
|
|
|
}));
|
2020-07-15 14:19:43 +02:00
|
|
|
if (executionMode == ExecutionMode.RANDOM) {
|
|
|
|
if (commandList.size() > 0) {
|
|
|
|
runCommand(player, commandList.get(Util.getFastRandom().nextInt(commandList.size())));
|
|
|
|
}
|
|
|
|
return;
|
2020-07-03 16:59:18 +02:00
|
|
|
}
|
2020-06-10 20:24:03 +02:00
|
|
|
int max = -1;
|
2020-07-03 16:59:18 +02:00
|
|
|
if (executionMode == ExecutionMode.SEQUENTIAL) {
|
2022-11-26 17:32:05 +01:00
|
|
|
Collections.sort(commandList, (o1, o2) -> Integer.compare(o1.id, o2.id));
|
2020-07-03 16:59:18 +02:00
|
|
|
max = commandList.size() > 0 ? commandList.get(commandList.size() - 1).id : -1;
|
2020-06-10 20:24:03 +02:00
|
|
|
}
|
2021-01-15 15:06:03 +01:00
|
|
|
if (executionMode == ExecutionMode.LINEAR) {
|
2022-10-24 16:01:40 +02:00
|
|
|
executionErrors.put(player.getUniqueId().toString(), EnumSet.noneOf(CommandTraitError.class));
|
2021-01-15 15:06:03 +01:00
|
|
|
}
|
2020-06-10 20:24:03 +02:00
|
|
|
for (NPCCommand command : commandList) {
|
2020-07-03 16:59:18 +02:00
|
|
|
if (executionMode == ExecutionMode.SEQUENTIAL) {
|
2022-08-21 10:15:40 +02:00
|
|
|
PlayerNPCCommand info = playerTracking.get(player.getUniqueId());
|
2021-04-25 06:06:59 +02:00
|
|
|
if (info != null && info.lastUsedHand != hand) {
|
|
|
|
info.lastUsedHand = hand;
|
|
|
|
info.lastUsedId = -1;
|
|
|
|
}
|
2020-06-11 10:23:48 +02:00
|
|
|
if (info != null && command.id <= info.lastUsedId) {
|
2020-06-10 20:24:03 +02:00
|
|
|
if (info.lastUsedId == max) {
|
|
|
|
info.lastUsedId = -1;
|
2020-06-11 10:23:48 +02:00
|
|
|
} else {
|
|
|
|
continue;
|
2020-06-10 20:24:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-07-03 16:59:18 +02:00
|
|
|
runCommand(player, command);
|
2022-07-24 18:23:44 +02:00
|
|
|
if (executionMode == ExecutionMode.SEQUENTIAL || (charged != null && charged == false)) {
|
2020-10-03 09:40:53 +02:00
|
|
|
break;
|
|
|
|
}
|
2020-07-03 16:59:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void runCommand(final Player player, NPCCommand command) {
|
2022-11-26 17:32:05 +01:00
|
|
|
Runnable runnable = () -> {
|
|
|
|
PlayerNPCCommand info = playerTracking.get(player.getUniqueId());
|
|
|
|
if (info == null && (executionMode == ExecutionMode.SEQUENTIAL
|
|
|
|
|| PlayerNPCCommand.requiresTracking(command))) {
|
|
|
|
playerTracking.put(player.getUniqueId(), info = new PlayerNPCCommand());
|
|
|
|
}
|
2023-03-16 15:01:04 +01:00
|
|
|
Transaction charge = null;
|
2022-11-26 17:32:05 +01:00
|
|
|
if (charged == null) {
|
2023-03-16 15:01:04 +01:00
|
|
|
charge = chargeCommandCosts(player, hand);
|
|
|
|
if (!charge.isPossible()) {
|
2022-11-26 17:32:05 +01:00
|
|
|
charged = false;
|
2020-07-03 16:59:18 +02:00
|
|
|
return;
|
|
|
|
}
|
2022-11-26 17:32:05 +01:00
|
|
|
}
|
2023-03-16 15:01:04 +01:00
|
|
|
|
|
|
|
if (info != null && !info.canUse(CommandTrait.this, player, command))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (charged == null) {
|
|
|
|
charge.run();
|
|
|
|
}
|
|
|
|
|
2022-11-26 17:32:05 +01:00
|
|
|
PermissionAttachment attachment = player.addAttachment(CitizensAPI.getPlugin());
|
|
|
|
if (temporaryPermissions.size() > 0) {
|
|
|
|
for (String permission : temporaryPermissions) {
|
|
|
|
attachment.setPermission(permission, true);
|
2020-04-30 15:15:24 +02:00
|
|
|
}
|
2020-04-15 21:04:42 +02:00
|
|
|
}
|
2022-11-26 17:32:05 +01:00
|
|
|
command.run(npc, player);
|
|
|
|
attachment.remove();
|
2020-07-03 16:59:18 +02:00
|
|
|
};
|
|
|
|
if (command.delay <= 0) {
|
|
|
|
runnable.run();
|
|
|
|
} else {
|
|
|
|
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), runnable, command.delay);
|
2020-04-15 21:04:42 +02:00
|
|
|
}
|
2020-02-22 05:57:03 +01:00
|
|
|
}
|
2020-04-15 21:04:42 +02:00
|
|
|
};
|
|
|
|
if (Bukkit.isPrimaryThread()) {
|
|
|
|
task.run();
|
|
|
|
} else {
|
2020-04-30 15:15:24 +02:00
|
|
|
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), task);
|
2019-09-23 14:29:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-26 08:51:59 +01:00
|
|
|
public String fillPlaceholder(CommandSender sender, String input) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-10-07 13:16:41 +02:00
|
|
|
public double getCost() {
|
|
|
|
return cost;
|
|
|
|
}
|
|
|
|
|
2020-07-03 16:59:18 +02:00
|
|
|
public ExecutionMode getExecutionMode() {
|
|
|
|
return executionMode;
|
|
|
|
}
|
|
|
|
|
2021-11-01 13:56:54 +01:00
|
|
|
public float getExperienceCost() {
|
|
|
|
return experienceCost;
|
|
|
|
}
|
|
|
|
|
2019-09-23 14:29:31 +02:00
|
|
|
private int getNewId() {
|
|
|
|
int i = 0;
|
2022-07-21 17:13:51 +02:00
|
|
|
while (commands.containsKey(i)) {
|
2019-09-23 14:29:31 +02:00
|
|
|
i++;
|
|
|
|
}
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasCommandId(int id) {
|
2022-07-21 17:13:51 +02:00
|
|
|
return commands.containsKey(id);
|
2019-09-23 14:29:31 +02:00
|
|
|
}
|
|
|
|
|
2021-11-19 16:32:28 +01:00
|
|
|
public boolean isHideErrorMessages() {
|
|
|
|
return hideErrorMessages;
|
|
|
|
}
|
|
|
|
|
2022-11-28 16:10:50 +01:00
|
|
|
public boolean persistSequence() {
|
|
|
|
return persistSequence;
|
|
|
|
}
|
|
|
|
|
2019-09-23 14:29:31 +02:00
|
|
|
public void removeCommandById(int id) {
|
2022-07-21 17:13:51 +02:00
|
|
|
commands.remove(id);
|
2019-09-23 14:29:31 +02:00
|
|
|
}
|
|
|
|
|
2022-07-26 17:50:28 +02:00
|
|
|
@Override
|
|
|
|
public void save(DataKey key) {
|
|
|
|
Collection<NPCCommand> commands = this.commands.values();
|
2022-11-26 17:32:05 +01:00
|
|
|
for (Iterator<PlayerNPCCommand> itr = playerTracking.values().iterator(); itr.hasNext();) {
|
|
|
|
PlayerNPCCommand playerCommand = itr.next();
|
2022-07-26 17:50:28 +02:00
|
|
|
playerCommand.prune(globalCooldowns, commands);
|
2022-11-28 16:10:50 +01:00
|
|
|
if (playerCommand.lastUsed.isEmpty() && playerCommand.nUsed.isEmpty()
|
|
|
|
&& (!persistSequence || playerCommand.lastUsedId == -1)) {
|
2022-11-26 17:32:05 +01:00
|
|
|
itr.remove();
|
|
|
|
}
|
2022-07-26 17:50:28 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-24 16:01:40 +02:00
|
|
|
private void sendErrorMessage(Player player, CommandTraitError msg, Function<String, String> transform,
|
2021-03-13 15:17:55 +01:00
|
|
|
Object... objects) {
|
2021-11-19 16:32:28 +01:00
|
|
|
if (hideErrorMessages) {
|
|
|
|
return;
|
|
|
|
}
|
2022-10-24 16:01:40 +02:00
|
|
|
Set<CommandTraitError> sent = executionErrors.get(player.getUniqueId().toString());
|
2021-01-15 15:06:03 +01:00
|
|
|
if (sent != null) {
|
|
|
|
if (sent.contains(msg))
|
|
|
|
return;
|
|
|
|
sent.add(msg);
|
|
|
|
}
|
2022-08-21 10:15:40 +02:00
|
|
|
String messageRaw = customErrorMessages.getOrDefault(msg, msg.setting.asString());
|
2021-03-13 15:17:55 +01:00
|
|
|
if (transform != null) {
|
|
|
|
messageRaw = transform.apply(messageRaw);
|
|
|
|
}
|
2020-10-21 09:18:07 +02:00
|
|
|
if (messageRaw != null && messageRaw.trim().length() > 0) {
|
|
|
|
Messaging.send(player, Translator.format(messageRaw, objects));
|
|
|
|
}
|
2020-10-05 06:18:19 +02:00
|
|
|
}
|
|
|
|
|
2020-06-30 09:20:02 +02:00
|
|
|
public void setCost(double cost) {
|
|
|
|
this.cost = cost;
|
|
|
|
}
|
|
|
|
|
2022-10-24 16:01:40 +02:00
|
|
|
public void setCustomErrorMessage(CommandTraitError which, String message) {
|
2022-08-21 10:15:40 +02:00
|
|
|
customErrorMessages.put(which, message);
|
|
|
|
}
|
|
|
|
|
2020-07-03 16:59:18 +02:00
|
|
|
public void setExecutionMode(ExecutionMode mode) {
|
|
|
|
this.executionMode = mode;
|
2020-06-10 20:24:03 +02:00
|
|
|
}
|
|
|
|
|
2023-03-16 15:01:04 +01:00
|
|
|
public void setExperienceCost(int experienceCost) {
|
2021-11-01 13:56:54 +01:00
|
|
|
this.experienceCost = experienceCost;
|
|
|
|
}
|
|
|
|
|
2021-11-19 16:32:28 +01:00
|
|
|
public void setHideErrorMessages(boolean hide) {
|
|
|
|
this.hideErrorMessages = hide;
|
|
|
|
}
|
|
|
|
|
2022-11-28 16:10:50 +01:00
|
|
|
public void setPersistSequence(boolean persistSequence) {
|
|
|
|
this.persistSequence = persistSequence;
|
|
|
|
}
|
|
|
|
|
2020-04-30 15:32:38 +02:00
|
|
|
public void setTemporaryPermissions(List<String> permissions) {
|
|
|
|
temporaryPermissions.clear();
|
|
|
|
temporaryPermissions.addAll(permissions);
|
|
|
|
}
|
|
|
|
|
2022-10-24 16:01:40 +02:00
|
|
|
public enum CommandTraitError {
|
2020-10-05 06:18:19 +02:00
|
|
|
MAXIMUM_TIMES_USED(Setting.NPC_COMMAND_MAXIMUM_TIMES_USED_MESSAGE),
|
2021-11-01 13:56:54 +01:00
|
|
|
MISSING_EXPERIENCE(Setting.NPC_COMMAND_NOT_ENOUGH_EXPERIENCE_MESSAGE),
|
2021-02-01 15:35:28 +01:00
|
|
|
MISSING_ITEM(Setting.NPC_COMMAND_MISSING_ITEM_MESSAGE),
|
2020-10-05 06:18:19 +02:00
|
|
|
MISSING_MONEY(Setting.NPC_COMMAND_NOT_ENOUGH_MONEY_MESSAGE),
|
|
|
|
NO_PERMISSION(Setting.NPC_COMMAND_NO_PERMISSION_MESSAGE),
|
2020-12-16 11:12:37 +01:00
|
|
|
ON_COOLDOWN(Setting.NPC_COMMAND_ON_COOLDOWN_MESSAGE),
|
|
|
|
ON_GLOBAL_COOLDOWN(Setting.NPC_COMMAND_ON_GLOBAL_COOLDOWN_MESSAGE);
|
2020-10-05 06:18:19 +02:00
|
|
|
|
|
|
|
private final Setting setting;
|
|
|
|
|
2022-10-24 16:01:40 +02:00
|
|
|
CommandTraitError(Setting setting) {
|
2020-10-05 06:18:19 +02:00
|
|
|
this.setting = setting;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-03 16:59:18 +02:00
|
|
|
public enum ExecutionMode {
|
|
|
|
LINEAR,
|
|
|
|
RANDOM,
|
|
|
|
SEQUENTIAL;
|
2022-04-29 20:39:26 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
2022-06-02 14:15:45 +02:00
|
|
|
return name().charAt(0) + name().substring(1).toLowerCase();
|
2022-04-29 20:39:26 +02:00
|
|
|
}
|
2020-07-03 16:59:18 +02:00
|
|
|
}
|
|
|
|
|
2019-10-01 08:16:00 +02:00
|
|
|
public static enum Hand {
|
2020-02-14 15:48:40 +01:00
|
|
|
BOTH,
|
|
|
|
LEFT,
|
2022-11-28 16:10:50 +01:00
|
|
|
RIGHT,
|
|
|
|
SHIFT_LEFT,
|
|
|
|
SHIFT_RIGHT;
|
2019-09-23 14:29:31 +02:00
|
|
|
}
|
|
|
|
|
2021-02-01 15:35:28 +01:00
|
|
|
@Menu(title = "Drag items for requirements", type = InventoryType.CHEST, dimensions = { 5, 9 })
|
|
|
|
public static class ItemRequirementGUI extends InventoryMenuPage {
|
|
|
|
private Inventory inventory;
|
|
|
|
private CommandTrait trait;
|
|
|
|
|
|
|
|
private ItemRequirementGUI() {
|
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
|
|
|
public ItemRequirementGUI(CommandTrait trait) {
|
|
|
|
this.trait = trait;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void initialise(MenuContext ctx) {
|
|
|
|
this.inventory = ctx.getInventory();
|
|
|
|
for (ItemStack stack : trait.itemRequirements) {
|
|
|
|
inventory.addItem(stack.clone());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-16 20:28:17 +02:00
|
|
|
@Override
|
|
|
|
public void onClick(InventoryMenuSlot slot, InventoryClickEvent event) {
|
|
|
|
event.setCancelled(false);
|
|
|
|
}
|
|
|
|
|
2021-02-01 15:35:28 +01:00
|
|
|
@Override
|
|
|
|
public void onClose(HumanEntity player) {
|
|
|
|
List<ItemStack> requirements = Lists.newArrayList();
|
|
|
|
for (ItemStack stack : inventory.getContents()) {
|
|
|
|
if (stack != null && stack.getType() != Material.AIR) {
|
|
|
|
requirements.add(stack);
|
|
|
|
}
|
|
|
|
}
|
2022-04-29 20:39:26 +02:00
|
|
|
this.trait.itemRequirements.clear();
|
|
|
|
this.trait.itemRequirements.addAll(requirements);
|
2021-02-01 15:35:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-23 14:29:31 +02:00
|
|
|
private static class NPCCommand {
|
2020-04-25 13:10:49 +02:00
|
|
|
String bungeeServer;
|
2019-09-23 14:29:31 +02:00
|
|
|
String command;
|
2020-02-22 05:57:03 +01:00
|
|
|
int cooldown;
|
2020-04-30 15:15:24 +02:00
|
|
|
int delay;
|
2020-12-16 11:12:37 +01:00
|
|
|
int globalCooldown;
|
2019-09-23 14:29:31 +02:00
|
|
|
Hand hand;
|
2020-06-10 20:24:03 +02:00
|
|
|
int id;
|
2022-07-26 17:50:28 +02:00
|
|
|
String key;
|
2020-03-03 16:40:42 +01:00
|
|
|
int n;
|
2019-12-29 14:14:38 +01:00
|
|
|
boolean op;
|
2020-03-02 16:40:13 +01:00
|
|
|
List<String> perms;
|
2020-02-22 05:57:03 +01:00
|
|
|
boolean player;
|
2019-09-23 14:29:31 +02:00
|
|
|
|
2020-06-10 20:24:03 +02:00
|
|
|
public NPCCommand(int id, String command, Hand hand, boolean player, boolean op, int cooldown,
|
2020-12-16 11:12:37 +01:00
|
|
|
List<String> perms, int n, int delay, int globalCooldown) {
|
2019-09-23 14:29:31 +02:00
|
|
|
this.id = id;
|
|
|
|
this.command = command;
|
|
|
|
this.hand = hand;
|
2019-12-02 04:27:15 +01:00
|
|
|
this.player = player;
|
2019-12-29 14:14:38 +01:00
|
|
|
this.op = op;
|
2020-02-22 05:57:03 +01:00
|
|
|
this.cooldown = cooldown;
|
2020-03-02 16:40:13 +01:00
|
|
|
this.perms = perms;
|
2020-03-03 16:40:42 +01:00
|
|
|
this.n = n;
|
2020-04-30 15:15:24 +02:00
|
|
|
this.delay = delay;
|
2020-12-16 11:12:37 +01:00
|
|
|
this.globalCooldown = globalCooldown;
|
2022-07-28 20:03:16 +02:00
|
|
|
List<String> split = Splitter.on(' ').omitEmptyStrings().trimResults().limit(2).splitToList(command);
|
2020-04-25 13:10:49 +02:00
|
|
|
this.bungeeServer = split.size() == 2 && split.get(0).equalsIgnoreCase("server") ? split.get(1) : null;
|
2019-09-23 14:29:31 +02:00
|
|
|
}
|
|
|
|
|
2022-07-26 17:50:28 +02:00
|
|
|
public String getEncodedKey() {
|
|
|
|
if (key != null)
|
|
|
|
return key;
|
|
|
|
return key = BaseEncoding.base64().encode(command.getBytes());
|
|
|
|
}
|
|
|
|
|
2019-09-23 14:29:31 +02:00
|
|
|
public void run(NPC npc, Player clicker) {
|
2022-12-10 06:42:07 +01:00
|
|
|
Util.runCommand(npc, clicker, command, op, player);
|
2020-04-30 15:15:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class NPCCommandBuilder {
|
|
|
|
String command;
|
|
|
|
int cooldown;
|
|
|
|
int delay;
|
2022-04-29 20:39:26 +02:00
|
|
|
int globalCooldown;
|
2020-04-30 15:15:24 +02:00
|
|
|
Hand hand;
|
|
|
|
int n = -1;
|
|
|
|
boolean op;
|
|
|
|
List<String> perms = Lists.newArrayList();
|
|
|
|
boolean player;
|
|
|
|
|
|
|
|
public NPCCommandBuilder(String command, Hand hand) {
|
|
|
|
this.command = command;
|
|
|
|
this.hand = hand;
|
|
|
|
}
|
|
|
|
|
|
|
|
public NPCCommandBuilder addPerm(String permission) {
|
|
|
|
this.perms.add(permission);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public NPCCommandBuilder addPerms(List<String> perms) {
|
|
|
|
this.perms.addAll(perms);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2020-06-10 20:24:03 +02:00
|
|
|
private NPCCommand build(int id) {
|
2020-12-16 11:12:37 +01:00
|
|
|
return new NPCCommand(id, command, hand, player, op, cooldown, perms, n, delay, globalCooldown);
|
2020-04-30 15:15:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public NPCCommandBuilder command(String command) {
|
|
|
|
this.command = command;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2023-03-12 15:29:41 +01:00
|
|
|
public NPCCommandBuilder cooldown(Duration cd) {
|
2023-03-14 07:31:07 +01:00
|
|
|
return cooldown(Util.convert(TimeUnit.SECONDS, cd));
|
2023-03-12 15:29:41 +01:00
|
|
|
}
|
|
|
|
|
2020-04-30 15:15:24 +02:00
|
|
|
public NPCCommandBuilder cooldown(int cooldown) {
|
|
|
|
this.cooldown = cooldown;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public NPCCommandBuilder delay(int delay) {
|
|
|
|
this.delay = delay;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2023-03-12 15:29:41 +01:00
|
|
|
public NPCCommandBuilder globalCooldown(Duration cd) {
|
2023-03-14 07:31:07 +01:00
|
|
|
return globalCooldown(Util.convert(TimeUnit.SECONDS, cd));
|
2023-03-12 15:29:41 +01:00
|
|
|
}
|
|
|
|
|
2020-12-16 11:12:37 +01:00
|
|
|
public NPCCommandBuilder globalCooldown(int cooldown) {
|
|
|
|
this.globalCooldown = cooldown;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2020-04-30 15:15:24 +02:00
|
|
|
public NPCCommandBuilder n(int n) {
|
|
|
|
this.n = n;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public NPCCommandBuilder op(boolean op) {
|
|
|
|
this.op = op;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public NPCCommandBuilder player(boolean player) {
|
|
|
|
this.player = player;
|
|
|
|
return this;
|
2019-09-23 14:29:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static class NPCCommandPersister implements Persister<NPCCommand> {
|
|
|
|
public NPCCommandPersister() {
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public NPCCommand create(DataKey root) {
|
2020-03-02 16:40:13 +01:00
|
|
|
List<String> perms = Lists.newArrayList();
|
|
|
|
for (DataKey key : root.getRelative("permissions").getIntegerSubKeys()) {
|
|
|
|
perms.add(key.getString(""));
|
|
|
|
}
|
2020-06-10 20:24:03 +02:00
|
|
|
return new NPCCommand(Integer.parseInt(root.name()), root.getString("command"),
|
|
|
|
Hand.valueOf(root.getString("hand")), Boolean.valueOf(root.getString("player")),
|
|
|
|
Boolean.valueOf(root.getString("op")), root.getInt("cooldown"), perms, root.getInt("n"),
|
2020-12-16 11:12:37 +01:00
|
|
|
root.getInt("delay"), root.getInt("globalcooldown"));
|
2019-09-23 14:29:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void save(NPCCommand instance, DataKey root) {
|
|
|
|
root.setString("command", instance.command);
|
|
|
|
root.setString("hand", instance.hand.name());
|
2019-12-02 04:27:15 +01:00
|
|
|
root.setBoolean("player", instance.player);
|
2019-12-29 14:14:38 +01:00
|
|
|
root.setBoolean("op", instance.op);
|
2020-02-22 05:57:03 +01:00
|
|
|
root.setInt("cooldown", instance.cooldown);
|
2020-12-16 11:12:37 +01:00
|
|
|
root.setInt("globalcooldown", instance.globalCooldown);
|
2020-03-03 16:40:42 +01:00
|
|
|
root.setInt("n", instance.n);
|
2020-04-30 15:15:24 +02:00
|
|
|
root.setInt("delay", instance.delay);
|
2020-03-02 16:40:13 +01:00
|
|
|
for (int i = 0; i < instance.perms.size(); i++) {
|
|
|
|
root.setString("permissions." + i, instance.perms.get(i));
|
|
|
|
}
|
2020-02-22 05:57:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static class PlayerNPCCommand {
|
2020-04-26 06:53:00 +02:00
|
|
|
@Persist(valueType = Long.class)
|
2020-02-22 05:57:03 +01:00
|
|
|
Map<String, Long> lastUsed = Maps.newHashMap();
|
2020-03-03 16:40:42 +01:00
|
|
|
@Persist
|
2021-04-25 06:06:59 +02:00
|
|
|
Hand lastUsedHand;
|
|
|
|
@Persist
|
2020-06-10 20:24:03 +02:00
|
|
|
int lastUsedId = -1;
|
|
|
|
@Persist
|
2020-03-03 16:40:42 +01:00
|
|
|
Map<String, Integer> nUsed = Maps.newHashMap();
|
2020-02-22 05:57:03 +01:00
|
|
|
|
|
|
|
public PlayerNPCCommand() {
|
|
|
|
}
|
|
|
|
|
2020-10-05 06:18:19 +02:00
|
|
|
public boolean canUse(CommandTrait trait, Player player, NPCCommand command) {
|
2020-03-02 16:40:13 +01:00
|
|
|
for (String perm : command.perms) {
|
2020-03-03 16:31:04 +01:00
|
|
|
if (!player.hasPermission(perm)) {
|
2022-10-24 16:01:40 +02:00
|
|
|
trait.sendErrorMessage(player, CommandTraitError.NO_PERMISSION, null);
|
2020-03-02 16:40:13 +01:00
|
|
|
return false;
|
2020-03-03 16:31:04 +01:00
|
|
|
}
|
2020-03-02 16:40:13 +01:00
|
|
|
}
|
2023-03-12 15:29:41 +01:00
|
|
|
long globalDelay = Setting.NPC_COMMAND_GLOBAL_COMMAND_COOLDOWN.asSeconds();
|
2020-02-22 05:57:03 +01:00
|
|
|
long currentTimeSec = System.currentTimeMillis() / 1000;
|
2022-07-26 17:50:28 +02:00
|
|
|
String commandKey = command.getEncodedKey();
|
2020-08-12 17:40:44 +02:00
|
|
|
if (lastUsed.containsKey(commandKey)) {
|
2022-12-29 16:26:02 +01:00
|
|
|
long deadline = ((Number) lastUsed.get(commandKey)).longValue()
|
|
|
|
+ (command.cooldown != 0 ? command.cooldown : globalDelay);
|
2021-06-13 08:53:19 +02:00
|
|
|
if (currentTimeSec < deadline) {
|
|
|
|
long seconds = deadline - currentTimeSec;
|
2022-10-24 16:01:40 +02:00
|
|
|
trait.sendErrorMessage(player, CommandTraitError.ON_COOLDOWN,
|
2021-03-13 15:17:55 +01:00
|
|
|
new TimeVariableFormatter(seconds, TimeUnit.SECONDS), seconds);
|
2020-02-22 05:57:03 +01:00
|
|
|
return false;
|
|
|
|
}
|
2020-08-12 17:40:44 +02:00
|
|
|
lastUsed.remove(commandKey);
|
2020-02-22 05:57:03 +01:00
|
|
|
}
|
2020-12-16 11:12:37 +01:00
|
|
|
if (command.globalCooldown > 0 && trait.globalCooldowns.containsKey(commandKey)) {
|
2022-02-13 10:33:44 +01:00
|
|
|
long deadline = ((Number) trait.globalCooldowns.get(commandKey)).longValue() + command.globalCooldown;
|
2021-06-13 08:53:19 +02:00
|
|
|
if (currentTimeSec < deadline) {
|
|
|
|
long seconds = deadline - currentTimeSec;
|
2022-10-24 16:01:40 +02:00
|
|
|
trait.sendErrorMessage(player, CommandTraitError.ON_GLOBAL_COOLDOWN,
|
2021-03-13 15:17:55 +01:00
|
|
|
new TimeVariableFormatter(seconds, TimeUnit.SECONDS), seconds);
|
2020-12-16 11:12:37 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
trait.globalCooldowns.remove(commandKey);
|
|
|
|
}
|
2023-02-10 16:44:54 +01:00
|
|
|
int timesUsed = nUsed.getOrDefault(commandKey, 0);
|
2023-02-10 16:42:57 +01:00
|
|
|
if (command.n > 0 && command.n <= timesUsed) {
|
2022-10-24 16:01:40 +02:00
|
|
|
trait.sendErrorMessage(player, CommandTraitError.MAXIMUM_TIMES_USED, null, command.n);
|
2020-03-03 16:40:42 +01:00
|
|
|
return false;
|
|
|
|
}
|
2022-08-21 10:15:40 +02:00
|
|
|
if (command.cooldown > 0 || globalDelay > 0) {
|
2020-08-12 17:40:44 +02:00
|
|
|
lastUsed.put(commandKey, currentTimeSec);
|
2020-02-22 05:57:03 +01:00
|
|
|
}
|
2020-12-16 11:12:37 +01:00
|
|
|
if (command.globalCooldown > 0) {
|
|
|
|
trait.globalCooldowns.put(commandKey, currentTimeSec);
|
|
|
|
}
|
2022-04-29 20:39:26 +02:00
|
|
|
if (command.n > 0) {
|
2023-02-10 16:44:54 +01:00
|
|
|
nUsed.put(commandKey, timesUsed + 1);
|
2022-04-29 20:39:26 +02:00
|
|
|
}
|
2020-06-10 20:24:03 +02:00
|
|
|
lastUsedId = command.id;
|
2020-02-22 05:57:03 +01:00
|
|
|
return true;
|
|
|
|
}
|
2020-06-11 17:31:14 +02:00
|
|
|
|
2022-07-26 17:50:28 +02:00
|
|
|
public void prune(Map<String, Long> globalCooldowns, Collection<NPCCommand> commands) {
|
|
|
|
long currentTimeSec = System.currentTimeMillis() / 1000;
|
|
|
|
Set<String> commandKeys = Sets.newHashSet();
|
|
|
|
for (NPCCommand command : commands) {
|
|
|
|
String commandKey = command.getEncodedKey();
|
|
|
|
commandKeys.add(commandKey);
|
|
|
|
Number number = lastUsed.get(commandKey);
|
2022-12-29 16:26:02 +01:00
|
|
|
if (number != null && number.longValue() + (command.cooldown != 0 ? command.cooldown
|
2023-03-12 15:29:41 +01:00
|
|
|
: Setting.NPC_COMMAND_GLOBAL_COMMAND_COOLDOWN.asSeconds()) <= currentTimeSec) {
|
2022-07-26 17:50:28 +02:00
|
|
|
lastUsed.remove(commandKey);
|
|
|
|
}
|
|
|
|
if (globalCooldowns != null) {
|
|
|
|
number = globalCooldowns.get(commandKey);
|
|
|
|
if (number != null && number.longValue() + command.globalCooldown <= currentTimeSec) {
|
|
|
|
globalCooldowns.remove(commandKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-11-28 16:10:50 +01:00
|
|
|
|
2022-08-17 17:33:29 +02:00
|
|
|
Set<String> diff = Sets.newHashSet(lastUsed.keySet());
|
|
|
|
diff.removeAll(commandKeys);
|
|
|
|
for (String key : diff) {
|
2022-07-26 17:50:28 +02:00
|
|
|
lastUsed.remove(key);
|
|
|
|
nUsed.remove(key);
|
|
|
|
}
|
2022-11-28 16:10:50 +01:00
|
|
|
|
2022-07-26 17:50:28 +02:00
|
|
|
if (globalCooldowns != null) {
|
2022-08-17 17:33:29 +02:00
|
|
|
diff = Sets.newHashSet(globalCooldowns.keySet());
|
|
|
|
diff.removeAll(commandKeys);
|
|
|
|
for (String key : diff) {
|
2022-07-26 17:50:28 +02:00
|
|
|
globalCooldowns.remove(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-11 17:31:14 +02:00
|
|
|
public static boolean requiresTracking(NPCCommand command) {
|
2022-04-29 20:39:26 +02:00
|
|
|
return command.globalCooldown > 0 || command.cooldown > 0 || command.n > 0
|
2022-08-21 10:15:40 +02:00
|
|
|
|| (command.perms != null && command.perms.size() > 0)
|
2023-03-12 15:29:41 +01:00
|
|
|
|| Setting.NPC_COMMAND_GLOBAL_COMMAND_COOLDOWN.asSeconds() > 0;
|
2020-06-11 17:31:14 +02:00
|
|
|
}
|
2020-02-22 05:57:03 +01:00
|
|
|
}
|
2021-03-13 15:17:55 +01:00
|
|
|
|
|
|
|
private static class TimeVariableFormatter implements Function<String, String> {
|
|
|
|
private final Map<String, String> map = Maps.newHashMapWithExpectedSize(5);
|
|
|
|
|
|
|
|
public TimeVariableFormatter(long source, TimeUnit unit) {
|
|
|
|
long seconds = TimeUnit.SECONDS.convert(source, unit);
|
|
|
|
long minutes = TimeUnit.MINUTES.convert(source, unit);
|
|
|
|
long hours = TimeUnit.HOURS.convert(source, unit);
|
|
|
|
long days = TimeUnit.DAYS.convert(source, unit);
|
|
|
|
map.put("seconds", "" + seconds);
|
|
|
|
map.put("seconds_over", "" + (seconds - TimeUnit.SECONDS.convert(minutes, TimeUnit.MINUTES)));
|
|
|
|
map.put("minutes", "" + minutes);
|
|
|
|
map.put("minutes_over", "" + (minutes - TimeUnit.MINUTES.convert(hours, TimeUnit.HOURS)));
|
|
|
|
map.put("hours", "" + hours);
|
|
|
|
map.put("hours_over", "" + (hours - TimeUnit.HOURS.convert(days, TimeUnit.DAYS)));
|
|
|
|
map.put("days", "" + days);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String apply(String t) {
|
2021-04-14 13:41:37 +02:00
|
|
|
return StrSubstitutor.replace(t, map, "{", "}");
|
2021-03-13 15:17:55 +01:00
|
|
|
}
|
|
|
|
}
|
2019-09-23 14:29:31 +02:00
|
|
|
}
|