Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6719950
Depent on SimpleConfig
HeatherComputer Feb 20, 2025
decabfe
Remote existing ConfigTypes
HeatherComputer Feb 20, 2025
86e2fe1
Refactor the ConfigManager.
HeatherComputer Feb 20, 2025
b4e14fb
Compatability changes to work with the new system
HeatherComputer Feb 20, 2025
22cd565
Forgot registration!
HeatherComputer Feb 20, 2025
1ae14fa
and this a needs to be capitalised. legacy shit, should probably chan…
HeatherComputer Feb 20, 2025
6a907d1
ClientConfigManager refactor, and its core changes.
HeatherComputer Feb 20, 2025
a8d6aca
Small cleanup that makes registration cleaner
HeatherComputer Feb 20, 2025
3a0168a
Relocate better
HeatherComputer Feb 22, 2025
75ac33f
This should bring in fabric 1.18 support. testing atm
HeatherComputer Mar 2, 2025
1ff42c4
Fabric 1.19.2
HeatherComputer Mar 3, 2025
3255169
Fabric 1.19.3
HeatherComputer Mar 3, 2025
1bd3696
and fabric 1.20
HeatherComputer Mar 17, 2025
769ba96
And this is 1.20.2 fabric!
HeatherComputer Mar 17, 2025
147a02a
And this is 1.20.6 fabric!
HeatherComputer Mar 17, 2025
f011f91
And this is 1.21 fabric
HeatherComputer Mar 17, 2025
c8bea29
And this is 1.21.2 fabric
HeatherComputer Mar 17, 2025
6bcb794
This is forge 1.7.10.. I forgot how much work this could be lmao
HeatherComputer Mar 17, 2025
15634c9
forge 1.12.2
HeatherComputer Mar 28, 2025
22e3365
support config refactor for 1.16 forge, and whilst i'm at it support …
HeatherComputer Apr 9, 2025
f1704fd
refactor 1.18 forge
HeatherComputer Apr 9, 2025
4d0ccf9
Config refactor for 1.19.2 forge
HeatherComputer May 9, 2025
b5edc1a
Config refactor forge 1.19.3
HeatherComputer May 12, 2025
a35b393
Config refactor for forge 1.20
HeatherComputer Jun 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,20 @@ println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty '
// Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' }

tasks.named('shadowJar', ShadowJar) {
relocate('computer.heather.simpleconfig', 'shadow/advancedbackups/simpleconfig')
relocate('org.fusesource.jansi', 'shadow/advancedbackups/jansi')
archiveClassifier.set('')
}

repositories {
// These repositories are only for Gradle plugins, put any other repositories in the repository block further below
mavenCentral()
}
maven {
name "heatherComputer"
url "https://maven.heather.computer/public"
}

tasks.named('shadowJar', ShadowJar) {
enableRelocation true
archiveClassifier.set('')
}

