Add per-path build numbers. Activate BlockChangeTRacker by default.

This commit is contained in:
asofold 2016-11-26 14:16:08 +01:00
parent 206d627e9b
commit 5939e1e206
5 changed files with 161 additions and 67 deletions

View File

@ -62,7 +62,11 @@ public abstract class ConfPaths {
public static final String SAVEBACKCONFIG = "savebackconfig";
// Configuration version.
@GlobalConfig // TODO: Per file versions should also be supported. Better with per-path comparison?
/*
* NOTE: The configuration allows setLastChangeBuildNumber(path), however
* some of these settings are still needed for that.
*/
@GlobalConfig // TODO: Per file versions should also be supported.
public static final String CONFIGVERSION = "configversion.";
public static final String CONFIGVERSION_NOTIFY = CONFIGVERSION + "notify";
/** Build number of the build for which the default config was first created (DefaultConfig.buildNumber), updated with first save. */

View File

@ -87,6 +87,7 @@ public class ConfigManager {
* with the NoCheatPlusAPI using the annotation SetupOrder with a higher negative value (-1000, see INotifyReload javadoc).
* @param factory
*/
// TODO: Register at GenericInstanceRegistry instead, store a handle at best (get rid of 'the other' static registries).
public static void setActionFactoryFactory(ActionFactoryFactory factory){
if (factory != null){
actionFactoryFactory = factory;
@ -203,9 +204,10 @@ public class ConfigManager {
LinkedHashMap<String, ConfigFile> newWorldsMap = new LinkedHashMap<String, ConfigFile>();
// Try to obtain and parse the global configuration file.
final File globalFile = new File(plugin.getDataFolder(), "config.yml");
final ConfigFile defaultConfig = new DefaultConfig();
PathUtils.processPaths(globalFile, "global config", false);
final ConfigFile globalConfig = new ConfigFile();
globalConfig.setDefaults(new DefaultConfig());
globalConfig.setDefaults(defaultConfig);
globalConfig.options().copyDefaults(true);
if (globalFile.exists()){
try {

View File

@ -30,9 +30,8 @@ import fr.neatmonster.nocheatplus.compat.BridgeMisc;
public class DefaultConfig extends ConfigFile {
/**
* NCP build number, for which an existing entry has been changed. (Should
* only increment, if the user is advised to change to that value instead of
* the former default one.)
* NCP build number, for which fundamental changes have been made. With
* setLastChangeBuildNumber, it's possible to do this on a per-value basis.
*/
public static final int buildNumber = 785;
@ -612,7 +611,7 @@ public class DefaultConfig extends ConfigFile {
)) {
set(ConfPaths.COMPATIBILITY_BLOCKS + ConfPaths.SUB_OVERRIDEFLAGS + "." + mat.name().toLowerCase(), "default+ign_passable+ground_height");
}
set(ConfPaths.COMPATIBILITY_BLOCKS_CHANGETRACKER_ACTIVE, false); // TODO: Activate once it really works?
set(ConfPaths.COMPATIBILITY_BLOCKS_CHANGETRACKER_ACTIVE, true, 1036); // With lastChangedBuildNumber.
set(ConfPaths.COMPATIBILITY_BLOCKS_CHANGETRACKER_PISTONS, true);
set(ConfPaths.COMPATIBILITY_BLOCKS_CHANGETRACKER_MAXAGETICKS, 80);
set(ConfPaths.COMPATIBILITY_BLOCKS_CHANGETRACKER_PERWORLD_MAXENTRIES, 1000);

View File

@ -16,6 +16,7 @@ package fr.neatmonster.nocheatplus.config;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -85,6 +86,9 @@ public class RawConfigFile extends YamlConfiguration{
// Not static.
////////////////
/** Meta data: The build number of the last significant change of a value. */
protected final Map<String, Integer> lastChangedBuildNumbers = new HashMap<String, Integer>();
/**
* Set a value depending on the detected Minecraft version.
* @param path
@ -321,4 +325,42 @@ public class RawConfigFile extends YamlConfiguration{
return super.saveToString();
}
/**
* Short cut to set a value and the last changed build number.
* <hr>
* Performs set(path, value) and setLastChangedBuildNumber(path,
* lastChangedBuildNumber).
*
* @param path
* @param value
* @param lastChangedBuildNumber
*/
public void set(String path, Object value, int lastChangedBuildNumber) {
set(path, value);
setLastChangedBuildNumber(path, lastChangedBuildNumber);
}
/**
* Set the build number at which a fundamental change of a value has
* happened (thus keeping an old value could be a problem).
*
* @param path
* @param value
*/
public void setLastChangedBuildNumber(String path, int value) {
lastChangedBuildNumbers.put(path, value);
}
/**
* Get the entire map of path -> last changed build number.
* <hr>
* Note that querying individual paths is not yet supported, as there may be
* different ways of handling parent/child node relations with this.
*
* @return
*/
public Map<String, Integer> getLastChangedBuildNumbers() {
return lastChangedBuildNumbers;
}
}

View File

@ -14,21 +14,34 @@
*/
package fr.neatmonster.nocheatplus.updates;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.configuration.ConfigurationSection;
import fr.neatmonster.nocheatplus.config.ConfPaths;
import fr.neatmonster.nocheatplus.config.ConfigFile;
import fr.neatmonster.nocheatplus.config.DefaultConfig;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
public class Updates {
/**
*
* @param config
* @param globalConfig
* @return null if everything is fine, a string with a message stating problems otherwise.
*/
public static String isConfigUpToDate(ConfigFile config){
Object created = config.get(ConfPaths.CONFIGVERSION_CREATED);
if (created != null && created instanceof Integer){
int buildCreated = ((Integer) created).intValue();
public static String isConfigUpToDate(ConfigFile globalConfig) {
Object created_o = globalConfig.get(ConfPaths.CONFIGVERSION_CREATED);
int buildCreated = -1;
if (created_o != null && created_o instanceof Integer) {
buildCreated = ((Integer) created_o).intValue();
}
if (buildCreated < 0) {
return null;
}
if (buildCreated < DefaultConfig.buildNumber) {
// Potentially outdated Configuration.
return "Your configuration might be outdated.\n" + "Some settings could have changed, you should regenerate it!";
@ -37,11 +50,41 @@ public class Updates {
// Installed an older version of NCP.
return "Your configuration seems to be created by a newer plugin version.\n" + "Some settings could have changed, you should regenerate it!";
}
else{
return null;
// So far so good... test individual paths.
final List<String> problems = new LinkedList<String>();
final ConfigFile defaultConfig = new DefaultConfig();
final Map<String, Integer> lastChangedBuildNumbers = defaultConfig.getLastChangedBuildNumbers();
int maxBuild = DefaultConfig.buildNumber;
// TODO: Consider some behavior for entire nodes ?
for (final Entry<String, Integer> entry : lastChangedBuildNumbers.entrySet()) {
final int defaultBuild = entry.getValue();
if (defaultBuild <= buildCreated) {
// Ignore, might've been changed on purpose.
continue;
}
final String path = entry.getKey();
final Object defaultValue = defaultConfig.get(path);
if (defaultValue instanceof ConfigurationSection) {
problems.add("Changed with build " + defaultBuild + ", can not handle entire configuration sections yet: " + path);
continue;
}
final Object currentValue = globalConfig.get(path);
if (currentValue == null || defaultValue == null) {
// To be handled elsewhere (@Moved / whatever).
continue;
}
if (defaultBuild > buildCreated && !defaultValue.equals(currentValue)) {
problems.add("Changed with build " + defaultBuild + ": " + path);
maxBuild = Math.max(defaultBuild, maxBuild);
continue;
}
}
// Error or not: could not determine versions, thus ignore.
if (!problems.isEmpty()) {
problems.add(0, "The following configuration default values have changed:");
problems.add("(Remove/update individual values or set configversion.created to " + maxBuild + " to ignore all, then reload the configuration with the 'ncp reload' command.)");
return StringUtil.join(problems, "\n");
}
// No errors could be determined (or versions coudl not be determined): ignore.
return null;
}
@ -63,13 +106,17 @@ public class Updates {
// connection.setReadTimeout(2 * updateTimeout);
// bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
// String line, content = "";
// while ((line = bufferedReader.readLine()) != null)
// while ((line = bufferedReader.readLine()) != null) {
// content += line;
// }
// final int jenkinsVersion = Integer.parseInt(content.split("\"number\":")[1].split(",")[0]);
// updateAvailable = currentVersion < jenkinsVersion;
// } catch (final Exception e) {}
// }
// catch (final Exception e) {}
// finally {
// if (bufferedReader != null) try{bufferedReader.close();}catch (IOException e){};
// if (bufferedReader != null) {
// try{bufferedReader.close();}catch (IOException e) {};
// }
// }
return updateAvailable;
}