Global config, config reload error check, fixes

TODO: Config load error check, remove Towny dep
#83
This commit is contained in:
Norbi Peti 2019-12-10 01:47:52 +01:00
parent fa18e8f22a
commit cecd8df991
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
9 changed files with 73 additions and 25 deletions

View file

@ -18,8 +18,6 @@
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <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="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: 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: com.google.code.findbugs:annotations:2.0.1" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.20.0-GA" level="project" /> <orderEntry type="library" name="Maven: org.javassist:javassist:3.20.0-GA" level="project" />

View file

@ -28,9 +28,12 @@ public class ComponentCommand extends ICommand2MC {
"Temporarily enables a component. If you want to permanently enable a component, change it's 'enabled' config option.\"" "Temporarily enables a component. If you want to permanently enable a component, change it's 'enabled' config option.\""
}) })
public boolean enable(CommandSender sender, Plugin plugin, String component) { public boolean enable(CommandSender sender, Plugin plugin, String component) {
if (plugin instanceof ButtonPlugin) if (plugin instanceof ButtonPlugin) {
((ButtonPlugin) plugin).justReload(); if (!((ButtonPlugin) plugin).justReload()) {
else sender.sendMessage("§cCouldn't reload config, check console.");
return true;
}
} else
plugin.reloadConfig(); //Reload config so the new config values are read - All changes are saved to disk on disable plugin.reloadConfig(); //Reload config so the new config values are read - All changes are saved to disk on disable
return enable_disable(sender, plugin, component, true); return enable_disable(sender, plugin, component, true);
} }

View file

