2 #include "cmd/unit_generic.h"
13 #include "cmd/script/mission.h"
14 #include "gfx/cockpit_generic.h"
15 #include "networking/const.h"
17 #include "cmd/fg_util.h"
23 using namespace VSFileSystem;
48 cout<<
"Hi helper play "<<num<<endl;
49 static string *res = NULL;
51 res =
new std::string;
63 fprintf( stderr,
"!!! ERROR : Creating default save.4.x.txt file : %s\n", f.
GetFullPath().c_str() );
68 fprintf( stderr,
"!!! ERROR : Opening the default save we just created\n" );
73 long length = f.
Size();
75 char *temp = (
char*) malloc( length+1 );
77 f.
Read( temp, length );
79 for (
int i = length-1; i >= 0; i--) {
80 if (temp[i] ==
'\r' || temp[i] ==
'\n')
81 temp[i] = (end ?
'\0' :
'_');
82 else if (temp[i] ==
'\0' || temp[i] ==
' ' || temp[i] ==
'\t')
83 temp[i] = (end ?
'\0' :
'_');
94 if (*res->begin() ==
'~') {
97 for (
unsigned int i = 1; i < res->length(); i++) {
98 char cc = *(res->begin()+i);
99 f.
Write( &cc,
sizeof (
char) );
102 f.
Write( &cc,
sizeof (
char) );
108 if ( num == 0 || res->empty() ) {
123 if (*ret.begin() ==
'~')
124 return ret.substr( 1, ret.length() );
132 if (*ret.begin() ==
'~')
140 if (dst[0] !=
'\0' && src[0] !=
'\0') {
148 f.
Write( savecontent );
151 fprintf( stderr,
"WARNING : couldn't open savegame to copy to : %s as SaveFile", dst );
154 fprintf( stderr,
"WARNING : couldn't find the savegame to copy : %s as SaveFile", src );
162 typedef std::map< string, vector< std::string > >
MSD;
169 typedef vsUMap< string, vector< float > >
MFD;
173 SaveGame::SaveGame(
const std::string &pilot )
176 ForceStarSystem = string(
"" );
177 PlayerLocation.Set( FLT_MAX, FLT_MAX, FLT_MAX );
184 delete missionstringdata;
190 ForceStarSystem = sys;
195 return ForceStarSystem;
200 return ForceStarSystem;
210 PlayerLocation.Set( 1, 1, 1 );
216 return PlayerLocation;
223 string SaveGame::WriteNewsData()
227 vector< gameMessage >tmp;
229 vector< string >newsvec;
230 newsvec.push_back(
"news" );
231 while ( (
mission->msgcenter->last( i++, last, newsvec ) ) )
232 tmp.push_back( last );
234 for (
int j = tmp.size()-1;
j >= 0;
j--) {
235 char *msg = strdup( tmp[
j].message.get().c_str() );
244 ret += string( msg )+
"\n";
252 string::size_type loc;
253 vector< string > ret;
254 while ( ( loc = s.find(
"|" ) ) != string::npos ) {
255 ret.push_back( s.substr( 0, loc ) );
256 cout<<
"Found ship named : "<<s.substr( 0, loc )<<endl;
257 s = s.substr( loc+1 );
261 cout<<
"Found ship named : "<<s<<endl;
269 for (
unsigned int i = 0; i < s.size()-1; i++)
276 void CopySavedShips( std::string filename,
int player_num,
const std::vector< std::string > &starships,
bool load )
278 for (
unsigned int i = 0; i < starships.size(); i += 2) {
281 string srcnam = filename;
295 dst.
Write( srcdata );
297 printf(
"Error: Cannot Copy Unit %s from save file %s to %s\n",
298 starships[i].c_str(),
303 printf(
"Error: Cannot Open Unit %s from save file %s.\n",
304 starships[i].c_str(),
316 Unit *un = cp->GetSaveParent();
319 if (un->GetHull() > 0) {
320 vector< string > packedInfo;
321 cp->PackUnitInfo(packedInfo);
323 cp->savegame->WriteSaveGame( cp->activeStarSystem->getFileName().c_str(),
324 un->LocalPosition(), cp->credits, packedInfo, auto_save ? -1 : player_num );
325 un->WriteUnit( cp->GetUnitModifications().c_str() );
328 cp->savegame->SetStarSystem( cp->activeStarSystem->getFileName() );
329 cp->savegame->SetPlayerLocation( un->LocalPosition() );
330 CopySavedShips( cp->GetUnitModifications(), player_num, packedInfo, false );
335 int hopto(
char *buf,
char endln,
char endln2,
int readlen )
337 if (endln ==
' ' || endln2 ==
' ')
338 while (buf[readlen] && buf[readlen] ==
' ')
340 for (; buf[readlen] != 0 && buf[readlen] != endln && buf[readlen] != endln2; readlen++)
342 if ( (buf[readlen] && buf[readlen] == endln) || buf[readlen] == endln2 )
347 void SaveGame::ReadNewsData(
char* &buf,
bool just_skip )
351 vector< string >n00s;
352 n00s.push_back(
"news" );
353 vector< string >
nada;
354 mission->msgcenter->clear( n00s, nada );
355 int offset =
hopto( buf,
'\n',
'\n', 0 );
357 sscanf( buf,
"%d\n", &numnews );
359 for (i = 0; i < numnews; i++) {
360 offset =
hopto( buf,
'\n',
'\n', 0 );
364 for (l = 0; l < offset-1; l++)
365 if (buf[l] !=
'\r' && buf[l] !=
'\n')
367 if (!just_skip && buf[l] !=
'\r' && buf[l] !=
'\n' && buf[l])
368 mission->msgcenter->add(
"game",
"news", buf+l );
376 if ( game_options.
Drone.compare( filename ) )
377 RemoveUnitFromSave( address );
382 return missiondata->m[magic_number];
387 static const std::vector< float > empty;
388 MissionFloatDat::MFD::const_iterator it = missiondata->m.find( magic_number );
389 return ( it == missiondata->m.end() ) ? empty : it->second;
394 MissionFloatDat::MFD::const_iterator it = missiondata->m.find( magic_number );
395 return ( it == missiondata->m.end() ) ? 0 : it->second.size();
400 static const std::vector< string > empty;
401 MissionStringDat::MSD::const_iterator it = missionstringdata->m.find( magic_number );
402 return ( it == missionstringdata->m.end() ) ? empty : it->second;
407 return missionstringdata->m[magic_number];
412 MissionStringDat::MSD::const_iterator it = missionstringdata->m.find( magic_number );
413 return ( it == missionstringdata->m.end() ) ? 0 : it->second.size();
416 template <
class MContainerType >
419 typename MContainerType::iterator i;
420 for (i = t.begin(); i != t.end();)
421 if ( i->second.empty() )
428 string SaveGame::WriteMissionData()
431 RemoveEmpty< MissionFloatDat::MFD > ( missiondata->m );
433 for (MissionFloatDat::MFD::iterator i = missiondata->m.begin(); i != missiondata->m.end(); i++) {
434 unsigned int siz = (*i).second.size();
437 string k = (*i).first;
438 {
for (
size_t i=0,len=k.length(); i<len; ++i)
439 if (k[i] ==
' ') k[i] =
'`'; }
442 for (
unsigned int j = 0;
j < siz;
j++)
451 while ( *buf && isspace( *buf ) )
454 while ( *buf && ( !isspace( *buf ) ) )
456 str.resize(buf - start);
457 for (
size_t i=0; start < buf; ++i)
462 void SaveGame::ReadMissionData(
char* &buf,
bool select_data,
const std::set< std::string > &select_data_filter )
464 missiondata->m.clear();
467 sscanf( buf2,
" %d ", &mdsize );
469 buf2 +=
hopto( buf2,
' ',
'\n', 0 );
470 for (
int i = 0; i < mdsize; i++) {
475 {
for (
size_t i=0,len=mag_num.length(); i<len; ++i)
476 if (mag_num[i] ==
'`') mag_num[i] =
' '; }
478 sscanf( buf2,
"%d ", &md_i_size );
480 buf2 +=
hopto( buf2,
' ',
'\n', 0 );
481 vector< float > *vecfloat = 0;
483 if ( !select_data || select_data_filter.count( mag_num ) ) {
484 vecfloat = &missiondata->m[mag_num];
486 vecfloat->reserve(md_i_size);
489 for (
int j = 0;
j < md_i_size;
j++) {
491 double float_val = atof(buf2);
492 vecfloat->push_back( float_val );
495 buf2 +=
hopto( buf2,
' ',
'\n', 0 );
503 unsigned int size = 0;
505 while ( (*buf) && ( (*buf) !=
' ' || (!found) ) ) {
506 if ( (*buf) >=
'0' && (*buf) <=
'9' ) {
518 while (i < size && *buf)
525 unsigned int size = 0;
527 while ( (*buf) && ( (*buf) !=
' ' || (!found) ) ) {
528 if ( (*buf) >=
'0' && (*buf) <=
'9' ) {
538 while (i < size && *buf)
547 void SaveGame::ReadMissionStringData(
char* &buf,
bool select_data,
const std::set< std::string > &select_data_filter )
549 missionstringdata->m.clear();
552 sscanf( buf2,
" %d ", &mdsize );
554 buf2 +=
hopto( buf2,
' ',
'\n', 0 );
555 for (
int i = 0; i < mdsize; i++) {
558 md_i_size = strtol( buf2, (
char**) NULL, 10 );
560 buf2 +=
hopto( buf2,
' ',
'\n', 0 );
561 vector< string > *vecstring = 0;
563 if ( !select_data || select_data_filter.count( mag_num ) ) {
564 vecstring = &missionstringdata->m[mag_num];
566 vecstring->reserve(md_i_size);
569 for (
int j = 0;
j < md_i_size;
j++) {
578 this->PurgeZeroStarships();
583 for (MissionStringDat::MSD::iterator i = missionstringdata->m.begin(), ie = missionstringdata->m.end(); i != ie; ++i)
584 if ( fg_util::IsFGKey( i->first ) )
585 if ( fg_util::CheckFG( i->second ) )
591 static inline void PushBackUInt(
unsigned int i, vector< char > &ret )
595 ret.push_back(
'0' );
597 unsigned int p = 0, q = ret.size();
599 tmp[p++] = (i%10+
'0');
608 static inline void PushBackChars(
const char *c, vector< char > &ret )
610 int ini = ret.size();
611 ret.resize( ret.size()+strlen( c ) );
616 static inline void PushBackString(
const string &input, vector< char > &ret )
618 PushBackUInt( input.length(), ret );
619 PushBackChars(
" ", ret );
620 PushBackChars( input.c_str(), ret );
623 void SaveGame::WriteMissionStringData( std::vector< char > &ret )
625 RemoveEmpty< MissionStringDat::MSD > ( missionstringdata->m );
626 PushBackUInt( missionstringdata->m.size(), ret );
627 for (MissionStringDat::MSD::iterator i = missionstringdata->m.begin(); i != missionstringdata->m.end(); i++) {
628 const string &key = (*i).first;
629 unsigned int siz = (*i).second.size();
630 if (key ==
"mission_descriptions" || key ==
"mission_scripts" || key ==
"mission_vars" || key ==
"mission_names") {
635 PushBackChars(
"\n", ret );
636 PushBackString( key, ret );
637 PushBackUInt( siz, ret );
638 PushBackChars(
" ", ret );
639 for (
unsigned int j = 0;
j < siz;
j++)
640 PushBackString( (*i).second[
j], ret );
644 void SaveGame::ReadStardate(
char* &buf )
647 cout<<
"Read stardate: "<<stardate<<endl;
655 const std::set< std::string > &select_data_filter )
660 while ( 3 == sscanf( buf,
"%d %s %s", &a, unitname, factname ) ) {
662 while ( (*buf) && isspace( *buf ) )
664 buf +=
hopto( buf,
' ',
'\n', 0 );
665 buf +=
hopto( buf,
' ',
'\n', 0 );
666 buf +=
hopto( buf,
' ',
'\n', 0 );
667 if ( a == 0 && 0 == strcmp( unitname,
"factions" ) && 0 == strcmp( factname,
"begin" ) ) {
670 }
else if ( a == 0 && 0 == strcmp( unitname,
"mission" ) && 0 == strcmp( factname,
"data" ) ) {
671 ReadMissionData( buf, select_data, select_data_filter );
672 }
else if ( a == 0 && 0 == strcmp( unitname,
"missionstring" ) && 0 == strcmp( factname,
"data" ) ) {
673 ReadMissionStringData( buf, select_data, select_data_filter );
674 }
else if ( a == 0 && 0 == strcmp( unitname,
"python" ) && 0 == strcmp( factname,
"data" ) ) {
676 }
else if ( a == 0 && 0 == strcmp( unitname,
"news" ) && 0 == strcmp( factname,
"data" ) ) {
677 if (commitfactions) ReadNewsData( buf, skip_news );
678 }
else if ( a == 0 && 0 == strcmp( unitname,
"stardate" ) && 0 == strcmp( factname,
"data" ) ) {
680 if (commitfactions && !
SERVER )
685 char output[31] = {0};
686 strncpy( output, buf, 30 );
687 printf(
"buf unrecognized %s...\n", output );
695 vector< string >scripts = getMissionStringData(
"active_scripts" );
696 vector< string >missions = getMissionStringData(
"active_missions" );
698 "import VS\nVS.loading_active_missions=True\nprint \"Loading active missions \"+str(VS.loading_active_missions)\n" );
705 for (i = 0; i < scripts.size() && i < missions.size(); ++i) {
707 if ( !missions[i].empty() )
708 LoadMission( missions[i].c_str(), scripts[i], false );
711 if ( PyErr_Occurred() ) {
718 PyRun_SimpleString(
"import VS\nVS.loading_active_missions=False\n" );
719 getMissionStringData(
"active_scripts" ) = scripts;
720 getMissionStringData(
"active_missions" ) = missions;
730 static char * tmprealloc(
char *var,
int &oldlength,
int newlength )
732 if (oldlength < newlength) {
733 oldlength = newlength;
734 var = (
char*) realloc( var, newlength );
736 memset( var, 0, newlength );
741 std::vector< std::string >unitname,
746 string playerdata(
"" );
748 char *tmp = (
char*) malloc( MB );
749 memset( tmp, 0, MB );
751 QVector FighterPos = PlayerLocation-FP;
754 tmp = tmprealloc( tmp, MB, pipedunitname.length()+strlen( systemname )+256 );
757 sprintf( tmp,
"%s^%f^%s %f %f %f %s", systemname, credits,
758 pipedunitname.c_str(), FighterPos.i, FighterPos.j, FighterPos.k, fact.c_str() );
760 sprintf( tmp,
"%s^%f^%s %f %f %f", systemname, credits, pipedunitname.c_str(), FighterPos.i, FighterPos.j, FighterPos.k );
761 playerdata = string( tmp );
762 this->playerfaction = fact;
763 SetSavedCredits( credits );
772 string dyn_univ(
"" );
774 char *tmp = (
char*) malloc( MB );
775 memset( tmp, 0, MB );
779 cerr<<
"SAVING STARDATE - SERVER="<<
SERVER<<endl;
782 dyn_univ +=
"\n0 stardate data " + stardate;
784 memset( tmp, 0, MB );
785 sprintf( tmp,
"\n%d %s %s", 0,
"mission",
"data " );
786 dyn_univ += string( tmp );
787 dyn_univ += WriteMissionData();
788 memset( tmp, 0, MB );
789 sprintf( tmp,
"\n%d %s %s", 0,
"missionstring",
"data " );
790 dyn_univ += string( tmp );
791 vector< char >missionstringdata1;
792 WriteMissionStringData( missionstringdata1 );
793 dyn_univ += string( &missionstringdata1[0], missionstringdata1.size() );
796 tmp = tmprealloc( tmp, MB, last_written_pickled_data.length()+256 );
797 sprintf( tmp,
"\n%d %s %s %s ", 0,
"python",
"data", last_written_pickled_data.c_str() );
798 dyn_univ += string( tmp );
801 memset( tmp, 0, MB );
802 sprintf( tmp,
"\n%d %s %s", 0,
"news",
"data " );
803 dyn_univ += string( tmp );
804 dyn_univ += WriteNewsData();
806 memset( tmp, 0, MB );
807 sprintf( tmp,
"\n%d %s %s", 0,
"factions",
"begin " );
808 dyn_univ += string( tmp );
817 using namespace VSFileSystem;
822 std::vector< std::string >unitname,
827 savestring = string(
"" );
828 printf(
"Writing Save Game %s", outputsavegame.c_str() );
829 savestring += WritePlayerData( FP, unitname, systemname, credits, fact );
830 savestring += WriteDynamicUniverse();
831 if (outputsavegame.length() != 0) {
838 f.
Write( savestring.c_str(), savestring.length() );
840 if (player_num != -1) {
842 last_pickled_data = last_written_pickled_data;
848 cerr<<
"occured while opening file: "<<outputsavegame<<endl;
855 static float savedcredits = 0;
868 if ( !filename.empty() )
869 outputsavegame =
string(
"Autosave-" )+filename;
871 outputsavegame = string(
"Autosave" );
876 const string &originalstarsystem,
878 bool &shouldupdatepos,
880 vector< string > &savedstarship,
882 const string &save_contents,
888 const std::set< std::string > &select_data_filter )
890 const string &str = save_contents;
893 shouldupdatepos = !(PlayerLocation.i == FLT_MAX || PlayerLocation.j == FLT_MAX || PlayerLocation.k == FLT_MAX);
895 SetOutputFileName( filename );
901 if ( plsave.length() ) {
906 }
else if (filename.length() > 0) {
922 if ( err <=
Ok || (!read && str !=
"") ) {
925 if (savestring.length() > 0) {
926 char *buf =
new char[savestring.length()+1];
927 buf[savestring.length()] =
'\0';
928 memcpy( buf, savestring.c_str(), savestring.length() );
929 int headlen =
hopto( buf,
'\n',
'\n', 0 );
930 char *deletebuf = buf;
931 char *tmp2 = (
char*) malloc( headlen+2 );
932 char *freetmp2 = tmp2;
933 char *factionname = (
char*) malloc( headlen+2 );
934 if ( headlen > 0 && (buf[headlen-1] ==
'\n' || buf[headlen-1] ==
' ' || buf[headlen-1] ==
'\r') )
935 buf[headlen-1] =
'\0';
936 factionname[headlen+1] =
'\0';
938 int res = sscanf( buf,
"%s %lf %lf %lf %s", tmp2, &tmppos.i, &tmppos.j, &tmppos.k, factionname );
939 if (res == 4 || res == 5) {
941 for (
int j = 0;
'\0' != tmp2[
j];
j++)
942 if (tmp2[
j] ==
'^') {
943 sscanf( tmp2+
j+1,
"%f", &credits );
945 for (
int k =
j+1; tmp2[k] !=
'\0'; k++)
946 if (tmp2[k] ==
'^') {
948 savedstarship.clear();
956 playerfaction = string( factionname );
957 cout<<
"Found faction in save file : "<<playerfaction<<endl;
960 playerfaction = string(
"privateer" );
961 cout<<
"Faction not found assigning default one: privateer"<<endl;
964 if (ForceStarSystem.length() == 0)
965 ForceStarSystem =
string( tmp2 );
966 if (PlayerLocation.i == FLT_MAX || PlayerLocation.j == FLT_MAX || PlayerLocation.k == FLT_MAX) {
967 shouldupdatepos =
true;
968 PlayerLocation = tmppos;
971 ReadSavedPackets( buf, commitfaction, skip_news, select_data, select_data_filter );
981 if (PlayerLocation.i == FLT_MAX || PlayerLocation.j == FLT_MAX || PlayerLocation.k == FLT_MAX) {
982 shouldupdatepos =
false;
986 shouldupdatepos =
true;
988 if (ForceStarSystem.length() == 0) {
989 ForceStarSystem = FSS;
990 originalsystem = FSS;
992 originalsystem = ForceStarSystem;
993 FSS = ForceStarSystem;
995 SetSavedCredits( credits );