]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/config/Configuration.java
Update to 1.17.1 (#124)
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / config / Configuration.java
1 package com.irtimaled.bbor.client.config;
2
3 import com.google.common.io.Files;
4
5 import java.io.BufferedWriter;
6 import java.io.File;
7 import java.io.FileOutputStream;
8 import java.io.IOException;
9 import java.io.OutputStreamWriter;
10 import java.io.Writer;
11 import java.nio.charset.StandardCharsets;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15
16 class Configuration {
17     private static final String FALLBACK_CATEGORY = "features";
18     private final File file;
19
20     Configuration(File file) {
21         this.file = file;
22     }
23
24     void save() {
25         try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
26             writer.write("# Configuration file\n");
27             for (String category : settingsGroup.keySet()) {
28                 writer.write("\n");
29                 writer.write(String.format("%s {\n", category));
30                 Map<String, Setting<?>> settings = settingsGroup.get(category);
31                 boolean first = true;
32                 for (String settingName : settings.keySet()) {
33                     if (!first)
34                         writer.write("\n");
35                     first = false;
36                     Setting setting = settings.get(settingName);
37                     writer.write(String.format("    # %s\n", setting.comment));
38                     writer.write(String.format("    %s:%s=%s\n", setting.getType(), settingName, setting.get()));
39                 }
40                 writer.write("}\n");
41             }
42         } catch (IOException ignored) {
43         }
44     }
45
46     private final Map<String, Map<String, Setting<?>>> settingsGroup = new HashMap<>();
47
48     void load() {
49         try {
50             List<String> lines = Files.readLines(file, StandardCharsets.UTF_8);
51             String category = null;
52             String lastCommentLine = null;
53             for (String line : lines) {
54                 String trimmedLine = line.trim();
55                 if (trimmedLine.isEmpty()) {
56                     continue;
57                 }
58                 if (trimmedLine.startsWith("#")) {
59                     lastCommentLine = trimmedLine.substring(1).trim();
60                     continue;
61                 }
62                 if (trimmedLine.equals("}")) {
63                     category = null;
64                     continue;
65                 }
66                 if (category == null && trimmedLine.endsWith("{")) {
67                     category = trimmedLine.substring(0, trimmedLine.length() - 1).trim();
68                     settingsGroup.put(category, new HashMap<>());
69                     continue;
70                 }
71                 if (category != null) {
72                     String[] items = trimmedLine.split("[:=]");
73                     char type = items[0].charAt(0);
74                     String name = items[1];
75                     String stringValue = items[2];
76                     Setting setting = getTypedSetting(type, stringValue);
77                     setting.comment = lastCommentLine;
78                     settingsGroup.get(category).put(name, setting);
79                 }
80             }
81         } catch (IOException ignored) {
82         }
83     }
84
85     private Setting<?> getTypedSetting(char type, String value) {
86         switch (type) {
87             case 'I':
88                 return new Setting<>(type, Integer.parseInt(value));
89             case 'B':
90                 return new Setting<>(type, value.equals("1") || value.toLowerCase().equals("true"));
91             case 'H':
92                 return new Setting<>(type, HexColor.from(value));
93         }
94         return new Setting<>(type, value);
95     }
96
97     <T> Setting<T> get(String category, String settingName, T defaultValue) {
98         char type = getType(defaultValue);
99         if (!settingsGroup.containsKey(category)) {
100             settingsGroup.put(category, new HashMap<>());
101         }
102         Map<String, Setting<?>> settings = settingsGroup.get(category);
103         Setting<?> setting = settings.get(settingName);
104         if (setting == null && !category.equals(FALLBACK_CATEGORY))
105             setting = getFallbackSetting(settingName, settings);
106         if (setting != null && setting.getType() != type) {
107             setting = null;
108         }
109         if (setting == null) {
110             settings.put(settingName, setting = new Setting<>(type, defaultValue));
111         }
112         return (Setting<T>) setting;
113     }
114
115     private Setting<?> getFallbackSetting(String settingName, Map<String, Setting<?>> settings) {
116         Map<String, Setting<?>> fallbackSettings = settingsGroup.get(FALLBACK_CATEGORY);
117         if (fallbackSettings == null) return null;
118
119         Setting<?> setting = fallbackSettings.get(settingName);
120         if (setting != null) {
121             fallbackSettings.remove(settingName);
122             settings.put(settingName, setting);
123         }
124         return setting;
125     }
126
127     private <T> char getType(T defaultValue) {
128         String[] typeNames = defaultValue.getClass().getName().split("[.]");
129         return typeNames[typeNames.length - 1].charAt(0);
130     }
131
132     void put(Setting<?> setting) {
133         String category = setting.category;
134         if (!settingsGroup.containsKey(category)) {
135             settingsGroup.put(category, new HashMap<>());
136         }
137         Map<String, Setting<?>> settings = settingsGroup.get(category);
138         settings.put(setting.name, setting);
139     }
140 }