@@ -39,7 +39,7 @@ type Header struct {
3939 LoadedFrom versionShort8 `json:"loaded_from"`
4040 LoadedFromBuild uint16 `json:"loaded_from_build"`
4141 AllowedCommads uint8 `json:"allowed_commads"`
42- NumMods uint8 `json:"num_mods"`
42+ NumMods uint32 `json:"num_mods"`
4343 Mods []singleMod `json:"mods"`
4444}
4545type singleMod struct {
@@ -50,10 +50,13 @@ type singleMod struct {
5050
5151var ErrorIncompatible = errors .New ("incompatible save" )
5252var data Header
53+ var constraintGreaterThan0_16 * semver.Constraints
5354
5455func ReadHeader (filePath string ) (Header , error ) {
5556 var err error
5657
58+ constraintGreaterThan0_16 , _ = semver .NewConstraint (">= 0.16.0" )
59+
5760 datFile , err := openSave (filePath )
5861 if err != nil {
5962 log .Printf ("error opening file: %s" , err )
@@ -67,7 +70,7 @@ func ReadHeader(filePath string) (Header, error) {
6770 return data , err
6871 }
6972
70- Constraint , _ := semver .NewConstraint ("0.16.0 - 0.17.0" )
73+ Constraint , _ := semver .NewConstraint ("0.14.14 - 0.17.0" )
7174 Compatible , err := data .FactorioVersion .CheckCompatibility (Constraint )
7275 if err != nil {
7376 log .Printf ("Error checking compatibility: %s" , err )
@@ -79,19 +82,19 @@ func ReadHeader(filePath string) (Header, error) {
7982 return data , ErrorIncompatible
8083 }
8184
82- data .Campaign , err = readUTF8String (datFile )
85+ data .Campaign , err = readUTF8String (datFile , false )
8386 if err != nil {
8487 log .Printf ("Cant read Campaign: %s" , err )
8588 return data , err
8689 }
8790
88- data .Name , err = readUTF8String (datFile )
91+ data .Name , err = readUTF8String (datFile , false )
8992 if err != nil {
9093 log .Printf ("Cant read Name: %s" , err )
9194 return data , err
9295 }
9396
94- data .BaseMod , err = readUTF8String (datFile )
97+ data .BaseMod , err = readUTF8String (datFile , false )
9598 if err != nil {
9699 log .Printf ("Cant read BaseMod: %s" , err )
97100 return data , err
@@ -115,7 +118,7 @@ func ReadHeader(filePath string) (Header, error) {
115118 return data , err
116119 }
117120
118- data .NextLevel , err = readUTF8String (datFile )
121+ data .NextLevel , err = readUTF8String (datFile , false )
119122 if err != nil {
120123 log .Printf ("Couldn't read NextLevel: %s" , err )
121124 return data , err
@@ -139,8 +142,7 @@ func ReadHeader(filePath string) (Header, error) {
139142 return data , err
140143 }
141144
142- Constraint , _ = semver .NewConstraint (">= 0.16.0" )
143- Used , err := data .FactorioVersion .CheckCompatibility (Constraint )
145+ Used , err := data .FactorioVersion .CheckCompatibility (constraintGreaterThan0_16 )
144146 if err != nil {
145147 log .Printf ("Error checking if used: %s" , err )
146148 return data , err
@@ -171,13 +173,25 @@ func ReadHeader(filePath string) (Header, error) {
171173 return data , err
172174 }
173175
174- data .NumMods , err = readUint8 (datFile )
176+ New , err := data .FactorioVersion .CheckCompatibility (constraintGreaterThan0_16 )
177+ if err != nil {
178+ log .Printf ("error checking compatibility: %s" , err )
179+ return data , err
180+ }
181+
182+ if New {
183+ numMods8 , err2 := readUint8 (datFile ) //TODO read Optim. int
184+ err = err2
185+ data .NumMods = uint32 (numMods8 )
186+ } else {
187+ data .NumMods , err = readUint32 (datFile )
188+ }
175189 if err != nil {
176190 log .Printf ("Couldn't read NumMods: %s" , err )
177191 return data , err
178192 }
179193
180- for i := uint8 (0 ); i < data .NumMods ; i ++ {
194+ for i := uint32 (0 ); i < data .NumMods ; i ++ {
181195 SingleMod , err := readSingleMod (datFile )
182196 if err != nil {
183197 log .Printf ("Couldn't read SingleMod: %s" , err )
@@ -191,18 +205,30 @@ func ReadHeader(filePath string) (Header, error) {
191205 return data , nil
192206}
193207
194- func readUTF8String (file io.ReadCloser ) (string , error ) {
208+ func readUTF8String (file io.ReadCloser , forcedOptim bool ) (string , error ) {
195209 var err error
196- infoByte := make ([]byte , 1 )
197210
198- _ , err = file . Read ( infoByte )
211+ New , err := data . FactorioVersion . CheckCompatibility ( constraintGreaterThan0_16 )
199212 if err != nil {
200- log .Printf ("Error reading infoByte: %s" , err )
201- return "" , nil
213+ log .Printf ("Couldn't checkCompatibility: %s" , err )
214+ return "" , err
215+ }
216+
217+ var infoByteStringLength uint32
218+ if New || forcedOptim {
219+ infoByteInt8 , err2 := readUint8 (file ) //TODO read optimized int
220+ err = err2
221+ infoByteStringLength = uint32 (infoByteInt8 )
222+ } else {
223+ infoByteStringLength , err = readUint32 (file ) //uint32
224+ }
225+
226+ if err != nil {
227+ log .Printf ("Couldn't read infoByteStringLength: %s" , err )
228+ return "" , err
202229 }
203- stringLengthInBytes := int8 (infoByte [0 ])
204230
205- stringBytes := make ([]byte , stringLengthInBytes )
231+ stringBytes := make ([]byte , infoByteStringLength )
206232 _ , err = file .Read (stringBytes )
207233 if err != nil {
208234 log .Printf ("error reading bytes: %s" , err )
@@ -339,7 +365,7 @@ func readSingleMod(file io.ReadCloser) (singleMod, error) {
339365 var Mod singleMod
340366 var err error
341367
342- Mod .Name , err = readUTF8String (file )
368+ Mod .Name , err = readUTF8String (file , true )
343369 if err != nil {
344370 log .Printf ("error loading modName: %s" , err )
345371 return Mod , err
0 commit comments