diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackMod.java b/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackMod.java index bc81e12..2b833dc 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackMod.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackMod.java @@ -172,4 +172,8 @@ public boolean isMinecraftInitialized() { public abstract String getCurrentGameVersion(); public abstract boolean checkResourcePackMetaValid(String s) throws Exception; + + public Path getResourcePackDir() { + return resourcePacks.toPath(); + } } \ No newline at end of file diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/Mod.java b/common/src/main/java/com/adamcalculator/dynamicpack/Mod.java index 5818af2..f4defbb 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/Mod.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/Mod.java @@ -8,10 +8,10 @@ import java.util.Set; public class Mod { - public static final String VERSION_NAME_MOD = "1.0.16"; + public static final String VERSION_NAME_MOD = "1.0.17"; public static final String VERSION_NAME_BRANCH = "mc1.20"; public static final String VERSION_NAME = VERSION_NAME_MOD + "-" + VERSION_NAME_BRANCH; - public static final long VERSION_BUILD = 16; + public static final long VERSION_BUILD = 17; public static final String MOD_ID = "dynamicpack"; @@ -129,6 +129,6 @@ public static boolean isDebugLogs() { } public static boolean isDebugMessageOnWorldJoin() { - return true; // TODO: Disable + return false; } } diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/client/Compat.java b/common/src/main/java/com/adamcalculator/dynamicpack/client/Compat.java index 0946497..addf053 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/client/Compat.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/client/Compat.java @@ -2,11 +2,13 @@ import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.Renderable; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.narration.NarratableEntry; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.locale.Language; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.FormattedText; @@ -60,4 +62,16 @@ public static void drawTexture(GuiGraphics context, ResourceLocation texture, in RenderSystem.setShaderTexture(0, texture); context.blit(texture, x, y, u, v, width, height, textureWidth, textureHeight); } + + public static void renderBackground(Screen screen, Object context, int mouseX, int mouseY, float delta) { + screen.renderBackground((GuiGraphics) context); + } + + public static void drawString(Object context, Font font, Component component, int i, int i1, int i2) { + ((GuiGraphics) context).drawString(font, component, i, i1, i2); + } + + public static void drawCenteredString(Object context, Font font, Component title, int i, int i1, int i2) { + ((GuiGraphics) context).drawCenteredString(font, title, i, i1, i2); + } } diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/client/ContentsList.java b/common/src/main/java/com/adamcalculator/dynamicpack/client/ContentsList.java new file mode 100644 index 0000000..d369fe9 --- /dev/null +++ b/common/src/main/java/com/adamcalculator/dynamicpack/client/ContentsList.java @@ -0,0 +1,153 @@ +package com.adamcalculator.dynamicpack.client; + +import com.adamcalculator.dynamicpack.pack.BaseContent; +import com.adamcalculator.dynamicpack.pack.DynamicRepoRemote; +import com.adamcalculator.dynamicpack.pack.OverrideType; +import com.adamcalculator.dynamicpack.pack.Pack; +import com.adamcalculator.dynamicpack.util.Out; +import com.google.common.collect.ImmutableList; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.ContainerObjectSelectionList; +import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.narration.NarratableEntry; +import net.minecraft.network.chat.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.function.Consumer; + +public class ContentsList extends ContainerObjectSelectionList { + private final ContentsScreen parent; + private final Pack pack; + private final Consumer resyncOnExit; + private final HashMap preChangeStates = new HashMap<>(); + private final List entries = new ArrayList<>(); + + public ContentsList(ContentsScreen parent, Minecraft minecraft, Pack pack, Consumer resyncOnExit) { + super(minecraft, parent.width, parent.height, 20, parent.height - 32, 40); + this.parent = parent; + this.pack = pack; + this.resyncOnExit = resyncOnExit; + + + for (BaseContent knownContent : ((DynamicRepoRemote) pack.getRemote()).getKnownContents()) { + preChangeStates.put(knownContent, knownContent.getOverride()); + var v = new BaseContentEntry(knownContent); + entries.add(v); + this.addEntry(v); + } + } + + public boolean isChanges() { + boolean t = false; + + for (BaseContent knownContent : preChangeStates.keySet()) { + if (preChangeStates.get(knownContent) != knownContent.getOverride()) { + t = true; + break; + } + } + return t; + } + + public void onAfterChange() { + boolean isChanges = isChanges(); + resyncOnExit.accept(isChanges); + } + + public void reset() { + for (BaseContent knownContent : preChangeStates.keySet()) { + OverrideType overrideType = preChangeStates.get(knownContent); + try { + knownContent.setOverrideType(overrideType); + } catch (Exception e) { + Out.error("Error while reset changes", e); + } + } + + + for (ContentEntry entry : entries) { + entry.refresh(); + } + + onAfterChange(); + } + + public class BaseContentEntry extends ContentEntry { + private final BaseContent content; + private final Button stateButton; + + BaseContentEntry(BaseContent knownContent) { + this.content = knownContent; + + this.stateButton = createStateButton(); + stateButton.active = !content.isRequired(); + if (!stateButton.active) { + this.stateButton.setTooltip(Tooltip.create(Component.translatable("dynamicpack.screen.pack_contents.state.tooltip_disabled"))); + } + } + + private Button createStateButton() { + return Button.builder(Component.translatable("dynamicpack.screen.pack_contents.state", currentState()), (button) -> { + try { + content.nextOverride(); + } catch (Exception e) { + Out.error("Error while switch content override", e); + } + onAfterChange(); + refresh(); + }).bounds(0, 0, 140, 20).build(); + } + + + @Override + public void refresh() { + stateButton.setMessage(Component.translatable("dynamicpack.screen.pack_contents.state", currentState())); + } + + private Component currentState() { + String s = switch (content.getOverride()) { + case TRUE -> "dynamicpack.screen.pack_contents.state.true"; + case FALSE -> "dynamicpack.screen.pack_contents.state.false"; + case NOT_SET -> { + if (content.getWithDefaultState()) { + yield "dynamicpack.screen.pack_contents.state.default.true"; + } else { + yield "dynamicpack.screen.pack_contents.state.default.false"; + } + } + }; + return Component.translatable(s); + } + + public void render(GuiGraphics context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + String txt = content.getId(); + String name = content.getName(); + if (name != null) { + txt = name; + } + Component text = Component.literal(txt); + context.drawString(ContentsList.this.minecraft.font, text, (x - 70), y+10, 16777215, false); + this.stateButton.setX(x+entryWidth-140); + this.stateButton.setY(y); + this.stateButton.render(context, mouseX, mouseY, tickDelta); + } + + public List children() { + return ImmutableList.of(this.stateButton); + } + + public List narratables() { + return ImmutableList.of(this.stateButton); + } + + } + + public abstract static class ContentEntry extends Entry { + public abstract void refresh(); + } +} diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/client/ContentsScreen.java b/common/src/main/java/com/adamcalculator/dynamicpack/client/ContentsScreen.java new file mode 100644 index 0000000..8cb709d --- /dev/null +++ b/common/src/main/java/com/adamcalculator/dynamicpack/client/ContentsScreen.java @@ -0,0 +1,85 @@ +package com.adamcalculator.dynamicpack.client; + +import com.adamcalculator.dynamicpack.DynamicPackMod; +import com.adamcalculator.dynamicpack.pack.Pack; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.Tooltip; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +public class ContentsScreen extends Screen { + private final Screen parent; + private final Pack pack; + private ContentsList contentsList; + private final Consumer onPackReSync = pack -> Compat.runAtUI(this::onClose); + private boolean syncOnExit = false; + private Button doneButton; + private Button resetButton; + + protected ContentsScreen(Screen parent, Pack pack) { + super(Component.translatable("dynamicpack.screen.pack_contents.title")); + this.parent = parent; + this.pack = pack; + this.minecraft = Minecraft.getInstance(); + this.pack.addDestroyListener(onPackReSync); + } + + @Override + public void onClose() { + this.minecraft.setScreen(this.parent); + pack.removeDestroyListener(onPackReSync); + if (syncOnExit) { + DynamicPackMod.INSTANCE.startManuallySync(); + } + } + + @Override + public boolean shouldCloseOnEsc() { + return !syncOnExit; + } + + @Override + public void render(@NotNull GuiGraphics context, int mouseX, int mouseY, float delta) { + Compat.renderBackground(this, context, mouseX, mouseY, delta); + contentsList.render(context, mouseX, mouseY, delta); + Compat.drawCenteredString(context, this.font, this.title, this.width / 2, 8, 16777215); + + super.render(context, mouseX, mouseY, delta); + } + + @Override + protected void init() { + super.init(); + this.contentsList = new ContentsList(this, this.minecraft, pack, (b) -> { + syncOnExit = b; + updateDoneButton(b); + }); + this.addWidget(this.contentsList); + + this.addRenderableWidget(doneButton = Compat.createButton(CommonComponents.GUI_DONE, this::onClose, 150, 20, this.width / 2 - 155 + 160, this.height - 29)); + this.addRenderableWidget(resetButton = Compat.createButton(Component.translatable("controls.reset"), this::reset, 150, 20, this.width / 2 - 155, this.height - 29)); + resetButton.visible = false; + } + + private void updateDoneButton(boolean syncOnExit) { + if (syncOnExit) { + doneButton.setMessage(Component.translatable("dynamicpack.screen.pack_contents.apply").withStyle(ChatFormatting.BOLD, ChatFormatting.GOLD)); + doneButton.setTooltip(Tooltip.create(Component.translatable("dynamicpack.screen.pack_contents.apply.tooltip"))); + } else { + doneButton.setMessage(CommonComponents.GUI_DONE); + doneButton.setTooltip(null); + } + resetButton.visible = syncOnExit; + } + + private void reset() { + contentsList.reset(); + } +} diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/client/DynamicPackScreen.java b/common/src/main/java/com/adamcalculator/dynamicpack/client/DynamicPackScreen.java index 59cfc38..d1cac36 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/client/DynamicPackScreen.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/client/DynamicPackScreen.java @@ -1,6 +1,7 @@ package com.adamcalculator.dynamicpack.client; import com.adamcalculator.dynamicpack.DynamicPackMod; +import com.adamcalculator.dynamicpack.pack.DynamicRepoRemote; import com.adamcalculator.dynamicpack.pack.Pack; import com.adamcalculator.dynamicpack.sync.SyncingTask; import com.adamcalculator.dynamicpack.util.TranslatableException; @@ -23,6 +24,7 @@ public class DynamicPackScreen extends Screen { private final MutableComponent screenDescText; private Button syncButton; private final Consumer destroyListener = this::setPack; + private Button contentsButton; public DynamicPackScreen(Screen parent, Pack pack) { super(Component.literal(pack.getName()).withStyle(ChatFormatting.BOLD)); @@ -43,13 +45,14 @@ private void setPack(Pack pack) { @Override public void render(@NotNull GuiGraphics context, int mouseX, int mouseY, float delta) { - renderBackground(context); + Compat.renderBackground(this, context, mouseX, mouseY, delta); syncButton.active = !SyncingTask.isSyncing; + contentsButton.active = !SyncingTask.isSyncing; int h = 20; - context.drawString(this.font, this.title, 20, 8, 16777215); - context.drawString(this.font, screenDescText, 20, 20 + h, 16777215); - context.drawString(this.font, Component.translatable("dynamicpack.screen.pack.remote_type", pack.getRemoteType()), 20, 36 + h, 16777215); - context.drawString(this.font, Component.translatable("dynamicpack.screen.pack.latestUpdated", pack.getLatestUpdated() < 0 ? "-" : new Date(pack.getLatestUpdated() * 1000)), 20, 52 + h, 16777215); + Compat.drawString(context, this.font, this.title, 20, 8, 16777215); + Compat.drawString(context, this.font, screenDescText, 20, 20 + h, 16777215); + Compat.drawString(context, this.font, Component.translatable("dynamicpack.screen.pack.remote_type", pack.getRemoteType()), 20, 36 + h, 16777215); + Compat.drawString(context, this.font, Component.translatable("dynamicpack.screen.pack.latestUpdated", pack.getLatestUpdated() < 0 ? "-" : new Date(pack.getLatestUpdated() * 1000)), 20, 52 + h, 16777215); if (pack.getLatestException() != null) { Compat.drawWrappedString(context, Component.translatable("dynamicpack.screen.pack.latestException", TranslatableException.getComponentFromException(pack.getLatestException())).getString(512), 20, 78 + h, 500, 99, 0xff2222); @@ -74,6 +77,10 @@ protected void init() { )); addRenderableWidget(Compat.createButton(CommonComponents.GUI_DONE, this::onClose, 150, 20, this.width / 2 + 4, this.height - 48)); + addRenderableWidget(contentsButton = Compat.createButton(Component.translatable("dynamicpack.screen.pack.dynamic.contents"), () -> { + Minecraft.getInstance().setScreen(new ContentsScreen(this, pack)); + }, 150, 20, this.width / 2 + 4-160, this.height - 48)); + contentsButton.visible = pack.getRemote() instanceof DynamicRepoRemote; } @Override diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/pack/BaseContent.java b/common/src/main/java/com/adamcalculator/dynamicpack/pack/BaseContent.java new file mode 100644 index 0000000..edb4a43 --- /dev/null +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/BaseContent.java @@ -0,0 +1,48 @@ +package com.adamcalculator.dynamicpack.pack; + +public class BaseContent { + private final DynamicRepoRemote parent; + private final String id; + private final boolean required; + private OverrideType overrideType; + private final String name; + private final boolean defaultStatus; + + public BaseContent(DynamicRepoRemote parent, String id, boolean required, OverrideType overrideType, String name, boolean defaultStatus) { + this.parent = parent; + this.id = id; + this.required = required; + this.overrideType = overrideType; + this.name = name; + this.defaultStatus = defaultStatus; + } + + public String getId() { + return id; + } + + public boolean isRequired() { + return required; + } + + public void nextOverride() throws Exception { + setOverrideType(overrideType.next()); + } + + public OverrideType getOverride() { + return overrideType; + } + + public boolean getWithDefaultState() { + return defaultStatus; + } + + public String getName() { + return name; + } + + public void setOverrideType(OverrideType overrideType) throws Exception { + this.overrideType = overrideType; + parent.setContentOverride(this, overrideType); + } +} diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoRemote.java b/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoRemote.java index 9efb262..d8de545 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoRemote.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoRemote.java @@ -15,7 +15,9 @@ import java.io.IOException; import java.nio.file.Path; import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.LongConsumer; @@ -25,8 +27,9 @@ public class DynamicRepoRemote extends Remote { public static final String REPO_SIGNATURE = "dynamicmcpack.repo.json.sig"; - private Pack parent; + Pack parent; private JSONObject cachedCurrentJson; + private JSONObject cachedRemoteJson; protected String url; protected String buildUrl; protected String packUrl; @@ -42,6 +45,7 @@ public DynamicRepoRemote() { public void init(Pack pack, JSONObject remote, JSONObject current) { this.parent = pack; this.cachedCurrentJson = current; + this.cachedRemoteJson = remote; this.url = remote.getString("url"); this.buildUrl = url + "/" + REPO_BUILD; this.packUrl = url + "/" + REPO_JSON; @@ -49,18 +53,23 @@ public void init(Pack pack, JSONObject remote, JSONObject current) { this.publicKey = remote.optString("public_key", "").replace("\n", "").trim(); this.skipSign = remote.optBoolean("sign_no_required", false); - if (remote.has("content_override")) { - JSONObject j = remote.getJSONObject("content_override"); - for (String s : j.keySet()) { - this.contentOverrides.put(s, j.getBoolean(s)); - } - } + recalculateContentOverrideFromJson(); if (skipSign != this.publicKey.isBlank()) { throw new RuntimeException("Incompatible parameters set. Select one of: sign_no_required or public_key"); } } + private void recalculateContentOverrideFromJson() { + this.contentOverrides.clear(); + if (cachedRemoteJson.has("content_override")) { + JSONObject j = cachedRemoteJson.getJSONObject("content_override"); + for (String s : j.keySet()) { + this.contentOverrides.put(s, j.getBoolean(s)); + } + } + } + @Override public boolean checkUpdateAvailable() throws IOException { String content = Urls.parseContent(buildUrl, 64).trim(); @@ -83,11 +92,13 @@ public void updateCurrentKnownContents(JSONArray repoContents) { JSONObject repoContent = (JSONObject) _repoContent; String id = repoContent.getString("id"); boolean required = repoContent.optBoolean("required", false); + boolean defaultActive = repoContent.optBoolean("default_active", true); JSONObject jsonObject = new JSONObject() .put("hash", repoContent.getString("hash")); if (required) { jsonObject.put("required", true); } + jsonObject.put("default_active", defaultActive); newKnown.put(id, jsonObject); } } @@ -178,10 +189,61 @@ public String getUrl() { return url; } - public boolean isContentActive(String id) { + public boolean isContentActive(String id, boolean def) { if (contentOverrides.containsKey(id)) { return contentOverrides.get(id); } - return true; + return def; + } + + public List getKnownContents() { + if (cachedCurrentJson.has("known_contents")) { + JSONObject known = cachedCurrentJson.getJSONObject("known_contents"); + List contents = new ArrayList<>(); + for (String contentId : known.keySet()) { + JSONObject content = known.getJSONObject(contentId); + boolean required = content.optBoolean("required", false); + boolean defaultValue = content.optBoolean("default_active", true); + contents.add(new BaseContent(this, contentId, required, required ? OverrideType.TRUE : getCurrentOverrideStatus(contentId), content.optString("name", null), required || defaultValue)); + } + return contents; + } + return new ArrayList<>(); + } + + private OverrideType getCurrentOverrideStatus(String contentId) { + if (contentOverrides.containsKey(contentId)) { + return OverrideType.ofBoolean(contentOverrides.get(contentId)); + } + return OverrideType.NOT_SET; + } + + public void setContentOverride(BaseContent baseContent, OverrideType overrideType) throws Exception { + Out.debug("setContentOverride: " + baseContent.getId() + ": " + overrideType); + JSONObject override = null; + if (cachedRemoteJson.has("content_override")) { + override = cachedRemoteJson.getJSONObject("content_override"); + + } else if (overrideType != OverrideType.NOT_SET) { + override = new JSONObject(); + } + + if (override != null) { + if (overrideType == OverrideType.NOT_SET) { + override.remove(baseContent.getId()); + } else { + override.put(baseContent.getId(), overrideType.asBoolean()); + } + if (override.keySet().isEmpty()) { + cachedRemoteJson.remove("content_override"); + + } else if (!cachedRemoteJson.has("content_override")) { + cachedRemoteJson.put("content_override", override); + } + } + + + recalculateContentOverrideFromJson(); + PackUtil.openPackFileSystem(parent.getLocation(), path -> AFiles.nioWriteText(path.resolve(DynamicPackMod.CLIENT_FILE), parent.getPackJson().toString(2))); } } diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoSyncProcessV1.java b/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoSyncProcessV1.java index d0573cc..d245cb5 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoSyncProcessV1.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoSyncProcessV1.java @@ -117,6 +117,12 @@ private void processContentParsed(JSONObject jsonContent) throws IOException { for (final String _relativePath : files.keySet()) { var path = getAndCheckPath(par, _relativePath); // parent / path. assets/minecraft var filePath = packRootPath.resolve(path); + Path filePathForLogs; + if (remote.parent.isZip()) { + filePathForLogs = filePath; + } else { + filePathForLogs = filePath.relativize(DynamicPackMod.INSTANCE.getResourcePackDir()); + } var fileRemoteUrl = getUrlFromPath(rem, path); JSONObject fileExtra = files.getJSONObject(_relativePath); @@ -130,10 +136,10 @@ private void processContentParsed(JSONObject jsonContent) throws IOException { String localHash = Hashes.nioCalcHashForPath(filePath); if (!localHash.equals(hash)) { isOverwrite = true; - this.progress.textLog(filePath + ": overwrite! hash not equal: local:" + localHash+ " remote:"+hash); + this.progress.textLog(filePathForLogs + ": overwrite! hash not equal: local:" + localHash+ " remote:"+hash); } } else { - this.progress.textLog("Overwrite! Not exists: " + filePath); + this.progress.textLog("Overwrite! Not exists: " + filePathForLogs); isOverwrite = true; } @@ -143,7 +149,7 @@ private void processContentParsed(JSONObject jsonContent) throws IOException { } markReloadRequired(); - this.progress.textLog("Overwriting: " + filePath); + this.progress.textLog("Overwriting: " + filePathForLogs); Urls.downloadDynamicFile(fileRemoteUrl, filePath, hash, new FileDownloadConsumer() { @Override public void onUpdate(FileDownloadConsumer it) { @@ -190,12 +196,13 @@ private List calcActiveContents() { while (i < contents.length()) { JSONObject content = contents.getJSONObject(i); String id = content.getString("id"); + boolean defaultActive = content.optBoolean("default_active", true); if (!InputValidator.isContentIdValid(id)) { throw new RuntimeException("Id of content is not valid."); } - if (remote.isContentActive(id) || content.optBoolean("required", false)) { + if (remote.isContentActive(id, defaultActive) || content.optBoolean("required", false)) { activeContents.add(content); } i++; diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/pack/OverrideType.java b/common/src/main/java/com/adamcalculator/dynamicpack/pack/OverrideType.java new file mode 100644 index 0000000..e1555d3 --- /dev/null +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/OverrideType.java @@ -0,0 +1,23 @@ +package com.adamcalculator.dynamicpack.pack; + +public enum OverrideType { + TRUE, + FALSE, + NOT_SET; + + public static OverrideType ofBoolean(boolean b) { + return b ? TRUE : FALSE; + } + + public OverrideType next() { + return switch (this) { + case TRUE -> FALSE; + case FALSE -> NOT_SET; + case NOT_SET -> TRUE; + }; + } + + public boolean asBoolean() { + return this == TRUE; + } +} diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/pack/Pack.java b/common/src/main/java/com/adamcalculator/dynamicpack/pack/Pack.java index b3f279d..adef745 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/Pack.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/Pack.java @@ -222,4 +222,8 @@ private void markAsDestroyed(Pack heirPack) { public boolean isDestroyed() { return destroyed; } + + public Remote getRemote() { + return remote; + } } diff --git a/common/src/main/resources/assets/dynamicpack/lang/en_us.json b/common/src/main/resources/assets/dynamicpack/lang/en_us.json index 6e7ec36..cceb6f2 100644 --- a/common/src/main/resources/assets/dynamicpack/lang/en_us.json +++ b/common/src/main/resources/assets/dynamicpack/lang/en_us.json @@ -1,28 +1,38 @@ { "dynamicpack.toast.needReload": "Packs updated!", - "dynamicpack.toast.needReload.description": "For update: F3 + T", + "dynamicpack.toast.needReload.description": "§6For update: F3 + T", "dynamicpack.toast.syncStarted": "Sync started", - "dynamicpack.toast.done": "Sync done", + "dynamicpack.toast.done": "§aSync done", "dynamicpack.toast.pack.done.success.title": "Pack %s", "dynamicpack.toast.pack.done.success.description": "Done!", "dynamicpack.toast.pack.error.title": "Pack %s", - "dynamicpack.toast.pack.error.description": "Error while sync...", + "dynamicpack.toast.pack.error.description": "§cError while sync...", "dynamicpack.toast.pack.state.downloading.title": "Pack %s", "dynamicpack.toast.pack.state.downloading.description": "[%s%%] %s", "dynamicpack.toast.pack.state.deleting.title": "Pack %s", "dynamicpack.toast.pack.state.deleting.description": "Delete %s", "dynamicpack.toast.pack.state.unknown.title": "Pack %s", "dynamicpack.toast.pack.state.unknown.description": "Processing...", - "dynamicpack.screen.pack.description": "This resource pack support DynamicPack features!", + "dynamicpack.screen.pack.description": "§aThis resource pack support DynamicPack features!", "dynamicpack.screen.pack.remote_type": "Remote type: %s", "dynamicpack.screen.pack.latestUpdated": "Latest updated at: %s", "dynamicpack.screen.pack.latestException": "Latest error on this pack: %s\nFor details see game logs", "dynamicpack.screen.pack.manually_sync": "Manually sync", + "dynamicpack.screen.pack.dynamic.contents": "Contents...", "dynamicpack.status_checker.not_safe": "Security update available for DynamicPack mod! This message should not be ignored, since the update has fixed possible vulnerabilities: %s", "dynamicpack.status_checker.not_safe.toast.title": "DynamicPack", "dynamicpack.status_checker.not_safe.toast.description": "Security update available", "dynamicpack.status_checker.format_not_actual": "Dynamic pack format update available! Perhaps resource pack developers will use it, and then without updating the mod they will stop working: %s", "dynamicpack.status_checker.download": "Download!", "dynamicpack.status_checker.download.hover": "Click for go to %s", - "dynamicpack.exceptions.pack.remote.modrinth.not_found_latest_version": "Could not find the latest version on modrinth with suitable parameters" + "dynamicpack.exceptions.pack.remote.modrinth.not_found_latest_version": "Could not find the latest version on modrinth with suitable parameters", + "dynamicpack.screen.pack_contents.title": "Contents", + "dynamicpack.screen.pack_contents.apply": "Apply & ReSync", + "dynamicpack.screen.pack_contents.apply.tooltip": "§cAfter exiting, everything unnecessary will be deleted, and the missing will be downloaded!", + "dynamicpack.screen.pack_contents.state": "State: %s", + "dynamicpack.screen.pack_contents.state.tooltip_disabled": "This pack cannot be disabled. Because it's required for work", + "dynamicpack.screen.pack_contents.state.true": "§aEnabled", + "dynamicpack.screen.pack_contents.state.false": "§cDisabled", + "dynamicpack.screen.pack_contents.state.default.true": "Default §a(ON)", + "dynamicpack.screen.pack_contents.state.default.false": "Default §c(OFF)" } \ No newline at end of file diff --git a/common/src/main/resources/assets/dynamicpack/lang/ru_ru.json b/common/src/main/resources/assets/dynamicpack/lang/ru_ru.json index 43e72b4..427d3f7 100644 --- a/common/src/main/resources/assets/dynamicpack/lang/ru_ru.json +++ b/common/src/main/resources/assets/dynamicpack/lang/ru_ru.json @@ -1,29 +1,38 @@ { "dynamicpack.toast.needReload": "Паки обновлены!", - "dynamicpack.toast.needReload.description": "Чтобы обновить: F3 + T", + "dynamicpack.toast.needReload.description": "§6Чтобы обновить: F3 + T", "dynamicpack.toast.syncStarted": "Процесс начат!", - "dynamicpack.toast.done": "Успешно!", + "dynamicpack.toast.done": "§aУспешно!", "dynamicpack.toast.pack.done.success.title": "Пак %s", "dynamicpack.toast.pack.done.success.description": "Успешно!", "dynamicpack.toast.pack.error.title": "Пак %s", - "dynamicpack.toast.pack.error.description": "Ошибка...", + "dynamicpack.toast.pack.error.description": "§cОшибка...", "dynamicpack.toast.pack.state.downloading.title": "Пак %s", "dynamicpack.toast.pack.state.downloading.description": "[%s%%] %s", "dynamicpack.toast.pack.state.deleting.title": "Пак %s", "dynamicpack.toast.pack.state.deleting.description": "Удаление %s", "dynamicpack.toast.pack.state.unknown.title": "Пак %s", "dynamicpack.toast.pack.state.unknown.description": "Обработка...", - "dynamicpack.screen.pack.description": "Этот ресурспак поддерживает возможности мода DynamicPack!", + "dynamicpack.screen.pack.description": "§aЭтот ресурспак поддерживает возможности мода DynamicPack!", "dynamicpack.screen.pack.remote_type": "Тип: %s", "dynamicpack.screen.pack.latestUpdated": "Обновлён: %s", "dynamicpack.screen.pack.latestException": "Последняя ошибка в паке: %s\nДля дополнительного смотрите логи", "dynamicpack.screen.pack.manually_sync": "Синхр. вручную", + "dynamicpack.screen.pack.dynamic.contents": "Контенты...", "dynamicpack.status_checker.not_safe": "Доступно обновление безопасности для мода DynamicPack! Это сообщение не стоит игнорировать, поскольку в обновлении были исправлены возможные уязвимости: %s", "dynamicpack.status_checker.not_safe.toast.title": "DynamicPack", "dynamicpack.status_checker.not_safe.toast.description": "Доступно обновление безопасности", "dynamicpack.status_checker.format_not_actual": "Доступно обновление формата динамических паков! Возможно разработчики ресурспаков будут его использовать, и тогда без обновления мода они работать перестанут: %s", "dynamicpack.status_checker.download": "Загрузить!", "dynamicpack.status_checker.download.hover": "Нажмите чтобы перейти %s", - "dynamicpack.exceptions.pack.remote.modrinth.not_found_latest_version": "Не удалось найти последнюю версию на modrinth с подходящими параметрами" - + "dynamicpack.exceptions.pack.remote.modrinth.not_found_latest_version": "Не удалось найти последнюю версию на modrinth с подходящими параметрами", + "dynamicpack.screen.pack_contents.title": "Параметры контентов", + "dynamicpack.screen.pack_contents.apply": "Применить", + "dynamicpack.screen.pack_contents.apply.tooltip": "§cПосле выхода всё ненужное будет удалено, а недостающее скачано!", + "dynamicpack.screen.pack_contents.state": "Режим: %s", + "dynamicpack.screen.pack_contents.state.tooltip_disabled": "Этот пак нельзя отключить. Он обязательный", + "dynamicpack.screen.pack_contents.state.true": "§aВключено", + "dynamicpack.screen.pack_contents.state.false": "§cОтключено", + "dynamicpack.screen.pack_contents.state.default.true": "По умолчанию §a(вкл)", + "dynamicpack.screen.pack_contents.state.default.false": "По умолчанию §c(выкл)" } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 49f622d..cb6265f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ # Every field you add must be added to the root build.gradle expandProps map. # Project -version=1.0.16 +version=1.0.17 group=com.adamcalculator.dynamicpack # Common