Esempio n. 1
0
static void InitVfs(const CmdLineArgs& args)
{
	TIMER(L"InitVfs");

	const Paths paths(args);

	OsPath logs(paths.Logs());
	CreateDirectories(logs, 0700);

	psSetLogDir(logs);
	// desired location for crashlog is now known. update AppHooks ASAP
	// (particularly before the following error-prone operations):
	AppHooks hooks = {0};
	hooks.bundle_logs = psBundleLogs;
	hooks.get_log_dir = psLogDir;
	hooks.display_error = psDisplayError;
	app_hooks_update(&hooks);

	const size_t cacheSize = ChooseCacheSize();
	g_VFS = CreateVfs(cacheSize);

	std::vector<CStr> mods = args.GetMultiple("mod");
	mods.insert(mods.begin(), "public");

	if (!args.Has("noUserMod"))
		mods.push_back("user");

	OsPath modPath = paths.RData()/"mods";
	OsPath modUserPath = paths.UserData()/"mods";
	for (size_t i = 0; i < mods.size(); ++i)
	{
		size_t priority = i+1;	// mods are higher priority than regular mountings, which default to priority 0
		size_t flags = VFS_MOUNT_WATCH|VFS_MOUNT_ARCHIVABLE|VFS_MOUNT_MUST_EXIST;
		OsPath modName(mods[i]);
		g_VFS->Mount(L"", modPath / modName/"", flags, priority);
		g_VFS->Mount(L"", modUserPath / modName/"", flags, priority);
	}

	// We mount these dirs last as otherwise writing could result in files being placed in a mod's dir.
	g_VFS->Mount(L"screenshots/", paths.UserData()/"screenshots"/"");
	g_VFS->Mount(L"saves/", paths.UserData()/"saves"/"", VFS_MOUNT_WATCH);
	const OsPath readonlyConfig = paths.RData()/"config"/"";
	// Mounting with highest priority, so that a mod supplied user.cfg is harmless
	g_VFS->Mount(L"config/", readonlyConfig, 0, (size_t)-1);
	if(readonlyConfig != paths.Config())
		g_VFS->Mount(L"config/", paths.Config(), 0, (size_t)-1);

	g_VFS->Mount(L"cache/", paths.Cache(), VFS_MOUNT_ARCHIVABLE);	// (adding XMBs to archive speeds up subsequent reads)

	// note: don't bother with g_VFS->TextRepresentation - directories
	// haven't yet been populated and are empty.
}
Esempio n. 2
0
CArchiveBuilder::CArchiveBuilder(const OsPath& mod, const OsPath& tempdir) :
	m_TempDir(tempdir)
{
	m_VFS = CreateVfs(20*MiB);

	DeleteDirectory(m_TempDir/"_archivecache"); // clean up in case the last run failed

	m_VFS->Mount(L"cache/", m_TempDir/"_archivecache"/"");

	m_VFS->Mount(L"", mod/"", VFS_MOUNT_MUST_EXIST | VFS_MOUNT_KEEP_DELETED);

	// Collect the list of files before loading any base mods
	vfs::ForEachFile(m_VFS, L"", &CollectFileCB, (uintptr_t)static_cast<void*>(this), 0, vfs::DIR_RECURSIVE);
}
Esempio n. 3
0
static void InitVfs(const CmdLineArgs& args, int flags)
{
	TIMER(L"InitVfs");

	const bool setup_error = (flags & INIT_HAVE_DISPLAY_ERROR) == 0;

	const Paths paths(args);

	OsPath logs(paths.Logs());
	CreateDirectories(logs, 0700);

	psSetLogDir(logs);
	// desired location for crashlog is now known. update AppHooks ASAP
	// (particularly before the following error-prone operations):
	AppHooks hooks = {0};
	hooks.bundle_logs = psBundleLogs;
	hooks.get_log_dir = psLogDir;
	if (setup_error)
		hooks.display_error = psDisplayError;
	app_hooks_update(&hooks);

	const size_t cacheSize = ChooseCacheSize();
	g_VFS = CreateVfs(cacheSize);
	
	const OsPath readonlyConfig = paths.RData()/"config"/"";
	g_VFS->Mount(L"config/", readonlyConfig);

	// Engine localization files.
	g_VFS->Mount(L"l10n/", paths.RData()/"l10n"/"");

	MountMods(paths, GetMods(args, flags));

	// We mount these dirs last as otherwise writing could result in files being placed in a mod's dir.
	g_VFS->Mount(L"screenshots/", paths.UserData()/"screenshots"/"");
	g_VFS->Mount(L"saves/", paths.UserData()/"saves"/"", VFS_MOUNT_WATCH);
	// Mounting with highest priority, so that a mod supplied user.cfg is harmless
	g_VFS->Mount(L"config/", readonlyConfig, 0, (size_t)-1);
	if(readonlyConfig != paths.Config())
		g_VFS->Mount(L"config/", paths.Config(), 0, (size_t)-1);

	g_VFS->Mount(L"cache/", paths.Cache(), VFS_MOUNT_ARCHIVABLE);	// (adding XMBs to archive speeds up subsequent reads)

	// note: don't bother with g_VFS->TextRepresentation - directories
	// haven't yet been populated and are empty.
}
Esempio n. 4
0
// moved into a helper function to ensure args is destroyed before
// exit(), which may result in a memory leak.
static void RunGameOrAtlas(int argc, const char* argv[])
{
	CmdLineArgs args(argc, argv);

	// We need to initialise libxml2 in the main thread before
	// any thread uses it. So initialise it here before we
	// might run Atlas.
	CXeromyces::Startup();

	// run Atlas (if requested via args)
	bool ran_atlas = ATLAS_RunIfOnCmdLine(args, false);
	// Atlas handles the whole init/shutdown/etc sequence by itself;
	// when we get here, it has exited and we're done.
	if(ran_atlas)
		return;

	// run non-visual simulation replay if requested
	if (args.Has("replay"))
	{
		// TODO: Support mods
		Paths paths(args);
		g_VFS = CreateVfs(20 * MiB);
		g_VFS->Mount(L"cache/", paths.Cache(), VFS_MOUNT_ARCHIVABLE);
		g_VFS->Mount(L"", paths.RData()/"mods"/"public", VFS_MOUNT_MUST_EXIST);

		{
			CReplayPlayer replay;
			replay.Load(args.Get("replay"));
			replay.Replay();
		}

		g_VFS.reset();

		CXeromyces::Terminate();
		return;
	}

	// run in archive-building mode if requested
	if (args.Has("archivebuild"))
	{
		Paths paths(args);

		OsPath mod(args.Get("archivebuild"));
		OsPath zip;
		if (args.Has("archivebuild-output"))
			zip = args.Get("archivebuild-output");
		else
			zip = mod.Filename().ChangeExtension(L".zip");

		CArchiveBuilder builder(mod, paths.Cache());
		builder.Build(zip, args.Has("archivebuild-compress"));

		CXeromyces::Terminate();
		return;
	}

	const double res = timer_Resolution();
	g_frequencyFilter = CreateFrequencyFilter(res, 30.0);

	// run the game
	Init(args, 0);
	InitGraphics(args, 0);
	MainControllerInit();
	while(!quit)
		Frame();
	Shutdown(0);
	MainControllerShutdown();

	if (restart_in_atlas)
	{
		ATLAS_RunIfOnCmdLine(args, true);
		return;
	}

	// Shut down libxml2 (done here to match the Startup call)
	CXeromyces::Terminate();
}
Esempio n. 5
0
/**
 * Returns a JS object containing a listing of available mods that
 * have a modname.json file in their modname folder. The returned
 * object looks like { modname1: json1, modname2: json2, ... } where
 * jsonN is the content of the modnameN/modnameN.json file as a JS
 * object.
 *
 * @return JS object with available mods as the keys of the modname.json
 *         properties.
 */
