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