diff --git a/src/main/java/com/skycatdev/binarysearchtool/CliUi.java b/src/main/java/com/skycatdev/binarysearchtool/CliUi.java index 0bccdcc..0f35fad 100644 --- a/src/main/java/com/skycatdev/binarysearchtool/CliUi.java +++ b/src/main/java/com/skycatdev/binarysearchtool/CliUi.java @@ -53,9 +53,16 @@ public void initialize(SearchHandler searchHandler) { } @Override - public void onFinished(Mod problematicMod) { + public void onFinished(ArrayList problematicMods) { assert searchHandler != null : "searchHandler should be the one calling, why is it null?"; - System.out.printf("Finished! The problematic mod was: %s (%s)%n", problematicMod.name(), problematicMod.filename()); + if (problematicMods.size() == 1) { + System.out.printf("Finished! The problematic mod was: %s (%s)%n", problematicMods.getFirst().name(), problematicMods.getFirst().filename()); + } else { + System.out.println("Finished! The following mods rely on each other, and one is the problem:"); + for (Mod problematicMod : problematicMods) { + System.out.printf("%s (%s)", problematicMod.name(), problematicMod.filename()); + } + } } @Override diff --git a/src/main/java/com/skycatdev/binarysearchtool/SearchGui.java b/src/main/java/com/skycatdev/binarysearchtool/SearchGui.java index c868780..16e8ea3 100644 --- a/src/main/java/com/skycatdev/binarysearchtool/SearchGui.java +++ b/src/main/java/com/skycatdev/binarysearchtool/SearchGui.java @@ -167,10 +167,19 @@ public Future asyncDisplayOption(String title, String text, MessageType me } @Override - public void onFinished(Mod problematicMod) { - JOptionPane.showMessageDialog(this, "Finished! The problematic mod is " + problematicMod.name() + "."); + public void onFinished(ArrayList problematicMods) { failureButton.setEnabled(false); successButton.setEnabled(false); + if (problematicMods.size() == 1) { + JOptionPane.showMessageDialog(this, "Finished! The problematic mod is " + problematicMods.getFirst().name() + "."); + } else { + StringBuilder message = new StringBuilder("Finished! The problem is one of these mods, which all rely on each other:"); + for (Mod problematicMod : problematicMods) { + message.append('\n'); + message.append(problematicMod.name()); + } + JOptionPane.showMessageDialog(this, message); + } } @Override diff --git a/src/main/java/com/skycatdev/binarysearchtool/SearchHandler.java b/src/main/java/com/skycatdev/binarysearchtool/SearchHandler.java index 83a3cea..0e23c33 100644 --- a/src/main/java/com/skycatdev/binarysearchtool/SearchHandler.java +++ b/src/main/java/com/skycatdev/binarysearchtool/SearchHandler.java @@ -163,7 +163,7 @@ public void bisect(boolean lastSuccessful) { finished = true; ui.updateLists(candidateMods, workingMods); ui.updateProgress(iterations, maxIterations); - ui.onFinished(candidateMods.getFirst()); + ui.onFinished(candidateMods); enableAll(mods); return; } else { @@ -174,17 +174,41 @@ public void bisect(boolean lastSuccessful) { } Main.log("Beginning bisection"); // Choose mods to use - candidateMods.sort(Comparator.comparing((mod) -> mod.dependencies().size())); - ui.updateLists(candidateMods, workingMods); - ui.updateProgress(iterations, maxIterations); - int candidatesSize = candidateMods.size(); - while (testingMods.size() < candidatesSize / 2) { - // Add the mod to the testing set, remove it from the candidate set - Mod mod = candidateMods.removeFirst(); - testingMods.add(mod); - Main.log("Added mod " + mod.name()); - addDeps(mod); + int rotation = 0; + boolean choseMods = false; + while (rotation < candidateMods.size()) { + candidateMods.sort(Comparator.comparing((mod) -> mod.dependencies().size())); + rotateList(candidateMods, rotation); + ui.updateLists(candidateMods, workingMods); + ui.updateProgress(iterations, maxIterations); + int candidatesSize = candidateMods.size(); + while (testingMods.size() < candidatesSize / 2) { + // Add the mod to the testing set, remove it from the candidate set + Mod mod = candidateMods.removeFirst(); + testingMods.add(mod); + Main.log("Added mod " + mod.name()); + addDeps(mod); + } + if (!candidateMods.isEmpty()) { + choseMods = true; + break; + } + Main.log("Unhelpful search set, rotating"); + candidateMods.addAll(testingMods); + testingMods.clear(); + testingDependencies.clear(); + rotation++; } + if (!choseMods) { + iterations++; + finished = true; + ui.updateLists(candidateMods, workingMods); + ui.updateProgress(iterations, maxIterations); + ui.onFinished(candidateMods); + enableAll(mods); + return; + } + for (Mod mod : forceEnabled) { enableMod(mod); Main.log("Added force-enabled mod " + mod.name()); @@ -198,6 +222,12 @@ public void bisect(boolean lastSuccessful) { Main.log("Bottom of bisect"); } + private static void rotateList(ArrayList list, int rotation) { + for (int i = 0; i < rotation; i++) { + list.addLast(list.removeFirst()); + } + } + private void disableAll(ArrayList mods) { for (Mod testingMod : mods) { disableMod(testingMod); diff --git a/src/main/java/com/skycatdev/binarysearchtool/SearchUi.java b/src/main/java/com/skycatdev/binarysearchtool/SearchUi.java index f9080ec..a33f51b 100644 --- a/src/main/java/com/skycatdev/binarysearchtool/SearchUi.java +++ b/src/main/java/com/skycatdev/binarysearchtool/SearchUi.java @@ -13,7 +13,7 @@ public interface SearchUi { Future asyncDisplayOption(String title, String text, MessageType messageType, Option[] options); SearchHandler getSearchHandler(); - void onFinished(Mod problematicMod); + void onFinished(ArrayList problematicMods); void initialize(SearchHandler searchHandler);