From 85948ac2e995afdb57f123ba60844930ee1d56c1 Mon Sep 17 00:00:00 2001 From: adam Date: Wed, 20 Mar 2024 05:49:55 +0700 Subject: [PATCH 1/7] 1.20.1 --- common/build.gradle.kts | 2 +- gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/build.gradle.kts b/common/build.gradle.kts index b47dd2d..6dac88e 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -3,7 +3,7 @@ plugins { } group = "com.adamcalculator" -version = "1.0.11" +version = "1.0.12" repositories { mavenCentral() diff --git a/gradle.properties b/gradle.properties index 828159c..f66a867 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,6 +12,6 @@ loader_version=0.15.7 fabric_version=0.92.0+1.20.1 # Mod Properties -mod_version=1.0.11-mc1.20.1 +mod_version=1.0.12-mc1.20.1 maven_group=com.adamcalculator archives_base_name=dynamicpack \ No newline at end of file From 24a54c64f32c5eab19d59130ad1b867925b53cf9 Mon Sep 17 00:00:00 2001 From: adam Date: Wed, 20 Mar 2024 16:56:30 +0700 Subject: [PATCH 2/7] add _ and : for id of content --- .../dynamicpack/IDValidator.java | 13 -------- .../dynamicpack/InputValidator.java | 24 +++++++++++++++ .../dynamicpack/pack/DynamicRepoRemote.java | 9 ++---- .../pack/DynamicRepoSyncProcessV1.java | 4 +-- .../test/java/tests/InputValidatorTest.java | 30 +++++++++++++++++++ 5 files changed, 59 insertions(+), 21 deletions(-) delete mode 100644 common/src/main/java/com/adamcalculator/dynamicpack/IDValidator.java create mode 100644 common/src/main/java/com/adamcalculator/dynamicpack/InputValidator.java create mode 100644 common/src/test/java/tests/InputValidatorTest.java diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/IDValidator.java b/common/src/main/java/com/adamcalculator/dynamicpack/IDValidator.java deleted file mode 100644 index a6cab54..0000000 --- a/common/src/main/java/com/adamcalculator/dynamicpack/IDValidator.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.adamcalculator.dynamicpack; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class IDValidator { - private static final Pattern PATTERN_ID = Pattern.compile("^[a-z0-9]{1,100}$"); - - public static boolean isValid(String input) { - Matcher matcher = PATTERN_ID.matcher(input); - return matcher.matches(); - } -} diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/InputValidator.java b/common/src/main/java/com/adamcalculator/dynamicpack/InputValidator.java new file mode 100644 index 0000000..696f4ca --- /dev/null +++ b/common/src/main/java/com/adamcalculator/dynamicpack/InputValidator.java @@ -0,0 +1,24 @@ +package com.adamcalculator.dynamicpack; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class InputValidator { + private static final Pattern CONTENT_ID_PATTERN = Pattern.compile("^[a-z0-9_:]{2,128}$"); + + public static boolean isContentIdValid(String input) { + if (input == null) { + return false; + } + Matcher matcher = CONTENT_ID_PATTERN.matcher(input); + return matcher.matches(); + } + + public static boolean isPackNameValid(String input) { + if (input == null) { + return false; + } + + return input.trim().length() < 64 && !input.trim().isEmpty() && !input.contains("\n") && !input.contains("\r") && !input.contains("\b"); + } +} 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 f0eb91d..2800b06 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoRemote.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoRemote.java @@ -1,6 +1,7 @@ package com.adamcalculator.dynamicpack.pack; import com.adamcalculator.dynamicpack.DynamicPackModBase; +import com.adamcalculator.dynamicpack.InputValidator; import com.adamcalculator.dynamicpack.Mod; import com.adamcalculator.dynamicpack.PackUtil; import com.adamcalculator.dynamicpack.sync.PackSyncProgress; @@ -12,7 +13,6 @@ import java.io.IOException; import java.nio.file.Path; -import java.rmi.RemoteException; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.function.LongConsumer; @@ -105,11 +105,8 @@ public void onUpdate(FileDownloadConsumer it) { } String remoteName = repoJson.getString("name"); - if (remoteName.isBlank()) { - throw new RuntimeException("Name of remote pack can't be blank"); - } - if (remoteName.trim().length() > 50) { - throw new RuntimeException("Length of name pack can't > 50"); + if (!InputValidator.isPackNameValid(remoteName)) { + throw new RuntimeException("Remote name of pack not valid."); } 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 d9d5f30..66e5cd7 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoSyncProcessV1.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoSyncProcessV1.java @@ -1,7 +1,7 @@ package com.adamcalculator.dynamicpack.pack; import com.adamcalculator.dynamicpack.DynamicPackModBase; -import com.adamcalculator.dynamicpack.IDValidator; +import com.adamcalculator.dynamicpack.InputValidator; import com.adamcalculator.dynamicpack.Mod; import com.adamcalculator.dynamicpack.PackUtil; import com.adamcalculator.dynamicpack.sync.PackSyncProgress; @@ -61,7 +61,7 @@ public void close() throws IOException { private void processContent(JSONObject jsonContent) throws IOException { String id = jsonContent.getString("id"); - if (!IDValidator.isValid(id)) { + if (!InputValidator.isContentIdValid(id)) { throw new RuntimeException("Id of content is not valid."); } diff --git a/common/src/test/java/tests/InputValidatorTest.java b/common/src/test/java/tests/InputValidatorTest.java new file mode 100644 index 0000000..8ddcf0d --- /dev/null +++ b/common/src/test/java/tests/InputValidatorTest.java @@ -0,0 +1,30 @@ +package tests; + +import com.adamcalculator.dynamicpack.InputValidator; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class InputValidatorTest { + + @Test + public void testContentId() { + Assertions.assertFalse(InputValidator.isContentIdValid("")); + Assertions.assertFalse(InputValidator.isContentIdValid(" ")); + Assertions.assertFalse(InputValidator.isContentIdValid(" ")); + Assertions.assertFalse(InputValidator.isContentIdValid(" 32")); + Assertions.assertFalse(InputValidator.isContentIdValid("test\ntest")); + + Assertions.assertTrue(InputValidator.isContentIdValid("__")); + Assertions.assertTrue(InputValidator.isContentIdValid("pack:megapack")); + Assertions.assertTrue(InputValidator.isContentIdValid("1234567890")); + Assertions.assertTrue(InputValidator.isContentIdValid("01")); + Assertions.assertTrue(InputValidator.isContentIdValid("test_pack")); + Assertions.assertTrue(InputValidator.isContentIdValid("super:mega_puper:")); + } + + @Test + public void testRemoteName() { + Assertions.assertFalse(InputValidator.isPackNameValid("\n")); + Assertions.assertTrue(InputValidator.isPackNameValid("__")); + } +} From 54c91fea75c3c6293bc2f8a95f037a3f23b59312 Mon Sep 17 00:00:00 2001 From: adam Date: Wed, 20 Mar 2024 17:29:59 +0700 Subject: [PATCH 3/7] optimizing --- .../dynamicpack/pack/DynamicRepoRemote.java | 47 +++++++++++++++++-- .../pack/DynamicRepoSyncProcessV1.java | 30 ++++++++---- .../dynamicpack/pack/ModrinthRemote.java | 30 ++++++++++-- .../adamcalculator/dynamicpack/pack/Pack.java | 17 +++---- .../dynamicpack/pack/Remote.java | 2 +- 5 files changed, 101 insertions(+), 25 deletions(-) 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 2800b06..01623ff 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoRemote.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoRemote.java @@ -9,6 +9,7 @@ import com.adamcalculator.dynamicpack.util.FileDownloadConsumer; import com.adamcalculator.dynamicpack.util.Out; import com.adamcalculator.dynamicpack.util.Urls; +import org.json.JSONArray; import org.json.JSONObject; import java.io.IOException; @@ -24,7 +25,7 @@ public class DynamicRepoRemote extends Remote { private Pack parent; - + private JSONObject cachedCurrentJson; protected String url; protected String buildUrl; protected String packUrl; @@ -37,8 +38,9 @@ public class DynamicRepoRemote extends Remote { public DynamicRepoRemote() { } - public void init(Pack pack, JSONObject remote) { + public void init(Pack pack, JSONObject remote, JSONObject current) { this.parent = pack; + this.cachedCurrentJson = current; this.url = remote.getString("url"); this.buildUrl = url + "/" + REPO_BUILD; this.packUrl = url + "/" + REPO_JSON; @@ -62,7 +64,45 @@ public void init(Pack pack, JSONObject remote) { @Override public boolean checkUpdateAvailable() throws IOException { String content = Urls.parseContent(buildUrl, 64).trim(); - return parent.getCurrentBuild() != Long.parseLong(content); + return getCurrentBuild() != Long.parseLong(content); + } + + public long getCurrentBuild() { + return cachedCurrentJson.optLong("build", -1); + } + + + // currently not using. but in feature this may be used in settings screen to Enable/disable contents + public void updateCurrentKnownContents(JSONArray repoContents) { + if (cachedCurrentJson.has("known_contents")) { + cachedCurrentJson.remove("known_contents"); + } + JSONObject newKnown = new JSONObject(); + cachedCurrentJson.put("known_contents", newKnown); + for (Object _repoContent : repoContents) { + JSONObject repoContent = (JSONObject) _repoContent; + String id = repoContent.getString("id"); + boolean required = repoContent.optBoolean("required", false); + JSONObject jsonObject = new JSONObject() + .put("hash", repoContent.getString("hash")); + if (required) { + jsonObject.put("required", true); + } + newKnown.put(id, jsonObject); + } + } + + public String getCurrentPackContentHash(String id) { + if (cachedCurrentJson.has("known_contents")) { + try { + return cachedCurrentJson.getJSONObject("known_contents").getJSONObject(id).getString("hash"); + + } catch (Exception e) { + // if hash not found + return null; + } + } + return null; } @@ -120,6 +160,7 @@ public void onUpdate(FileDownloadConsumer it) { throw e; } parent.getPackJson().getJSONObject("current").put("build", repoJson.getLong("build")); + parent.updateJsonLatestUpdate(); AFiles.nioWriteText(path.resolve(DynamicPackModBase.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 66e5cd7..05064aa 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoSyncProcessV1.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoSyncProcessV1.java @@ -6,10 +6,7 @@ import com.adamcalculator.dynamicpack.PackUtil; import com.adamcalculator.dynamicpack.sync.PackSyncProgress; import com.adamcalculator.dynamicpack.sync.state.StateFileDeleted; -import com.adamcalculator.dynamicpack.util.AFiles; -import com.adamcalculator.dynamicpack.util.FileDownloadConsumer; -import com.adamcalculator.dynamicpack.util.Hashes; -import com.adamcalculator.dynamicpack.util.Urls; +import com.adamcalculator.dynamicpack.util.*; import org.json.JSONArray; import org.json.JSONObject; @@ -17,10 +14,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class DynamicRepoSyncProcessV1 { private final DynamicRepoRemote remote; @@ -54,6 +48,12 @@ public void run() throws IOException { progress.textLog("File deleted from resource-pack: " + s); AFiles.nioSmartDelete(path); } + + try { + remote.updateCurrentKnownContents(repoJson.getJSONArray("contents")); + } catch (Exception e) { + Out.error("Error while update known_packs. Not fatal", e); + } } public void close() throws IOException { @@ -66,6 +66,14 @@ private void processContent(JSONObject jsonContent) throws IOException { } String contentRemoteHash = jsonContent.getString("hash"); + String localCache = remote.getCurrentPackContentHash(id); + if (Objects.equals(localCache, contentRemoteHash)) { + progress.textLog("Skipping content " + id + " because local hash is equal with remote..."); + return; + } else { + progress.textLog("Content " + id + " local hash different with remote or null. Updating..."); + } + String url = jsonContent.getString("url"); String urlCompressed = jsonContent.optString("url_compressed", null); boolean compressSupported = urlCompressed != null; @@ -180,12 +188,16 @@ private List calcActiveContents() { while (i < contents.length()) { JSONObject content = contents.getJSONObject(i); String id = content.getString("id"); + + if (!InputValidator.isContentIdValid(id)) { + throw new RuntimeException("Id of content is not valid."); + } + if (remote.isContentActive(id) || content.optBoolean("required", false)) { activeContents.add(content); } i++; } - return activeContents; } } diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/pack/ModrinthRemote.java b/common/src/main/java/com/adamcalculator/dynamicpack/pack/ModrinthRemote.java index 84b25f8..127beed 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/ModrinthRemote.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/ModrinthRemote.java @@ -13,6 +13,8 @@ public class ModrinthRemote extends Remote { private Pack parent; + private JSONObject cachedCurrentJson; + private boolean usesCurrentGameVersion; private String projectId; private String gameVersion; @@ -21,21 +23,40 @@ public class ModrinthRemote extends Remote { public ModrinthRemote() { } - public void init(Pack parent, JSONObject json) { + public void init(Pack parent, JSONObject json, JSONObject current) { this.parent = parent; + this.cachedCurrentJson = current; this.projectId = json.getString("modrinth_project_id"); var ver = json.optString("game_version", "current"); - this.gameVersion = ver.equalsIgnoreCase("current") ? getCurrentGameVersion() : ver; + this.usesCurrentGameVersion = ver.equalsIgnoreCase("current"); + this.gameVersion = usesCurrentGameVersion ? getCurrentGameVersion() : ver; } private String getCurrentGameVersion() { return DynamicPackModBase.INSTANCE.getCurrentGameVersion(); } + public String getCurrentUnique() { + return cachedCurrentJson.optString("version", ""); + } + + + public String getCurrentVersionNumber() { + return cachedCurrentJson.optString("version_number", ""); + } + public String getVersionsUrl() { return "https://api.modrinth.com/v2/project/" + projectId + "/version"; } + public String getProjectId() { + return projectId; + } + + public boolean isUsesCurrentGameVersion() { + return usesCurrentGameVersion; + } + public JSONObject parseLatestVersionJson() throws IOException { String content = Urls.parseContent(getVersionsUrl(), Mod.MOD_MODTINTH_API_LIMIT); JSONArray j = new JSONArray(content); @@ -63,10 +84,10 @@ public boolean checkUpdateAvailable() throws IOException { Out.warn("Latest version of " + parent.getLocation().getName() + " not available for this game_version"); return false; } - if (latest.optString("version_number", "").equals(parent.getCurrentVersionNumber())) { + if (latest.optString("version_number", "").equals(getCurrentVersionNumber())) { return false; } - return !parent.getCurrentUnique().equals(latest.getString("id")); + return !getCurrentUnique().equals(latest.getString("id")); } @Override @@ -98,6 +119,7 @@ public void onUpdate(FileDownloadConsumer it) { parent.getPackJson().getJSONObject("current").put("version", latest.latestId); parent.getPackJson().getJSONObject("current").remove("version_number"); + parent.updateJsonLatestUpdate(); PackUtil.openPackFileSystem(tempFile, path -> AFiles.nioWriteText(path.resolve(DynamicPackModBase.CLIENT_FILE), parent.getPackJson().toString(2))); 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 1fbeabc..5a2bbca 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/Pack.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/Pack.java @@ -37,7 +37,7 @@ public Pack(File location, JSONObject json) { JSONObject remote = json.getJSONObject("remote"); String remoteType = remote.getString("type"); this.remote = Remote.REMOTES.get(remoteType).get(); - this.remote.init(this, remote); + this.remote.init(this, remote, cachedJson.getJSONObject("current")); } catch (Exception e) { throw new RuntimeException("Failed to parse remote", e); @@ -63,17 +63,18 @@ public JSONObject getPackJson() { return cachedJson; } - public long getCurrentBuild() { - return cachedJson.getJSONObject("current").optLong("build", -1); - } - public String getCurrentUnique() { - return cachedJson.getJSONObject("current").optString("version", ""); + public void updateJsonLatestUpdate() { + cachedJson.getJSONObject("current").put("latest_updated", System.currentTimeMillis() / 1000); } + public long getLatestUpdated() { + try { + return cachedJson.getJSONObject("current").getLong("latest_updated"); - public String getCurrentVersionNumber() { - return cachedJson.getJSONObject("current").optString("version_number", ""); + } catch (Exception e) { + return -1; + } } public boolean checkIsUpdateAvailable() throws IOException { diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/pack/Remote.java b/common/src/main/java/com/adamcalculator/dynamicpack/pack/Remote.java index 4f3d3f2..b155df5 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/Remote.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/Remote.java @@ -24,7 +24,7 @@ public static void initRemoteTypes() { REMOTES.put("dynamic_repo", DynamicRepoRemote::new); } - public abstract void init(Pack pack, JSONObject remote); + public abstract void init(Pack pack, JSONObject remote, JSONObject current); public abstract boolean checkUpdateAvailable() throws IOException; From 97fb0079320bc3ff76c6093365fdcc51bfc250f7 Mon Sep 17 00:00:00 2001 From: adam Date: Wed, 20 Mar 2024 17:39:00 +0700 Subject: [PATCH 4/7] disable skip because oldestFilesList not updating --- .../dynamicpack/pack/DynamicRepoSyncProcessV1.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 05064aa..d5421fb 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoSyncProcessV1.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoSyncProcessV1.java @@ -68,10 +68,9 @@ private void processContent(JSONObject jsonContent) throws IOException { String contentRemoteHash = jsonContent.getString("hash"); String localCache = remote.getCurrentPackContentHash(id); if (Objects.equals(localCache, contentRemoteHash)) { - progress.textLog("Skipping content " + id + " because local hash is equal with remote..."); - return; + progress.textLog("Content '" + id + "' local hash is equal with remote..."); } else { - progress.textLog("Content " + id + " local hash different with remote or null. Updating..."); + progress.textLog("Content '" + id + "' local hash different with remote or null."); } String url = jsonContent.getString("url"); From dfcd7aafb2e9e69b062cbbac3572d1149671d4b2 Mon Sep 17 00:00:00 2001 From: adam Date: Wed, 20 Mar 2024 19:08:24 +0700 Subject: [PATCH 5/7] noname commit --- .../dynamicpack/DynamicPackModBase.java | 6 ++++ .../com/adamcalculator/dynamicpack/Mod.java | 2 +- .../dynamicpack/pack/DynamicRepoRemote.java | 2 +- .../dynamicpack/pack/ModrinthRemote.java | 20 ++++++++++-- .../adamcalculator/dynamicpack/pack/Pack.java | 2 +- .../dynamicpack/pack/Remote.java | 2 +- .../dynamicpack/sync/SyncThread.java | 32 +++++++++++++++++++ .../dynamicpack/sync/SyncingTask.java | 8 ++++- .../adamcalculator/dynamicpack/util/Out.java | 4 +++ .../adamcalculator/dynamicpack/Compat.java | 13 ++++++++ .../dynamicpack/DebugScreen.java | 2 +- .../dynamicpack/DynamicPackScreen.java | 7 ++-- .../dynamicpack/FabricDynamicMod.java | 25 +++++++++++---- 13 files changed, 107 insertions(+), 18 deletions(-) create mode 100644 common/src/main/java/com/adamcalculator/dynamicpack/sync/SyncThread.java create mode 100644 src/client/java/com/adamcalculator/dynamicpack/Compat.java diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackModBase.java b/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackModBase.java index 19dc2ee..ecdca4b 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackModBase.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackModBase.java @@ -19,6 +19,7 @@ public abstract class DynamicPackModBase { public static final String MINECRAFT_META = "pack.mcmeta"; public static DynamicPackModBase INSTANCE; + protected static int manuallySyncThreadCounter = 0; private boolean isPacksScanning = false; private List packs = new ArrayList<>(); @@ -40,8 +41,13 @@ public void init(File gameDir) { startSyncThread(); } + /** + * ONLY FOR FIRST INIT RUN! FOR MANUALLY USE startManuallySync!!!!! + */ public abstract void startSyncThread(); + public abstract void startManuallySync(); + public void rescanPacks() { if (isPacksScanning) { Out.warn("rescanPacks already in scanning!"); diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/Mod.java b/common/src/main/java/com/adamcalculator/dynamicpack/Mod.java index b523e9e..830d46e 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/Mod.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/Mod.java @@ -101,7 +101,7 @@ public static boolean isHTTPTrafficAllowed() { // DebugScreen allowed public static boolean isDebugScreenAllowed() { - return true; + return false; } public static void debugNetwork() { 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 01623ff..fb74540 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoRemote.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/DynamicRepoRemote.java @@ -107,7 +107,7 @@ public String getCurrentPackContentHash(String id) { @Override - public boolean sync(PackSyncProgress progress) throws IOException, NoSuchAlgorithmException { + public boolean sync(PackSyncProgress progress, boolean manually) throws IOException, NoSuchAlgorithmException { PackUtil.openPackFileSystem(parent.getLocation(), path -> { try { sync0(progress, path); diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/pack/ModrinthRemote.java b/common/src/main/java/com/adamcalculator/dynamicpack/pack/ModrinthRemote.java index 127beed..1235d31 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/ModrinthRemote.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/ModrinthRemote.java @@ -85,16 +85,27 @@ public boolean checkUpdateAvailable() throws IOException { return false; } if (latest.optString("version_number", "").equals(getCurrentVersionNumber())) { + Out.debug("version number equal"); return false; } + Out.debug("version rem.id="+latest.getString("id") + "; curr=" + getCurrentUnique()); + return !getCurrentUnique().equals(latest.getString("id")); } @Override - public boolean sync(PackSyncProgress progress) throws IOException { + public boolean sync(PackSyncProgress progress, boolean manually) throws IOException { progress.textLog("getting latest version on modrinth..."); ModrinthRemote.LatestModrinthVersion latest = getLatest(); + if (manually) { + if (latest.latestId.equals(getCurrentUnique())) { + progress.textLog("Manually & version ids equal. skipping."); + + return false; + } + } + progress.textLog("downloading..."); File tempFile = null; int attempts = 3; @@ -140,6 +151,7 @@ public void onUpdate(FileDownloadConsumer it) { public LatestModrinthVersion getLatest() throws IOException { JSONObject latest = parseLatestVersionJson(); String latestId = latest.getString("id"); + String latestVersionNumber = latest.getString("version_number"); JSONArray files = latest.getJSONArray("files"); int i = 0; while (i < files.length()) { @@ -147,7 +159,7 @@ public LatestModrinthVersion getLatest() throws IOException { if (j.getBoolean("primary")) { String url = j.getString("url"); JSONObject hashes = j.getJSONObject("hashes"); - return new LatestModrinthVersion(latestId, url, hashes.getString("sha1")); + return new LatestModrinthVersion(latestId, latestVersionNumber, url, hashes.getString("sha1")); } i++; } @@ -157,11 +169,13 @@ public LatestModrinthVersion getLatest() throws IOException { public static class LatestModrinthVersion { public final String latestId; + public final String latestVersionNumber; public final String url; public final String fileHash; - public LatestModrinthVersion(String latestId, String url, String fileHash) { + public LatestModrinthVersion(String latestId, String latestVersionNumber, String url, String fileHash) { this.latestId = latestId; + this.latestVersionNumber = latestVersionNumber; this.url = url; this.fileHash = fileHash; } 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 5a2bbca..c7485bd 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/Pack.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/Pack.java @@ -112,7 +112,7 @@ private void sync0(PackSyncProgress progress, boolean manually) throws Exception progress.start(); progress.textLog("start syncing..."); - boolean reloadRequired = remote.sync(progress); + boolean reloadRequired = remote.sync(progress, manually); isSyncing = false; progress.done(reloadRequired); diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/pack/Remote.java b/common/src/main/java/com/adamcalculator/dynamicpack/pack/Remote.java index b155df5..1435582 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/Remote.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/Remote.java @@ -28,5 +28,5 @@ public static void initRemoteTypes() { public abstract boolean checkUpdateAvailable() throws IOException; - public abstract boolean sync(PackSyncProgress progress) throws IOException, NoSuchAlgorithmException; + public abstract boolean sync(PackSyncProgress progress, boolean manually) throws IOException, NoSuchAlgorithmException; } diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/sync/SyncThread.java b/common/src/main/java/com/adamcalculator/dynamicpack/sync/SyncThread.java new file mode 100644 index 0000000..d8e2894 --- /dev/null +++ b/common/src/main/java/com/adamcalculator/dynamicpack/sync/SyncThread.java @@ -0,0 +1,32 @@ +package com.adamcalculator.dynamicpack.sync; + +import java.util.function.Supplier; + +public class SyncThread extends Thread { + private static int counter = 0; + private static final long SLEEP_DELAY = 1000 * 60 * 60 * 24; // 24 hours + + private final Supplier taskSupplier; + + public SyncThread(Supplier taskSupplier) { + super("SyncThread" + (counter++)); + this.taskSupplier = taskSupplier; + } + + @Override + public void run() { + while (true) { + startSync(); + try { + Thread.sleep(SLEEP_DELAY); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + + + private void startSync() { + taskSupplier.get().run(); + } +} diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/sync/SyncingTask.java b/common/src/main/java/com/adamcalculator/dynamicpack/sync/SyncingTask.java index a5e7f1c..a9e3234 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/sync/SyncingTask.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/sync/SyncingTask.java @@ -12,7 +12,7 @@ * Re-check all packs and update packs with update available */ public class SyncingTask implements Runnable { - public static long threadCounter = 0; + public static boolean isSyncing = false; private final boolean manually; // skip checkUpdateAvailable(). private boolean reloadRequired = false; @@ -24,6 +24,11 @@ public SyncingTask(boolean manually) { @Override public void run() { + if (isSyncing) { + Out.warn("SyncTask already syncing...."); + return; + } + isSyncing = true; Out.println("SyncTask started!"); onSyncStart(); DynamicPackModBase.INSTANCE.rescanPacks(); @@ -39,6 +44,7 @@ public void run() { } onSyncDone(reloadRequired); Out.println("SyncTask ended!"); + isSyncing = false; } public void onPackDoneSuccess(Pack pack) {} diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/util/Out.java b/common/src/main/java/com/adamcalculator/dynamicpack/util/Out.java index 401130b..cf627f6 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/util/Out.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/util/Out.java @@ -62,4 +62,8 @@ public static void securityWarning(String s) { System.out.println("[dynamicpack] " + s); } } + + public static void debug(String s) { + println("DEBUG: " + s); + } } diff --git a/src/client/java/com/adamcalculator/dynamicpack/Compat.java b/src/client/java/com/adamcalculator/dynamicpack/Compat.java new file mode 100644 index 0000000..f24e674 --- /dev/null +++ b/src/client/java/com/adamcalculator/dynamicpack/Compat.java @@ -0,0 +1,13 @@ +package com.adamcalculator.dynamicpack; + +import net.minecraft.client.gui.Drawable; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.Selectable; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.text.Text; + +public class Compat { + public static T createButton(Text text, Runnable press, int w, int h, int x, int y) { + return (T) ButtonWidget.builder(text, button -> press.run()).size(w, h).position(x, y).build(); + } +} diff --git a/src/client/java/com/adamcalculator/dynamicpack/DebugScreen.java b/src/client/java/com/adamcalculator/dynamicpack/DebugScreen.java index f5c744b..ebe975c 100644 --- a/src/client/java/com/adamcalculator/dynamicpack/DebugScreen.java +++ b/src/client/java/com/adamcalculator/dynamicpack/DebugScreen.java @@ -18,6 +18,6 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { @Override protected void init() { - addDrawableChild(ButtonWidget.builder(Text.of("Re-Scan & Re-sync normally"), button -> DynamicPackModBase.INSTANCE.startSyncThread()).size(120, 20).position(this.width / 2, this.height / 2).build()); + addDrawableChild(ButtonWidget.builder(Text.of("Re-Scan & Re-sync normally"), button -> DynamicPackModBase.INSTANCE.startManuallySync()).size(120, 20).position(this.width / 2, this.height / 2).build()); } } diff --git a/src/client/java/com/adamcalculator/dynamicpack/DynamicPackScreen.java b/src/client/java/com/adamcalculator/dynamicpack/DynamicPackScreen.java index 9c26ed8..5cde355 100644 --- a/src/client/java/com/adamcalculator/dynamicpack/DynamicPackScreen.java +++ b/src/client/java/com/adamcalculator/dynamicpack/DynamicPackScreen.java @@ -4,7 +4,6 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.text.Text; public class DynamicPackScreen extends Screen { @@ -24,7 +23,11 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { @Override protected void init() { - addDrawableChild(ButtonWidget.builder(Text.of("Manually sync"), button -> DynamicPackModBase.INSTANCE.startSyncThread()).size(120, 20).position(this.width / 2, this.height / 2).build()); + addDrawableChild(Compat.createButton( + Text.of("Manually sync"), + () -> DynamicPackModBase.INSTANCE.startManuallySync(), + 100, 20, width - 120, 10 + )); } @Override diff --git a/src/client/java/com/adamcalculator/dynamicpack/FabricDynamicMod.java b/src/client/java/com/adamcalculator/dynamicpack/FabricDynamicMod.java index f278200..d253bd6 100644 --- a/src/client/java/com/adamcalculator/dynamicpack/FabricDynamicMod.java +++ b/src/client/java/com/adamcalculator/dynamicpack/FabricDynamicMod.java @@ -1,6 +1,7 @@ package com.adamcalculator.dynamicpack; import com.adamcalculator.dynamicpack.pack.Pack; +import com.adamcalculator.dynamicpack.sync.SyncThread; import com.adamcalculator.dynamicpack.sync.SyncingTask; import com.adamcalculator.dynamicpack.sync.state.StateDownloading; import com.adamcalculator.dynamicpack.sync.state.StateFileDeleted; @@ -43,23 +44,36 @@ public void onInitializeClient() { @Override public void startSyncThread() { - SyncingTask syncingTask = new SyncingTask(false) { + new SyncThread(() -> createSyncTask(false)).start(); + } + + @Override + public void startManuallySync() { + Thread thread = new Thread(() -> createSyncTask(true).run()); + thread.setName("DynamicPack-ManuallySyncThread" + (DynamicPackModBase.manuallySyncThreadCounter++)); + thread.start(); + } + + private SyncingTask createSyncTask(boolean manually) { + return new SyncingTask(manually) { @Override public void onSyncStart() { - setToastContent(Text.literal("DynamicPack"), Text.translatable("dynamicpack.toast.syncStarted")); + if (manually) setToastContent(Text.literal("DynamicPack"), Text.translatable("dynamicpack.toast.syncStarted")); } @Override public void onSyncDone(boolean reloadRequired) { - if (reloadRequired) { + if (manually || reloadRequired) { setToastContent(Text.literal("DynamicPack"), Text.translatable("dynamicpack.toast.done")); + } + if (reloadRequired) { tryToReloadResources(); } } @Override public void onStateChanged(Pack pack, SyncProgressState state) { - if (!FabricDynamicMod.SHOW_STATE) return; + if (!manually) return; if (state instanceof StateDownloading downloading) { setToastContent(Text.translatable("dynamicpack.toast.pack.state.downloading.title", pack.getName()), Text.translatable("dynamicpack.toast.pack.state.downloading.description", downloading.getPercentage(), downloading.getName())); @@ -72,9 +86,6 @@ public void onStateChanged(Pack pack, SyncProgressState state) { } } }; - Thread thread = new Thread(syncingTask); - thread.setName("DynamicPack-SyncTask" + (SyncingTask.threadCounter++)); - thread.start(); } @Override From af527f0305861bf15dedaa5c1a60cfaa6c6d7b02 Mon Sep 17 00:00:00 2001 From: adam Date: Wed, 20 Mar 2024 19:44:06 +0700 Subject: [PATCH 6/7] add - --- .../java/com/adamcalculator/dynamicpack/InputValidator.java | 2 +- common/src/test/java/tests/InputValidatorTest.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/InputValidator.java b/common/src/main/java/com/adamcalculator/dynamicpack/InputValidator.java index 696f4ca..80af5a6 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/InputValidator.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/InputValidator.java @@ -4,7 +4,7 @@ import java.util.regex.Pattern; public class InputValidator { - private static final Pattern CONTENT_ID_PATTERN = Pattern.compile("^[a-z0-9_:]{2,128}$"); + private static final Pattern CONTENT_ID_PATTERN = Pattern.compile("^[a-z0-9_:-]{2,128}$"); public static boolean isContentIdValid(String input) { if (input == null) { diff --git a/common/src/test/java/tests/InputValidatorTest.java b/common/src/test/java/tests/InputValidatorTest.java index 8ddcf0d..95230cd 100644 --- a/common/src/test/java/tests/InputValidatorTest.java +++ b/common/src/test/java/tests/InputValidatorTest.java @@ -15,6 +15,7 @@ public void testContentId() { Assertions.assertFalse(InputValidator.isContentIdValid("test\ntest")); Assertions.assertTrue(InputValidator.isContentIdValid("__")); + Assertions.assertTrue(InputValidator.isContentIdValid("_-")); Assertions.assertTrue(InputValidator.isContentIdValid("pack:megapack")); Assertions.assertTrue(InputValidator.isContentIdValid("1234567890")); Assertions.assertTrue(InputValidator.isContentIdValid("01")); From 263e50f550bf7968b9ee42f8f0b5b95bda38d0eb Mon Sep 17 00:00:00 2001 From: adam Date: Wed, 20 Mar 2024 20:18:25 +0700 Subject: [PATCH 7/7] GUI!!! --- .../dynamicpack/DynamicPackModBase.java | 13 +++++++---- .../adamcalculator/dynamicpack/PackUtil.java | 3 ++- .../adamcalculator/dynamicpack/pack/Pack.java | 10 +++++++++ .../FailedOpenPackFileSystemException.java | 22 +++++++++++++++++++ .../dynamicpack/DynamicPackScreen.java | 22 +++++++++++++++++-- .../dynamicpack/PackMixinHelper.java | 4 +++- .../mixin/client/ResourcePackScreenMixin.java | 16 ++++++++++++++ .../resources/dynamicpack.client.mixins.json | 3 ++- .../assets/dynamicpack/lang/en_us.json | 5 ++++- .../assets/dynamicpack/lang/ru_ru.json | 5 ++++- 10 files changed, 92 insertions(+), 11 deletions(-) create mode 100644 common/src/main/java/com/adamcalculator/dynamicpack/util/FailedOpenPackFileSystemException.java create mode 100644 src/client/java/com/adamcalculator/dynamicpack/mixin/client/ResourcePackScreenMixin.java diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackModBase.java b/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackModBase.java index ecdca4b..76a56e4 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackModBase.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/DynamicPackModBase.java @@ -3,6 +3,7 @@ import com.adamcalculator.dynamicpack.pack.Pack; import com.adamcalculator.dynamicpack.pack.Remote; import com.adamcalculator.dynamicpack.util.AFiles; +import com.adamcalculator.dynamicpack.util.FailedOpenPackFileSystemException; import com.adamcalculator.dynamicpack.util.Out; import org.json.JSONObject; @@ -61,18 +62,22 @@ public void rescanPacks() { PackUtil.openPackFileSystem(packFile, path -> { Path dynamicPackPath = path.resolve(CLIENT_FILE); if (Files.exists(dynamicPackPath)) { - Out.println(" + Pack " + packFile.getName() + " supported by mod!"); + Out.println("+ Pack " + packFile.getName() + " supported by mod!"); try { processPack(packFile, PackUtil.readJson(dynamicPackPath)); } catch (IOException e) { throw new RuntimeException(e); } } else { - Out.println(" - Pack " + packFile.getName() + " not supported by mod."); + Out.println("- Pack " + packFile.getName() + " not supported by mod."); } }); } catch (Exception e) { - Out.error("Error while processing pack: " + packFile, e); + if (e instanceof FailedOpenPackFileSystemException) { + Out.warn("Error while processing pack " + packFile.getName() + ": " + e.getMessage()); + } else { + Out.error("Error while processing pack: " + packFile.getName(), e); + } } } isPacksScanning = false; @@ -105,7 +110,7 @@ public boolean isNameIsDynamic(String name) { } public Pack getDynamicPackByMinecraftName(String name) { - for (Pack pack : packs) { + for (Pack pack : getPacks()) { if (("file/" + pack.getName()).equals(name)) { return pack; } diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/PackUtil.java b/common/src/main/java/com/adamcalculator/dynamicpack/PackUtil.java index fa7b5b5..02875b8 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/PackUtil.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/PackUtil.java @@ -1,5 +1,6 @@ package com.adamcalculator.dynamicpack; +import com.adamcalculator.dynamicpack.util.FailedOpenPackFileSystemException; import org.json.JSONObject; import java.io.File; @@ -56,7 +57,7 @@ public static void openPackFileSystem(File pack, Consumer consumer) throws } } else { - throw new RuntimeException("Failed to open pack file system"); + throw new FailedOpenPackFileSystemException("Failed to open pack file system"); } } 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 c7485bd..90ada74 100644 --- a/common/src/main/java/com/adamcalculator/dynamicpack/pack/Pack.java +++ b/common/src/main/java/com/adamcalculator/dynamicpack/pack/Pack.java @@ -27,6 +27,7 @@ public class Pack { private boolean cachedUpdateAvailable; private boolean isSyncing = false; + private final String remoteTypeStr; public Pack(File location, JSONObject json) { @@ -36,6 +37,7 @@ public Pack(File location, JSONObject json) { try { JSONObject remote = json.getJSONObject("remote"); String remoteType = remote.getString("type"); + this.remoteTypeStr = remoteType; this.remote = Remote.REMOTES.get(remoteType).get(); this.remote.init(this, remote, cachedJson.getJSONObject("current")); @@ -44,6 +46,10 @@ public Pack(File location, JSONObject json) { } } + public boolean isSyncing() { + return isSyncing; + } + public boolean isZip() { if (location.isDirectory()) { return false; @@ -144,4 +150,8 @@ private boolean checkMinecraftMetaIsValid(String s) { return false; } } + + public String getRemoteType() { + return remoteTypeStr; + } } diff --git a/common/src/main/java/com/adamcalculator/dynamicpack/util/FailedOpenPackFileSystemException.java b/common/src/main/java/com/adamcalculator/dynamicpack/util/FailedOpenPackFileSystemException.java new file mode 100644 index 0000000..f39ad3a --- /dev/null +++ b/common/src/main/java/com/adamcalculator/dynamicpack/util/FailedOpenPackFileSystemException.java @@ -0,0 +1,22 @@ +package com.adamcalculator.dynamicpack.util; + +public class FailedOpenPackFileSystemException extends RuntimeException { + public FailedOpenPackFileSystemException() { + } + + public FailedOpenPackFileSystemException(String message) { + super(message); + } + + public FailedOpenPackFileSystemException(String message, Throwable cause) { + super(message, cause); + } + + public FailedOpenPackFileSystemException(Throwable cause) { + super(cause); + } + + public FailedOpenPackFileSystemException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/client/java/com/adamcalculator/dynamicpack/DynamicPackScreen.java b/src/client/java/com/adamcalculator/dynamicpack/DynamicPackScreen.java index 5cde355..24491b9 100644 --- a/src/client/java/com/adamcalculator/dynamicpack/DynamicPackScreen.java +++ b/src/client/java/com/adamcalculator/dynamicpack/DynamicPackScreen.java @@ -4,20 +4,33 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.screen.ScreenTexts; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; + +import java.util.Date; public class DynamicPackScreen extends Screen { private final Screen parent; + private final Pack pack; + private final Text screenDescText; public DynamicPackScreen(Screen parent, Pack pack) { - super(Text.literal(pack.getName())); + super(Text.literal(pack.getName()).formatted(Formatting.BOLD)); + this.pack = pack; this.client = MinecraftClient.getInstance(); this.parent = parent; + this.screenDescText = Text.translatable("dynamicpack.screen.pack.description"); } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { renderBackground(context); + context.drawTextWithShadow(this.textRenderer, this.title, 20, 8, 16777215); + context.drawTextWithShadow(this.textRenderer, screenDescText, 20, 20, 16777215); + context.drawTextWithShadow(this.textRenderer, Text.translatable("dynamicpack.screen.pack.remote_type", pack.getRemoteType()), 20, 36, 16777215); + context.drawTextWithShadow(this.textRenderer, Text.translatable("dynamicpack.screen.pack.latestUpdated", pack.getLatestUpdated() < 0 ? "-" : new Date(pack.getLatestUpdated() * 1000)), 20, 52, 16777215); + super.render(context, mouseX, mouseY, delta); } @@ -25,9 +38,14 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { protected void init() { addDrawableChild(Compat.createButton( Text.of("Manually sync"), - () -> DynamicPackModBase.INSTANCE.startManuallySync(), + () -> { + DynamicPackModBase.INSTANCE.startManuallySync(); + close(); + }, 100, 20, width - 120, 10 )); + + addDrawableChild(Compat.createButton(ScreenTexts.DONE, this::close, 150, 20, this.width / 2 + 4, this.height - 48)); } @Override diff --git a/src/client/java/com/adamcalculator/dynamicpack/PackMixinHelper.java b/src/client/java/com/adamcalculator/dynamicpack/PackMixinHelper.java index a3d28b3..ea19f41 100644 --- a/src/client/java/com/adamcalculator/dynamicpack/PackMixinHelper.java +++ b/src/client/java/com/adamcalculator/dynamicpack/PackMixinHelper.java @@ -9,12 +9,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; public class PackMixinHelper { + private static final Identifier BUTTON_TEXTURE = Identifier.of("dynamicpack", "select_button.png"); + public static void renderResourcePackEntry(Object resourcePackEntryMixin, DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta, CallbackInfo ci) { PackListWidget.ResourcePackEntry entry = (PackListWidget.ResourcePackEntry) resourcePackEntryMixin; if (DynamicPackModBase.INSTANCE.isNameIsDynamic(entry.getName())) { int i = mouseX - x; int j = mouseY - y; - context.drawTexture(Identifier.of("dynamicpack", "select_button.png"), x + 174, y+16, 0.0F, ((i >= 174 && j >= 16 && hovered) ? 16f : 0f), 16, 16, 16, 32); + context.drawTexture(BUTTON_TEXTURE, x + 174, y+16, 0.0F, ((i >= 174 && j >= 16 && hovered) ? 16f : 0f), 16, 16, 16, 32); } } diff --git a/src/client/java/com/adamcalculator/dynamicpack/mixin/client/ResourcePackScreenMixin.java b/src/client/java/com/adamcalculator/dynamicpack/mixin/client/ResourcePackScreenMixin.java new file mode 100644 index 0000000..4109d1b --- /dev/null +++ b/src/client/java/com/adamcalculator/dynamicpack/mixin/client/ResourcePackScreenMixin.java @@ -0,0 +1,16 @@ +package com.adamcalculator.dynamicpack.mixin.client; + +import com.adamcalculator.dynamicpack.DynamicPackModBase; +import net.minecraft.client.gui.screen.pack.PackScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(PackScreen.class) +public class ResourcePackScreenMixin { + @Inject(at = @At("RETURN"), method = "updatePackLists") + private void updatePackLists(CallbackInfo ci) { + DynamicPackModBase.INSTANCE.rescanPacks(); + } +} diff --git a/src/client/resources/dynamicpack.client.mixins.json b/src/client/resources/dynamicpack.client.mixins.json index 2986611..b2855b1 100644 --- a/src/client/resources/dynamicpack.client.mixins.json +++ b/src/client/resources/dynamicpack.client.mixins.json @@ -4,7 +4,8 @@ "compatibilityLevel": "JAVA_17", "client": [ "MinecraftClientMixin", - "ResourcePackEntryMixin" + "ResourcePackEntryMixin", + "ResourcePackScreenMixin" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/assets/dynamicpack/lang/en_us.json b/src/main/resources/assets/dynamicpack/lang/en_us.json index 8e02ff5..042f466 100644 --- a/src/main/resources/assets/dynamicpack/lang/en_us.json +++ b/src/main/resources/assets/dynamicpack/lang/en_us.json @@ -12,5 +12,8 @@ "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.toast.pack.state.unknown.description": "Processing...", + "dynamicpack.screen.pack.description": "This resource pack support DynamicPack features!", + "dynamicpack.screen.pack.remote_type": "Remote type: %s", + "dynamicpack.screen.pack.latestUpdated": "Latest updated at: %s" } \ No newline at end of file diff --git a/src/main/resources/assets/dynamicpack/lang/ru_ru.json b/src/main/resources/assets/dynamicpack/lang/ru_ru.json index d489c2a..0f4e7cd 100644 --- a/src/main/resources/assets/dynamicpack/lang/ru_ru.json +++ b/src/main/resources/assets/dynamicpack/lang/ru_ru.json @@ -12,5 +12,8 @@ "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.toast.pack.state.unknown.description": "Обработка...", + "dynamicpack.screen.pack.description": "Этот ресурспак поддерживает возможности мода DynamicPack!", + "dynamicpack.screen.pack.remote_type": "Тип: %s", + "dynamicpack.screen.pack.latestUpdated": "Обновлён: %s" } \ No newline at end of file