/** * @brief Writes unistate data to xml writer passed * * @param list pointer to first element of list to be written * @param writer xml writer to be used when writing * @return 0 on success */ int unistate_writeFile(assetStatePtr list, xmlTextWriterPtr writer) { if(!list) return 0; if(!writer) return -1; assetStatePtr curEntry = NULL; #ifdef UNISTATE_DEBUG char debugBuffer[PATH_MAX]; #endif curEntry = list; //iterate over entries, and save them to gamesave xmlw_startElem(writer, "uni_state"); do { //start code block xmlw_startElem(writer, "asset"); //for debug purposes #ifdef UNISTATE_DEBUG snprintf(debugBuffer, sizeof(char) * (PATH_MAX - 1),\ "UniState Debug: Adding entry: %s, %s, %d, %d\n",\ curEntry->name, curEntry->faction, curEntry->presence, curEntry->range); logprintf(stdout, debugBuffer); #endif //print data xmlw_attr(writer, "name", "%s", curEntry->name); if(curEntry->faction != NULL) xmlw_elem(writer, "faction", "%s", curEntry->faction); if(curEntry->presence != -1) xmlw_elem(writer, "presence", "%i", curEntry->presence); if(curEntry->range != -1) xmlw_elem(writer, "presence_range", "%i", curEntry->range); //close code block xmlw_endElem(writer); } while((curEntry = curEntry->next) != NULL); xmlw_endElem(writer); return 0; }
/** * @brief Saves player's standings with the factions. * * @param writer The xml writer to use. * @return 0 on success. */ int pfaction_save( xmlTextWriterPtr writer ) { int i; xmlw_startElem(writer,"factions"); for (i=1; i<faction_nstack; i++) { /* player is faction 0 */ /* Must not be static. */ if (faction_isFlag( &faction_stack[i], FACTION_STATIC )) continue; xmlw_startElem(writer,"faction"); xmlw_attr(writer,"name","%s",faction_stack[i].name); xmlw_elem(writer, "standing", "%f", faction_stack[i].player); if (faction_isKnown_(&faction_stack[i])) xmlw_elemEmpty(writer, "known"); xmlw_endElem(writer); /* "faction" */ } xmlw_endElem(writer); /* "factions" */ return 0; }
/** * @brief Saves the active diffs. * * @param writer XML Writer to use. * @return 0 on success. */ int diff_save( xmlTextWriterPtr writer ) { int i; UniDiff_t *diff; xmlw_startElem(writer,"diffs"); for (i=0; i<diff_nstack; i++) { diff = &diff_stack[i]; xmlw_elem(writer, "diff", "%s", diff->name); } xmlw_endElem(writer); /* "diffs" */ return 0; }
/** * @brief Saves all the systems in a claim in XML. * * Use between xmlw_startElem and xmlw_endElem. * * @param writer XML Writer to use. * @param claim Claim to save. */ int claim_xmlSave( xmlTextWriterPtr writer, SysClaim_t *claim ) { int i; StarSystem *sys; if ((claim == NULL) || (claim->ids == NULL)) return 0; for (i=0; i<array_size(claim->ids); i++) { sys = system_getIndex( claim->ids[i] ); if (sys != NULL) { xmlw_elem( writer, "sys", "%s", sys->name ); } else WARN("System Claim has inexistent system."); } return 0; }
/** * @brief Writes a group in an xml node. */ int tech_groupWrite( xmlTextWriterPtr writer, tech_group_t *grp ) { int i, s; /* Handle empty groups. */ if (grp == NULL) return 0; /* Node header. */ xmlw_startElem( writer, "tech" ); /* Save items. */ s = array_size( grp->items ); for (i=0; i<s; i++) xmlw_elem( writer, "item", "%s", tech_getItemName( &grp->items[i] ) ); xmlw_endElem( writer ); /* "tech" */ return 0; }
/** * @brief Saves the current game. * * @return 0 on success. */ int save_all (void) { char file[PATH_MAX]; xmlDocPtr doc; xmlTextWriterPtr writer; /* Create the writer. */ writer = xmlNewTextWriterDoc(&doc, conf.save_compress); if (writer == NULL) { ERR("testXmlwriterDoc: Error creating the xml writer"); return -1; } /* Set the writer parameters. */ xmlTextWriterSetIndentString(writer, (const xmlChar*)" "); xmlTextWriterSetIndent(writer, 1); /* Start element. */ xmlw_start(writer); xmlw_startElem(writer,"naev_save"); /* Save the version and such. */ xmlw_startElem(writer,"version"); xmlw_elem( writer, "naev", "%d.%d.%d", VMAJOR, VMINOR, VREV ); xmlw_elem( writer, "data", "%s", ndata_name() ); xmlw_endElem(writer); /* "version" */ /* Save the data. */ if (save_data(writer) < 0) { ERR("Trying to save game data"); goto err_writer; } /* Finish element. */ xmlw_endElem(writer); /* "naev_save" */ xmlw_done(writer); /* Write to file. */ if (nfile_dirMakeExist("%ssaves", nfile_basePath()) < 0) { WARN("Aborting save..."); goto err_writer; } snprintf(file, PATH_MAX, "%ssaves/%s.ns", nfile_basePath(), player_name); /* Back up old savegame. */ if (nfile_backupIfExists(file) < 0) { WARN("Aborting save..."); goto err_writer; } /* Critical section, if crashes here player's game gets corrupted. * Luckily we have a copy just in case... */ xmlFreeTextWriter(writer); if (xmlSaveFileEnc(file, doc, "UTF-8") < 0) { WARN("Failed to write savegame! You'll most likely have to restore it by copying your backup savegame over your current savegame."); goto err; } xmlFreeDoc(doc); return 0; err_writer: xmlFreeTextWriter(writer); err: xmlFreeDoc(doc); return -1; }
/** * @brief Saves a star system. * * @param writer Write to use for saving the star system. * @param sys Star system to save. * @return 0 on success. */ int dsys_saveSystem( StarSystem *sys ) { int i; xmlDocPtr doc; xmlTextWriterPtr writer; const Planet **sorted_planets; const JumpPoint **sorted_jumps, *jp; char file[PATH_MAX], *cleanName; /* Reconstruct jumps so jump pos are updated. */ system_reconstructJumps(sys); /* Create the writer. */ writer = xmlNewTextWriterDoc(&doc, 0); if (writer == NULL) { WARN("testXmlwriterDoc: Error creating the xml writer"); return -1; } /* Set the writer parameters. */ xmlw_setParams( writer ); /* Start writer. */ xmlw_start(writer); xmlw_startElem( writer, "ssys" ); /* Attributes. */ xmlw_attr( writer, "name", "%s", sys->name ); /* General. */ xmlw_startElem( writer, "general" ); if (sys->background != NULL) xmlw_elem( writer, "background", "%s", sys->background ); xmlw_elem( writer, "radius", "%f", sys->radius ); xmlw_elem( writer, "stars", "%d", sys->stars ); xmlw_elem( writer, "interference", "%f", sys->interference ); xmlw_startElem( writer, "nebula" ); xmlw_attr( writer, "volatility", "%f", sys->nebu_volatility ); xmlw_str( writer, "%f", sys->nebu_density ); xmlw_endElem( writer ); /* "nebula" */ xmlw_endElem( writer ); /* "general" */ /* Position. */ xmlw_startElem( writer, "pos" ); xmlw_elem( writer, "x", "%f", sys->pos.x ); xmlw_elem( writer, "y", "%f", sys->pos.y ); xmlw_endElem( writer ); /* "pos" */ /* Planets. */ sorted_planets = malloc( sizeof(Planet*) * sys->nplanets); memcpy( sorted_planets, sys->planets, sizeof(Planet*) * sys->nplanets ); qsort( sorted_planets, sys->nplanets, sizeof(Planet*), dsys_compPlanet ); xmlw_startElem( writer, "assets" ); for (i=0; i<sys->nplanets; i++) xmlw_elem( writer, "asset", "%s", sorted_planets[i]->name ); xmlw_endElem( writer ); /* "assets" */ free(sorted_planets); /* Jumps. */ sorted_jumps = malloc( sizeof(JumpPoint*) * sys->njumps ); for (i=0; i<sys->njumps; i++) sorted_jumps[i] = &sys->jumps[i]; qsort( sorted_jumps, sys->njumps, sizeof(JumpPoint*), dsys_compJump ); xmlw_startElem( writer, "jumps" ); for (i=0; i<sys->njumps; i++) { jp = sorted_jumps[i]; xmlw_startElem( writer, "jump" ); xmlw_attr( writer, "target", "%s", jp->target->name ); /* Position. */ if (!jp_isFlag( jp, JP_AUTOPOS )) { xmlw_startElem( writer, "pos" ); xmlw_attr( writer, "x", "%f", jp->pos.x ); xmlw_attr( writer, "y", "%f", jp->pos.y ); xmlw_endElem( writer ); /* "pos" */ } else xmlw_elemEmpty( writer, "autopos" ); /* Radius and misc properties. */ if (jp->radius != 200.) xmlw_elem( writer, "radius", "%f", jp->radius ); /* More flags. */ if (jp_isFlag( jp, JP_HIDDEN )) xmlw_elemEmpty( writer, "hidden" ); if (jp_isFlag( jp, JP_EXITONLY )) xmlw_elemEmpty( writer, "exitonly" ); xmlw_elem( writer, "hide", "%f", sqrt(jp->hide) ); xmlw_endElem( writer ); /* "jump" */ } xmlw_endElem( writer ); /* "jumps" */ free(sorted_jumps); xmlw_endElem( writer ); /** "ssys" */ xmlw_done(writer); /* No need for writer anymore. */ xmlFreeTextWriter(writer); /* Write data. */ cleanName = uniedit_nameFilter( sys->name ); nsnprintf( file, sizeof(file), "%s/%s.xml", conf.dev_save_sys, cleanName ); xmlSaveFileEnc( file, doc, "UTF-8" ); /* Clean up. */ xmlFreeDoc(doc); free(cleanName); return 0; }
/** * @brief Saves selected systems as a map outfit file. * * @return 0 on success. */ int dsys_saveMap (StarSystem **uniedit_sys, int uniedit_nsys) { int i, j, k; xmlDocPtr doc; xmlTextWriterPtr writer; StarSystem *s; char file[PATH_MAX], *cleanName; /* Create the writer. */ writer = xmlNewTextWriterDoc(&doc, 0); if (writer == NULL) { WARN("testXmlwriterDoc: Error creating the xml writer"); return -1; } /* Set the writer parameters. */ xmlw_setParams( writer ); /* Start writer. */ xmlw_start(writer); xmlw_startElem( writer, "outfit" ); /* Attributes. */ xmlw_attr( writer, "name", "Editor-generated Map" ); /* General. */ xmlw_startElem( writer, "general" ); xmlw_elem( writer, "mass", "%d", 0 ); xmlw_elem( writer, "price", "%d", 1000 ); xmlw_elem( writer, "description", "%s", "This map has been created by the universe editor." ); xmlw_elem( writer, "gfx_store", "%s", "map" ); xmlw_endElem( writer ); /* "general" */ xmlw_startElem( writer, "specific" ); xmlw_attr( writer, "type", "map" ); /* Iterate over all selected systems. Save said systems and any NORMAL jumps they might share. */ for (i = 0; i < uniedit_nsys; i++) { s = uniedit_sys[i]; xmlw_startElem( writer, "sys" ); xmlw_attr( writer, "name", "%s", s->name ); /* Iterate jumps and see if they lead to any other systems in our array. */ for (j = 0; j < s->njumps; j++) { /* Ignore hidden and exit-only jumps. */ if (jp_isFlag(&s->jumps[j], JP_EXITONLY )) continue; if (jp_isFlag(&s->jumps[j], JP_HIDDEN)) continue; /* This is a normal jump. */ for (k = 0; k < uniedit_nsys; k++) { if (s->jumps[j].target == uniedit_sys[k]) { xmlw_elem( writer, "jump", "%s", uniedit_sys[k]->name ); break; } } } /* Iterate assets and add them */ for (j = 0; j < s->nplanets; j++) { if (s->planets[j]->real) xmlw_elem( writer, "asset", "%s", s->planets[j]->name ); } xmlw_endElem( writer ); /* "sys" */ } xmlw_endElem( writer ); /* "specific" */ xmlw_endElem( writer ); /* "outfit" */ xmlw_done(writer); /* No need for writer anymore. */ xmlFreeTextWriter(writer); /* Write data. */ cleanName = uniedit_nameFilter( "saved map" ); nsnprintf( file, sizeof(file), "%s/%s.xml", conf.dev_save_map, cleanName ); xmlSaveFileEnc( file, doc, "UTF-8" ); /* Clean up. */ xmlFreeDoc(doc); free(cleanName); return 0; }
/** * @brief Saves the player's active missions. * * @param writer XML Write to use to save missions. * @return 0 on success. */ int missions_saveActive( xmlTextWriterPtr writer ) { int i,j,n; int nitems; char **items; xmlw_startElem(writer,"missions"); for (i=0; i<MISSION_MAX; i++) { if (player_missions[i]->id != 0) { xmlw_startElem(writer,"mission"); /* data and id are attributes because they must be loaded first */ xmlw_attr(writer,"data","%s",player_missions[i]->data->name); xmlw_attr(writer,"id","%u",player_missions[i]->id); xmlw_elem(writer,"title","%s",player_missions[i]->title); xmlw_elem(writer,"desc","%s",player_missions[i]->desc); xmlw_elem(writer,"reward","%s",player_missions[i]->reward); /* Markers. */ xmlw_startElem( writer, "markers" ); if (player_missions[i]->markers != NULL) { n = array_size( player_missions[i]->markers ); for (j=0; j<n; j++) { xmlw_startElem(writer,"marker"); xmlw_attr(writer,"id","%d",player_missions[i]->markers[j].id); xmlw_attr(writer,"type","%d",player_missions[i]->markers[j].type); xmlw_str(writer,"%s", system_getIndex(player_missions[i]->markers[j].sys)->name); xmlw_endElem(writer); /* "marker" */ } } xmlw_endElem( writer ); /* "markers" */ /* Cargo */ xmlw_startElem(writer,"cargos"); for (j=0; j<player_missions[i]->ncargo; j++) xmlw_elem(writer,"cargo","%u", player_missions[i]->cargo[j]); xmlw_endElem(writer); /* "cargos" */ /* OSD. */ if (player_missions[i]->osd > 0) { xmlw_startElem(writer,"osd"); /* Save attributes. */ items = osd_getItems(player_missions[i]->osd, &nitems); xmlw_attr(writer,"title","%s",osd_getTitle(player_missions[i]->osd)); xmlw_attr(writer,"nitems","%d",nitems); xmlw_attr(writer,"active","%d",osd_getActive(player_missions[i]->osd)); /* Save messages. */ for (j=0; j<nitems; j++) xmlw_elem(writer,"msg","%s",items[j]); xmlw_endElem(writer); /* "osd" */ } /* Claims. */ xmlw_startElem(writer,"claims"); claim_xmlSave( writer, player_missions[i]->claims ); xmlw_endElem(writer); /* "claims" */ /* Write Lua magic */ xmlw_startElem(writer,"lua"); nxml_persistLua( player_missions[i]->L, writer ); xmlw_endElem(writer); /* "lua" */ xmlw_endElem(writer); /* "mission" */ } } xmlw_endElem(writer); /* "missions" */ return 0; }
/** * @brief Saves a planet. * * @param writer Write to use for saving the star planet. * @param p Planet to save. * @return 0 on success. */ static int dpl_savePlanet( xmlTextWriterPtr writer, const Planet *p ) { int i; xmlw_startElem( writer, "asset" ); /* Attributes. */ xmlw_attr( writer, "name", "%s", p->name ); /* Explicit virtualness. */ if (p->real == ASSET_VIRTUAL) xmlw_elemEmpty( writer, "virtual" ); /* Position. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "pos" ); xmlw_elem( writer, "x", "%f", p->pos.x ); xmlw_elem( writer, "y", "%f", p->pos.y ); xmlw_endElem( writer ); /* "pos" */ } /* GFX. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "GFX" ); xmlw_elem( writer, "space", "%s", p->gfx_spacePath ); xmlw_elem( writer, "exterior", "%s", p->gfx_exteriorPath ); xmlw_endElem( writer ); /* "GFX" */ } /* Presence. */ if (p->faction >= 0) { xmlw_startElem( writer, "presence" ); xmlw_elem( writer, "faction", "%s", faction_name( p->faction ) ); xmlw_elem( writer, "value", "%f", p->presenceAmount ); xmlw_elem( writer, "range", "%d", p->presenceRange ); xmlw_endElem( writer ); } /* General. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "general" ); xmlw_elem( writer, "class", "%c", planet_getClass( p ) ); xmlw_elem( writer, "population", "%"PRIu64, p->population ); xmlw_startElem( writer, "services" ); if (planet_hasService( p, PLANET_SERVICE_LAND )) { if (p->land_func == NULL) xmlw_elemEmpty( writer, "land" ); else xmlw_elem( writer, "land", "%s", p->land_func ); } if (planet_hasService( p, PLANET_SERVICE_REFUEL )) xmlw_elemEmpty( writer, "refuel" ); if (planet_hasService( p, PLANET_SERVICE_BAR )) xmlw_elemEmpty( writer, "bar" ); if (planet_hasService( p, PLANET_SERVICE_MISSIONS )) xmlw_elemEmpty( writer, "missions" ); if (planet_hasService( p, PLANET_SERVICE_COMMODITY )) xmlw_elemEmpty( writer, "commodity" ); if (planet_hasService( p, PLANET_SERVICE_OUTFITS )) xmlw_elemEmpty( writer, "outfits" ); if (planet_hasService( p, PLANET_SERVICE_SHIPYARD )) xmlw_elemEmpty( writer, "shipyard" ); xmlw_endElem( writer ); /* "services" */ if (planet_hasService( p, PLANET_SERVICE_LAND )) { xmlw_startElem( writer, "commodities" ); for (i=0; i<p->ncommodities; i++) xmlw_elem( writer, "commodity", "%s", p->commodities[i]->name ); xmlw_endElem( writer ); /* "commodities" */ xmlw_elem( writer, "description", "%s", p->description ); if (planet_hasService( p, PLANET_SERVICE_BAR )) xmlw_elem( writer, "bar", "%s", p->bar_description ); } xmlw_endElem( writer ); /* "general" */ } /* Tech. */ if (planet_hasService( p, PLANET_SERVICE_LAND )) tech_groupWrite( writer, p->tech ); xmlw_endElem( writer ); /** "planet" */ return 0; }
/** * @brief Saves a planet. * * @param writer Write to use for saving the star planet. * @param p Planet to save. * @return 0 on success. */ int dpl_savePlanet( const Planet *p ) { xmlDocPtr doc; xmlTextWriterPtr writer; char file[PATH_MAX], *cleanName; int i; /* Create the writer. */ writer = xmlNewTextWriterDoc(&doc, 0); if (writer == NULL) { WARN("testXmlwriterDoc: Error creating the xml writer"); return -1; } /* Set the writer parameters. */ xmlw_setParams( writer ); /* Start writer. */ xmlw_start(writer); xmlw_startElem( writer, "asset" ); /* Attributes. */ xmlw_attr( writer, "name", "%s", p->name ); /* Explicit virtualness. */ if (p->real == ASSET_VIRTUAL) xmlw_elemEmpty( writer, "virtual" ); /* Position. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "pos" ); xmlw_elem( writer, "x", "%f", p->pos.x ); xmlw_elem( writer, "y", "%f", p->pos.y ); xmlw_endElem( writer ); /* "pos" */ } /* GFX. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "GFX" ); xmlw_elem( writer, "space", "%s", p->gfx_spacePath ); xmlw_elem( writer, "exterior", "%s", p->gfx_exteriorPath ); xmlw_endElem( writer ); /* "GFX" */ } /* Presence. */ if (p->faction >= 0) { xmlw_startElem( writer, "presence" ); xmlw_elem( writer, "faction", "%s", faction_name( p->faction ) ); xmlw_elem( writer, "value", "%f", p->presenceAmount ); xmlw_elem( writer, "range", "%d", p->presenceRange ); xmlw_endElem( writer ); } /* General. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "general" ); xmlw_elem( writer, "class", "%s", p->class ); xmlw_elem( writer, "population", "%"PRIu64, p->population ); xmlw_elem( writer, "hide", "%f", sqrt(p->hide) ); xmlw_startElem( writer, "services" ); if (planet_hasService( p, PLANET_SERVICE_LAND )) { if (p->land_func == NULL) xmlw_elemEmpty( writer, "land" ); else xmlw_elem( writer, "land", "%s", p->land_func ); } if (planet_hasService( p, PLANET_SERVICE_REFUEL )) xmlw_elemEmpty( writer, "refuel" ); if (planet_hasService( p, PLANET_SERVICE_BAR )) xmlw_elemEmpty( writer, "bar" ); if (planet_hasService( p, PLANET_SERVICE_MISSIONS )) xmlw_elemEmpty( writer, "missions" ); if (planet_hasService( p, PLANET_SERVICE_COMMODITY )) xmlw_elemEmpty( writer, "commodity" ); if (planet_hasService( p, PLANET_SERVICE_OUTFITS )) xmlw_elemEmpty( writer, "outfits" ); if (planet_hasService( p, PLANET_SERVICE_SHIPYARD )) xmlw_elemEmpty( writer, "shipyard" ); xmlw_endElem( writer ); /* "services" */ if (planet_hasService( p, PLANET_SERVICE_LAND )) { xmlw_startElem( writer, "commodities" ); for (i=0; i<p->ncommodities; i++) xmlw_elem( writer, "commodity", "%s", p->commodities[i]->name ); xmlw_endElem( writer ); /* "commodities" */ if (planet_isBlackMarket(p)) xmlw_elemEmpty( writer, "blackmarket" ); xmlw_elem( writer, "description", "%s", p->description ); if (planet_hasService( p, PLANET_SERVICE_BAR )) xmlw_elem( writer, "bar", "%s", p->bar_description ); } xmlw_endElem( writer ); /* "general" */ }