diff --git a/lib/main.dart b/lib/main.dart index 9a2d290..049c60d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,13 +8,16 @@ import "path_picker_button.dart"; import "prefs.dart"; import "tech_app.dart"; -const String commit = String.fromEnvironment("commit", defaultValue: "development"); - +// == Hardcoded BlueMap CLI JAR download URL and hash == const blueMapCliJarUrl = "https://github.com/BlueMap-Minecraft/BlueMap/releases/download/" "v5.3/BlueMap-5.3-cli.jar"; +const blueMapCliJarHash = + "a0be9a36325f3caabc6306e9c6dd306aeec464b8abe907e93b6589659c8751f5"; //SHA256 String get blueMapCliJarName => blueMapCliJarUrl.split("/").last; +const String commit = String.fromEnvironment("commit", defaultValue: "development"); + final projectDirectoryProvider = Provider((ref) { final String? bluemapJarPath = Prefs.instance.projectPath; if (bluemapJarPath == null) { diff --git a/lib/path_picker_button.dart b/lib/path_picker_button.dart index 180b7fd..24d034e 100644 --- a/lib/path_picker_button.dart +++ b/lib/path_picker_button.dart @@ -1,10 +1,12 @@ import "dart:convert"; import "dart:io"; +import "package:crypto/crypto.dart"; import "package:file_picker/file_picker.dart"; import "package:flutter/material.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:path/path.dart" as p; +import "package:url_launcher/url_launcher_string.dart"; import "main.dart"; import "prefs.dart"; @@ -14,6 +16,8 @@ enum _PickingState { picking, scanning, downloading, + hashing, + wrongHash, running, } @@ -69,6 +73,14 @@ class _PathPickerButtonState extends ConsumerState { client.close(); } + // == Verify BlueMap CLI JAR hash == + setState(() => _pickingState = _PickingState.hashing); + final String hash = await bluemapJar.openRead().transform(sha256).join(); + if (hash != blueMapCliJarHash) { + setState(() => _pickingState = _PickingState.wrongHash); + return; + } + // == Run BlueMap CLI JAR to generate default configs == setState(() => _pickingState = _PickingState.running); ProcessResult run = await Process.run( @@ -121,6 +133,33 @@ class _PathPickerButtonState extends ConsumerState { ), ], ), + _PickingState.hashing => Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text("Verifying BlueMap CLI JAR hash..."), + const SizedBox(height: 8), + ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 300), + child: const LinearProgressIndicator(), + ), + ], + ), + _PickingState.wrongHash => Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text( + "Downloaded failed! Invalid hash!", + style: TextStyle(color: Colors.red), + ), + const SizedBox(height: 8), + ElevatedButton( + onPressed: () => launchUrlString( + "https://github.com/TechnicJelle/BlueMapGUI/issues/new", + ), + child: const Text("Contact developer"), + ), + ], + ), _PickingState.running => Column( mainAxisSize: MainAxisSize.min, children: [ diff --git a/pubspec.lock b/pubspec.lock index 7a71ae4..8575e0f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -135,7 +135,7 @@ packages: source: hosted version: "0.3.4+2" crypto: - dependency: transitive + dependency: "direct main" description: name: crypto sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 diff --git a/pubspec.yaml b/pubspec.yaml index 87a7a71..512b7c2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -28,6 +28,7 @@ environment: # the latest version available on pub.dev. To see which dependencies have newer # versions available, run `flutter pub outdated`. dependencies: + crypto: ^3.0.5 file_picker: ^8.1.2 flutter: sdk: flutter