private static Installation?FindGoGInstallation(ModData modData, IGeneration generation) { if (Platform.CurrentPlatform == PlatformType.Windows) { var prefixes = new[] { "HKEY_LOCAL_MACHINE\\Software\\", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\" }; foreach (var prefix in prefixes) { var installDir = Registry.GetValue($"{prefix}GOG.com\\Games\\{generation.GogAppId}", "path", null) as string; if (installDir == null) { continue; } Log.Write("debug", $"GoG version candidate: {installDir}"); var game = InstallationUtils.TryRegister(modData, installDir, generation); if (game != null) { return(game); } } Log.Write("debug", "GoG version not found"); } else { Log.Write("debug", "GoG version not supported on this platform"); } return(null); }
private static Installation?FindCdVersion(ModData modData, IGeneration generation) { foreach (var driveInfo in DriveInfo.GetDrives()) { if (driveInfo.DriveType != DriveType.CDRom || !driveInfo.IsReady) { continue; } var installDir = driveInfo.RootDirectory.FullName; Log.Write("debug", $"CD version candidate: {installDir}"); var game = InstallationUtils.TryRegister(modData, installDir, generation); if (game != null) { return(game); } } Log.Write("debug", "CD version not found"); return(null); }
private static Installation?FindSteamInstallation(ModData modData, IGeneration generation) { foreach (var steamDirectory in InstallationFinder.SteamDirectory()) { var manifestPath = Path.Combine(steamDirectory, "steamapps", $"appmanifest_{generation.SteamAppId}.acf"); if (!File.Exists(manifestPath)) { continue; } var data = InstallationFinder.ParseKeyValuesManifest(manifestPath); if (!data.TryGetValue("StateFlags", out var stateFlags) || stateFlags != "4") { continue; } if (!data.TryGetValue("installdir", out var installDir)) { continue; } installDir = Path.Combine(steamDirectory, "steamapps", "common", installDir); Log.Write("debug", $"Steam version candidate: {installDir}"); var game = InstallationUtils.TryRegister(modData, installDir, generation); if (game != null) { return(game); } } Log.Write("debug", "Steam version not found"); return(null); }
public Installation?TryRegister(string path) { var executablePath = path; // Xtreme GoG and Steam var executable = InstallationUtils.GetFile(executablePath, "kkndgame.exe"); if (executable == null) { // Xtreme CD executablePath = InstallationUtils.GetDirectory(path, "game"); if (executablePath == null) { // Dos CD executablePath = InstallationUtils.GetDirectory(path, "kknd"); if (executablePath == null) { return(null); } } executable = InstallationUtils.GetFile(executablePath, "kknd.exe"); if (executable == null) { return(null); } } Log.Write("debug", $"Detected installation: {path}"); var release = CryptoUtil.SHA1Hash(File.OpenRead(executable)); var isXtreme = true; switch (release) { case "d1f41d7129b6f377869f28b89f92c18f4977a48f": Log.Write("debug", "=> Krush, Kill 'N' Destroy Xtreme (Steam/GoG, English)"); break; case "6fb10d85739ef63b28831ada4cdfc159a950c5d2": Log.Write("debug", "=> Krush, Kill 'N' Destroy Xtreme (Disc, English)"); break; case "024e96860c504b462b24b9237d49bfe8de6eb8e0": Log.Write("debug", "=> Krush, Kill 'N' Destroy (Disc, English)"); isXtreme = false; path = executablePath; break; default: Log.Write("debug", "=> Unsupported game version"); return(null); } var levelsFolder = InstallationUtils.GetDirectory(path, "levels"); if (levelsFolder == null) { Log.Write("debug", "=> Missing folder: levels"); return(null); } var fmvFolder = InstallationUtils.GetDirectory(path, "fmv"); if (fmvFolder == null) { Log.Write("debug", "=> Missing folder: fmv"); return(null); } var graphicsFolder = InstallationUtils.GetDirectory(levelsFolder, "640"); if (graphicsFolder == null) { Log.Write("debug", "=> Missing folder: 640"); return(null); } // Required files. var files = new Dictionary <string, string> { { "sprites.lvl", graphicsFolder }, { "surv.slv", levelsFolder }, { "mute.slv", levelsFolder }, { "mh_fmv.vbc", fmvFolder }, { "intro.vbc", fmvFolder } }.Concat( isXtreme ? new() { { "surv1.wav", levelsFolder }, { "surv2.wav", levelsFolder },
public Installation?TryRegister(string path) { var executablePath = path; // Krossfire GoG and Steam var executable = InstallationUtils.GetFile(executablePath, "kknd2.exe"); // TODO CD version is more tricky // its compressed in a .cab. So we need to use the local installation for the .exe and the base assets. // however briefing videos and music tracks must be loaded from CD // but depending on the faction, you need CD1 or CD2. // this requires us to implement a "Insert Disc X" dialog. // to avoid disk swapping while playing, we should make the dialog copy the data into the installation dir. if (executable == null) { return(null); } Log.Write("debug", $"Detected installation: {path}"); var release = CryptoUtil.SHA1Hash(File.OpenRead(executable)); switch (release) { case "8d81c9183d04eb834aff29195797abe11aedc249": Log.Write("debug", "=> Krush, Kill 'N' Destroy 2: Krossfire (Steam/GoG, English)"); break; default: Log.Write("debug", "=> Unsupported game version"); return(null); } var levelsFolder = InstallationUtils.GetDirectory(path, "levels"); if (levelsFolder == null) { Log.Write("debug", "=> Missing folder: levels"); return(null); } var fmvFolder = InstallationUtils.GetDirectory(path, "fmv"); if (fmvFolder == null) { Log.Write("debug", "=> Missing folder: fmv"); return(null); } // TODO the name of the graphics folder is tied to the language of the executable const string language = "english"; var graphicsFolder = InstallationUtils.GetDirectory(levelsFolder, language); if (graphicsFolder == null) { Log.Write("debug", $"=> Missing folder: {language}"); return(null); } var multiFolder = InstallationUtils.GetDirectory(levelsFolder, "multi"); if (multiFolder == null) { Log.Write("debug", "=> Missing folder: multi"); return(null); } // Required files. var files = new Dictionary <string, string> { { "gamesprt.lpk", graphicsFolder }, { "surv.spk", graphicsFolder }, { "mute.spk", graphicsFolder }, { "robo.spk", graphicsFolder }, { "mh.vbc", fmvFolder }, { "intro.vbc", fmvFolder } }.Concat( new Dictionary <string, string> { { "surv_01.wav", levelsFolder }, { "surv_02.wav", levelsFolder }, { "surv_03.wav", levelsFolder }, { "mute_01.wav", levelsFolder }, { "mute_02.wav", levelsFolder }, { "mute_03.wav", levelsFolder }, { "robo_01.wav", levelsFolder }, { "robo_02.wav", levelsFolder }, { "robo_03.wav", levelsFolder } } ); var foundFiles = new Dictionary <string, string>(); foreach (var(file, folder) in files) { var resolved = InstallationUtils.GetFile(folder, file); if (resolved == null) { Log.Write("debug", $"=> Missing file: {file}"); return(null); } foundFiles.Add(file, resolved); } var game = new Installation("gen2", path); game.Music.Add("Survivors 1", game.GetPath(foundFiles["surv_01.wav"])); game.Music.Add("Survivors 2", game.GetPath(foundFiles["surv_02.wav"])); game.Music.Add("Survivors 3", game.GetPath(foundFiles["surv_03.wav"])); game.Music.Add("Evolved 1", game.GetPath(foundFiles["mute_01.wav"])); game.Music.Add("Evolved 2", game.GetPath(foundFiles["mute_02.wav"])); game.Music.Add("Evolved 3", game.GetPath(foundFiles["mute_03.wav"])); game.Music.Add("Series9 1", game.GetPath(foundFiles["robo_01.wav"])); game.Music.Add("Series9 2", game.GetPath(foundFiles["robo_02.wav"])); game.Music.Add("Series9 3", game.GetPath(foundFiles["robo_03.wav"])); // Any other container for asset browser purpose game.Packages.Add("gen2_levels", game.GetPath(levelsFolder)); game.Packages.Add("gen2_graphics", game.GetPath(graphicsFolder)); game.Packages.Add("gen2_multi", game.GetPath(multiFolder)); game.Packages.Add("gen2_fmv", game.GetPath(fmvFolder)); foreach (var file in Directory.GetFiles(levelsFolder) .Concat(Directory.GetFiles(graphicsFolder)) .Concat(Directory.GetFiles(multiFolder)) .Where( f => f.EndsWith(".lpk", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".bpk", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".spk", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".lps", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".lpm", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".mpk", StringComparison.OrdinalIgnoreCase) )) { if (!game.Packages.ContainsValue(file)) { game.Packages.Add(Path.GetFileName(file).ToLower(), game.GetPath(file)); } } return(game); }