Ejemplo n.º 1
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);
	}
}
Ejemplo n.º 2
0
void MOD_SelectModMenu(char *basedir){

	SceCtrlData pad, oldpad;
	sceCtrlPeekBufferPositive(0, &pad, 1);

	// Ch0wW: Enable the mod menu once the R trigger is hold on startup.
	if (!(pad.buttons & SCE_CTRL_RTRIGGER))
	{
		// Reading current used mod
		char cur_mod[64];
		modname = malloc(64);
		FILE* f;
		if ((f = fopen( va("%s/%s", basedir, MOD_FILE), "r")) != NULL) {
			char tmp[256];
			fseek(f, 0, SEEK_END);
			int len = ftell(f);
			fseek(f, 0, SEEK_SET);
			fread(tmp, 1, len, f);
			fclose(f);
			tmp[len] = 0;
			sprintf(modname, "%s", tmp);
		}
		else
			modname = NULL;
		return;
	}

	// Initializing empty ModList
	ModsList* mods = NULL;
	int i = 0;
	int max_idx = -1;
	
	// Scanning main folder in search of mods
	int dd = sceIoDopen(basedir);
	SceIoDirent entry;
	int res;
	while (sceIoDread(dd, &entry) > 0){
		if (SCE_S_ISDIR(entry.d_stat.st_mode)){
			if (CheckForMod( va("%s/%s", basedir, entry.d_name))){
				mods = addMod(entry.d_name, mods);
				max_idx++;
			}
		}
	}
	sceIoDclose(dd);
	
	// Reading current used mod
	char cur_mod[64];
	modname = malloc(64);
	FILE* f;
	if ((f = fopen(va("%s/%s", basedir, MOD_FILE), "r")) != NULL) {
		char tmp[256];
		fseek(f, 0, SEEK_END);
		int len = ftell(f);
		fseek(f, 0, SEEK_SET);
		fread(tmp, 1, len, f);
		fclose(f);
		tmp[len] = 0;
		sprintf(modname, "%s", tmp);
		sprintf(cur_mod, "Current in use mod: %s - Press START to launch vitaQuake core", tmp);
	}else strcpy(cur_mod,"Current in use mod: id1 - Press START to launch vitaQuake core");
	
	// Initializing graphics stuffs
	vita2d_set_clear_color(RGBA8(0x00, 0x00, 0x00, 0xFF));
	vita2d_pgf* debug_font = vita2d_load_default_pgf();
	uint32_t white = RGBA8(0xFF, 0xFF, 0xFF, 0xFF);
	uint32_t green = RGBA8(0x00, 0xFF, 0x00, 0xFF);
	uint32_t red = RGBA8(0xFF, 0x00, 0x00, 0xFF);
	
	// Main loop
	while (max_idx >= 0){
		vita2d_start_drawing();
		vita2d_clear_screen();
		vita2d_pgf_draw_text(debug_font, 2, 20, red, 1.0, cur_mod);
		
		// Drawing menu
		int y = 40;
		int d = 0;
		ModsList* ptr = mods;
		while (ptr != NULL && y < 540){
			uint32_t color = white;
			if (d++ == i) color = green;
			vita2d_pgf_draw_text(debug_font, 2, y, color, 1.0, ptr->name);
			ptr = ptr->next;
			y += 20;
		}
		
		// Controls checking
		sceCtrlPeekBufferPositive(0, &pad, 1);
		if ((pad.buttons & SCE_CTRL_CROSS) && (!(oldpad.buttons & SCE_CTRL_CROSS))){
			int z = 0;
			ModsList* tmp = mods;
			while (z < i){
				tmp = tmp->next;
				z++;
			}
			sprintf(cur_mod,"Current in use mod: %s - Press START to launch vitaQuake core", tmp->name);
			if (!strcmp(tmp->name, "id1"))
			{
				sceIoRemove( va("%s/%s", basedir, MOD_FILE) );
				modname = NULL;
			}
			else{
				f = fopen(va("%s/%s", basedir, MOD_FILE), "w");
				fwrite(tmp->name,1,strlen(tmp->name),f);
				fclose(f);
				strcpy(modname, tmp->name);	// Refresh the mod directory.
			}
		}else if ((pad.buttons & SCE_CTRL_UP) && (!(oldpad.buttons & SCE_CTRL_UP))){
			i--;
			if (i < 0) i = max_idx;
		}else if ((pad.buttons & SCE_CTRL_DOWN) && (!(oldpad.buttons & SCE_CTRL_DOWN))){
			i++;
			if (i > max_idx) i = 0;
		}else if (pad.buttons & SCE_CTRL_START) break;
		oldpad = pad;
		
		vita2d_end_drawing();
		vita2d_wait_rendering_done();
		vita2d_swap_buffers();
	}
	
	// Freeing stuffs
	ModsList* tmp = mods;
	ModsList* tmp2;
	while (tmp != NULL){
		tmp2 = tmp->next;
		free(tmp);
		tmp = tmp2;
	}

	return;
}