Probably fix a memory leak that happened in tandem with the Spigot timing system.
This commit is contained in:
parent
8a7f4d1718
commit
7fc9b09279
@ -1,6 +1,7 @@
|
||||
package com.massivecraft.massivecore;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@ -36,7 +37,8 @@ public class MassiveCoreEngineCommandRegistration extends EngineAbstract
|
||||
@Override
|
||||
public Long getPeriod()
|
||||
{
|
||||
return 20L;
|
||||
// Every second
|
||||
return 1 * 20L;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
@ -55,48 +57,81 @@ public class MassiveCoreEngineCommandRegistration extends EngineAbstract
|
||||
|
||||
public static void updateRegistrations()
|
||||
{
|
||||
// Get the SimpleCommandMap and it's knownCommands.
|
||||
// Step #1: Hack into Bukkit and get the SimpleCommandMap and it's knownCommands.
|
||||
SimpleCommandMap simpleCommandMap = getSimpleCommandMap();
|
||||
Map<String, Command> knownCommands = getSimpleCommandMapDotKnownCommands(simpleCommandMap);
|
||||
|
||||
// Step #2: Create a "name --> target" map that contains the MassiveCommands that /should/ be registered in Bukkit.
|
||||
Map<String, MassiveCommand> nameTargets = new HashMap<String, MassiveCommand>();
|
||||
// For each MassiveCommand that is supposed to be registered ...
|
||||
for (MassiveCommand massiveCommand : MassiveCommand.getRegisteredCommands())
|
||||
{
|
||||
// ... and for each of it's aliases ...
|
||||
for (String alias : massiveCommand.getAliases())
|
||||
{
|
||||
// ... that aren't null ...
|
||||
if (alias == null) continue;
|
||||
|
||||
// ... clean the alias ...
|
||||
alias = alias.trim().toLowerCase();
|
||||
|
||||
// ... and put it in the map.
|
||||
// NOTE: In case the same alias is used by many commands the overwrite occurs here!
|
||||
nameTargets.put(alias, massiveCommand);
|
||||
}
|
||||
}
|
||||
|
||||
// Step #3: Ensure the nameTargets created in Step #2 are registered in Bukkit.
|
||||
// For each nameTarget entry ...
|
||||
for (Entry<String, MassiveCommand> entry : nameTargets.entrySet())
|
||||
{
|
||||
String name = entry.getKey();
|
||||
MassiveCommand target = entry.getValue();
|
||||
|
||||
// ... find the current command registered in Bukkit under that name (if any) ...
|
||||
Command current = knownCommands.get(name);
|
||||
MassiveCommand massiveCurrent = getMassiveCommand(current);
|
||||
|
||||
// ... and if the current command is not the target ...
|
||||
// NOTE: We do this check since it's important we don't create new MassiveCoreBukkitCommands unless required.
|
||||
// NOTE: Before I implemented this check I caused a memory leak in tandem with Spigots timings system.
|
||||
if (target == massiveCurrent) continue;
|
||||
|
||||
// ... unregister the current command if there is one ...
|
||||
if (current != null)
|
||||
{
|
||||
knownCommands.remove(name);
|
||||
current.unregister(simpleCommandMap);
|
||||
}
|
||||
|
||||
// ... create a new MassiveCoreBukkitCommand ...
|
||||
MassiveCoreBukkitCommand command = new MassiveCoreBukkitCommand(name, target);
|
||||
|
||||
// ... and finally register it.
|
||||
simpleCommandMap.register("MassiveCore", command);
|
||||
}
|
||||
|
||||
// Step #4: Remove/Unregister MassiveCommands from Bukkit that are but should not be that any longer.
|
||||
// For each known command ...
|
||||
Iterator<Entry<String, Command>> iter = knownCommands.entrySet().iterator();
|
||||
while (iter.hasNext())
|
||||
{
|
||||
Entry<String, Command> entry = iter.next();
|
||||
String name = entry.getKey();
|
||||
Command command = entry.getValue();
|
||||
|
||||
// ... if this command is a MassiveCoreBukkitCommand ...
|
||||
if (!(command instanceof MassiveCoreBukkitCommand)) continue;
|
||||
// ... that is a MassiveCoreBukkitCommand ...
|
||||
MassiveCommand massiveCommand = getMassiveCommand(command);
|
||||
if (massiveCommand == null) continue;
|
||||
|
||||
// ... and not a target ...
|
||||
if (nameTargets.containsKey(name)) continue;
|
||||
|
||||
// ... unregister it.
|
||||
command.unregister(simpleCommandMap);
|
||||
iter.remove();
|
||||
}
|
||||
|
||||
// For each MCommand that is supposed to be registered ...
|
||||
for (MassiveCommand mcommand : MassiveCommand.getRegisteredCommands())
|
||||
{
|
||||
// ... and for each of it's aliases ...
|
||||
for (String alias : mcommand.getAliases())
|
||||
{
|
||||
// ... clean the alias ...
|
||||
alias = alias.trim().toLowerCase();
|
||||
|
||||
// ... unregister current occupant of that alias ...
|
||||
Command previousOccupant = knownCommands.remove(alias);
|
||||
if (previousOccupant != null)
|
||||
{
|
||||
previousOccupant.unregister(simpleCommandMap);
|
||||
}
|
||||
|
||||
// ... create a new MassiveCoreBukkitCommand ...
|
||||
MassiveCoreBukkitCommand command = new MassiveCoreBukkitCommand(alias, mcommand);
|
||||
|
||||
// ... and finally register it.
|
||||
simpleCommandMap.register("MassiveCore", command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
@ -119,6 +154,14 @@ public class MassiveCoreEngineCommandRegistration extends EngineAbstract
|
||||
// UTIL
|
||||
// -------------------------------------------- //
|
||||
|
||||
public static MassiveCommand getMassiveCommand(Command command)
|
||||
{
|
||||
if (command == null) return null;
|
||||
if (!(command instanceof MassiveCoreBukkitCommand)) return null;
|
||||
MassiveCoreBukkitCommand mcbc = (MassiveCoreBukkitCommand)command;
|
||||
return mcbc.getMassiveCommand();
|
||||
}
|
||||
|
||||
public static Object get(Class<?> clazz, String fieldName, Object object)
|
||||
{
|
||||
try
|
||||
|
@ -19,22 +19,22 @@ public class MassiveCoreBukkitCommand extends Command
|
||||
// FIELDS
|
||||
// -------------------------------------------- //
|
||||
|
||||
private final MassiveCommand mcommand;
|
||||
public MassiveCommand getMcommand() { return this.mcommand; }
|
||||
private final MassiveCommand massiveCommand;
|
||||
public MassiveCommand getMassiveCommand() { return this.massiveCommand; }
|
||||
|
||||
// -------------------------------------------- //
|
||||
// CONSTRUCT
|
||||
// -------------------------------------------- //
|
||||
|
||||
public MassiveCoreBukkitCommand(String name, MassiveCommand mcommand)
|
||||
public MassiveCoreBukkitCommand(String name, MassiveCommand massiveCommand)
|
||||
{
|
||||
super(
|
||||
name,
|
||||
mcommand.getDesc(),
|
||||
mcommand.getUseageTemplate(),
|
||||
massiveCommand.getDesc(),
|
||||
massiveCommand.getUseageTemplate(),
|
||||
new ArrayList<String>() // We don't use aliases
|
||||
);
|
||||
this.mcommand = mcommand;
|
||||
this.massiveCommand = massiveCommand;
|
||||
}
|
||||
|
||||
// -------------------------------------------- //
|
||||
@ -45,7 +45,7 @@ public class MassiveCoreBukkitCommand extends Command
|
||||
public boolean execute(CommandSender sender, String commandLabel, String[] args)
|
||||
{
|
||||
List<String> argList;
|
||||
if (this.mcommand.isUsingTokenizer())
|
||||
if (this.massiveCommand.isUsingTokenizer())
|
||||
{
|
||||
argList = Txt.tokenizeArguments(Txt.implode(args, " "));
|
||||
}
|
||||
@ -54,7 +54,7 @@ public class MassiveCoreBukkitCommand extends Command
|
||||
argList = new ArrayList<String>(Arrays.asList(args));
|
||||
}
|
||||
|
||||
if (this.mcommand.isUsingSmartQuotesRemoval())
|
||||
if (this.massiveCommand.isUsingSmartQuotesRemoval())
|
||||
{
|
||||
List<String> oldArgList = argList;
|
||||
argList = new ArrayList<String>();
|
||||
@ -64,7 +64,7 @@ public class MassiveCoreBukkitCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
this.mcommand.execute(sender, argList);
|
||||
this.massiveCommand.execute(sender, argList);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user