3737import java .util .List ;
3838import java .util .Map ;
3939import java .util .Objects ;
40+ import java .util .StringJoiner ;
4041import java .util .regex .Pattern ;
4142import java .util .stream .Stream ;
4243
4647import static airsquared .blobsaver .app .Utils .getFirmwareList ;
4748import static airsquared .blobsaver .app .Utils .getSignedBetas ;
4849import static airsquared .blobsaver .app .Utils .getSignedFirmwares ;
50+ import static airsquared .blobsaver .app .Utils .isNumeric ;
4951
5052public class TSS extends Task <String > {
5153
@@ -95,13 +97,14 @@ protected String call() throws TSSException {
9597 System .out .println ("iosVersions = " + iosVersions );
9698 ArrayList <String > args = constructArgs ();
9799
98- StringBuilder responseBuilder = new StringBuilder ("Successfully saved blobs in\n " ).append (savePath );
99- if (manualIpswURL == null ) {
100- responseBuilder .append (iosVersions .size () == 1 ? "\n \n For version " : "\n \n For versions " );
101- }
102-
103- // can't use forEach() because exception won't be caught
100+ var alreadySaved = new StringJoiner (", " );
101+ var savedFor = new StringJoiner (", " );
104102 for (Utils .IOSVersion iosVersion : iosVersions ) {
103+ if (!Prefs .getAlwaysSaveNewBlobs () && checkAlreadySaved (iosVersion )) {
104+ alreadySaved .add (iosVersion .versionString ());
105+ continue ;
106+ }
107+
105108 try {
106109 saveFor (iosVersion , args );
107110 } catch (TSSException e ) {
@@ -113,11 +116,22 @@ protected String call() throws TSSException {
113116 }
114117
115118 if (iosVersion .versionString () != null ) {
116- responseBuilder .append (iosVersion .versionString ());
117- if (iosVersion != iosVersions .get (iosVersions .size () - 1 ))
118- responseBuilder .append (", " );
119+ savedFor .add (iosVersion .versionString ());
119120 }
120121 }
122+ StringBuilder responseBuilder = new StringBuilder ();
123+ if (manualIpswURL != null || savedFor .length () > 0 ) {
124+ responseBuilder .append ("Successfully saved blobs in\n " ).append (savePath );
125+ if (savedFor .length () > 0 ) {
126+ responseBuilder .append ("\n \n For version" ).append (iosVersions .size () == 1 ? " " : "s " ).append (savedFor );
127+ }
128+ if (alreadySaved .length () > 0 ) {
129+ responseBuilder .append ("\n \n " );
130+ }
131+ }
132+ if (alreadySaved .length () > 0 ) {
133+ responseBuilder .append ("Already saved for " ).append (alreadySaved );
134+ }
121135
122136 if (saveToTSSSaver || saveToSHSHHost ) {
123137 responseBuilder .append ("\n \n " );
@@ -133,6 +147,27 @@ protected String call() throws TSSException {
133147 return responseBuilder .toString ();
134148 }
135149
150+ private boolean checkAlreadySaved (Utils .IOSVersion ios ) {
151+ if (ios .versionString () == null ) {
152+ return false ;
153+ }
154+ var versionStringOnly = ios .versionString ().trim ().replaceFirst (" .*" , "" ); // strip out 'beta' labels
155+ // https://github.com/1Conan/tsschecker/blob/0bc6174c3c2f77a0de525b71e7d8ec0987f07aa1/tsschecker/tsschecker.c#L1262
156+ String fileName = "%s_%s_%s_%s-%s_%s.shsh2"
157+ .formatted (parseECID (), deviceIdentifier , getBoardConfig (), versionStringOnly , ios .buildid (), apnonce );
158+
159+ if (Files .exists (Path .of (savePath , fileName ))) {
160+ System .out .println ("Already Saved: " + fileName );
161+ return true ;
162+ }
163+ return false ;
164+ }
165+
166+ private long parseECID () {
167+ return isNumeric (ecid ) ? Long .parseLong (ecid )
168+ : Long .parseLong (ecid .startsWith ("0x" ) ? ecid .substring (2 ) : ecid , 16 );
169+ }
170+
136171
137172 private void saveFor (Utils .IOSVersion iosVersion , ArrayList <String > args ) throws TSSException {
138173 final int urlIndex = args .size () - 1 ;
@@ -203,7 +238,7 @@ private List<Utils.IOSVersion> getIOSVersions() throws TSSException {
203238 manualVersion .equals (iosVersion .versionString ())).findFirst ()
204239 .orElseThrow (() -> new TSSException ("No versions found." , false )));
205240 } else if (manualIpswURL != null ) {
206- return Collections .singletonList (new Utils .IOSVersion (null , manualIpswURL , null ));
241+ return Collections .singletonList (new Utils .IOSVersion (null , null , manualIpswURL , null ));
207242 } else if (includeBetas ) {
208243 return Stream .concat (getSignedFirmwares (deviceIdentifier ), getSignedBetas (deviceIdentifier )).toList ();
209244 } else { // all signed firmwares
@@ -391,7 +426,7 @@ public void showErrorAlert() {
391426 private void saveBlobsTSSSaver (StringBuilder responseBuilder ) {
392427 Map <Object , Object > deviceParameters = new HashMap <>();
393428
394- deviceParameters .put ("ecid" , String .valueOf (Long . parseLong ( ecid . startsWith ( "0x" ) ? ecid . substring ( 2 ) : ecid , 16 )));
429+ deviceParameters .put ("ecid" , String .valueOf (parseECID ( )));
395430 deviceParameters .put ("deviceIdentifier" , deviceIdentifier );
396431 deviceParameters .put ("boardConfig" , getBoardConfig ());
397432
0 commit comments