コード例 #1
0
static void onHostPlayerReady(tCheckBoxInfo* pInfo)
{
	tRmInfo* reInfo = LmRaceEngine().inData();
	char dname[256];

	int nCars = GfParmGetEltNb(reInfo->params, RM_SECT_DRIVERS);

	NetServerMutexData *pSData = NetGetServer()->LockServerData();
	for (int i=1; i <= nCars; i++) {
		sprintf(dname, "%s/%d", RM_SECT_DRIVERS, i);

		GfLogInfo("Setting driver %d to %d\n", i, pInfo->bChecked);
		if(strcmp(NETWORKROBOT, GfParmGetStr(reInfo->params, dname, RM_ATTR_MODULE, "")) == 0) {
			// Human drive, check if local
			int index = GfParmGetNum(reInfo->params, dname, RM_ATTR_IDX, NULL, 1.0) - 1;

			GfLogInfo("Index %d\n", index);
			if (pSData->m_vecNetworkPlayers[index].client == false)
				NetGetServer()->OverrideDriverReady(i, pInfo->bChecked);
		} else {
			// Robot driver, all are local
			NetGetServer()->OverrideDriverReady(i, pInfo->bChecked);
		}

		bRobotsReady = pInfo->bChecked;
	}
	NetGetServer()->UnlockServerData();

	EnableMenuHostButtons(pInfo->bChecked);
	GfLogInfo("menu ready\n");
}
コード例 #2
0
static void
rmNetworkServerDisconnect(void * /* dummy */)
{
	GfLogInfo("Disconnecting all clients\n");
	if (NetGetServer())
		NetGetServer()->Disconnect();

	GfuiScreenActivate(RmRaceSelectMenuHandle);
}
コード例 #3
0
static void
ServerPrepareStartNetworkRace(void * /* dummy */)
{
	NetGetServer()->SetLocalDrivers();
	
	//Tell all clients to prepare to race and wait for response from all clients
	NetGetServer()->SendPrepareToRacePacket();

	//restore the idle function
	GfuiApp().eventLoop().setRecomputeCB(GfuiIdle);
	LmRaceEngine().startNewRace();
}
コード例 #4
0
static void
HostServerIdle(void)
{
	GfuiIdle();
	if (NetIsServer())
	{
		if (NetGetServer()->GetRaceInfoChanged())
		{
			CheckDriversCategory();
			//Send to clients all of the xml files we modified and client needs to reload
			NetGetServer()->SendFilePacket("drivers/networkhuman/networkhuman.xml");
			NetGetServer()->SendFilePacket("config/raceman/networkrace.xml");
			NetGetServer()->SendRaceSetupPacket();
			NetGetServer()->SendDriversReadyPacket();
			NetGetServer()->SetRaceInfoChanged(false);
		}
		else
		{
			if (NetGetServer()->GetRefreshDisplay())
			{
				UpdateNetworkPlayers();
			}

		}

		GfuiApp().eventLoop().postRedisplay();
	}
	
    /* Let CPU take breath (and fans stay at low and quiet speed) */
    GfSleep(0.001);
}
コード例 #5
0
static void
OnActivateNetworkHost(void *)
{
	tRmInfo* reInfo = LmRaceEngine().inData();

	// Set everyone to the 'not-ready' state
	bRobotsReady = 0;
	NetMutexData *pNData = NetGetNetwork()->LockNetworkData();
	for (unsigned int i=0;i<pNData->m_vecReadyStatus.size();i++)
		pNData->m_vecReadyStatus[i] = false;
	NetGetNetwork()->UnlockNetworkData();

	NetGetServer()->SetRaceInfoChanged(true);

	reInfo->params = GfParmReadFileLocal("config/raceman/networkrace.xml",GFPARM_RMODE_REREAD);
	assert(reInfo->params);
	reInfo->_reName = GfParmGetStr(reInfo->params, RM_SECT_HEADER, RM_ATTR_NAME, "");
	GfuiApp().eventLoop().setRecomputeCB(HostServerIdle);	

	NetGetServer()->SetRefreshDisplay(true);
}
コード例 #6
0
ファイル: racenetwork.cpp プロジェクト: 702nADOS/speed-dreams
int
ReNetworkWaitReady()
{
	// No wait if not an online race.
	if (!NetGetNetwork())
		return RM_SYNC | RM_NEXT_STEP;

	// If network race, wait for other players and start when the server tells to
	bool bWaitFinished = false;
	if (NetGetClient())
	{
		NetGetClient()->SendReadyToStartPacket();
		ReInfo->s->currentTime = NetGetClient()->WaitForRaceStart();
		GfLogInfo("Client beginning race in %lf seconds!\n", - ReInfo->s->currentTime);
		bWaitFinished = true;
	}
	
	else if (NetGetServer())
	{
		if (NetGetServer()->ClientsReadyToRace())
		{
			ReInfo->s->currentTime = NetGetServer()->WaitForRaceStart();
			GfLogInfo("Server beginning race in %lf seconds!\n", - ReInfo->s->currentTime);
			bWaitFinished = true;
		}
	}

	if (bWaitFinished)
	{
		ReSituation::self().setRaceMessage("", -1/*always*/, /*big=*/true);
		return RM_SYNC | RM_NEXT_STEP;
	}
	else
	{
		ReSituation::self().setRaceMessage("Waiting for online players",
										   -1/*always*/, /*big=*/true);
		return RM_ASYNC;
	}
}
コード例 #7
0
static void
CheckDriversCategory()
{
	bool bDriversChange = false;
	std::string strCarCat;
	bool bCollisions;
	NetGetNetwork()->GetHostSettings(strCarCat,bCollisions);
	if (strCarCat =="All")
		return;

	const std::vector<std::string> vecCars =
		GfCars::self()->getCarIdsInCategory(strCarCat);

	//Make sure all cars are in the correct category or force change of car
	unsigned int count = 0;
	NetServerMutexData *pSData = NetGetServer()->LockServerData();

	count = pSData->m_vecNetworkPlayers.size();
	
	for (unsigned int i=0;i<count;i++)
	{
		const GfCar* pCar = GfCars::self()->getCar(pSData->m_vecNetworkPlayers[i].car);
		if (pCar->getCategoryId() != strCarCat)
		{
			//Pick first car in categroy
			//strncpy(pSData->m_vecNetworkPlayers[i].car,vecCars[0].c_str(),64);
			bDriversChange = true;
			NetGetServer()->OverrideDriverReady(pSData->m_vecNetworkPlayers[i].idx,false);
		}
	}

	if(bDriversChange)
	{
		NetGetServer()->CreateNetworkRobotFile();
	}
	
	//NetGetServer()->UnlockDrivers();
	NetGetServer()->UnlockServerData();
}
コード例 #8
0
ファイル: racecars.cpp プロジェクト: 702nADOS/speed-dreams
void
ReCarsManageCar(tCarElt *car, bool& bestLapChanged)
{
	char msg[64];
	int i;
	int xx;
	tTrackSeg *sseg;
	tdble wseg;
	static const float ctrlMsgColor[] = {0.0, 0.0, 1.0, 1.0};
	tSituation *s = ReInfo->s;
	
	tReCarInfo *info = &(ReInfo->_reCarInfo[car->index]);

	// Update top speeds.
	if (car->_speed_x > car->_topSpeed)
		car->_topSpeed = car->_speed_x;

	// (practice and qualification only).
	if (car->_speed_x > info->topSpd)
		info->topSpd = car->_speed_x;
	if (car->_speed_x < info->botSpd)
		info->botSpd = car->_speed_x;
	
	// Pitstop management.
	if (car->_pit) {

		// If the driver can ask for a pit, update control messages whether slot occupied or not.
		if (car->ctrl.raceCmd & RM_CMD_PIT_ASKED) {
			// Pit already occupied?
			if (car->_pit->pitCarIndex == TR_PIT_STATE_FREE)
				snprintf(car->ctrl.msg[2], RM_CMD_MAX_MSG_SIZE, "Can Pit");
			else
				snprintf(car->ctrl.msg[2], RM_CMD_MAX_MSG_SIZE, "Pit Occupied");
			car->ctrl.msg[2][RM_CMD_MAX_MSG_SIZE-1] = 0; // Some snprintf implementations fail to do so.
			memcpy(car->ctrl.msgColor, ctrlMsgColor, sizeof(car->ctrl.msgColor));
		}

		// If pitting, check if pitting delay over, and end up with pitting process if so.
		if (car->_state & RM_CAR_STATE_PIT) {
			car->ctrl.raceCmd &= ~RM_CMD_PIT_ASKED; // clear the flag.
			// Note: Due to asynchronous behaviour of the main updater and the situation updater,
			//       we have to wait for car->_scheduledEventTime being set to smthg > 0.
			if (car->_scheduledEventTime > 0.0) {
				if (car->_scheduledEventTime < s->currentTime) {
					car->_state &= ~RM_CAR_STATE_PIT;
					car->_pit->pitCarIndex = TR_PIT_STATE_FREE;
					snprintf(msg, sizeof(msg), "%s pit stop %.1f s", car->_name, info->totalPitTime);
					msg[sizeof(msg)-1] = 0; // Some snprintf implementations fail to do so.
					ReSituation::self().setRaceMessage(msg, 5);
					GfLogInfo("%s exiting pit (%.1f s elapsed).\n", car->_name, info->totalPitTime);
				} else {
					snprintf(car->ctrl.msg[2], RM_CMD_MAX_MSG_SIZE, "In pits %.1f s",
							s->currentTime - info->startPitTime);
					car->ctrl.msg[2][RM_CMD_MAX_MSG_SIZE-1] = 0; // Some snprintf implementations fail to do so.
				}
			}
			
		// If the driver asks for a pit, check if the car is in the right conditions
		// (position, speed, ...) and start up pitting process if so.
		} else if ((car->ctrl.raceCmd & RM_CMD_PIT_ASKED) &&
				   car->_pit->pitCarIndex == TR_PIT_STATE_FREE &&	
				   (s->_maxDammage == 0 || car->_dammage <= s->_maxDammage)) {
			snprintf(car->ctrl.msg[2], RM_CMD_MAX_MSG_SIZE, "Pit request");
			car->ctrl.msg[2][RM_CMD_MAX_MSG_SIZE-1] = 0; // Some snprintf implementations fail to do so.
 
			tdble lgFromStart = car->_trkPos.seg->lgfromstart;
			
			switch (car->_trkPos.seg->type) {
				case TR_STR:
					lgFromStart += car->_trkPos.toStart;
					break;
				default:
					lgFromStart += car->_trkPos.toStart * car->_trkPos.seg->radius;
					break;
			}
		
			if ((lgFromStart > car->_pit->lmin) && (lgFromStart < car->_pit->lmax)) {
				int side;
				tdble toBorder;
				if (ReInfo->track->pits.side == TR_RGT) {
					side = TR_SIDE_RGT;
					toBorder = car->_trkPos.toRight;
				} else {
					side = TR_SIDE_LFT;
					toBorder = car->_trkPos.toLeft;
				}
				
				sseg = car->_trkPos.seg->side[side];
				wseg = RtTrackGetWidth(sseg, car->_trkPos.toStart);
				if (sseg->side[side]) {
					sseg = sseg->side[side];
					wseg += RtTrackGetWidth(sseg, car->_trkPos.toStart);
				}
				if (((toBorder + wseg) < (ReInfo->track->pits.width - car->_dimension_y / 2.0)) &&
					(fabs(car->_speed_x) < 1.0) && (fabs(car->_speed_y) < 1.0))
				{
					// All conditions fullfilled => enter pitting process
					car->_state |= RM_CAR_STATE_PIT;
					car->_scheduledEventTime = 0.0; // Pit will really start when set to smthg > 0.
					car->_nbPitStops++;
					for (i = 0; i < car->_pit->freeCarIndex; i++) {
						if (car->_pit->car[i] == car) {
							car->_pit->pitCarIndex = i;
							break;
						}
					}
					info->startPitTime = s->currentTime;
					snprintf(msg, sizeof(msg), "%s in pits", car->_name);
					msg[sizeof(msg)-1] = 0; // Some snprintf implementations fail to do so.
					ReSituation::self().setRaceMessage(msg, 5);
					GfLogInfo("%s entering in pit slot.\n", car->_name);
					if (car->robot->rbPitCmd(car->robot->index, car, s) == ROB_PIT_MENU) {
						// the pit cmd is modified by menu.
						reCarsSchedulePitMenu(car);
					} else {
						ReCarsUpdateCarPitTime(car);
					}
				}
				else
				{   // The cars speed or offset is out of accepted range
					// Show the user/developer/robot the reason of the issue
  				    tTeamDriver* TeamDriver = RtTeamDriverByCar(car);
					if (TeamDriver)
					{
					  TeamDriver->StillToGo  = 0.0;
					  TeamDriver->MoreOffset = 0.0;
					  TeamDriver->TooFastBy  = 0.0;
					}

					float Offset = (float) ((toBorder + wseg) - (ReInfo->track->pits.width - car->_dimension_y / 2.0));
  				    if (Offset >= 0.0)
					{
						// The car's position across the track is out of accepted range 
						snprintf(car->ctrl.msg[2], RM_CMD_MAX_MSG_SIZE, "Offset: %.02f",Offset);
						car->ctrl.msg[2][RM_CMD_MAX_MSG_SIZE-1] = 0; // Some snprintf implementations fail to do so.
						if (TeamDriver)
						  TeamDriver->MoreOffset = Offset;
					}

					float TooFastBy = MAX(fabs(car->_speed_x),fabs(car->_speed_y));
  				    if (TooFastBy >= 1.0)
					{
						// The car's speed is out of accepted range 
						snprintf(car->ctrl.msg[2], RM_CMD_MAX_MSG_SIZE, "Speed: %.02f",TooFastBy);
						car->ctrl.msg[2][RM_CMD_MAX_MSG_SIZE-1] = 0; // Some snprintf implementations fail to do so.
						if (TeamDriver)
						  TeamDriver->TooFastBy = TooFastBy;
					}
				}
			}
			else
			{	// The car's position along the track is out of accepted range
				// Show the user/developer/robot the reason of the issue
				tTeamDriver* TeamDriver = RtTeamDriverByCar(car);
				if (TeamDriver)
				{
				  TeamDriver->StillToGo  = 0.0;
				  TeamDriver->MoreOffset = 0.0;
				  TeamDriver->TooFastBy  = 0.0;
				}

				if (car->_pit->lmin > lgFromStart)
				{
				  float StillToGo = car->_pit->lmin - lgFromStart;
				  snprintf(car->ctrl.msg[2], RM_CMD_MAX_MSG_SIZE, "Still to go: %0.2f m" ,StillToGo);
				  car->ctrl.msg[2][RM_CMD_MAX_MSG_SIZE-1] = 0; // Some snprintf implementations fail to do so.
				  if (TeamDriver)
				    TeamDriver->StillToGo = StillToGo;
				}
				else if (car->_pit->lmax < lgFromStart)
				{
  				  float StillToGo = lgFromStart - car->_pit->lmax;
				  snprintf(car->ctrl.msg[2], RM_CMD_MAX_MSG_SIZE, "Overrun: %0.2f m" ,StillToGo);
				  car->ctrl.msg[2][RM_CMD_MAX_MSG_SIZE-1] = 0; // Some snprintf implementations fail to do so.
				  if (TeamDriver)
				    TeamDriver->StillToGo = -StillToGo;
				}
			}
		}
	}

	/* Check if it is in a new sector */
	while (true)
	{
		if (car->_currentSector < ReInfo->track->numberOfSectors - 1 && car->_laps > 0 && info->lapFlag == 0)
		{
			/* Must pass at least one sector before the finish */
			if (RtGetDistFromStart(car) > ReInfo->track->sectors[car->_currentSector])
			{
				/* It is in a new sector : update split time */
				car->_curSplitTime[car->_currentSector] = car->_curLapTime;
				++car->_currentSector;
				continue;
			}
		}
		break;
	}
	
	/* Start Line Crossing */
	if (info->prevTrkPos.seg != car->_trkPos.seg) {
		
		if ((info->prevTrkPos.seg->raceInfo & TR_LAST)
			&& (car->_trkPos.seg->raceInfo & TR_START)) {
			
			if (info->lapFlag == 0) {

				// If the car has not yet finished the race :
				if (!(car->_state & RM_CAR_STATE_FINISH)) {

					// 1 more lap completed
					// (Note: lap with index 0 finishes when the car crosses the start line the 1st time,
					//        and is thus considered a real lap, whereas it is not).
					car->_laps++;

					/*if (NetGetNetwork())
						NetGetNetwork()->SendLapStatusPacket(car);*/

					car->_remainingLaps--;
					if (car->_pos == 1 && s->currentTime < s->_totTime
						&& s->_raceType == RM_TYPE_RACE)
					{
						/* First car passed finish time before the time ends: increase the number of laps for everyone */
						for (xx = 0; xx < s->_ncars; ++xx)
							++ReInfo->s->cars[xx]->_remainingLaps;
						++s->_totLaps;
					}
					
					car->_currentSector = 0;
					if (car->_laps > 1) {
						car->_lastLapTime = s->currentTime - info->sTime;
						if (car->_bestLapTime != 0) {
							car->_deltaBestLapTime = car->_lastLapTime - car->_bestLapTime;
						}
						if ((car->_lastLapTime < car->_bestLapTime) || (car->_bestLapTime == 0)) {
							car->_bestLapTime = car->_lastLapTime;
							memcpy(car->_bestSplitTime, car->_curSplitTime, sizeof(double)*(ReInfo->track->numberOfSectors - 1) );
							if (s->_raceType != RM_TYPE_RACE && s->_ncars > 1)
							{
								/* Best lap time is made better : update times behind leader */
								bestLapChanged = true;
								car->_timeBehindLeader = car->_bestLapTime - s->cars[0]->_bestLapTime;
								if (car->_pos > 1)
								{
									car->_timeBehindPrev = car->_bestLapTime - s->cars[car->_pos - 1]->_bestLapTime;
								}
								else
								{
									/* New best time for the leader : update the differences */
									for (xx = 1; xx < s->_ncars; ++xx)
									{
										if (s->cars[xx]->_bestLapTime > 0.0f)
											s->cars[xx]->_timeBehindLeader = s->cars[xx]->_bestLapTime - car->_bestLapTime;
									}
								}
								if (car->_pos + 1 < s->_ncars && s->cars[car->_pos+1]->_bestLapTime > 0.0f)
									car->_timeBeforeNext = s->cars[car->_pos + 1]->_bestLapTime - car->_bestLapTime;
								else
									car->_timeBeforeNext = 0;
							}
						}
					}
					if (car->_laps > 0) {
						car->_curTime += s->currentTime - info->sTime;
						
						if (car->_pos != 1 && s->_raceType == RM_TYPE_RACE) {
							car->_timeBehindLeader = car->_curTime - s->cars[0]->_curTime;
							car->_lapsBehindLeader = s->cars[0]->_laps - car->_laps;
							car->_timeBehindPrev = car->_curTime - s->cars[car->_pos - 2]->_curTime;
							s->cars[car->_pos - 2]->_timeBeforeNext = car->_timeBehindPrev;
						} else if (s->_raceType == RM_TYPE_RACE) {
							car->_timeBehindLeader = 0;
							car->_lapsBehindLeader = 0;
							car->_timeBehindPrev = 0;
						}
						
						info->sTime = (tdble)s->currentTime;

						if (ReInfo->s->_raceType == RM_TYPE_PRACTICE && 
								(car->_laps > 1 || s->_totLaps == 0))
							ReSavePracticeLap(car);
					}

					if (ReInfo->_displayMode == RM_DISP_MODE_NONE)
					{
						switch(s->_raceType)
						{
							case RM_TYPE_PRACTICE:
								ReUpdatePracticeCurRes(car);
								break;
							case RM_TYPE_QUALIF:
								ReUpdateQualifCurRes(car);
								break;
							case RM_TYPE_RACE:
								ReUpdateRaceCurRes();
								break;
							default:
								break;
						}
					}
	
					info->topSpd = car->_speed_x;
					info->botSpd = car->_speed_x;
					if ((car->_remainingLaps < 0 && s->currentTime > s->_totTime) || (s->_raceState == RM_RACE_FINISHING)) {
						car->_state |= RM_CAR_STATE_FINISH;
						s->_raceState = RM_RACE_FINISHING;
						if (ReInfo->s->_raceType == RM_TYPE_RACE) {
							if (car->_pos == 1) {
								snprintf(msg, sizeof(msg), "Winner %s", car->_name);
								msg[sizeof(msg)-1] = 0; // Some snprintf implementations fail to do so.
								ReSituation::self().setRaceMessage(msg, 10, /*big=*/true);
								if (NetGetServer())
								{
									NetGetServer()->SetFinishTime(s->currentTime+FINISHDELAY);
								}
							} else {
								const char *numSuffix = "th";
								if (abs(12 - car->_pos) > 1) { /* leave suffix as 'th' for 11 to 13 */
									switch (car->_pos % 10) {
										case 1:
											numSuffix = "st";
											break;
										case 2:
											numSuffix = "nd";
											break;
										case 3:
											numSuffix = "rd";
											break;
										default:
											break;
									}
								}
								snprintf(msg, sizeof(msg), "%s finished %d%s", car->_name, car->_pos, numSuffix);
								msg[sizeof(msg)-1] = 0; // Some snprintf implementations fail to do so.
								ReSituation::self().setRaceMessage(msg, 5);
							}
						}
					}
					
					// Notify the UI when a lap is completed (by the leader)
					// and race results have been updated.
					if (car->_pos == 1)
						ReUI().onLapCompleted(car->_laps - 1);

				} else {
					// Prevent infinite looping of cars around track,
					// allowing one lap after finish for the first car, but no more
					for (i = 0; i < s->_ncars; i++) {
						s->cars[i]->_state |= RM_CAR_STATE_FINISH;
					}
					return;
				}

			} else {
				info->lapFlag--;
			}
		}
		if ((info->prevTrkPos.seg->raceInfo & TR_START)
			&& (car->_trkPos.seg->raceInfo & TR_LAST)) {
			/* going backward through the start line */
			info->lapFlag++;
		}
	} // Start Line Crossing


	// Apply race rules (penalties if enabled).
	reCarsApplyRaceRules(car);

	// Update misc car info.
	info->prevTrkPos = car->_trkPos;
	car->_curLapTime = s->currentTime - info->sTime;
	car->_distFromStartLine = car->_trkPos.seg->lgfromstart +
		(car->_trkPos.seg->type == TR_STR ? car->_trkPos.toStart : car->_trkPos.toStart * car->_trkPos.seg->radius);
	car->_distRaced = (car->_laps - 1) * ReInfo->track->length + car->_distFromStartLine;
}
コード例 #9
0
// Host on-line race menu.
void
RmNetworkHostMenu(void * /* dummy */)
{
	GfLogTrace("Entering Network Host menu.\n");
	
	if (!NetGetNetwork())
	{
		NetSetServer(true);
		NetSetClient(false);
		if (!NetGetServer()->Start(SPEEDDREAMSPORT))
		{
			NetSetServer(false);
			return;
		}
	}

	if (racemanMenuHdle)
		GfuiScreenRelease(racemanMenuHdle);

	racemanMenuHdle = GfuiScreenCreate(NULL,  NULL, (tfuiCallback)OnActivateNetworkHost, 
								   NULL, (tfuiCallback)NULL, 1);

	void *mparam = GfuiMenuLoad("networkhostmenu.xml");

	GfuiMenuCreateStaticControls(racemanMenuHdle, mparam);

	RmSetRacemanMenuHandle(racemanMenuHdle);

	NetworkRaceInfo();

	g_trackHd = GfuiMenuCreateLabelControl(racemanMenuHdle,mparam,"trackname");

	g_lapsHd = GfuiMenuCreateLabelControl(racemanMenuHdle,mparam,"lapcountname");
	g_catHd = GfuiMenuCreateLabelControl(racemanMenuHdle,mparam,"carcatname");
    
	g_OutlineId = GfuiMenuCreateStaticImageControl(racemanMenuHdle,mparam,"outlineimage");
	
	//Show players
	for (int i = 0; i < MAXNETWORKPLAYERS; i++) {
		char buf[1024];
		sprintf(buf,"ready%i",i);
		g_readystatus[i] = GfuiMenuCreateStaticImageControl(racemanMenuHdle,mparam,buf);
		GfuiVisibilitySet(racemanMenuHdle,g_readystatus[i],false);

		sprintf(buf,"driver%i",i);
		g_playerNames[i] = GfuiMenuCreateLabelControl(racemanMenuHdle,mparam,buf);
		GfuiLabelSetText(racemanMenuHdle,g_playerNames[i],"");

		sprintf(buf,"car%i",i);
		g_carNames[i] =  GfuiMenuCreateLabelControl(racemanMenuHdle,mparam,buf);
		GfuiLabelSetText(racemanMenuHdle,g_carNames[i],"");
	}

	g_ReadyCheckboxId =
		GfuiMenuCreateCheckboxControl(racemanMenuHdle, mparam, "playerreadycheckbox",
								NULL, onHostPlayerReady);

	g_HostSettingsButtonId =
		GfuiMenuCreateButtonControl(racemanMenuHdle, mparam, "networkhostsettings",
								racemanMenuHdle, rmNetworkHostSettingsMenu);
	GfuiEnable(racemanMenuHdle, g_HostSettingsButtonId, GFUI_DISABLE);

	g_RaceSetupId =
		GfuiMenuCreateButtonControl(racemanMenuHdle, mparam, "racesetup",
								racemanMenuHdle, RmConfigureRace);

	GfuiMenuCreateButtonControl(racemanMenuHdle, mparam, "start race",
								NULL, ServerPrepareStartNetworkRace);
	g_CancelButtonId = GfuiMenuCreateButtonControl(racemanMenuHdle, mparam, "cancel",
								NULL, rmNetworkServerDisconnect);

	GfParmReleaseHandle(mparam);
	
	GfuiMenuDefaultKeysAdd(racemanMenuHdle);
	GfuiAddKey(racemanMenuHdle, GFUIK_ESCAPE, "Back to previous menu",
								0, 0, rmNetworkServerDisconnect);

	UpdateNetworkPlayers();

	GfuiScreenActivate(racemanMenuHdle);
}
コード例 #10
0
static void
NetworkRaceInfo()
{
	NetDriver driver;
	int i = 1;

	NetGetServer()->SetRaceXMLFile("config/raceman/networkrace.xml");

	//Look up race info
	tRmInfo* reInfo = LmRaceEngine().inData();
	reInfo->params = GfParmReadFileLocal("config/raceman/networkrace.xml",GFPARM_RMODE_STD);

	int nCars = GfParmGetEltNb(reInfo->params, RM_SECT_DRIVERS);

	if (nCars == 0)
	{
		// Add all local humans if there are no drivers already specified
		while (GetHumanDriver(driver,i++)) {
			driver.client = false;
			driver.active = true;
			NetGetServer()->UpdateDriver(driver);
			NetGetServer()->SetDriverName(driver.name);
			GfLogInfo("NetworkRaceInfo: Adding default driver %s\n",driver.name);

		}

		// ensure changes writen to 'networkrace.xml'
		NetGetServer()->GenerateDriversForXML();

		// add drivers so they show up in race config dialogue
		GfDrivers::self()->reload();
		LmRaceEngine().race()->load(LmRaceEngine().race()->getManager(), true);
	} else {
		// Add the humans which are already in the race
		char	dname[256];

		for (i = 1; i < nCars+1; i++) {
			sprintf(dname, "%s/%d", RM_SECT_DRIVERS, i);

			if(strcmp(NETWORKROBOT, GfParmGetStr(reInfo->params, dname, RM_ATTR_MODULE, "")) == 0) {
				if (GetHumanDriver(driver,i) > -1) {
					driver.client = false;
					driver.active = true;
					NetGetServer()->UpdateDriver(driver);
					NetGetServer()->SetDriverName(driver.name);
					GfLogInfo("NetworkRaceInfo: Adding default driver %s\n",driver.name);
				}
			}
		}
	}

	// make sure nobody is 'ready to race'
	NetMutexData *pNData = NetGetNetwork()->LockNetworkData();
	for (unsigned int i=0; i < pNData->m_vecReadyStatus.size(); i++)
		pNData->m_vecReadyStatus[i] = false;
	NetGetNetwork()->UnlockNetworkData();
	bRobotsReady = false;

	// ensure the system knows about 'new' network drivers
	reInfo->params = GfParmReadFileLocal("config/raceman/networkrace.xml",GFPARM_RMODE_REREAD);
	reInfo->_reName = GfParmGetStr(reInfo->params, RM_SECT_HEADER, RM_ATTR_NAME, "");
}
コード例 #11
0
static void 
UpdateNetworkPlayers()
{
	GfDriver* newDriver;
	NetNetwork *pNetwork = NetGetNetwork();

	if (pNetwork->GetRefreshDisplay() == false)
		return;

	tRmInfo* reInfo = LmRaceEngine().inData();

	//Set current driver that camera will look at
	pNetwork->SetCurrentDriver();

	//reload xml file
	NetGetNetwork()->SetRaceXMLFile("config/raceman/networkrace.xml");
	reInfo->params = GfParmReadFileLocal("config/raceman/networkrace.xml",GFPARM_RMODE_REREAD);
	assert(reInfo->params);

	reInfo->_reName = GfParmGetStr(reInfo->params, RM_SECT_HEADER, RM_ATTR_NAME, "");
	assert(reInfo->_reName);

	// Scan each of the human drivers to see if they're active in this race
	if (NetIsServer()) {
		NetServerMutexData *pSData = NetGetServer()->LockServerData();
		assert(pSData);

		// Ensure that garage menu knows about driver
		for (unsigned int i=0; i < pSData->m_vecNetworkPlayers.size(); i++) {
			newDriver = GfDrivers::self()->getDriver(NETWORKROBOT, pSData->m_vecNetworkPlayers[i].idx);

			if (!newDriver) { 
				GfLogInfo("Driver %s not found, reloading drivers\n", pSData->m_vecNetworkPlayers[i].name);
				GfDrivers::self()->reload();
				LmRaceEngine().race()->load(LmRaceEngine().race()->getManager(), true);
				break;
			}
		}

		for (unsigned int i=0; i < pSData->m_vecNetworkPlayers.size(); i++) {
			int k = 1;
			char path2[256];

			pSData->m_vecNetworkPlayers[i].active = false;
			newDriver = GfDrivers::self()->getDriver(NETWORKROBOT, pSData->m_vecNetworkPlayers[i].idx);

			// Scan through drivers listed in 'networkrace.xml'
			while (pSData->m_vecNetworkPlayers[i].active == false) {
				sprintf(path2, "%s/%d", RM_SECT_DRIVERS, k++);
				if (GfParmExistsSection(reInfo->params, path2) == 0) {
					GfLogInfo("UpdateNetworkPlayers: Removing driver %s\n", pSData->m_vecNetworkPlayers[i].name);

					if (pSData->m_vecNetworkPlayers[i].client) {
						//need to tell/force client to disconnect
					}
					break;
				}

				if ((tdble)pSData->m_vecNetworkPlayers[i].idx == GfParmGetNum(reInfo->params, path2, RM_ATTR_IDX, NULL, 1.0) &&
						strcmp(NETWORKROBOT, GfParmGetStr(reInfo->params, path2, RM_ATTR_MODULE, "")) == 0) {
					pSData->m_vecNetworkPlayers[i].active = true;
				}
			}

			// add or remove from competitor list (for garage menu)
			GfDriver* activeDriver = LmRaceEngine().race()->getCompetitor(NETWORKROBOT, pSData->m_vecNetworkPlayers[i].idx);
			if (pSData->m_vecNetworkPlayers[i].active) {
				if (!activeDriver) LmRaceEngine().race()->appendCompetitor(newDriver);
			} else {
				if (activeDriver) LmRaceEngine().race()->removeCompetitor(newDriver);
			}
		}
		NetGetServer()->UnlockServerData();
	} else {
#if 1
		// Client XML files already written to disk - this works but is not the best solution....
		GfDrivers::self()->reload();
		LmRaceEngine().race()->load(LmRaceEngine().race()->getManager(), true);
#endif
	}

	//Update track info
	std::string strTrackPath = GfParmGetStr(reInfo->params, "Tracks/1", RM_ATTR_NAME, "");
	std::string strCategory = GfParmGetStr(reInfo->params, "Tracks/1", RM_ATTR_CATEGORY, "");

	std::string strTrackName = GetTrackName(strCategory.c_str(),strTrackPath.c_str());

	sprintf(buf, "%s", strTrackName.c_str());
	GfuiLabelSetText(racemanMenuHdle,g_trackHd,buf);

	//Store current track - client needs this
	GfTrack* PCurTrack = GfTracks::self()->getTrackWithName(buf);
	LmRaceEngine().race()->getManager()->setEventTrack(0, PCurTrack);
	
	int laps = (int)GfParmGetNum(reInfo->params, reInfo->_reName,"laps", "", 1);
	sprintf(buf, "%i", laps);
	GfuiLabelSetText(racemanMenuHdle,g_lapsHd,buf);

	GfuiScreenAddBgImg(racemanMenuHdle,
					   GetTrackPreviewFileName(strCategory.c_str(),strTrackPath.c_str()).c_str());
	GfuiStaticImageSet(racemanMenuHdle, g_OutlineId,
					   GetTrackOutlineFileName(strCategory.c_str(),strTrackPath.c_str()).c_str());

	// Update category info
	std::string strCarCat;
	bool bCollisions;
	NetGetNetwork()->GetHostSettings(strCarCat,bCollisions);
	GfuiLabelSetText(racemanMenuHdle,g_catHd,strCarCat.c_str());

	//fill in player data
	int nCars = GfParmGetEltNb(reInfo->params, RM_SECT_DRIVERS);

	char	dname[256];
	char    robpath[256];

	float *pColor = &green[0];

	bool bEveryoneReadyToRace = true;
	
	for (int i = 1; i < nCars+1; i++) 
	{
		sprintf(dname, "%s/%d", RM_SECT_DRIVERS, i);

		const char* robot = GfParmGetStr(reInfo->params, dname, RM_ATTR_MODULE, "");

		//lookup playerName and car name
		sprintf(robpath,"drivers/%s/%s.xml",robot,robot);
		void *pMod = GfParmReadFileLocal(robpath,GFPARM_RMODE_REREAD);

		if (pMod == NULL)
		{
			//try again in other path
			sprintf(robpath,"drivers/%s/%s.xml",robot,robot);
			pMod = GfParmReadFile(robpath,GFPARM_RMODE_REREAD);
			if (pMod == NULL)
				continue;
		}

		assert(pMod);

		char ppname[256];
		int idx = GfParmGetNum(reInfo->params, dname, RM_ATTR_IDX, "",0);
		sprintf(ppname,"Robots/index/%d",idx);
		const char* name = GfParmGetStr(pMod, ppname, RM_ATTR_NAME, "");

		const char* car = GfParmGetStr(pMod, ppname, "car name", "");
		std::string strRealCar = GfCars::self()->getCar(car)->getName();

		// WAIT : pNData->m_vecReadyStatus[i-1] ?!
		//        This can only work when _only_ networkhuman drivers in the race
		//        (that is _no_robot_driver_) ; because m_vecReadyStatus is indexed
		//        by the networkhuman drivers list.
		// TO fix this, 2 solutions:
		// 1) make the networking module take care of the robot drivers too
		//    (in m_vecReadyStatus, m_vecNetworkPlayers, ...)
		// 2) make the networking _menu_ only take care of the networkhuman drivers.
		bool bReady = bRobotsReady;
		if(strcmp(NETWORKROBOT, GfParmGetStr(reInfo->params, dname, RM_ATTR_MODULE, "")) == 0) {
			// Write car model, as it may have changed via garage menu
			if (NetIsServer()) {
				NetServerMutexData *pSData = NetGetServer()->LockServerData();
				strncpy(pSData->m_vecNetworkPlayers[idx-1].car, car, 64);
				GfLogInfo("idx %d car set to %s\n", idx, car);

				// also need to write back for garage menu
				const GfCar* newCar = GfCars::self()->getCar(car);
				newDriver = GfDrivers::self()->getDriver(NETWORKROBOT, pSData->m_vecNetworkPlayers[idx-1].idx);
				newDriver->setCar(newCar);
				NetGetServer()->UnlockServerData();
			}

			//GfLogInfo("idx %d, m_vecReadyStatus.size() %d\n", idx, pNData->m_vecReadyStatus.size());
			NetMutexData *pNData = NetGetNetwork()->LockNetworkData();
			bReady = pNData->m_vecReadyStatus[idx-1];
			NetGetNetwork()->UnlockNetworkData();
		}

		int readyindex = 0;
		if (bReady)
			readyindex = 1;	
		else
			bEveryoneReadyToRace = false;

		if (strcmp(NetGetNetwork()->GetDriverName(),name)==0)
		{
			pColor = &green[0];
			g_strCar = strRealCar;
			//Make sure checkbox matches ready state
			GfuiCheckboxSetChecked(racemanMenuHdle, g_ReadyCheckboxId, bReady);
			if (NetGetClient())
				EnableMenuClientButtons(bReady);
			else
				EnableMenuHostButtons(bReady);
		}
		else
			pColor = &white[0];

		GfuiVisibilitySet(racemanMenuHdle,g_readystatus[i-1],true);
		GfuiStaticImageSetActive(racemanMenuHdle,g_readystatus[i-1],readyindex);
		GfuiLabelSetColor(racemanMenuHdle, g_playerNames[i-1], pColor);
		GfuiLabelSetText(racemanMenuHdle,g_playerNames[i-1],name);

		GfuiLabelSetColor(racemanMenuHdle, g_carNames[i-1], pColor);
		GfuiLabelSetText(racemanMenuHdle,g_carNames[i-1],strRealCar.c_str());
		GfParmReleaseHandle(pMod);
	}

	//Clear out rest of table
	for (int i=nCars;i<MAXNETWORKPLAYERS;i++)
	{
		GfuiVisibilitySet(racemanMenuHdle,g_readystatus[i],false);
		GfuiLabelSetText(racemanMenuHdle,g_playerNames[i],"");
		GfuiLabelSetText(racemanMenuHdle,g_carNames[i],"");
	}

	pNetwork->SetRefreshDisplay(false);
	GfuiApp().eventLoop().postRedisplay();

	if (NetIsClient())
	{	
		NetGetClient()->ConnectToClients();

		if (!NetGetClient()->TimeSynced())
		{
			NetGetClient()->SendServerTimeRequest();
		}
	}

	if (NetIsServer())
	{
		if (bEveryoneReadyToRace && nCars > 1)
			ServerPrepareStartNetworkRace(NULL);
	}
}