naev 0.11.5
save.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <errno.h>
11#include "physfs.h"
12
13#include "naev.h"
16#include "save.h"
17
18#include "array.h"
19#include "conf.h"
20#include "dialogue.h"
21#include "event.h"
22#include "gui.h"
23#include "hook.h"
24#include "land.h"
25#include "load.h"
26#include "log.h"
27#include "menu.h"
28#include "news.h"
29#include "ndata.h"
30#include "nlua_var.h"
31#include "nstring.h"
32#include "nxml.h"
33#include "player.h"
34#include "plugin.h"
35#include "shiplog.h"
36#include "start.h"
37#include "unidiff.h"
38
39int save_loaded = 0;
41/*
42 * prototypes
43 */
44/* externs */
45/* player.c */
46extern int player_save( xmlTextWriterPtr writer );
47/* event.c */
48extern int events_saveActive( xmlTextWriterPtr writer );
49/* news.c */
50extern int news_saveArticles( xmlTextWriterPtr writer );
51/* nlua_var.c */
52extern int var_save( xmlTextWriterPtr writer );
53/* faction.c */
54extern int pfaction_save( xmlTextWriterPtr writer );
55/* hook.c */
56extern int hook_save( xmlTextWriterPtr writer );
57/* space.c */
58extern int space_sysSave( xmlTextWriterPtr writer );
59/* economy.c */
60extern int economy_sysSave( xmlTextWriterPtr writer );
61/* unidiff.c */
62extern int diff_save( xmlTextWriterPtr writer );
63/* static */
64static int save_data( xmlTextWriterPtr writer );
65
72static int save_data( xmlTextWriterPtr writer )
73{
74 /* the data itself */
75 if (diff_save(writer) < 0) return -1; /* Must save first or can get cleared. */
76 if (player_save(writer) < 0) return -1;
77 if (missions_saveActive(writer) < 0) return -1;
78 if (events_saveActive(writer) < 0) return -1;
79 if (news_saveArticles( writer ) < 0) return -1;
80 if (var_save(writer) < 0) return -1;
81 if (pfaction_save(writer) < 0) return -1;
82 if (hook_save(writer) < 0) return -1;
83 if (space_sysSave(writer) < 0) return -1;
84 if (economy_sysSave(writer) < 0) return -1;
85 if (shiplog_save(writer) < 0) return -1;
86 return 0;
87}
88
94int save_all (void)
95{
96 return save_all_with_name( "autosave" );
97}
98
105int save_all_with_name( const char *name )
106{
107 char file[PATH_MAX];
108 const plugin_t *plugins = plugin_list();
109 xmlDocPtr doc;
110 xmlTextWriterPtr writer;
111
112 /* Do not save if saving is off. */
113 if (player_isFlag(PLAYER_NOSAVE))
114 return 0;
115
116 /* Create the writer. */
117 writer = xmlNewTextWriterDoc(&doc, conf.save_compress);
118 if (writer == NULL) {
119 ERR(_("testXmlwriterDoc: Error creating the xml writer"));
120 return -1;
121 }
122
123 /* Set the writer parameters. */
124 xmlw_setParams( writer );
125
126 /* Start element. */
127 xmlw_start(writer);
128 xmlw_startElem(writer,"naev_save");
129
130 /* Save the version and such. */
131 xmlw_startElem(writer,"version");
132 xmlw_elem( writer, "naev", "%s", naev_version( 0 ) );
133 xmlw_elem( writer, "data", "%s", start_name() );
134 xmlw_endElem(writer); /* "version" */
135
136 /* Save last played. */
137 xmlw_saveTime( writer, "last_played", time(NULL) );
138
139 /* Save plugins. */
140 xmlw_startElem(writer,"plugins");
141 for (int i=0; i<array_size(plugins); i++)
142 xmlw_elem( writer, "plugin", "%s", plugin_name( &plugins[i] ) );
143 xmlw_endElem(writer); /* "plugins" */
144
145 /* Save the data. */
146 if (save_data(writer) < 0) {
147 ERR(_("Trying to save game data"));
148 goto err_writer;
149 }
150
151 /* Finish element. */
152 xmlw_endElem(writer); /* "naev_save" */
153 xmlw_done(writer);
154
155 /* Write to file. */
156 if (PHYSFS_mkdir("saves") == 0) {
157 snprintf(file, sizeof(file), "%s/saves", PHYSFS_getWriteDir());
158 WARN(_( "Dir '%s' does not exist and unable to create: %s" ), file,
159 _(PHYSFS_getErrorByCode( PHYSFS_getLastErrorCode() ) ) );
160 goto err_writer;
161 }
162 snprintf(file, sizeof(file), "saves/%s", player.name);
163 if (PHYSFS_mkdir(file) == 0) {
164 snprintf(file, sizeof(file), "%s/saves/%s", PHYSFS_getWriteDir(), player.name);
165 WARN(_( "Dir '%s' does not exist and unable to create: %s" ), file,
166 _(PHYSFS_getErrorByCode( PHYSFS_getLastErrorCode() ) ) );
167 goto err_writer;
168 }
169
170 /* Back up old saved game. */
171 if (!strcmp(name, "autosave")) {
172 if (!save_loaded) {
173 char backup[PATH_MAX];
174 snprintf(file, sizeof(file), "saves/%s/autosave.ns", player.name);
175 snprintf(backup, sizeof(backup), "saves/%s/backup.ns", player.name);
176 if (ndata_copyIfExists(file, backup) < 0) {
177 WARN(_("Aborting save…"));
178 goto err_writer;
179 }
180 }
181 save_loaded = 0;
182 }
183
184 /* Critical section, if crashes here player's game gets corrupted.
185 * Luckily we have a copy just in case... */
186 xmlFreeTextWriter(writer);
187 snprintf(file, sizeof(file), "%s/saves/%s/%s.ns", PHYSFS_getWriteDir(), player.name, name); /* TODO: write via physfs */
188 if (xmlSaveFileEnc(file, doc, "UTF-8") < 0) {
189 WARN(_("Failed to write saved game! You'll most likely have to restore it by copying your backup saved game over your current saved game."));
190 goto err;
191 }
192 xmlFreeDoc(doc);
193
194 return 0;
195
196err_writer:
197 xmlFreeTextWriter(writer);
198err:
199 xmlFreeDoc(doc);
200 return -1;
201}
202
206void save_reload (void)
207{
208 /* Should be refreshed already when menu is opened (load_refresh). */
209 const nsave_t *ns = load_getList( player.name );
210 if (array_size(ns) <= 0) {
211 WARN(_("Unable to reload save for '%s'!"),player.name);
212 return;
213 }
214 load_gameFile( ns[0].path );
215}
Provides macros to work with dynamic arrays.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition array.h:168
const nsave_t * load_getList(const char *name)
Gets the array (array.h) of loaded saves.
Definition load.c:477
int load_gameFile(const char *file)
Loads the game from a file.
Definition load.c:1103
Handles the important game menus.
int missions_saveActive(xmlTextWriterPtr writer)
Saves the player's active missions.
Definition mission.c:1287
Header file with generic functions and naev-specifics.
const char * naev_version(int long_version)
Returns the version in a human readable string.
#define PATH_MAX
Definition naev.h:50
int ndata_copyIfExists(const char *file1, const char *file2)
Copy a file, if it exists.
Definition ndata.c:303
void xmlw_setParams(xmlTextWriterPtr writer)
Sets up the standard xml write parameters.
Definition nxml.c:64
Player_t player
Definition player.c:74
const char * plugin_name(const plugin_t *plg)
Tries to tget the name of a plugin.
Definition plugin.c:218
const plugin_t * plugin_list(void)
Returns the list of all the plugins.
Definition plugin.c:281
int player_save(xmlTextWriterPtr writer)
Save the freaking player in a freaking xmlfile.
Definition player.c:3232
int var_save(xmlTextWriterPtr writer)
Saves the mission variables.
Definition nlua_var.c:71
void save_reload(void)
Reload the current saved game.
Definition save.c:206
int save_all_with_name(const char *name)
Saves the current game.
Definition save.c:105
int save_all(void)
Saves the current game.
Definition save.c:94
int space_sysSave(xmlTextWriterPtr writer)
Saves what is needed to be saved for space.
Definition space.c:3898
int pfaction_save(xmlTextWriterPtr writer)
Saves player's standings with the factions.
Definition faction.c:1760
static int save_data(xmlTextWriterPtr writer)
Saves all the player's game data.
Definition save.c:72
int events_saveActive(xmlTextWriterPtr writer)
Saves the player's active events.
Definition event.c:816
int economy_sysSave(xmlTextWriterPtr writer)
Saves what is needed to be saved for economy.
Definition economy.c:1069
int diff_save(xmlTextWriterPtr writer)
Saves the active diffs.
Definition unidiff.c:1776
int save_loaded
Definition save.c:39
int hook_save(xmlTextWriterPtr writer)
Saves all the hooks.
Definition hook.c:1183
const char * start_name(void)
Gets the module name.
Definition start.c:177
int save_compress
Definition conf.h:149
char * name
Definition player.h:103
A naev save.
Definition load.h:23