Merge pull request #31 from TBMCPlugins/dev
Command annotations added instead of methods, improved channels
This commit is contained in:
commit
c0e4a9e065
26 changed files with 514 additions and 224 deletions
2
.factorypath
Normal file
2
.factorypath
Normal file
|
@ -0,0 +1,2 @@
|
|||
<factorypath>
|
||||
</factorypath>
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -224,3 +224,4 @@ TheButtonAutoFlair/out/artifacts/Autoflair/Autoflair.jar
|
|||
*.xml
|
||||
|
||||
TBMC/
|
||||
/.apt_generated/
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.processAnnotations=enabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
|
|
1
META-INF/services/javax.annotation.processing.Processor
Normal file
1
META-INF/services/javax.annotation.processing.Processor
Normal file
|
@ -0,0 +1 @@
|
|||
buttondevteam.lib.AnnotationProcessor
|
11
pom.xml
11
pom.xml
|
@ -9,12 +9,6 @@
|
|||
<build>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src</directory>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
|
@ -34,6 +28,7 @@
|
|||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<compilerArgument>-proc:none</compilerArgument>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
@ -76,7 +71,7 @@
|
|||
<outputDirectory>target</outputDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>resources</directory>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
|
@ -114,7 +109,7 @@
|
|||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-io -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>1.3.2</version>
|
||||
<scope>provided</scope>
|
||||
|
|
|
@ -5,43 +5,35 @@ import org.bukkit.command.Command;
|
|||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.chat.CommandClass;
|
||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||
|
||||
public class CommandCaller implements CommandExecutor {
|
||||
|
||||
private static final String REGISTER_ERROR_MSG = "An error occured while registering commands";
|
||||
|
||||
private CommandCaller() {
|
||||
}
|
||||
|
||||
private static CommandCaller instance;
|
||||
|
||||
public static void RegisterCommand(TBMCCommandBase cmd) {
|
||||
public static void RegisterCommand(TBMCCommandBase cmd) throws Exception {
|
||||
if (instance == null)
|
||||
instance = new CommandCaller();
|
||||
if (cmd.GetCommandPath() == null) {
|
||||
TBMCCoreAPI.SendException(REGISTER_ERROR_MSG,
|
||||
new Exception("Command " + cmd.getClass().getSimpleName() + " has no command path!"));
|
||||
return;
|
||||
}
|
||||
if (cmd.getPlugin() == null) {
|
||||
TBMCCoreAPI.SendException(REGISTER_ERROR_MSG,
|
||||
new Exception("Command " + cmd.GetCommandPath() + " has no plugin!"));
|
||||
return;
|
||||
}
|
||||
String topcmd = cmd.GetCommandPath();
|
||||
if (topcmd == null)
|
||||
throw new Exception("Command " + cmd.getClass().getSimpleName() + " has no command path!");
|
||||
if (cmd.getPlugin() == null)
|
||||
throw new Exception("Command " + cmd.GetCommandPath() + " has no plugin!");
|
||||
int i;
|
||||
String topcmd;
|
||||
if ((i = (topcmd = cmd.GetCommandPath()).indexOf(' ')) != -1) // Get top-level command
|
||||
topcmd = cmd.GetCommandPath().substring(0, i);
|
||||
if ((i = topcmd.indexOf(' ')) != -1) // Get top-level command
|
||||
topcmd = topcmd.substring(0, i);
|
||||
{
|
||||
PluginCommand pc = ((JavaPlugin) cmd.getPlugin()).getCommand(topcmd);
|
||||
if (pc == null)
|
||||
TBMCCoreAPI.SendException(REGISTER_ERROR_MSG, new Exception("Top level command " + topcmd
|
||||
+ " not registered in plugin.yml for plugin: " + cmd.getPlugin().getName()));
|
||||
throw new Exception("Top level command " + topcmd + " not registered in plugin.yml for plugin: "
|
||||
+ cmd.getPlugin().getName());
|
||||
else
|
||||
pc.setExecutor(instance);
|
||||
}
|
||||
|
@ -69,14 +61,11 @@ public class CommandCaller implements CommandExecutor {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
if (cmd.GetModOnly() && !MainPlugin.permission.has(sender, "tbmc.admin")) {
|
||||
if (cmd.getClass().getAnnotation(CommandClass.class).modOnly()
|
||||
&& !MainPlugin.permission.has(sender, "tbmc.admin")) {
|
||||
sender.sendMessage("§cYou need to be a mod to use this command.");
|
||||
return true;
|
||||
}
|
||||
if (cmd.GetPlayerOnly() && !(sender instanceof Player)) {
|
||||
sender.sendMessage("§cOnly ingame players can use this command.");
|
||||
return true;
|
||||
}
|
||||
final String[] cmdargs = args.length > 0 ? Arrays.copyOfRange(args, args.length - argc, args.length) : args;
|
||||
try {
|
||||
if (!cmd.OnCommand(sender, alias, cmdargs)) {
|
||||
|
|
|
@ -1,22 +1,16 @@
|
|||
package buttondevteam.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import buttondevteam.lib.chat.Color;
|
||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
import buttondevteam.lib.player.ChromaGamerBase;
|
||||
import buttondevteam.lib.chat.Channel.RecipientTestResult;
|
||||
import buttondevteam.lib.player.TBMCPlayerBase;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
|
||||
|
@ -27,7 +21,6 @@ public class MainPlugin extends JavaPlugin {
|
|||
|
||||
private PluginDescriptionFile pdfFile;
|
||||
private Logger logger;
|
||||
private int C = 0, keep = 0;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
@ -42,46 +35,15 @@ public class MainPlugin extends JavaPlugin {
|
|||
TBMCChatAPI.AddCommand(this, ScheduledRestartCommand.class);
|
||||
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
|
||||
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase.class);
|
||||
logger.info(pdfFile.getName() + " has been Enabled (V." + pdfFile.getVersion() + ").");
|
||||
Arrays.stream(new File(ChromaGamerBase.TBMC_PLAYERS_DIR).listFiles(f -> !f.isDirectory())).map(f -> {
|
||||
YamlConfiguration yc = new YamlConfiguration();
|
||||
try {
|
||||
yc.load(f);
|
||||
} catch (IOException | InvalidConfigurationException e) {
|
||||
TBMCCoreAPI.SendException("Error while converting player data!", e);
|
||||
}
|
||||
f.delete();
|
||||
return yc;
|
||||
}).forEach(yc -> {
|
||||
try {
|
||||
int flairtime = yc.getInt("flairtime"), fcount = yc.getInt("fcount"), fdeaths = yc.getInt("fdeaths");
|
||||
String flairstate = yc.getString("flairstate");
|
||||
List<String> usernames = yc.getStringList("usernames");
|
||||
boolean flaircheater = yc.getBoolean("flaircheater");
|
||||
final String uuid = yc.getString("uuid");
|
||||
C++;
|
||||
if ((fcount == 0 || fdeaths == 0)
|
||||
&& (flairstate == null || "NoComment".equals(flairstate) || flairtime <= 0))
|
||||
return; // Those who received no Fs yet will also get their stats reset if no flair
|
||||
final File file = new File(ChromaGamerBase.TBMC_PLAYERS_DIR + "minecraft", uuid + ".yml");
|
||||
YamlConfiguration targetyc = YamlConfiguration.loadConfiguration(file);
|
||||
targetyc.set("PlayerName", yc.getString("playername"));
|
||||
targetyc.set("minecraft_id", uuid);
|
||||
ConfigurationSection bc = targetyc.createSection("ButtonChat");
|
||||
bc.set("FlairTime", "NoComment".equals(flairstate) ? -3 : flairtime); // FlairTimeNone: -3
|
||||
bc.set("FCount", fcount);
|
||||
bc.set("FDeaths", fdeaths);
|
||||
bc.set("FlairState", flairstate);
|
||||
bc.set("UserNames", usernames);
|
||||
bc.set("FlairCheater", flaircheater);
|
||||
targetyc.save(file);
|
||||
keep++;
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Error while converting player data!", e);
|
||||
}
|
||||
});
|
||||
Bukkit.getScheduler().runTask(this, () -> logger.info("Converted " + keep + " player data from " + C));
|
||||
//TODO: Remove once ran it at least once
|
||||
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null));
|
||||
TBMCChatAPI.RegisterChatChannel(
|
||||
Channel.AdminChat = new Channel("§cADMIN§f", Color.Red, "a", s -> s.isOp() ? new RecipientTestResult(0)
|
||||
: new RecipientTestResult("You need to be an admin to use this channel.")));
|
||||
TBMCChatAPI.RegisterChatChannel(Channel.ModChat = new Channel("§9MOD§f", Color.Blue, "mod",
|
||||
s -> s.isOp() || (s instanceof Player && MainPlugin.permission.playerInGroup((Player) s, "mod"))
|
||||
? new RecipientTestResult(0) //
|
||||
: new RecipientTestResult("You need to be a mod to use this channel.")));
|
||||
logger.info(pdfFile.getName() + " has been Enabled (V." + pdfFile.getVersion() + ") Test: " + Test + ".");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,8 +9,10 @@ import org.bukkit.command.CommandSender;
|
|||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import buttondevteam.lib.ScheduledServerRestartEvent;
|
||||
import buttondevteam.lib.chat.CommandClass;
|
||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||
|
||||
@CommandClass(modOnly = true, path = "schrestart")
|
||||
public class ScheduledRestartCommand extends TBMCCommandBase {
|
||||
private static volatile int restartcounter;
|
||||
private static volatile BukkitTask restarttask;
|
||||
|
@ -32,11 +34,7 @@ public class ScheduledRestartCommand extends TBMCCommandBase {
|
|||
restartbar = Bukkit.createBossBar("Server restart in " + ticks / 20f, BarColor.RED, BarStyle.SOLID,
|
||||
BarFlag.DARKEN_SKY);
|
||||
restartbar.setProgress(1);
|
||||
// System.out.println("Progress: " + restartbar.getProgress());
|
||||
Bukkit.getOnlinePlayers().stream().forEach(p -> restartbar.addPlayer(p));
|
||||
/*
|
||||
* System.out.println( "Players: " + restartbar.getPlayers().stream().map(p -> p.getName()).collect(Collectors.joining(", ")));
|
||||
*/
|
||||
sender.sendMessage("Scheduled restart in " + ticks / 20f);
|
||||
ScheduledServerRestartEvent e = new ScheduledServerRestartEvent(ticks);
|
||||
Bukkit.getPluginManager().callEvent(e);
|
||||
|
@ -50,9 +48,6 @@ public class ScheduledRestartCommand extends TBMCCommandBase {
|
|||
Bukkit.broadcastMessage("§c-- The server is restarting in " + restartcounter / 20 + " seconds!");
|
||||
restartbar.setProgress(restartcounter / (double) restarttime);
|
||||
restartbar.setTitle(String.format("Server restart in %f.2", restartcounter / 20f));
|
||||
/*
|
||||
* if (restartcounter % 20 == 0) System.out.println("Progress: " + restartbar.getProgress());
|
||||
*/
|
||||
restartcounter--;
|
||||
}, 1, 1);
|
||||
return true;
|
||||
|
@ -66,19 +61,4 @@ public class ScheduledRestartCommand extends TBMCCommandBase {
|
|||
"You can optionally set the amount of ticks to wait before the restart." //
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean GetPlayerOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean GetModOnly() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String GetCommandPath() {
|
||||
return "schrestart";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,14 +11,16 @@ import org.mockito.Mockito;
|
|||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import buttondevteam.lib.chat.Color;
|
||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
|
||||
public class TestPrepare {
|
||||
public static void PrepareServer() {
|
||||
Bukkit.setServer(Mockito.mock(Server.class, new Answer<Object>() {
|
||||
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
// System.out.println("Return type: " + invocation.getMethod().getReturnType());
|
||||
// System.out.println(String.class.isAssignableFrom(invocation.getMethod().getReturnType()));
|
||||
if (returns(invocation, String.class))
|
||||
return "test";
|
||||
if (returns(invocation, Logger.class))
|
||||
|
@ -34,5 +36,6 @@ public class TestPrepare {
|
|||
return cl.isAssignableFrom(invocation.getMethod().getReturnType());
|
||||
}
|
||||
}));
|
||||
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,10 @@ import org.bukkit.Bukkit;
|
|||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.chat.CommandClass;
|
||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||
|
||||
@CommandClass(modOnly = true)
|
||||
public class UpdatePluginCommand extends TBMCCommandBase {
|
||||
@Override
|
||||
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
|
||||
|
@ -37,14 +39,4 @@ public class UpdatePluginCommand extends TBMCCommandBase {
|
|||
"To list the plugin names: /" + alias //
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean GetPlayerOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean GetModOnly() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
33
src/main/java/buttondevteam/lib/AnnotationProcessor.java
Normal file
33
src/main/java/buttondevteam/lib/AnnotationProcessor.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package buttondevteam.lib;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import buttondevteam.lib.player.ChromaGamerEnforcer;
|
||||
|
||||
/** * A simple session bean type annotation processor. The implementation * is based on the standard annotation processing API in Java 6. */
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||
public class AnnotationProcessor extends AbstractProcessor {
|
||||
/** * Check if both @Stateful and @Stateless are present in an * session bean. If so, emits a warning message. */
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> typeElements, RoundEnvironment roundEnv) { // TODO: SEparate JAR
|
||||
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(ChromaGamerEnforcer.class);
|
||||
for (Element element : elements) {
|
||||
System.out.println("Processing " + element);
|
||||
List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors();
|
||||
System.out.println("Annotations: " + annotationMirrors);
|
||||
for (AnnotationMirror annotation : annotationMirrors) {
|
||||
String type = annotation.getAnnotationType().toString();
|
||||
System.out.println("Type: " + type);
|
||||
}
|
||||
}
|
||||
return true; // claim the annotations
|
||||
}
|
||||
}
|
|
@ -6,7 +6,14 @@ import org.bukkit.event.Event;
|
|||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import buttondevteam.lib.chat.Channel.RecipientTestResult;
|
||||
|
||||
/**
|
||||
* Make sure to only send the message to users who {@link #shouldSendTo(CommandSender)} returns true.
|
||||
*
|
||||
* @author NorbiPeti
|
||||
*
|
||||
*/
|
||||
public class TBMCChatEvent extends Event implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
|
@ -14,11 +21,13 @@ public class TBMCChatEvent extends Event implements Cancellable {
|
|||
private CommandSender sender;
|
||||
private String message;
|
||||
private boolean cancelled;
|
||||
private int score;
|
||||
|
||||
public TBMCChatEvent(CommandSender sender, Channel channel, String message) {
|
||||
public TBMCChatEvent(CommandSender sender, Channel channel, String message, int score) {
|
||||
this.sender = sender;
|
||||
this.channel = channel;
|
||||
this.message = message; // TODO: Message object with data?
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -56,4 +65,23 @@ public class TBMCChatEvent extends Event implements Cancellable {
|
|||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: Errors are sent to the sender automatically
|
||||
*/
|
||||
public boolean shouldSendTo(CommandSender sender) {
|
||||
if (channel.filteranderrormsg == null)
|
||||
return true;
|
||||
RecipientTestResult result = channel.filteranderrormsg.apply(sender);
|
||||
return result.errormessage == null && score == result.score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: Errors are sent to the sender automatically
|
||||
*/
|
||||
public int getMCScore(CommandSender sender) {
|
||||
if (channel.filteranderrormsg == null)
|
||||
return 0;
|
||||
RecipientTestResult result = channel.filteranderrormsg.apply(sender);
|
||||
return result.errormessage == null ? result.score : -1;
|
||||
}
|
||||
}
|
||||
|
|
68
src/main/java/buttondevteam/lib/TBMCChatPreprocessEvent.java
Normal file
68
src/main/java/buttondevteam/lib/TBMCChatPreprocessEvent.java
Normal file
|
@ -0,0 +1,68 @@
|
|||
package buttondevteam.lib;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
|
||||
/**
|
||||
* Can be used to change messages before it's sent.
|
||||
*
|
||||
* @author NorbiPeti
|
||||
*
|
||||
*/
|
||||
public class TBMCChatPreprocessEvent extends Event implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private Channel channel;
|
||||
private CommandSender sender;
|
||||
private String message;
|
||||
private boolean cancelled;
|
||||
|
||||
public TBMCChatPreprocessEvent(CommandSender sender, Channel channel, String message) {
|
||||
this.sender = sender;
|
||||
this.channel = channel;
|
||||
this.message = message; // TODO: Message object with data?
|
||||
}
|
||||
|
||||
/*
|
||||
* public TBMCPlayer getPlayer() { return TBMCPlayer.getPlayer(sender); // TODO: Get Chroma user }
|
||||
*/
|
||||
|
||||
public Channel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public CommandSender getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
}
|
|
@ -201,8 +201,10 @@ public class TBMCCoreAPI {
|
|||
SendUnsentExceptions();
|
||||
TBMCExceptionEvent event = new TBMCExceptionEvent(sourcemsg, e);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (!event.isHandled())
|
||||
exceptionsToSend.put(sourcemsg, e);
|
||||
synchronized (exceptionsToSend) {
|
||||
if (!event.isHandled())
|
||||
exceptionsToSend.put(sourcemsg, e);
|
||||
}
|
||||
Bukkit.getLogger().warning(sourcemsg);
|
||||
e.printStackTrace();
|
||||
if (debugPotato) {
|
||||
|
@ -212,7 +214,6 @@ public class TBMCCoreAPI {
|
|||
devsOnline.add(player);
|
||||
}
|
||||
}
|
||||
;
|
||||
if (!devsOnline.isEmpty()) {
|
||||
DebugPotato potato = new DebugPotato()
|
||||
.setMessage(new String[] { //
|
||||
|
@ -234,8 +235,10 @@ public class TBMCCoreAPI {
|
|||
SendUnsentDebugMessages();
|
||||
TBMCDebugMessageEvent event = new TBMCDebugMessageEvent(debugMessage);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (!event.isSent())
|
||||
debugMessagesToSend.add(debugMessage);
|
||||
synchronized (debugMessagesToSend) {
|
||||
if (!event.isSent())
|
||||
debugMessagesToSend.add(debugMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -258,28 +261,32 @@ public class TBMCCoreAPI {
|
|||
* Send exceptions that haven't been sent (their events didn't get handled). This method is used by the DiscordPlugin's ready event
|
||||
*/
|
||||
public static void SendUnsentExceptions() {
|
||||
if (exceptionsToSend.size() > 20) {
|
||||
exceptionsToSend.clear(); // Don't call more and more events if all the handler plugins are unloaded
|
||||
Bukkit.getLogger().warning("Unhandled exception list is over 20! Clearing!");
|
||||
}
|
||||
for (Entry<String, Throwable> entry : exceptionsToSend.entrySet()) {
|
||||
TBMCExceptionEvent event = new TBMCExceptionEvent(entry.getKey(), entry.getValue());
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isHandled())
|
||||
exceptionsToSend.remove(entry.getKey());
|
||||
synchronized (exceptionsToSend) {
|
||||
if (exceptionsToSend.size() > 20) {
|
||||
exceptionsToSend.clear(); // Don't call more and more events if all the handler plugins are unloaded
|
||||
Bukkit.getLogger().warning("Unhandled exception list is over 20! Clearing!");
|
||||
}
|
||||
for (Entry<String, Throwable> entry : exceptionsToSend.entrySet()) {
|
||||
TBMCExceptionEvent event = new TBMCExceptionEvent(entry.getKey(), entry.getValue());
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isHandled())
|
||||
exceptionsToSend.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SendUnsentDebugMessages() {
|
||||
if (debugMessagesToSend.size() > 20) {
|
||||
debugMessagesToSend.clear(); // Don't call more and more DebugMessages if all the handler plugins are unloaded
|
||||
Bukkit.getLogger().warning("Unhandled Debug Message list is over 20! Clearing!");
|
||||
}
|
||||
for (String message : debugMessagesToSend) {
|
||||
TBMCDebugMessageEvent event = new TBMCDebugMessageEvent(message);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isSent())
|
||||
debugMessagesToSend.remove(message);
|
||||
synchronized (debugMessagesToSend) {
|
||||
if (debugMessagesToSend.size() > 20) {
|
||||
debugMessagesToSend.clear(); // Don't call more and more DebugMessages if all the handler plugins are unloaded
|
||||
Bukkit.getLogger().warning("Unhandled Debug Message list is over 20! Clearing!");
|
||||
}
|
||||
for (String message : debugMessagesToSend) {
|
||||
TBMCDebugMessageEvent event = new TBMCDebugMessageEvent(message);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if (event.isSent())
|
||||
debugMessagesToSend.remove(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,26 +2,41 @@ package buttondevteam.lib.chat;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
public class Channel {
|
||||
public final String DisplayName;
|
||||
public final Color color;
|
||||
public final String Command;
|
||||
public final String ID;
|
||||
/**
|
||||
* Filters both the sender and the targets
|
||||
*/
|
||||
public final Function<CommandSender, RecipientTestResult> filteranderrormsg;
|
||||
|
||||
private static List<Channel> channels = new ArrayList<>();
|
||||
|
||||
public Channel(String displayname, Color color, String command) {
|
||||
/**
|
||||
* Creates a channel.
|
||||
*
|
||||
* @param displayname
|
||||
* The name that should appear at the start of the message
|
||||
* @param color
|
||||
* The default color of the messages sent in the channel
|
||||
* @param command
|
||||
* The command to be used for the channel <i>without /</i>. For example "mod". It's also used for scoreboard objective names.
|
||||
* @param filteranderrormsg
|
||||
* Checks all senders against the criteria provided here and sends the message if the index matches the sender's - if no score at all, displays the error.<br>
|
||||
* May be null to send to everyone.
|
||||
*/
|
||||
public Channel(String displayname, Color color, String command,
|
||||
Function<CommandSender, RecipientTestResult> filteranderrormsg) {
|
||||
DisplayName = displayname;
|
||||
this.color = color;
|
||||
Command = command;
|
||||
}
|
||||
|
||||
static {
|
||||
channels.add(GlobalChat = new Channel("§fg§f", Color.White, "g"));
|
||||
channels.add(TownChat = new Channel("§3TC§f", Color.DarkAqua, "tc"));
|
||||
channels.add(NationChat = new Channel("§6NC§f", Color.Gold, "nc"));
|
||||
channels.add(AdminChat = new Channel("§cADMIN§f", Color.Red, "a"));
|
||||
channels.add(ModChat = new Channel("§9MOD§f", Color.Blue, "mod"));
|
||||
ID = command;
|
||||
this.filteranderrormsg = filteranderrormsg;
|
||||
}
|
||||
|
||||
public static List<Channel> getChannels() {
|
||||
|
@ -29,8 +44,36 @@ public class Channel {
|
|||
}
|
||||
|
||||
public static Channel GlobalChat;
|
||||
public static Channel TownChat;
|
||||
public static Channel NationChat;
|
||||
public static Channel AdminChat;
|
||||
public static Channel ModChat;
|
||||
|
||||
static void RegisterChannel(Channel channel) {
|
||||
channels.add(channel);
|
||||
Bukkit.getPluginManager().callEvent(new ChatChannelRegisterEvent(channel));
|
||||
}
|
||||
|
||||
public static class RecipientTestResult {
|
||||
public String errormessage;
|
||||
public int score;
|
||||
|
||||
/**
|
||||
* Creates a result that indicates an <b>error</b>
|
||||
*
|
||||
* @param errormessage
|
||||
* The error message to show the sender if they don't meet the criteria.
|
||||
*/
|
||||
public RecipientTestResult(String errormessage) {
|
||||
this.errormessage = errormessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a result that indicates a <b>success</b>
|
||||
*
|
||||
* @param score
|
||||
* The score that identifies the target group. For example, the index of the town or nation to send to.
|
||||
*/
|
||||
public RecipientTestResult(int score) {
|
||||
this.score = score;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package buttondevteam.lib.chat;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class ChatChannelRegisterEvent extends Event {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private Channel channel;
|
||||
|
||||
public ChatChannelRegisterEvent(Channel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public Channel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
41
src/main/java/buttondevteam/lib/chat/CommandClass.java
Normal file
41
src/main/java/buttondevteam/lib/chat/CommandClass.java
Normal file
|
@ -0,0 +1,41 @@
|
|||
package buttondevteam.lib.chat;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* <b>Abstract classes with no {@link CommandClass} annotations will be ignored.</b> Classes that are not abstract or have the annotation will be included in the command path unless
|
||||
* {@link #excludeFromPath()} is true.
|
||||
*
|
||||
* @author NorbiPeti
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Inherited
|
||||
public @interface CommandClass {
|
||||
/**
|
||||
* Determines whether the command can only be used by mods and above or regular players can use it as well.
|
||||
*
|
||||
* @return If the command is mod only
|
||||
*/
|
||||
public boolean modOnly();
|
||||
|
||||
/**
|
||||
* The command's path, or name if top-level command.<br>
|
||||
* For example:<br>
|
||||
* "u admin updateplugin" or "u" for the top level one<br>
|
||||
* <u>The path must be lowercase!</u><br>
|
||||
*
|
||||
* @return The command path, <i>which is the command class name by default</i> (removing any "command" from it)
|
||||
*/
|
||||
public String path() default "";
|
||||
|
||||
/**
|
||||
* Exclude this class from the path. Useful if more commands share some property but aren't subcommands of a common command. See {@link CommandClass} for more details.
|
||||
*/
|
||||
public boolean excludeFromPath() default false;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package buttondevteam.lib.chat;
|
||||
|
||||
public enum Format implements TellrawSerializableEnum {
|
||||
Bold("bold"), Underlined("underlined"), Italic("italic"), Strikethrough("strikethrough"), Obfuscated(
|
||||
"obfuscated");
|
||||
// TODO: Add format codes to /u c <mode>
|
||||
private String name;
|
||||
|
||||
Format(String name) {
|
||||
this.name = name;
|
||||
this.flag = 1 << this.ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private final int flag;
|
||||
|
||||
public int getFlag() {
|
||||
return flag;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package buttondevteam.lib.chat;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
|
||||
public abstract class OptionallyPlayerCommandBase extends TBMCCommandBase {
|
||||
public boolean OnCommand(Player player, String alias, String[] args) {
|
||||
if (getClass().isAnnotationPresent(OptionallyPlayerCommandClass.class)
|
||||
&& getClass().getAnnotation(OptionallyPlayerCommandClass.class).playerOnly())
|
||||
TBMCCoreAPI.SendException("Error while executing command " + getClass().getSimpleName() + "!",
|
||||
new Exception(
|
||||
"The PlayerCommand annotation is present and set to playerOnly but the Player overload isn't overriden!"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
|
||||
if (sender instanceof Player)
|
||||
return OnCommand((Player) sender, alias, args);
|
||||
if (!getClass().isAnnotationPresent(OptionallyPlayerCommandClass.class)
|
||||
|| !getClass().getAnnotation(OptionallyPlayerCommandClass.class).playerOnly())
|
||||
TBMCCoreAPI.SendException("Error while executing command " + getClass().getSimpleName() + "!",
|
||||
new Exception(
|
||||
"Command class doesn't override the CommandSender overload and no PlayerCommandClass annotation is present or playerOnly is false!"));
|
||||
sender.sendMessage("§cYou need to be a player to use this command.");
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package buttondevteam.lib.chat;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Only needed to use with {@link OptionallyPlayerCommandBase} command classes
|
||||
*
|
||||
* @author NorbiPeti
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Inherited
|
||||
public @interface OptionallyPlayerCommandClass {
|
||||
public boolean playerOnly();
|
||||
}
|
16
src/main/java/buttondevteam/lib/chat/PlayerCommandBase.java
Normal file
16
src/main/java/buttondevteam/lib/chat/PlayerCommandBase.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
package buttondevteam.lib.chat;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public abstract class PlayerCommandBase extends TBMCCommandBase {
|
||||
public abstract boolean OnCommand(Player player, String alias, String[] args);
|
||||
|
||||
@Override
|
||||
public final boolean OnCommand(CommandSender sender, String alias, String[] args) {
|
||||
if (sender instanceof Player)
|
||||
return OnCommand((Player) sender, alias, args);
|
||||
sender.sendMessage("§cYou need to be a player to use this command.");
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import java.lang.reflect.Modifier;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
@ -19,7 +20,9 @@ import org.reflections.util.ConfigurationBuilder;
|
|||
import buttondevteam.core.CommandCaller;
|
||||
import buttondevteam.core.MainPlugin;
|
||||
import buttondevteam.lib.TBMCChatEvent;
|
||||
import buttondevteam.lib.TBMCChatPreprocessEvent;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.chat.Channel.RecipientTestResult;
|
||||
|
||||
public class TBMCChatAPI {
|
||||
|
||||
|
@ -59,19 +62,20 @@ public class TBMCChatAPI {
|
|||
cmds.add("§6---- Subcommands ----");
|
||||
cmds.add(cmd);
|
||||
};
|
||||
for (TBMCCommandBase cmd : TBMCChatAPI.GetCommands().values()) {
|
||||
if (cmd.GetCommandPath().startsWith(command + " ")) {
|
||||
if (cmd.GetPlayerOnly() && !(sender instanceof Player))
|
||||
for (Entry<String, TBMCCommandBase> cmd : TBMCChatAPI.GetCommands().entrySet()) {
|
||||
if (cmd.getKey().startsWith(command + " ")) {
|
||||
if (cmd.getValue().isPlayerOnly() && !(sender instanceof Player))
|
||||
continue;
|
||||
if (cmd.GetModOnly() && !MainPlugin.permission.has(sender, "tbmc.admin"))
|
||||
if (cmd.getClass().getAnnotation(CommandClass.class).modOnly()
|
||||
&& !MainPlugin.permission.has(sender, "tbmc.admin"))
|
||||
continue;
|
||||
int ind = cmd.GetCommandPath().indexOf(' ', command.length() + 2);
|
||||
int ind = cmd.getKey().indexOf(' ', command.length() + 2);
|
||||
if (ind >= 0) {
|
||||
String newcmd = cmd.GetCommandPath().substring(0, ind);
|
||||
String newcmd = cmd.getKey().substring(0, ind);
|
||||
if (!cmds.contains("/" + newcmd))
|
||||
addToCmds.accept("/" + newcmd);
|
||||
} else
|
||||
addToCmds.accept("/" + cmd.GetCommandPath());
|
||||
addToCmds.accept("/" + cmd.getKey());
|
||||
}
|
||||
}
|
||||
return cmds.toArray(new String[cmds.size()]);
|
||||
|
@ -96,15 +100,21 @@ public class TBMCChatAPI {
|
|||
* @param acmdclass
|
||||
* A command's class to get the package name for commands. The provided class's package and subpackages are scanned for commands.
|
||||
*/
|
||||
public static void AddCommands(JavaPlugin plugin, Class<? extends TBMCCommandBase> acmdclass) {
|
||||
plugin.getLogger().info("Registering commands for " + plugin.getName());
|
||||
public static synchronized void AddCommands(JavaPlugin plugin, Class<? extends TBMCCommandBase> acmdclass) {
|
||||
plugin.getLogger().info("Registering commands from " + acmdclass.getPackage().getName());
|
||||
Reflections rf = new Reflections(new ConfigurationBuilder()
|
||||
.setUrls(ClasspathHelper.forPackage(acmdclass.getPackage().getName(),
|
||||
plugin.getClass().getClassLoader()))
|
||||
.addUrls(
|
||||
ClasspathHelper.forClass(OptionallyPlayerCommandBase.class,
|
||||
OptionallyPlayerCommandBase.class.getClassLoader()),
|
||||
ClasspathHelper.forClass(PlayerCommandBase.class, PlayerCommandBase.class.getClassLoader())) // http://stackoverflow.com/questions/12917417/using-reflections-for-finding-the-transitive-subtypes-of-a-class-when-not-all
|
||||
.addClassLoader(plugin.getClass().getClassLoader()).addScanners(new SubTypesScanner()));
|
||||
Set<Class<? extends TBMCCommandBase>> cmds = rf.getSubTypesOf(TBMCCommandBase.class);
|
||||
for (Class<? extends TBMCCommandBase> cmd : cmds) {
|
||||
try {
|
||||
if (!cmd.getPackage().getName().startsWith(acmdclass.getPackage().getName()))
|
||||
continue; // It keeps including the commands from here
|
||||
if (Modifier.isAbstract(cmd.getModifiers()))
|
||||
continue;
|
||||
TBMCCommandBase c = cmd.newInstance();
|
||||
|
@ -113,9 +123,7 @@ public class TBMCChatAPI {
|
|||
continue;
|
||||
commands.put(c.GetCommandPath(), c);
|
||||
CommandCaller.RegisterCommand(c);
|
||||
} catch (InstantiationException e) {
|
||||
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getName(), e);
|
||||
} catch (IllegalAccessException e) {
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while registering command " + cmd.getName(), e);
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +207,7 @@ public class TBMCChatAPI {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sends a chat message to Minecraft
|
||||
* Sends a chat message to Minecraft. Make sure that the channel is registered with {@link #RegisterChatChannel(Channel)}.
|
||||
*
|
||||
* @param channel
|
||||
* The channel to send to
|
||||
|
@ -210,8 +218,35 @@ public class TBMCChatAPI {
|
|||
* @return The event cancelled state
|
||||
*/
|
||||
public static boolean SendChatMessage(Channel channel, CommandSender sender, String message) {
|
||||
TBMCChatEvent event = new TBMCChatEvent(sender, channel, message);
|
||||
if (!Channel.getChannels().contains(channel))
|
||||
throw new RuntimeException("Channel " + channel.DisplayName + " not registered!");
|
||||
TBMCChatPreprocessEvent eventPre = new TBMCChatPreprocessEvent(sender, channel, message);
|
||||
Bukkit.getPluginManager().callEvent(eventPre);
|
||||
if (eventPre.isCancelled())
|
||||
return true;
|
||||
int score;
|
||||
if (channel.filteranderrormsg == null)
|
||||
score = -1;
|
||||
else {
|
||||
RecipientTestResult result = channel.filteranderrormsg.apply(sender);
|
||||
if (result.errormessage != null) {
|
||||
sender.sendMessage("§c" + result.errormessage);
|
||||
return true;
|
||||
}
|
||||
score = result.score;
|
||||
}
|
||||
TBMCChatEvent event = new TBMCChatEvent(sender, channel, eventPre.getMessage(), score);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
return event.isCancelled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a chat channel. See {@link Channel#Channel(String, Color, String, java.util.function.Function)} for details.
|
||||
*
|
||||
* @param channel
|
||||
* A new {@link Channel} to register
|
||||
*/
|
||||
public static void RegisterChatChannel(Channel channel) {
|
||||
Channel.RegisterChannel(channel);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package buttondevteam.lib.chat;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javassist.Modifier;
|
||||
|
||||
/**
|
||||
* Extend this class to create new TBMCCommand and use {@link TBMCChatAPI#AddCommand(org.bukkit.plugin.java.JavaPlugin, TBMCCommandBase)} to add it. <u><b>Note:</b></u> The command path (command name
|
||||
* and subcommand arguments) will be the class name by default, removing any "command" from it. To change it (especially for subcommands), override {@link #GetCommandPath()}.
|
||||
* and subcommand arguments) will be the class name by default, removing any "command" from it. To change it (especially for subcommands), use the path field in the {@link CommandClass} annotation.
|
||||
*
|
||||
* @author Norbi
|
||||
*
|
||||
|
@ -13,41 +17,64 @@ import org.bukkit.plugin.Plugin;
|
|||
public abstract class TBMCCommandBase {
|
||||
|
||||
public TBMCCommandBase() {
|
||||
path = getcmdpath();
|
||||
}
|
||||
|
||||
public abstract boolean OnCommand(CommandSender sender, String alias, String[] args);
|
||||
|
||||
public abstract String[] GetHelpText(String alias);
|
||||
|
||||
private String path = null;
|
||||
|
||||
/**
|
||||
* The command's path, or name if top-level command.<br>
|
||||
* For example:<br>
|
||||
* "u admin updateplugin" or "u" for the top level one<br>
|
||||
* <u>The path must be lowercase!</u><br>
|
||||
* <b>Abstract classes with no {@link CommandClass} annotations will be ignored.</b>
|
||||
*
|
||||
* @return The command path, <i>which is the command class name by default</i> (removing any "command" from it)
|
||||
* @return The command path, <i>which is the command class name by default</i> (removing any "command" from it) - Change via the {@link CommandClass} annotation
|
||||
*/
|
||||
public String GetCommandPath() {
|
||||
return getClass().getSimpleName().toLowerCase().replace("command", "");
|
||||
public final String GetCommandPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the command can only be used as a player, or command blocks or the console can use it as well.
|
||||
*
|
||||
* @return If the command is player only
|
||||
*/
|
||||
public abstract boolean GetPlayerOnly();
|
||||
|
||||
/**
|
||||
* Determines whether the command can only be used by mods or regular players can use it as well.
|
||||
*
|
||||
* @return If the command is mod only
|
||||
*/
|
||||
public abstract boolean GetModOnly();
|
||||
private final String getcmdpath() {
|
||||
if (!getClass().isAnnotationPresent(CommandClass.class))
|
||||
throw new RuntimeException(
|
||||
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
|
||||
Function<Class<?>, String> getFromClass = cl -> cl.getSimpleName().toLowerCase().replace("commandbase", "") // <-- ...
|
||||
.replace("command", "");
|
||||
String path = getClass().getAnnotation(CommandClass.class).path(),
|
||||
prevpath = path = path.length() == 0 ? getFromClass.apply(getClass()) : path;
|
||||
for (Class<?> cl = getClass().getSuperclass(); cl != null
|
||||
&& !cl.getPackage().getName().equals(TBMCCommandBase.class.getPackage().getName()); cl = cl
|
||||
.getSuperclass()) { //
|
||||
String newpath;
|
||||
if (!cl.isAnnotationPresent(CommandClass.class)
|
||||
|| (newpath = cl.getAnnotation(CommandClass.class).path()).length() == 0
|
||||
|| newpath.equals(prevpath)) {
|
||||
if (Modifier.isAbstract(cl.getModifiers()) && (!cl.isAnnotationPresent(CommandClass.class))
|
||||
|| cl.getAnnotation(CommandClass.class).excludeFromPath()) // <--
|
||||
continue;
|
||||
newpath = getFromClass.apply(cl);
|
||||
}
|
||||
path = (prevpath = newpath) + " " + path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
Plugin plugin; // Used By TBMCChatAPI
|
||||
|
||||
public final Plugin getPlugin() { // Used by CommandCaller (ButtonChat)
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public final boolean isPlayerOnly() {
|
||||
return this instanceof PlayerCommandBase ? true
|
||||
: this instanceof OptionallyPlayerCommandBase
|
||||
? getClass().isAnnotationPresent(OptionallyPlayerCommandClass.class)
|
||||
? getClass().getAnnotation(OptionallyPlayerCommandClass.class).playerOnly() : true
|
||||
: false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.bukkit.Bukkit;
|
|||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
|
||||
@ChromaGamerEnforcer
|
||||
public abstract class ChromaGamerBase implements AutoCloseable {
|
||||
public static final String TBMC_PLAYERS_DIR = "TBMC/players/";
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package buttondevteam.lib.player;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@Target(ElementType.TYPE)
|
||||
@Inherited
|
||||
public @interface ChromaGamerEnforcer {
|
||||
|
||||
}
|
|
@ -74,17 +74,14 @@ public abstract class TBMCPlayerBase extends ChromaGamerBase {
|
|||
public static <T extends TBMCPlayerBase> T getPlayer(UUID uuid, Class<T> cl) {
|
||||
if (playermap.containsKey(uuid + "-" + cl.getSimpleName()))
|
||||
return (T) playermap.get(uuid + "-" + cl.getSimpleName());
|
||||
// System.out.println("A");
|
||||
try {
|
||||
T player;
|
||||
if (playermap.containsKey(uuid + "-" + TBMCPlayer.class.getSimpleName())) {
|
||||
// System.out.println("B"); - Don't program when tired
|
||||
player = cl.newInstance();
|
||||
player.plugindata = playermap.get(uuid + "-" + TBMCPlayer.class.getSimpleName()).plugindata;
|
||||
playermap.put(uuid + "-" + cl.getSimpleName(), player); // It will get removed on player quit
|
||||
} else
|
||||
player = ChromaGamerBase.getUser(uuid.toString(), cl);
|
||||
// System.out.println("C");
|
||||
player.uuid = uuid;
|
||||
return player;
|
||||
} catch (Exception e) {
|
||||
|
|
Loading…
Reference in a new issue