0

Async mod #1

Merged
Pepich merged 4 commits from AsyncMod into master 2017-05-09 12:15:10 +00:00
5 changed files with 121 additions and 6 deletions

View File

@ -7,7 +7,14 @@ import java.lang.annotation.Target;
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Command { public @interface Command
{
enum AsyncType
{
NEVER, ALWAYS;
}
String hook(); String hook();
AsyncType async() default AsyncType.NEVER;
} }

View File

@ -1,3 +1,4 @@
//@noformat
package com.nemez.cmdmgr; package com.nemez.cmdmgr;
import java.io.BufferedReader; import java.io.BufferedReader;
@ -5,11 +6,16 @@ import java.io.File;
import java.io.FileReader; import java.io.FileReader;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandMap;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import com.nemez.cmdmgr.component.ArgumentComponent; import com.nemez.cmdmgr.component.ArgumentComponent;
@ -100,6 +106,11 @@ public class CommandManager {
public static String noPermissionFormatting = "&c"; public static String noPermissionFormatting = "&c";
public static String notAllowedFormatting = "&c"; public static String notAllowedFormatting = "&c";
/* List of all commands that can be invoked async */
public static ArrayList<Executable> asyncExecutables = new ArrayList<Executable>();
public static HashMap<Object, ArrayList<String>> commands = new HashMap<Object, ArrayList<String>>();
/* */
/** /**
* Registers a command from a String of source code * Registers a command from a String of source code
* *
@ -139,7 +150,7 @@ public class CommandManager {
try { try {
BufferedReader reader = new BufferedReader(new FileReader(sourceFile)); BufferedReader reader = new BufferedReader(new FileReader(sourceFile));
while ((buf = reader.readLine()) != null) { while ((buf = reader.readLine()) != null) {
src.append(buf); src.append(buf + '\n');
} }
reader.close(); reader.close();
} catch (Exception e) { } catch (Exception e) {
@ -165,7 +176,7 @@ public class CommandManager {
try { try {
BufferedReader reader = new BufferedReader(new InputStreamReader(sourceStream)); BufferedReader reader = new BufferedReader(new InputStreamReader(sourceStream));
while ((buf = reader.readLine()) != null) { while ((buf = reader.readLine()) != null) {
src.append(buf); src.append(buf + '\n');
} }
reader.close(); reader.close();
} catch (Exception e) { } catch (Exception e) {
@ -177,6 +188,28 @@ public class CommandManager {
return registerCommand(src.toString(), commandHandler, plugin); return registerCommand(src.toString(), commandHandler, plugin);
} }
public static void unregisterAll(String[] commands)
{
for (String name : commands)
{
EmptyCommand emptyCommand = new EmptyCommand(name);
try {
final Field cmdMap = Bukkit.getServer().getClass().getDeclaredField("commandMap");
cmdMap.setAccessible(true);
CommandMap map = (CommandMap) cmdMap.get(Bukkit.getServer());
final Field knownCommandsField = map.getClass().getDeclaredField("knownCommands");
knownCommandsField.setAccessible(true);
@SuppressWarnings("unchecked")
Map<String, Command> knownCommands = (Map<String, Command>) knownCommandsField.get(map);
knownCommands.remove(name);
map.register(name, emptyCommand);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/** /**
* Parses the source code into an abstract command syntax * Parses the source code into an abstract command syntax
* *
@ -626,4 +659,4 @@ public class CommandManager {
return data; return data;
} }
} }//@format

View File

@ -0,0 +1,20 @@
package com.nemez.cmdmgr;
import org.bukkit.command.CommandSender;
import com.nemez.cmdmgr.util.Executable;
public class EmptyCommand extends Executable
{
public EmptyCommand(String name)
{
super(name, null);
}
@Override
public boolean execute(CommandSender sender, String name, String[] args_)
{
sender.sendMessage("§cUnknown command. Use §e/help§c, §e/plugins§c or ask a mod.");
return true;
}
}

View File

@ -0,0 +1,39 @@
package com.nemez.cmdmgr.util;
import java.lang.reflect.Method;
import java.util.ArrayList;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;
import com.nemez.cmdmgr.component.ICommandComponent;
public class AsyncExecutableDefinition extends ExecutableDefinition
{
public AsyncExecutableDefinition(ArrayList<ICommandComponent> cmd, ArrayList<Integer> paramLinks, String perm,
Method method, Object methodContainer, Type type)
{
super(cmd, paramLinks, perm, method, methodContainer, type);
}
@Override
public boolean invoke(Object[] args, CommandSender sender, JavaPlugin plugin)
{
Thread t = new Thread(new Runnable()
{
@Override
public void run()
{
invokeFromThread(args, sender, plugin);
}
});
t.setDaemon(true);
t.start();
return true;
}
private final void invokeFromThread(Object[] args, CommandSender sender, JavaPlugin plugin)
{
super.invoke(args, sender, plugin);
}
}

View File

@ -1,9 +1,11 @@
//@noformat
package com.nemez.cmdmgr.util; package com.nemez.cmdmgr.util;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -14,6 +16,7 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import com.nemez.cmdmgr.Command; import com.nemez.cmdmgr.Command;
import com.nemez.cmdmgr.Command.AsyncType;
import com.nemez.cmdmgr.CommandManager; import com.nemez.cmdmgr.CommandManager;
import com.nemez.cmdmgr.component.BooleanComponent; import com.nemez.cmdmgr.component.BooleanComponent;
import com.nemez.cmdmgr.component.ByteComponent; import com.nemez.cmdmgr.component.ByteComponent;
@ -86,6 +89,11 @@ public class Executable extends org.bukkit.command.Command {
final Field cmdMap = Bukkit.getServer().getClass().getDeclaredField("commandMap"); final Field cmdMap = Bukkit.getServer().getClass().getDeclaredField("commandMap");
cmdMap.setAccessible(true); cmdMap.setAccessible(true);
CommandMap map = (CommandMap) cmdMap.get(Bukkit.getServer()); CommandMap map = (CommandMap) cmdMap.get(Bukkit.getServer());
final Field knownCommandsField = map.getClass().getDeclaredField("knownCommands");
knownCommandsField.setAccessible(true);
@SuppressWarnings("unchecked")
Map<String, Command> knownCommands = (Map<String, Command>) knownCommandsField.get(map);
knownCommands.remove(name);
map.register(name, this); map.register(name, this);
} catch (Exception e) { } catch (Exception e) {
plugin.getLogger().log(Level.SEVERE, "Failed to register command '" + name + "'!"); plugin.getLogger().log(Level.SEVERE, "Failed to register command '" + name + "'!");
@ -263,8 +271,15 @@ public class Executable extends org.bukkit.command.Command {
if (etype == null) { if (etype == null) {
etype = Type.BOTH; etype = Type.BOTH;
} }
ExecutableDefinition def = new ExecutableDefinition(command, links, permission, target, methodContainer, etype); ExecutableDefinition def;
AsyncType type = target.getAnnotation(Command.class).async();
if (type == AsyncType.ALWAYS)
def = new AsyncExecutableDefinition(command, links, permission, target, methodContainer, etype);
else
def = new ExecutableDefinition(command, links, permission, target, methodContainer, etype);
commands.add(def); commands.add(def);
if (def instanceof AsyncExecutableDefinition)
CommandManager.asyncExecutables.add(this);
} }
@Override @Override
@ -426,3 +441,4 @@ public class Executable extends org.bukkit.command.Command {
} }
} }
} }
//@format