@@ -2,163 +2,168 @@ package factorioSave
22
33import (
44 "log"
5- "os"
65 "encoding/binary"
6+ "errors"
7+ "io"
78)
89
910type version16 struct {
1011 versionShort16
11- Revision uint16
12+ Revision uint16 `json:"revision"`
1213}
1314type versionShort16 struct {
14- Major uint16
15- Minor uint16
16- Build uint16
15+ Major uint16 `json:"major"`
16+ Minor uint16 `json:"minor"`
17+ Build uint16 `json:"build"`
1718}
1819type versionShort8 struct {
19- Major uint8
20- Minor uint8
21- Build uint8
20+ Major uint8 `json:"major"`
21+ Minor uint8 `json:"minor"`
22+ Build uint8 `json:"build"`
2223}
2324type Header struct {
24- FactorioVersion version16
25- Campaign string
26- Name string
27- BaseMod string
28- Difficulty uint8
29- Finished bool
30- PlayerWon bool
31- NextLevel string
32- CanContinue bool
33- FinishedButContinuing bool
34- SavingReplay bool
35- AllowNonAdminDebugOptions bool
36- LoadedFrom versionShort8
37- LoadedFromBuild uint16
38- AllowedCommads uint8
39- NumMods uint8
40- Mods []singleMod
25+ FactorioVersion version16 `json:"factorio_version"`
26+ Campaign string `json:"campaign"`
27+ Name string `json:"name"`
28+ BaseMod string `json:"base_mod"`
29+ Difficulty uint8 `json:"difficulty"`
30+ Finished bool `json:"finished"`
31+ PlayerWon bool `json:"player_won"`
32+ NextLevel string `json:"next_level"`
33+ CanContinue bool `json:"can_continue"`
34+ FinishedButContinuing bool `json:"finished_but_continuing"`
35+ SavingReplay bool `json:"saving_replay"`
36+ AllowNonAdminDebugOptions bool `json:"allow_non_admin_debug_options"`
37+ LoadedFrom versionShort8 `json:"loaded_from"`
38+ LoadedFromBuild uint16 `json:"loaded_from_build"`
39+ AllowedCommads uint8 `json:"allowed_commads"`
40+ NumMods uint8 `json:"num_mods"`
41+ Mods []singleMod `json:"mods"`
4142}
4243type singleMod struct {
43- Name string
44- Version versionShort8
45- CRC uint32
44+ Name string `json:"name"`
45+ Version versionShort8 `json:"version"`
46+ CRC uint32 `json:"crc"`
4647}
4748
49+ var ErrorIncompatible = errors .New ("incompatible save" )
50+
4851
4952func ReadHeader (filePath string ) (Header , error ) {
5053 var data Header
54+ var err error
5155
52- fp , err := os . Open (filePath )
56+ datFile , err := openSave (filePath )
5357 if err != nil {
5458 log .Printf ("error opening file: %s" , err )
5559 return data , err
5660 }
57- defer fp .Close ()
61+ defer datFile .Close ()
5862
59- data .FactorioVersion , err = readVersion16 (fp )
63+ data .FactorioVersion , err = readVersion16 (datFile )
6064 if err != nil {
6165 log .Printf ("Cant read FactorioVersion: %s" , err )
6266 return data , err
6367 }
6468
6569 if ! data .FactorioVersion .CheckCompatibility (0 , 16 , 0 ) {
6670 log .Printf ("NOT COMPATIBLE Save-File" )
67- return data , err
71+ log .Println (data )
72+ return data , ErrorIncompatible
6873 }
6974
70- data .Campaign , err = readUTF8String (fp )
75+ data .Campaign , err = readUTF8String (datFile )
7176 if err != nil {
7277 log .Printf ("Cant read Campaign: %s" , err )
7378 return data , err
7479 }
7580
76- data .Name , err = readUTF8String (fp )
81+ data .Name , err = readUTF8String (datFile )
7782 if err != nil {
7883 log .Printf ("Cant read Name: %s" , err )
7984 return data , err
8085 }
8186
82- data .BaseMod , err = readUTF8String (fp )
87+ data .BaseMod , err = readUTF8String (datFile )
8388 if err != nil {
8489 log .Printf ("Cant read BaseMod: %s" , err )
8590 return data , err
8691 }
8792
88- data .Difficulty , err = readUint8 (fp )
93+ data .Difficulty , err = readUint8 (datFile )
8994 if err != nil {
9095 log .Printf ("Cant read Difficulty: %s" , err )
9196 return data , err
9297 }
9398
94- data .Finished , err = readBool (fp )
99+ data .Finished , err = readBool (datFile )
95100 if err != nil {
96101 log .Printf ("Couln't read Finished bool: %s" , err )
97102 return data , err
98103 }
99104
100- data .PlayerWon , err = readBool (fp )
105+ data .PlayerWon , err = readBool (datFile )
101106 if err != nil {
102107 log .Printf ("Couldn't read PlayerWon: %s" , err )
103108 return data , err
104109 }
105110
106- data .NextLevel , err = readUTF8String (fp )
111+ data .NextLevel , err = readUTF8String (datFile )
107112 if err != nil {
108113 log .Printf ("Couldn't read NextLevel: %s" , err )
109114 return data , err
110115 }
111116
112- data .CanContinue , err = readBool (fp )
117+ data .CanContinue , err = readBool (datFile )
113118 if err != nil {
114119 log .Printf ("Couldn't read CanContinue: %s" , err )
115120 return data , err
116121 }
117122
118- data .FinishedButContinuing , err = readBool (fp )
123+ data .FinishedButContinuing , err = readBool (datFile )
119124 if err != nil {
120125 log .Printf ("Couldn't read FinishedButContinuing: %s" , err )
121126 return data , err
122127 }
123128
124- data .SavingReplay , err = readBool (fp )
129+ data .SavingReplay , err = readBool (datFile )
125130 if err != nil {
126131 log .Printf ("Couldn't read SavingReplay: %s" , err )
127132 return data , err
128133 }
129134
130- data .AllowNonAdminDebugOptions , err = readBool (fp )
135+ data .AllowNonAdminDebugOptions , err = readBool (datFile )
131136 if err != nil {
132137 log .Printf ("Couldn't read allow_non_admin_debug_options: %s" , err )
133138 return data , err
134139 }
135140
136- data .LoadedFrom , err = readVersionShort8 (fp )
141+ data .LoadedFrom , err = readVersionShort8 (datFile )
137142 if err != nil {
138143 log .Printf ("Couldn't read LoadedFrom: %s" , err )
139144 return data , err
140145 }
141146
142- data .LoadedFromBuild , err = readUint16 (fp )
147+ data .LoadedFromBuild , err = readUint16 (datFile )
143148 if err != nil {
144149 log .Printf ("Couldn't read LoadedFromBuild: %s" , err )
145150 return data , err
146151 }
147152
148- data .AllowedCommads , err = readUint8 (fp )
153+ data .AllowedCommads , err = readUint8 (datFile )
149154 if err != nil {
150155 log .Printf ("Couldn't read AllowedCommands: %s" , err )
151156 return data , err
152157 }
153158
154- data .NumMods , err = readUint8 (fp )
159+ data .NumMods , err = readUint8 (datFile )
155160 if err != nil {
156161 log .Printf ("Couldn't read NumMods: %s" , err )
157162 return data , err
158163 }
159164
160165 for i := uint8 (0 ); i < data .NumMods ; i ++ {
161- SingleMod , err := readSingleMod (fp )
166+ SingleMod , err := readSingleMod (datFile )
162167 if err != nil {
163168 log .Printf ("Couldn't read SingleMod: %s" , err )
164169 return data , err
@@ -167,11 +172,10 @@ func ReadHeader(filePath string) (Header, error) {
167172 data .Mods = append (data .Mods , SingleMod )
168173 }
169174
170- log .Println (data )
171175 return data , nil
172176}
173177
174- func readUTF8String (file * os. File ) (string , error ) {
178+ func readUTF8String (file io. ReadCloser ) (string , error ) {
175179 var err error
176180 infoByte := make ([]byte , 1 )
177181
@@ -193,7 +197,7 @@ func readUTF8String(file *os.File) (string, error) {
193197 return finalizedString , nil
194198}
195199
196- func readUint8 (file * os. File ) (uint8 , error ) {
200+ func readUint8 (file io. ReadCloser ) (uint8 , error ) {
197201 var err error
198202 var temp [1 ]byte
199203 _ , err = file .Read (temp [:])
@@ -205,7 +209,7 @@ func readUint8(file *os.File) (uint8, error) {
205209 return uint8 (temp [0 ]), nil
206210}
207211
208- func readUint16 (file * os. File ) (uint16 , error ) {
212+ func readUint16 (file io. ReadCloser ) (uint16 , error ) {
209213 var err error
210214 var temp [2 ]byte
211215
@@ -218,7 +222,7 @@ func readUint16(file *os.File) (uint16, error) {
218222 return binary .LittleEndian .Uint16 (temp [:]), nil
219223}
220224
221- func readUint32 (file * os. File ) (uint32 , error ) {
225+ func readUint32 (file io. ReadCloser ) (uint32 , error ) {
222226 var err error
223227 var temp [4 ]byte
224228
@@ -231,7 +235,7 @@ func readUint32(file *os.File) (uint32, error) {
231235 return binary .LittleEndian .Uint32 (temp [:]), nil
232236}
233237
234- func readBool (file * os. File ) (bool , error ) {
238+ func readBool (file io. ReadCloser ) (bool , error ) {
235239 byteAsInt , err := readUint8 (file )
236240 if err != nil {
237241 log .Printf ("error loading Uint8: %s" , err )
@@ -241,7 +245,7 @@ func readBool(file *os.File) (bool, error) {
241245 return byteAsInt != 0 , nil
242246}
243247
244- func readVersion16 (file * os. File ) (version16 , error ) {
248+ func readVersion16 (file io. ReadCloser ) (version16 , error ) {
245249 var Version version16
246250 var VersionShort versionShort16
247251 var err error
@@ -265,7 +269,7 @@ func readVersion16(file *os.File) (version16, error) {
265269 return Version , nil
266270}
267271
268- func readVersionShort16 (file * os. File ) (versionShort16 , error ) {
272+ func readVersionShort16 (file io. ReadCloser ) (versionShort16 , error ) {
269273 var Version versionShort16
270274 var err error
271275
@@ -290,7 +294,7 @@ func readVersionShort16(file *os.File) (versionShort16, error) {
290294 return Version , err
291295}
292296
293- func readVersionShort8 (file * os. File ) (versionShort8 , error ) {
297+ func readVersionShort8 (file io. ReadCloser ) (versionShort8 , error ) {
294298 var Version versionShort8
295299 var err error
296300
@@ -315,7 +319,7 @@ func readVersionShort8(file *os.File) (versionShort8, error) {
315319 return Version , nil
316320}
317321
318- func readSingleMod (file * os. File ) (singleMod , error ) {
322+ func readSingleMod (file io. ReadCloser ) (singleMod , error ) {
319323 var Mod singleMod
320324 var err error
321325
@@ -341,5 +345,5 @@ func readSingleMod(file *os.File) (singleMod, error) {
341345}
342346
343347func (Version * versionShort16 ) CheckCompatibility (Major uint16 , Minor uint16 , Build uint16 ) (bool ) {
344- return Major >= Version . Major && Minor >= Version . Minor && Build >= Version . Build
348+ return Version . Major >= Major && Version . Minor >= Minor && Version . Build >= Build
345349}
0 commit comments