diff --git a/pom.xml b/pom.xml
index 50c5de3..e8a3e6d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -85,6 +85,12 @@
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.14.0
+ test
+
net.tfminecraft
magic
@@ -130,6 +136,11 @@
maven-compiler-plugin
3.14.1
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.5.4
+
diff --git a/src/main/java/net/tfminecraft/dowsing/utils/Database.java b/src/main/java/net/tfminecraft/dowsing/utils/Database.java
index 089a0d7..2d96d6c 100644
--- a/src/main/java/net/tfminecraft/dowsing/utils/Database.java
+++ b/src/main/java/net/tfminecraft/dowsing/utils/Database.java
@@ -140,6 +140,9 @@ public void loadNodes() {
}
setSlots(currentType, activePMs);
Node n = new Node(id, b, loc, g, isActive, level, cycleTime, currentType, timeLeft, inputCounter, efficiency);
+ if(json.containsKey(LastCycleResult.KEY)) {
+ n.setLastResult(LastCycleResult.fromJson(json.get(LastCycleResult.KEY)));
+ }
NodeManager.nodes.add(n);
} catch (Exception ex) {
ex.printStackTrace();
@@ -261,6 +264,7 @@ public void saveNode(Node n) {
}
defaults.put("active pms", pmArray);
defaults.put("efficiency", n.getEfficiency());
+ defaults.put(LastCycleResult.KEY, LastCycleResult.toJson(n.getLastResult()));
save(file, defaults);
} catch (Throwable ex) {
ex.printStackTrace();
diff --git a/src/main/java/net/tfminecraft/dowsing/utils/LastCycleResult.java b/src/main/java/net/tfminecraft/dowsing/utils/LastCycleResult.java
new file mode 100644
index 0000000..cb0e627
--- /dev/null
+++ b/src/main/java/net/tfminecraft/dowsing/utils/LastCycleResult.java
@@ -0,0 +1,59 @@
+package net.tfminecraft.dowsing.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.json.simple.JSONObject;
+
+public final class LastCycleResult {
+
+ public static final String KEY = "last result";
+
+ private LastCycleResult() {}
+
+ @SuppressWarnings("unchecked")
+ public static JSONObject toJson(Map result) {
+ JSONObject object = new JSONObject();
+ if(result == null) {
+ return object;
+ }
+ for(Map.Entry entry : result.entrySet()) {
+ if(entry.getKey() == null || entry.getKey().isBlank() || entry.getValue() == null || entry.getValue() <= 0) {
+ continue;
+ }
+ object.put(entry.getKey(), entry.getValue());
+ }
+ return object;
+ }
+
+ public static Map fromJson(Object raw) {
+ Map result = new HashMap<>();
+ if(!(raw instanceof JSONObject object)) {
+ return result;
+ }
+ for(Object key : object.keySet()) {
+ if(key == null) {
+ continue;
+ }
+ int amount = amountOf(object.get(key));
+ if(amount > 0) {
+ result.put(String.valueOf(key), amount);
+ }
+ }
+ return result;
+ }
+
+ static int amountOf(Object value) {
+ if(value instanceof Number number) {
+ return number.intValue();
+ }
+ if(value == null) {
+ return 0;
+ }
+ try {
+ return (int) Math.round(Double.parseDouble(value.toString()));
+ } catch (NumberFormatException ex) {
+ return 0;
+ }
+ }
+}
diff --git a/src/test/java/net/tfminecraft/dowsing/utils/LastCycleResultTest.java b/src/test/java/net/tfminecraft/dowsing/utils/LastCycleResultTest.java
new file mode 100644
index 0000000..8f6b52f
--- /dev/null
+++ b/src/test/java/net/tfminecraft/dowsing/utils/LastCycleResultTest.java
@@ -0,0 +1,45 @@
+package net.tfminecraft.dowsing.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.json.simple.JSONObject;
+import org.junit.jupiter.api.Test;
+
+class LastCycleResultTest {
+
+ @Test
+ void roundTripsExtractedItems() {
+ Map extracted = new LinkedHashMap<>();
+ extracted.put("m.materials.niter", 1);
+ extracted.put("m.materials.arcane_crystal", 3);
+
+ JSONObject stored = LastCycleResult.toJson(extracted);
+ Map loaded = LastCycleResult.fromJson(stored);
+
+ assertEquals(extracted, loaded);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ void readsNumericAmountsWrittenByTheJsonParser() {
+ JSONObject stored = new JSONObject();
+ stored.put("m.materials.niter", 1L);
+ stored.put("m.materials.arcane_crystal", 3.0d);
+
+ Map loaded = LastCycleResult.fromJson(stored);
+
+ assertEquals(1, loaded.get("m.materials.niter"));
+ assertEquals(3, loaded.get("m.materials.arcane_crystal"));
+ }
+
+ @Test
+ void missingOrEmptyResultsStayEmpty() {
+ assertTrue(LastCycleResult.fromJson(null).isEmpty());
+ assertTrue(LastCycleResult.toJson(Map.of()).isEmpty());
+ assertTrue(LastCycleResult.toJson(null).isEmpty());
+ }
+}