Optimize language file generation

When reloading the plugin:
If the language file does not exist, generate
If present, check for missing keys and add them, delete extra keys
This commit is contained in:
halogly 2025-10-29 11:10:01 +08:00
parent 76204cd69d
commit ed0b596d0b
4 changed files with 64 additions and 20 deletions

View File

@ -12,6 +12,8 @@ import org.bukkit.configuration.file.YamlConfiguration;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class FileHandler {
private final Context ctx;
@ -41,7 +43,8 @@ public class FileHandler {
// Create panels folder and add example panels if not there
if (!ctx.plugin.folder.exists()) {
if (!ctx.plugin.folder.mkdirs()) {
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_PANELS_FAIL));
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task ->
ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_PANELS_FAIL));
return;
}
createExamplePanels();
@ -54,6 +57,8 @@ public class FileHandler {
ctx.plugin.panels.putAll(panels);
ctx.panelCommand.populateCommands();
});
createLangFile();
}
private HashMap<String, Panel> loadYamlFilesRecursively(File directory) {
@ -89,7 +94,7 @@ public class FileHandler {
// Code for config files
//this reads the encrypted resource files in the jar file
private Reader getReaderFromStream(InputStream initialStream) throws IOException {
if(initialStream == null) return new StringReader("Missing resource for this file!");
if (initialStream == null) return new StringReader("Missing resource for this file!");
// Read all bytes from the input stream
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] data = new byte[8192];
@ -120,32 +125,69 @@ public class FileHandler {
FileConfiguration floodgateCustomFile = YamlConfiguration.loadConfiguration(getReaderFromStream(ctx.plugin.getResource("floodgate_custom.yml")));
floodgateCustomFile.save(new File(ctx.plugin.folder, "floodgate_custom.yml"));
} catch (IOException | NullPointerException e) {
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_EXAMPLE_FAIL));
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task ->
ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_EXAMPLE_FAIL));
}
}
// if lang file is missing add it back
private void createLangFile() {
File messagesFile = new File(ctx.plugin.getDataFolder(), "lang.yml");
YamlConfiguration messagesYaml = Message.toYaml();
if (messagesFile.exists()) {
// Return, lang file already exists
// Update, lang file already exists
updateLangFile(messagesFile, messagesYaml);
return;
}
YamlConfiguration messagesYaml = Message.toYaml();
try {
messagesYaml.save(messagesFile);
} catch (IOException ex) {
Bukkit.getGlobalRegionScheduler().run(ctx.plugin,
task -> ctx.text.sendError(
ctx.plugin.getServer().getConsoleSender(),
Message.FILE_CREATE_LANG_FAIL
)
);
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task ->
ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_LANG_FAIL));
}
}
public void updateConfigFiles(){
public void updateLangFile(File langFile, YamlConfiguration defaultLang) {
YamlConfiguration existingLang = YamlConfiguration.loadConfiguration(langFile);
boolean hasChanges = false;
Set<String> defaultKeys = defaultLang.getKeys(false);
Set<String> existingKeys = existingLang.getKeys(false);
// find missing key
Set<String> missingKeys = new HashSet<>(defaultKeys);
missingKeys.removeAll(existingKeys);
// find extra key
Set<String> extraKeys = new HashSet<>(existingKeys);
extraKeys.removeAll(defaultKeys);
// add missing key
for (String missingKey : missingKeys) {
String defaultValue = defaultLang.getString(missingKey);
existingLang.set(missingKey, defaultValue);
hasChanges = true;
}
// remove extra key
for (String extraKey : extraKeys) {
existingLang.set(extraKey, null);
hasChanges = true;
}
// If file changes, save it
if (hasChanges) {
try {
existingLang.save(langFile);
} catch (IOException e) {
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task ->
ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_UPDATE_LANG_FAIL));
}
}
}
public void updateConfigFiles() {
// Register config files
config = YamlConfiguration.loadConfiguration(new File(ctx.plugin.getDataFolder(), "config.yml"));
@ -158,9 +200,10 @@ public class FileHandler {
configFileConfiguration.save(configFile);
config = YamlConfiguration.loadConfiguration(new File(ctx.plugin.getDataFolder(), "config.yml"));
} catch (IOException var11) {
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_CONFIG_FAIL));
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task ->
ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_CONFIG_FAIL));
}
}else{
} else {
// Check if the config file has any missing elements
try {
YamlConfiguration configFileConfiguration = YamlConfiguration.loadConfiguration(getReaderFromStream(ctx.plugin.getResource("config.yml")));
@ -168,7 +211,8 @@ public class FileHandler {
config.options().copyDefaults(true);
config.save(new File(ctx.plugin.getDataFolder() + File.separator + "config.yml"));
} catch (IOException var10) {
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_UPDATE_CONFIG_FAIL));
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task ->
ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_UPDATE_CONFIG_FAIL));
}
}
}

View File

@ -22,7 +22,7 @@ public class HeadDatabaseComponent implements MaterialComponent {
api = new HeadDatabaseAPI();
return api.getItemHead(head);
} else {
ctx.text.sendWarn(player, Message.REQUIRE_HEADDATABASE);
ctx.text.sendWarn(player, Message.REQUIRE_HEAD_DATABASE);
}
return null;
}

View File

@ -21,14 +21,13 @@ public class ReloadCommand implements SubCommand {
@Override
public boolean execute(Context ctx, CommandSender sender, String[] args) {
Bukkit.getAsyncScheduler().runNow(ctx.plugin, task -> {
ctx.text.lang.reloadTranslations();
ctx.fileHandler.updateConfigFiles();
ctx.fileHandler.reloadPanels();
ctx.panelCommand.populateCommands();
ctx.text.lang.reloadTranslations();
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, t ->
ctx.text.sendInfo(sender, Message.PLUGIN_RELOADED));
});
return true;
}
}

View File

@ -13,9 +13,10 @@ public enum Message {
// FileHandler / DataLoader / GenerateManager
FILE_CREATE_PANELS_FAIL("Failed to create panels folder!"),
FILE_CREATE_EXAMPLE_FAIL("Could not create example panels!"),
FILE_CREATE_LANG_FAIL("Failed to create language file!"),
FILE_CREATE_CONFIG_FAIL("Could not create the config file!"),
FILE_UPDATE_CONFIG_FAIL("Could not update the config file!"),
FILE_CREATE_LANG_FAIL("Failed to create language file!"),
FILE_UPDATE_LANG_FAIL("Failed to update language file!"),
FILE_SAVE_DATA_FAIL("Could not save data file."),
FILE_SAVE_PANEL_FAIL("Could not save new panel file."),
@ -113,7 +114,7 @@ public enum Message {
DIALOG_NO_BUTTONS("Dialog needs at least one button"),
COOLDOWN_ERROR("You're opening panels too quickly"),
TELEPORT_ERROR("Error with teleport tag"),
REQUIRE_HEADDATABASE("Download the HeadDatabase plugin to use this feature!");
REQUIRE_HEAD_DATABASE("Download the HeadDatabase plugin to use this feature!");
private final String message;