示例#1
0
// ////////////////////////////////////////////////////////////////////////////
// Set Player's stats
// send stats to all players when bLocal is false
BOOL setMultiStats(SDWORD player, PLAYERSTATS plStats, BOOL bLocal)
{
	uint32_t playerIndex = (uint32_t)player;

	if (playerIndex >= MAX_PLAYERS)
	{
		return true;
	}

	// First copy over the data into our local array
	memcpy(&playerStats[playerIndex], &plStats, sizeof(plStats));

	if (!bLocal)
	{
		// Now send it to all other players
		NETbeginEncode(NETbroadcastQueue(), NET_PLAYER_STATS);
			// Send the ID of the player's stats we're updating
			NETuint32_t(&playerIndex);

			// Send over the actual stats
			NETuint32_t(&playerStats[playerIndex].played);
			NETuint32_t(&playerStats[playerIndex].wins);
			NETuint32_t(&playerStats[playerIndex].losses);
			NETuint32_t(&playerStats[playerIndex].totalKills);
			NETuint32_t(&playerStats[playerIndex].totalScore);
			NETuint32_t(&playerStats[playerIndex].recentKills);
			NETuint32_t(&playerStats[playerIndex].recentScore);
			NETuint32_t(&playerStats[playerIndex].killsToAdd);
			NETuint32_t(&playerStats[playerIndex].scoreToAdd);
		NETend();
	}

	return true;
}
示例#2
0
// send complete game info set!
void sendOptions()
{
	bool dummy = true;
	unsigned int i;

	if (!NetPlay.isHost || !bHosted)  // Only host should act, and only if the game hasn't started yet.
	{
		ASSERT(false, "Host only routine detected for client or not hosting yet!");
		return;
	}

	NETbeginEncode(NETbroadcastQueue(), NET_OPTIONS);

	// First send information about the game
	NETuint8_t(&game.type);
	NETstring(game.map, 128);
	NETuint8_t(&game.maxPlayers);
	NETstring(game.name, 128);
	NETbool(&dummy);
	NETuint32_t(&game.power);
	NETuint8_t(&game.base);
	NETuint8_t(&game.alliance);
	NETbool(&game.scavengers);

	for (i = 0; i < MAX_PLAYERS; i++)
	{
		NETuint8_t(&game.skDiff[i]);
	}

	// Send the list of who is still joining
	for (i = 0; i < MAX_PLAYERS; i++)
	{
		NETbool(&ingame.JoiningInProgress[i]);
	}

	// Same goes for the alliances
	for (i = 0; i < MAX_PLAYERS; i++)
	{
		unsigned int j;

		for (j = 0; j < MAX_PLAYERS; j++)
		{
			NETuint8_t(&alliances[i][j]);
		}
	}

	// Send the number of structure limits to expect
	NETuint32_t(&ingame.numStructureLimits);
	debug(LOG_NET, "(Host) Structure limits to process on client is %u", ingame.numStructureLimits);
	// Send the structures changed
	for (i = 0; i < ingame.numStructureLimits; i++)
	{
		NETuint32_t(&ingame.pStructureLimits[i].id);
		NETuint32_t(&ingame.pStructureLimits[i].limit);
	}
	updateLimitFlags();
	NETuint8_t(&ingame.flags);

	NETend();
}
示例#3
0
// ////////////////////////////////////////////////////////////////////////////
// Set Player's stats
// send stats to all players when bLocal is false
bool setMultiStats(uint32_t playerIndex, PLAYERSTATS plStats, bool bLocal)
{
	if (playerIndex >= MAX_PLAYERS)
	{
		return true;
	}

	// First copy over the data into our local array
	playerStats[playerIndex] = plStats;

	if (!bLocal)
	{
		// Now send it to all other players
		NETbeginEncode(NETbroadcastQueue(), NET_PLAYER_STATS);
			// Send the ID of the player's stats we're updating
			NETuint32_t(&playerIndex);

			// Send over the actual stats
			NETuint32_t(&playerStats[playerIndex].played);
			NETuint32_t(&playerStats[playerIndex].wins);
			NETuint32_t(&playerStats[playerIndex].losses);
			NETuint32_t(&playerStats[playerIndex].totalKills);
			NETuint32_t(&playerStats[playerIndex].totalScore);
			NETuint32_t(&playerStats[playerIndex].recentKills);
			NETuint32_t(&playerStats[playerIndex].recentScore);
		NETend();
	}

	return true;
}
示例#4
0
// ////////////////////////////////////////////////////////////////////////////
// Network File packet processor.
bool recvMapFileRequested(NETQUEUE queue)
{
	//char mapStr[256],mapName[256],fixedname[256];
	uint32_t player;

	PHYSFS_sint64 fileSize_64;
	PHYSFS_file	*pFileHandle;

	if(!NetPlay.isHost)				// only host should act
	{
		ASSERT(false, "Host only routine detected for client!");
		return false;
	}

	//	Check to see who wants the file
	NETbeginDecode(queue, NET_FILE_REQUESTED);
	NETuint32_t(&player);
	NETend();

	if (!NetPlay.players[player].wzFile.isSending)
	{
		NetPlay.players[player].needFile = true;
		NetPlay.players[player].wzFile.isCancelled = false;
		NetPlay.players[player].wzFile.isSending = true;

		LEVEL_DATASET *mapData = levFindDataSet(game.map, &game.hash);

		addConsoleMessage("Map was requested: SENDING MAP!",DEFAULT_JUSTIFY, SYSTEM_MESSAGE);

		char *mapStr = mapData->realFileName;
		debug(LOG_NET, "Map was requested. Looking for %s", mapStr);

		// Checking to see if file is available...
		pFileHandle = PHYSFS_openRead(mapStr);
		if (pFileHandle == NULL)
		{
			debug(LOG_ERROR, "Failed to open %s for reading: %s", mapStr, PHYSFS_getLastError());
			debug(LOG_FATAL, "You have a map (%s) that can't be located.\n\nMake sure it is in the correct directory and or format! (No map packs!)", mapStr);
			// NOTE: if we get here, then the game is basically over, The host can't send the file for whatever reason...
			// Which also means, that we can't continue.
			debug(LOG_NET, "***Host has a file issue, and is being forced to quit!***");
			NETbeginEncode(NETbroadcastQueue(), NET_HOST_DROPPED);
			NETend();
			abort();
		}

		// get the file's size.
		fileSize_64 = PHYSFS_fileLength(pFileHandle);
		debug(LOG_NET, "File is valid, sending [directory: %s] %s to client %u", PHYSFS_getRealDir(mapStr), mapStr, player);

		NetPlay.players[player].wzFile.pFileHandle = pFileHandle;
		NetPlay.players[player].wzFile.fileSize_32 = (int32_t) fileSize_64;		//we don't support 64bit int nettypes.
		NetPlay.players[player].wzFile.currPos = 0;

		NETsendFile(game.map, game.hash, player);
	}
	return true;
}
示例#5
0
// send complete game info set!
void sendOptions()
{
	unsigned int i;

	NETbeginEncode(NETbroadcastQueue(), NET_OPTIONS);

	// First send information about the game
	NETuint8_t(&game.type);
	NETstring(game.map, 128);
	NETuint8_t(&game.maxPlayers);
	NETstring(game.name, 128);
	NETbool(&game.fog);
	NETuint32_t(&game.power);
	NETuint8_t(&game.base);
	NETuint8_t(&game.alliance);
	NETbool(&game.scavengers);

	for (i = 0; i < MAX_PLAYERS; i++)
	{
		NETuint8_t(&game.skDiff[i]);
	}

	// Send the list of who is still joining
	for (i = 0; i < MAX_PLAYERS; i++)
	{
		NETbool(&ingame.JoiningInProgress[i]);
	}

	// Same goes for the alliances
	for (i = 0; i < MAX_PLAYERS; i++)
	{
		unsigned int j;

		for (j = 0; j < MAX_PLAYERS; j++)
		{
			NETuint8_t(&alliances[i][j]);
		}
	}

	// Send the number of structure limits to expect
	NETuint32_t(&ingame.numStructureLimits);
	debug(LOG_NET, "(Host) Structure limits to process on client is %u", ingame.numStructureLimits);
	// Send the structures changed
	for (i = 0; i < ingame.numStructureLimits; i++)
	{
		NETuint32_t(&ingame.pStructureLimits[i].id);
		NETuint32_t(&ingame.pStructureLimits[i].limit);
	}
	updateLimitFlags();
	NETuint8_t(&ingame.flags);

	NETend();
}
示例#6
0
// ////////////////////////////////////////////////////////////////////////////
// say hi to everyone else....
void playerResponding(void)
{
	ingame.startTime = gameTime;
	ingame.localJoiningInProgress = false; // No longer joining.
	ingame.JoiningInProgress[selectedPlayer] = false;

	// Home the camera to the player
	cameraToHome(selectedPlayer, false);

	// Tell the world we're here
	NETbeginEncode(NETbroadcastQueue(), NET_PLAYERRESPONDING);
	NETuint32_t(&selectedPlayer);
	NETend();
}
示例#7
0
bool sendPing(void)
{
	bool			isNew = true;
	uint8_t			player = selectedPlayer;
	int				i;
	static UDWORD	lastPing = 0;	// Last time we sent a ping
	static UDWORD	lastav = 0;		// Last time we updated average

	// Only ping every so often
	if (lastPing > realTime)
	{
		lastPing = 0;
	}

	if (realTime - lastPing < PING_FREQUENCY)
	{
		return true;
	}

	lastPing = realTime;

	// If host, also update the average ping stat for joiners
	if (NetPlay.isHost)
	{
		if (lastav > realTime)
		{
			lastav = 0;
		}

		if (realTime - lastav > AV_PING_FREQUENCY)
		{
			NETsetGameFlags(2, averagePing());
			lastav = realTime;
		}
	}

	/*
	 * Before we send the ping, if any player failed to respond to the last one
	 * we should re-enumerate the players.
	 */

	for (i = 0; i < MAX_PLAYERS; i++)
	{
		if (isHumanPlayer(i)
		    && PingSend[i]
		    && ingame.PingTimes[i]
		    && i != selectedPlayer)
		{
			ingame.PingTimes[i] = PING_LIMIT;
		}
		else if (!isHumanPlayer(i)
		         && PingSend[i]
		         && ingame.PingTimes[i]
		         && i != selectedPlayer)
		{
			ingame.PingTimes[i] = 0;
		}
	}

	uint64_t pingChallengei = (uint64_t)rand() << 32 | rand();
	memcpy(pingChallenge, &pingChallengei, sizeof(pingChallenge));

	NETbeginEncode(NETbroadcastQueue(), NET_PING);
	NETuint8_t(&player);
	NETbool(&isNew);
	NETbin(pingChallenge, sizeof(pingChallenge));
	NETend();

	// Note when we sent the ping
	for (i = 0; i < MAX_PLAYERS; i++)
	{
		PingSend[i] = realTime;
	}

	return true;
}
示例#8
0
// ////////////////////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////////////////////
// Text Messaging between players. proceed string with players to send to.
// eg "123hi there" sends "hi there" to players 1,2 and 3.
bool sendTextMessage(const char *pStr, bool all, uint32_t from)
{
	bool				normal = true;
	bool				sendto[MAX_PLAYERS];
	int					posTable[MAX_PLAYERS];
	UDWORD				i;
	char				display[MAX_CONSOLE_STRING_LENGTH];
	char				msg[MAX_CONSOLE_STRING_LENGTH];
	char*				curStr = (char*)pStr;

	memset(display,0x0, sizeof(display));	//clear buffer
	memset(msg,0x0, sizeof(display));		//clear buffer
	memset(sendto,0x0, sizeof(sendto));		//clear private flag
	memset(posTable,0x0, sizeof(posTable));		//clear buffer
	sstrcpy(msg, curStr);

	if (!all)
	{
		// create a position table
		for (i = 0; i < game.maxPlayers; i++)
		{
			posTable[NetPlay.players[i].position] = i;
		}

		if (curStr[0] == '.')
		{
			curStr++;
			for (i = 0; i < game.maxPlayers; i++)
			{
				if (i != from && aiCheckAlliances(from, i))
				{
					sendto[i] = true;
				}
			}
			normal = false;
			if (!all)
			{
				sstrcpy(display, _("(allies"));
			}
		}
		for (; curStr[0] >= '0' && curStr[0] <= '9'; ++curStr)  // for each 0..9 numeric char encountered
		{
			i = posTable[curStr[0]-'0'];
			if (normal)
			{
				sstrcpy(display, _("(private to "));
			}
			else
			{
				sstrcat(display, ", ");
			}
			if ((isHumanPlayer(i) || (game.type == SKIRMISH && i<game.maxPlayers && game.skDiff[i] ) ))
			{
				sstrcat(display, getPlayerName(posTable[curStr[0]-'0']));
				sendto[i] = true;
			}
			else
			{
				sstrcat(display, _("[invalid]"));
			}
			normal = false;
		}

		if (!normal)	// lets user know it is a private message
		{
			if (curStr[0] == ' ')
			{
				curStr++;
			}
			sstrcat(display, ") ");
			sstrcat(display, curStr);
		}
	}

	if (all)	//broadcast
	{
		NETbeginEncode(NETbroadcastQueue(), NET_TEXTMSG);
		NETuint32_t(&from);		// who this msg is from
		NETstring(msg,MAX_CONSOLE_STRING_LENGTH);	// the message to send
		NETend();
	}
	else if (normal)
	{
		for (i = 0; i < MAX_PLAYERS; i++)
		{
			if (i != from && openchannels[i])
			{
				if (isHumanPlayer(i))
				{
					NETbeginEncode(NETnetQueue(i), NET_TEXTMSG);
					NETuint32_t(&from);		// who this msg is from
					NETstring(msg,MAX_CONSOLE_STRING_LENGTH);	// the message to send
					NETend();
				}
				else	//also send to AIs now (non-humans), needed for AI
				{
					sendAIMessage(msg, from, i);
				}
			}
		}
	}
	else	//private msg
	{
		for (i = 0; i < MAX_PLAYERS; i++)
		{
			if (sendto[i])
			{
				if (isHumanPlayer(i))
				{
					NETbeginEncode(NETnetQueue(i), NET_TEXTMSG);
					NETuint32_t(&from);				// who this msg is from
					NETstring(display, MAX_CONSOLE_STRING_LENGTH);	// the message to send
					NETend();
				}
				else	//also send to AIs now (non-humans), needed for AI
				{
					sendAIMessage(curStr, from, i);
				}
			}
		}
	}

	// This is for local display
	if (from == selectedPlayer)
	{
		sstrcpy(msg, NetPlay.players[from].name);		// name
		sstrcat(msg, ": ");					// seperator
		sstrcat(msg, (normal ? curStr : display));		// add message
		addConsoleMessage(msg, DEFAULT_JUSTIFY, from);		// display
	}

	return true;
}
示例#9
0
// ////////////////////////////////////////////////////////////////////////////
// Network File packet processor.
bool recvMapFileRequested(NETQUEUE queue)
{
	char mapStr[256],mapName[256],fixedname[256];
	uint32_t player;

	PHYSFS_sint64 fileSize_64;
	PHYSFS_file	*pFileHandle;

	if(!NetPlay.isHost)				// only host should act
	{
		ASSERT(false, "Host only routine detected for client!");
		return false;
	}

	//	Check to see who wants the file
	NETbeginDecode(queue, NET_FILE_REQUESTED);
	NETuint32_t(&player);
	NETend();

	if (!NetPlay.players[player].wzFile.isSending)
	{
		NetPlay.players[player].needFile = true;
		NetPlay.players[player].wzFile.isCancelled = false;
		NetPlay.players[player].wzFile.isSending = true;

		memset(mapStr,0,256);
		memset(mapName,0,256);
		memset(fixedname,0,256);

		addConsoleMessage("Map was requested: SENDING MAP!",DEFAULT_JUSTIFY, SYSTEM_MESSAGE);

		sstrcpy(mapName, game.map);
		if (	strstr(mapName,"-T1") != 0
			|| strstr(mapName,"-T2") != 0
			|| strstr(mapName,"-T3") != 0)
		{
		// chop off the -T1 *only when needed!*
		mapName[strlen(game.map)-3] = 0;		// chop off the -T1 etc..
		}
		// chop off the sk- if required.
		if(strncmp(mapName,"Sk-",3) == 0)
		{
			sstrcpy(mapStr, &(mapName[3]));
			sstrcpy(mapName, mapStr);
		}

		snprintf(mapStr, sizeof(mapStr), "%dc-%s.wz", game.maxPlayers, mapName);
		snprintf(fixedname, sizeof(fixedname), "maps/%s", mapStr);		//We know maps are in /maps dir...now. fix for linux -Q
		sstrcpy(mapStr, fixedname);
		debug(LOG_NET, "Map was requested. Looking for %s", mapStr);

		// Checking to see if file is available...
		pFileHandle = PHYSFS_openRead(mapStr);
		if (pFileHandle == NULL)
		{
			debug(LOG_ERROR, "Failed to open %s for reading: %s", mapStr, PHYSFS_getLastError());
			debug(LOG_FATAL, "You have a map (%s) that can't be located.\n\nMake sure it is in the correct directory and or format! (No map packs!)", mapStr);
			// NOTE: if we get here, then the game is basically over, The host can't send the file for whatever reason...
			// Which also means, that we can't continue.
			debug(LOG_NET, "***Host has a file issue, and is being forced to quit!***");
			NETbeginEncode(NETbroadcastQueue(), NET_HOST_DROPPED);
			NETend();
			abort();
	}

		// get the file's size.
		fileSize_64 = PHYSFS_fileLength(pFileHandle);
		debug(LOG_NET, "File is valid, sending [directory: %s] %s to client %u", PHYSFS_getRealDir(mapStr), mapStr, player);

		NetPlay.players[player].wzFile.pFileHandle = pFileHandle;
		NetPlay.players[player].wzFile.fileSize_32 = (int32_t) fileSize_64;		//we don't support 64bit int nettypes.
		NetPlay.players[player].wzFile.currPos = 0;

		NETsendFile(mapStr, player);
	}
	return true;
}