Ejemplo n.º 1
0
/*!
 * \brief Rebuilds the PHYSFS searchPath with mode specific subdirs
 *
 * Priority:
 * maps > mods > base > base.wz
 */
bool rebuildSearchPath( searchPathMode mode, bool force )
{
	static searchPathMode current_mode = mod_clean;
	static std::string current_current_map;
	wzSearchPath * curSearchPath = searchPathRegistry;
	char tmpstr[PATH_MAX] = "\0";

	if (mode != current_mode || (current_map != NULL? current_map : "") != current_current_map || force ||
	    (use_override_mods && strcmp(override_mod_list, getModList())))
	{
		if (mode != mod_clean)
		{
			rebuildSearchPath( mod_clean, false );
		}

		current_mode = mode;
		current_current_map = current_map != NULL? current_map : "";

		// Start at the lowest priority
		while( curSearchPath->lowerPriority )
			curSearchPath = curSearchPath->lowerPriority;

		switch ( mode )
		{
			case mod_clean:
				debug(LOG_WZ, "Cleaning up");
				clearLoadedMods();

				while( curSearchPath )
				{
#ifdef DEBUG
					debug(LOG_WZ, "Removing [%s] from search path", curSearchPath->path);
#endif // DEBUG
					// Remove maps and mods
					removeSubdirs( curSearchPath->path, "maps", NULL );
					removeSubdirs( curSearchPath->path, "mods/music", NULL );
					removeSubdirs( curSearchPath->path, "mods/global", NULL );
					removeSubdirs( curSearchPath->path, "mods/campaign", NULL );
					removeSubdirs( curSearchPath->path, "mods/multiplay", NULL );
					removeSubdirs( curSearchPath->path, "mods/autoload", NULL );

					// Remove multiplay patches
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "mp");
					PHYSFS_removeFromSearchPath( tmpstr );
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "mp.wz");
					PHYSFS_removeFromSearchPath( tmpstr );

					// Remove plain dir
					PHYSFS_removeFromSearchPath( curSearchPath->path );

					// Remove base files
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base");
					PHYSFS_removeFromSearchPath( tmpstr );
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base.wz");
					PHYSFS_removeFromSearchPath( tmpstr );

					// remove video search path as well
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "sequences.wz");
					PHYSFS_removeFromSearchPath( tmpstr );
					curSearchPath = curSearchPath->higherPriority;
				}
				break;
			case mod_campaign:
				debug(LOG_WZ, "*** Switching to campaign mods ***");
				clearLoadedMods();

				while (curSearchPath)
				{
					// make sure videos override included files
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "sequences.wz");
					PHYSFS_addToSearchPath(tmpstr, PHYSFS_APPEND);
					curSearchPath = curSearchPath->higherPriority;
				}
				curSearchPath = searchPathRegistry;
				while (curSearchPath->lowerPriority)
					curSearchPath = curSearchPath->lowerPriority;
				while( curSearchPath )
				{
#ifdef DEBUG
					debug(LOG_WZ, "Adding [%s] to search path", curSearchPath->path);
#endif // DEBUG
					// Add global and campaign mods
					PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND );

					addSubdirs( curSearchPath->path, "mods/music", PHYSFS_APPEND, NULL, false );
					addSubdirs( curSearchPath->path, "mods/global", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true );
					addSubdirs( curSearchPath->path, "mods", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true );
					addSubdirs( curSearchPath->path, "mods/autoload", PHYSFS_APPEND, use_override_mods?override_mods:NULL, true );
					addSubdirs( curSearchPath->path, "mods/campaign", PHYSFS_APPEND, use_override_mods?override_mods:campaign_mods, true );
					if (!PHYSFS_removeFromSearchPath( curSearchPath->path ))
					{
						debug(LOG_WZ, "* Failed to remove path %s again", curSearchPath->path);
					}

					// Add plain dir
					PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND );

					// Add base files
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base.wz");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );

					curSearchPath = curSearchPath->higherPriority;
				}
				break;
			case mod_multiplay:
				debug(LOG_WZ, "*** Switching to multiplay mods ***");
				clearLoadedMods();

				while (curSearchPath)
				{
					// make sure videos override included files
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "sequences.wz");
					PHYSFS_addToSearchPath(tmpstr, PHYSFS_APPEND);
					curSearchPath = curSearchPath->higherPriority;
				}
				// Add the selected map first, for mapmod support
				if (current_map != NULL)
				{
					std::string realPathAndDir = std::string(PHYSFS_getRealDir(current_map)) + current_map;
					PHYSFS_addToSearchPath(realPathAndDir.c_str(), PHYSFS_APPEND);
				}
				curSearchPath = searchPathRegistry;
				while (curSearchPath->lowerPriority)
					curSearchPath = curSearchPath->lowerPriority;
				while( curSearchPath )
				{
#ifdef DEBUG
					debug(LOG_WZ, "Adding [%s] to search path", curSearchPath->path);
#endif // DEBUG
					// Add global and multiplay mods
					PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND );
					addSubdirs( curSearchPath->path, "mods/music", PHYSFS_APPEND, NULL, false );
					addSubdirs( curSearchPath->path, "mods/global", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true );
					addSubdirs( curSearchPath->path, "mods", PHYSFS_APPEND, use_override_mods?override_mods:global_mods, true );
					addSubdirs( curSearchPath->path, "mods/autoload", PHYSFS_APPEND, use_override_mods?override_mods:NULL, true );
					addSubdirs( curSearchPath->path, "mods/multiplay", PHYSFS_APPEND, use_override_mods?override_mods:multiplay_mods, true );
					PHYSFS_removeFromSearchPath( curSearchPath->path );

					// Add multiplay patches
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "mp");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "mp.wz");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );

					// Add plain dir
					PHYSFS_addToSearchPath( curSearchPath->path, PHYSFS_APPEND );

					// Add base files
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );
					sstrcpy(tmpstr, curSearchPath->path);
					sstrcat(tmpstr, "base.wz");
					PHYSFS_addToSearchPath( tmpstr, PHYSFS_APPEND );

					curSearchPath = curSearchPath->higherPriority;
				}
				break;
			default:
				debug(LOG_ERROR, "Can't switch to unknown mods %i", mode);
				return false;
		}
		if (use_override_mods && mode != mod_clean)
		{
			if (strcmp(getModList(),override_mod_list))
			{
				debug(LOG_POPUP, _("The required mod could not be loaded: %s\n\nWarzone will try to load the game without it."), override_mod_list);
			}
			clearOverrideMods();
			current_mode = mod_override;
		}

		// User's home dir must be first so we allways see what we write
		PHYSFS_removeFromSearchPath(PHYSFS_getWriteDir());
		PHYSFS_addToSearchPath( PHYSFS_getWriteDir(), PHYSFS_PREPEND );

