Config.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package me.lortseam.completeconfig.data;
  2. import lombok.NonNull;
  3. import lombok.extern.log4j.Log4j2;
  4. import me.lortseam.completeconfig.api.ConfigContainer;
  5. import me.lortseam.completeconfig.data.text.TranslationIdentifier;
  6. import me.lortseam.completeconfig.io.ConfigSource;
  7. import net.fabricmc.loader.api.FabricLoader;
  8. import net.fabricmc.loader.api.metadata.ModMetadata;
  9. import java.util.*;
  10. @Log4j2
  11. public final class Config extends BaseCollection {
  12. private static final Map<String, Config> mainConfigs = new HashMap<>();
  13. private static final Set<Config> saveOnExitConfigs = new HashSet<>();
  14. static {
  15. Runtime.getRuntime().addShutdownHook(new Thread(() -> {
  16. for (Config config : saveOnExitConfigs) {
  17. config.save();
  18. }
  19. }));
  20. }
  21. public static Map<String, Config> getMainConfigs() {
  22. return Collections.unmodifiableMap(mainConfigs);
  23. }
  24. /**
  25. * Creates a new config builder for the specified mod.
  26. *
  27. * @param modID the ID of the mod creating the config
  28. */
  29. public static Builder builder(@NonNull String modID) {
  30. if (!FabricLoader.getInstance().isModLoaded(modID)) {
  31. throw new IllegalArgumentException("Mod " + modID + " is not loaded");
  32. }
  33. return new Builder(modID);
  34. }
  35. private final ConfigSource source;
  36. private Config(ConfigSource source, LinkedHashSet<ConfigContainer> children) {
  37. super(TranslationIdentifier.from(source));
  38. this.source = source;
  39. resolve(children);
  40. }
  41. public ModMetadata getMod() {
  42. return FabricLoader.getInstance().getModContainer(source.getModID()).get().getMetadata();
  43. }
  44. public TranslationIdentifier getTranslation(boolean includeBranch) {
  45. if (includeBranch) {
  46. return translation.append(source.getBranch());
  47. } else {
  48. return translation;
  49. }
  50. }
  51. private void load() {
  52. source.load(this);
  53. }
  54. public void save() {
  55. source.save(this);
  56. }
  57. @Log4j2
  58. public final static class Builder {
  59. private final String modID;
  60. private String[] branch = new String[0];
  61. private final LinkedHashSet<ConfigContainer> children = new LinkedHashSet<>();
  62. private boolean main;
  63. private boolean saveOnExit;
  64. private Builder(String modID) {
  65. this.modID = modID;
  66. }
  67. /**
  68. * Sets the branch. Every config of a mod needs a unique branch, therefore setting a branch is only required
  69. * when using more than one config.
  70. *
  71. * <p>The branch determines the location of the config's save file.
  72. *
  73. * @param branch the branch
  74. * @return this builder
  75. */
  76. public Builder setBranch(@NonNull String[] branch) {
  77. Arrays.stream(branch).forEach(Objects::requireNonNull);
  78. this.branch = branch;
  79. return this;
  80. }
  81. /**
  82. * Adds one or more containers to the config.
  83. *
  84. * @param containers one or more containers
  85. * @return this builder
  86. */
  87. public Builder add(@NonNull ConfigContainer... containers) {
  88. Arrays.stream(containers).forEach(Objects::requireNonNull);
  89. for (ConfigContainer container : containers) {
  90. if (!children.add(container)) {
  91. throw new IllegalArgumentException("Duplicate container");
  92. }
  93. }
  94. return this;
  95. }
  96. /**
  97. * Sets a flag to save the config when the game closes.
  98. *
  99. * @return this builder
  100. */
  101. public Builder saveOnExit() {
  102. saveOnExit = true;
  103. return this;
  104. }
  105. /**
  106. * Registers the config as main mod config.
  107. *
  108. * @return this builder
  109. */
  110. public Builder main() {
  111. main = true;
  112. return this;
  113. }
  114. /**
  115. * Creates and loads the config.
  116. *
  117. * @return the created config
  118. */
  119. public Config build() {
  120. if (children.isEmpty()) {
  121. logger.warn("[CompleteConfig] Mod " + modID + " tried to create an empty config");
  122. return null;
  123. }
  124. Config config = new Config(new ConfigSource(modID, branch), children);
  125. if (config.isEmpty()) {
  126. logger.warn("[CompleteConfig] Config of " + config.source + " is empty");
  127. return null;
  128. }
  129. config.load();
  130. if (main || branch.length == 0 && !mainConfigs.containsKey(modID)) {
  131. mainConfigs.put(modID, config);
  132. }
  133. if (saveOnExit) {
  134. saveOnExitConfigs.add(config);
  135. }
  136. return config;
  137. }
  138. }
  139. }