warning dialog for unsupported groove.exe versions at start and before the first apply of a session (nothing blocked)
This commit is contained in:
1 parent
ff6673af66
commit
932ccf5fc8
6 files changed
+123
-2
No files matched your search
+2
-1
@@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
- **English game version supported.** All exe mods (boot to level, cheats, intro skip, practice
|
- **English game version supported.** All exe mods (boot to level, cheats, intro skip, practice
|
||||||
tools, free camera) and the base patch now also work with the English groove.exe of
|
tools, free camera) and the base patch now also work with the English groove.exe of
|
||||||
2000-10-17; other unknown versions still stop with a clear message.
|
2000-10-17. With any other version LlamaMod warns at start and before the first Apply (nothing
|
||||||
|
is blocked); mods that change groove.exe then stop with a clear message.
|
||||||
- **Display diagnostics option renamed and explained.** The cheats option is now called
|
- **Display diagnostics option renamed and explained.** The cheats option is now called
|
||||||
"Troubleshooting: write display diagnostics" and warns that the game switches through every
|
"Troubleshooting: write display diagnostics" and warns that the game switches through every
|
||||||
screen mode of every monitor at start (screens go black for a while). It stays off by default.
|
screen mode of every monitor at start (screens go black for a while). It stays off by default.
|
||||||
|
|||||||
@@ -104,7 +104,8 @@ after an update, **Settings → Clear cache** throws it away; active mods are re
|
|||||||
|
|
||||||
**Which versions of the game work?**
|
**Which versions of the game work?**
|
||||||
The German CD (`groove.exe` of 2001-02-12) and the English first release (2000-10-17) are
|
The German CD (`groove.exe` of 2001-02-12) and the English first release (2000-10-17) are
|
||||||
supported, including every mod. With another version the level mods still work, but the mods
|
supported, including every mod. With another version LlamaMod shows a warning at start and before
|
||||||
|
the first Apply (nothing is blocked); the level mods still work, but the mods
|
||||||
marked *modifies groove.exe* stop with "unknown program version" – the first lines of
|
marked *modifies groove.exe* stop with "unknown program version" – the first lines of
|
||||||
`logs/apply.log` name the version LlamaMod found. Please report it together with that
|
`logs/apply.log` name the version LlamaMod found. Please report it together with that
|
||||||
`groove.exe`, then it can be added.
|
`groove.exe`, then it can be added.
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ final class MainFrame extends JFrame {
|
|||||||
private boolean crashReported;
|
private boolean crashReported;
|
||||||
private boolean oldWineAccepted;
|
private boolean oldWineAccepted;
|
||||||
private final RecoveryNotice recoveryNotice = new RecoveryNotice();
|
private final RecoveryNotice recoveryNotice = new RecoveryNotice();
|
||||||
|
final UnsupportedExeWarning exeWarning = new UnsupportedExeWarning();
|
||||||
private boolean recoveryRunning;
|
private boolean recoveryRunning;
|
||||||
|
|
||||||
MainFrame(AppState state) {
|
MainFrame(AppState state) {
|
||||||
@@ -223,6 +224,9 @@ final class MainFrame extends JFrame {
|
|||||||
showRecovery(state.recovery);
|
showRecovery(state.recovery);
|
||||||
state.recovery = ModManager.Recovery.NONE;
|
state.recovery = ModManager.Recovery.NONE;
|
||||||
}
|
}
|
||||||
|
if (inst) {
|
||||||
|
SwingUtilities.invokeLater(() -> exeWarning.atStart(this, state));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tells the user once that an interrupted apply was repaired; BUSY is retried later. */
|
/** Tells the user once that an interrupted apply was repaired; BUSY is retried later. */
|
||||||
|
|||||||
@@ -677,6 +677,7 @@ final class ModsPanel extends JPanel {
|
|||||||
}
|
}
|
||||||
List<Mod> mods = selected();
|
List<Mod> mods = selected();
|
||||||
ModManager mm = frame.state.modManager;
|
ModManager mm = frame.state.modManager;
|
||||||
|
frame.exeWarning.beforeApply(frame, frame.state);
|
||||||
if (!AntivirusDialogs.notice(frame, mm.exeMods(mods), true)) {
|
if (!AntivirusDialogs.notice(frame, mm.exeMods(mods), true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package com.eliasmueller.llamamod.ui;
|
||||||
|
|
||||||
|
import com.eliasmueller.llamamod.exe.GameExe;
|
||||||
|
import com.eliasmueller.llamamod.platform.FileOps;
|
||||||
|
import com.eliasmueller.llamamod.platform.Integrity;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warns (never blocks) when the installed groove.exe is not one of the supported builds: once at
|
||||||
|
* start and once before the first Apply of a session.
|
||||||
|
*/
|
||||||
|
final class UnsupportedExeWarning {
|
||||||
|
private boolean shownAtStart;
|
||||||
|
private boolean shownAtApply;
|
||||||
|
private String checkedSha;
|
||||||
|
private boolean unsupported;
|
||||||
|
|
||||||
|
/** The warning text, or null if the build is supported or unknown because nothing is installed. */
|
||||||
|
static String message(String sha256) {
|
||||||
|
if (sha256 == null || sha256.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (GameExe.Build b : GameExe.Build.values()) {
|
||||||
|
if (b.sha256.equalsIgnoreCase(sha256)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "You are running an unsupported version of the game. Mods, especially mods that modify"
|
||||||
|
+ " groove.exe, probably won't work.\n\nSupported are: "
|
||||||
|
+ Arrays.stream(GameExe.Build.values())
|
||||||
|
.map(GameExe.Build::toString)
|
||||||
|
.collect(Collectors.joining(", "))
|
||||||
|
+ ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** SHA-256 of the set-up original groove.exe ("" if not installed or unreadable). */
|
||||||
|
static String installedSha(AppState state) {
|
||||||
|
if (!state.cfg.installed()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (!state.cfg.exeSha256.isEmpty()) {
|
||||||
|
return state.cfg.exeSha256;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Path hd = state.paths.originalHd();
|
||||||
|
Path exe = Files.isDirectory(hd) ? Integrity.find(hd, "groove.exe") : null;
|
||||||
|
return exe != null && Files.isRegularFile(exe) ? FileOps.sha256(exe) : "";
|
||||||
|
} catch (IOException e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String current(AppState state) {
|
||||||
|
String sha = installedSha(state);
|
||||||
|
if (!sha.equals(checkedSha)) {
|
||||||
|
checkedSha = sha;
|
||||||
|
unsupported = message(sha) != null;
|
||||||
|
shownAtStart = false;
|
||||||
|
shownAtApply = false;
|
||||||
|
}
|
||||||
|
return unsupported ? message(sha) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void atStart(Component parent, AppState state) {
|
||||||
|
String m = current(state);
|
||||||
|
if (m != null && !shownAtStart) {
|
||||||
|
shownAtStart = true;
|
||||||
|
JOptionPane.showMessageDialog(parent, m, "Unsupported game version", JOptionPane.WARNING_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Shows the warning before the first Apply of a session; Apply always continues afterwards. */
|
||||||
|
void beforeApply(Component parent, AppState state) {
|
||||||
|
String m = current(state);
|
||||||
|
if (m != null && !shownAtApply) {
|
||||||
|
shownAtApply = true;
|
||||||
|
JOptionPane.showMessageDialog(parent, m, "Unsupported game version", JOptionPane.WARNING_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.eliasmueller.llamamod.ui;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import com.eliasmueller.llamamod.exe.GameExe;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class UnsupportedExeWarningTest {
|
||||||
|
@Test
|
||||||
|
void supportedBuildsAndMissingInstallGiveNoWarning() {
|
||||||
|
for (GameExe.Build b : GameExe.Build.values()) {
|
||||||
|
assertNull(UnsupportedExeWarning.message(b.sha256));
|
||||||
|
assertNull(UnsupportedExeWarning.message(b.sha256.toUpperCase()));
|
||||||
|
}
|
||||||
|
assertNull(UnsupportedExeWarning.message(""));
|
||||||
|
assertNull(UnsupportedExeWarning.message(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void otherBuildsAreWarnedAboutAndTheSupportedOnesListed() {
|
||||||
|
String m = UnsupportedExeWarning.message("00".repeat(32));
|
||||||
|
assertNotNull(m);
|
||||||
|
assertTrue(m.startsWith("You are running an unsupported version of the game."), m);
|
||||||
|
assertTrue(m.contains("German version of 2001-02-12") && m.contains("English version of 2000-10-17"), m);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user