#ifdef DEBUG
		printSearchPath();
#endif // DEBUG
	}
	else if (use_override_mods)
	{
		// override mods are already the same as current mods, so no need to do anything
		clearOverrideMods();
	}
	return true;
}
Ejemplo n.º 2
0
/*!
 * \brief Rebuilds the PHYSFS searchPath with mode specific subdirs
 *
 * Priority:
 * maps > mods > base > base.wz
 */
bool rebuildSearchPath(searchPathMode mode, bool force, const char *current_map)
{
	static searchPathMode current_mode = mod_clean;
	static std::string current_current_map;
	wzSearchPath *curSearchPath = searchPathRegistry;
	char tmpstr[PATH_MAX] = "\0";

	if (mode != current_mode || (current_map != nullptr ? current_map : "") != current_current_map || force ||
	    (use_override_mods && override_mod_list != getModList()))
	{
		if (mode != mod_clean)
		{
			rebuildSearchPath(mod_clean, false);
		}

		current_mode = mode;
		current_current_map = current_map != nullptr ? current_map : "";

		// Start at the lowest priority
		while (curSearchPath->lowerPriority)
		{
			curSearchPath = curSearchPath->lowerPriority;
		}

		switch (mode)
		{
		case mod_clean:
			debug(LOG_WZ, "Cleaning up");
			clearLoadedMods();

			while (curSearchPath)
			{
#ifdef DEBUG
				debug(LOG_WZ, "Removing [%s] from search path", curSearchPath->path);
#endif // DEBUG
				// Remove maps and mods
				removeSubdirs(curSearchPath->path, "maps");
				removeSubdirs(curSearchPath->path, "mods/music");
				removeSubdirs(curSearchPath->path, "mods/global");
				removeSubdirs(curSearchPath->path, "mods");
				removeSubdirs(curSearchPath->path, "mods/autoload");
				removeSubdirs(curSearchPath->path, "mods/campaign");
				removeSubdirs(curSearchPath->path, "mods/multiplay");
				removeSubdirs(curSearchPath->path, "mods/downloads");

				// Remove multiplay patches
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "mp");
				WZ_PHYSFS_unmount(tmpstr);
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "mp.wz");
				WZ_PHYSFS_unmount(tmpstr);

				// Remove plain dir
				WZ_PHYSFS_unmount(curSearchPath->path);

				// Remove base files
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "base");
				WZ_PHYSFS_unmount(tmpstr);
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "base.wz");
				WZ_PHYSFS_unmount(tmpstr);

				// remove video search path as well
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "sequences.wz");
				WZ_PHYSFS_unmount(tmpstr);
				curSearchPath = curSearchPath->higherPriority;
			}
			break;
		case mod_campaign:
			debug(LOG_WZ, "*** Switching to campaign mods ***");
			clearLoadedMods();

			while (curSearchPath)
			{
				// make sure videos override included files
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "sequences.wz");
				PHYSFS_mount(tmpstr, NULL, PHYSFS_APPEND);
				curSearchPath = curSearchPath->higherPriority;
			}
			curSearchPath = searchPathRegistry;
			while (curSearchPath->lowerPriority)
			{
				curSearchPath = curSearchPath->lowerPriority;
			}
			while (curSearchPath)
			{
#ifdef DEBUG
				debug(LOG_WZ, "Adding [%s] to search path", curSearchPath->path);
#endif // DEBUG
				// Add global and campaign mods
				PHYSFS_mount(curSearchPath->path, NULL, PHYSFS_APPEND);

				addSubdirs(curSearchPath->path, "mods/music", PHYSFS_APPEND, nullptr, false);
				addSubdirs(curSearchPath->path, "mods/global", PHYSFS_APPEND, use_override_mods ? &override_mods : &global_mods, true);
				addSubdirs(curSearchPath->path, "mods", PHYSFS_APPEND, use_override_mods ? &override_mods : &global_mods, true);
				addSubdirs(curSearchPath->path, "mods/autoload", PHYSFS_APPEND, use_override_mods ? &override_mods : nullptr, true);
				addSubdirs(curSearchPath->path, "mods/campaign", PHYSFS_APPEND, use_override_mods ? &override_mods : &campaign_mods, true);
				if (!WZ_PHYSFS_unmount(curSearchPath->path))
				{
					debug(LOG_WZ, "* Failed to remove path %s again", curSearchPath->path);
				}

				// Add plain dir
				PHYSFS_mount(curSearchPath->path, NULL, PHYSFS_APPEND);

				// Add base files
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "base");
				PHYSFS_mount(tmpstr, NULL, PHYSFS_APPEND);
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "base.wz");
				PHYSFS_mount(tmpstr, NULL, PHYSFS_APPEND);

				curSearchPath = curSearchPath->higherPriority;
			}
			break;
		case mod_multiplay:
			debug(LOG_WZ, "*** Switching to multiplay mods ***");
			clearLoadedMods();

			while (curSearchPath)
			{
				// make sure videos override included files
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "sequences.wz");
				PHYSFS_mount(tmpstr, NULL, PHYSFS_APPEND);
				curSearchPath = curSearchPath->higherPriority;
			}
			// Add the selected map first, for mapmod support
			if (current_map != nullptr)
			{
				WzString realPathAndDir = WzString::fromUtf8(PHYSFS_getRealDir(current_map)) + current_map;
				realPathAndDir.replace("/", PHYSFS_getDirSeparator()); // Windows fix
				PHYSFS_mount(realPathAndDir.toUtf8().c_str(), NULL, PHYSFS_APPEND);
			}
			curSearchPath = searchPathRegistry;
			while (curSearchPath->lowerPriority)
			{
				curSearchPath = curSearchPath->lowerPriority;
			}
			while (curSearchPath)
			{
#ifdef DEBUG
				debug(LOG_WZ, "Adding [%s] to search path", curSearchPath->path);
#endif // DEBUG
				// Add global and multiplay mods
				PHYSFS_mount(curSearchPath->path, NULL, PHYSFS_APPEND);
				addSubdirs(curSearchPath->path, "mods/music", PHYSFS_APPEND, nullptr, false);
				if (NetPlay.isHost || !NetPlay.bComms)
				{
					addSubdirs(curSearchPath->path, "mods/global", PHYSFS_APPEND, use_override_mods ? &override_mods : &global_mods, true);
					addSubdirs(curSearchPath->path, "mods", PHYSFS_APPEND, use_override_mods ? &override_mods : &global_mods, true);
					addSubdirs(curSearchPath->path, "mods/autoload", PHYSFS_APPEND, use_override_mods ? &override_mods : nullptr, true);
					addSubdirs(curSearchPath->path, "mods/multiplay", PHYSFS_APPEND, use_override_mods ? &override_mods : &multiplay_mods, true);
				}
				else
				{
					std::vector<std::string> hashList;
					for (Sha256 &hash : game.modHashes)
					{
						hashList = {hash.toString()};
						addSubdirs(curSearchPath->path, "mods/downloads", PHYSFS_APPEND, &hashList, true);
					}
				}
				WZ_PHYSFS_unmount(curSearchPath->path);

				// Add multiplay patches
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "mp");
				PHYSFS_mount(tmpstr, NULL, PHYSFS_APPEND);
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "mp.wz");
				PHYSFS_mount(tmpstr, NULL, PHYSFS_APPEND);

				// Add plain dir
				PHYSFS_mount(curSearchPath->path, NULL, PHYSFS_APPEND);

				// Add base files
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "base");
				PHYSFS_mount(tmpstr, NULL, PHYSFS_APPEND);
				sstrcpy(tmpstr, curSearchPath->path);
				sstrcat(tmpstr, "base.wz");
				PHYSFS_mount(tmpstr, NULL, PHYSFS_APPEND);

				curSearchPath = curSearchPath->higherPriority;
			}
			break;
		default:
			debug(LOG_ERROR, "Can't switch to unknown mods %i", mode);
			return false;
		}
		if (use_override_mods && mode != mod_clean)
		{
			if (getModList() != override_mod_list)
			{
				debug(LOG_POPUP, _("The required mod could not be loaded: %s\n\nWarzone will try to load the game without it."), override_mod_list.c_str());
			}
			clearOverrideMods();
			current_mode = mod_override;
		}

		// User's home dir must be first so we always see what we write
		WZ_PHYSFS_unmount(PHYSFS_getWriteDir());
		PHYSFS_mount(PHYSFS_getWriteDir(), NULL, PHYSFS_PREPEND);

#ifdef DEBUG
		printSearchPath();
#endif // DEBUG
	}
	else if (use_override_mods)
	{
		// override mods are already the same as current mods, so no need to do anything
		clearOverrideMods();
	}
	return true;
}