New command system improvements, broadcast toggles, config fixes #62

Merged
NorbiPeti merged 23 commits from dev into master 2019-03-17 01:27:43 +00:00
15 changed files with 141 additions and 27 deletions
Showing only changes of commit 9c15d0ffff - Show all commits

View file

@ -20,6 +20,8 @@ import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import com.earth2me.essentials.Essentials;
import lombok.Getter;
import lombok.Setter;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Bukkit;
@ -50,11 +52,23 @@ public class MainPlugin extends ButtonPlugin {
private Logger logger;
@Nullable
private Economy economy;
/**
* Whether the Core's chat handler should be enabled.
* Other chat plugins handling messages from other platforms should set this to false.
*/
@Getter
@Setter
private boolean chatHandlerEnabled = true;
private ConfigData<Boolean> writePluginList() {
return getIConfig().getData("writePluginList", false);
}
ConfigData<String> chatFormat() {
return getIConfig().getData("chatFormat", "[{origin}|" +
"{channel}] <{name}> {message}");
}
@Override
public void pluginEnable() {
// Logs "Plugin Enabled", registers commands

View file

@ -1,8 +1,6 @@
package buttondevteam.core;
import buttondevteam.lib.TBMCCommandPreprocessEvent;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.*;
import buttondevteam.lib.architecture.ButtonPlugin;
import buttondevteam.lib.chat.ChatMessage;
import buttondevteam.lib.chat.Command2MCSender;
@ -12,6 +10,7 @@ import buttondevteam.lib.player.TBMCPlayerBase;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@ -84,4 +83,21 @@ public class PlayerListener implements Listener {
//Not cancelling the original event here, it's cancelled in the chat plugin
//This way other plugins can deal with the MC formatting if the chat plugin isn't present, but other platforms still get the message
}
@EventHandler(priority = EventPriority.HIGH) //The one in the chat plugin is set to highest
public void onPlayerChat(TBMCChatEvent event) {
if (event.isCancelled())
return;
if (!MainPlugin.Instance.isChatHandlerEnabled()) return;
if (event.getOrigin().equals("Minecraft")) return; //Let other plugins handle MC messages
String msg = MainPlugin.Instance.chatFormat().get()
.replace("{channel}", event.getChannel().DisplayName().get())
.replace("{origin}", event.getOrigin().substring(0, 1))
.replace("{name}", ThorpeUtils.getDisplayName(event.getSender()))
.replace("{message}", event.getMessage());
for (Player player : Bukkit.getOnlinePlayers())
if (event.shouldSendTo(player))
player.sendMessage(msg);
Bukkit.getConsoleSender().sendMessage(msg);
}
}

View file

@ -4,8 +4,12 @@ import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.architecture.Component;
import org.bukkit.plugin.java.JavaPlugin;
/**
* Manages chat channels. If disabled, only global channels will be registered.
*/
public class ChannelComponent extends Component {
static TBMCSystemChatEvent.BroadcastTarget roomJoinLeave;
@Override
protected void register(JavaPlugin plugin) {
super.register(plugin);

View file

@ -14,11 +14,31 @@ import java.util.Date;
import static buttondevteam.core.MainPlugin.permission;
/**
* Allows giving a 'member' group over some time elapsed OR played.
*/
public class MemberComponent extends Component<MainPlugin> implements Listener {
/**
* The permission group to give to the player
*/
ConfigData<String> memberGroup() {
return getConfig().getData("memberGroup", "member");
}
/**
* The amount of hours needed to play before promotion
*/
private ConfigData<Integer> playedHours() {
return getConfig().getData("playedHours", 12);
}
/**
* The amount of days passed since first login
*/
private ConfigData<Integer> registeredForDays() {
return getConfig().getData("registeredForDays", 7);
}
@Override
protected void enable() {
registerListener(this);
@ -32,8 +52,8 @@ public class MemberComponent extends Component<MainPlugin> implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
if (permission != null && !permission.playerInGroup(event.getPlayer(), memberGroup().get())
&& (new Date(event.getPlayer().getFirstPlayed()).toInstant().plus(7, ChronoUnit.DAYS).isBefore(Instant.now())
|| event.getPlayer().getStatistic(Statistic.PLAY_ONE_TICK) > 20 * 3600 * 12)) {
&& (new Date(event.getPlayer().getFirstPlayed()).toInstant().plus(registeredForDays().get(), ChronoUnit.DAYS).isBefore(Instant.now())
|| event.getPlayer().getStatistic(Statistic.PLAY_ONE_TICK) > 20 * 3600 * playedHours().get())) {
permission.playerAddGroup(null, event.getPlayer(), memberGroup().get());
event.getPlayer().sendMessage("§bYou are a member now. YEEHAW");
MainPlugin.Instance.getLogger().info("Added " + event.getPlayer().getName() + " as a member.");

View file

@ -3,6 +3,10 @@ package buttondevteam.core.component.randomtp;
import buttondevteam.core.MainPlugin;
import buttondevteam.lib.architecture.Component;
/**
* Teleport player to random location within world border.
* Every five players teleport to the same general area, and then a new general area is randomly selected for the next five players.
*/
public class RandomTPComponent extends Component<MainPlugin> {
@Override
protected void enable() {

View file

@ -13,6 +13,9 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
/**
* Provides commands such as /schrestart (restart after a countdown) and /primerestart (restart when nobody is online)
*/
public class RestartComponent extends Component<MainPlugin> implements Listener {
@Override
public void enable() {

View file

@ -11,6 +11,9 @@ import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import org.bukkit.Bukkit;
/**
* Automatically renames Towny players if they changed their Minecraft name
*/
public class TownyComponent extends Component<MainPlugin> {
@Override
protected void enable() {

View file

@ -4,7 +4,10 @@ import buttondevteam.core.MainPlugin;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.TBMCChatAPI;
public class PluginUpdaterComponent extends Component<MainPlugin> {
/**
* Downloads plugin updates built from their source using JitPack - older code
*/
public class PluginUpdaterComponent extends Component<MainPlugin> { //TODO: Config
@Override
public void enable() {
TBMCChatAPI.AddCommand(this, new UpdatePluginCommand());

View file

@ -11,12 +11,15 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
/**
* Do not use (EULA)
*/
@RequiredArgsConstructor
public class VotifierComponent extends Component<MainPlugin> {
private final Economy economy;
private ConfigData<Double> rewardAmount() {
return getConfig().getData("rewardAmount", 50.0);
return getConfig().getData("rewardAmount", 0.0);
}
@Override

View file

@ -11,6 +11,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import java.util.Stack;
@HasConfig
public abstract class ButtonPlugin extends JavaPlugin {
@Getter
private static Command2MC command2MC = new Command2MC();

View file

@ -23,6 +23,7 @@ import java.util.stream.Collectors;
/**
* Configuration is based on class name
*/
@HasConfig //Used for obtaining javadoc
public abstract class Component<TP extends JavaPlugin> {
private static HashMap<Class<? extends Component>, Component<? extends JavaPlugin>> components = new HashMap<>();

View file

@ -8,5 +8,5 @@ import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentMetadata {
Class<? extends Component>[] depends();
Class<? extends Component>[] depends() default {};
}

View file

@ -0,0 +1,13 @@
package buttondevteam.lib.architecture;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Target;
/**
* Used to generate documentation for the config
*/
@Target(ElementType.TYPE)
@Inherited
public @interface HasConfig {
}

View file

@ -8,14 +8,11 @@ import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
@ -25,6 +22,8 @@ import java.util.stream.Collectors;
public class ButtonProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (configProcessor == null)
configProcessor = new ConfigProcessor(processingEnv);
for (TypeElement te : annotations) {
Set<? extends Element> classes = roundEnv.getElementsAnnotatedWith(te);
for (Element targetcl : classes) {
@ -47,6 +46,8 @@ public class ButtonProcessor extends AbstractProcessor {
//System.out.println("Type: " + type);
}
processSubcommands(targetcl, annotationMirrors);
if (hasAnnotation.apply("HasConfig"))
configProcessor.process(targetcl);
}
}
try {
@ -63,6 +64,7 @@ public class ButtonProcessor extends AbstractProcessor {
private YamlConfiguration yc = new YamlConfiguration();
private boolean found = false;
private ConfigProcessor configProcessor;
private void processSubcommands(Element targetcl, List<? extends AnnotationMirror> annotationMirrors) {
if (!(targetcl instanceof ExecutableElement))
@ -91,20 +93,4 @@ public class ButtonProcessor extends AbstractProcessor {
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
private String fetchSourcePath() {
try {
JavaFileObject generationForPath = processingEnv.getFiler().createSourceFile("PathFor" + getClass().getSimpleName());
Writer writer = generationForPath.openWriter();
String sourcePath = generationForPath.toUri().getPath();
writer.close();
generationForPath.delete();
return sourcePath;
} catch (IOException e) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, "Unable to determine source file path!");
}
return "";
}
}

View file

@ -0,0 +1,43 @@
package buttondevteam.buttonproc;
import org.bukkit.configuration.file.YamlConfiguration;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.File;
import java.io.IOException;
public class ConfigProcessor {
private final ProcessingEnvironment procEnv;
private final YamlConfiguration yaml;
private final File file;
public ConfigProcessor(ProcessingEnvironment procEnv) {
this.procEnv = procEnv;
FileObject file = null;
try {
file = procEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "config.yml");
} catch (IOException e) {
e.printStackTrace();
}
yaml = new YamlConfiguration();
this.file = new File(file.toUri());
}
public void process(Element targetcl) {
if (targetcl.getModifiers().contains(Modifier.ABSTRACT)) return;
String javadoc = procEnv.getElementUtils().getDocComment(targetcl);
if (javadoc == null) return;
System.out.println("JAVADOC"); //TODO: Config methods
System.out.println(javadoc);
yaml.set("components." + targetcl.getSimpleName() + "._doc", javadoc);
try {
yaml.save(file);
} catch (IOException e) {
e.printStackTrace();
}
}
}