Beispiel #1
0
void NetServer::SetLocalDrivers()
{
	m_setLocalDrivers.clear();

	m_driverIdx = GetDriverIdx();
	GfLogTrace("Adding Human start rank: %i\n",m_driverIdx);
	m_setLocalDrivers.insert(m_driverIdx-1);

	assert(m_strRaceXMLFile!="");

	void *params = GfParmReadFileLocal(m_strRaceXMLFile.c_str(),GFPARM_RMODE_STD);
	assert(params);

	//const char *pName =GfParmGetStr(params, RM_SECT_HEADER, RM_ATTR_NAME, "");

    int nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS);	
	//Gather vector of all non human drivers
	std::vector<NetDriver> vecRDrivers;
	for (int i=1;i<=nCars;i++)
	{
		NetDriver driver;
		ReadDriverData(driver,i,params);
		if ((strcmp(driver.module,NETWORKROBOT)!=0)
			&&(strcmp(driver.module,HUMANROBOT)!=0))
		{
			m_setLocalDrivers.insert(i-1);
			GfLogTrace("Adding driver start rank:%i\n",i);
		}
	}
}
static void
rmCarSettingsMenu(void *pMenu)
{
	int nDriverIdx = NetGetNetwork()->GetDriverIdx();

	if (nDriverIdx > -1) {
		NetDriver driver;
		// char newName[64]; Never used
		char dname[256];

		// check for car change
		GfLogInfo("Car %d changed \n", nDriverIdx);

		tRmInfo* reInfo = LmRaceEngine().inData();
		reInfo->params = GfParmReadFileLocal("config/raceman/networkrace.xml",GFPARM_RMODE_REREAD);
		reInfo->_reName = GfParmGetStr(reInfo->params, RM_SECT_HEADER, RM_ATTR_NAME, "");

		sprintf(dname, "%s/%d", RM_SECT_DRIVERS, nDriverIdx);
		int idx = GfParmGetNum(reInfo->params, dname, RM_ATTR_IDX, "",0);

		// Garage menu to change clients car
		GfDriver* PCurrentDriver = GfDrivers::self()->getDriver(NETWORKROBOT, idx);

		GarageMenu.setPreviousMenuHandle(racemanMenuHdle);
		GarageMenu.runMenu(LmRaceEngine().race(), PCurrentDriver);
		bGarage = true;
	}
}
// Retrieve the NetDriver instance with given index in the human module interface list
static int
GetHumanDriver(NetDriver &driver,int index)
{
	void *params = GfParmReadFileLocal("drivers/human/human.xml", GFPARM_RMODE_STD);
	assert(params);
	char path2[256];
	sprintf(path2, "Robots/index/%d",index);

	if (GfParmExistsSection(params, path2) == 0) return 0;

	strncpy(driver.name,GfParmGetStr(params, path2, "name",NULL),64);
	strncpy(driver.sname,GfParmGetStr(params, path2, ROB_ATTR_SNAME, NULL), 64);
	strncpy(driver.cname,GfParmGetStr(params, path2, ROB_ATTR_CODE, NULL), 4);
	strncpy(driver.car,GfParmGetStr(params, path2, "car name",NULL),64);
	strncpy(driver.type,GfParmGetStr(params, path2, "type",NULL),64);
	strncpy(driver.skilllevel,GfParmGetStr(params, path2, "skill level",NULL),64);

	driver.racenumber = GfParmGetNum(params, path2, "race number",NULL,1.0);
	driver.red = GfParmGetNum(params, path2, "red",NULL,1.0);
	driver.green = GfParmGetNum(params, path2, "green",NULL,1.0);
	driver.blue = GfParmGetNum(params, path2, "blue",NULL,1.0);

	strncpy(driver.module,NETWORKROBOT,64);
	GfParmReleaseHandle(params);

	return 1;
}
Beispiel #4
0
void NetServer::SetHostSettings(const char *pszCarCat,bool bCollisions)
{
	assert(m_strRaceXMLFile!="");

	void *params = GfParmReadFileLocal(m_strRaceXMLFile.c_str(),GFPARM_RMODE_STD);
	assert(params);
	const char *pName =GfParmGetStr(params, RM_SECT_HEADER, RM_ATTR_NAME, "");


	GfParmSetStr(params, RM_SECT_HEADER,RM_ATTR_CAR_CATEGORY, pszCarCat);
	GfParmWriteFileLocal(m_strRaceXMLFile.c_str(), params, pName);
}
Beispiel #5
0
void NetServer::GenerateDriversForXML()
{
	assert(m_strRaceXMLFile!="");

	void *params = GfParmReadFileLocal(m_strRaceXMLFile.c_str(),GFPARM_RMODE_STD);
	assert(params);
	
	const char *pName =GfParmGetStr(params, RM_SECT_HEADER, RM_ATTR_NAME, "");

    int nCars = GfParmGetEltNb(params, RM_SECT_DRIVERS);
	
	//Gather vector of all non human drivers
	std::vector<NetDriver> vecRDrivers;
	for (int i=1;i<=nCars;i++)
	{
		NetDriver driver;
		ReadDriverData(driver,i,params);
		if (strcmp(driver.module,NETWORKROBOT)	&& strcmp(driver.module,HUMANROBOT))
			vecRDrivers.push_back(driver);
	}

	//Recreate drivers section robots first
	char drvSec[256];
	GfParmListClean(params, RM_SECT_DRIVERS);
	for (int i=0;i<(int)vecRDrivers.size();i++)
	{
		int index = i+1;
		sprintf(drvSec, "%s/%d", RM_SECT_DRIVERS, index);
		GfParmSetNum(params, drvSec, RM_ATTR_IDX, (char*)NULL, (tdble)vecRDrivers[i].idx);
		GfParmSetStr(params, drvSec, RM_ATTR_MODULE, vecRDrivers[i].module);
    }

	//And then add the networkhuman drivers
	NetServerMutexData *pSData = LockServerData();
	for (int i=0;i<(int)pSData->m_vecNetworkPlayers.size();i++)
	{
		int index = i+1+vecRDrivers.size();
		sprintf(drvSec, "%s/%d", RM_SECT_DRIVERS, index);
		GfParmSetNum(params, drvSec, RM_ATTR_IDX, (char*)NULL,(tdble) pSData->m_vecNetworkPlayers[i].idx);
		GfParmSetStr(params, drvSec, RM_ATTR_MODULE, pSData->m_vecNetworkPlayers[i].module);
    }

	UnlockServerData();
	
	//Save our changes
	GfParmWriteFileLocal(m_strRaceXMLFile.c_str(), params, pName);
}
Beispiel #6
0
bool RobotXml::ReadRobotDrivers(const char*pRobotName,std::vector<NetDriver> &vecDrivers)
{
 	char buf[255];
	sprintf(buf,"drivers/%s/%s.xml",pRobotName,pRobotName);
	void *params = GfParmReadFileLocal(buf,GFPARM_RMODE_REREAD);

	char path2[256];

	//bool bFound = true;
	//int i = 1;
	int nPlayers = GfParmGetEltNb(params, "Robots/index");

	for (int i= 1;i<=nPlayers;i++)
	{
		sprintf(path2, "Robots/index/%i",i);
		NetDriver driver;
		strncpy(driver.name,GfParmGetStr(params, path2, "name",NULL),64);
		std::string strClient = GfParmGetStr(params, path2, "client",NULL);
		if (strClient == "yes")
			driver.client = true;
		else 
			driver.client = false;

		strncpy(driver.car,GfParmGetStr(params, path2, "car name",NULL),64);
		strncpy(driver.type,GfParmGetStr(params, path2, "type",NULL),64);
		strncpy(driver.skilllevel,GfParmGetStr(params, path2, "skill level",NULL),64);
		
		driver.racenumber = (int)GfParmGetNum(params, path2, "race number",NULL,1.0);
		driver.red = GfParmGetNum(params, path2, "red",NULL,1.0);
		driver.green = GfParmGetNum(params, path2, "green",NULL,1.0);
		driver.blue = GfParmGetNum(params, path2, "blue",NULL,1.0);
		std::string strHost = GfParmGetStr(params, path2, "host",NULL);
			
		ENetAddress address;
		enet_address_set_host (& address, strHost.c_str());
		driver.address.host = address.host;
		driver.address.port = (int)GfParmGetNum(params, path2, "port",NULL,0);
		strncpy(driver.module,NETWORKROBOT,64);
		vecDrivers.push_back(driver);
		printf("Adding driver \n");
	}

	GfParmReleaseHandle(params);
	return true;
}
static void
LookupPlayerSetup(std::string & strDriver,std::string & strCar)
{
    	void	*drvinfo;
	
	char buf[255];
	sprintf(buf, "%s", HM_DRV_FILE);

	drvinfo = GfParmReadFileLocal(buf, GFPARM_RMODE_REREAD);
		assert(drvinfo);
	if (drvinfo == NULL) {
		return;
	}

	char sstring[256];

	sprintf(sstring, "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, 1);
	strDriver = GfParmGetStr(drvinfo, sstring, ROB_ATTR_NAME, "");
	strCar = GfParmGetStr(drvinfo, sstring, ROB_ATTR_CAR, "");
	GfParmReleaseHandle(drvinfo);
}
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);
}
Beispiel #9
0
bool RobotXml::CreateRobotFile(const char*pRobotName,std::vector<NetDriver> &vecDrivers)
{
 	char buf[255];
	sprintf(buf,"drivers/%s/%s.xml",pRobotName,pRobotName);
	void *params = GfParmReadFileLocal(buf,GFPARM_RMODE_CREAT);
	//Erase existing robots
	GfParmListClean(params, "Robots");
	char path2[256];

	for (int i=0;i<(int)vecDrivers.size();i++)
	{
		sprintf(path2, "Robots/index/%d",i+1);
		GfParmSetStr(params, path2, "name",vecDrivers[i].name);
		GfParmSetStr(params, path2, "car name",vecDrivers[i].car);
		GfParmSetNum(params, path2, "race number", (char*)NULL,(tdble) vecDrivers[i].racenumber);
		GfParmSetNum(params, path2, "red", (char*)NULL, vecDrivers[i].red);
		GfParmSetNum(params, path2, "green", (char*)NULL, vecDrivers[i].green);
		GfParmSetNum(params, path2, "blue", (char*)NULL, vecDrivers[i].blue);
		GfParmSetStr(params, path2, "type",vecDrivers[i].type);
		GfParmSetStr(params, path2, "skill level",vecDrivers[i].skilllevel);
		GfParmSetStr(params, path2, "networkrace","yes");
		if (vecDrivers[i].client)
			GfParmSetStr(params, path2, "client","yes");
		else
			GfParmSetStr(params, path2, "client","no");
		

		char hostName[256];
		enet_address_get_host_ip (&vecDrivers[i].address,hostName,256);
		GfParmSetStr(params, path2, "host",hostName);
		GfParmSetNum(params, path2, "port",(char*)NULL, vecDrivers[i].address.port);
	}

	//Save our changes
	GfParmWriteFileLocal(buf, params, pRobotName);

	GfParmReleaseHandle(params);

	return true;
}
static void OnActivateNetworkClient(void *)
{
	int nDriverIdx = NetGetNetwork()->GetDriverIdx();

	if(NetGetNetwork()->IsConnected() && nDriverIdx > -1) {
		// Menu reactivated after garage menu is done
		NetDriver driver;
		char newName[64];
		char dname[256];

		// check for car change
		if (bGarage == true ) {
			bGarage = false;

			tRmInfo* reInfo = LmRaceEngine().inData();
			reInfo->params = GfParmReadFileLocal("config/raceman/networkrace.xml",GFPARM_RMODE_REREAD);
			reInfo->_reName = GfParmGetStr(reInfo->params, RM_SECT_HEADER, RM_ATTR_NAME, "");

			sprintf(dname, "%s/%d", RM_SECT_DRIVERS, nDriverIdx);
			int idx = GfParmGetNum(reInfo->params, dname, RM_ATTR_IDX, "",0);

			GfDriver* PCurrentDriver = GfDrivers::self()->getDriver(NETWORKROBOT, idx);
			strncpy(newName, PCurrentDriver->getCar()->getId().c_str(), sizeof(newName));

			GfLogInfo("Client: Index %d changed to %s\n", idx, newName);
			NetGetNetwork()->SetCarInfo(newName);
		} else {
			// Ensure menu system knows about all cars
			GfDrivers::self()->reload();
			// tRmInfo* reInfo = LmRaceEngine().inData(); // Never used
			LmRaceEngine().race()->load(LmRaceEngine().race()->getManager(), true);
		}
	}

	GfuiApp().eventLoop().setRecomputeCB(ClientIdle);
	bGarage = false;
}
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, "");
}
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);
	}
}