From d4ca612bff5fc1752f1bda18c8d0b80d81bef543 Mon Sep 17 00:00:00 2001 From: Sevastjan <80479533+Anon8281@users.noreply.github.com> Date: Fri, 21 Jul 2023 17:11:48 +0300 Subject: [PATCH] =?UTF-8?q?[FEATURE]=20=D0=A4=D0=B8=D0=BA=D1=81=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=B8=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=8C=20=D0=B2=D0=B7=D0=B0=D0=B8=D0=BC=D0=BE?= =?UTF-8?q?=D0=B8=D1=81=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BE=D0=BF=D1=86=D0=B8=D0=BE=D0=BD=D0=B0?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D1=8B=D1=85=20=D0=BC=D0=BE=D0=B4=D0=BE=D0=B2?= =?UTF-8?q?=20(#663)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [FEATURE] Mutually exclusive optional mods (XOR logic) * [FIX] Bug with missing forgotten dependency/conflict * [FIX] ArrayIndexOutOfBoundsException if xorConfict is empty * [STYLE] Rename "xorConflict" to "group" --- .../launcher/profiles/ClientProfile.java | 11 +++++ .../profiles/optional/OptionalFile.java | 4 ++ .../profiles/optional/OptionalView.java | 41 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java index b0265d08..36c533ee 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/ClientProfile.java @@ -254,6 +254,12 @@ public void updateOptionalGraph() { file.conflict[i] = getOptionalFile(file.conflictFile[i].name); } } + if(file.groupFile != null) { + file.group = new OptionalFile[file.groupFile.length]; + for(int i = 0; i < file.groupFile.length; ++i) { + file.group[i] = getOptionalFile(file.groupFile[i].name); + } + } } } @@ -369,6 +375,11 @@ public void verify() { if (s == null) throw new IllegalArgumentException(String.format("Found null entry in updateOptional.%s.dependenciesFile", f.name)); } + if(f.groupFile != null) + for (OptionalDepend s : f.groupFile) { + if (s == null) + throw new IllegalArgumentException(String.format("Found null entry in updateOptional.%s.groupFile", f.name)); + } if (f.triggersList != null) { for (OptionalTrigger trigger : f.triggersList) { if (trigger == null) diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/OptionalFile.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/OptionalFile.java index a5ad4f25..bbe85fc9 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/OptionalFile.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/OptionalFile.java @@ -24,10 +24,14 @@ public class OptionalFile { @LauncherNetworkAPI public OptionalDepend[] conflictFile; @LauncherNetworkAPI + public OptionalDepend[] groupFile; + @LauncherNetworkAPI public transient OptionalFile[] dependencies; @LauncherNetworkAPI public transient OptionalFile[] conflict; @LauncherNetworkAPI + public transient OptionalFile[] group; + @LauncherNetworkAPI public int subTreeLevel = 1; @LauncherNetworkAPI public boolean isPreset; diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/OptionalView.java b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/OptionalView.java index 658edd0b..25fdb266 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/OptionalView.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/profiles/optional/OptionalView.java @@ -7,7 +7,9 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.Arrays; import java.util.function.BiConsumer; +import java.util.stream.Collectors; public class OptionalView { public Set enabled = new HashSet<>(); @@ -25,6 +27,7 @@ public OptionalView(OptionalView view) { this.enabled = new HashSet<>(view.enabled); this.installInfo = new HashMap<>(view.installInfo); this.all = view.all; + fixDependencies(); } public OptionalView(ClientProfile profile, OptionalView old) { @@ -40,6 +43,7 @@ public OptionalView(ClientProfile profile, OptionalView old) { disable(newFile, (file, status) -> {}); } } + fixDependencies(); } @SuppressWarnings("unchecked") @@ -80,6 +84,33 @@ public Set getEnabledActions() { return results; } + //Needed if dependency/conflict was added after mod declaring it and clients have their profiles with this mod enabled + public void fixDependencies() { + Set disabled = all.stream().filter(t -> !isEnabled(t)).collect(Collectors.toSet()); + for (OptionalFile file : disabled) { + if (file.group != null && Arrays.stream(file.group).noneMatch(this::isEnabled)) { + enable(file.group[0], false, null); + } + } + for (OptionalFile file : enabled) { + if (file.dependencies != null) { + for (OptionalFile dep : file.dependencies) { + enable(dep, false, null); + } + } + if (file.conflict != null) { + for (OptionalFile conflict : file.conflict) { + disable(conflict, null); + } + } + if (file.group != null) { + for (OptionalFile member : file.group) { + disable(member, null); + } + } + } + } + public Set getDisabledActions() { Set results = new HashSet<>(); for (OptionalFile e : all) { @@ -111,6 +142,11 @@ public void enable(OptionalFile file, boolean manual, BiConsumer callback) { @@ -129,6 +165,11 @@ public void disable(OptionalFile file, BiConsumer callbac } } } + if (file.group != null && file.group.length != 0) { + if (Arrays.stream(file.group).noneMatch(this::isEnabled)) { + enable(file.group[0], false, callback); + } + } } private boolean contains(OptionalFile file, OptionalFile[] array) {