Skip to content

Commit

Permalink
Use WeakReference to store alternative commands (#5572)
Browse files Browse the repository at this point in the history
Co-authored-by: oop778 <[email protected]>
  • Loading branch information
JRoy and OOP-778 authored Nov 27, 2023
1 parent c68b277 commit bb7b334
Showing 1 changed file with 47 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.plugin.Plugin;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
Expand All @@ -13,7 +14,7 @@
import java.util.logging.Level;

public class AlternativeCommandsHandler {
private final transient Map<String, List<Command>> altcommands = new HashMap<>();
private final transient Map<String, List<WeakReference<Command>>> altCommands = new HashMap<>();
private final transient Map<String, String> disabledList = new HashMap<>();
private final transient IEssentials ess;

Expand All @@ -35,17 +36,30 @@ public final void addPlugin(final Plugin plugin) {
final String commandName = commandSplit.length > 1 ? commandSplit[1] : entry.getKey();
final Command command = entry.getValue();

final List<Command> pluginCommands = altcommands.computeIfAbsent(commandName.toLowerCase(Locale.ENGLISH), k -> new ArrayList<>());
final List<WeakReference<Command>> pluginCommands = altCommands.computeIfAbsent(commandName.toLowerCase(Locale.ENGLISH), k -> new ArrayList<>());
boolean found = false;
for (final Command pc2 : pluginCommands) {

final Iterator<WeakReference<Command>> pluginCmdIterator = pluginCommands.iterator();
while (pluginCmdIterator.hasNext()) {
final Command cmd = pluginCmdIterator.next().get();
if (cmd == null) {
if (ess.getSettings().isDebug()) {
ess.getLogger().log(Level.INFO, "Essentials: Alternative command for " + commandName + " removed due to garbage collection");
}

pluginCmdIterator.remove();
continue;
}

// Safe cast, everything that's added comes from getPluginCommands which already performs the cast check.
if (((PluginIdentifiableCommand) pc2).getPlugin().equals(plugin)) {
if (((PluginIdentifiableCommand) cmd).getPlugin().equals(plugin)) {
found = true;
break;
}
}

if (!found) {
pluginCommands.add(command);
pluginCommands.add(new WeakReference<>(command));
}
}
}
Expand All @@ -61,32 +75,51 @@ private Map<String, Command> getPluginCommands(Plugin plugin) {
}

public void removePlugin(final Plugin plugin) {
final Iterator<Map.Entry<String, List<Command>>> iterator = altcommands.entrySet().iterator();
final Iterator<Map.Entry<String, List<WeakReference<Command>>>> iterator = altCommands.entrySet().iterator();
while (iterator.hasNext()) {
final Map.Entry<String, List<Command>> entry = iterator.next();
entry.getValue().removeIf(pc -> !(pc instanceof PluginIdentifiableCommand) || ((PluginIdentifiableCommand) pc).getPlugin().equals(plugin));
final Map.Entry<String, List<WeakReference<Command>>> entry = iterator.next();

final Iterator<WeakReference<Command>> commands = entry.getValue().iterator();
while (commands.hasNext()) {
final Command pc = commands.next().get();
if (pc instanceof PluginIdentifiableCommand && !((PluginIdentifiableCommand) pc).getPlugin().equals(plugin)) {
continue;
}
commands.remove();
}

if (entry.getValue().isEmpty()) {
iterator.remove();
}
}
}

public Command getAlternative(final String label) {
final List<Command> commands = altcommands.get(label);
final List<WeakReference<Command>> commands = altCommands.get(label);
if (commands == null || commands.isEmpty()) {
return null;
}

if (commands.size() == 1) {
return commands.get(0);
return commands.get(0).get();
}

// return the first command that is not an alias
for (final Command command : commands) {
if (command.getName().equalsIgnoreCase(label)) {
return command;
final Iterator<WeakReference<Command>> iterator = commands.iterator();
while (iterator.hasNext()) {
final Command cmd = iterator.next().get();
if (cmd == null) {
iterator.remove();
continue;
}

if (cmd.getName().equalsIgnoreCase(label)) {
return cmd;
}
}

// return the first alias
return commands.get(0);
return commands.get(0).get();
}

public void executed(final String label, final Command pc) {
Expand Down

0 comments on commit bb7b334

Please sign in to comment.