Skip to content

Commit af3f527

Browse files
committed
Compress .sav files too.
1 parent 0bae4f7 commit af3f527

File tree

8 files changed

+210
-93
lines changed

8 files changed

+210
-93
lines changed

src/auto_note.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ void auto_note_settings::clear()
4141

4242
bool auto_note_settings::save( bool bCharacter )
4343
{
44-
if( bCharacter && !file_exist( PATH_INFO::player_base_save_path() + ".sav" ) ) {
44+
if( bCharacter && !file_exist( PATH_INFO::player_base_save_path() + ".sav" ) ||
45+
!file_exist( PATH_INFO::player_base_save_path() + ".sav.zzip" ) ) {
4546
return true;
4647
}
4748
cata_path sGlobalFile = PATH_INFO::autonote();

src/auto_pickup.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,9 @@ bool player_settings::save( const bool bCharacter )
889889
savefile = PATH_INFO::player_base_save_path() + ".apu.json";
890890

891891
const cata_path player_save = PATH_INFO::player_base_save_path() + ".sav";
892+
const cata_path player_save_zzip = player_save + ".zzip";
892893
//Character not saved yet.
893-
if( !file_exist( player_save ) ) {
894+
if( !file_exist( player_save ) || !file_exist( player_save_zzip ) ) {
894895
return true;
895896
}
896897
}

src/game.cpp

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@
215215
#include "weather.h"
216216
#include "weather_type.h"
217217
#include "worldfactory.h"
218+
#include "zzip.h"
218219

219220
#if defined(TILES)
220221
#include "sdl_utils.h"
@@ -3247,12 +3248,19 @@ bool game::load( const save_t &name )
32473248

32483249
u = avatar();
32493250
u.set_save_id( name.decoded_name() );
3250-
if( !read_from_file(
3251-
save_file_path,
3252-
[this, &save_file_path]( std::istream & is ) {
3253-
unserialize( is, save_file_path );
3254-
} ) ) {
3255-
abort = true;
3251+
3252+
if( world_generator->active_world->has_compression_enabled() ) {
3253+
std::shared_ptr<zzip> z = zzip::load( ( save_file_path + ".zzip" ).get_unrelative_path() );
3254+
abort = !read_from_zzip_optional( z, save_file_path.get_unrelative_path().filename(),
3255+
[this, &save_file_path]( std::string_view sv ) {
3256+
unserialize( std::string{ sv } );
3257+
} );
3258+
} else {
3259+
abort = !read_from_file(
3260+
save_file_path,
3261+
[this, &save_file_path]( std::istream & is ) {
3262+
unserialize( is, save_file_path );
3263+
} );
32563264
}
32573265
}
32583266
},
@@ -3528,9 +3536,20 @@ bool game::save_player_data()
35283536
{
35293537
const cata_path playerfile = PATH_INFO::player_base_save_path();
35303538

3531-
const bool saved_data = write_to_file( playerfile + SAVE_EXTENSION, [&]( std::ostream & fout ) {
3532-
serialize( fout );
3533-
}, _( "player data" ) );
3539+
bool saved_data;
3540+
if( world_generator->active_world->has_compression_enabled() ) {
3541+
std::stringstream save;
3542+
serialize_json( save );
3543+
std::shared_ptr<zzip> z = zzip::load( ( playerfile + SAVE_EXTENSION +
3544+
".zzip" ).get_unrelative_path() );
3545+
saved_data = z->add_file( ( playerfile + SAVE_EXTENSION ).get_unrelative_path().filename(),
3546+
save.str() );
3547+
saved_data = saved_data && z->compact( 1.0 );
3548+
} else {
3549+
saved_data = write_to_file( playerfile + SAVE_EXTENSION, [&]( std::ostream & fout ) {
3550+
serialize_json( fout );
3551+
}, _( "player data" ) );
3552+
}
35343553
const bool saved_map_memory = u.save_map_memory();
35353554
const bool saved_log = write_to_file( playerfile + SAVE_EXTENSION_LOG, [&](
35363555
std::ostream & fout ) {

src/game.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,14 @@ class game
236236
public:
237237
void setup();
238238
/** Saving and loading functions. */
239-
void serialize( std::ostream &fout ); // for save
239+
void serialize_json( std::ostream &fout ); // for save
240240
void unserialize( std::istream &fin, const cata_path &path ); // for load
241+
void unserialize( std::string fin ); // for load
241242
void unserialize_master( const cata_path &file_name, std::istream &fin ); // for load
242243
void unserialize_master( const JsonValue &jv ); // for load
244+
private:
245+
void unserialize_impl( const JsonObject &jsin );
246+
public:
243247

244248
/** Returns false if saving failed. */
245249
bool save();

src/global_vars.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class global_variables
5959
void set_global_values( impl_t input ) {
6060
global_values = std::move( input );
6161
}
62-
void unserialize( JsonObject &jo );
62+
void unserialize( const JsonObject &jo );
6363
void serialize( JsonOut &jsout ) const;
6464

6565
std::map<std::string, std::string> migrations; // NOLINT(cata-serialize)

src/safemode_ui.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,8 @@ bool safemode::save( const bool is_character_in )
788788

789789
if( is_character ) {
790790
file = PATH_INFO::player_base_save_path() + ".sfm.json";
791-
if( !file_exist( PATH_INFO::player_base_save_path() + ".sav" ) ) {
791+
if( !file_exist( PATH_INFO::player_base_save_path() + ".sav" ) ||
792+
!file_exist( PATH_INFO::player_base_save_path() + ".sav.zzip" ) ) {
792793
return true; //Character not saved yet.
793794
}
794795
}

src/savegame.cpp

Lines changed: 97 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,18 @@ int savegame_loading_version = savegame_version;
8181
/*
8282
* Save to opened character.sav
8383
*/
84-
void game::serialize( std::ostream &fout )
84+
void game::serialize_json( std::ostream &fout )
8585
{
8686
/*
8787
* Format version 12: Fully json, save the header. Weather and memorial exist elsewhere.
8888
* To prevent (or encourage) confusion, there is no version 8. (cata 0.8 uses v7)
8989
*/
9090
// Header
91-
fout << "# version " << savegame_version << std::endl;
92-
9391
JsonOut json( fout, true ); // pretty-print
9492

9593
json.start_object();
9694
// basic game state information.
95+
json.member( "savegame_loading_version", savegame_version );
9796
json.member( "turn", calendar::turn );
9897
json.member( "calendar_start", calendar::start_of_cataclysm );
9998
json.member( "game_start", calendar::start_of_game );
@@ -203,92 +202,112 @@ static size_t chkversion( std::istream &fin )
203202
/*
204203
* Parse an open .sav file.
205204
*/
205+
206206
void game::unserialize( std::istream &fin, const cata_path &path )
207207
{
208-
size_t json_file_offset = chkversion( fin );
208+
try {
209+
size_t json_file_offset = chkversion( fin );
210+
JsonObject data = json_loader::from_path_at_offset( path, json_file_offset );
211+
if( data.has_member( "savegame_loading_version" ) ) {
212+
data.read( "savegame_loading_version", savegame_loading_version );
213+
}
214+
unserialize_impl( data );
215+
} catch( const JsonError &jsonerr ) {
216+
debugmsg( "Bad save json\n%s", jsonerr.c_str() );
217+
return;
218+
}
219+
}
220+
221+
void game::unserialize( std::string fin )
222+
{
223+
try {
224+
JsonObject data = json_loader::from_string( std::move( fin ) );
225+
savegame_loading_version = data.get_int( "savegame_loading_version" );
226+
unserialize_impl( data );
227+
} catch( const JsonError &jsonerr ) {
228+
debugmsg( "Bad save json\n%s", jsonerr.c_str() );
229+
return;
230+
}
231+
}
232+
233+
void game::unserialize_impl( const JsonObject &data )
234+
{
209235
int tmpturn = 0;
210236
int tmpcalstart = 0;
211237
int tmprun = 0;
212238
tripoint_om_sm lev;
213239
point_abs_om com;
214-
JsonValue jsin = json_loader::from_path_at_offset( path, json_file_offset );
215-
try {
216-
JsonObject data = jsin.get_object();
217240

218-
data.read( "turn", tmpturn );
219-
data.read( "calendar_start", tmpcalstart );
220-
calendar::initial_season = static_cast<season_type>( data.get_int( "initial_season",
221-
static_cast<int>( SPRING ) ) );
222-
223-
data.read( "auto_travel_mode", auto_travel_mode );
224-
data.read( "run_mode", tmprun );
225-
data.read( "mostseen", mostseen );
226-
data.read( "levx", lev.x() );
227-
data.read( "levy", lev.y() );
228-
data.read( "levz", lev.z() );
229-
data.read( "om_x", com.x() );
230-
data.read( "om_y", com.y() );
231-
232-
data.read( "view_offset_x", u.view_offset.x() );
233-
data.read( "view_offset_y", u.view_offset.y() );
234-
data.read( "view_offset_z", u.view_offset.z() );
235-
236-
calendar::turn = time_point( tmpturn );
237-
calendar::start_of_cataclysm = time_point( tmpcalstart );
238-
239-
if( !data.read( "game_start", calendar::start_of_game ) ) {
240-
calendar::start_of_game = calendar::start_of_cataclysm;
241-
}
242-
243-
load_map( project_combine( com, lev ), /*pump_events=*/true );
241+
data.read( "turn", tmpturn );
242+
data.read( "calendar_start", tmpcalstart );
243+
calendar::initial_season = static_cast<season_type>( data.get_int( "initial_season",
244+
static_cast<int>( SPRING ) ) );
245+
246+
data.read( "auto_travel_mode", auto_travel_mode );
247+
data.read( "run_mode", tmprun );
248+
data.read( "mostseen", mostseen );
249+
data.read( "levx", lev.x() );
250+
data.read( "levy", lev.y() );
251+
data.read( "levz", lev.z() );
252+
data.read( "om_x", com.x() );
253+
data.read( "om_y", com.y() );
254+
255+
data.read( "view_offset_x", u.view_offset.x() );
256+
data.read( "view_offset_y", u.view_offset.y() );
257+
data.read( "view_offset_z", u.view_offset.z() );
258+
259+
calendar::turn = time_point( tmpturn );
260+
calendar::start_of_cataclysm = time_point( tmpcalstart );
261+
262+
if( !data.read( "game_start", calendar::start_of_game ) ) {
263+
calendar::start_of_game = calendar::start_of_cataclysm;
264+
}
244265

245-
safe_mode = static_cast<safe_mode_type>( tmprun );
246-
if( get_option<bool>( "SAFEMODE" ) && safe_mode == SAFE_MODE_OFF ) {
247-
safe_mode = SAFE_MODE_ON;
248-
}
266+
load_map( project_combine( com, lev ), /*pump_events=*/true );
249267

250-
std::string linebuff;
251-
std::string linebuf;
252-
if( data.read( "grscent", linebuf ) && data.read( "typescent", linebuff ) ) {
253-
scent.deserialize( linebuf );
254-
scent.deserialize( linebuff, true );
255-
} else {
256-
scent.reset();
257-
}
258-
data.read( "active_monsters", *critter_tracker );
259-
260-
data.has_null( "stair_monsters" ); // TEMPORARY until 0.G
261-
data.has_null( "monstairz" ); // TEMPORARY until 0.G
262-
263-
data.read( "driving_view_offset", driving_view_offset );
264-
data.read( "turnssincelastmon", turnssincelastmon );
265-
data.read( "bVMonsterLookFire", bVMonsterLookFire );
266-
267-
data.read( "kill_tracker", *kill_tracker_ptr );
268-
269-
data.read( "player", u );
270-
data.read( "inactive_global_effect_on_condition_vector",
271-
inactive_global_effect_on_condition_vector );
272-
//load queued_eocs
273-
for( JsonObject elem : data.get_array( "queued_global_effect_on_conditions" ) ) {
274-
queued_eoc temp;
275-
temp.time = time_point( elem.get_int( "time" ) );
276-
temp.eoc = effect_on_condition_id( elem.get_string( "eoc" ) );
277-
elem.read( "context", temp.context );
278-
queued_global_effect_on_conditions.push( temp );
279-
}
280-
global_variables_instance.unserialize( data );
281-
data.read( "unique_npcs", unique_npcs );
282-
inp_mngr.pump_events();
283-
data.read( "stats_tracker", *stats_tracker_ptr );
284-
data.read( "achievements_tracker", *achievements_tracker_ptr );
285-
inp_mngr.pump_events();
286-
Messages::deserialize( data );
268+
safe_mode = static_cast<safe_mode_type>( tmprun );
269+
if( get_option<bool>( "SAFEMODE" ) && safe_mode == SAFE_MODE_OFF ) {
270+
safe_mode = SAFE_MODE_ON;
271+
}
287272

288-
} catch( const JsonError &jsonerr ) {
289-
debugmsg( "Bad save json\n%s", jsonerr.c_str() );
290-
return;
273+
std::string linebuff;
274+
std::string linebuf;
275+
if( data.read( "grscent", linebuf ) && data.read( "typescent", linebuff ) ) {
276+
scent.deserialize( linebuf );
277+
scent.deserialize( linebuff, true );
278+
} else {
279+
scent.reset();
291280
}
281+
data.read( "active_monsters", *critter_tracker );
282+
283+
data.has_null( "stair_monsters" ); // TEMPORARY until 0.G
284+
data.has_null( "monstairz" ); // TEMPORARY until 0.G
285+
286+
data.read( "driving_view_offset", driving_view_offset );
287+
data.read( "turnssincelastmon", turnssincelastmon );
288+
data.read( "bVMonsterLookFire", bVMonsterLookFire );
289+
290+
data.read( "kill_tracker", *kill_tracker_ptr );
291+
292+
data.read( "player", u );
293+
data.read( "inactive_global_effect_on_condition_vector",
294+
inactive_global_effect_on_condition_vector );
295+
//load queued_eocs
296+
for( JsonObject elem : data.get_array( "queued_global_effect_on_conditions" ) ) {
297+
queued_eoc temp;
298+
temp.time = time_point( elem.get_int( "time" ) );
299+
temp.eoc = effect_on_condition_id( elem.get_string( "eoc" ) );
300+
elem.read( "context", temp.context );
301+
queued_global_effect_on_conditions.push( temp );
302+
}
303+
global_variables_instance.unserialize( data );
304+
data.read( "unique_npcs", unique_npcs );
305+
inp_mngr.pump_events();
306+
data.read( "stats_tracker", *stats_tracker_ptr );
307+
data.read( "achievements_tracker", *achievements_tracker_ptr );
308+
inp_mngr.pump_events();
309+
Messages::deserialize( data );
310+
292311
}
293312

294313
void scent_map::deserialize( const std::string &data, bool is_type )
@@ -1587,7 +1606,7 @@ void weather_manager::unserialize_all( const JsonObject &w )
15871606
}
15881607
}
15891608

1590-
void global_variables::unserialize( JsonObject &jo )
1609+
void global_variables::unserialize( const JsonObject &jo )
15911610
{
15921611
// global variables
15931612
jo.read( "global_vals", global_values );

0 commit comments

Comments
 (0)