@@ -90,17 +90,17 @@ func (h *SaveHeader) ReadFrom(r io.Reader) (err error) {
9090
9191 atLeast016 := ! h .FactorioVersion .Less (Version {0 , 16 , 0 , 0 })
9292
93- h .Campaign , err = readString (r , atLeast016 )
93+ h .Campaign , err = readString (r , Version ( h . FactorioVersion ), false )
9494 if err != nil {
9595 return fmt .Errorf ("read Campaign: %v" , err )
9696 }
9797
98- h .Name , err = readString (r , atLeast016 )
98+ h .Name , err = readString (r , Version ( h . FactorioVersion ), false )
9999 if err != nil {
100100 return fmt .Errorf ("read Name: %v" , err )
101101 }
102102
103- h .BaseMod , err = readString (r , atLeast016 )
103+ h .BaseMod , err = readString (r , Version ( h . FactorioVersion ), false )
104104 if err != nil {
105105 return fmt .Errorf ("read BaseMod: %v" , err )
106106 }
@@ -123,7 +123,7 @@ func (h *SaveHeader) ReadFrom(r io.Reader) (err error) {
123123 }
124124 h .PlayerWon = scratch [0 ] != 0
125125
126- h .NextLevel , err = readString (r , atLeast016 )
126+ h .NextLevel , err = readString (r , Version ( h . FactorioVersion ), false )
127127 if err != nil {
128128 return fmt .Errorf ("read NextLevel: %v" , err )
129129 }
@@ -156,12 +156,9 @@ func (h *SaveHeader) ReadFrom(r io.Reader) (err error) {
156156 h .AllowNonAdminDebugOptions = scratch [0 ] != 0
157157 }
158158
159- var loadedFrom version24
160- _ , err = r . Read ( scratch [: 3 ] )
159+ var loadedFrom version48
160+ err = loadedFrom . ReadFrom ( r , Version ( h . FactorioVersion ) )
161161 if err != nil {
162- return err
163- }
164- if err := loadedFrom .UnmarshalBinary (scratch [:3 ]); err != nil {
165162 return fmt .Errorf ("read LoadedFrom: %v" , err )
166163 }
167164 h .LoadedFrom = Version (loadedFrom )
@@ -194,7 +191,7 @@ func (h *SaveHeader) ReadFrom(r io.Reader) (err error) {
194191
195192 var n uint32
196193 if atLeast016 {
197- n , err = readOptimUint32 ( r )
194+ n , err = readOptimUint ( r , Version ( h . FactorioVersion ), 32 )
198195 if err != nil {
199196 return fmt .Errorf ("read num mods: %v" , err )
200197 }
@@ -217,27 +214,42 @@ func (h *SaveHeader) ReadFrom(r io.Reader) (err error) {
217214 return nil
218215}
219216
220- func readOptimUint32 (r io.Reader ) (uint32 , error ) {
217+ func readOptimUint (r io.Reader , v Version , bitSize int ) (uint32 , error ) {
221218 var b [4 ]byte
222- _ , err := r .Read (b [:1 ])
223- if err != nil {
224- return 0 , err
219+ if ! v .Less (Version {0 , 14 , 14 , 0 }) {
220+ _ , err := r .Read (b [:1 ])
221+ if err != nil {
222+ return 0 , err
223+ }
224+ if b [0 ] != 0xFF {
225+ return uint32 (b [0 ]), nil
226+ }
225227 }
226- if b [0 ] != 0xFF {
227- return uint32 (b [0 ]), nil
228+
229+ if bitSize < 0 || bitSize > 64 || (bitSize % 8 != 0 ) {
230+ panic ("invalid bit size" )
228231 }
229- _ , err = r .Read (b [:4 ])
232+
233+ _ , err := r .Read (b [:bitSize / 8 ])
230234 if err != nil {
231235 return 0 , err
232236 }
233- return binary .LittleEndian .Uint32 (b [:4 ]), nil
237+
238+ switch bitSize {
239+ case 16 :
240+ return uint32 (binary .LittleEndian .Uint16 (b [:2 ])), nil
241+ case 32 :
242+ return binary .LittleEndian .Uint32 (b [:4 ]), nil
243+ default :
244+ panic ("invalid bit size" )
245+ }
234246}
235247
236- func readString (r io.Reader , optimized bool ) (s string , err error ) {
248+ func readString (r io.Reader , game Version , forceOptimized bool ) (s string , err error ) {
237249 var n uint32
238250
239- if optimized {
240- n , err = readOptimUint32 ( r )
251+ if ! game . Less ( Version { 0 , 16 , 0 , 0 }) || forceOptimized {
252+ n , err = readOptimUint ( r , game , 32 )
241253 if err != nil {
242254 return "" , err
243255 }
@@ -302,22 +314,19 @@ func (h SaveHeader) readStats(r io.Reader) (stats map[byte][]map[uint16]uint32,
302314}
303315
304316func (m * Mod ) ReadFrom (r io.Reader , game Version ) (err error ) {
305- m .Name , err = readString (r , true )
317+ m .Name , err = readString (r , game , true )
306318 if err != nil {
307319 return fmt .Errorf ("read Name: %v" , err )
308320 }
309321
310- var scratch [4 ]byte
311- var version version24
312- _ , err = r .Read (scratch [:3 ])
322+ var version version48
323+ err = version .ReadFrom (r , game )
313324 if err != nil {
314325 return err
315326 }
316- if err := version .UnmarshalBinary (scratch [:3 ]); err != nil {
317- return fmt .Errorf ("read Version: %v" , err )
318- }
319327 m .Version = Version (version )
320328
329+ var scratch [4 ]byte
321330 if game .Greater (Version {0 , 15 , 0 , 91 }) {
322331 _ , err = r .Read (scratch [:4 ])
323332 if err != nil {
0 commit comments