Skip to content

Commit 21a28b5

Browse files
committed
Fix running from .jar file and Windows support
1 parent c3c61d4 commit 21a28b5

File tree

6 files changed

+105
-88
lines changed

6 files changed

+105
-88
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# blobsaver
2-
A GUI for saving SHSH blobs using tsschecker. Supports both Mac and <s>Windows</s>(not yet).
2+
A GUI for saving SHSH blobs using encounter's fork of tsschecker. Supports both Mac and Windows.
3+
4+
If you have an antivirus, select "Always Allow" for anything related to tsschecker or Java. An antivirus may cause blobsaver to crash. If that happens please send feedback.
35

46
# Features
57
- Store up to three devices with presets
@@ -9,5 +11,6 @@ A GUI for saving SHSH blobs using tsschecker. Supports both Mac and <s>Windows</
911

1012
# TODO:
1113
- Show success/failure using alerts
12-
- Windows support
14+
- Menu bar
15+
- Check for updates and prompt if available
1316
- Choose where to save blobs

src/META-INF/MANIFEST.MF

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Manifest-Version: 1.0
2+
Main-Class: blobsaver.Main
3+

src/blobsaver/Controller.java

Lines changed: 90 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package blobsaver;
22

3+
import com.sun.javafx.PlatformUtil;
34
import javafx.beans.value.ObservableValue;
45
import javafx.collections.FXCollections;
56
import javafx.collections.ObservableList;
@@ -19,7 +20,7 @@
1920
import java.net.URISyntaxException;
2021
import java.util.ArrayList;
2122
import java.util.Arrays;
22-
import java.util.Properties;
23+
import java.util.prefs.Preferences;
2324

2425
public class Controller {
2526

@@ -137,7 +138,6 @@ public void initialize() {
137138
});
138139
goButton.setDefaultButton(true);
139140

140-
141141
errorBorder.setOffsetY(0f);
142142
errorBorder.setOffsetX(0f);
143143
errorBorder.setColor(Color.RED);
@@ -146,7 +146,48 @@ public void initialize() {
146146
}
147147

148148
private void run(String device) {
149-
ArrayList<String> args = new ArrayList<>(Arrays.asList(getClass().getResource("tsschecker").getPath(), "-d", device, "-s", "-e", ecidField.getText()));
149+
File file;
150+
try {
151+
InputStream input;
152+
if (PlatformUtil.isWindows()) {
153+
input = getClass().getResourceAsStream("tsschecker.exe");
154+
file = File.createTempFile("tsschecker", ".tmp.exe");
155+
} else {
156+
input = getClass().getResourceAsStream("tsschecker");
157+
file = File.createTempFile("tsschecker", ".tmp");
158+
}
159+
OutputStream out = new FileOutputStream(file);
160+
int read;
161+
byte[] bytes = new byte[1024];
162+
163+
while ((read = input.read(bytes)) != -1) {
164+
out.write(bytes, 0, read);
165+
}
166+
out.close();
167+
} catch (IOException ex) {
168+
ex.printStackTrace();
169+
return;
170+
}
171+
file.deleteOnExit();
172+
173+
if (!file.setExecutable(true, false)) {
174+
Alert alert = new Alert(Alert.AlertType.ERROR, "There was an error setting tsschecker as executable.\n\nPlease create a new issue on Github or PM me on Reddit.", githubIssue, redditPM, ButtonType.CANCEL);
175+
alert.showAndWait();
176+
try {
177+
if (alert.getResult().equals(githubIssue) && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
178+
Desktop.getDesktop().browse(new URI("https://github.com/airsquared/blobsaver/issues/new"));
179+
} else if (alert.getResult().equals(redditPM) && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
180+
Desktop.getDesktop().browse(new URI("https://www.reddit.com//message/compose?to=01110101_00101111&subject=Blobsaver+Bug+Report"));
181+
}
182+
} catch (IOException | URISyntaxException ee) {
183+
ee.printStackTrace();
184+
}
185+
return;
186+
}
187+
188+
ArrayList<String> args;
189+
args = new ArrayList<>(Arrays.asList(file.getPath(), "-d", device, "-s", "-e", ecidField.getText()));
190+
150191
if (boardConfig) {
151192
args.add("--boardconfig");
152193
args.add(boardConfigField.getText());
@@ -163,6 +204,7 @@ private void run(String device) {
163204
}
164205
Process proc = null;
165206
try {
207+
System.out.println(args.toString());
166208
proc = new ProcessBuilder(args).start();
167209
} catch (IOException e) {
168210
Alert alert = new Alert(Alert.AlertType.ERROR, "There was an error starting tsschecker.\n\nPlease create a new issue on Github or PM me on Reddit. The crash log has been copied to your clipboard", githubIssue, redditPM, ButtonType.CANCEL);
@@ -182,10 +224,14 @@ private void run(String device) {
182224
e.printStackTrace();
183225
}
184226
try (BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()))) {
185-
String line = "";
227+
StringBuilder log = new StringBuilder();
228+
String line;
186229
while ((line = reader.readLine()) != null) {
187230
System.out.print(line + "\n");
231+
log.append(line).append("\n");
188232
}
233+
Alert alert = new Alert(Alert.AlertType.INFORMATION, log.toString(), ButtonType.OK);
234+
alert.showAndWait();
189235
} catch (IOException e) {
190236
Alert alert = new Alert(Alert.AlertType.ERROR, "There was an error getting the tsschecker log.\n\nPlease create a new issue on Github or PM me on Reddit. The crash log has been copied to your clipboard", githubIssue, redditPM, ButtonType.CANCEL);
191237
StringSelection stringSelection = new StringSelection(e.toString());
@@ -222,6 +268,12 @@ private void run(String device) {
222268
ee.printStackTrace();
223269
}
224270
}
271+
272+
if (!file.delete()) {
273+
Alert alert = new Alert(Alert.AlertType.ERROR, "There was an error deleting the temporary file.", githubIssue, redditPM, ButtonType.CANCEL);
274+
alert.showAndWait();
275+
}
276+
225277
}
226278