dependencies {
Expand All @@ -50,6 +55,9 @@ dependencies {
//extraLibs 'com.sun.jna.platform:5.13.0'
compileOnly 'com.google.code.gson:gson:2.10.1'
implementation 'org.fusesource.jansi:jansi:2.4.0'
//The + allows us to pin to the latest version. This is fine and useful.
implementation "computer.heather:SimpleConfig:+"


// Real mod deobf dependency examples - these get remapped to your current mappings
// compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency
Expand All @@ -70,11 +78,11 @@ jar {
attributes([
"Main-Class" : "computer.heather.advancedbackups.cli.AdvancedBackupsCLI",
"Specification-Title" : "advancedbackups",
"Specification-Vendor" : "raveninthedark",
"Specification-Vendor" : "heathercomputer",
"Specification-Version" : "1", // We are version 1 of ourselves
"Implementation-Title" : project.name,
"Implementation-Version" : project.jar.archiveVersion,
"Implementation-Vendor" : "raveninthedark",
"Implementation-Vendor" : "heathercomputer",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
])
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.util.function.Consumer;

Expand All @@ -35,13 +36,13 @@ public static void startBackup(Consumer<String> chat) {
BackupWrapper.makeSingleBackup(0, chat, false);
}

public static void reloadConfig(Consumer<String> chat) {
public static void reloadConfig(Consumer<String> chat) throws IOException {
chat.accept("Reloading config...");
ConfigManager.loadOrCreateConfig();
chat.accept("Done!");
}

public static void reloadClientConfig(Consumer<String> chat) {
public static void reloadClientConfig(Consumer<String> chat) throws IOException {
chat.accept("Reloading client config...");
ClientConfigManager.loadOrCreateConfig();
chat.accept("Done!");
Expand All @@ -66,8 +67,8 @@ public static void resetChainLength(Consumer<String> chat) {
try {
BackupManifest manifest = gson.fromJson(new String(Files.readAllBytes(backupManifest.toPath())), BackupManifest.class);

manifest.incremental.chainLength += (int) ConfigManager.length.get();
manifest.differential.chainLength += (int) ConfigManager.length.get();
manifest.incremental.chainLength += ConfigManager.length.get().intValue();
manifest.differential.chainLength += ConfigManager.length.get().intValue();


FileWriter writer = new FileWriter(backupManifest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ private void makeZipBackup(File file, boolean b) throws InterruptedException, IO
this.output.accept("Preparing " + (this.snapshot ? "snapshot" : "zip") + " backup with name:\n " + zip.getName().replace("incomplete", this.snapshot ? snapshotName : "backup"));
FileOutputStream outputStream = new FileOutputStream(zip);
ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
zipOutputStream.setLevel((int) ConfigManager.compression.get());
zipOutputStream.setLevel(ConfigManager.compression.get().intValue());

ArrayList<Path> paths = new ArrayList<>();

Expand Down Expand Up @@ -227,7 +227,7 @@ public FileVisitResult visitFileFailed(Path path, IOException exc) {
continue;
}
zipOutputStream.putNextEntry(new ZipEntry(targetFile.toString()));
byte[] bytes = new byte[(int) ConfigManager.buffer.get()];
byte[] bytes = new byte[ConfigManager.buffer.get().intValue()];
try {
FileInputStream is = new FileInputStream(sourceFile);
while (true) {
Expand Down Expand Up @@ -378,7 +378,7 @@ public FileVisitResult visitFileFailed(Path path, IOException exc) {
File zip = differential ? new File(location.toString() + "/differential/", backupName + ".zip") : new File(location.toString() + "/incremental/", backupName + ".zip");
FileOutputStream outputStream = new FileOutputStream(zip);
ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
zipOutputStream.setLevel((int) ConfigManager.compression.get());
zipOutputStream.setLevel(ConfigManager.compression.get().intValue());

int max = toBackup.size();
int index = 0;
Expand All @@ -402,7 +402,7 @@ public FileVisitResult visitFileFailed(Path path, IOException exc) {
}
zipOutputStream.putNextEntry(new ZipEntry(path.toString()));

byte[] bytes = new byte[(int) ConfigManager.buffer.get()];
byte[] bytes = new byte[ConfigManager.buffer.get().intValue()];
try {
FileInputStream is = new FileInputStream(sourceFile);
while (true) {
Expand Down Expand Up @@ -523,7 +523,7 @@ public void shutdown() {
private String getFileHash(Path path) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] data = new byte[(int) ConfigManager.buffer.get()];
byte[] data = new byte[ConfigManager.buffer.get().intValue()];
FileInputStream is = new FileInputStream(path.toFile());
while (true) {
int i = is.read(data);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,136 +1,106 @@
package computer.heather.advancedbackups.core.config;

import computer.heather.advancedbackups.core.ABCore;
import computer.heather.advancedbackups.core.config.ConfigTypes.BooleanValue;
import computer.heather.advancedbackups.core.config.ConfigTypes.ConfigValidationEnum;
import computer.heather.advancedbackups.core.config.ConfigTypes.LongValue;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import computer.heather.simpleconfig.exceptions.validation.BaseValidationException;
import computer.heather.simpleconfig.exceptions.validation.MissingOptionException;
import computer.heather.simpleconfig.exceptions.validation.MissingValueException;
import computer.heather.simpleconfig.managers.PremadePropertiesManager;
import computer.heather.simpleconfig.types.BaseConfigType;
import computer.heather.simpleconfig.types.BooleanValue;
import computer.heather.simpleconfig.types.LongValue;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
import java.util.stream.Collectors;

public class ClientConfigManager {

private static HashMap<String, ConfigTypes> entries = new HashMap<>();


public static void register(String key, ConfigTypes configType) {
entries.put(key, configType);
}

public static final BooleanValue showProgress = new BooleanValue("config.advancedbackups.showProgress", true);

public static final BooleanValue showProgress = new BooleanValue("config.advancedbackups.showProgress", true, ClientConfigManager::register);
public static final BooleanValue darkMode = new BooleanValue("config.advancedbackups.darkToasts", true);

public static final BooleanValue darkMode = new BooleanValue("config.advancedbackups.darkToasts", true, ClientConfigManager::register);
public static final LongValue progressTextRed = new LongValue("config.advancedbackups.colours.progress.red", 82, 0, 255);
public static final LongValue progressTextGreen = new LongValue("config.advancedbackups.colours.progress.green", 255, 0, 255);
public static final LongValue progressTextBlue = new LongValue("config.advancedbackups.colours.progress.blue", 82, 0, 255);

public static final LongValue progressTextRed = new LongValue("config.advancedbackups.colours.progress.red", 82, 0, 255, ClientConfigManager::register);
public static final LongValue progressTextGreen = new LongValue("config.advancedbackups.colours.progress.green", 255, 0, 255, ClientConfigManager::register);
public static final LongValue progressTextBlue = new LongValue("config.advancedbackups.colours.progress.blue", 82, 0, 255, ClientConfigManager::register);
public static final LongValue errorTextRed = new LongValue("config.advancedbackups.colours.error.red", 255, 0, 255);
public static final LongValue errorTextGreen = new LongValue("config.advancedbackups.colours.error.green", 50, 0, 255);
public static final LongValue errorTextBlue = new LongValue("config.advancedbackups.colours.error.blue", 50, 0, 255);

public static final LongValue errorTextRed = new LongValue("config.advancedbackups.colours.error.red", 255, 0, 255, ClientConfigManager::register);
public static final LongValue errorTextGreen = new LongValue("config.advancedbackups.colours.error.green", 50, 0, 255, ClientConfigManager::register);
public static final LongValue errorTextBlue = new LongValue("config.advancedbackups.colours.error.blue", 50, 0, 255, ClientConfigManager::register);
public static final LongValue progressBarRed = new LongValue("config.advancedbackups.colours.bar.red", 88, 0, 255);
public static final LongValue progressBarGreen = new LongValue("config.advancedbackups.colours.bar.green", 242, 0, 255);
public static final LongValue progressBarBlue = new LongValue("config.advancedbackups.colours.bar.blue", 82, 0, 255);

public static final LongValue progressBarRed = new LongValue("config.advancedbackups.colours.bar.red", 88, 0, 255, ClientConfigManager::register);
public static final LongValue progressBarGreen = new LongValue("config.advancedbackups.colours.bar.green", 242, 0, 255, ClientConfigManager::register);
public static final LongValue progressBarBlue = new LongValue("config.advancedbackups.colours.bar.blue", 82, 0, 255, ClientConfigManager::register);
public static final LongValue progressBackgroundRed = new LongValue("config.advancedbackups.colours.background.red", 255, 0, 255);
public static final LongValue progressBackgroundGreen = new LongValue("config.advancedbackups.colours.background.green", 255, 0, 255);
public static final LongValue progressBackgroundBlue = new LongValue("config.advancedbackups.colours.background.blue", 255, 0, 255);

public static final LongValue progressBackgroundRed = new LongValue("config.advancedbackups.colours.background.red", 255, 0, 255, ClientConfigManager::register);
public static final LongValue progressBackgroundGreen = new LongValue("config.advancedbackups.colours.background.green", 255, 0, 255, ClientConfigManager::register);
public static final LongValue progressBackgroundBlue = new LongValue("config.advancedbackups.colours.background.blue", 255, 0, 255, ClientConfigManager::register);

//Make the manager. Chaining!
private static final PremadePropertiesManager MANAGER = new PremadePropertiesManager()
.setConfigLocation(Paths.get("config/Advancedbackups-client.properties"))
.setPremadeLocation("advancedbackups-client-properties.txt")
.register(
showProgress, darkMode,
progressTextRed, progressTextGreen, progressTextBlue,
errorTextRed, errorTextGreen, errorTextBlue,
progressBarRed, progressBarGreen, progressBarBlue,
progressBackgroundRed, progressBackgroundGreen, progressBackgroundBlue
);


public static void loadOrCreateConfig() {
// Called when the config needs to be loaded, but one may not exist.
// Creates a new config it one doesn't exist, then loads it.
File dir = new File("./config");
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, "AdvancedBackups-client.properties");
if (!file.exists()) {
writeConfig();
public static void loadOrCreateConfig() throws IOException {
ArrayList<String> missingProperties = new ArrayList<>();
ArrayList<String> erroringProperties = new ArrayList<>();
try {
MANAGER.loadOrCreate((configType, value, exception) -> {
//MissingOptionException is used for config types that don't exist in code. This means we can migrate stuff.
if (exception instanceof MissingOptionException) {
handleMigration(configType, value);
}
else if (exception instanceof MissingValueException) {
missingProperties.add(configType.getKey());
}
else {
erroringProperties.add(configType.getKey() + exception);
}
});
} catch (IOException e) {
ABCore.errorLogger.accept("Failed to load config! Cannot proceed due to IO error.");
throw e;
} catch (BaseValidationException e) {
// Nothing to do here. This catch will never trigger.
}
loadConfig();
}

private static void writeConfig() {
// Called to write to a config file.
// Create a complete properties file in the cwd, including any existing changes
ABCore.infoLogger.accept("Preparing to write to client properties file...");
File file = new File("./config/AdvancedBackups-client.properties");
try {
file.createNewFile();
file.setWritable(true);
InputStream is = ClientConfigManager.class.getClassLoader().getResourceAsStream("advancedbackups-client-properties.txt");

String text = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))
.lines().collect(Collectors.joining("\n"));
//We use this flat just so we can ensure the final error message is only logged once.
boolean flag = false;

for (String key : entries.keySet()) {
text = text.replace(key, key + "=" + entries.get(key).save());
//Now, we have loaded and created with our error handler. But let's make sure we log missing options properly!
if (!missingProperties.isEmpty()) {
flag = true;
ABCore.warningLogger.accept("The following options were missing from the loaded file :");
for (String string : missingProperties) {
ABCore.warningLogger.accept(string);
}

FileWriter writer = new FileWriter(file);
writer.write(text);
writer.close();
} catch (IOException e) {
// TODO : Scream to user
ABCore.logStackTrace(e);
}
}


private static void loadConfig() {
//Load the config file.
Properties props = new Properties();
File file = new File("./config/AdvancedBackups-client.properties");
FileReader reader;
try {
reader = new FileReader(file);
props.load(reader);
reader.close();
} catch (IOException e) {
// TODO : Scream to user
ABCore.logStackTrace(e);
return;
//And now the same for erroring options.
if (!erroringProperties.isEmpty()) {
ABCore.warningLogger.accept("The following options failed to validate :");
for (String string : erroringProperties) {
ABCore.warningLogger.accept(string);
}
}

ArrayList<String> missingProps = new ArrayList<>();
if (flag) ABCore.warningLogger.accept("Client config file has been regenerated! Existing config values have been preserved.");
}

for (String key : entries.keySet()) {
if (!props.containsKey(key)) {
missingProps.add(key);
ABCore.warningLogger.accept("Missing key : " + key);
continue;
}
ConfigValidationEnum valid = entries.get(key).validate(props.getProperty(key));
if (valid != ConfigValidationEnum.VALID) {
missingProps.add(key);
ABCore.warningLogger.accept(valid.getError() + " : " + key);
continue;

}
entries.get(key).load(props.getProperty(key));
}

if (!missingProps.isEmpty()) {
ABCore.warningLogger.accept("The following properties were missing from the loaded file :");
for (String string : missingProps) {
ABCore.warningLogger.accept(string);
}
ABCore.warningLogger.accept("Client properties file will be regenerated! Existing config values will be preserved.");

writeConfig();
}
private static void handleMigration(BaseConfigType<?> configType, String value) {
//For now, do nothing! Migratory code from the past is unneeded now.
ABCore.warningLogger.accept("Discarding unused config option: " + configType.getKey() + " with value: " + value);
}
}
Loading