JS::Value JSI_Mod::GetAvailableMods(ScriptInterface::CxPrivate* pCxPrivate)
{
	ScriptInterface* scriptInterface = pCxPrivate->pScriptInterface;
	JSContext* cx = scriptInterface->GetContext();
	JSAutoRequest rq(cx);
	JS::RootedObject obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));

	const Paths paths(g_args);

	// loop over all possible paths
	OsPath modPath = paths.RData()/"mods";
	OsPath modUserPath = paths.UserData()/"mods";

	DirectoryNames modDirs;
	DirectoryNames modDirsUser;

	GetDirectoryEntries(modPath, NULL, &modDirs);
	// Sort modDirs so that we can do a fast lookup below
	std::sort(modDirs.begin(), modDirs.end());

	PIVFS vfs = CreateVfs(1); // No cache needed; TODO but 0 crashes

	for (DirectoryNames::iterator iter = modDirs.begin(); iter != modDirs.end(); ++iter)
	{
		vfs->Clear();
		if (vfs->Mount(L"", modPath / *iter, VFS_MOUNT_MUST_EXIST) < 0)
			continue;

		CVFSFile modinfo;
		if (modinfo.Load(vfs, L"mod.json", false) != PSRETURN_OK)
			continue;

		JS::RootedValue json(cx);
		if (!scriptInterface->ParseJSON(modinfo.GetAsString(), &json))
			continue;

		// Valid mod, add it to our structure
		JS_SetProperty(cx, obj, utf8_from_wstring(iter->string()).c_str(), json);
	}

	GetDirectoryEntries(modUserPath, NULL, &modDirsUser);
	bool dev = InDevelopmentCopy();

	for (DirectoryNames::iterator iter = modDirsUser.begin(); iter != modDirsUser.end(); ++iter)
	{
		// If we are in a dev copy we do not mount mods in the user mod folder that
		// are already present in the mod folder, thus we skip those here.
		if (dev && std::binary_search(modDirs.begin(), modDirs.end(), *iter))
			continue;

		vfs->Clear();
		if (vfs->Mount(L"", modUserPath / *iter, VFS_MOUNT_MUST_EXIST) < 0)
			continue;

		CVFSFile modinfo;
		if (modinfo.Load(vfs, L"mod.json", false) != PSRETURN_OK)
			continue;

		JS::RootedValue json(cx);
		if (!scriptInterface->ParseJSON(modinfo.GetAsString(), &json))
			continue;

		// Valid mod, add it to our structure
		JS_SetProperty(cx, obj, utf8_from_wstring(iter->string()).c_str(), json);
	}

	return JS::ObjectValue(*obj);
}
Esempio n. 6
0
static void InitVfs(const CmdLineArgs& args, int flags)
{
	TIMER(L"InitVfs");

	const bool setup_error = (flags & INIT_HAVE_DISPLAY_ERROR) == 0;

	const Paths paths(args);

	OsPath logs(paths.Logs());
	CreateDirectories(logs, 0700);

	psSetLogDir(logs);
	// desired location for crashlog is now known. update AppHooks ASAP
	// (particularly before the following error-prone operations):
	AppHooks hooks = {0};
	hooks.bundle_logs = psBundleLogs;
	hooks.get_log_dir = psLogDir;
	if (setup_error)
		hooks.display_error = psDisplayError;
	app_hooks_update(&hooks);

	const size_t cacheSize = ChooseCacheSize();
	g_VFS = CreateVfs(cacheSize);
	
	// Work out whether we are a dev version to make sure saved files
	// (maps, etc) end up in version control.
	const OsPath readonlyConfig = paths.RData()/"config"/"";
	g_VFS->Mount(L"config/", readonlyConfig);
	bool dev = (g_VFS->GetFileInfo(L"config/dev.cfg", NULL) == INFO::OK);

	const std::vector<CStr> mods = GetMods(args, dev);

	OsPath modPath = paths.RData()/"mods";
	OsPath modUserPath = paths.UserData()/"mods";
	for (size_t i = 0; i < mods.size(); ++i)
	{
		size_t priority = (i+1)*2;	// mods are higher priority than regular mountings, which default to priority 0
		size_t userFlags = VFS_MOUNT_WATCH|VFS_MOUNT_ARCHIVABLE|VFS_MOUNT_REPLACEABLE;
		size_t baseFlags = userFlags|VFS_MOUNT_MUST_EXIST;
		
		OsPath modName(mods[i]);
		if (dev)
		{
			// We are running a dev copy, so only mount mods in the user mod path
			// if the mod does not exist in the data path.
			if (DirectoryExists(modPath / modName/""))
				g_VFS->Mount(L"", modPath / modName/"", baseFlags, priority);
			else
				g_VFS->Mount(L"", modUserPath / modName/"", userFlags, priority);
		}
		else
		{
			g_VFS->Mount(L"", modPath / modName/"", baseFlags, priority);
			// Ensure that user modified files are loaded, if they are present
			g_VFS->Mount(L"", modUserPath / modName/"", userFlags, priority+1);
		}
	}

	// We mount these dirs last as otherwise writing could result in files being placed in a mod's dir.
	g_VFS->Mount(L"screenshots/", paths.UserData()/"screenshots"/"");
	g_VFS->Mount(L"saves/", paths.UserData()/"saves"/"", VFS_MOUNT_WATCH);
	// Mounting with highest priority, so that a mod supplied user.cfg is harmless
	g_VFS->Mount(L"config/", readonlyConfig, 0, (size_t)-1);
	if(readonlyConfig != paths.Config())
		g_VFS->Mount(L"config/", paths.Config(), 0, (size_t)-1);

	g_VFS->Mount(L"cache/", paths.Cache(), VFS_MOUNT_ARCHIVABLE);	// (adding XMBs to archive speeds up subsequent reads)

	// note: don't bother with g_VFS->TextRepresentation - directories
	// haven't yet been populated and are empty.
}
Esempio n. 7
0
File: main.cpp Progetto: 2asoft/0ad
// moved into a helper function to ensure args is destroyed before
// exit(), which may result in a memory leak.
static void RunGameOrAtlas(int argc, const char* argv[])
{
	CmdLineArgs args(argc, argv);

	g_args = args;

	if (args.Has("version") || args.Has("-version"))
	{
		debug_printf("Pyrogenesis %s\n", engine_version);
		return;
	}

	const bool isVisualReplay = args.Has("replay-visual");
	const bool isNonVisualReplay = args.Has("replay");

	const CStr replayFile =
		isVisualReplay ? args.Get("replay-visual") :
		isNonVisualReplay ? args.Get("replay") : "";

	if (isVisualReplay || isNonVisualReplay)
	{
		if (!FileExists(OsPath(replayFile)))
		{
			debug_printf("ERROR: The requested replay file '%s' does not exist!\n", replayFile.c_str());
			return;
		}
		if (DirectoryExists(OsPath(replayFile)))
		{
			debug_printf("ERROR: The requested replay file '%s' is a directory!\n", replayFile.c_str());
			return;
		}
	}

	// We need to initialize SpiderMonkey and libxml2 in the main thread before
	// any thread uses them. So initialize them here before we might run Atlas.
	ScriptEngine scriptEngine;
	CXeromyces::Startup();

	if (ATLAS_RunIfOnCmdLine(args, false))
	{
		CXeromyces::Terminate();
		return;
	}

	if (isNonVisualReplay)
	{
		if (!args.Has("mod"))
		{
			LOGERROR("At least one mod should be specified! Did you mean to add the argument '-mod=public'?");
			CXeromyces::Terminate();
			return;
		}

		Paths paths(args);
		g_VFS = CreateVfs(20 * MiB);
		g_VFS->Mount(L"cache/", paths.Cache(), VFS_MOUNT_ARCHIVABLE);
		MountMods(paths, GetMods(args, INIT_MODS));

		{
			CReplayPlayer replay;
			replay.Load(replayFile);
			replay.Replay(
				args.Has("serializationtest"),
				args.Has("rejointest") ? args.Get("rejointest").ToInt() : -1,
				args.Has("ooslog"));
		}

		g_VFS.reset();

		CXeromyces::Terminate();
		return;
	}

	// run in archive-building mode if requested
	if (args.Has("archivebuild"))
	{
		Paths paths(args);

		OsPath mod(args.Get("archivebuild"));
		OsPath zip;
		if (args.Has("archivebuild-output"))
			zip = args.Get("archivebuild-output");
		else
			zip = mod.Filename().ChangeExtension(L".zip");

		CArchiveBuilder builder(mod, paths.Cache());

		// Add mods provided on the command line
		// NOTE: We do not handle mods in the user mod path here
		std::vector<CStr> mods = args.GetMultiple("mod");
		for (size_t i = 0; i < mods.size(); ++i)
			builder.AddBaseMod(paths.RData()/"mods"/mods[i]);

		builder.Build(zip, args.Has("archivebuild-compress"));

		CXeromyces::Terminate();
		return;
	}

	const double res = timer_Resolution();
	g_frequencyFilter = CreateFrequencyFilter(res, 30.0);

	// run the game
	int flags = INIT_MODS;
	do
	{
		restart = false;
		quit = false;
		if (!Init(args, flags))
		{
			flags &= ~INIT_MODS;
			Shutdown(SHUTDOWN_FROM_CONFIG);
			continue;
		}
		InitGraphics(args, 0);
		MainControllerInit();
		while (!quit)
			Frame();
		Shutdown(0);
		MainControllerShutdown();
		flags &= ~INIT_MODS;
	} while (restart);

	if (restart_in_atlas)
		ATLAS_RunIfOnCmdLine(args, true);

	CXeromyces::Terminate();
}
Esempio n. 8
0
// moved into a helper function to ensure args is destroyed before
// exit(), which may result in a memory leak.
static void RunGameOrAtlas(int argc, const char* argv[])
{
	CmdLineArgs args(argc, argv);

	g_args = args;

	// We need to initialise libxml2 in the main thread before
	// any thread uses it. So initialise it here before we
	// might run Atlas.
	CXeromyces::Startup();

	// run Atlas (if requested via args)
	bool ran_atlas = ATLAS_RunIfOnCmdLine(args, false);
	// Atlas handles the whole init/shutdown/etc sequence by itself;
	// when we get here, it has exited and we're done.
	if(ran_atlas)
		return;

	// run non-visual simulation replay if requested
	if (args.Has("replay"))
	{
		std::string replayFile = args.Get("replay");
		if (!FileExists(OsPath(replayFile)))
		{
			debug_printf("ERROR: The requested replay file '%s' does not exist!\n", replayFile.c_str());
			return;
		}
		Paths paths(args);
		g_VFS = CreateVfs(20 * MiB);
		g_VFS->Mount(L"cache/", paths.Cache(), VFS_MOUNT_ARCHIVABLE);
		MountMods(paths, GetMods(args, INIT_MODS));

		{
			CReplayPlayer replay;
			replay.Load(replayFile);
			replay.Replay(args.Has("serializationtest"), args.Has("ooslog"));
		}

		g_VFS.reset();

		CXeromyces::Terminate();
		return;
	}

	// If visual replay file does not exist, quit before starting the renderer
	if (args.Has("replay-visual"))
	{
		std::string replayFile = args.Get("replay-visual");
		if (!FileExists(OsPath(replayFile)))
		{
			debug_printf("ERROR: The requested replay file '%s' does not exist!\n", replayFile.c_str());
			return;
		}
	}

	// run in archive-building mode if requested
	if (args.Has("archivebuild"))
	{
		Paths paths(args);

		OsPath mod(args.Get("archivebuild"));
		OsPath zip;
		if (args.Has("archivebuild-output"))
			zip = args.Get("archivebuild-output");
		else
			zip = mod.Filename().ChangeExtension(L".zip");

		CArchiveBuilder builder(mod, paths.Cache());

		// Add mods provided on the command line
		// NOTE: We do not handle mods in the user mod path here
		std::vector<CStr> mods = args.GetMultiple("mod");
		for (size_t i = 0; i < mods.size(); ++i)
			builder.AddBaseMod(paths.RData()/"mods"/mods[i]);

		builder.Build(zip, args.Has("archivebuild-compress"));

		CXeromyces::Terminate();
		return;
	}

	const double res = timer_Resolution();
	g_frequencyFilter = CreateFrequencyFilter(res, 30.0);

	// run the game
	int flags = INIT_MODS;
	do
	{
		restart = false;
		quit = false;
		if (!Init(args, flags))
		{
			flags &= ~INIT_MODS;
			Shutdown(SHUTDOWN_FROM_CONFIG);
			continue;
		}
		InitGraphics(args, 0);
		MainControllerInit();
		while (!quit)
			Frame();
		Shutdown(0);
		MainControllerShutdown();
		flags &= ~INIT_MODS;
	} while (restart);

	if (restart_in_atlas)
	{
		ATLAS_RunIfOnCmdLine(args, true);
		return;
	}

	// Shut down libxml2 (done here to match the Startup call)
	CXeromyces::Terminate();
}