227279
public void apnonceCheckBoxHandler() {
@@ -288,63 +340,37 @@ public void identifierCheckBoxHandler() {
288340

289341
@SuppressWarnings("unchecked")
290342
private void loadPreset(int preset) {
291-
File file;
292-
try {
293-
file = new File(getClass().getResource("preset" + Integer.toString(preset) + ".properties").toURI());
294-
if (file.exists()) {
295-
Properties prop = new Properties();
296-
try (InputStream input = new FileInputStream(file)) {
297-
prop.load(input);
298-
ecidField.setText(prop.getProperty("ecid"));
299-
if (prop.getProperty("deviceModel").equals("none")) {
300-
identifierCheckBox.fire();
301-
identifierField.setText(prop.getProperty("deviceIdentifier"));
302-
} else {
303-
deviceTypeChoiceBox.setValue(prop.getProperty("deviceType"));
304-
deviceModelChoiceBox.setValue(prop.getProperty("deviceModel"));
305-
}
306-
if (!prop.getProperty("boardConfig").equals("none")) {
307-
boardConfigField.setText(prop.getProperty("boardConfig"));
308-
}
309-
} catch (IOException e) {
310-
Alert alert = new Alert(Alert.AlertType.ERROR, "There was an error loading the profile.\n\nPlease create a new issue on Github or PM me on Reddit. The crash log has been copied to your clipboard", githubIssue, redditPM, ButtonType.CANCEL);
311-
StringSelection stringSelection = new StringSelection(e.toString());
312-
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
313-
alert.showAndWait();
314-
try {
315-
if (alert.getResult().equals(githubIssue) && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
316-
Desktop.getDesktop().browse(new URI("https://github.com/airsquared/blobsaver/issues/new"));
317-
318-
} else if (alert.getResult().equals(redditPM) && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
319-
Desktop.getDesktop().browse(new URI("https://www.reddit.com//message/compose?to=01110101_00101111&subject=Blobsaver+Bug+Report"));
320-
}
321-
} catch (IOException | URISyntaxException ee) {
322-
ee.printStackTrace();
323-
}
324-
e.printStackTrace();
325-
}
326-
}
327-
} catch (URISyntaxException e) {
328-
e.printStackTrace();
329-
} catch (NullPointerException e) {
330-
Alert alert = new Alert(Alert.AlertType.ERROR, "Preset " + preset + " does not have anything", ButtonType.OK);
331-
alert.showAndWait();
343+
Preferences prefs = Preferences.userRoot().node("airsquared/blobsaver/preset" + preset);
344+
ecidField.setText(prefs.get("ECID", ""));
345+
if (prefs.get("Device Model", "").equals("none")) {
346+
identifierCheckBox.setSelected(true);
347+
identifierCheckBoxHandler();
348+
identifierField.setText(prefs.get("Device Identifier", ""));
349+
} else {
350+
identifierCheckBox.setSelected(false);
351+
identifierCheckBoxHandler();
352+
deviceTypeChoiceBox.setValue(prefs.get("Device Type", ""));
353+
deviceModelChoiceBox.setValue(prefs.get("Device Model", ""));
332354
}
355+
if (!prefs.get("Board Config", "").equals("none")) {
356+
boardConfigField.setText(prefs.get("Board Config", ""));
357+
}
358+
333359
}
334360

335361
public void presetButtonHandler(ActionEvent evt) {
336362
Button btn = (Button) evt.getTarget();
337363
String text = btn.getText();
338364
int preset = Integer.valueOf(text.substring(text.length() - 1));
339365
if (editingPresets) {
340-
saveOptions(preset);
341-
saveOptionsHandler();
366+
savePreset(preset);
367+
savePresetHandler();
342368
} else {
343369
loadPreset(preset);
344370
}
345371
}
346372

347-
private void saveOptions(int preset) {
373+
private void savePreset(int preset) {
348374
boolean doReturn = false;
349375
if (ecidField.getText().equals("")) {
350376
ecidField.setEffect(errorBorder);
@@ -365,45 +391,25 @@ private void saveOptions(int preset) {
365391
if (doReturn) {
366392
return;
367393
}
368-
Properties prop = new Properties();
369-
File file = new File(getClass().getResource("").toString().substring(5), "preset" + Integer.toString(preset) + ".properties");
370-
try (OutputStream output = new FileOutputStream(file)) {
371-
prop.setProperty("ecid", ecidField.getText());
372-
if (identifierCheckBox.isSelected()) {
373-
prop.setProperty("deviceType", "none");
374-
prop.setProperty("deviceModel", "none");
375-
prop.setProperty("deviceIdentifier", identifierField.getText());
376-
} else {
377-
prop.setProperty("deviceType", (String) deviceTypeChoiceBox.getValue());
378-
prop.setProperty("deviceModel", (String) deviceModelChoiceBox.getValue());
379-
}
380-
if (boardConfig) {
381-
prop.setProperty("boardConfig", boardConfigField.getText());
382-
} else {
383-
prop.setProperty("boardConfig", "none");
384-
}
385-
prop.store(output, null);
386-
} catch (IOException e) {
387-
Alert alert = new Alert(Alert.AlertType.ERROR, "There was an error while saving the data.\n\nPlease create a new issue on Github or PM me on Reddit. The crash log has been copied to your clipboard", githubIssue, redditPM, ButtonType.CANCEL);
388-
StringSelection stringSelection = new StringSelection(e.toString());
389-
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
390-
alert.showAndWait();
391-
try {
392-
if (alert.getResult().equals(githubIssue) && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
393-
Desktop.getDesktop().browse(new URI("https://github.com/airsquared/blobsaver/issues/new"));
394-
395-
} else if (alert.getResult().equals(redditPM) && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
396-
Desktop.getDesktop().browse(new URI("https://www.reddit.com//message/compose?to=01110101_00101111&subject=Blobsaver+Bug+Report"));
397-
}
398-
} catch (IOException | URISyntaxException ee) {
399-
ee.printStackTrace();
400-
}
401-
402-
e.printStackTrace();
394+
Preferences prefs = Preferences.userRoot().node("airsquared/blobsaver/preset" + preset);
395+
prefs.putBoolean("Exists", true);
396+
prefs.put("ECID", ecidField.getText());
397+
if (identifierCheckBox.isSelected()) {
398+
prefs.put("Device Type", "none");
399+
prefs.put("Device Model", "none");
400+
prefs.put("Device Identifier", identifierField.getText());
401+
} else {
402+
prefs.put("Device Type", (String) deviceTypeChoiceBox.getValue());
403+
prefs.put("Device Model", (String) deviceModelChoiceBox.getValue());
404+
}
405+
if (boardConfig) {
406+
prefs.put("Board Config", boardConfigField.getText());
407+
} else {
408+
prefs.put("Board Config", "none");
403409
}
404410
}
405411

406-
public void saveOptionsHandler() {
412+
public void savePresetHandler() {
407413
editingPresets = !editingPresets;
408414
if (editingPresets) {
409415
int depth = 40;

src/blobsaver/Main.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package blobsaver;
22

3+
import com.sun.javafx.PlatformUtil;
34
import javafx.application.Application;
45
import javafx.fxml.FXMLLoader;
56
import javafx.scene.Parent;
@@ -16,7 +17,11 @@ public static void main(String[] args) {
1617
public void start(Stage primaryStage) throws Exception {
1718
Parent root = FXMLLoader.load(getClass().getResource("blobsaver.fxml"));
1819
primaryStage.setTitle("SHSH Blob Saver 1.0 beta");
19-
primaryStage.setScene(new Scene(root, 500, 420));
20+
if (PlatformUtil.isWindows()) {
21+
primaryStage.setScene(new Scene(root, 520, 450));
22+
} else {
23+
primaryStage.setScene(new Scene(root, 500, 420));
24+
}
2025
primaryStage.getScene().getStylesheets().add(getClass().getResource("app.css").toExternalForm());
2126
primaryStage.show();
2227
primaryStage.setResizable(false);

src/blobsaver/blobsaver.fxml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
<Insets left="10.0" right="5.0"/>
105105
</HBox.margin>
106106
</Button>
107-
<Button mnemonicParsing="false" onAction="#saveOptionsHandler" text="Save as preset">
107+
<Button mnemonicParsing="false" onAction="#savePresetHandler" text="Save as preset">
108108
<HBox.margin>
109109
<Insets left="5.0" right="5.0"/>
110110
</HBox.margin>

src/blobsaver/tsschecker.exe

1.9 MB
Binary file not shown.

0 commit comments

Comments
 (0)