@@ -286,7 +286,7 @@ public void LoadPackage()
286286 subfiles . Add ( newSubfile ) ;
287287 }
288288 }
289- if ( MSKindexversion == 4 )
289+ else if ( MSKindexversion == 4 )
290290 {
291291 Console . WriteLine ( "index version 4" ) ;
292292 reader . BaseStream . Position += 4 ;
@@ -852,7 +852,7 @@ public void RebuildPackage()
852852
853853 utility . AddUIntToList ( output , ReverseEndianIfNeeded ( indexmajorversion ) ) ;
854854
855- utility . AddUIntToList ( output , ReverseEndianIfNeeded ( filecount ) ) ;
855+ utility . AddUIntToList ( output , ReverseEndianIfNeeded ( ( uint ) subfiles . Count ) ) ;
856856
857857 //offset 0x28
858858
@@ -890,40 +890,110 @@ public void RebuildPackage()
890890 output . Add ( 0x00 ) ;
891891 }
892892
893- //=====================================================================================
894- //ACTUALLY, ISN'T IT ORGANISED BY TYPE ID? (IN MSA, AT LEAST?) THAT MIGHT BE IMPORTANT
895- //and then, within a type id, it's alphabetical
896- //=====================================================================================
893+ //sort by type ID, and within a type ID, by hash
894+ subfiles = subfiles . OrderBy ( s => s . typeID ) . ThenBy ( s => s . hash ) . ToList ( ) ;
897895
898- foreach ( Subfile f in subfiles )
896+ List < IndexEntry > indexEntriesForWriting = new List < IndexEntry > ( ) ;
897+ List < uint > TypeIDsThatRequireCompression = new List < uint > ( ) ;
898+
899+ int [ ] subfileOffsets = new int [ subfiles . Count ] ;
900+
901+ for ( int f = 0 ; f < subfiles . Count ; f ++ )
899902 {
900- if ( f . filebytes == null || f . filebytes . Length == 0 ) //then the file was not modified or read, so transfer it directly from the old package
903+ subfileOffsets [ f ] = output . Count ;
904+
905+ bool typeIDhasIndexEntry = false ;
906+
907+ foreach ( IndexEntry entry in indexEntriesForWriting )
908+ {
909+ if ( entry . typeID == subfiles [ f ] . typeID )
910+ {
911+ entry . typeNumberOfInstances ++ ;
912+ typeIDhasIndexEntry = true ;
913+ break ;
914+ }
915+ }
916+
917+ if ( ! typeIDhasIndexEntry )
918+ {
919+ IndexEntry newIndexEntry = new IndexEntry ( ) ;
920+ newIndexEntry . typeID = subfiles [ f ] . typeID ;
921+ newIndexEntry . groupID = subfiles [ f ] . groupID ; //TODO: if files are compressed then group ID should be 2! Otherwise, 0
922+ newIndexEntry . indexnulls = 0 ;
923+ newIndexEntry . typeNumberOfInstances = 1 ;
924+
925+ if ( newIndexEntry . groupID != 0 )
926+ {
927+ TypeIDsThatRequireCompression . Add ( newIndexEntry . typeID ) ;
928+ }
929+
930+ indexEntriesForWriting . Add ( newIndexEntry ) ;
931+ }
932+
933+ if ( subfiles [ f ] . filebytes == null || subfiles [ f ] . filebytes . Length == 0 ) //then the file was not modified or read, so transfer it directly from the old package
901934 {
902- for ( int i = 0 ; i < f . filesize ; i ++ )
935+ for ( int i = 0 ; i < subfiles [ f ] . filesize ; i ++ )
903936 {
904- output . Add ( filebytes [ f . fileoffset + i ] ) ;
937+ output . Add ( filebytes [ subfiles [ f ] . fileoffset + i ] ) ;
905938 }
906939 }
907940 else //if it was modified or read, use the bytes from its filebytes array
908941 {
909- for ( int i = 0 ; i < f . filebytes . Length ; i ++ )
942+ subfiles [ f ] . filesize = ( uint ) subfiles [ f ] . filebytes . Length ;
943+ for ( int i = 0 ; i < subfiles [ f ] . filebytes . Length ; i ++ )
910944 {
911- output . Add ( f . filebytes [ i ] ) ;
945+ output . Add ( subfiles [ f ] . filebytes [ i ] ) ;
946+ MessageBox . Show ( "Need to ensure that the file is compressed if it needs to be" ) ;
912947 }
913948 }
949+
950+ while ( output . Count % 0x20 != 0 )
951+ {
952+ output . Add ( 0x00 ) ; //pad to multiple of 0x20
953+ }
914954 }
915955
916956 //that should bring us up to the start of the index table
917957
918- //=====================================================================================
919- //ACTUALLY, ISN'T IT ORGANISED BY TYPE ID? (IN MSA, AT LEAST?) THAT MIGHT BE IMPORTANT.
920- //and then, within a type id, it's alphabetical
921- //=====================================================================================
958+ uint newIndexOffset = ( uint ) output . Count ;
922959
960+ if ( packageType == PackageType . Agents )
961+ {
962+ utility . AddULongToList ( output , utility . ReverseEndianULong ( ( ulong ) indexEntriesForWriting . Count ) ) ;
963+
964+ for ( int i = 0 ; i < indexEntriesForWriting . Count ; i ++ ) //a bunch of entries that describe how many files there are of each type
965+ {
966+ utility . AddUIntToList ( output , utility . ReverseEndian ( indexEntriesForWriting [ i ] . typeID ) ) ;
967+ utility . AddUIntToList ( output , utility . ReverseEndian ( indexEntriesForWriting [ i ] . groupID ) ) ;
968+ utility . AddUIntToList ( output , utility . ReverseEndian ( indexEntriesForWriting [ i ] . typeNumberOfInstances ) ) ;
969+ utility . AddUIntToList ( output , utility . ReverseEndian ( indexEntriesForWriting [ i ] . indexnulls ) ) ;
970+ }
923971
972+ for ( int i = 0 ; i < subfiles . Count ; i ++ ) //go through the files and add them to the index list. They are organised by type, one type after the other. (So X number of type A, as described above, then Y number of type B...) Within a type, they are organised by hash
973+ {
974+ utility . AddULongToList ( output , utility . ReverseEndianULong ( subfiles [ i ] . hash ) ) ;
975+ utility . AddIntToList ( output , utility . ReverseEndianSigned ( subfileOffsets [ i ] ) ) ;
976+ utility . AddUIntToList ( output , utility . ReverseEndian ( subfiles [ i ] . filesize ) ) ;
977+ utility . AddUIntToList ( output , utility . ReverseEndian ( subfiles [ i ] . typeID ) ) ;
978+ utility . AddUIntToList ( output , utility . ReverseEndian ( subfiles [ i ] . groupID ) ) ;
924979
980+ if ( TypeIDsThatRequireCompression . Contains ( subfiles [ i ] . typeID ) )
981+ {
982+ utility . AddUIntToList ( output , utility . ReverseEndian ( subfiles [ i ] . uncompressedsize ) ) ;
983+ }
984+ }
925985
986+ utility . OverWriteUIntInList ( output , 0x28 , ReverseEndianIfNeeded ( newIndexOffset ) ) ;
987+ utility . OverWriteUIntInList ( output , 0x2C , ReverseEndianIfNeeded ( ( uint ) ( output . Count - newIndexOffset ) ) ) ;
988+ utility . OverWriteUIntInList ( output , 0x44 , ReverseEndianIfNeeded ( newIndexOffset ) ) ;
989+ }
990+ else
991+ {
992+ MessageBox . Show ( "only Agents works at the moment" ) ;
993+
994+ }
926995
996+ File . WriteAllBytes ( "test.package" , output . ToArray ( ) ) ;
927997 }
928998 }
929999
0 commit comments