Slow startup debug, async command handling
The command argument processing and permission checking is done asynchronously, mainly because LuckPerms (rightfully) complains that loading player data (for unconnected DC users) should not be done on the main thread. The actual command execution is still done on the main thread.
This commit is contained in:
parent
feee6a0ebe
commit
a17923602f
5 changed files with 109 additions and 84 deletions
|
@ -12,6 +12,8 @@
|
|||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
||||
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
||||
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
|
||||
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.findbugs:annotations:2.0.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.javassist:javassist:3.20.0-GA" level="project" />
|
||||
|
|
|
@ -53,11 +53,15 @@ public class RandomTP extends TBMCCommandBase
|
|||
|
||||
public void onEnable(Component component)
|
||||
{
|
||||
System.out.println("Adding command");
|
||||
TBMCChatAPI.AddCommand(component, this);
|
||||
|
||||
System.out.println("Getting world");
|
||||
world = Bukkit.getWorld("World");
|
||||
System.out.println("Getting border");
|
||||
border = world.getWorldBorder();
|
||||
newLocation();
|
||||
System.out.println("Getting new location");
|
||||
System.out.println("Success: "+newLocation()); //TODO: It takes 10-30 seconds to find a location (newLocation() was there)
|
||||
}
|
||||
|
||||
/*================================================================================================*/
|
||||
|
|
|
@ -19,7 +19,6 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
|||
public class RestartComponent extends Component<MainPlugin> implements Listener {
|
||||
@Override
|
||||
public void enable() {
|
||||
//TODO: Permissions for the commands
|
||||
registerCommand(new ScheduledRestartCommand(this));
|
||||
TBMCChatAPI.AddCommand(this, new PrimeRestartCommand(this));
|
||||
registerListener(this);
|
||||
|
|
|
@ -131,10 +131,15 @@ public abstract class Component<TP extends JavaPlugin> {
|
|||
throw new UnregisteredComponentException(component);
|
||||
if (component.enabled == enabled) return; //Don't do anything
|
||||
if (component.enabled = enabled) {
|
||||
//System.out.println("Updating config for "+component.getClassName());
|
||||
updateConfig(component.getPlugin(), component);
|
||||
//System.out.println("Enabling "+component.getClassName());
|
||||
component.enable();
|
||||
if (ButtonPlugin.configGenAllowed(component))
|
||||
if (ButtonPlugin.configGenAllowed(component)) {
|
||||
//System.out.println("Pregenning config for "+component.getClassName());
|
||||
IHaveConfig.pregenConfig(component, null);
|
||||
}
|
||||
//System.out.println("Done enabling "+component.getClassName());
|
||||
} else {
|
||||
component.disable();
|
||||
component.plugin.saveConfig();
|
||||
|
|
|
@ -126,18 +126,32 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
|||
paramConverters.put(cl, new ParamConverter<>(converter, errormsg));
|
||||
}
|
||||
|
||||
public boolean handleCommand(TP sender, String commandline) throws Exception {
|
||||
public boolean handleCommand(TP sender, String commandline) {
|
||||
for (int i = commandline.length(); i != -1; i = commandline.lastIndexOf(' ', i - 1)) {
|
||||
String subcommand = commandline.substring(0, i).toLowerCase();
|
||||
SubcommandData<TC> sd = subcommands.get(subcommand); //O(1)
|
||||
if (sd == null) continue;
|
||||
Bukkit.getScheduler().runTaskAsynchronously(MainPlugin.Instance, () -> {
|
||||
try {
|
||||
handleCommandAsync(sender, commandline, sd, subcommand);
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Command execution failed for sender " + sender + " and message " + commandline, e);
|
||||
}
|
||||
});
|
||||
return true; //We found a method
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//Needed because permission checking may load the (perhaps offline) sender's file which is disallowed on the main thread
|
||||
public void handleCommandAsync(TP sender, String commandline, SubcommandData<TC> sd, String subcommand) throws Exception {
|
||||
if (sd.method == null || sd.command == null) { //Main command not registered, but we have subcommands
|
||||
sender.sendMessage(sd.helpText);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
if (!hasPermission(sender, sd.command, sd.method)) {
|
||||
sender.sendMessage("§cYou don't have permission to use this command");
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
val params = new ArrayList<Object>(sd.method.getParameterCount());
|
||||
int j = subcommand.length(), pj;
|
||||
|
@ -158,7 +172,7 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
|||
params.add(cg);
|
||||
else {
|
||||
sender.sendMessage("§cYou need to be a " + sendertype.getSimpleName() + " to use this command.");
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
val paramArr = sd.method.getParameters();
|
||||
for (int i1 = 1; i1 < parameterTypes.length; i1++) {
|
||||
|
@ -176,7 +190,7 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
|||
continue; //Fill the remaining params with nulls
|
||||
} else {
|
||||
sender.sendMessage(sd.helpText); //Required param missing
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (paramArr[i1].isVarArgs()) {
|
||||
|
@ -197,7 +211,7 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
|||
params.add(n);
|
||||
} catch (ParseException e) {
|
||||
sender.sendMessage("§c'" + param + "' is not a number.");
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -207,10 +221,11 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
|||
val cparam = conv.converter.apply(param);
|
||||
if (cparam == null) {
|
||||
sender.sendMessage(conv.errormsg); //Param conversion failed - ex. plugin not found
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
params.add(cparam);
|
||||
}
|
||||
Bukkit.getScheduler().runTask(MainPlugin.Instance, () -> {
|
||||
try {
|
||||
val ret = sd.method.invoke(sd.command, params.toArray()); //I FORGOT TO TURN IT INTO AN ARRAY (for a long time)
|
||||
if (ret instanceof Boolean) {
|
||||
|
@ -218,12 +233,12 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
|
|||
sender.sendMessage(sd.helpText);
|
||||
} else if (ret != null)
|
||||
throw new Exception("Wrong return type! Must return a boolean or void. Return value: " + ret);
|
||||
return true; //We found a method
|
||||
} catch (InvocationTargetException e) {
|
||||
TBMCCoreAPI.SendException("An error occurred in a command handler!", e.getCause());
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Command handling failed for sender " + sender + " and subcommand " + subcommand, e);
|
||||
}
|
||||
}
|
||||
return false; //Didn't handle
|
||||
});
|
||||
} //TODO: Add to the help
|
||||
|
||||
public abstract void registerCommand(TC command);
|
||||
|
|
Loading…
Reference in a new issue