Esempio n. 1
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;
}
Esempio n. 2
0
Sha256 levGetMapNameHash(char const *mapName)
{
	LEVEL_DATASET *level = levFindDataSet(mapName, NULL);
	if (level == NULL)
	{
		debug(LOG_WARNING, "Couldn't find map \"%s\" to hash.", mapName);
		Sha256 zero;
		zero.setZero();
		return zero;
	}
	return levGetFileHash(level);
}
Esempio n. 3
0
// load up the data for a level
bool levLoadData(const char* name, char *pSaveName, GAME_TYPE saveType)
{
	LEVEL_DATASET	*psNewLevel, *psBaseData, *psChangeLevel;
	SDWORD			i;
	bool            bCamChangeSaveGame;

	debug(LOG_WZ, "Loading level %s (%s, type %d)", name, pSaveName, (int)saveType);
	if (saveType == GTYPE_SAVE_START || saveType == GTYPE_SAVE_MIDMISSION)
	{
		if (!levReleaseAll())
		{
			debug(LOG_ERROR, "Failed to unload old data");
			return false;
		}
	}

	levelLoadType = saveType;

	// find the level dataset
	psNewLevel = levFindDataSet(name);
	if (psNewLevel == NULL)
	{
		debug(LOG_WZ, "Dataset %s not found - trying to load as WRF", name);
		return levLoadSingleWRF(name);
	}
	debug(LOG_WZ, "** Data set found is %s type %d", psNewLevel->pName, (int)psNewLevel->type);

	/* Keep a copy of the present level name */
	sstrcpy(currentLevelName, name);

	bCamChangeSaveGame = false;
	if (pSaveName && saveType == GTYPE_SAVE_START)
	{
		if (psNewLevel->psChange != NULL)
		{
			bCamChangeSaveGame = true;
			debug(LOG_WZ, "** CAMCHANGE FOUND");
		}
	}

	// select the change dataset if there is one
	psChangeLevel = NULL;
	if (((psNewLevel->psChange != NULL) && (psCurrLevel != NULL)) || bCamChangeSaveGame)
	{
		//store the level name
		debug(LOG_WZ, "Found CAMCHANGE dataset");
		psChangeLevel = psNewLevel;
		psNewLevel = psNewLevel->psChange;
	}

	// ensure the correct dataset is loaded
	if (psNewLevel->type == LDS_CAMPAIGN)
	{
		debug(LOG_ERROR, "Cannot load a campaign dataset (%s)", psNewLevel->pName);
		return false;
	}
	else
	{
		if (psCurrLevel != NULL)
		{
			if ((psCurrLevel->psBaseData != psNewLevel->psBaseData) ||
				(psCurrLevel->type < LDS_NONE && psNewLevel->type  >= LDS_NONE) ||
				(psCurrLevel->type >= LDS_NONE && psNewLevel->type  < LDS_NONE))
			{
				// there is a dataset loaded but it isn't the correct one
				debug(LOG_WZ, "Incorrect base dataset loaded (%p != %p, %d - %d)",
				      psCurrLevel->psBaseData, psNewLevel->psBaseData, (int)psCurrLevel->type, (int)psNewLevel->type);
				if (!levReleaseAll())	// this sets psCurrLevel to NULL
				{
					return false;
				}
			}
			else
			{
				debug(LOG_WZ, "Correct base dataset already loaded.");
			}
		}

		// setup the correct dataset to load if necessary
		if (psCurrLevel == NULL)
		{
			if (psNewLevel->psBaseData != NULL)
			{
				debug(LOG_WZ, "Setting base dataset to load: %s", psNewLevel->psBaseData->pName);
			}
			psBaseData = psNewLevel->psBaseData;
		}
		else
		{
			debug(LOG_WZ, "No base dataset to load");
			psBaseData = NULL;
		}
	}

	setCurrentMap(psNewLevel->pName, psNewLevel->players);
	if (!rebuildSearchPath(psNewLevel->dataDir, true))
	{
		return false;
	}

	// reset the old mission data if necessary
	if (psCurrLevel != NULL)
	{
		debug(LOG_WZ, "Reseting old mission data");
		if (!levReleaseMissionData())
		{
			return false;
		}
	}

	// need to free the current map and droids etc for a save game
	if ((psBaseData == NULL) &&
		(pSaveName != NULL))
	{
		if (!saveGameReset())
		{
			return false;
		}
	}

	// initialise if necessary
	if (psNewLevel->type == LDS_COMPLETE || //psNewLevel->type >= LDS_MULTI_TYPE_START ||
		psBaseData != NULL)
	{
		debug(LOG_WZ, "Calling stageOneInitialise!");
		if (!stageOneInitialise())
		{
			return false;
		}
	}

	// load up a base dataset if necessary
	if (psBaseData != NULL)
	{
		debug(LOG_WZ, "Loading base dataset %s", psBaseData->pName);
		for(i=0; i<LEVEL_MAXFILES; i++)
		{
			if (psBaseData->apDataFiles[i])
			{
				// load the data
				debug(LOG_WZ, "Loading [directory: %s] %s ...", PHYSFS_getRealDir(psBaseData->apDataFiles[i]), psBaseData->apDataFiles[i]);
				if (!resLoad(psBaseData->apDataFiles[i], i))
				{
					return false;
				}
			}
		}
	}
	if (psNewLevel->type == LDS_CAMCHANGE)
	{
		if (!campaignReset())
		{
			return false;
		}
	}
	if (psNewLevel->game == -1)  //no .gam file to load - BETWEEN missions (for Editor games only)
	{
		ASSERT( psNewLevel->type == LDS_BETWEEN,
			"levLoadData: only BETWEEN missions do not need a .gam file" );
		debug(LOG_WZ, "No .gam file for level: BETWEEN mission");
		if (pSaveName != NULL)
		{
			if (psBaseData != NULL)
			{
				if (!stageTwoInitialise())
				{
					return false;
				}
			}

			//set the mission type before the saveGame data is loaded
			if (saveType == GTYPE_SAVE_MIDMISSION)
			{
				debug(LOG_WZ, "Init mission stuff");
				if (!startMissionSave(psNewLevel->type))
				{
					return false;
				}

				debug(LOG_NEVER, "dataSetSaveFlag");
				dataSetSaveFlag();
			}

			debug(LOG_NEVER, "Loading savegame: %s", pSaveName);
			if (!loadGame(pSaveName, false, true,true))
			{
				return false;
			}
		}

		if ((pSaveName == NULL) ||
			(saveType == GTYPE_SAVE_START))
		{
			debug(LOG_NEVER, "Start mission - no .gam");
			if (!startMission((LEVEL_TYPE)psNewLevel->type, NULL))
			{
				return false;
			}
		}
	}

	//we need to load up the save game data here for a camchange
	if (bCamChangeSaveGame)
	{
		if (pSaveName != NULL)
		{
			if (psBaseData != NULL)
			{
				if (!stageTwoInitialise())
				{
					return false;
				}
			}

			debug(LOG_NEVER, "loading savegame: %s", pSaveName);
			if (!loadGame(pSaveName, false, true,true))
			{
				return false;
			}

			if (!campaignReset())
			{
				return false;
			}
		}
	}


	// load the new data
	debug(LOG_NEVER, "Loading mission dataset: %s", psNewLevel->pName);
	for(i=0; i < LEVEL_MAXFILES; i++)
	{
		if (psNewLevel->game == i)
		{
			// do some more initialising if necessary
			if (psNewLevel->type == LDS_COMPLETE || psNewLevel->type >= LDS_MULTI_TYPE_START || (psBaseData != NULL && !bCamChangeSaveGame))
			{
				if (!stageTwoInitialise())
				{
					return false;
				}
			}

			// load a savegame if there is one - but not if already done so
			if (pSaveName != NULL && !bCamChangeSaveGame)
			{
				//set the mission type before the saveGame data is loaded
				if (saveType == GTYPE_SAVE_MIDMISSION)
				{
					debug(LOG_WZ, "Init mission stuff");
					if (!startMissionSave(psNewLevel->type))
					{
						return false;
					}

					debug(LOG_NEVER, "dataSetSaveFlag");
					dataSetSaveFlag();
				}

				debug(LOG_NEVER, "Loading save game %s", pSaveName);
				if (!loadGame(pSaveName, false, true,true))
				{
					return false;
				}
			}

			if ((pSaveName == NULL) ||
				(saveType == GTYPE_SAVE_START))
			{
				// load the game
				debug(LOG_WZ, "Loading scenario file %s", psNewLevel->apDataFiles[i]);
				switch (psNewLevel->type)
				{
				case LDS_COMPLETE:
				case LDS_CAMSTART:
					debug(LOG_WZ, "LDS_COMPLETE / LDS_CAMSTART");
					if (!startMission(LDS_CAMSTART, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				case LDS_BETWEEN:
					debug(LOG_WZ, "LDS_BETWEEN");
					if (!startMission(LDS_BETWEEN, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;

				case LDS_MKEEP:
					debug(LOG_WZ, "LDS_MKEEP");
					if (!startMission(LDS_MKEEP, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				case LDS_CAMCHANGE:
					debug(LOG_WZ, "LDS_CAMCHANGE");
					if (!startMission(LDS_CAMCHANGE, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;

				case LDS_EXPAND:
					debug(LOG_WZ, "LDS_EXPAND");
					if (!startMission(LDS_EXPAND, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				case LDS_EXPAND_LIMBO:
					debug(LOG_WZ, "LDS_LIMBO");
					if (!startMission(LDS_EXPAND_LIMBO, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;

				case LDS_MCLEAR:
					debug(LOG_WZ, "LDS_MCLEAR");
					if (!startMission(LDS_MCLEAR, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				case LDS_MKEEP_LIMBO:
					debug(LOG_WZ, "LDS_MKEEP_LIMBO");
					if (!startMission(LDS_MKEEP_LIMBO, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				default:
					ASSERT( psNewLevel->type >= LDS_MULTI_TYPE_START,
						"levLoadData: Unexpected mission type" );
					debug(LOG_WZ, "default (MULTIPLAYER)");
					if (!startMission(LDS_CAMSTART, psNewLevel->apDataFiles[i]))
					{
						return false;
					}
					break;
				}
			}
		}
		else if (psNewLevel->apDataFiles[i])
		{
			// load the data
			debug(LOG_WZ, "Loading %s", psNewLevel->apDataFiles[i]);
			if (!resLoad(psNewLevel->apDataFiles[i], i + CURRENT_DATAID))
			{
				return false;
			}
		}
	}

	if (pSaveName != NULL)
	{
		//load MidMission Extras
		if (!loadMissionExtras(pSaveName, psNewLevel->type))
		{
			return false;
		}
	}

	if (bMultiPlayer)
	{
		loadMultiScripts();
	}
	if (pSaveName != NULL && saveType == GTYPE_SAVE_MIDMISSION)
	{
		//load script stuff
		// load the event system state here for a save game
		debug(LOG_SAVE, "Loading script system state");
		if (!loadScriptState(pSaveName))
		{
			return false;
		}
	}

	if (!stageThreeInitialise())
	{
		return false;
	}

	dataClearSaveFlag();

	//this enables us to to start cam2/cam3 without going via a save game and get the extra droids
	//in from the script-controlled Transporters
	if (!pSaveName && psNewLevel->type == LDS_CAMSTART)
	{
		eventFireCallbackTrigger((TRIGGER_TYPE)CALL_NO_REINFORCEMENTS_LEFT);
	}

	//restore the level name for comparisons on next mission load up
	if (psChangeLevel == NULL)
	{
		psCurrLevel = psNewLevel;
	}
	else
	{
		psCurrLevel = psChangeLevel;
	}

	{
		// Copy this info to be used by the crash handler for the dump file
		char buf[256];

		ssprintf(buf, "Current Level/map is %s", psCurrLevel->pName);
		addDumpInfo(buf);
	}


	return true;
}
Esempio n. 4
0
// parse a level description data file
// the ignoreWrf hack is for compatibility with old maps that try to link in various
// data files that we have removed
bool levParse(const char* buffer, size_t size, searchPathMode datadir, bool ignoreWrf)
{
	lexerinput_t input;
	LEVELPARSER_STATE state;
	int token, currData = -1;
	LEVEL_DATASET	*psDataSet = NULL;

	input.type = LEXINPUT_BUFFER;
	input.input.buffer.begin = buffer;
	input.input.buffer.end = &buffer[size];

	lev_set_extra(&input);

	state = LP_START;
	for (token = lev_lex(); token != 0; token = lev_lex())
	{
		switch (token)
		{
		case LTK_LEVEL:
		case LTK_CAMPAIGN:
		case LTK_CAMSTART:
		case LTK_CAMCHANGE:
		case LTK_EXPAND:
		case LTK_BETWEEN:
		case LTK_MKEEP:
		case LTK_MCLEAR:
		case LTK_EXPAND_LIMBO:
		case LTK_MKEEP_LIMBO:
			if (state == LP_START || state == LP_WAITDATA)
			{
				// start a new level data set
				psDataSet = (LEVEL_DATASET*)malloc(sizeof(LEVEL_DATASET));
				if (!psDataSet)
				{
					debug(LOG_FATAL, "Out of memory");
					abort();
					return false;
				}
				memset(psDataSet, 0, sizeof(LEVEL_DATASET));
				psDataSet->players = 1;
				psDataSet->game = -1;
				psDataSet->dataDir = datadir;
				LIST_APPEND(psLevels, psDataSet, LEVEL_DATASET);
				currData = 0;

				// set the dataset type
				switch (token)
				{
				case LTK_LEVEL:
					psDataSet->type = LDS_COMPLETE;
					break;
				case LTK_CAMPAIGN:
					psDataSet->type = LDS_CAMPAIGN;
					break;
				case LTK_CAMSTART:
					psDataSet->type = LDS_CAMSTART;
					break;
				case LTK_BETWEEN:
					psDataSet->type = LDS_BETWEEN;
					break;
				case LTK_MKEEP:
					psDataSet->type = LDS_MKEEP;
					break;
				case LTK_CAMCHANGE:
					psDataSet->type = LDS_CAMCHANGE;
					break;
				case LTK_EXPAND:
					psDataSet->type = LDS_EXPAND;
					break;
				case LTK_MCLEAR:
					psDataSet->type = LDS_MCLEAR;
					break;
				case LTK_EXPAND_LIMBO:
					psDataSet->type = LDS_EXPAND_LIMBO;
					break;
				case LTK_MKEEP_LIMBO:
					psDataSet->type = LDS_MKEEP_LIMBO;
					break;
				default:
					ASSERT( false,"eh?" );
					break;
				}
			}
			else
			{
				lev_error("Syntax Error");
				return false;
			}
			state = LP_LEVEL;
			break;
		case LTK_PLAYERS:
			if (state == LP_LEVELDONE &&
				(psDataSet->type == LDS_COMPLETE || psDataSet->type >= LDS_MULTI_TYPE_START))
			{
				state = LP_PLAYERS;
			}
			else
			{
				lev_error("Syntax Error");
				return false;
			}
			break;
		case LTK_TYPE:
			if (state == LP_LEVELDONE && psDataSet->type == LDS_COMPLETE)
			{
				state = LP_TYPE;
			}
			else
			{
				lev_error("Syntax Error");
				return false;
			}
			break;
		case LTK_INTEGER:
			if (state == LP_PLAYERS)
			{
				psDataSet->players = (SWORD)levVal;
			}
			else if (state == LP_TYPE)
			{
				if (levVal < LDS_MULTI_TYPE_START)
				{
					lev_error("invalid type number");
					return false;
				}

				psDataSet->type = (SWORD)levVal;
			}
			else
			{
				lev_error("Syntax Error");
				return false;
			}
			state = LP_LEVELDONE;
			break;
		case LTK_DATASET:
			if (state == LP_LEVELDONE && psDataSet->type != LDS_COMPLETE)
			{
				state = LP_DATASET;
			}
			else
			{
				lev_error("Syntax Error");
				return false;
			}
			break;
		case LTK_DATA:
			if (state == LP_WAITDATA)
			{
				state = LP_DATA;
			}
			else if (state == LP_LEVELDONE)
			{
				if (psDataSet->type == LDS_CAMSTART ||
					psDataSet->type == LDS_MKEEP
					||psDataSet->type == LDS_CAMCHANGE ||
					psDataSet->type == LDS_EXPAND ||
					psDataSet->type == LDS_MCLEAR ||
					psDataSet->type == LDS_EXPAND_LIMBO ||
					psDataSet->type == LDS_MKEEP_LIMBO
					)
				{
					lev_error("Missing dataset command");
					return false;
				}
				state = LP_DATA;
			}
			else
			{
				lev_error("Syntax Error");
				return false;
			}
			break;
		case LTK_GAME:
			if ((state == LP_WAITDATA || state == LP_LEVELDONE) &&
				psDataSet->game == -1 && psDataSet->type != LDS_CAMPAIGN)
			{
				state = LP_GAME;
			}
			else
			{
				lev_error("Syntax Error");
				return false;
			}
			break;
		case LTK_IDENT:
			if (state == LP_LEVEL)
			{
				if (psDataSet->type == LDS_CAMCHANGE)
				{
					// This is a campaign change dataset, we need to find the full data set.
					LEVEL_DATASET * const psFoundData = levFindDataSet(pLevToken);

					if (psFoundData == NULL)
					{
						lev_error("Cannot find full data set for camchange");
						return false;
					}

					if (psFoundData->type != LDS_CAMSTART)
					{
						lev_error("Invalid data set name for cam change");
						return false;
					}
					psFoundData->psChange = psDataSet;
				}
				// store the level name
				psDataSet->pName = strdup(pLevToken);
				if (psDataSet->pName == NULL)
				{
					debug(LOG_FATAL, "Out of memory!");
					abort();
					return false;
				}

				state = LP_LEVELDONE;
			}
			else if (state == LP_DATASET)
			{
				// find the dataset
				psDataSet->psBaseData = levFindDataSet(pLevToken);

				if (psDataSet->psBaseData == NULL)
				{
					lev_error("Unknown dataset");
					return false;
				}
				state = LP_WAITDATA;
			}
			else
			{
				lev_error("Syntax Error");
				return false;
			}
			break;
		case LTK_STRING:
			if (state == LP_DATA || state == LP_GAME)
			{
				if (currData >= LEVEL_MAXFILES)
				{
					lev_error("Too many data files");
					return false;
				}

				// note the game index if necessary
				if (state == LP_GAME)
				{
					psDataSet->game = (SWORD)currData;
				}
				else if (ignoreWrf)
				{
					state = LP_WAITDATA;
					break;	// ignore this wrf line
				}

				// store the data name
				psDataSet->apDataFiles[currData] = strdup(pLevToken);
				if (psDataSet->apDataFiles[currData] == NULL)
				{
					debug(LOG_FATAL, "Out of memory!");
					abort();
					return false;
				}

				resToLower(pLevToken);

				currData += 1;
				state = LP_WAITDATA;
			}
			else
			{
				lev_error("Syntax Error");
				return false;
			}
			break;
		default:
			lev_error("Unexpected token");
			break;
		}
	}

	lev_lex_destroy();

	// Accept empty files when parsing (indicated by currData < 0)
	if (currData >= 0
	 && (state != LP_WAITDATA
	  || currData == 0))
	{
		lev_error("Unexpected end of file");
		return false;
	}

	return true;
}
Esempio n. 5
0
// ////////////////////////////////////////////////////////////////////////////
// options for a game. (usually recvd in frontend)
void recvOptions(NETQUEUE queue)
{
	unsigned int i;

	debug(LOG_NET, "Receiving options from host");
	NETbeginDecode(queue, NET_OPTIONS);

	// Get general information about the game
	NETuint8_t(&game.type);
	NETstring(game.map, 128);
	NETbin(game.hash.bytes, game.hash.Bytes);
	uint32_t modHashesSize;
	NETuint32_t(&modHashesSize);
	ASSERT_OR_RETURN(, modHashesSize < 1000000, "Way too many mods %u", modHashesSize);
	game.modHashes.resize(modHashesSize);
	for (auto &hash : game.modHashes)
	{
		NETbin(hash.bytes, hash.Bytes);
	}
	NETuint8_t(&game.maxPlayers);
	NETstring(game.name, 128);
	NETuint32_t(&game.power);
	NETuint8_t(&game.base);
	NETuint8_t(&game.alliance);
	NETbool(&game.scavengers);
	NETbool(&game.isMapMod);

	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]);
	}

	// Alliances
	for (i = 0; i < MAX_PLAYERS; i++)
	{
		unsigned int j;

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

	// Free any structure limits we may have in-place
	if (ingame.numStructureLimits)
	{
		ingame.numStructureLimits = 0;
		free(ingame.pStructureLimits);
		ingame.pStructureLimits = NULL;
	}

	// Get the number of structure limits to expect
	NETuint32_t(&ingame.numStructureLimits);
	debug(LOG_NET, "Host is sending us %u structure limits", ingame.numStructureLimits);
	// If there were any changes allocate memory for them
	if (ingame.numStructureLimits)
	{
		ingame.pStructureLimits = (MULTISTRUCTLIMITS *)malloc(ingame.numStructureLimits * sizeof(MULTISTRUCTLIMITS));
	}

	for (i = 0; i < ingame.numStructureLimits; i++)
	{
		NETuint32_t(&ingame.pStructureLimits[i].id);
		NETuint32_t(&ingame.pStructureLimits[i].limit);
	}
	NETuint8_t(&ingame.flags);

	NETend();

	// Do the skirmish slider settings if they are up
	for (i = 0; i < MAX_PLAYERS; i++)
	{
		if (widgGetFromID(psWScreen, MULTIOP_SKSLIDE + i))
		{
			widgSetSliderPos(psWScreen, MULTIOP_SKSLIDE + i, game.skDiff[i]);
		}
	}
	debug(LOG_INFO, "Rebuilding map list");
	// clear out the old level list.
	levShutDown();
	levInitialise();
	rebuildSearchPath(mod_multiplay, true);	// MUST rebuild search path for the new maps we just got!
	buildMapList();

	bool haveData = true;
	auto requestFile = [&haveData](Sha256 &hash, char const *filename) {
		if (std::any_of(NetPlay.wzFiles.begin(), NetPlay.wzFiles.end(), [&hash](WZFile const &file) { return file.hash == hash; }))
		{
			debug(LOG_INFO, "Already requested file, continue waiting.");
			haveData = false;
			return false;  // Downloading the file already
		}

		if (!PHYSFS_exists(filename))
		{
			debug(LOG_INFO, "Creating new file %s", filename);
		}
		else if (findHashOfFile(filename) != hash)
		{
			debug(LOG_INFO, "Overwriting old incomplete or corrupt file %s", filename);
		}
		else
		{
			return false;  // Have the file already.
		}

		NetPlay.wzFiles.emplace_back(PHYSFS_openWrite(filename), hash);

		// Request the map/mod from the host
		NETbeginEncode(NETnetQueue(NET_HOST_ONLY), NET_FILE_REQUESTED);
		NETbin(hash.bytes, hash.Bytes);
		NETend();

		haveData = false;
		return true;  // Starting download now.
	};

	LEVEL_DATASET *mapData = levFindDataSet(game.map, &game.hash);
	// See if we have the map or not
	if (mapData == nullptr)
	{
		char mapName[256];
		sstrcpy(mapName, game.map);
		removeWildcards(mapName);

		if (strlen(mapName) >= 3 && mapName[strlen(mapName) - 3] == '-' && mapName[strlen(mapName) - 2] == 'T' && unsigned(mapName[strlen(mapName) - 1] - '1') < 3)
		{
			mapName[strlen(mapName) - 3] = '\0';  // Cut off "-T1", "-T2" or "-T3".
		}
		char filename[256];
		ssprintf(filename, "maps/%dc-%s-%s.wz", game.maxPlayers, mapName, game.hash.toString().c_str());  // Wonder whether game.maxPlayers is initialised already?

		if (requestFile(game.hash, filename))
		{
			debug(LOG_INFO, "Map was not found, requesting map %s from host, type %d", game.map, game.isMapMod);
			addConsoleMessage("MAP REQUESTED!", DEFAULT_JUSTIFY, SYSTEM_MESSAGE);
		}
		else
		{
			debug(LOG_FATAL, "Can't load map %s, even though we downloaded %s", game.map, filename);
			abort();
		}
	}

	for (Sha256 &hash : game.modHashes)
	{
		char filename[256];
		ssprintf(filename, "mods/downloads/%s", hash.toString().c_str());

		if (requestFile(hash, filename))
		{
			debug(LOG_INFO, "Mod was not found, requesting mod %s from host", hash.toString().c_str());
			addConsoleMessage("MOD REQUESTED!", DEFAULT_JUSTIFY, SYSTEM_MESSAGE);
		}
	}

	if (mapData && CheckForMod(mapData->realFileName))
	{
		char const *str = game.isMapMod ?
			_("Warning, this is a map-mod, it could alter normal gameplay.") :
			_("Warning, HOST has altered the game code, and can't be trusted!");
		addConsoleMessage(str, DEFAULT_JUSTIFY, NOTIFY_MESSAGE);
		game.isMapMod = true;
	}

	if (mapData)
	{
		loadMapPreview(false);
	}
}
Esempio n. 6
0
// ////////////////////////////////////////////////////////////////////////////
// options for a game. (usually recvd in frontend)
void recvOptions(NETQUEUE queue)
{
    unsigned int i;

    debug(LOG_NET, "Receiving options from host");
    NETbeginDecode(queue, NET_OPTIONS);

    // Get general information about the game
    NETuint8_t(&game.type);
    NETstring(game.map, 128);
    NETbin(game.hash.bytes, game.hash.Bytes);
    NETuint8_t(&game.maxPlayers);
    NETstring(game.name, 128);
    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]);
    }

    // Alliances
    for (i = 0; i < MAX_PLAYERS; i++)
    {
        unsigned int j;

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

    // Free any structure limits we may have in-place
    if (ingame.numStructureLimits)
    {
        ingame.numStructureLimits = 0;
        free(ingame.pStructureLimits);
        ingame.pStructureLimits = NULL;
    }

    // Get the number of structure limits to expect
    NETuint32_t(&ingame.numStructureLimits);
    debug(LOG_NET, "Host is sending us %u structure limits", ingame.numStructureLimits);
    // If there were any changes allocate memory for them
    if (ingame.numStructureLimits)
    {
        ingame.pStructureLimits = (MULTISTRUCTLIMITS *)malloc(ingame.numStructureLimits * sizeof(MULTISTRUCTLIMITS));
    }

    for (i = 0; i < ingame.numStructureLimits; i++)
    {
        NETuint32_t(&ingame.pStructureLimits[i].id);
        NETuint32_t(&ingame.pStructureLimits[i].limit);
    }
    NETuint8_t(&ingame.flags);

    NETend();

    // Do the skirmish slider settings if they are up
    for (i = 0; i < MAX_PLAYERS; i++)
    {
        if (widgGetFromID(psWScreen, MULTIOP_SKSLIDE + i))
        {
            widgSetSliderPos(psWScreen, MULTIOP_SKSLIDE + i, game.skDiff[i]);
        }
    }
    debug(LOG_INFO, "Rebuilding map list");
    // clear out the old level list.
    levShutDown();
    levInitialise();
    setCurrentMap(NULL, 42);
    rebuildSearchPath(mod_multiplay, true);	// MUST rebuild search path for the new maps we just got!
    buildMapList();
    // See if we have the map or not
    if (levFindDataSet(game.map, &game.hash) == NULL)
    {
        uint32_t player = selectedPlayer;

        debug(LOG_INFO, "Map was not found, requesting map %s from host.", game.map);
        // Request the map from the host
        NETbeginEncode(NETnetQueue(NET_HOST_ONLY), NET_FILE_REQUESTED);
        NETuint32_t(&player);
        NETend();

        addConsoleMessage("MAP REQUESTED!", DEFAULT_JUSTIFY, SYSTEM_MESSAGE);
    }
    else
    {
        loadMapPreview(false);
    }
}
Esempio n. 7
0
/// default value load routine
bool scrValDefLoad(INTERP_VAL *psVal, WzConfig &ini)
{
	DROID			*psCDroid;
	SDWORD			index, members;
	UDWORD			id;
	LEVEL_DATASET	*psLevel;
	DROID_GROUP		*psGroup = NULL;

	switch ((unsigned)psVal->type)  // Unsigned cast to suppress compiler warnings due to enum abuse.
	{
	case ST_INTMESSAGE:
		if (ini.contains("data"))
		{
			psVal->v.oval = (void*)getViewData(ini.value("data").toString().toAscii().constData());
		}
		else
		{
			psVal->v.oval = NULL;
		}
		break;
	case ST_BASEOBJECT:
	case ST_DROID:
	case ST_STRUCTURE:
	case ST_FEATURE:
		if (ini.contains("data"))
		{
			psVal->v.oval = (void*)getBaseObjFromId(ini.value("data").toInt());
		}
		else
		{
			psVal->v.oval = NULL;
		}
		break;
	case ST_BASESTATS:
	case ST_COMPONENT:
		break;
	case ST_STRUCTURESTAT:
		index = 0;
		if (ini.contains("data"))
		{
			index = getStructStatFromName(ini.value("data").toString().toAscii().constData());
			if (index == -1)
			{
				debug( LOG_FATAL, "Could not find stat");
				index = 0;
			}
		}
		psVal->v.ival = index;
		break;
	case ST_FEATURESTAT:
		index = 0;
		if (ini.contains("data"))
		{
			index = getFeatureStatFromName(ini.value("data").toString().toAscii().constData());
			if (index == -1)
			{
				debug( LOG_FATAL, "Could not find stat");
				index = 0;
			}
		}
		psVal->v.ival = index;
		break;
	case ST_BODY:
		index = getCompFromResName(COMP_BODY, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find body component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_PROPULSION:
		index = getCompFromResName(COMP_PROPULSION, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find propulsion component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_ECM:
		index = getCompFromResName(COMP_ECM, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find ECM component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_SENSOR:
		index = getCompFromResName(COMP_SENSOR, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find sensor component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_CONSTRUCT:
		index = getCompFromResName(COMP_CONSTRUCT, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find constructor component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_WEAPON:
		index = getCompFromResName(COMP_WEAPON, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find weapon");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_REPAIR:
		index = getCompFromResName(COMP_REPAIRUNIT, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find repair component");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_BRAIN:
		index = getCompFromResName(COMP_BRAIN, ini.value("data").toString().toAscii().constData());
		if (index == -1)
		{
			debug(LOG_FATAL, "Could not find repair brain");
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_TEMPLATE:
		psVal->v.oval = NULL;
		if (ini.contains("data"))
		{
			// FIXME: Ugh. Find a better way to show full template info
			psVal->v.oval = (void*)IdToTemplate(ini.value("data").toInt(), ANYPLAYER);
			if ((DROID_TEMPLATE*)(psVal->v.oval) == NULL)
			{
				debug(LOG_FATAL, "Could not find template %d", ini.value("data").toInt());
			}
		}
		break;
	case ST_TEXTSTRING:
		psVal->v.sval = NULL;
		if (ini.contains("data"))
		{
			psVal->v.sval = strdup(ini.value("data").toString().toAscii().constData());
		}
		break;
	case ST_LEVEL:
		psVal->v.sval = NULL;
		if (ini.contains("data"))
		{
			psLevel = levFindDataSet(ini.value("data").toString().toAscii().constData());
			if (psLevel == NULL)
			{
				debug(LOG_FATAL, "Could not find level dataset");
			}
			psVal->v.sval = psLevel->pName;
		}
		break;
	case ST_RESEARCH:
		psVal->v.oval = NULL;
		if (ini.contains("data"))
		{
			QString research = ini.value("data").toString();
			if (!research.isEmpty())
			{
				psVal->v.oval = (void*)getResearch(research.toUtf8().constData());
				ASSERT_OR_RETURN(false, psVal->v.oval, "Could not find research %s", research.toUtf8().constData());
			}
		}
		break;
	case ST_GROUP:
		if (psVal->v.oval == NULL)
		{
			DROID_GROUP *tmp = grpCreate();
			tmp->add(NULL);
			psVal->v.oval = tmp;
		}
		psGroup = (DROID_GROUP *)(psVal->v.oval);
		members = ini.value("members", 0).toInt();
		if (psGroup && members > 0)
		{
			QStringList droids = ini.value("data").toStringList();

			// load the retreat data
			psGroup->sRunData.sPos = ini.vector2i("runpos");
			psGroup->sRunData.forceLevel = ini.value("forceLevel").toInt();
			psGroup->sRunData.leadership = ini.value("leadership").toInt();
			psGroup->sRunData.healthLevel = ini.value("healthLevel").toInt();

			// load the droids
			while (members > 0)
			{
				id = droids.takeLast().toInt();
				psCDroid = (DROID *)getBaseObjFromId(id);
				if (!psCDroid)
				{
					debug(LOG_ERROR, "Could not find object id %d", id);
				}
				else
				{
					((DROID_GROUP*)(psVal->v.oval))->add(psCDroid);
				}
				members--;
			}
		}
		break;
	case ST_SOUND:
		// find audio id

		// don't use sound if it's disabled
		if (audio_Disabled())
		{
			psVal->v.ival = NO_SOUND;
			break;
		}

		index = audio_GetTrackID(ini.value("data").toString().toAscii().constData());
		if (index == SAMPLE_NOT_FOUND)
		{
			// find empty id and set track vals
			QString soundname = ini.value("data").toString();
			index = audio_SetTrackVals(soundname.toAscii().constData(), false, 100, 1800);
			if (!index)			// this is a NON fatal error.
			{
				// We can't find filename of the sound for some reason.
				debug(LOG_ERROR, "Sound ID not available %s not found", soundname.toAscii().constData());
				break;
			}
		}
		psVal->v.ival = index;
		break;
	case ST_STRUCTUREID:
	case ST_DROIDID:
	default:
		// just set the contents directly
		psVal->v.ival = ini.value("data").toInt();
		break;
	}

	return true;
}
Esempio n. 8
0
/// default value load routine
bool scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size)
{
	char			*pPos;
	DROID			*psCDroid;
	SDWORD			index, members, savedMembers;
	UDWORD			id;
	LEVEL_DATASET	*psLevel;
	DROID_GROUP		*psGroup = NULL;
	const char              *pName;
	bool			bObjectDefined;

	switch ((unsigned)psVal->type)  // Unsigned cast to suppress compiler warnings due to enum abuse.
	{
	case ST_INTMESSAGE:
		if ((size == 1) &&
			(*pBuffer == 0))
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)getViewData(pBuffer);
			if (psVal->v.oval == NULL)
			{
				return false;
			}
		}
		break;
	case ST_BASEOBJECT:
	case ST_DROID:
	case ST_STRUCTURE:
	case ST_FEATURE:
		id = *((UDWORD *)pBuffer);
		endian_udword(&id);

		if (id == UDWORD_MAX)
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)getBaseObjFromId(id);
			if (!psVal->v.oval)
			{
				debug(LOG_ERROR, "Could not find object id %d", id);
			}
		}
		break;
	case ST_BASESTATS:
	case ST_COMPONENT:
		break;
	case ST_STRUCTURESTAT:
		index = getStructStatFromName(pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find structure stat %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_FEATURESTAT:
		index = getFeatureStatFromName(pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find feature stat %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_BODY:
		index = getCompFromResName(COMP_BODY, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find body component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_PROPULSION:
		index = getCompFromResName(COMP_PROPULSION, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find propulsion component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_ECM:
		index = getCompFromResName(COMP_ECM, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find ECM component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_SENSOR:
		index = getCompFromResName(COMP_SENSOR, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find sensor component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_CONSTRUCT:
		index = getCompFromResName(COMP_CONSTRUCT, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find constructor component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_WEAPON:
		index = getCompFromResName(COMP_WEAPON, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find weapon %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_REPAIR:
		index = getCompFromResName(COMP_REPAIRUNIT, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find repair component %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_BRAIN:
		index = getCompFromResName(COMP_BRAIN, pBuffer);
		if (index == -1)
		{
			debug( LOG_FATAL, "scrValDefLoad: couldn't find repair brain %s", pBuffer );
			abort();
			index = 0;
		}
		psVal->v.ival = index;
		break;
	case ST_TEMPLATE:
		id = *((UDWORD *)pBuffer);
		endian_udword(&id);

		if (id == UDWORD_MAX)
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)IdToTemplate(id, ANYPLAYER);
			if ((DROID_TEMPLATE*)(psVal->v.oval) == NULL)
			{
				debug( LOG_FATAL, "scrValDefLoad: couldn't find template id %d", id );
				abort();
			}
		}
		break;
	case ST_TEXTSTRING:
		{
			const char* str;
			char* idStr;
			uint16_t len;

			if (size < sizeof(len))
			{
				debug(LOG_ERROR, "Data size is too small, %u is expected, but %u is provided", (unsigned int)(sizeof(len)), (unsigned int)size);
				return false;
			}

			len = *((uint16_t*)pBuffer);
			endian_uword(&len);

			if (size < sizeof(len) + len)
			{
				debug(LOG_ERROR, "Data size is too small, %u is expected, but %u is provided", (unsigned int)(sizeof(len) + len), (unsigned int)size);
				return false;
			}

			if (len == 0)
			{
				psVal->v.sval = NULL;
				return true;
			}

			idStr = (char *)malloc(len);
			if (!idStr)
			{
				debug(LOG_ERROR, "Out of memory (tried to allocate %u bytes)", (unsigned int)len);
				// Don't abort() here, as this might be the result from a bad "len" field in the data
				return false;
			}

			memcpy(idStr, pBuffer + sizeof(len), len);

			if (idStr[len - 1] != '\0')
			{
				debug(LOG_WARNING, "Non-NUL terminated string encountered!");
			}
			idStr[len - 1] = '\0';

			str = strresGetString(psStringRes, idStr);
			if (!str)
			{
				debug(LOG_ERROR, "Couldn't find string with id \"%s\"", idStr);
				free(idStr);
				return false;
			}
			free(idStr);

			psVal->v.sval = strdup(str);
			if (!psVal->v.sval)
			{
				debug(LOG_FATAL, "Out of memory");
				abort();
				return false;
			}
		}
		break;
	case ST_LEVEL:
		if ((size == 1) &&
			(*pBuffer == 0))
		{
			psVal->v.sval = '\0';
		}
		else
		{
			psLevel = levFindDataSet(pBuffer);
			if (psLevel == NULL)
			{
				debug( LOG_FATAL, "scrValDefLoad: couldn't find level dataset %s", pBuffer );
				abort();
			}
			psVal->v.sval = psLevel->pName;
		}
		break;
	case ST_RESEARCH:
		if ((size == 1) &&
			(*pBuffer == 0))
		{
			psVal->v.oval = NULL;
		}
		else
		{
			psVal->v.oval = (void*)getResearch(pBuffer);
			if (psVal->v.oval == NULL)
			{
				debug( LOG_FATAL, "scrValDefLoad: couldn't find research %s", pBuffer );
				abort();
			}
		}
		break;
	case ST_GROUP:
		bObjectDefined = true;

		if (psVal->v.oval == NULL)
		{
			DROID_GROUP *tmp = grpCreate();
			tmp->add(NULL);
			psVal->v.oval = tmp;
		}

		pPos = pBuffer;

		if (version < 2)
		{
			members = size / sizeof(UDWORD);
		}
		else if (version < 3)
		{
			members = (size - sizeof(SDWORD)*4) / sizeof(UDWORD);
		}
		else
		{
			members = (size - sizeof(SDWORD)*6) / sizeof(UDWORD);

			// get saved group member count/nullpointer flag
			endian_sdword((SDWORD*)pPos);
			bObjectDefined = ( *((SDWORD *)pPos) != UNALLOCATED_OBJECT );

			if(bObjectDefined)
			{
				savedMembers = *((SDWORD *)pPos);	// get number of saved group members

				ASSERT(savedMembers == members, "scrValDefLoad: calculated and saved group member count did not match." );
			}
			pPos += sizeof(SDWORD);
		}

		// make sure group was allocated when it was saved (relevant starting from version 3)
		if( version < 3 || bObjectDefined )
		{
			if (version >= 2)
			{
				// load the retreat data
				psGroup = (DROID_GROUP*)(psVal->v.oval);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.sPos.x = *((SDWORD *)pPos);
				pPos += sizeof(SDWORD);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.sPos.y = *((SDWORD *)pPos);
				pPos += sizeof(SDWORD);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.forceLevel = (UBYTE)(*((SDWORD *)pPos));
				pPos += sizeof(SDWORD);
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.leadership = (UBYTE)(*((SDWORD *)pPos));
				pPos += sizeof(SDWORD);
			}
			if (version >= 3)
			{
				endian_sdword((SDWORD*)pPos);
				psGroup->sRunData.healthLevel = (UBYTE)(*((SDWORD *)pPos));
				pPos += sizeof(SDWORD);
			}

			// load the droids
			while (members > 0)
			{
				endian_udword((UDWORD*)pPos);
				id = *((UDWORD *) pPos);
				psCDroid = (DROID *)getBaseObjFromId(id);
				if (!psCDroid)
				{
					debug(LOG_ERROR, "Could not find object id %d", id);
				}
				else
				{
					((DROID_GROUP*)(psVal->v.oval))->add(psCDroid);
				}

				pPos += sizeof(UDWORD);
				members -= 1;
			}
		}
		else		// a group var was unallocated during saving
		{
			pPos += sizeof(UWORD);
		}
		break;
	case ST_SOUND:
		// find audio id

		// don't use sound if it's disabled
		if (audio_Disabled())
		{
			psVal->v.ival = NO_SOUND;
			break;
		}

		pName = pBuffer;
		index = audio_GetTrackID( pName );
		if (index == SAMPLE_NOT_FOUND)
		{
			// find empty id and set track vals
			index = audio_SetTrackVals(pName, false, 100, 1800);
			if (!index)			//this is a NON fatal error.
			{
				// We can't find filename of the sound for some reason.
				debug(LOG_ERROR, "Sound ID not available %s not found", pName);
				break;
			}
		}
		psVal->v.ival = index;
		break;
	case ST_STRUCTUREID:
	case ST_DROIDID:
	default:
		// just set the contents directly
		psVal->v.ival = *((SDWORD *)pBuffer);
		endian_sdword(&psVal->v.ival);
		break;
	}

	return true;
}