1818
1919package airsquared .blobsaver .app ;
2020
21+ import com .google .gson .Gson ;
2122import javafx .concurrent .Task ;
2223
2324import java .io .File ;
2728import java .net .URI ;
2829import java .net .URISyntaxException ;
2930import java .net .URL ;
31+ import java .net .http .HttpResponse ;
3032import java .nio .file .Path ;
3133import java .util .ArrayList ;
3234import java .util .Collections ;
35+ import java .util .HashMap ;
3336import java .util .List ;
37+ import java .util .Map ;
3438import java .util .Objects ;
3539import java .util .regex .Matcher ;
3640import java .util .regex .Pattern ;
@@ -58,10 +62,12 @@ public class TSS extends Task<String> {
5862
5963 private final String apnonce , generator ;
6064
65+ private final boolean saveToTSSSaver , saveToSHSHHost ;
66+
6167 /**
6268 * Private constructor; use {@link TSS.Builder} instead
6369 */
64- private TSS (String deviceIdentifier , String ecid , String savePath , String boardConfig , String manualVersion , String manualIpswURL , String apnonce , String generator ) {
70+ private TSS (String deviceIdentifier , String ecid , String savePath , String boardConfig , String manualVersion , String manualIpswURL , String apnonce , String generator , boolean saveToTSSSaver , boolean saveToSHSHHost ) {
6571 this .deviceIdentifier = deviceIdentifier ;
6672 this .ecid = ecid ;
6773 this .savePath = savePath ;
@@ -70,6 +76,8 @@ private TSS(String deviceIdentifier, String ecid, String savePath, String boardC
7076 this .manualIpswURL = manualIpswURL ;
7177 this .apnonce = apnonce ;
7278 this .generator = generator ;
79+ this .saveToTSSSaver = saveToTSSSaver ;
80+ this .saveToSHSHHost = saveToSHSHHost ;
7381 }
7482
7583 /**
@@ -85,9 +93,9 @@ protected String call() throws TSSException {
8593 ArrayList <String > args = constructArgs ();
8694 final int urlIndex = args .size () - 1 ;
8795
88- StringBuilder sb = new StringBuilder ("Successfully saved blobs in\n " ).append (savePath );
96+ StringBuilder responseBuilder = new StringBuilder ("Successfully saved blobs in\n " ).append (savePath );
8997 if (manualIpswURL == null ) {
90- sb .append (iosVersions .size () == 1 ? "\n \n For version " : "\n \n For versions " );
98+ responseBuilder .append (iosVersions .size () == 1 ? "\n \n For version " : "\n \n For versions " );
9199 }
92100
93101 // can't use forEach() because exception won't be caught
@@ -106,14 +114,24 @@ protected String call() throws TSSException {
106114 }
107115
108116 if (iosVersion .versionString () != null ) {
109- sb .append (iosVersion .versionString ());
117+ responseBuilder .append (iosVersion .versionString ());
110118 if (iosVersion != iosVersions .get (iosVersions .size () - 1 ))
111- sb .append (", " );
119+ responseBuilder .append (", " );
112120 }
113121 }
114122
123+ if (saveToTSSSaver || saveToSHSHHost ) {
124+ responseBuilder .append ("\n \n " );
125+ }
126+ if (saveToTSSSaver ) {
127+ saveBlobsTSSSaver (responseBuilder );
128+ }
129+ if (saveToSHSHHost ) {
130+ saveBlobsSHSHHost (responseBuilder );
131+ }
132+
115133 Analytics .saveBlobs ();
116- return sb .toString ();
134+ return responseBuilder .toString ();
117135 }
118136
119137 private void checkInputs () throws TSSException {
@@ -122,6 +140,9 @@ private void checkInputs() throws TSSException {
122140 if (!deviceIdentifier .contains ("," ) || !hasCorrectIdentifierPrefix ) {
123141 throw new TSSException ("\" " + deviceIdentifier + "\" is not a valid identifier" , false );
124142 }
143+ if (boardConfig == null && Devices .doesRequireBoardConfig (deviceIdentifier )) {
144+ throw new TSSException ("A board configuration is required for this device." , false );
145+ }
125146 if (manualIpswURL != null ) { // check URL
126147 try {
127148 if (!ipswURLMatcher .reset (manualIpswURL ).matches ()) {
@@ -152,7 +173,7 @@ private List<Utils.IOSVersion> getIOSVersions() throws TSSException {
152173 try {
153174 if (manualVersion != null ) {
154175 return Collections .singletonList (getFirmwareList (deviceIdentifier ).filter (iosVersion ->
155- manualVersion .equals (iosVersion .versionString ())).findFirst ()
176+ manualVersion .equals (iosVersion .versionString ())).findFirst ()
156177 .orElseThrow (() -> new TSSException ("No versions found." , false )));
157178 } else if (manualIpswURL != null ) {
158179 return Collections .singletonList (new Utils .IOSVersion (null , manualIpswURL , null ));
@@ -172,8 +193,7 @@ private ArrayList<String> constructArgs() {
172193 //noinspection ResultOfMethodCallIgnored
173194 new File (savePath ).mkdirs ();
174195 Collections .addAll (args , tsscheckerPath , "--nocache" , "--save" , "--device" , deviceIdentifier , "--ecid" , ecid , "--save-path" , savePath );
175- Collections .addAll (args , "--boardconfig" ,
176- Objects .requireNonNullElse (boardConfig , Devices .getBoardConfig (deviceIdentifier )));
196+ Collections .addAll (args , "--boardconfig" , getBoardConfig ());
177197 if (apnonce != null ) {
178198 Collections .addAll (args , "--apnonce" , apnonce );
179199 if (generator != null ) {
@@ -187,6 +207,10 @@ private ArrayList<String> constructArgs() {
187207 return args ;
188208 }
189209
210+ private String getBoardConfig () {
211+ return Objects .requireNonNullElse (boardConfig , Devices .getBoardConfig (deviceIdentifier ));
212+ }
213+
190214 @ SuppressWarnings ("TextBlockMigration" )
191215 private void parseTSSLog (String tsscheckerLog ) throws TSSException {
192216 if (containsIgnoreCase (tsscheckerLog , "Saved shsh blobs" )) {
@@ -228,6 +252,7 @@ && containsIgnoreCase(tsscheckerLog, "checking tss status failed")) {
228252 @ SuppressWarnings ("UnusedReturnValue" )
229253 public static class Builder {
230254 private String device , ecid , savePath , boardConfig , manualVersion , manualIpswURL , apnonce , generator ;
255+ private boolean saveToTSSSaver , saveToSHSHHost ;
231256
232257 public Builder setDevice (String device ) {
233258 this .device = device ;
@@ -271,11 +296,21 @@ public Builder setGenerator(String generator) {
271296 return this ;
272297 }
273298
299+ public Builder saveToTSSSaver (boolean saveToTSSSaver ) {
300+ this .saveToTSSSaver = saveToTSSSaver ;
301+ return this ;
302+ }
303+
304+ public Builder saveToSHSHHost (boolean saveToSHSHHost ) {
305+ this .saveToSHSHHost = saveToSHSHHost ;
306+ return this ;
307+ }
308+
274309 public TSS build () {
275310 return new TSS (Objects .requireNonNull (device , "Device" ),
276311 Objects .requireNonNull (ecid , "ECID" ),
277312 Objects .requireNonNull (savePath , "Save Path" ),
278- boardConfig , manualVersion , manualIpswURL , apnonce , generator );
313+ boardConfig , manualVersion , manualIpswURL , apnonce , generator , saveToTSSSaver , saveToSHSHHost );
279314 }
280315 }
281316
@@ -308,4 +343,85 @@ public TSSException(String message, boolean isReportable, Throwable cause) {
308343
309344 }
310345
346+ private void saveBlobsTSSSaver (StringBuilder responseBuilder ) {
347+ Map <Object , Object > deviceParameters = new HashMap <>();
348+
349+ deviceParameters .put ("ecid" , String .valueOf (Long .parseLong (ecid , 16 )));
350+ deviceParameters .put ("deviceIdentifier" , deviceIdentifier );
351+ deviceParameters .put ("boardConfig" , getBoardConfig ());
352+
353+ if (generator != null ) {
354+ deviceParameters .put ("generator" , generator );
355+ }
356+ if (apnonce != null ) {
357+ deviceParameters .put ("apnonce" , apnonce );
358+ }
359+
360+ System .out .println (deviceParameters );
361+ var headers = new HashMap <String , String >();
362+ headers .put ("Content-Type" , "application/x-www-form-urlencoded" );
363+
364+ HttpResponse <String > response ;
365+ try {
366+ response = Network .makePOSTRequest ("https://tsssaver.1conan.com/v2/api/save.php" , deviceParameters , headers , true );
367+ } catch (IOException | InterruptedException e ) {
368+ e .printStackTrace ();
369+ responseBuilder .append ("Error encountered while trying to save blobs to TSSSaver: " ).append (e .getMessage ());
370+ return ;
371+ }
372+ System .out .println (response .body ());
373+
374+ @ SuppressWarnings ("rawtypes" ) Map responseBody = new Gson ().fromJson (response .body (), Map .class );
375+
376+ if (responseBody .containsKey ("errors" )) {
377+ responseBuilder .append ("Error encountered while trying to save blobs to TSSSaver: " ).append (responseBody .get ("errors" ));
378+ } else {
379+ responseBuilder .append ("Also saved blobs online to TSS Saver." );
380+ }
381+ }
382+
383+ private void saveBlobsSHSHHost (StringBuilder responseBuilder ) {
384+ if (saveToTSSSaver ) {
385+ responseBuilder .append ("\n " );
386+ }
387+
388+ Map <Object , Object > deviceParameters = new HashMap <>();
389+
390+ deviceParameters .put ("ecid" , ecid );
391+ deviceParameters .put ("boardconfig" , getBoardConfig ());
392+ deviceParameters .put ("device" , deviceIdentifier );
393+ deviceParameters .put ("selected_firmware" , "All" );
394+
395+ if (generator != null ) {
396+ deviceParameters .put ("generator" , generator );
397+ }
398+ if (apnonce != null ) {
399+ deviceParameters .put ("apnonce" , apnonce );
400+ }
401+
402+ System .out .println (deviceParameters );
403+ String userAgent = "Blobsaver " + Main .appVersion ;
404+ var headers = new HashMap <String , String >();
405+ headers .put ("Content-Type" , "application/x-www-form-urlencoded" );
406+ headers .put ("User-Agent" , userAgent );
407+ headers .put ("X-CPU-STATE" , "0000000000000000000000000000000000000000" );
408+
409+ HttpResponse <String > response ;
410+ try {
411+ response = Network .makePOSTRequest ("https://api.arx8x.net/shsh3/" , deviceParameters , headers , false );
412+ } catch (IOException | InterruptedException e ) {
413+ e .printStackTrace ();
414+ responseBuilder .append ("Error encountered while trying to save blobs to SHSH Host: " ).append (e .getMessage ());
415+ return ;
416+ }
417+ System .out .println (response .body ());
418+
419+ @ SuppressWarnings ("rawtypes" ) Map responseBody = new Gson ().fromJson (response .body (), Map .class );
420+
421+ if (responseBody .get ("code" ).equals ((double ) 0 )) {
422+ responseBuilder .append ("Also saved blobs online to SHSH Host." );
423+ } else {
424+ responseBuilder .append ("Error encountered while trying to save blobs to SHSH Host: " ).append (responseBody .get ("message" ));
425+ }
426+ }
311427}
0 commit comments