@ -61,15 +61,25 @@ public class MainPlugin extends ButtonPlugin {
@Setter @Setter
private boolean chatHandlerEnabled = true; private boolean chatHandlerEnabled = true;
/**
* Sets whether the plugin should write a list of installed plugins in a txt file.
* It can be useful if some other software needs to know the plugins.
*/
private ConfigData<Boolean> writePluginList() { private ConfigData<Boolean> writePluginList() {
return getIConfig().getData("writePluginList", false); return getIConfig().getData("writePluginList", false);
} }
/**
* The chat format to use for messages from other platforms if Chroma-Chat is not installed.
*/
ConfigData<String> chatFormat() { ConfigData<String> chatFormat() {
return getIConfig().getData("chatFormat", "[{origin}|" + return getIConfig().getData("chatFormat", "[{origin}|" +
"{channel}] <{name}> {message}"); "{channel}] <{name}> {message}");
} }
/**
* Print some debug information.
*/
public ConfigData<Boolean> test() { public ConfigData<Boolean> test() {
return getIConfig().getData("test", false); return getIConfig().getData("test", false);
} }

View file

@ -1,5 +1,6 @@
package buttondevteam.lib.architecture; package buttondevteam.lib.architecture;
import buttondevteam.buttonproc.HasConfig;
import buttondevteam.core.ComponentManager; import buttondevteam.core.ComponentManager;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Command2MC; import buttondevteam.lib.chat.Command2MC;
@ -19,7 +20,7 @@ import java.util.Arrays;
import java.util.Optional; import java.util.Optional;
import java.util.Stack; import java.util.Stack;
@HasConfig @HasConfig(global = true)
public abstract class ButtonPlugin extends JavaPlugin { public abstract class ButtonPlugin extends JavaPlugin {
@Getter @Getter
private static Command2MC command2MC = new Command2MC(); private static Command2MC command2MC = new Command2MC();
@ -72,7 +73,8 @@ public abstract class ButtonPlugin extends JavaPlugin {
pluginPreDisable(); pluginPreDisable();
ComponentManager.unregComponents(this); ComponentManager.unregComponents(this);
pluginDisable(); pluginDisable();
saveConfig(); if (ConfigData.saveNow(getConfig()))
getLogger().info("Saved configuration changes.");
iConfig = null; //Clearing the hashmap is not enough, we need to update the section as well iConfig = null; //Clearing the hashmap is not enough, we need to update the section as well
TBMCChatAPI.RemoveCommands(this); TBMCChatAPI.RemoveCommands(this);
} catch (Exception e) { } catch (Exception e) {
@ -94,27 +96,31 @@ public abstract class ButtonPlugin extends JavaPlugin {
public boolean justReload() { public boolean justReload() {
if (yaml != null && ConfigData.saveNow(getConfig())) { if (yaml != null && ConfigData.saveNow(getConfig())) {
getLogger().warning("Saved pending configuration changes to the file, didn't reload (try again)."); getLogger().warning("Saved pending configuration changes to the file, didn't reload. Apply your changes again.");
return false; return false;
} }
yaml = new CommentedConfiguration(new File(getDataFolder(), "config.yml")); var file = new File(getDataFolder(), "config.yml");
yaml.load(); var yaml = new CommentedConfiguration(file);
if (file.exists() && !yaml.load()) {
getLogger().warning("Failed to load config! Check for syntax errors.");
return false;
}
this.yaml = yaml;
var res = getTextResource("configHelp.yml"); var res = getTextResource("configHelp.yml");
if (res == null) if (res == null)
return true; return true;
var yc = YamlConfiguration.loadConfiguration(res); var yc = YamlConfiguration.loadConfiguration(res);
for (var kv : yc.getValues(true).entrySet()) for (var kv : yc.getValues(true).entrySet())
if (kv.getValue() instanceof String) if (kv.getValue() instanceof String)
yaml.addComment(kv.getKey(), yaml.addComment(kv.getKey(), Arrays.stream(((String) kv.getValue()).split("\n"))
Arrays.stream(((String) kv.getValue()).split("\n")) .map(str -> "# " + str.trim()).toArray(String[]::new));
.map(str -> "# " + str.trim()).toArray(String[]::new));
return true; return true;
} }
@Override @Override
public FileConfiguration getConfig() { public FileConfiguration getConfig() {
if (yaml == null) if (yaml == null)
justReload(); justReload(); //TODO: If it fails to load, it'll probably throw an NPE
return yaml; return yaml;
} }

View file

@ -1,5 +1,6 @@
package buttondevteam.lib.architecture; package buttondevteam.lib.architecture;
import buttondevteam.buttonproc.HasConfig;
import buttondevteam.core.ComponentManager; import buttondevteam.core.ComponentManager;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException; import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
@ -22,7 +23,7 @@ import java.util.stream.Collectors;
/** /**
* Configuration is based on class name * Configuration is based on class name
*/ */
@HasConfig //Used for obtaining javadoc @HasConfig(global = false) //Used for obtaining javadoc
public abstract class Component<TP extends JavaPlugin> { public abstract class Component<TP extends JavaPlugin> {
private static HashMap<Class<? extends Component>, Component<? extends JavaPlugin>> components = new HashMap<>(); private static HashMap<Class<? extends Component>, Component<? extends JavaPlugin>> components = new HashMap<>();
@ -141,7 +142,6 @@ public abstract class Component<TP extends JavaPlugin> {
//System.out.println("Done enabling "+component.getClassName()); //System.out.println("Done enabling "+component.getClassName());
} else { } else {
component.disable(); component.disable();
component.plugin.saveConfig();
TBMCChatAPI.RemoveCommands(component); TBMCChatAPI.RemoveCommands(component);
} }
} }

View file

@ -125,17 +125,29 @@ public class ConfigData<T> {
} }
private void setInternal(Object val) { private void setInternal(Object val) {
/*//if (path.contains("Channel")) {
System.out.println("Setting value: " + val);
System.out.println("For path: " + path);
if(path.contains("tc.enabled"))
new Exception("Why does this get set on a reload?").printStackTrace();*/
config.set(path, val); config.set(path, val);
if (!saveTasks.containsKey(config.getRoot())) { if (!saveTasks.containsKey(config.getRoot())) {
/*//if (path.contains("Channel"))
System.out.println("No save task found, adding new one");*/
synchronized (saveTasks) { synchronized (saveTasks) {
saveTasks.put(config.getRoot(), new SaveTask(Bukkit.getScheduler().runTaskLaterAsynchronously(MainPlugin.Instance, () -> { saveTasks.put(config.getRoot(), new SaveTask(Bukkit.getScheduler().runTaskLaterAsynchronously(MainPlugin.Instance, () -> {
/*//if (path.contains("Channel"))
System.out.println("Executing save task...");*/
synchronized (saveTasks) { synchronized (saveTasks) {
saveTasks.remove(config.getRoot()); saveTasks.remove(config.getRoot());
saveAction.run(); saveAction.run();
} }
/*//if (path.contains("Channel"))
System.out.println("Save task done");*/
}, 100), saveAction)); }, 100), saveAction));
} }
} } /*else //if (path.contains("Channel")) - The answer is... The chat plugin goes through the chat channels on command preprocess
System.out.println("Found a save task");*/
} }
@AllArgsConstructor @AllArgsConstructor
@ -145,12 +157,14 @@ public class ConfigData<T> {
} }
public static boolean saveNow(Configuration config) { public static boolean saveNow(Configuration config) {
SaveTask st = saveTasks.get(config); synchronized (saveTasks) {
if (st != null) { SaveTask st = saveTasks.get(config);
st.task.cancel(); if (st != null) {
saveTasks.remove(config); st.task.cancel();
st.saveAction.run(); saveTasks.remove(config);
return true; st.saveAction.run();
return true;
}
} }
return false; return false;
} }

View file

@ -144,6 +144,17 @@ public abstract class Command2<TC extends ICommand2, TP extends Command2Sender>
} }
//Needed because permission checking may load the (perhaps offline) sender's file which is disallowed on the main thread //Needed because permission checking may load the (perhaps offline) sender's file which is disallowed on the main thread
/**
* Handles a command asynchronously
*
* @param sender The command sender
* @param commandline The command line the sender sent
* @param sd The subcommand data
* @param subcommand The subcommand text
* @param sync Whether the command was originally sync
* @throws Exception If something's not right
*/
public void handleCommandAsync(TP sender, String commandline, SubcommandData<TC> sd, String subcommand, boolean sync) throws Exception { public void handleCommandAsync(TP sender, String commandline, SubcommandData<TC> sd, String subcommand, boolean sync) throws Exception {
if (sd.method == null || sd.command == null) { //Main command not registered, but we have subcommands if (sd.method == null || sd.command == null) { //Main command not registered, but we have subcommands
sender.sendMessage(sd.helpText); sender.sendMessage(sd.helpText);

View file

@ -34,7 +34,12 @@ public class ConfigProcessor {
public void process(Element targetcl) { public void process(Element targetcl) {
if (targetcl.getModifiers().contains(Modifier.ABSTRACT)) return; if (targetcl.getModifiers().contains(Modifier.ABSTRACT)) return;
final String path = "components." + targetcl.getSimpleName(); HasConfig hasConfig = targetcl.getAnnotation(HasConfig.class);
if (hasConfig == null) {
System.out.println("That's not our HasConfig annotation...");
return;
}
final String path = hasConfig.global() ? "global" : "components." + targetcl.getSimpleName();
File file = new File(fo.toUri()); File file = new File(fo.toUri());
try { try {
if (file.exists()) if (file.exists())

View file

@ -1,4 +1,4 @@
package buttondevteam.lib.architecture; package buttondevteam.buttonproc;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited; import java.lang.annotation.Inherited;
@ -10,4 +10,5 @@ import java.lang.annotation.Target;
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Inherited @Inherited
public @interface HasConfig { public @interface HasConfig {
boolean global();
} }