Global config, config reload error check, fixes
TODO: Config load error check, remove Towny dep #83
This commit is contained in:
parent
fa18e8f22a
commit
cecd8df991
9 changed files with 73 additions and 25 deletions
|
@ -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" />
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
Loading…
Reference in a new issue