diff --git a/Minosoft.iml b/Minosoft.iml
deleted file mode 100644
index 8bc82d596..000000000
--- a/Minosoft.iml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/java/de/bixilon/minosoft/Minosoft.java b/src/main/java/de/bixilon/minosoft/Minosoft.java
index af9501b33..67b9e18b6 100644
--- a/src/main/java/de/bixilon/minosoft/Minosoft.java
+++ b/src/main/java/de/bixilon/minosoft/Minosoft.java
@@ -50,9 +50,7 @@ import java.util.UUID;
public final class Minosoft {
public static final HashSet eventManagers = new HashSet<>();
private static final CountUpAndDownLatch startStatusLatch = new CountUpAndDownLatch(1);
- public static HashBiMap accountList;
public static MojangAccount selectedAccount;
- public static ArrayList serverList;
public static Configuration config;
public static void main(String[] args) {
@@ -112,8 +110,6 @@ public final class Minosoft {
// set log level from config
Log.setLevel(LogLevels.valueOf(config.getString(ConfigurationPaths.StringPaths.GENERAL_LOG_LEVEL)));
Log.info(String.format("Logging info with level: %s", Log.getLevel()));
-
- serverList = config.getServers();
progress.countDown();
}, "Configuration", String.format("Load config file (%s)", StaticConfiguration.CONFIG_FILENAME), Priorities.HIGHEST, TaskImportance.REQUIRED));
@@ -139,8 +135,7 @@ public final class Minosoft {
taskWorker.addTask(new Task(progress -> {
Log.debug("Refreshing account token...");
checkClientToken();
- accountList = config.getMojangAccounts();
- selectAccount(accountList.get(config.getString(ConfigurationPaths.StringPaths.ACCOUNT_SELECTED)));
+ selectAccount(config.getAccountList().get(config.getString(ConfigurationPaths.StringPaths.ACCOUNT_SELECTED)));
}, "Token refresh", "Refresh selected account token", Priorities.LOW, TaskImportance.OPTIONAL, "Configuration"));
taskWorker.addTask(new Task(progress -> {
@@ -195,7 +190,6 @@ public final class Minosoft {
}
MojangAccount.RefreshStates refreshState = account.refreshToken();
if (refreshState == MojangAccount.RefreshStates.ERROR) {
- accountList.remove(account.getUserId());
account.delete();
AccountListCell.listView.getItems().remove(account);
selectedAccount = null;
@@ -211,14 +205,6 @@ public final class Minosoft {
return config;
}
- public static ArrayList getServerList() {
- return serverList;
- }
-
- public static HashBiMap getAccountList() {
- return accountList;
- }
-
public static MojangAccount getSelectedAccount() {
return selectedAccount;
}
diff --git a/src/main/java/de/bixilon/minosoft/config/Configuration.java b/src/main/java/de/bixilon/minosoft/config/Configuration.java
index 0f07b0230..b456334f9 100644
--- a/src/main/java/de/bixilon/minosoft/config/Configuration.java
+++ b/src/main/java/de/bixilon/minosoft/config/Configuration.java
@@ -14,9 +14,7 @@
package de.bixilon.minosoft.config;
import com.google.common.collect.HashBiMap;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonObject;
+import com.google.gson.*;
import de.bixilon.minosoft.gui.main.Server;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.util.Util;
@@ -25,11 +23,15 @@ import de.bixilon.minosoft.util.mojang.api.MojangAccount;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
public class Configuration {
public static final int LATEST_CONFIG_VERSION = 1;
- final JsonObject config;
+ private final static JsonObject DEFAULT_CONFIGURATION = JsonParser.parseReader(new InputStreamReader(Configuration.class.getResourceAsStream("/config/" + StaticConfiguration.CONFIG_FILENAME))).getAsJsonObject();
+ private final HashMap config = new HashMap<>();
+ private final HashBiMap accountList = HashBiMap.create();
+ private final HashBiMap serverList = HashBiMap.create();
private final Object lock = new Object();
public Configuration() throws IOException, ConfigMigrationException {
@@ -47,7 +49,23 @@ public class Configuration {
Files.copy(input, Paths.get(file.getAbsolutePath()));
file = new File(StaticConfiguration.HOME_DIRECTORY + "config/" + StaticConfiguration.CONFIG_FILENAME);
}
- config = Util.readJsonFromFile(file.getAbsolutePath());
+
+ JsonObject json = Util.readJsonFromFile(file.getAbsolutePath());
+ for (ConfigurationPaths.ConfigurationPath path : ConfigurationPaths.ALL_PATHS) {
+ config.put(path, getData(json, path));
+ }
+
+ // servers
+ for (Map.Entry entry : json.getAsJsonObject("servers").getAsJsonObject("entries").entrySet()) {
+ serverList.put(Integer.parseInt(entry.getKey()), Server.deserialize(entry.getValue().getAsJsonObject()));
+ }
+
+ // accounts
+ for (Map.Entry entry : json.getAsJsonObject("accounts").getAsJsonObject("entries").entrySet()) {
+ MojangAccount account = MojangAccount.deserialize(entry.getValue().getAsJsonObject());
+ accountList.put(account.getUserId(), account);
+ }
+
int configVersion = getInt(ConfigurationPaths.IntegerPaths.GENERAL_CONFIG_VERSION);
if (configVersion > LATEST_CONFIG_VERSION) {
throw new ConfigMigrationException(String.format("Configuration was migrated to newer config format (version=%d, expected=%d). Downgrading the config file is unsupported!", configVersion, LATEST_CONFIG_VERSION));
@@ -76,9 +94,27 @@ public class Configuration {
e.printStackTrace();
return;
}
+ JsonObject jsonObject = DEFAULT_CONFIGURATION.deepCopy();
synchronized (config) {
- gson.toJson(config, writer);
+
+ // accounts
+ JsonObject accountsEntriesJson = jsonObject.getAsJsonObject("servers").getAsJsonObject("entries");
+ for (Map.Entry entry : serverList.entrySet()) {
+ accountsEntriesJson.add(String.valueOf(entry.getKey()), entry.getValue().serialize());
+ }
+
+ // servers
+ JsonObject serversEntriesJson = jsonObject.getAsJsonObject("accounts").getAsJsonObject("entries");
+ for (Map.Entry entry : accountList.entrySet()) {
+ serversEntriesJson.add(entry.getKey(), entry.getValue().serialize());
+ }
+
+ // rest of data
+ for (ConfigurationPaths.ConfigurationPath path : ConfigurationPaths.ALL_PATHS) {
+ saveData(jsonObject, path, config.get(path));
+ }
}
+ gson.toJson(jsonObject, writer);
try {
writer.close();
} catch (IOException e) {
@@ -99,65 +135,39 @@ public class Configuration {
}
public boolean getBoolean(ConfigurationPaths.BooleanPaths path) {
- return switch (path) {
- case NETWORK_FAKE_CLIENT_BRAND -> config.getAsJsonObject("network").get("fake-network-brand").getAsBoolean();
- case NETWORK_SHOW_LAN_SERVERS -> config.getAsJsonObject("network").get("show-lan-servers").getAsBoolean();
- case DEBUG_VERIFY_ASSETS -> config.getAsJsonObject("debug").get("verify-assets").getAsBoolean();
- };
+ return (boolean) config.get(path);
}
public void putBoolean(ConfigurationPaths.BooleanPaths path, boolean value) {
- switch (path) {
- case NETWORK_FAKE_CLIENT_BRAND -> config.getAsJsonObject("network").addProperty("fake-network-brand", value);
- case NETWORK_SHOW_LAN_SERVERS -> config.getAsJsonObject("network").addProperty("show-lan-servers", value);
- case DEBUG_VERIFY_ASSETS -> config.getAsJsonObject("debug").addProperty("verify-assets", value);
- }
+ config.put(path, value);
}
public int getInt(ConfigurationPaths.IntegerPaths path) {
- return switch (path) {
- case GENERAL_CONFIG_VERSION -> config.getAsJsonObject("general").get("version").getAsInt();
- case GAME_RENDER_DISTANCE -> config.getAsJsonObject("game").get("render-distance").getAsInt();
- };
+ return (int) config.get(path);
}
public void putInt(ConfigurationPaths.IntegerPaths path, int value) {
- switch (path) {
- case GENERAL_CONFIG_VERSION -> config.getAsJsonObject("general").addProperty("version", value);
- case GAME_RENDER_DISTANCE -> config.getAsJsonObject("game").addProperty("render-distance", value);
- }
+ config.put(path, value);
}
public String getString(ConfigurationPaths.StringPaths path) {
- return switch (path) {
- case ACCOUNT_SELECTED -> config.getAsJsonObject("accounts").get("selected").getAsString();
- case GENERAL_LOG_LEVEL -> config.getAsJsonObject("general").get("log-level").getAsString();
- case GENERAL_LANGUAGE -> config.getAsJsonObject("general").get("language").getAsString();
- case RESOURCES_URL -> config.getAsJsonObject("download").getAsJsonObject("urls").get("resources").getAsString();
- case CLIENT_TOKEN -> config.getAsJsonObject("accounts").get("client-token").getAsString();
- };
+ return (String) config.get(path);
}
public void putString(ConfigurationPaths.StringPaths path, String value) {
- switch (path) {
- case ACCOUNT_SELECTED -> config.getAsJsonObject("accounts").addProperty("selected", value);
- case GENERAL_LOG_LEVEL -> config.getAsJsonObject("general").addProperty("log-level", value);
- case GENERAL_LANGUAGE -> config.getAsJsonObject("general").addProperty("language", value);
- case RESOURCES_URL -> config.getAsJsonObject("download").getAsJsonObject("urls").addProperty("resources", value);
- case CLIENT_TOKEN -> config.getAsJsonObject("accounts").addProperty("client-token", value);
- }
+ config.put(path, value);
}
public void putMojangAccount(MojangAccount account) {
- config.getAsJsonObject("accounts").getAsJsonObject("entries").add(account.getUserId(), account.serialize());
+ accountList.put(account.getUserId(), account);
}
public void putServer(Server server) {
- config.getAsJsonObject("servers").getAsJsonObject("entries").add(String.valueOf(server.getId()), server.serialize());
+ serverList.put(server.getId(), server);
}
public void removeServer(Server server) {
- config.getAsJsonObject("servers").getAsJsonObject("entries").remove(String.valueOf(server.getId()));
+ serverList.remove(server.getId());
}
public void saveToFile() {
@@ -166,29 +176,16 @@ public class Configuration {
}
}
- public HashBiMap getMojangAccounts() {
- HashBiMap accounts = HashBiMap.create();
- JsonObject entries = config.getAsJsonObject("accounts").getAsJsonObject("entries");
- entries.keySet().forEach((entry) -> {
- MojangAccount account = MojangAccount.deserialize(entries.get(entry).getAsJsonObject());
- accounts.put(account.getUserId(), account);
- });
- return accounts;
- }
-
- public ArrayList getServers() {
- ArrayList servers = new ArrayList<>();
- JsonObject entries = config.getAsJsonObject("servers").getAsJsonObject("entries");
- entries.keySet().forEach((entry) -> servers.add(Server.deserialize(entries.get(entry).getAsJsonObject())));
- return servers;
- }
-
public void removeAccount(MojangAccount account) {
- config.getAsJsonObject("accounts").getAsJsonObject("entries").remove(account.getUserId());
+ accountList.remove(account.getUserId());
}
- public JsonObject getConfig() {
- return config;
+ public HashBiMap getServerList() {
+ return serverList;
+ }
+
+ public HashBiMap getAccountList() {
+ return accountList;
}
private void migrateConfiguration() throws ConfigMigrationException {
@@ -209,4 +206,53 @@ public class Configuration {
default -> throw new ConfigMigrationException("Can not migrate config: Unknown config version " + nextVersion);
}
}
+
+ private Object getData(JsonObject json, ConfigurationPaths.ConfigurationPath path) {
+ if (path instanceof ConfigurationPaths.BooleanPaths booleanPath) {
+ return switch (booleanPath) {
+ case NETWORK_FAKE_CLIENT_BRAND -> json.getAsJsonObject("network").get("fake-network-brand").getAsBoolean();
+ case NETWORK_SHOW_LAN_SERVERS -> json.getAsJsonObject("network").get("show-lan-servers").getAsBoolean();
+ case DEBUG_VERIFY_ASSETS -> json.getAsJsonObject("debug").get("verify-assets").getAsBoolean();
+ };
+ }
+ if (path instanceof ConfigurationPaths.IntegerPaths integerPath) {
+ return switch (integerPath) {
+ case GENERAL_CONFIG_VERSION -> json.getAsJsonObject("general").get("version").getAsInt();
+ case GAME_RENDER_DISTANCE -> json.getAsJsonObject("game").get("render-distance").getAsInt();
+ };
+ }
+ if (path instanceof ConfigurationPaths.StringPaths stringPath) {
+ return switch (stringPath) {
+ case ACCOUNT_SELECTED -> json.getAsJsonObject("accounts").get("selected").getAsString();
+ case GENERAL_LOG_LEVEL -> json.getAsJsonObject("general").get("log-level").getAsString();
+ case GENERAL_LANGUAGE -> json.getAsJsonObject("general").get("language").getAsString();
+ case RESOURCES_URL -> json.getAsJsonObject("download").getAsJsonObject("urls").get("resources").getAsString();
+ case CLIENT_TOKEN -> json.getAsJsonObject("accounts").get("client-token").getAsString();
+ };
+ }
+ throw new RuntimeException();
+ }
+
+ private void saveData(JsonObject input, ConfigurationPaths.ConfigurationPath path, Object data) {
+ if (data instanceof Boolean bool) {
+ switch ((ConfigurationPaths.BooleanPaths) path) {
+ case NETWORK_FAKE_CLIENT_BRAND -> input.getAsJsonObject("network").addProperty("fake-network-brand", bool);
+ case NETWORK_SHOW_LAN_SERVERS -> input.getAsJsonObject("network").addProperty("show-lan-servers", bool);
+ case DEBUG_VERIFY_ASSETS -> input.getAsJsonObject("debug").addProperty("verify-assets", bool);
+ }
+ } else if (data instanceof Integer integer) {
+ switch ((ConfigurationPaths.IntegerPaths) path) {
+ case GENERAL_CONFIG_VERSION -> input.getAsJsonObject("general").addProperty("version", integer);
+ case GAME_RENDER_DISTANCE -> input.getAsJsonObject("game").addProperty("render-distance", integer);
+ }
+ } else if (data instanceof String string) {
+ switch ((ConfigurationPaths.StringPaths) path) {
+ case ACCOUNT_SELECTED -> input.getAsJsonObject("accounts").addProperty("selected", string);
+ case GENERAL_LOG_LEVEL -> input.getAsJsonObject("general").addProperty("log-level", string);
+ case GENERAL_LANGUAGE -> input.getAsJsonObject("general").addProperty("language", string);
+ case RESOURCES_URL -> input.getAsJsonObject("download").getAsJsonObject("urls").addProperty("resources", string);
+ case CLIENT_TOKEN -> input.getAsJsonObject("accounts").addProperty("client-token", string);
+ }
+ }
+ }
}
diff --git a/src/main/java/de/bixilon/minosoft/config/ConfigurationPaths.java b/src/main/java/de/bixilon/minosoft/config/ConfigurationPaths.java
index dc1316f52..492674eac 100644
--- a/src/main/java/de/bixilon/minosoft/config/ConfigurationPaths.java
+++ b/src/main/java/de/bixilon/minosoft/config/ConfigurationPaths.java
@@ -13,8 +13,19 @@
package de.bixilon.minosoft.config;
+import java.util.Arrays;
+import java.util.HashSet;
+
public abstract class ConfigurationPaths {
- public enum StringPaths {
+ static HashSet ALL_PATHS = new HashSet<>();
+
+ static {
+ ALL_PATHS.addAll(Arrays.asList(StringPaths.values()));
+ ALL_PATHS.addAll(Arrays.asList(BooleanPaths.values()));
+ ALL_PATHS.addAll(Arrays.asList(IntegerPaths.values()));
+ }
+
+ public enum StringPaths implements ConfigurationPath {
GENERAL_LOG_LEVEL,
CLIENT_TOKEN,
RESOURCES_URL,
@@ -22,14 +33,17 @@ public abstract class ConfigurationPaths {
GENERAL_LANGUAGE,
}
- public enum BooleanPaths {
+ public enum BooleanPaths implements ConfigurationPath {
NETWORK_FAKE_CLIENT_BRAND,
NETWORK_SHOW_LAN_SERVERS,
DEBUG_VERIFY_ASSETS
}
- public enum IntegerPaths {
+ public enum IntegerPaths implements ConfigurationPath {
GENERAL_CONFIG_VERSION,
GAME_RENDER_DISTANCE
}
+
+ public interface ConfigurationPath {
+ }
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/AccountListCell.java b/src/main/java/de/bixilon/minosoft/gui/main/AccountListCell.java
index 5592f9386..9df1aca87 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/AccountListCell.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/AccountListCell.java
@@ -102,10 +102,10 @@ public class AccountListCell extends ListCell implements Initiali
public void delete() {
account.delete();
if (Minosoft.getSelectedAccount() == account) {
- if (Minosoft.getAccountList().isEmpty()) {
+ if (Minosoft.getConfig().getAccountList().isEmpty()) {
Minosoft.selectAccount(null);
} else {
- Minosoft.selectAccount(Minosoft.getAccountList().values().iterator().next());
+ Minosoft.selectAccount(Minosoft.getConfig().getAccountList().values().iterator().next());
}
listView.refresh();
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/AccountWindow.java b/src/main/java/de/bixilon/minosoft/gui/main/AccountWindow.java
index bfff0d48b..0f9909eb5 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/AccountWindow.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/AccountWindow.java
@@ -46,7 +46,7 @@ public class AccountWindow implements Initializable {
public void initialize(URL url, ResourceBundle resourceBundle) {
AccountListCell.listView.setCellFactory((lv) -> AccountListCell.newInstance());
- ObservableList accounts = FXCollections.observableArrayList(Minosoft.getAccountList().values());
+ ObservableList accounts = FXCollections.observableArrayList(Minosoft.getConfig().getAccountList().values());
AccountListCell.listView.setItems(accounts);
accountPane.setCenter(AccountListCell.listView);
@@ -91,7 +91,7 @@ public class AccountWindow implements Initializable {
if (attempt.succeeded()) {
// login okay
MojangAccount account = attempt.getAccount();
- Minosoft.accountList.put(account.getUserId(), account);
+ Minosoft.getConfig().putMojangAccount(account);
account.saveToConfig();
AccountListCell.listView.getItems().add(account);
Log.info(String.format("Added and saved account (playerName=%s, email=%s, uuid=%s)", account.getPlayerName(), account.getMojangUserName(), account.getUUID()));
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/Launcher.java b/src/main/java/de/bixilon/minosoft/gui/main/Launcher.java
index b0fc5c4f4..d2745a131 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/Launcher.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/Launcher.java
@@ -62,7 +62,7 @@ public class Launcher {
ServerListCell.listView.setCellFactory((lv) -> ServerListCell.newInstance());
ObservableList servers = FXCollections.observableArrayList();
- servers.addAll(Minosoft.serverList);
+ servers.addAll(Minosoft.getConfig().getServerList().values());
ServerListCell.listView.setItems(servers);
LANServerListener.removeAll(); // remove all LAN Servers
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java b/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java
index 8863da32e..9247b31d5 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java
@@ -203,7 +203,7 @@ public class MainWindow implements Initializable {
if (server1 == null) {
server1 = new Server(Server.getNextServerId(), serverName, serverAddress, desiredVersionId);
- Minosoft.serverList.add(server1);
+ Minosoft.getConfig().putServer(server1);
ServerListCell.listView.getItems().add(server1);
} else {
server1.setName(serverName);
diff --git a/src/main/java/de/bixilon/minosoft/util/mojang/api/MojangAccount.java b/src/main/java/de/bixilon/minosoft/util/mojang/api/MojangAccount.java
index d9691b054..a96bc77f0 100644
--- a/src/main/java/de/bixilon/minosoft/util/mojang/api/MojangAccount.java
+++ b/src/main/java/de/bixilon/minosoft/util/mojang/api/MojangAccount.java
@@ -105,7 +105,6 @@ public class MojangAccount {
}
public void delete() {
- Minosoft.getAccountList().remove(this.getUserId());
Minosoft.getConfig().removeAccount(this);
Minosoft.getConfig().saveToFile();
}