Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
netclient_login.cpp
Go to the documentation of this file.
2 #include "cmd/unit_generic.h"
3 #include "vs_globals.h"
4 #include "vsfilesystem.h"
5 #include "networking/netclient.h"
6 #include "savegame.h"
7 #include "main_loop.h"
10 #include "lin_time.h"
15 #include "networking/client.h"
16 #include "networking/fileutil.h"
17 
18 std::string global_username;
19 std::string global_password;
20 /*
21  ************************************************************
22  **** Authenticate the client ***
23  ************************************************************
24  */
25 
27 {
28  COUT<<" enter "<<__PRETTY_FUNCTION__<<endl;
29 
30  Packet packet2;
31  string str_callsign, str_passwd;
32  NetBuffer netbuf;
33 
34  //Get the name and password from vegastrike.config
35  //Maybe someday use a default Guest account if no callsign or password is provided thus allowing
36  //Player to wander but not interact with the universe
37  this->callsign = str_callsign = vs_config->getVariable( "player", "callsign", "" );
38  this->password = str_passwd = vs_config->getVariable( "player", "password", "" );
39  if ( global_username.length() )
40  this->callsign = global_username;
41  if ( global_password.length() )
42  this->password = global_password;
43  if ( str_callsign.length() && str_passwd.length() ) {
44  netbuf.addString( str_callsign );
45  netbuf.addString( str_passwd );
46 
47  packet2.send( CMD_LOGIN, 0,
48  netbuf.getData(), netbuf.getDataLength(),
49  SENDRELIABLE, NULL, *this->clt_tcp_sock,
50  __FILE__, PSEUDO__LINE__( 165 ) );
51  COUT<<"Send login for player <"<<str_callsign<<">:<*******"
52  "> - buffer length : "<<packet2.getDataLength()
53  <<" (+"<<packet2.getHeaderLength()<<" header len"<<endl;
54  } else {
55  cerr<<"Callsign and/or password not specified in vegastrike.config, please check this."<<endl<<endl;
56  return -1;
57  }
58  return 0;
59 }
60 
61 /*
62  ************************************************************
63  **** Login loop : waiting for game server to respond ***
64  ************************************************************
65  */
66 
67 int NetClient::loginAuth( string str_callsign, string str_passwd, string &error )
68 {
69  COUT<<"enter "<<"NetClient::loginLoop"<<endl;
70  lastsave.clear();
71  ship_select_list.clear();
72 
73  Packet packet2;
74  NetBuffer netbuf;
75 
76  //memset( buffer, 0, tmplen+1);
77  netbuf.addString( str_callsign );
78  netbuf.addString( str_passwd );
79 
80  packet2.send( CMD_LOGIN, 0,
81  netbuf.getData(), netbuf.getDataLength(),
82  SENDRELIABLE, NULL, *this->clt_tcp_sock,
83  __FILE__, PSEUDO__LINE__( 316 ) );
84  COUT<<"Sent login for player <"<<str_callsign<<">:<*******"
85  <<">"<<endl
86  <<" - buffer length : "<<packet2.getDataLength()<<endl;
87  this->callsign = str_callsign;
88  this->password = str_passwd;
89  //Now the loop
90  return loginLoop( error );
91 }
92 
94 {
95  int timeout = 0, recv = 0;
96  //int ret=0;
97 
98  Packet packet;
99 
100  string login_tostr = vs_config->getVariable( "network", "logintimeout", "100" );
101  timeval tv = {atoi( login_tostr.c_str() ), 0};
102  while (!timeout) {
103  recv = this->recvMsg( &packet, &tv );
104  if (recv == 0) {
105  error = "NETWORK ERROR : Login procedeure timed out.";
106  timeout = 1;
107  } else if (recv < 0) {
108  char str[127];
109  sprintf( str, "NETWORK ERROR in recieving login data (error number %d)!!!",
110 #ifdef _WIN32
111  WSAGetLastError()
112 #else
113  errno
114 #endif
115  );
116  error = (str);
117  timeout = 1;
118  } else {
119  break;
120  }
121  }
122  COUT<<"End of login loop"<<endl;
123  if (lastsave.empty() || lastsave[0] == "") {
124  if ( ship_select_list.empty() )
125  error = "Login failure!";
126  return ship_select_list.size();
127  }
128  //cout<<"GLOBALSAVES[0] : "
129  //cout<<"GLOBALSAVES[1] : "<<globalsaves[1]<<endl;
130  return 1;
131 }
132 
133 /*
134  ************************************************************
135  **** Login loop : waiting for account server to respond ***
136  ************************************************************
137  */
138 
139 vector< string >& NetClient::loginAcctLoop( string str_callsign, string str_passwd )
140 {
141  COUT<<"enter "<<"NetClient::loginAcctLoop"<<endl;
142 
143  this->error_message = string();
144 
145  std::string netbuf;
146  addSimpleChar( netbuf, ACCT_LOGIN_DATA );
147  //memset( buffer, 0, tmplen+1);
148  addSimpleString( netbuf, str_callsign );
149  addSimpleString( netbuf, str_passwd );
150 
151  COUT<<"Buffering to send with LOGIN_DATA for "<<str_callsign<<endl;
152  //PacketMem m( netbuf.getData(), netbuf.getDataLength(), PacketMem::LeaveOwnership );
153  //m.dump( cerr, 3 );
154  acct_sock->sendstr( netbuf );
155  /*
156  * packet2.send( LOGIN_DATA, 0,
157  * netbuf.getData(), netbuf.getDataLength(),
158  * SENDRELIABLE, NULL, this->acct_sock,
159  * __FILE__, PSEUDO__LINE__(378) );
160  */
161  //Now the loop
162  int timeout = 0, recv = 0;
163  //int ret=0;
164 
165  Packet packet;
166 
167  double initial = queryTime();
168  double newtime = 0;
169  double elapsed = 0;
170  string login_tostr = vs_config->getVariable( "network", "logintimeout", "20" );
171  int login_to = atoi( login_tostr.c_str() );
172  while (!timeout && !recv) {
173  //If we have no response in "login_to" seconds -> fails
174  newtime = queryTime();
175  elapsed = newtime-initial;
176  //COUT<<elapsed<<" seconds since login request"<<endl;
177  if (elapsed > login_to) {
178  //lastsave.push_back( "");
179  COUT<<"!!! NETWORK ERROR : Connection to account server timed out !!!"<<endl;
180  timeout = 1;
181  break;
182  }
183  recv = checkAcctMsg();
184  _sock_set.waste_time( 0, 40000 );
185  }
186  COUT<<"End of loginAcct loop"<<endl;
187  //globalsaves should be empty otherwise we filled it with an empty string followed by the error message
188  if (lastsave.empty() || lastsave[0] != "") {
189  //this->callsign = str_callsign;
190  //savefiles = globalsaves;
191  COUT<<"Trying to connect to game server..."<<endl
192  <<"\tIP="<<_serverip<<":"<<_serverport<<endl;
193  }
194  return lastsave;
195 }
196 
198 {
199  NetBuffer netbuf( p1.getData(), p1.getDataLength() );
200  ship_select_list.clear();
201  unsigned short numShips = netbuf.getShort();
202  ship_select_list.reserve( numShips );
203  for (int i = 0; i < numShips; i++)
204  ship_select_list.push_back( netbuf.getString() );
205 }
206 
208 {
209  using namespace VSFileSystem;
210  NetBuffer netbuf( p1.getData(), p1.getDataLength() );
211 
212  Packet pckt;
213  this->serial = p1.getSerial();
214  COUT<<">>> LOGIN ACCEPTED =( serial #"<<serial<<" )= --------------------------------------"<<endl;
215  {
216  char msg[100];
217  sprintf( msg, "#cc66ffNETWORK: Login Accepted. Serial number is %d. Downloading system file...", serial );
218  bootstrap_draw( msg, NULL );
219  }
220  //Should receive player's data (savegame) from server if there is a save
221  localSerials.push_back( serial );
222 
223  string datestr = netbuf.getString();
224  _Universe->current_stardate.InitTrek( datestr );
225  cerr<<"Stardate initialized"<<endl;
226  cerr<<"WE ARE ON STARDATE "<<datestr<<" - converted : "
228  lastsave.push_back( netbuf.getString() );
229  lastsave.push_back( netbuf.getString() );
230  unsigned char *digest = 0;
231  unsigned short digest_length;
232 
233  /*
234  * // Get universe file... not too useful.
235  * // But this is a good example of using VsnetDownload download manager.
236  *
237  * // Get the galaxy file from buffer with relative path to datadir !
238  * digest_length = netbuf.getShort();
239  * string univfile = netbuf.getString();
240  * if (digest_length) {
241  * digest = netbuf.getBuffer( digest_length );
242  * #ifdef CRYPTO
243  * cerr<<"Initial system = "<<VSFileSystem::datadir+univfile<<" - File Hash = "<<digest<<endl;
244  * // Compare to local hash and ask for the good file if we don't have it or bad version
245  * if( !FileUtil::HashCompare( univfile, digest, UniverseFile))
246  * {
247  * VsnetDownload::Client::NoteFile f( this->clt_tcp_sock, univfile, VSFileSystem::UniverseFile);
248  * _downloadManagerClient->addItem( &f);
249  * timeval timeout={10,0};
250  * while( !f.done())
251  * {
252  * if (recvMsg( NULL, &timeout )<=0) {
253  * //NETFIXME: What to do if the download times out?
254  * break;
255  * }
256  * }
257  * }
258  * #endif
259  * }
260  */
261 
262  //Get the initial system file...
263  string sysfile = netbuf.getString();
264  bool downloadsystem = true;
265  bool autogen;
266  string fullsys = VSFileSystem::GetCorrectStarSysPath( sysfile, autogen );
267  if ( fullsys.empty() ) fullsys = sysfile;
268  digest_length = netbuf.getShort();
269  COUT<<"Initial system = "<<fullsys;
270  if (digest_length) {
271  digest = netbuf.getBuffer( digest_length );
272 #ifdef CRYPTO
273  cerr<<" - File Hash = "<<digest;
274  if ( FileUtil::HashCompare( fullsys, digest, SystemFile ) )
275  downloadsystem = false;
276 #endif
277  }
278  //Set the zone number
279  this->zone = netbuf.getShort();
280  //Did the hash compare fail?
281  if (downloadsystem) {
282  cerr<<": Downloading system from server..."<<endl;
283  VsnetDownload::Client::NoteFile f( fullsys, *this->clt_tcp_sock, sysfile, VSFileSystem::SystemFile );
284  _downloadManagerClient->addItem( &f );
285  timeval timeout = {10, 0};
286  while ( !f.done() )
287  if (recvMsg( NULL, &timeout ) <= 0)
288  //NETFIXME: what to do if timeout elapses...
289  break;
290  }
291  cout<<endl;
292 }
293 
295 {
296  Packet packet2;
297  NetBuffer netbuf;
298  //No data.
299  packet2.send( CMD_RESPAWN, 0,
300  netbuf.getData(), netbuf.getDataLength(),
301  SENDRELIABLE, NULL, *this->clt_tcp_sock,
302  __FILE__, PSEUDO__LINE__( 165 ) );
303 }
304 void NetClient::textMessage( const std::string &data )
305 {
306  Packet packet2;
307  NetBuffer netbuf;
308  netbuf.addString( data );
309  //No data.
310  packet2.send( CMD_TXTMESSAGE, 0,
311  netbuf.getData(), netbuf.getDataLength(),
312  SENDRELIABLE, NULL, *this->clt_tcp_sock,
313  __FILE__, PSEUDO__LINE__( 165 ) );
314 }
315 
316 void NetClient::GetCurrentServerAddress( string &addr, unsigned short &port )
317 {
318  addr = this->_serverip;
319  port = this->_serverport;
320 }
321 
322 void NetClient::SetCurrentServerAddress( string addr, unsigned short port )
323 {
324  this->_serverip = addr;
325  this->_serverport = port;
326 }
327 
328 void NetClient::SetConfigServerAddress( string &addr, unsigned short &port )
329 {
330  bool use_acctserver = XMLSupport::parse_bool( vs_config->getVariable( "network", "use_account_server", "false" ) );
331  if (use_acctserver) {
332  this->_serverport = port = 0;
333  this->_serverip = addr = vs_config->getVariable( "network", "account_server_url",
334  "http://localhost/cgi-bin/accountserver.py" );
335  cout<<endl<<"Account Server URL : "<<addr<<endl<<endl;
336  return;
337  }
338  int port_tmp;
339  string srvport = vs_config->getVariable( "network", "server_port", "6777" );
340  port_tmp = atoi( srvport.c_str() );
341  if (port_tmp > 65535 || port_tmp < 0)
342  port_tmp = 0;
343  port = (unsigned short) port_tmp;
344 
345  addr = vs_config->getVariable( "network", "server_ip", "" );
346  this->_serverip = addr;
347  this->_serverport = port;
348  cout<<endl<<"Server IP : "<<addr<<" - port : "<<srvport<<endl<<endl;
349 }
350 
351 /*
352  ************************************************************
353  **** Initialize the client network to account server ***
354  ************************************************************
355  */
356 VsnetHTTPSocket* NetClient::init_acct( const std::string &addr )
357 {
358  COUT<<" enter "<<__PRETTY_FUNCTION__
359  <<" with "<<addr<<endl;
360 
361  _sock_set.start();
362 
363  cout<<"Initializing connection to account server..."<<endl;
364  acct_sock = new VsnetHTTPSocket( addr, _sock_set );
365  COUT<<"accountserver on socket "<<acct_sock<<" done."<<endl;
366 
367  return acct_sock;
368 }
369 
370 /*
371  ************************************************************
372  **** Initialize the client network ***
373  ************************************************************
374  */
375 
376 SOCKETALT NetClient::init( const char *addr, unsigned short port, std::string &error )
377 {
378  if ( clt_tcp_sock && clt_tcp_sock->valid() ) clt_tcp_sock->disconnect( "NC_init_tcp" );
379  if ( clt_udp_sock && clt_udp_sock->valid() ) NetUIUDP::disconnectSaveUDP( *clt_udp_sock );
380  lastsave.clear();
381  netversion = 0;
382  if (addr == NULL) {
383  addr = _serverip.c_str();
384  port = _serverport;
385  }
386  COUT<<" enter "<<__PRETTY_FUNCTION__
387  <<" with "<<addr<<":"<<port<<endl;
388 
389  _sock_set.start();
390 
391  string strnetatom;
392  strnetatom = vs_config->getVariable( "network", "network_atom", "" );
393  if (strnetatom == "")
394  NETWORK_ATOM = 0.2;
395  else
396  NETWORK_ATOM = (double) atof( strnetatom.c_str() );
397  *this->clt_tcp_sock = NetUITCP::createSocket( addr, port, _sock_set );
398  this->lossy_socket = this->clt_tcp_sock;
399  if ( !clt_tcp_sock->valid() )
400  return *this->clt_tcp_sock;
401  COUT<<"created TCP socket ("<<addr<<","<<port<<") -> "<<this->clt_tcp_sock<<endl;
402 
403  /*
404  * if( this->authenticate() == -1)
405  * {
406  * perror( "Error login in ");
407  * return -1;
408  * }
409  */
410  Packet join;
411  join.send( CMD_CONNECT, CLIENT_NETVERSION, "", 0, SENDRELIABLE, NULL,
412  *this->clt_tcp_sock, __FILE__, PSEUDO__LINE__( 407 ) );
413  this->enabled = 1;
414 
415  string login_tostr = vs_config->getVariable( "network", "connecttimeout", "10" );
416  timeval tv = {atoi( login_tostr.c_str() ), 0};
417  int timeout = 0;
418  Packet packet;
419  while (!timeout) {
420  int recvd = this->recvMsg( &packet, &tv );
421  if (recvd == 0) {
422  error = "Connection to game server timed out!";
423  timeout = 1;
424  } else if (recvd < 0) {
425  char str[127];
426  sprintf( str, "NETWORK ERROR in recieving socket (error number %d)!!!",
427 #ifdef _WIN32
428  WSAGetLastError()
429 #else
430  errno
431 #endif
432  );
433  error = str;
434  timeout = 1;
435  } else if (this->netversion) {
436  break;
437  }
438  }
439  if (!this->netversion) {
440  if ( error.empty() )
441  error = "Unable to receive a valid version from this server.";
442  timeout = 1;
443  }
444  if (timeout)
445  clt_tcp_sock->disconnect( "NCinit_timedout" );
446  return *this->clt_tcp_sock;
447 }
448 
449 /*
450  ************************************************************
451  **** Synchronize server time and client time ***
452  ************************************************************
453  **** This function creates the UDP socket and determines ***
454  **** whether to use the UDP or the TCP socket for lossy ***
455  **** packet data. ***
456  ************************************************************
457  */
458 
459 //NETFIXME: Correctly obtain ping time.
460 #include "vs_random.h" //For random ping time.
461 
463 {
464  int i = 0;
465  int timeout = 0;
466  int recv;
467  timeval tv = {1, 0}; //Timeout after 1 second, request send again.
468  double ping; //use deltaTime?
469  double pingavg = 0.;
470  double timeavg = 0.;
471  std::map< double, double >times; //sorted container.
472  double initialTime = queryTime();
473  static int NUM_TIMES = XMLSupport::parse_int( vs_config->getVariable( "network", "servertime_calibration", "10" ) );
474  static int UDP_TIMEOUT = XMLSupport::parse_int( vs_config->getVariable( "network", "udp_timeout", "1" ) );
475  static int clt_port_read = XMLSupport::parse_int( vs_config->getVariable( "network", "udp_listen_port", "6778" ) );
476  if (clt_port_read > 65535 || clt_port_read <= 0)
477  clt_port_read = 0;
478  static int clt_port_read_max = XMLSupport::parse_int( vs_config->getVariable( "network", "udp_listen_port_max", "6778" ) );
479  if (clt_port_read_max > 65535 || clt_port_read_max <= 0)
480  clt_port_read_max = clt_port_read;
481  unsigned short clt_port = (unsigned short) clt_port_read;
482  unsigned short clt_port_max = (unsigned short) clt_port_read_max;
483  if (clt_port_max < clt_port)
484  clt_port_max = clt_port;
485  static string nettransport = vs_config->getVariable( "network", "transport", "udp" );
486 
487  //std::string addr;
488  unsigned short port = this->_serverport;
489  //getConfigServerAddress(addr, port);
490  if ( !( udpsock != NULL && udpsock->setRemoteAddress( NetUIBase::lookupHost( this->_serverip.c_str(), port ) ) ) ) {
491  do
492  *this->clt_udp_sock = NetUIUDP::createSocket( this->_serverip.c_str(), port, clt_port, _sock_set );
493  while ( ( !this->clt_udp_sock->valid() ) && (clt_port++) );
494  } else {
495  this->clt_udp_sock = udpsock;
496  }
497  COUT<<"created UDP socket ("<<this->_serverip<<","<<port<<", listen on "<<clt_port<<") -> "<<this->clt_udp_sock<<endl;
498  if (nettransport == "udp") {
499  //NETFIXME: Keep trying ports until a connection is established.
500  COUT<<"Default lossy transport configured to UDP."<<endl;
501  this->lossy_socket = clt_udp_sock;
502  } else {
503  COUT<<"Default lossy transport configured to TCP (behind firewall)."<<endl;
504  this->lossy_socket = clt_tcp_sock;
505  clt_port = 0;
506  }
507  this->clt_tcp_sock->set_block();
508  this->clt_udp_sock->set_block();
509  //Wait for NUM_TIMES (10) successful tries, or 10 consecutive 1-second timeouts
510  //(we use UDP on the response (SENDANDFORGET) to improve timing accuracy).
511  while (i < NUM_TIMES && timeout < UDP_TIMEOUT) {
512  Packet packet;
513  NetBuffer outData;
514  outData.addShort( clt_port );
515  packet.send( CMD_SERVERTIME, 0,
516  outData.getData(), outData.getDataLength(), //No data.
517  SENDRELIABLE, NULL, *this->clt_tcp_sock,
518  __FILE__, PSEUDO__LINE__( 343 ) );
519  recv = this->recvMsg( &packet, &tv );
520  //If we have no response.
521  if (recv <= 0) {
522  COUT<<"synchronizeTime() Timed out"<<endl;
523  ++timeout;
524  if (timeout >= UDP_TIMEOUT) {
525  if (this->lossy_socket->isTcp() == false) {
526  if (clt_port < clt_port_max && !udpsock) {
527  NetUIUDP::disconnectSaveUDP( *this->clt_udp_sock );
528  *this->clt_udp_sock = NetUIUDP::createSocket( this->_serverip.c_str(), port, clt_port, _sock_set );
529  clt_port++;
530  COUT<<"Trying UDP port "<<clt_port<<"."<<endl;
531  } else {
532  //no UDP requests made it, fallback to TCP.
533  this->lossy_socket = this->clt_tcp_sock;
534  clt_port = 0;
535  COUT<<"Setting default lossy transport to TCP (UDP timeout)."<<endl;
536  }
537  timeout = 0;
538  }
539  }
540  } else if (packet.getCommand() == CMD_SERVERTIME) {
541  //NETFIXME: obtain actual ping time
542  //ping = getPingTime( &tv );
543  ping = exp( vsrandom.uniformInc( -10, 0 ) );
544  if (ping > 0 && ping < 1.) {
545  ++i;
546  NetBuffer data( packet.getData(), packet.getDataLength() );
547  double serverTime = data.getDouble();
548  double currentTime = queryTime();
549  serverTime += initialTime-currentTime;
550  times.insert( std::multimap< double, double >::value_type( ping, serverTime-ping ) );
551  timeout = 0;
552  } else {
553  ++timeout;
554  }
555  }
556  }
557  this->clt_tcp_sock->set_nonblock();
558  this->clt_udp_sock->set_nonblock();
559 //std::sort(times[0], times[i]);
560  if (i >= NUM_TIMES) {
561  int mid = i/2;
562  double median = 0.;
563  double tot = 0.;
564  int location = 0;
565  std::map< double, double >::const_iterator iter;
566  for (iter = times.begin(); iter != times.end(); ++iter) {
567  if (location == mid) {
568  median = iter->first;
569  if (i%2 == 1) {
570  ++iter;
571  median += iter->first;
572  }
573  break;
574  }
575  ++location;
576  }
577  if (i%2 == 1)
578  median /= 2;
579  for (iter = times.begin(); iter != times.end(); ++iter) {
580  double wdiff = exp( -10*(median-iter->first)*(median-iter->first) );
581  pingavg += wdiff*iter->first;
582  timeavg += wdiff*iter->second;
583  tot += wdiff;
584  }
585  pingavg /= tot;
586  timeavg /= tot;
587  } else {
588  COUT<<"Error in time synchronization: connection ended or timed out.";
589  }
590  this->deltatime = pingavg;
591  double newTime = timeavg+queryTime()-initialTime;
592  COUT<<"Setting time to: New time: "<<newTime<<endl;
593  setNewTime( newTime );
594  for (unsigned int cpnum = 0; cpnum < _Universe->numPlayers(); cpnum++)
595  //Seems like a bad idea... shouldn't this rely on SIMULATION_ATOM?
596  _Universe->AccessCockpit( cpnum )->TimeOfLastCollision = -200;
597  cur_time = newTime;
598 }
599 
600 /*
601  ************************************************************
602  **** Receive that start locations ***
603  ************************************************************
604  */
605 
606 //Receives possible start locations (first a short representing number of locations)
607 //Then for each number, a desc
608 
609 void NetClient::receiveLocations( const Packet* )
610 {
611  unsigned char cmd;
612 
613 #ifdef __DEBUG__
614  COUT<<"Nb start locations : "<<nblocs<<endl;
615 #endif
616  //Choose starting location here
617 
618  //Send the chosen location to the server
619  cmd = CMD_ADDCLIENT;
620 }
621 
622 /*
623  ************************************************************
624  **** Create a new character ***
625  ************************************************************
626  */
627 bool NetClient::selectShip( unsigned int ship )
628 {
629  if (lastsave.empty() || lastsave[0] == "") {
630  NetBuffer netbuf;
631  string shipname;
632  netbuf.addShort( (unsigned short) ship );
633  if ( ship < ship_select_list.size() )
634  shipname = ship_select_list[ship];
635  netbuf.addString( shipname );
636  Packet p;
637  p.send( CMD_CHOOSESHIP, 0, netbuf.getData(), netbuf.getDataLength(), SENDRELIABLE,
638  NULL, *clt_tcp_sock, __FILE__, PSEUDO__LINE__( 628 ) );
639  string err;
640  int ret = loginLoop( err );
641  if (ret != 1 || lastsave.size() < 2 || lastsave[0] == "") {
642  cout<<"Error in CHOOSEHIP: "<<err
643  <<"choice="<<ship<<"("<<shipname<<"), max="<<ret<<endl;
644  return false;
645  }
646  }
647  return true;
648 }
649 
650 void NetClient::createChar()
651 {}
652 
653 int NetClient::connectLoad( string username, string passwd, string &error )
654 {
655  localSerials.resize( 0 );
656  bootstrap_draw( "#cc66ffNETWORK: Initializing...", NULL );
657  cout<<"NETWORK: Initializing..."<<endl;
658  string srvipadr;
659  unsigned short port;
660  bool ret = false;
661  //Are we using the directly account server to identify us ?
662  GetCurrentServerAddress( srvipadr, port );
663  if (!port) {
664  //using account server.
665  string srvipadr = vs_config->getVariable( "network", "account_server_url", "http://localhost/cgi-bin/accountserver.py" );
666  bootstrap_draw( "#cc66ffNETWORK: Connecting to account server.", NULL );
667  cout<<"NETWORK: Connecting to account server."<<endl;
668  init_acct( srvipadr );
669  vector< string > &savetmp = loginAcctLoop( username, passwd );
670  //We don't expect a saved game...
671  if ( savetmp.size() >= 2 && savetmp[0].empty() ) {
672  //But this is the way the acctserver code indicates an error.
673  error = savetmp[1];
674  return 0;
675  }
676  bootstrap_draw( "#cc66ffNETWORK: Connecting to VegaServer.", NULL );
677  cout<<"NETWORK: Connecting to VegaServer."<<endl;
678  ret = init( NULL, 0, error ).valid();
679  } else {
680  //Or are we going through a game server to do so ?
681  bootstrap_draw( "#cc66ffNETWORK: Connecting to VegaServer.", NULL );
682  cout<<"NETWORK: Connecting to VegaServer."<<endl;
683  ret = init( srvipadr.c_str(), port, error ).valid();
684  }
685  if (ret == false) {
686  //If network initialization fails, exit
687  if ( error.empty() ) error = "Network connection error";
688  if ( !this->error_message.empty() )
689  error += "\n"+this->error_message;
690  cout<<"Error: "<<error<<endl;
691  return 0;
692  }
693  cout<<"Successfully connected!";
694  //sleep( 3);
695  cout<<"Waiting for player "<<username<<": login response..."<<endl;
696  bootstrap_draw( "#cc66ffNETWORK: Successful connection! Waiting to log in.", NULL );
697  int loggedin = loginAuth( username, passwd, error );
698  if ( !this->error_message.empty() ) {
699  cout<<"Warning: "<<this->error_message<<endl;
700  if ( !error.empty() )
701  error += "\n";
702  error += this->error_message;
703  }
704  return loggedin;
705 }
706 vector< string >* NetClient::loginSavedGame( int ship )
707 {
708  if ( !selectShip( ship ) )
709  return NULL;
710  /************* NETWORK PART ***************/
711 
712  return &lastsave;
713 }
714 
716 {
717  vector< string >savedships;
718  QVector pos;
719  //useless.
720  string mysystem;
721  string savefiles;
722  bool setplayerXloc = false;
723  float credits = 0.0;
724  vector< StarSystem* >ss;
725  vector< QVector > playerNloc;
726  vector< string >playersaveunit;
727  vector< vector< string > >vecstr;
728 
729  bootstrap_draw( "#cc66ffNETWORK: Checking for UDP connection.", NULL );
730  cout<<"NETWORK: Checking for UDP connection."<<endl;
731  synchronizeTime( NULL );
732  cout<<" logged in !"<<endl;
733 
734  bootstrap_draw( "#cc66ffNETWORK: Loading player ship.", NULL );
735  cout<<"NETWORK: Loading player ship."<<endl;
736  if (_Universe->numPlayers() == 0)
737  _Universe->createCockpit( callsign );
739  _Universe->AccessCockpit( 0 )->savegame->SetStarSystem( string() );
741  mysystem,
742  "",
743  pos,
744  setplayerXloc,
745  credits,
746  savedships,
747  0,
748  lastsave[0],
749  false );
750 
751  ss.push_back( _Universe->Init( mysystem, Vector( 0, 0, 0 ), string() ) );
752 
753  CopySavedShips( callsign, 0, savedships, true );
754  playersaveunit.push_back( savedships[0] );
755  if (setplayerXloc)
756  playerNloc.push_back( pos );
757  else
758  playerNloc.push_back( QVector( FLT_MAX, FLT_MAX, FLT_MAX ) );
759  vecstr.push_back( lastsave );
760  createObjects( playersaveunit, ss, playerNloc, vecstr );
761  bootstrap_draw( "#cc66ffNETWORK: Loading system.", NULL );
762  cout<<"NETWORK: Loading system."<<endl;
763  inGame();
764  //PacketLoop(CMD_ADDEDYOU); // Wait for the command before stopping.
765 }
766