Skip to content

Commit 595738d

Browse files
committed
Some lib config changes
1 parent e45d43d commit 595738d

File tree

6 files changed

+97
-44
lines changed

6 files changed

+97
-44
lines changed

ChatUILib/src/main/java/com/simon816/chatui/lib/ChatUILib.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.spongepowered.api.command.CommandSource;
2020
import org.spongepowered.api.command.args.GenericArguments;
2121
import org.spongepowered.api.command.spec.CommandSpec;
22+
import org.spongepowered.api.config.ConfigDir;
2223
import org.spongepowered.api.entity.living.player.Player;
2324
import org.spongepowered.api.event.Listener;
2425
import org.spongepowered.api.event.Order;
@@ -48,6 +49,8 @@
4849
@Plugin(id = "chatuilib", name = "Chat UI Library")
4950
public class ChatUILib {
5051

52+
private static final String COMMAND_NAME = "chatui";
53+
5154
private static ChatUILib instance;
5255

5356
private final Map<UUID, PlayerChatView> playerViewMap = Maps.newHashMap();
@@ -57,6 +60,10 @@ public class ChatUILib {
5760
@Inject
5861
private Logger logger;
5962

63+
@Inject
64+
@ConfigDir(sharedRoot = false)
65+
private Path confDir;
66+
6067
/* Public API utility functions */
6168

6269
public static PlayerChatView getView(UUID uuid) {
@@ -73,7 +80,7 @@ public static PlayerChatView getView(CommandSource source) {
7380
}
7481

7582
public static ClickAction<?> command(String subcommand) {
76-
return TextActions.runCommand("/chatui " + subcommand);
83+
return TextActions.runCommand("/" + COMMAND_NAME + " " + subcommand);
7784
}
7885

7986
public static ChatUILib getInstance() {
@@ -93,17 +100,16 @@ public void onPreInit(GamePreInitializationEvent event) {
93100

94101
@Listener
95102
public void onInit(GameInitializationEvent event) {
96-
Path confDir = Sponge.getGame().getConfigManager().getSharedConfig(this).getDirectory().resolve("chatui");
97103
try {
98-
Files.createDirectories(confDir);
104+
Files.createDirectories(this.confDir);
99105
} catch (IOException e) {
100-
this.logger.error("Failed to create configuration directory at {}", confDir, e);
106+
this.logger.error("Failed to create config directory {}", this.confDir, e);
101107
}
102-
Path confFile = confDir.resolve("preferences.conf");
103-
108+
Path confFile = this.confDir.resolve("preferences.conf");
104109
HoconConfigurationLoader confLoader = HoconConfigurationLoader.builder().setPath(confFile).build();
105110
LibConfig.init(confLoader, this.logger);
106-
this.languageManager = new LanguagePackManager(confDir);
111+
112+
this.languageManager = new LanguagePackManager(this.confDir, this.logger);
107113
if (LibConfig.useLanguagePack()) {
108114
this.languageManager.fetch(this.logger);
109115
}
@@ -134,7 +140,7 @@ public void onInit(GameInitializationEvent event) {
134140
})
135141
.description(Text.of("Internal Chat UI commands"))
136142
.build();
137-
Sponge.getGame().getCommandManager().register(this, cmd, "chatui");
143+
Sponge.getGame().getCommandManager().register(this, cmd, COMMAND_NAME);
138144
}
139145

140146
@Listener

ChatUILib/src/main/java/com/simon816/chatui/lib/config/LibConfig.java

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.simon816.chatui.lib.config;
22

33
import com.simon816.chatui.lib.event.PlayerChangeConfigEvent;
4+
import com.simon816.chatui.util.FontData;
45
import ninja.leaping.configurate.commented.CommentedConfigurationNode;
56
import ninja.leaping.configurate.loader.ConfigurationLoader;
67
import ninja.leaping.configurate.objectmapping.ObjectMapper;
@@ -26,10 +27,12 @@ public class LibConfig {
2627

2728
private static Logger logger;
2829
private static CommentedConfigurationNode config;
30+
private static boolean dirty;
2931

3032
private static ObjectMapper<PlayerSettings> settingsMapper;
3133

3234
private static boolean useLanguagePack;
35+
private static FontData defaultFontData;
3336

3437
public static CommandCallable createCommand() {
3538
return CommandSpec.builder()
@@ -94,35 +97,65 @@ public static void init(ConfigurationLoader<CommentedConfigurationNode> confLoad
9497
}
9598

9699
public static void loadConfig() {
100+
try {
101+
settingsMapper = ObjectMapper.forClass(PlayerSettings.class);
102+
} catch (ObjectMappingException e) {
103+
throw new RuntimeException(e);
104+
}
97105
try {
98106
config = confLoader.load();
99107
} catch (IOException e) {
100-
logger.error("Error while loading config", e);
108+
logger.error("Error while loading config. Resetting to default config.", e);
101109
config = confLoader.createEmptyNode();
102110
}
111+
dirty = false;
112+
103113
CommentedConfigurationNode playerSettings = config.getNode("player-settings");
104114
if (playerSettings.isVirtual()) {
105115
playerSettings.setValue(Collections.emptyMap());
116+
dirty = true;
106117
}
107-
try {
108-
settingsMapper = ObjectMapper.forClass(PlayerSettings.class);
109-
} catch (ObjectMappingException e) {
110-
throw new RuntimeException(e);
111-
}
118+
112119
CommentedConfigurationNode useLanguagePack = config.getNode("use-language-pack");
113120
if (useLanguagePack.isVirtual()) {
114121
useLanguagePack.setValue(false);
122+
dirty = true;
115123
}
116124
LibConfig.useLanguagePack = useLanguagePack.getBoolean();
125+
126+
CommentedConfigurationNode defaultFontNode = config.getNode("default-font");
127+
if (defaultFontNode.isVirtual()) {
128+
defaultFontNode.setValue("");
129+
dirty = true;
130+
}
131+
132+
String defaultFontString = defaultFontNode.getString();
133+
try {
134+
FontData.checkValid(defaultFontString);
135+
} catch (IllegalArgumentException e) {
136+
logger.warn("Default font is invalid, falling back to vanilla font", e);
137+
defaultFontString = null;
138+
}
139+
defaultFontData = FontData.fromString(defaultFontString, FontData.VANILLA);
140+
141+
saveConfig();
117142
}
118143

119144
public static boolean useLanguagePack() {
120145
return useLanguagePack;
121146
}
122147

148+
public static FontData defaultFontData() {
149+
return defaultFontData;
150+
}
151+
123152
public static void saveConfig() {
153+
if (!dirty) {
154+
return;
155+
}
124156
try {
125157
confLoader.save(config);
158+
dirty = false;
126159
} catch (IOException e) {
127160
logger.error("Failed to save config", e);
128161
}
@@ -131,6 +164,8 @@ public static void saveConfig() {
131164
public static PlayerSettings playerConfig(UUID uuid) {
132165
CommentedConfigurationNode settings = config.getNode("player-settings", uuid.toString());
133166
try {
167+
// Save defaults to config file
168+
dirty |= settings.isVirtual();
134169
return settingsMapper.bindToNew().populate(settings);
135170
} catch (ObjectMappingException e) {
136171
throw new RuntimeException(e);
@@ -149,6 +184,7 @@ public static void updatePlayer(PlayerSettings settings, Player player) {
149184
return;
150185
}
151186
settingsMapper.bind(settings).serialize(config.getNode("player-settings", uuid.toString()));
187+
dirty = true;
152188
Sponge.getEventManager()
153189
.post(new PlayerChangeConfigEvent(player, oldSettings, settings, Sponge.getCauseStackManager().getCurrentCause()));
154190
} catch (ObjectMappingException e) {

ChatUILib/src/main/java/com/simon816/chatui/lib/config/PlayerSettings.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ public PlayerSettings withFontData(String fontData) {
8282
}
8383

8484
public PlayerContext createContext(Player player) {
85-
return new PlayerContext(player, getWidth(), getHeightLines(), getForceUnicode(), FontData.fromString(getFontData()));
85+
return new PlayerContext(player, getWidth(), getHeightLines(), getForceUnicode(),
86+
FontData.fromString(getFontData(), LibConfig.defaultFontData()));
8687
}
8788

8889
@Override

ChatUILib/src/main/java/com/simon816/chatui/lib/lang/LanguagePackFetchTask.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public void run() {
6767
}
6868
}
6969
if (versionUrlString == null) {
70-
this.logger.error("Could not find version %s from manifest", this.mcVersion);
70+
this.logger.error("Could not find version {} from manifest", this.mcVersion);
7171
return;
7272
}
7373
URL versionJsonUrl;

ChatUILib/src/main/java/com/simon816/chatui/lib/lang/LanguagePackManager.java

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.io.InputStreamReader;
1717
import java.nio.file.Files;
1818
import java.nio.file.Path;
19+
import java.util.Collections;
1920
import java.util.IllegalFormatException;
2021
import java.util.Locale;
2122
import java.util.Map;
@@ -38,12 +39,12 @@ public Map<String, String> load(Locale key) throws Exception {
3839
}
3940
});
4041

41-
public LanguagePackManager(Path confDir) {
42+
public LanguagePackManager(Path confDir, Logger logger) {
4243
this.langZipFile = confDir.resolve("lang").resolve(getMcVersion() + "-languagepack.zip");
4344
try {
4445
Files.createDirectories(this.langZipFile.getParent());
4546
} catch (IOException e) {
46-
e.printStackTrace();
47+
logger.error("Failed to create language pack directory {}", this.langZipFile.getParent(), e);
4748
}
4849
}
4950

@@ -68,7 +69,6 @@ public Translation forTranslation(Translation translation) {
6869

6970
public String translate(Locale locale, String id) {
7071
return this.translationCache.getUnchecked(locale).getOrDefault(id, id);
71-
7272
}
7373

7474
public void incrementLocale(Locale locale) {
@@ -96,32 +96,29 @@ public boolean isDefault(Locale locale) {
9696
}
9797

9898
Map<String, String> loadTranslations(Locale locale) {
99-
Map<String, String> translations = Maps.newHashMap();
100-
if (!Files.exists(langZipFile)) {
101-
return translations;
99+
if (!Files.exists(this.langZipFile)) {
100+
return Collections.emptyMap();
102101
}
103-
try {
104-
ZipFile zipFile = new ZipFile(this.langZipFile.toFile());
102+
Map<String, String> translations = Maps.newHashMap();
103+
try (ZipFile zipFile = new ZipFile(this.langZipFile.toFile())) {
105104
ZipEntry entry = zipFile.getEntry(locale.toString().toLowerCase() + ".lang");
106105
if (entry == null) {
107-
zipFile.close();
108106
return translations;
109107
}
110-
BufferedReader reader = new BufferedReader(new InputStreamReader(zipFile.getInputStream(entry)));
111-
String line;
112-
while ((line = reader.readLine()) != null) {
113-
if (!line.isEmpty() && line.charAt(0) != '#') {
114-
int eqPos = line.indexOf('=');
115-
if (eqPos != -1) {
116-
String key = line.substring(0, eqPos);
117-
String value = eqPos == line.length() - 1 ? "" : line.substring(eqPos + 1);
118-
value = NUMERIC_VARIABLE_PATTERN.matcher(value).replaceAll("%$1s");
119-
translations.put(key, value);
108+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(zipFile.getInputStream(entry)))) {
109+
String line;
110+
while ((line = reader.readLine()) != null) {
111+
if (!line.isEmpty() && line.charAt(0) != '#') {
112+
int eqPos = line.indexOf('=');
113+
if (eqPos != -1) {
114+
String key = line.substring(0, eqPos);
115+
String value = eqPos == line.length() - 1 ? "" : line.substring(eqPos + 1);
116+
value = NUMERIC_VARIABLE_PATTERN.matcher(value).replaceAll("%$1s");
117+
translations.put(key, value);
118+
}
120119
}
121120
}
122121
}
123-
reader.close();
124-
zipFile.close();
125122
} catch (IOException e) {
126123
e.printStackTrace();
127124
}

ChatUILib/src/main/java/com/simon816/chatui/util/FontData.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,17 @@ public FontData(InputStream asciiPng) throws IOException {
7777
readCompressedAscii(compressedData);
7878
}
7979

80-
private void readCompressedAscii(byte[] compressedData) {
80+
private static Inflater inflate(byte[] src, byte[] dest) throws DataFormatException {
8181
Inflater inflater = new Inflater();
82-
inflater.setInput(compressedData);
82+
inflater.setInput(src);
83+
inflater.inflate(dest);
84+
return inflater;
85+
}
86+
87+
private void readCompressedAscii(byte[] compressedData) {
8388
byte[] data = new byte[this.asciiCharWidths.length >>> 1];
8489
try {
85-
inflater.inflate(data);
90+
inflate(compressedData, data);
8691
} catch (DataFormatException e) {
8792
throw new RuntimeException(e);
8893
}
@@ -180,15 +185,15 @@ public int getWidthInt(int codePoint, boolean isBold, boolean forceUnicode) {
180185
return (int) Math.ceil(getWidth(codePoint, isBold, forceUnicode));
181186
}
182187

183-
public static FontData fromString(String fontData) {
188+
public static FontData fromString(String fontData, FontData fallback) {
184189
if (fontData == null || fontData.isEmpty()) {
185-
return VANILLA;
190+
return fallback;
186191
}
187192
try {
188193
return dataCache.getUnchecked(fontData);
189194
} catch (Exception e) {
190195
e.printStackTrace();
191-
return VANILLA;
196+
return fallback;
192197
}
193198
}
194199

@@ -198,7 +203,15 @@ public static void checkValid(String fontData) throws IllegalArgumentException {
198203
}
199204
// Throws IllegalArgumentException if invalid
200205
byte[] data = Base64.getDecoder().decode(fontData);
201-
checkArgument(data.length == ASCII_PNG_CHARS.length() >>> 1, "Length of font data not valid");
206+
try {
207+
int expectLen = ASCII_PNG_CHARS.length() >>> 1;
208+
Inflater inflater = inflate(data, new byte[expectLen]);
209+
long written = inflater.getBytesWritten();
210+
checkArgument(inflater.finished(), "Font data larger than expected, expected %s", expectLen);
211+
checkArgument(written == expectLen, "Font data not of expected size, expected %s got %s", expectLen, written);
212+
} catch (DataFormatException e) {
213+
throw new IllegalArgumentException("Corrupt font data", e);
214+
}
202215
}
203216

204217
}

0 commit comments

Comments
 (0)