From 656ec493940b99ca0e004286416111df8186ccf8 Mon Sep 17 00:00:00 2001 From: oxydien Date: Sun, 15 Sep 2024 20:21:44 +0200 Subject: [PATCH] Fixed the issues from last commit, - Added back fabric-api (for translations) - Maximized amount of threads to 4 (to not overload mod serving sites) - Probably fixed `ConcurrentModificationException` issue - Fixed maximum character limit in ui - Fixed crash when opening sync screen while downloading --- gradle.properties | 2 +- .../dev/oxydien/data/ContentSyncProgress.java | 32 +++++++++++-------- src/main/java/dev/oxydien/data/SyncData.java | 3 +- .../dev/oxydien/ui/SetSyncRemoteScreen.java | 1 + .../dev/oxydien/ui/SyncFullViewScreen.java | 12 +++++-- .../oxydien/workers/ModDownloadWorker.java | 22 +++++++------ src/main/resources/fabric.mod.json | 1 + 7 files changed, 44 insertions(+), 29 deletions(-) diff --git a/gradle.properties b/gradle.properties index aa0190b..c532480 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ yarn_mappings=1.21.1+build.3 loader_version=0.16.5 # Mod Properties -mod_version=1.1.0 +mod_version=1.1.1 maven_group=dev.oxydien archives_base_name=simple-mod-sync diff --git a/src/main/java/dev/oxydien/data/ContentSyncProgress.java b/src/main/java/dev/oxydien/data/ContentSyncProgress.java index dd0105c..8cc6c3a 100644 --- a/src/main/java/dev/oxydien/data/ContentSyncProgress.java +++ b/src/main/java/dev/oxydien/data/ContentSyncProgress.java @@ -3,18 +3,21 @@ import dev.oxydien.enums.ContentSyncOutcome; import org.jetbrains.annotations.Nullable; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + public class ContentSyncProgress { private final int index; - private int progress; - private ContentSyncOutcome outcome; - private Exception exception; + private final AtomicInteger progress; + private AtomicReference outcome; + private AtomicReference exception; public ContentSyncProgress(int index, int progress) { this.index = index; - this.progress = progress; - this.outcome = ContentSyncOutcome.IN_PROGRESS; - this.exception = null; + this.progress = new AtomicInteger(progress); + this.outcome = new AtomicReference<>(ContentSyncOutcome.IN_PROGRESS); + this.exception = new AtomicReference<>(null); } public int getIndex() { @@ -22,28 +25,29 @@ public int getIndex() { } public int getProgress() { - return this.progress; + return this.progress.get(); } public ContentSyncOutcome getOutcome() { - return this.outcome; + return this.outcome.get(); } public Exception getException() { - return this.exception; + return this.exception.get(); } public void setProgress(int progress) { - this.progress = progress; + this.progress.set(progress); } public void setOutcome(ContentSyncOutcome outcome, @Nullable Exception exception) { - this.outcome = outcome; - this.exception = exception; + this.outcome.set(outcome); + this.exception.set(exception); } public boolean isError() { - return this.outcome == ContentSyncOutcome.INVALID_URL || this.outcome == ContentSyncOutcome.DOWNLOAD_INTERRUPTED || - this.outcome == ContentSyncOutcome.ALREADY_EXISTS; + var outcome = this.getOutcome(); + return outcome == ContentSyncOutcome.INVALID_URL || outcome == ContentSyncOutcome.DOWNLOAD_INTERRUPTED || + outcome == ContentSyncOutcome.ALREADY_EXISTS; } } diff --git a/src/main/java/dev/oxydien/data/SyncData.java b/src/main/java/dev/oxydien/data/SyncData.java index 2ece853..bec7bd8 100644 --- a/src/main/java/dev/oxydien/data/SyncData.java +++ b/src/main/java/dev/oxydien/data/SyncData.java @@ -2,6 +2,7 @@ import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.List; public class SyncData { @@ -18,7 +19,7 @@ public int getSyncVersion() { } public List getContent() { - return content; + return Collections.unmodifiableList(this.content); } public static class Content { diff --git a/src/main/java/dev/oxydien/ui/SetSyncRemoteScreen.java b/src/main/java/dev/oxydien/ui/SetSyncRemoteScreen.java index 232569d..f813843 100644 --- a/src/main/java/dev/oxydien/ui/SetSyncRemoteScreen.java +++ b/src/main/java/dev/oxydien/ui/SetSyncRemoteScreen.java @@ -37,6 +37,7 @@ public void init() { // URL field widget TextFieldWidget remote_url = new TextFieldWidget(this.textRenderer, this.width / 2 - 100, this.height / 2 + 20, 200, 20, Text.literal("")); + remote_url.setMaxLength(368); this.addDrawableChild(remote_url); // Auto download toggle button widget diff --git a/src/main/java/dev/oxydien/ui/SyncFullViewScreen.java b/src/main/java/dev/oxydien/ui/SyncFullViewScreen.java index d247126..3b112c6 100644 --- a/src/main/java/dev/oxydien/ui/SyncFullViewScreen.java +++ b/src/main/java/dev/oxydien/ui/SyncFullViewScreen.java @@ -17,6 +17,7 @@ import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -66,6 +67,7 @@ public void init() { // Url field TextFieldWidget urlField = new TextFieldWidget(this.textRenderer, this.width / 2 - 150, 24, 300, 20, Text.literal("")); + urlField.setMaxLength(368); urlField.setText(Config.instance.getDownloadUrl()); this.addDrawableChild(urlField); @@ -112,8 +114,10 @@ public void render(DrawContext context, int mouseX, int mouseY, float delta) { super.render(context, mouseX, mouseY, delta); int index = 0; - for (ContentSyncProgressWidget widget : progress.values().stream() - .sorted(Comparator.comparingInt(w -> w.getProgress() == 0 ? Integer.MAX_VALUE : w.getProgress())).toList()) { + List sortedWidgets = new ArrayList<>(progress.values()); + sortedWidgets.sort(Comparator.comparingInt(w -> w != null && w.getProgress() == 0 ? Integer.MAX_VALUE : w != null ? w.getProgress() : Integer.MAX_VALUE)); + for (ContentSyncProgressWidget widget : sortedWidgets) { + if (widget == null) continue; if (index >= page * pageSize && index < (page + 1) * pageSize) { widget.setPosition(this.width / 2 - widget.getWidth() / 2, 70 + (index - page * pageSize) * widget.getHeight() + (index - page * pageSize) * 3); @@ -140,7 +144,9 @@ public void onProgress(CallbackReason reason) { } ContentSyncProgressWidget widget = progress.get(content.getIndex()); - widget.setProgress(modProgress); + if (widget != null) { + widget.setProgress(modProgress); + } } } } diff --git a/src/main/java/dev/oxydien/workers/ModDownloadWorker.java b/src/main/java/dev/oxydien/workers/ModDownloadWorker.java index 6bef952..097b45f 100644 --- a/src/main/java/dev/oxydien/workers/ModDownloadWorker.java +++ b/src/main/java/dev/oxydien/workers/ModDownloadWorker.java @@ -33,7 +33,7 @@ public class ModDownloadWorker implements Runnable { @Nullable private SyncData syncData; private SyncErrorType errorType; private final AtomicInteger overallProgress; - public static List callbacks = new ArrayList<>(); + public static List callbacks = new CopyOnWriteArrayList<>(); private final AtomicReference workerThread; private final AtomicReference> modProgress; private CompletionService completionService; @@ -65,8 +65,8 @@ public ModDownloadWorker() { this.errorType = SyncErrorType.NONE; this.workerThread = new AtomicReference<>(); this.overallProgress = new AtomicInteger(0); - this.modProgress = new AtomicReference<>(new ArrayList<>()); - this.executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + this.modProgress = new AtomicReference<>(new CopyOnWriteArrayList<>()); + this.executorService = Executors.newFixedThreadPool(Math.min(Runtime.getRuntime().availableProcessors(), 4)); this.completionService = new ExecutorCompletionService<>(this.executorService); } @@ -145,10 +145,12 @@ public void run() { changed |= future.get(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); - SimpleModSync.LOGGER.error("[SMS-WORKER] Download process was interrupted", e); + SimpleModSync.LOGGER.error("[SMS-WORKER] Download process was interrupted for {}", + this.syncData.getContent().get(i).getModName(), e); break; } catch (ExecutionException e) { - SimpleModSync.LOGGER.error("[SMS-WORKER] Error during parallel download", e); + SimpleModSync.LOGGER.error("[SMS-WORKER] Error during parallel download for {}", + this.syncData.getContent().get(i).getModName(), e); } } @@ -202,7 +204,7 @@ private boolean downloadMod(SyncData.Content content) { Path olderVersion = PathUtils.PathExistsFromStartInDir(Config.instance.getDownloadDestination(), content.getModName()); if (olderVersion != null) { - SimpleModSync.LOGGER.info("[SMS-WORKER] Found older version, deleting {}", olderVersion.getFileName()); + SimpleModSync.LOGGER.info("[SMS-WORKER] Found older version of {}, deleting {}", content.getModName(), olderVersion.getFileName()); try { Files.delete(olderVersion); } catch (IOException e) { @@ -215,11 +217,11 @@ private boolean downloadMod(SyncData.Content content) { FileDownloader.downloadFileWithProgress(content.getUrl(), path, (progress) -> this.updateModProgress(content.getIndex(), progress, ContentSyncOutcome.IN_PROGRESS, null)); } catch (IOException e) { - SimpleModSync.LOGGER.error("[SMS-WORKER] Failed to download file", e); + SimpleModSync.LOGGER.error("[SMS-WORKER] Failed to download file {}", content.getModName(), e); this.updateModProgress(content.getIndex(), 100, ContentSyncOutcome.DOWNLOAD_INTERRUPTED , e); return false; } catch (URISyntaxException e) { - SimpleModSync.LOGGER.error("[SMS-WORKER] Failed to download file", e); + SimpleModSync.LOGGER.error("[SMS-WORKER] Failed to download file {}", content.getModName(), e); this.updateModProgress(content.getIndex(), 100, ContentSyncOutcome.INVALID_URL , e); return false; } @@ -308,10 +310,10 @@ private void setState(SyncState state) { public void start() { Thread thread = new Thread(this); this.syncData = null; - this.modProgress.set(new ArrayList<>()); + this.modProgress.set(new CopyOnWriteArrayList<>()); this.overallProgress.set(0); this.errorType = null; - this.executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + this.executorService = Executors.newFixedThreadPool(Math.min(Runtime.getRuntime().availableProcessors(), 4)); this.completionService = new ExecutorCompletionService<>(this.executorService); this.setState(SyncState.INITIALIZING); this.workerThread.set(thread); diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 0cf2faf..ad7401d 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -28,6 +28,7 @@ "depends": { "fabricloader": ">=0.16.5", "minecraft": "~1.21.1", + "fabric-api": "*", "java": ">=21" } }