コード例 #1
0
ファイル: multiplay.cpp プロジェクト: Timo6/trackeditor
float MULTIPLAY::GetLatency(int player)
{
	if (NumConnected() > player-1 && player >= 0)
	{
		return timeindex[0] - timeindex[player];
	}
	else
		return 0;
}
コード例 #2
0
ファイル: multiplay.cpp プロジェクト: Timo6/trackeditor
void MULTIPLAY::AddRecord(string newdofunction, float newval, int newstate)
{
	if (MP_DISABLEADDRECORD)
		return;
	
	//if (replay && num_packets < MAX_PACKETS)
	if (NumConnected() > 0 && GetFuncMem(0) != NULL)
	{
		//packet
		
		int funcidx = 0;
		int i;
		for (i = 0; i < fnums[0]; i++)
		{
			if (GetFuncMem(0)[i].func_name == newdofunction)
				funcidx = i;
		}
		
		//put the values into their functional slot.  this allows higher priority
		// commands to be considered over lower priority ones (as with the vamosworld
		// control processing code (effectively)
		if (newstate != 2)
		{
			GetFuncMem(0)[funcidx].lastupdateat = timeindex[0];
			GetFuncMem(0)[funcidx].newval = newval;
			if (newstate == 1)
				GetFuncMem(0)[funcidx].held = true;
			else
				GetFuncMem(0)[funcidx].held = false;
			GetFuncMem(0)[funcidx].active = true;
			//if (newdofunction == "gas")
				//cout << newdofunction << ", lastupdate set at " << timeindex << endl;
		}
	}
	else
	{
		if (NET_DEBUG)
		{
			cout << "net:  AddRecord:  wrong state for addrecord or funcmems not created" << endl;
		}
	}
}
コード例 #3
0
ファイル: multiplay.cpp プロジェクト: Timo6/trackeditor
bool MULTIPLAY::ExchangeWorldInfo()
{
	char tc[32767];
	sprintf(tc, "%c%c %s\n%i\n%s\n%i\n%i", (char) (replay.Get_FuncNetControl()), (char) CONTROL_WORLDINFO, state.GetCarName(0).c_str(), state.GetCarPaint(0), state.GetTrackName().c_str(), NumConnected(), NumConnected());
	
	//encode string length into the packet
	tc[2] = (char) ((Uint8) strlen(tc));
	
	//encode function memories, starting at strlen(tc)
	int tclen = strlen(tc);
	int opos = tclen;
	
	//tc[opos] = (char)((Uint8) fnums[0]);
	opos = AddToData(tc, &(fnums[0]), sizeof(int), opos);
	int f;
	for (f = 0; f < fnums[0]; f++)
	{
		char fout[FUNCTION_CHARS];
		strcpy(fout, GetFuncMem(0)[f].func_name.c_str());
		//fwrite(fout,1,FUNCTION_CHARS, rf);
		opos = AddToData(tc, fout, FUNCTION_CHARS, opos);
	}
	
	net.Send(tc, opos);
	
	int ret = net.RecvBlock(tc, 32767, GENERIC_TIMEOUT);
	if (ret > 0)
	{
		int pos = 0;
		int err = 0;
		
		if (tc[pos] == (char) (replay.Get_FuncNetControl()))
		{
			pos++;
			if (tc[pos] == (char) (CONTROL_WORLDINFO))
			{
				pos++;
				
				//decode string section length
				int slen = tc[2];
				pos++;
				
				string car;
				string carpaint;
				string track;
				string numplayers;
				string myplayernum;
				char sc[2];
				sc[1] = '\0';
				
				while (pos < slen && tc[pos] != '\n')
				{
					sc[0] = tc[pos];
					car.append(sc);
					
					pos++;
				}
				
				pos++;
				
				while (pos < slen && tc[pos] != '\n')
				{
					sc[0] = tc[pos];
					carpaint.append(sc);
					
					pos++;
				}
				
				pos++;
				
				while (pos < slen && tc[pos] != '\n')
				{
					sc[0] = tc[pos];
					track.append(sc);
					
					pos++;
				}
				
				pos++;
				
				while (pos < slen && tc[pos] != '\n')
				{
					sc[0] = tc[pos];
					numplayers.append(sc);
					
					pos++;
				}
				
				pos++;
				
				while (pos < slen && tc[pos] != '\n')
				{
					sc[0] = tc[pos];
					myplayernum.append(sc);
					
					pos++;
				}
				
				int icarpaint = atoi(carpaint.c_str());
				int inumplayers = atoi(numplayers.c_str());
				int imyplayernum = atoi(myplayernum.c_str());
				
				if (MP_DEBUG)
				{
					/*tc[ret] = '\0';
					cout << "raw worldinfo:  " << tc << endl;*/
					cout << "worldinfo size:  " << ret << endl;
					cout << "got worldinfo:  " << car << "," << icarpaint << "," << track << "," << inumplayers << "," << imyplayernum << endl;
				}
				
				//decode function memory
				//first clear it out
				int newpnum = NumConnected();
				if (funcmems[newpnum] != NULL)
				{
					delete [] funcmems[newpnum];
					funcmems[newpnum] = NULL;
				}
				pos = slen;
				pos = GetFromData(tc, &(fnums[newpnum]), sizeof(int), pos);
				funcmems[newpnum] = new FUNCTION_MEMORY [fnums[newpnum]];
				for (f = 0; f < fnums[newpnum]; f++)
				{
					char fin[FUNCTION_CHARS];
					pos = GetFromData(tc, fin, FUNCTION_CHARS, pos);
					GetFuncMem(newpnum)[f].func_name = fin;
					GetFuncMem(newpnum)[f].oldval = 0.0;
					GetFuncMem(newpnum)[f].held = false;
					GetFuncMem(newpnum)[f].active = false;
				}
				
				if (NET_DEBUG)
				{
					cout << "got functions:  " << fnums[newpnum];
					cout << " (" << fnums[0] << " local)" << endl;
					/*cout << "function list:  ";
					for (f = 0; f < fnums[newpnum]; f++)
					{
						cout << GetFuncMem(newpnum)[f].func_name << ",";
					}
					cout << endl;*/
				}
				
				if (!Server())
				{
					state.SetTrackName(track);
					state.SetCarName(1, car);
					state.SetCarPaint(1, icarpaint);
					remote_players = inumplayers;
					remote_playernum = imyplayernum;
					
					LoadWorld();
				}
				else
				{
					state.SetCarName(1, car);
					state.SetCarPaint(1, icarpaint);
					
					SelectCar(state.GetCarName(0), true);
					/*try
					{
						int numcars = NumConnected();
						Vamos_Body::Gl_Car* car = 0;
						car = new Vamos_Body::Gl_Car (Vamos_Geometry::Three_Vector (11.0, 0.0, 0.6));
						car->read ("data/", state.GetCarName(numcars));
						car->SetPaint(state.GetCarPaint(numcars));
						car->chassis ().translate (Vamos_Geometry::Three_Vector (10.0, 0.0, 
							-car->chassis ().lowest_contact_position () + 0.5));
						car->start_engine ();
						car->set_controller(2);
						world.add_car (car);
					}
					catch (Vamos_Geometry::XML_Exception& error)
					{
					  std::cerr << error.message () << std::endl;
					  std::exit (EXIT_FAILURE);
					}*/
				}
			}
			else
				err = 2;
		}
		else
			err = 1;
		
		if (err)
		{
			//retry?
		
			//nah, just disconnect.
			net.Disconnect();
			if (MP_DEBUG)
			{
				cout << "multiplay:  Update:  error parsing world info:  error " << err << endl;
			}
			return false;
		}
	}
	else
	{
		//retry?
		
		//nah, just disconnect.
		net.Disconnect();
		if (MP_DEBUG)
		{
			cout << "multiplay:  Update:  didn't receive world info:  error " << ret << endl;
		}
		
		return false;
	}
	
	return true;
}
コード例 #4
0
ファイル: multiplay.cpp プロジェクト: Timo6/trackeditor
void MULTIPLAY::Update(double inc)
{	
	if (MP_DBGDEEP)
		cout << "multiplay update" << endl;
	
	//create packet arrays if necessary
	int i;
	for (i = 0; i < NumConnected() + 1; i++)
	{
		if (packetarrays[i] == NULL)
		{
			packetarrays[i] = new REPLAY_PACKET [PACKET_ARRAY_SIZE];
		}
	}
	
	if (MP_DBGDEEP)
		cout << "packet mem allocated" << endl;
	
	bool oldc = Connected();
	net.Update();
	if (!oldc && Connected())
	{
		//wasn't connected before, connected now.
		if (Server())
			remote_players++;
		
		ExchangeWorldInfo();
		
		int i;
		for (i = 0; i < MAX_PLAYERS; i++)
		{
			timeindex[i] = 0.0;
			loadstates[i].time = 0.0;
			loadstatenow[i] = false;
			numpackets[i] = 0;
			
			//packetarraytime[i] = 0.0;
			
			nooptime[i] = 0;
			noopvalid[i] = false;
			tickthisframe[i] = false;
			nooptick[i] = false;
		}
		
		dbgnumstates = 0;
		dbgnumpackets = 0;
		
		mq1.Clear();
		mq1.AddMessage("A client successfully connected");
	}
	
	if (MP_DBGDEEP)
		cout << "net updated" << endl;
	
	//read incoming data
	/*if (Connected() && net.NumBufferedPackets() > 0)
	{
		int i;
		for (i = 0; i < net.GetMaxBuffers(); i++)
		{
			if (net.GetBuffer(i)->Valid())
				ProcessPacket(net.GetBuffer(i));
		}
	}*/
	if (Connected())
	{
		if (!MP_DISABLEGET)
		{		
			ReceiveState();
		
			if (MP_DBGDEEP)
				cout << "state receive" << endl;
			
			ReceivePacketArray();
			
			if (MP_DBGDEEP)
				cout << "packet array receive" << endl;
		}
		
		if (!MP_DISABLEFUNCUPDATE)
		{
			double tval = 0;
			string ticktype = "packet array";
			nooptick[1] = false;
			if (PacketArrayValid(1))
				tval = GetPacketArrayTime(1);
			if (noopvalid[1] && nooptime[1] > tval)
			{
				tval = nooptime[1];
				ticktype = "noop";
				nooptick[1] = true;
			}
			if ((noopvalid[1] || PacketArrayValid(1)) && timeindex[1] < tval + PACKET_ARRAY_FREQUENCY - FrameTime()/2.0)
			{
				tickthisframe[1] = true;
				
				/*int nextpacket = curpackets[1];
				if (nextpacket >= numpackets[1])
					nextpacket = numpackets[1] - 1;
				if (ticktype == "packet array")
					cout << "ticking " << ticktype << ": " << GetFuncMem(1)[GetPacketArray(1)[nextpacket].chardata[CHAR_FUNCNUM]].func_name << " " << curpackets[1] << "/" << numpackets[1] << " packets for " << tval << " at " << timeindex[1] << endl;
				else
					cout << "ticking " << ticktype << " for " << tval << " at " << timeindex[1] << endl;*/
				
				timeindex[1] += inc;
				
				//process packet data into the function memory (which is then given to DoOp by vamosworld)
				//if (PacketArrayValid(1))// && !(ticktype == "noop"))
				int i;
				for (i = 0; i < fnums[1]; i++)
				{
					if (!GetFuncMem(1)[i].held && GetFuncMem(1)[i].active)
						GetFuncMem(1)[i].active = false;
				}
				
				UpdateFuncmem(1);
			}
			else
			{
				tickthisframe[1] = false;
				//cout << "not ticking at " << timeindex[1] << endl;
			}
		}
		
		if (MP_DBGDEEP)
			cout << "ticked" << endl;
		
		//check to see if we need to increment		
		/*for (i = 0; i < NumConnected(); i++)
		{
			if (loadstatevalid[i+1] && timeindex[i+1] < loadstates[i+1].time + STATE_FREQUENCY + FrameTime()/2.0)
			{
				timeindex[i+1] += inc;
			}
		}*/
		//if (packetarrayvalid[1] && timeindex[1] < loadstates[1].time + STATE_FREQUENCY - FrameTime()/2.0)
	}

	//cout << "Latency: " << GetLatency(1) << " (" << timeindex[0] << "-" << timeindex[1] << ")" << endl;
	
	//disconnect if the latency is super high
	if (GetLatency(1) > CLIENT_DISCONNECT_TIMEOUT)
	{
		Disconnect();
	}
	
	//update statistics
	UpdateStats();
	
	if (MP_DBGDEEP)
			cout << "multiplay update done" << endl;
}
コード例 #5
0
ファイル: net_gui.c プロジェクト: kevans91/strife-ve
//
// haleyjd 20141022: [SVE] Alternate waiting on Steam clients
//
void NET_WaitForSteamLaunch(void)
{
    boolean isServer = (net_SteamNodeType == NET_STEAM_SERVER);
    const char *strConn = "Connecting Netgame";
    char numConn[64];
    char pressStr[64];
    char pressStr2[64];
    int strConnWidth, pressStrWidth, pressStrX, numConnWidth;
    const char *keyActivateName = GetNameForKey(key_menu_activate);
    const char *keyForwardName  = GetNameForKey(key_menu_forward);

    if(!keyActivateName)
        keyActivateName = "key_menu_activate";
    if(!keyForwardName)
        keyForwardName  = "key_menu_forward";

    M_snprintf(pressStr, sizeof(pressStr), "(Press %s to cancel%c",
               keyActivateName, isServer ? ',' : ')');
    if(isServer)
    {
        M_snprintf(pressStr2, sizeof(pressStr2), "%s to start now)",
                   keyForwardName);
    }
    strConnWidth  = V_BigFontStringWidth(strConn);
    pressStrWidth = M_StringWidth(pressStr);
    pressStrX     = (SCREENWIDTH - pressStrWidth) / 2;

    expected_nodes = net_SteamNumNodes;

    while(net_waiting_for_launch)
    {
        event_t *ev;

        CheckAutoLaunch();

        I_StartTic();
        
        while((ev = D_PopEvent()))
        {
            switch(ev->type)
            {
            case ev_keydown:
                if(ev->data1 == key_menu_activate)
                    I_Quit();
                if(ev->data1 == key_menu_forward && isServer)
                    StartGame(NULL, NULL);
                break;
            default:
                break;
            }
        }

        if(use3drenderer)
            RB_ClearBuffer(GLCB_COLOR);

        M_snprintf(numConn, sizeof(numConn), "%d of %d nodes connected",
                   NumConnected(), net_SteamNumNodes);
        numConnWidth = M_StringWidth(numConn);

        V_DrawFilledBox(0, 0, SCREENWIDTH, SCREENHEIGHT, 0);
        V_WriteBigText(strConn, (SCREENWIDTH - strConnWidth)/2, 60);
        M_WriteText((SCREENWIDTH - numConnWidth)/2, 100, numConn);
        M_WriteText(pressStrX, 112, pressStr);
        if(isServer)
            M_WriteText(pressStrX+12, 124, pressStr2);

        NET_CL_Run();
        NET_SV_Run();

        if(!net_client_connected)
            I_Error("Lost connection to server");

        I_FinishUpdate();
        I_Sleep(100);        
    }
}