void NetClient::textMessage( const std::string &data ) { Packet packet2; NetBuffer netbuf; netbuf.addString( data ); //No data. packet2.send( CMD_TXTMESSAGE, 0, netbuf.getData(), netbuf.getDataLength(), SENDRELIABLE, NULL, *this->clt_tcp_sock, __FILE__, PSEUDO__LINE__( 165 ) ); }
void Server::prespawn(char *cmdline, void *p, ...) { Client *client = reinterpret_cast<Client *>(p); if (client->m_spawned) { printf("prespawn not valid -- allready spawned\n"); return; } NetBuffer *msg = &client->m_msg; msg->write(m_signon); msg->write_byte(svc_signonnum); msg->write_byte(2); client->m_sendsignon = true; }
void Server::god(char *cmdline, void *p, ...) { Client *client = reinterpret_cast<Client *>(p); edict_t *ent = client->m_edict; NetBuffer *msg = &client->m_msg; ent->v.flags = (int)ent->v.flags ^ FL_GODMODE; msg->write_byte(svc_print); if (!((int)ent->v.flags & FL_GODMODE)) msg->write_string("godmode OFF\n"); else msg->write_string("godmode ON\n"); }
void Server::read_client_move(Client *client) { NetBuffer *msg = client->m_netconnection->m_receiveMessage; usercmd_t *move = &client->m_cmd; int i; vec3_t angle; int bits; // read ping time client->m_ping_times[client->m_num_pings%NUM_PING_TIMES] = m_time - msg->read_float(); client->m_num_pings++; // read current angles for (i = 0; i<3; i++) angle[i] = msg->read_angle(); VectorCopy(angle, client->m_edict->v.v_angle); // read movement move->forwardmove = msg->read_short(); move->sidemove = msg->read_short(); move->upmove = msg->read_short(); // read buttons bits = msg->read_byte(); client->m_edict->v.button0 = (bits & 1); client->m_edict->v.button2 = (bits & 2) >> 1; i = msg->read_byte(); if (i) client->m_edict->v.impulse = i; }
void NetChannel::Send(NetBuffer& buffer) { if (buffer.GetCurLength() > FRAGMENT_SIZE) { return SendFragmented(buffer); } static char msgBuffer[FRAGMENT_SIZE + 100]; *(uint32_t*)(msgBuffer) = m_outSequence; memcpy(&msgBuffer[4], buffer.GetBuffer(), buffer.GetCurLength()); m_netLibrary->SendData(m_targetAddress, msgBuffer, buffer.GetCurLength() + 4); m_outSequence++; }
void Server::fly(char *cmdline, void *p, ...) { Client *client = reinterpret_cast<Client *>(p); edict_t *ent = client->m_edict; NetBuffer *msg = &client->m_msg; msg->write_byte(svc_print); if (ent->v.movetype != MOVETYPE_FLY) { ent->v.movetype = MOVETYPE_FLY; msg->write_string("flymode ON\n"); } else { ent->v.movetype = MOVETYPE_WALK; msg->write_string("flymode OFF\n"); } }
/* send func 테스트 프로토콜 타입 test0: 문자열 test1: 소수점 4바이트 test2: 소수점 8바이트 test3: 정수 1바이트 test4: 정수 2바이트 test5: 정수 4바이트 test6: 정수 8바이트 */ bool ProtocolHandler::sfReqTest(string test0, float test1, double test2, uint8_t test3, uint16_t test4, uint32_t test5, uint64_t test6) { NetBuffer buffer; buffer.AddUInt32(PROTOCOLS::PPREQTEST); buffer.AddString(test0); buffer.AddFloat(test1); buffer.AddDouble(test2); buffer.AddUInt8(test3); buffer.AddUInt16(test4); buffer.AddUInt32(test5); buffer.AddUInt64(test6); return mpPeer->SendData(&buffer); }
void Server::noclip(char *cmdline, void *p, ...) { Client *client = reinterpret_cast<Client *>(p); edict_t *ent = client->m_edict; NetBuffer *msg = &client->m_msg; if (m_progs->m_global_struct->deathmatch) return; msg->write_byte(svc_print); if (ent->v.movetype != MOVETYPE_NOCLIP) { //noclip_anglehack = true; ent->v.movetype = MOVETYPE_NOCLIP; msg->write_string("noclip ON\n"); } else { ent->v.movetype = MOVETYPE_WALK; msg->write_string("noclip OFF\n"); } }
/* ************************************************************ **** Create a new character *** ************************************************************ */ bool NetClient::selectShip( unsigned int ship ) { if (lastsave.empty() || lastsave[0] == "") { NetBuffer netbuf; string shipname; netbuf.addShort( (unsigned short) ship ); if ( ship < ship_select_list.size() ) shipname = ship_select_list[ship]; netbuf.addString( shipname ); Packet p; p.send( CMD_CHOOSESHIP, 0, netbuf.getData(), netbuf.getDataLength(), SENDRELIABLE, NULL, *clt_tcp_sock, __FILE__, PSEUDO__LINE__( 628 ) ); string err; int ret = loginLoop( err ); if (ret != 1 || lastsave.size() < 2 || lastsave[0] == "") { cout<<"Error in CHOOSEHIP: "<<err <<"choice="<<ship<<"("<<shipname<<"), max="<<ret<<endl; return false; } } return true; }
void MacBase::handleTransmitInterrupt() { uint16_t i; ETH_DMADESCTypeDef *txbuf; NetBuffer *nb; // loop over the small number of tx buffers txbuf=_transmitDmaDescriptors.get(); for(i=0;i<_params.mac_transmitBufferCount;i++) { // if the CPU owns the descriptor and a buffer is present then it's finished // free the buffer and clear it out if((txbuf->Status & ETH_DMATxDesc_OWN)==0 && _transmitNetBuffers[i]!=nullptr) { // send a notification that a NetBuffer is being cleaned up. This can be used by // the receiver to synchronise frame send requests with the frame actually being // transmitted nb=_transmitNetBuffers[i]; this->NetworkNotificationEventSender.raiseEvent(DatalinkFrameSentEvent(*nb)); // if this is the last in a sequence of fragmented packets then there will be a referenced // netbuffer that is serving to hold the jumbo packet's memory in scope while the fragments // got tx'd. now that's done we're safe to delete it and we must also notify it upwards // because that's the buffer that anything waiting on will recognise. if(nb->getReference()) this->NetworkNotificationEventSender.raiseEvent(DatalinkFrameSentEvent(*(nb->getReference()))); // clean up the buffer delete _transmitNetBuffers[i]; _transmitNetBuffers[i]=nullptr; } } }
void UnitFactory::addAsteroidBuffer( NetBuffer &netbuf, const char *filename, int faction, Flightgroup *fg, int fg_snumber, float difficulty, ObjSerial netcreate ) { netbuf.addChar( ZoneMgr::AddAsteroid ); netbuf.addSerial( netcreate ); netbuf.addString( string( filename ) ); netbuf.addInt32( faction ); netbuf.addString( fg->name ); netbuf.addInt32( fg_snumber ); netbuf.addFloat( difficulty ); }
void UnitFactory::addNebulaBuffer( NetBuffer &netbuf, const char *unitfile, bool SubU, int faction, Flightgroup *fg, int fg_snumber, ObjSerial netcreate ) { netbuf.addChar( ZoneMgr::AddNebula ); netbuf.addSerial( netcreate ); netbuf.addString( string( unitfile ) ); netbuf.addChar( SubU ); netbuf.addInt32( faction ); netbuf.addString( fg->name ); netbuf.addInt32( fg_snumber ); }
void NetServer::sendLoginAccept( ClientPtr clt, Cockpit *cp ) { COUT<<"enter "<<__PRETTY_FUNCTION__<<endl; //Verify that client already has a character NetBuffer netbuf; Unit *un = cp->GetParent(); if (!un) { sendLoginError( clt ); return; } //Put the save parts in buffers in order to load them properly netbuf.Reset(); string datestr = _Universe->current_stardate.GetFullTrekDate(); netbuf.addString( datestr ); netbuf.addString( clt->savegame[0] ); netbuf.addString( clt->savegame[1] ); Packet packet2; //Create a cockpit for the player and parse its savegame ObjSerial cltserial = un->GetSerial(); COUT<<">>> SEND LOGIN ACCEPT =( serial #"<<cltserial<<" )= --------------------------------------"<<endl; COUT<<"SAVE="<<clt->savegame[0].length()<<" bytes - XML="<<clt->savegame[1].length()<<" bytes"<<endl; cerr<<"SENDING STARDATE : "<<datestr<<endl; //Add the initial star system filename + hash if crypto++ support too string sysname = cp->savegame->GetStarSystem(); string relsys = sysname+".system"; netbuf.addString( relsys ); //Generate the starsystem before addclient so that it already contains serials StarSystem *sts = zonemgr->addZone( sysname ); #ifdef CRYPTO unsigned char *digest = new unsigned char[FileUtil::Hash.DigestSize()]; string sysxml; if ( !( sysxml = zonemgr->getSystem( relsys ) ).empty() ) FileUtil::HashStringCompute( sysxml, digest ); else if ( !sysname.empty() ) FileUtil::HashFileCompute( relsys, digest, SystemFile ); netbuf.addShort( FileUtil::Hash.DigestSize() ); netbuf.addBuffer( digest, FileUtil::Hash.DigestSize() ); delete[] digest; #else netbuf.addShort( 0 ); #endif int zoneid = _Universe->StarSystemIndex( sts ); netbuf.addShort( zoneid ); //Add system string to packet... //Long, I know, but is there any other way to keep all the proper graphics-related data that the server discards? //netbuf.addString( zonemgr->getSystem(sysname) ); packet2.send( LOGIN_ACCEPT, cltserial, netbuf.getData(), netbuf.getDataLength(), SENDRELIABLE, &clt->cltadr, clt->tcp_sock, __FILE__, PSEUDO__LINE__( 241 ) ); //Now that we have a starsystem, we will want to make a mission. if (Mission::getNthPlayerMission( _Universe->whichPlayerStarship( un ), 0 ) == NULL) { if (active_missions.size() == 1) active_missions[0]->DirectorInitgame(); //Make a mission specially for this cockpit. unsigned int oldcp = _Universe->CurrentCockpit(); _Universe->SetActiveCockpit( cp ); _Universe->pushActiveStarSystem( _Universe->AccessCockpit()->activeStarSystem ); LoadMission( "", vs_config->getVariable( "server", "serverscript", "import server;my_obj=server.player()" ), false ); _Universe->popActiveStarSystem(); _Universe->SetActiveCockpit( oldcp ); } }
bool IpPacketFragmentFeature::createFragmentsFrom(NetBuffer *inputBuffer, const void *sourceData, uint16_t sourceDataSize, NetBuffer **outputBuffers, uint16_t firstOutputBuffer, bool lastFragmentIsHere, uint16_t& offset) { NetBuffer *nb; uint16_t fragmentSize,flags; const uint8_t *ptr; ptr=reinterpret_cast<const uint8_t *>(sourceData); while(sourceDataSize) { // calculate sizes fragmentSize=sourceDataSize<_mtu-IpPacketHeader::getNoOptionsHeaderSize() ? sourceDataSize : _mtu-IpPacketHeader::getNoOptionsHeaderSize(); // create a new netbuffer for the fragment nb=new NetBuffer(_linkHeaderSize+IpPacketHeader::getNoOptionsHeaderSize(), // needs IP and link layer headers 0, ptr, // fragment data starts here fragmentSize); // size of this fragment // more fragments flag if this is not the last in the run if(lastFragmentIsHere && fragmentSize==sourceDataSize) { // this is the last flags=0; nb->setReference(inputBuffer); } else flags=MORE_FRAGMENTS; // insert the IP fragment header IpPacketHeader *header=reinterpret_cast<IpPacketHeader *>(nb->moveWritePointerBack(IpPacketHeader::getNoOptionsHeaderSize())); // set up only the parts that are unique to the fragmenter header->ip_hdr_length=NetUtil::htons(IpPacketHeader::getNoOptionsHeaderSize()+fragmentSize); header->ip_hdr_identification=_identification; header->ip_hdr_flagsAndOffset=NetUtil::htons((offset/8) | flags); // store the netbuffer in the array outputBuffers[firstOutputBuffer++]=nb; // update pointers ptr+=fragmentSize; sourceDataSize-=fragmentSize; offset+=fragmentSize; } return true; }
void Server::spawn(char *cmdline, void *p, ...) { Client *client = reinterpret_cast<Client *>(p); if (client->m_spawned) { printf("Spawn not valid -- allready spawned\n"); return; } if (m_loadgame) { m_paused = false; } else { edict_t *ent = client->m_edict; memset(&ent->v, 0, m_progs->m_programs.entityfields * 4); ent->v.colormap = m_progs->NUM_FOR_EDICT(ent); ent->v.team = (client->m_colors & 15) + 1; ent->v.netname = client->m_name - m_progs->m_strings; // copy spawn parms out of the client_t for (int i = 0; i< NUM_SPAWN_PARMS; i++) (&m_progs->m_global_struct->parm1)[i] = client->m_spawn_parms[i]; // call the spawn function m_progs->m_global_struct->time = m_time; m_progs->m_global_struct->self = m_progs->edict_to_prog(ent); m_progs->program_execute(m_progs->m_global_struct->ClientConnect); if ((sys.seconds() - client->m_netconnection->m_connecttime) <= m_time) printf("%s entered the game\n", client->m_name); m_progs->program_execute(m_progs->m_global_struct->PutClientInServer); } NetBuffer *msg = &client->m_msg; msg->clear(); // send time of update msg->write_byte(svc_time); msg->write_float(m_time); for (int i = 0; i<m_maxclients; i++) { Client *client2 = &m_clients[i]; msg->write_byte(svc_updatename); msg->write_byte(i); msg->write_string(client2->m_name); msg->write_byte(svc_updatefrags); msg->write_byte(i); msg->write_short(client2->m_old_frags); msg->write_byte(svc_updatecolors); msg->write_byte(i); msg->write_byte(client2->m_colors); } // send all current light styles for (int i = 0; i<MAX_LIGHTSTYLES; i++) { msg->write_byte(svc_lightstyle); msg->write_byte((char)i); msg->write_string(m_progs->m_lightstyles[i]); } // // send some stats // msg->write_byte(svc_updatestat); msg->write_byte(STAT_TOTALSECRETS); msg->write_long((int)m_progs->m_global_struct->total_secrets); msg->write_byte(svc_updatestat); msg->write_byte(STAT_TOTALMONSTERS); msg->write_long((int)m_progs->m_global_struct->total_monsters); msg->write_byte(svc_updatestat); msg->write_byte(STAT_SECRETS); msg->write_long((int)m_progs->m_global_struct->found_secrets); msg->write_byte(svc_updatestat); msg->write_byte(STAT_MONSTERS); msg->write_long((int)m_progs->m_global_struct->killed_monsters); // // send a fixangle // Never send a roll angle, because savegames can catch the server // in a state where it is expecting the client to correct the angle // and it won't happen if the game was just loaded, so you wind up // with a permanent head tilt edict_t *ent = m_progs->EDICT_NUM(1 + (client - m_clients)); msg->write_byte(svc_setangle); for (int i = 0; i < 2; i++) { msg->write_angle(ent->v.angles[i]); } msg->write_angle(0); write_client_data_to_message(ent, msg); //SV_WriteClientdataToMessage(sv_player, &host_client->message); msg->write_byte(svc_signonnum); msg->write_byte(3); client->m_sendsignon = true; host.printf("pool : %d used: %d free: %d\n", pool.size(), pool.used(), pool.size() - pool.used()); host.printf("linear: %d used: %d free: %d\n", linear.size(), linear.used(), linear.size() - linear.used()); host.printf("LINEAR free: %dKB\n", (int)linearSpaceFree() / 1024); host.printf("REGULAR free: %dKB\n", (int)getMemFree() / 1024); host.printf("vbo_cb : %d\n", vbo_cb); host.printf("vbo_tx : %d\n", vbo_tx); host.printf("vbo_ls : %d\n", vbo_ls); host.printf("mdl_cb : %d\n", mdl_cb); host.printf("mdl_tx : %d\n", mdl_tx); }
void UnitFactory::addPlanetBuffer( NetBuffer &netbuf, QVector x, QVector y, float vely, const Vector &rotvel, float pos, float gravity, float radius, const char *filename, BLENDFUNC sr, BLENDFUNC ds, const vector< string > &dest, const QVector &orbitcent, Unit *parent, const GFXMaterial &ourmat, const std::vector< GFXLightLocal > &ligh, int faction, string fullname, bool inside_out, ObjSerial netcreate ) { netbuf.addChar( ZoneMgr::AddPlanet ); netbuf.addSerial( netcreate ); netbuf.addQVector( x ); netbuf.addQVector( y ); netbuf.addFloat( vely ); netbuf.addVector( Vector( rotvel ) ); netbuf.addFloat( pos ); netbuf.addFloat( gravity ); netbuf.addFloat( radius ); netbuf.addString( string( filename ) ); netbuf.addChar( sr ); netbuf.addChar( ds ); netbuf.addShort( dest.size() ); for (unsigned int i = 0; i < dest.size(); i++) netbuf.addString( dest[i] ); netbuf.addQVector( QVector( orbitcent ) ); netbuf.addSerial( parent->GetSerial() ); netbuf.addGFXMaterial( ourmat ); netbuf.addShort( ligh.size() ); for (unsigned int j = 0; j < ligh.size(); j++) netbuf.addGFXLightLocal( ligh[j] ); netbuf.addInt32( faction ); netbuf.addString( fullname ); netbuf.addChar( inside_out ); }
void UnitFactory::endBuffer( NetBuffer &netbuf ) { netbuf.addChar( ZoneMgr::End ); }
void UnitFactory::addMissileBuffer( NetBuffer &netbuf, const string &filename, const string &name, const string &fullname, int faction, const string &modifications, const ClientState &curr_state, const float damage, float phasedamage, float time, float radialeffect, float radmult, float detonation_radius, ObjSerial netcreate ) { netbuf.addChar( ZoneMgr::AddMissile ); netbuf.addSerial( netcreate ); netbuf.addString( filename ); netbuf.addString( name ); netbuf.addString( fullname ); netbuf.addInt32( faction ); netbuf.addString( modifications ); netbuf.addFloat( damage ); netbuf.addFloat( phasedamage ); netbuf.addFloat( time ); netbuf.addFloat( radialeffect ); netbuf.addFloat( radmult ); netbuf.addFloat( detonation_radius ); if (netbuf.version() <= 4951) netbuf.addTransformation( curr_state.getTransformation() ); else netbuf.addClientState( curr_state ); }
void UnitFactory::addUnitBuffer( NetBuffer &netbuf, const string &filename, const string &name, const string &fullname, bool SubUnit, int faction, std::string customizedUnit, const ClientState &curr_state, Flightgroup *flightgroup, int fg_subnumber, string *netxml, ObjSerial netcreate ) { netbuf.addChar( ZoneMgr::AddUnit ); assert( netcreate != 0 ); //crash if we are doing something stupid :) netbuf.addSerial( netcreate ); netbuf.addString( filename ); netbuf.addString( name ); netbuf.addString( fullname ); netbuf.addChar( SubUnit ); netbuf.addInt32( faction ); netbuf.addString( flightgroup != NULL ? flightgroup->name : std::string( "Object" ) ); netbuf.addString( customizedUnit ); netbuf.addInt32( fg_subnumber ); if (netbuf.version() <= 4951) netbuf.addTransformation( curr_state.getTransformation() ); else netbuf.addClientState( curr_state ); }
bool Server::read_client_message(Client *client) { NetBuffer *msg = client->m_netconnection->m_receiveMessage; char *s; int ret; do { if (msg->pos() == 0 || msg->read_pos() == msg->pos()) { break; } int r = msg->read_byte(); if (r == -1) { return false; } int len = msg->read_short(); /*int skip = */msg->read_byte(); int end = msg->read_pos() + len; do { if (len == 0 || !client->is_active()) { return false; } int cmd = msg->read_byte(); //check end of message if (cmd == -1) { break; } switch (cmd) { case -1: //goto nextmsg; // end of message default: printf("SV_ReadClientMessage: unknown command char\n"); return false; case clc_nop: printf("clc_nop\n"); break; case clc_stringcmd: s = msg->read_string(); ret = 0; if (strncasecmp(s, "status", 6) == 0) ret = 1; else if (strncasecmp(s, "god", 3) == 0) ret = 1; else if (strncasecmp(s, "notarget", 8) == 0) ret = 1; else if (strncasecmp(s, "fly", 3) == 0) ret = 1; else if (strncasecmp(s, "name", 4) == 0) ret = 1; else if (strncasecmp(s, "noclip", 6) == 0) ret = 1; else if (strncasecmp(s, "create", 6) == 0) ret = 1; else if (strncasecmp(s, "say", 3) == 0) ret = 1; else if (strncasecmp(s, "say_team", 8) == 0) ret = 1; else if (strncasecmp(s, "tell", 4) == 0) ret = 1; else if (strncasecmp(s, "color", 5) == 0) ret = 1; else if (strncasecmp(s, "kill", 4) == 0) ret = 1; else if (strncasecmp(s, "pause", 5) == 0) ret = 1; else if (strncasecmp(s, "spawn", 5) == 0) { ret = 1; } else if (strncasecmp(s, "begin", 5) == 0) { ret = 1; client->m_spawned = true; break; } else if (strncasecmp(s, "prespawn", 8) == 0) { ret = 1; } else if (strncasecmp(s, "kick", 4) == 0) ret = 1; else if (strncasecmp(s, "ping", 4) == 0) ret = 1; else if (strncasecmp(s, "give", 4) == 0) ret = 1; if (ret == 2) Cbuf_InsertText(s); else if (ret == 1) { m_cmds.call(s, client); Cmd_ExecuteString(s, src_client); } else printf("%s tried to %s\n", client->m_name, s); break; case clc_disconnect: printf("SV_ReadClientMessage: client disconnected\n"); return false; case clc_move: read_client_move(client); break; } } while (msg->read_pos() < end); //read alignment bytes while (msg->read_pos() & 0x3) { msg->read_byte(); } //break; } while (1); client->m_netconnection->clear(); return true; }
void NetClient::synchronizeTime( SOCKETALT *udpsock ) { int i = 0; int timeout = 0; int recv; timeval tv = {1, 0}; //Timeout after 1 second, request send again. double ping; //use deltaTime? double pingavg = 0.; double timeavg = 0.; std::map< double, double >times; //sorted container. double initialTime = queryTime(); static int NUM_TIMES = XMLSupport::parse_int( vs_config->getVariable( "network", "servertime_calibration", "10" ) ); static int UDP_TIMEOUT = XMLSupport::parse_int( vs_config->getVariable( "network", "udp_timeout", "1" ) ); static int clt_port_read = XMLSupport::parse_int( vs_config->getVariable( "network", "udp_listen_port", "6778" ) ); if (clt_port_read > 65535 || clt_port_read <= 0) clt_port_read = 0; static int clt_port_read_max = XMLSupport::parse_int( vs_config->getVariable( "network", "udp_listen_port_max", "6778" ) ); if (clt_port_read_max > 65535 || clt_port_read_max <= 0) clt_port_read_max = clt_port_read; unsigned short clt_port = (unsigned short) clt_port_read; unsigned short clt_port_max = (unsigned short) clt_port_read_max; if (clt_port_max < clt_port) clt_port_max = clt_port; static string nettransport = vs_config->getVariable( "network", "transport", "udp" ); //std::string addr; unsigned short port = this->_serverport; //getConfigServerAddress(addr, port); if ( !( udpsock != NULL && udpsock->setRemoteAddress( NetUIBase::lookupHost( this->_serverip.c_str(), port ) ) ) ) { do *this->clt_udp_sock = NetUIUDP::createSocket( this->_serverip.c_str(), port, clt_port, _sock_set ); while ( ( !this->clt_udp_sock->valid() ) && (clt_port++) ); } else { this->clt_udp_sock = udpsock; } COUT<<"created UDP socket ("<<this->_serverip<<","<<port<<", listen on "<<clt_port<<") -> "<<this->clt_udp_sock<<endl; if (nettransport == "udp") { //NETFIXME: Keep trying ports until a connection is established. COUT<<"Default lossy transport configured to UDP."<<endl; this->lossy_socket = clt_udp_sock; } else { COUT<<"Default lossy transport configured to TCP (behind firewall)."<<endl; this->lossy_socket = clt_tcp_sock; clt_port = 0; } this->clt_tcp_sock->set_block(); this->clt_udp_sock->set_block(); //Wait for NUM_TIMES (10) successful tries, or 10 consecutive 1-second timeouts //(we use UDP on the response (SENDANDFORGET) to improve timing accuracy). while (i < NUM_TIMES && timeout < UDP_TIMEOUT) { Packet packet; NetBuffer outData; outData.addShort( clt_port ); packet.send( CMD_SERVERTIME, 0, outData.getData(), outData.getDataLength(), //No data. SENDRELIABLE, NULL, *this->clt_tcp_sock, __FILE__, PSEUDO__LINE__( 343 ) ); recv = this->recvMsg( &packet, &tv ); //If we have no response. if (recv <= 0) { COUT<<"synchronizeTime() Timed out"<<endl; ++timeout; if (timeout >= UDP_TIMEOUT) { if (this->lossy_socket->isTcp() == false) { if (clt_port < clt_port_max && !udpsock) { NetUIUDP::disconnectSaveUDP( *this->clt_udp_sock ); *this->clt_udp_sock = NetUIUDP::createSocket( this->_serverip.c_str(), port, clt_port, _sock_set ); clt_port++; COUT<<"Trying UDP port "<<clt_port<<"."<<endl; } else { //no UDP requests made it, fallback to TCP. this->lossy_socket = this->clt_tcp_sock; clt_port = 0; COUT<<"Setting default lossy transport to TCP (UDP timeout)."<<endl; } timeout = 0; } } } else if (packet.getCommand() == CMD_SERVERTIME) { //NETFIXME: obtain actual ping time //ping = getPingTime( &tv ); ping = exp( vsrandom.uniformInc( -10, 0 ) ); if (ping > 0 && ping < 1.) { ++i; NetBuffer data( packet.getData(), packet.getDataLength() ); double serverTime = data.getDouble(); double currentTime = queryTime(); serverTime += initialTime-currentTime; times.insert( std::multimap< double, double >::value_type( ping, serverTime-ping ) ); timeout = 0; } else { ++timeout; } } } this->clt_tcp_sock->set_nonblock(); this->clt_udp_sock->set_nonblock(); //std::sort(times[0], times[i]); if (i >= NUM_TIMES) { int mid = i/2; double median = 0.; double tot = 0.; int location = 0; std::map< double, double >::const_iterator iter; for (iter = times.begin(); iter != times.end(); ++iter) { if (location == mid) { median = iter->first; if (i%2 == 1) { ++iter; median += iter->first; } break; } ++location; } if (i%2 == 1) median /= 2; for (iter = times.begin(); iter != times.end(); ++iter) { double wdiff = exp( -10*(median-iter->first)*(median-iter->first) ); pingavg += wdiff*iter->first; timeavg += wdiff*iter->second; tot += wdiff; } pingavg /= tot; timeavg /= tot; } else { COUT<<"Error in time synchronization: connection ended or timed out."; } this->deltatime = pingavg; double newTime = timeavg+queryTime()-initialTime; COUT<<"Setting time to: New time: "<<newTime<<endl; setNewTime( newTime ); for (unsigned int cpnum = 0; cpnum < _Universe->numPlayers(); cpnum++) //Seems like a bad idea... shouldn't this rely on SIMULATION_ATOM? _Universe->AccessCockpit( cpnum )->TimeOfLastCollision = -200; cur_time = newTime; }