Replaced hardcoded source actions by user defined ISourceAction.
This commit is contained in:
committed by
Matthias Mailänder
parent
fcc8f53b59
commit
7188f88ba1
21
OpenRA.Mods.Common/Installer/ISourceAction.cs
Normal file
21
OpenRA.Mods.Common/Installer/ISourceAction.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Installer
|
||||||
|
{
|
||||||
|
public interface ISourceAction
|
||||||
|
{
|
||||||
|
void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List<string> extracted, Action<string> updateMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
78
OpenRA.Mods.Common/Installer/InstallerUtils.cs
Normal file
78
OpenRA.Mods.Common/Installer/InstallerUtils.cs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using FS = OpenRA.FileSystem.FileSystem;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Installer
|
||||||
|
{
|
||||||
|
public class InstallerUtils
|
||||||
|
{
|
||||||
|
public static bool IsValidSourcePath(string path, ModContent.ModSource source)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var kv in source.IDFiles.Nodes)
|
||||||
|
{
|
||||||
|
var filePath = FS.ResolveCaseInsensitivePath(Path.Combine(path, kv.Key));
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
using (var fileStream = File.OpenRead(filePath))
|
||||||
|
{
|
||||||
|
var offsetNode = kv.Value.Nodes.FirstOrDefault(n => n.Key == "Offset");
|
||||||
|
var lengthNode = kv.Value.Nodes.FirstOrDefault(n => n.Key == "Length");
|
||||||
|
if (offsetNode != null || lengthNode != null)
|
||||||
|
{
|
||||||
|
var offset = 0L;
|
||||||
|
if (offsetNode != null)
|
||||||
|
offset = FieldLoader.GetValue<long>("Offset", offsetNode.Value.Value);
|
||||||
|
|
||||||
|
var length = fileStream.Length - offset;
|
||||||
|
if (lengthNode != null)
|
||||||
|
length = FieldLoader.GetValue<long>("Length", lengthNode.Value.Value);
|
||||||
|
|
||||||
|
fileStream.Position = offset;
|
||||||
|
var data = fileStream.ReadBytes((int)length);
|
||||||
|
if (CryptoUtil.SHA1Hash(data) != kv.Value.Value)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (CryptoUtil.SHA1Hash(fileStream) != kv.Value.Value)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CopyStream(Stream input, Stream output, long length, Action<long> onProgress = null)
|
||||||
|
{
|
||||||
|
var buffer = new byte[4096];
|
||||||
|
var copied = 0L;
|
||||||
|
while (copied < length)
|
||||||
|
{
|
||||||
|
var read = (int)Math.Min(buffer.Length, length - copied);
|
||||||
|
var write = input.Read(buffer, 0, read);
|
||||||
|
output.Write(buffer, 0, write);
|
||||||
|
copied += write;
|
||||||
|
|
||||||
|
onProgress?.Invoke(copied);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using OpenRA.Mods.Common.Widgets.Logic;
|
||||||
|
using FS = OpenRA.FileSystem.FileSystem;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Installer
|
||||||
|
{
|
||||||
|
public class CopySourceAction : ISourceAction
|
||||||
|
{
|
||||||
|
public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List<string> extracted, Action<string> updateMessage)
|
||||||
|
{
|
||||||
|
var sourceDir = Path.Combine(path, actionYaml.Value);
|
||||||
|
foreach (var node in actionYaml.Nodes)
|
||||||
|
{
|
||||||
|
var sourcePath = FS.ResolveCaseInsensitivePath(Path.Combine(sourceDir, node.Value.Value));
|
||||||
|
var targetPath = Platform.ResolvePath(node.Key);
|
||||||
|
if (File.Exists(targetPath))
|
||||||
|
{
|
||||||
|
Log.Write("install", "Ignoring installed file " + targetPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Write("install", $"Copying {sourcePath} -> {targetPath}");
|
||||||
|
extracted.Add(targetPath);
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
|
||||||
|
|
||||||
|
using (var source = File.OpenRead(sourcePath))
|
||||||
|
using (var target = File.OpenWrite(targetPath))
|
||||||
|
{
|
||||||
|
var displayFilename = Path.GetFileName(targetPath);
|
||||||
|
var length = source.Length;
|
||||||
|
|
||||||
|
Action<long> onProgress = null;
|
||||||
|
if (length < InstallFromDiscLogic.ShowPercentageThreshold)
|
||||||
|
updateMessage(modData.Translation.GetString(InstallFromDiscLogic.CopyingFilename, Translation.Arguments("filename", displayFilename)));
|
||||||
|
else
|
||||||
|
onProgress = b => updateMessage(modData.Translation.GetString(InstallFromDiscLogic.CopyingFilenameProgress, Translation.Arguments("filename", displayFilename, "progress", 100 * b / length)));
|
||||||
|
|
||||||
|
InstallerUtils.CopyStream(source, target, length, onProgress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Installer
|
||||||
|
{
|
||||||
|
public class DeleteSourceAction : ISourceAction
|
||||||
|
{
|
||||||
|
public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List<string> extracted, Action<string> updateMessage)
|
||||||
|
{
|
||||||
|
// Yaml path must be specified relative to a named directory (e.g. ^SupportDir)
|
||||||
|
if (!actionYaml.Value.StartsWith("^"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var sourcePath = Platform.ResolvePath(actionYaml.Value);
|
||||||
|
|
||||||
|
Log.Write("debug", $"Deleting {sourcePath}");
|
||||||
|
File.Delete(sourcePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.Mods.Common.FileFormats;
|
||||||
|
using OpenRA.Mods.Common.Widgets.Logic;
|
||||||
|
using FS = OpenRA.FileSystem.FileSystem;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Installer
|
||||||
|
{
|
||||||
|
public class ExtractBlastSourceAction : ISourceAction
|
||||||
|
{
|
||||||
|
public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List<string> extracted, Action<string> updateMessage)
|
||||||
|
{
|
||||||
|
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected source path
|
||||||
|
var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value));
|
||||||
|
|
||||||
|
using (var source = File.OpenRead(sourcePath))
|
||||||
|
{
|
||||||
|
foreach (var node in actionYaml.Nodes)
|
||||||
|
{
|
||||||
|
var targetPath = Platform.ResolvePath(node.Key);
|
||||||
|
|
||||||
|
if (File.Exists(targetPath))
|
||||||
|
{
|
||||||
|
Log.Write("install", "Skipping installed file " + targetPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var offsetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Offset");
|
||||||
|
if (offsetNode == null)
|
||||||
|
{
|
||||||
|
Log.Write("install", "Skipping entry with missing Offset definition " + targetPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lengthNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Length");
|
||||||
|
if (lengthNode == null)
|
||||||
|
{
|
||||||
|
Log.Write("install", "Skipping entry with missing Length definition " + targetPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var length = FieldLoader.GetValue<int>("Length", lengthNode.Value.Value);
|
||||||
|
source.Position = FieldLoader.GetValue<int>("Offset", offsetNode.Value.Value);
|
||||||
|
|
||||||
|
extracted.Add(targetPath);
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
|
||||||
|
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
|
||||||
|
|
||||||
|
Action<long> onProgress = null;
|
||||||
|
if (length < InstallFromDiscLogic.ShowPercentageThreshold)
|
||||||
|
updateMessage(modData.Translation.GetString(InstallFromDiscLogic.Extracing, Translation.Arguments("filename", displayFilename)));
|
||||||
|
else
|
||||||
|
onProgress = b => updateMessage(modData.Translation.GetString(InstallFromDiscLogic.ExtracingProgress, Translation.Arguments("filename", displayFilename, "progress", 100 * b / length)));
|
||||||
|
|
||||||
|
using (var target = File.OpenWrite(targetPath))
|
||||||
|
{
|
||||||
|
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
|
||||||
|
Blast.Decompress(source, target, (read, _) => onProgress?.Invoke(read));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.Mods.Common.FileFormats;
|
||||||
|
using OpenRA.Mods.Common.Widgets.Logic;
|
||||||
|
using FS = OpenRA.FileSystem.FileSystem;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Installer
|
||||||
|
{
|
||||||
|
public class ExtractIscabSourceAction : ISourceAction
|
||||||
|
{
|
||||||
|
public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List<string> extracted, Action<string> updateMessage)
|
||||||
|
{
|
||||||
|
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected source path
|
||||||
|
var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value));
|
||||||
|
|
||||||
|
var volumeNode = actionYaml.Nodes.FirstOrDefault(n => n.Key == "Volumes");
|
||||||
|
if (volumeNode == null)
|
||||||
|
throw new InvalidDataException("extract-iscab entry doesn't define a Volumes node");
|
||||||
|
|
||||||
|
var extractNode = actionYaml.Nodes.FirstOrDefault(n => n.Key == "Extract");
|
||||||
|
if (extractNode == null)
|
||||||
|
throw new InvalidDataException("extract-iscab entry doesn't define an Extract node");
|
||||||
|
|
||||||
|
var volumes = new Dictionary<int, Stream>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var node in volumeNode.Value.Nodes)
|
||||||
|
{
|
||||||
|
var volume = FieldLoader.GetValue<int>("(key)", node.Key);
|
||||||
|
var stream = File.OpenRead(FS.ResolveCaseInsensitivePath(Path.Combine(path, node.Value.Value)));
|
||||||
|
volumes.Add(volume, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var source = File.OpenRead(sourcePath))
|
||||||
|
{
|
||||||
|
var reader = new InstallShieldCABCompression(source, volumes);
|
||||||
|
foreach (var node in extractNode.Value.Nodes)
|
||||||
|
{
|
||||||
|
var targetPath = Platform.ResolvePath(node.Key);
|
||||||
|
|
||||||
|
if (File.Exists(targetPath))
|
||||||
|
{
|
||||||
|
Log.Write("install", "Skipping installed file " + targetPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
extracted.Add(targetPath);
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
|
||||||
|
using (var target = File.OpenWrite(targetPath))
|
||||||
|
{
|
||||||
|
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
|
||||||
|
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
|
||||||
|
Action<int> onProgress = percent => updateMessage(modData.Translation.GetString(InstallFromDiscLogic.ExtracingProgress, Translation.Arguments("filename", displayFilename, "progress", percent)));
|
||||||
|
reader.ExtractFile(node.Value.Value, target, onProgress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
foreach (var kv in volumes)
|
||||||
|
kv.Value.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using OpenRA.Mods.Common.FileFormats;
|
||||||
|
using OpenRA.Mods.Common.Widgets.Logic;
|
||||||
|
using FS = OpenRA.FileSystem.FileSystem;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Installer
|
||||||
|
{
|
||||||
|
public class ExtractMscabSourceAction : ISourceAction
|
||||||
|
{
|
||||||
|
public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List<string> extracted, Action<string> updateMessage)
|
||||||
|
{
|
||||||
|
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected source path
|
||||||
|
var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value));
|
||||||
|
|
||||||
|
using (var source = File.OpenRead(sourcePath))
|
||||||
|
{
|
||||||
|
var reader = new MSCabCompression(source);
|
||||||
|
foreach (var node in actionYaml.Nodes)
|
||||||
|
{
|
||||||
|
var targetPath = Platform.ResolvePath(node.Key);
|
||||||
|
|
||||||
|
if (File.Exists(targetPath))
|
||||||
|
{
|
||||||
|
Log.Write("install", "Skipping installed file " + targetPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
extracted.Add(targetPath);
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
|
||||||
|
using (var target = File.OpenWrite(targetPath))
|
||||||
|
{
|
||||||
|
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
|
||||||
|
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
|
||||||
|
Action<int> onProgress = percent => updateMessage(modData.Translation.GetString(InstallFromDiscLogic.ExtracingProgress, Translation.Arguments("filename", displayFilename, "progress", percent)));
|
||||||
|
reader.ExtractFile(node.Value.Value, target, onProgress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2022 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation, either version 3 of
|
||||||
|
* the License, or (at your option) any later version. For more
|
||||||
|
* information, see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.Mods.Common.Widgets.Logic;
|
||||||
|
using FS = OpenRA.FileSystem.FileSystem;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Installer
|
||||||
|
{
|
||||||
|
public class ExtractRawSourceAction : ISourceAction
|
||||||
|
{
|
||||||
|
public void RunActionOnSource(MiniYaml actionYaml, string path, ModData modData, List<string> extracted, Action<string> updateMessage)
|
||||||
|
{
|
||||||
|
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected source path
|
||||||
|
var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value));
|
||||||
|
|
||||||
|
using (var source = File.OpenRead(sourcePath))
|
||||||
|
{
|
||||||
|
foreach (var node in actionYaml.Nodes)
|
||||||
|
{
|
||||||
|
var targetPath = Platform.ResolvePath(node.Key);
|
||||||
|
|
||||||
|
if (File.Exists(targetPath))
|
||||||
|
{
|
||||||
|
Log.Write("install", "Skipping installed file " + targetPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var offsetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Offset");
|
||||||
|
if (offsetNode == null)
|
||||||
|
{
|
||||||
|
Log.Write("install", "Skipping entry with missing Offset definition " + targetPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lengthNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Length");
|
||||||
|
if (lengthNode == null)
|
||||||
|
{
|
||||||
|
Log.Write("install", "Skipping entry with missing Length definition " + targetPath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var length = FieldLoader.GetValue<int>("Length", lengthNode.Value.Value);
|
||||||
|
source.Position = FieldLoader.GetValue<int>("Offset", offsetNode.Value.Value);
|
||||||
|
|
||||||
|
extracted.Add(targetPath);
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
|
||||||
|
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
|
||||||
|
|
||||||
|
Action<long> onProgress = null;
|
||||||
|
if (length < InstallFromDiscLogic.ShowPercentageThreshold)
|
||||||
|
updateMessage(modData.Translation.GetString(InstallFromDiscLogic.Extracing, Translation.Arguments("filename", displayFilename)));
|
||||||
|
else
|
||||||
|
onProgress = b => updateMessage(modData.Translation.GetString(InstallFromDiscLogic.ExtracingProgress, Translation.Arguments("filename", displayFilename, "progress", 100 * b / length)));
|
||||||
|
|
||||||
|
using (var target = File.OpenWrite(targetPath))
|
||||||
|
{
|
||||||
|
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
|
||||||
|
InstallerUtils.CopyStream(source, target, length, onProgress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,6 +41,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
public class ModSource
|
public class ModSource
|
||||||
{
|
{
|
||||||
|
public readonly ObjectCreator ObjectCreator;
|
||||||
public readonly SourceType Type = SourceType.Disc;
|
public readonly SourceType Type = SourceType.Disc;
|
||||||
|
|
||||||
// Used to find installation locations for SourceType.Install
|
// Used to find installation locations for SourceType.Install
|
||||||
@@ -56,8 +57,9 @@ namespace OpenRA
|
|||||||
[FieldLoader.Ignore]
|
[FieldLoader.Ignore]
|
||||||
public readonly List<MiniYamlNode> Install;
|
public readonly List<MiniYamlNode> Install;
|
||||||
|
|
||||||
public ModSource(MiniYaml yaml)
|
public ModSource(MiniYaml yaml, ObjectCreator objectCreator)
|
||||||
{
|
{
|
||||||
|
ObjectCreator = objectCreator;
|
||||||
Title = yaml.Value;
|
Title = yaml.Value;
|
||||||
|
|
||||||
var idFiles = yaml.Nodes.FirstOrDefault(n => n.Key == "IDFiles");
|
var idFiles = yaml.Nodes.FirstOrDefault(n => n.Key == "IDFiles");
|
||||||
|
|||||||
@@ -13,18 +13,16 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using OpenRA.Mods.Common.FileFormats;
|
using OpenRA.Mods.Common.Installer;
|
||||||
using OpenRA.Widgets;
|
using OpenRA.Widgets;
|
||||||
using FS = OpenRA.FileSystem.FileSystem;
|
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Widgets.Logic
|
namespace OpenRA.Mods.Common.Widgets.Logic
|
||||||
{
|
{
|
||||||
public class InstallFromDiscLogic : ChromeLogic
|
public class InstallFromDiscLogic : ChromeLogic
|
||||||
{
|
{
|
||||||
// Hide percentage indicators for files smaller than 25 MB
|
// Hide percentage indicators for files smaller than 25 MB
|
||||||
const int ShowPercentageThreshold = 26214400;
|
public const int ShowPercentageThreshold = 26214400;
|
||||||
|
|
||||||
enum Mode { Progress, Message, List }
|
enum Mode { Progress, Message, List }
|
||||||
|
|
||||||
@@ -83,10 +81,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
static readonly string InstallingContent = "installing-content";
|
static readonly string InstallingContent = "installing-content";
|
||||||
|
|
||||||
[TranslationReference("filename")]
|
[TranslationReference("filename")]
|
||||||
static readonly string CopyingFilename = "copying-filename";
|
public static readonly string CopyingFilename = "copying-filename";
|
||||||
|
|
||||||
[TranslationReference("filename", "progress")]
|
[TranslationReference("filename", "progress")]
|
||||||
static readonly string CopyingFilenameProgress = "copying-filename-progress";
|
public static readonly string CopyingFilenameProgress = "copying-filename-progress";
|
||||||
|
|
||||||
[TranslationReference]
|
[TranslationReference]
|
||||||
static readonly string InstallationFailed = "installation-failed";
|
static readonly string InstallationFailed = "installation-failed";
|
||||||
@@ -95,10 +93,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
static readonly string CheckInstallLog = "check-install-log";
|
static readonly string CheckInstallLog = "check-install-log";
|
||||||
|
|
||||||
[TranslationReference("filename")]
|
[TranslationReference("filename")]
|
||||||
static readonly string Extracing = "extracting-filename";
|
public static readonly string Extracing = "extracting-filename";
|
||||||
|
|
||||||
[TranslationReference("filename", "progress")]
|
[TranslationReference("filename", "progress")]
|
||||||
static readonly string ExtracingProgress = "extracting-filename-progress";
|
public static readonly string ExtracingProgress = "extracting-filename-progress";
|
||||||
|
|
||||||
[TranslationReference]
|
[TranslationReference]
|
||||||
static readonly string Continue = "continue";
|
static readonly string Continue = "continue";
|
||||||
@@ -264,82 +262,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
{
|
{
|
||||||
foreach (var i in modSource.Install)
|
foreach (var i in modSource.Install)
|
||||||
{
|
{
|
||||||
switch (i.Key)
|
var sourceAction = modSource.ObjectCreator.CreateObject<ISourceAction>($"{i.Key}SourceAction");
|
||||||
{
|
sourceAction.RunActionOnSource(i.Value, path, modData, extracted, m => message = m);
|
||||||
case "copy":
|
|
||||||
{
|
|
||||||
var sourceDir = Path.Combine(path, i.Value.Value);
|
|
||||||
foreach (var node in i.Value.Nodes)
|
|
||||||
{
|
|
||||||
var sourcePath = FS.ResolveCaseInsensitivePath(Path.Combine(sourceDir, node.Value.Value));
|
|
||||||
var targetPath = Platform.ResolvePath(node.Key);
|
|
||||||
if (File.Exists(targetPath))
|
|
||||||
{
|
|
||||||
Log.Write("install", "Ignoring installed file " + targetPath);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.Write("install", $"Copying {sourcePath} -> {targetPath}");
|
|
||||||
extracted.Add(targetPath);
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
|
|
||||||
|
|
||||||
using (var source = File.OpenRead(sourcePath))
|
|
||||||
using (var target = File.OpenWrite(targetPath))
|
|
||||||
{
|
|
||||||
var displayFilename = Path.GetFileName(targetPath);
|
|
||||||
var length = source.Length;
|
|
||||||
|
|
||||||
Action<long> onProgress = null;
|
|
||||||
if (length < ShowPercentageThreshold)
|
|
||||||
message = modData.Translation.GetString(CopyingFilename, Translation.Arguments("filename", displayFilename));
|
|
||||||
else
|
|
||||||
onProgress = b => message = modData.Translation.GetString(CopyingFilenameProgress, Translation.Arguments("filename", displayFilename, "progress", 100 * b / length));
|
|
||||||
|
|
||||||
CopyStream(source, target, length, onProgress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "extract-raw":
|
|
||||||
{
|
|
||||||
ExtractFromPackage(modData, ExtractionType.Raw, path, i.Value, extracted, m => message = m);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "extract-blast":
|
|
||||||
{
|
|
||||||
ExtractFromPackage(modData, ExtractionType.Blast, path, i.Value, extracted, m => message = m);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "extract-mscab":
|
|
||||||
{
|
|
||||||
ExtractFromMSCab(modData, path, i.Value, extracted, m => message = m);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "extract-iscab":
|
|
||||||
{
|
|
||||||
ExtractFromISCab(modData, path, i.Value, extracted, m => message = m);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "delete":
|
|
||||||
{
|
|
||||||
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected disc path
|
|
||||||
var sourcePath = i.Value.Value.StartsWith("^") ? Platform.ResolvePath(i.Value.Value) : Path.Combine(path, i.Value.Value);
|
|
||||||
|
|
||||||
Log.Write("debug", $"Deleting {sourcePath}");
|
|
||||||
File.Delete(sourcePath);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
Log.Write("debug", $"Unknown installation command {i.Key} - ignoring");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Game.RunAfterTick(Ui.CloseWindow);
|
Game.RunAfterTick(Ui.CloseWindow);
|
||||||
@@ -363,244 +287,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
}).Start();
|
}).Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CopyStream(Stream input, Stream output, long length, Action<long> onProgress = null)
|
|
||||||
{
|
|
||||||
var buffer = new byte[4096];
|
|
||||||
var copied = 0L;
|
|
||||||
while (copied < length)
|
|
||||||
{
|
|
||||||
var read = (int)Math.Min(buffer.Length, length - copied);
|
|
||||||
var write = input.Read(buffer, 0, read);
|
|
||||||
output.Write(buffer, 0, write);
|
|
||||||
copied += write;
|
|
||||||
|
|
||||||
onProgress?.Invoke(copied);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ExtractionType { Raw, Blast }
|
|
||||||
|
|
||||||
static void ExtractFromPackage(ModData modData, ExtractionType type, string path, MiniYaml actionYaml, List<string> extractedFiles, Action<string> updateMessage)
|
|
||||||
{
|
|
||||||
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected disc path
|
|
||||||
var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value));
|
|
||||||
|
|
||||||
using (var source = File.OpenRead(sourcePath))
|
|
||||||
{
|
|
||||||
foreach (var node in actionYaml.Nodes)
|
|
||||||
{
|
|
||||||
var targetPath = Platform.ResolvePath(node.Key);
|
|
||||||
|
|
||||||
if (File.Exists(targetPath))
|
|
||||||
{
|
|
||||||
Log.Write("install", "Skipping installed file " + targetPath);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var offsetNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Offset");
|
|
||||||
if (offsetNode == null)
|
|
||||||
{
|
|
||||||
Log.Write("install", "Skipping entry with missing Offset definition " + targetPath);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var lengthNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "Length");
|
|
||||||
if (lengthNode == null)
|
|
||||||
{
|
|
||||||
Log.Write("install", "Skipping entry with missing Length definition " + targetPath);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var length = FieldLoader.GetValue<int>("Length", lengthNode.Value.Value);
|
|
||||||
source.Position = FieldLoader.GetValue<int>("Offset", offsetNode.Value.Value);
|
|
||||||
|
|
||||||
extractedFiles.Add(targetPath);
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
|
|
||||||
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
|
|
||||||
|
|
||||||
Action<long> onProgress = null;
|
|
||||||
if (length < ShowPercentageThreshold)
|
|
||||||
updateMessage(modData.Translation.GetString(Extracing, Translation.Arguments("filename", displayFilename)));
|
|
||||||
else
|
|
||||||
onProgress = b => updateMessage(modData.Translation.GetString(ExtracingProgress, Translation.Arguments("filename", displayFilename, "progress", 100 * b / length)));
|
|
||||||
|
|
||||||
using (var target = File.OpenWrite(targetPath))
|
|
||||||
{
|
|
||||||
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
|
|
||||||
if (type == ExtractionType.Blast)
|
|
||||||
Blast.Decompress(source, target, (read, _) => onProgress?.Invoke(read));
|
|
||||||
else
|
|
||||||
CopyStream(source, target, length, onProgress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ExtractFromMSCab(ModData modData, string path, MiniYaml actionYaml, List<string> extractedFiles, Action<string> updateMessage)
|
|
||||||
{
|
|
||||||
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected disc path
|
|
||||||
var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value));
|
|
||||||
|
|
||||||
using (var source = File.OpenRead(sourcePath))
|
|
||||||
{
|
|
||||||
var reader = new MSCabCompression(source);
|
|
||||||
foreach (var node in actionYaml.Nodes)
|
|
||||||
{
|
|
||||||
var targetPath = Platform.ResolvePath(node.Key);
|
|
||||||
|
|
||||||
if (File.Exists(targetPath))
|
|
||||||
{
|
|
||||||
Log.Write("install", "Skipping installed file " + targetPath);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
extractedFiles.Add(targetPath);
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
|
|
||||||
using (var target = File.OpenWrite(targetPath))
|
|
||||||
{
|
|
||||||
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
|
|
||||||
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
|
|
||||||
Action<int> onProgress = percent => updateMessage(modData.Translation.GetString(ExtracingProgress, Translation.Arguments("filename", displayFilename, "progress", percent)));
|
|
||||||
reader.ExtractFile(node.Value.Value, target, onProgress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ExtractFromISCab(ModData modData, string path, MiniYaml actionYaml, List<string> extractedFiles, Action<string> updateMessage)
|
|
||||||
{
|
|
||||||
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected disc path
|
|
||||||
var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : FS.ResolveCaseInsensitivePath(Path.Combine(path, actionYaml.Value));
|
|
||||||
|
|
||||||
var volumeNode = actionYaml.Nodes.FirstOrDefault(n => n.Key == "Volumes");
|
|
||||||
if (volumeNode == null)
|
|
||||||
throw new InvalidDataException("extract-iscab entry doesn't define a Volumes node");
|
|
||||||
|
|
||||||
var extractNode = actionYaml.Nodes.FirstOrDefault(n => n.Key == "Extract");
|
|
||||||
if (extractNode == null)
|
|
||||||
throw new InvalidDataException("extract-iscab entry doesn't define an Extract node");
|
|
||||||
|
|
||||||
var volumes = new Dictionary<int, Stream>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (var node in volumeNode.Value.Nodes)
|
|
||||||
{
|
|
||||||
var volume = FieldLoader.GetValue<int>("(key)", node.Key);
|
|
||||||
var stream = File.OpenRead(FS.ResolveCaseInsensitivePath(Path.Combine(path, node.Value.Value)));
|
|
||||||
volumes.Add(volume, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var source = File.OpenRead(sourcePath))
|
|
||||||
{
|
|
||||||
var reader = new InstallShieldCABCompression(source, volumes);
|
|
||||||
foreach (var node in extractNode.Value.Nodes)
|
|
||||||
{
|
|
||||||
var targetPath = Platform.ResolvePath(node.Key);
|
|
||||||
|
|
||||||
if (File.Exists(targetPath))
|
|
||||||
{
|
|
||||||
Log.Write("install", "Skipping installed file " + targetPath);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
extractedFiles.Add(targetPath);
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
|
|
||||||
using (var target = File.OpenWrite(targetPath))
|
|
||||||
{
|
|
||||||
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
|
|
||||||
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
|
|
||||||
Action<int> onProgress = percent => updateMessage(modData.Translation.GetString(ExtracingProgress, Translation.Arguments("filename", displayFilename, "progress", percent)));
|
|
||||||
reader.ExtractFile(node.Value.Value, target, onProgress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
foreach (var kv in volumes)
|
|
||||||
kv.Value.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string FindSourcePath(ModContent.ModSource source, IEnumerable<string> volumes)
|
|
||||||
{
|
|
||||||
if (source.Type == ModContent.SourceType.RegistryDirectory || source.Type == ModContent.SourceType.RegistryDirectoryFromFile)
|
|
||||||
{
|
|
||||||
if (source.RegistryKey == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (Platform.CurrentPlatform != PlatformType.Windows)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// We need an extra check for the platform here to silence a warning when the registry is accessed
|
|
||||||
// TODO: Remove this once our platform checks use the same method
|
|
||||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
foreach (var prefix in source.RegistryPrefixes)
|
|
||||||
{
|
|
||||||
if (!(Microsoft.Win32.Registry.GetValue(prefix + source.RegistryKey, source.RegistryValue, null) is string path))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (source.Type == ModContent.SourceType.RegistryDirectoryFromFile)
|
|
||||||
path = Path.GetDirectoryName(path);
|
|
||||||
|
|
||||||
return IsValidSourcePath(path, source) ? path : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (source.Type == ModContent.SourceType.Disc)
|
|
||||||
foreach (var volume in volumes)
|
|
||||||
if (IsValidSourcePath(volume, source))
|
|
||||||
return volume;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool IsValidSourcePath(string path, ModContent.ModSource source)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (var kv in source.IDFiles.Nodes)
|
|
||||||
{
|
|
||||||
var filePath = FS.ResolveCaseInsensitivePath(Path.Combine(path, kv.Key));
|
|
||||||
if (!File.Exists(filePath))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
using (var fileStream = File.OpenRead(filePath))
|
|
||||||
{
|
|
||||||
var offsetNode = kv.Value.Nodes.FirstOrDefault(n => n.Key == "Offset");
|
|
||||||
var lengthNode = kv.Value.Nodes.FirstOrDefault(n => n.Key == "Length");
|
|
||||||
if (offsetNode != null || lengthNode != null)
|
|
||||||
{
|
|
||||||
var offset = 0L;
|
|
||||||
if (offsetNode != null)
|
|
||||||
offset = FieldLoader.GetValue<long>("Offset", offsetNode.Value.Value);
|
|
||||||
|
|
||||||
var length = fileStream.Length - offset;
|
|
||||||
if (lengthNode != null)
|
|
||||||
length = FieldLoader.GetValue<long>("Length", lengthNode.Value.Value);
|
|
||||||
|
|
||||||
fileStream.Position = offset;
|
|
||||||
var data = fileStream.ReadBytes((int)length);
|
|
||||||
if (CryptoUtil.SHA1Hash(data) != kv.Value.Value)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (CryptoUtil.SHA1Hash(fileStream) != kv.Value.Value)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShowMessage(string title, string message)
|
void ShowMessage(string title, string message)
|
||||||
{
|
{
|
||||||
visible = Mode.Message;
|
visible = Mode.Message;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
var sourceYaml = MiniYaml.Load(modFileSystem, content.Sources, null);
|
var sourceYaml = MiniYaml.Load(modFileSystem, content.Sources, null);
|
||||||
foreach (var s in sourceYaml)
|
foreach (var s in sourceYaml)
|
||||||
sources.Add(s.Key, new ModContent.ModSource(s.Value));
|
sources.Add(s.Key, new ModContent.ModSource(s.Value, modObjectCreator));
|
||||||
|
|
||||||
var downloadYaml = MiniYaml.Load(modFileSystem, content.Downloads, null);
|
var downloadYaml = MiniYaml.Load(modFileSystem, content.Downloads, null);
|
||||||
foreach (var d in downloadYaml)
|
foreach (var d in downloadYaml)
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ covertops: Covert Operations Expansion (English)
|
|||||||
GAME/GAME.DAT: be5a6c4c0a581da09e8f34a3bbf7bd17e525085c
|
GAME/GAME.DAT: be5a6c4c0a581da09e8f34a3bbf7bd17e525085c
|
||||||
CONQUER.MIX: 713b53fa4c188ca9619c6bbeadbfc86513704266
|
CONQUER.MIX: 713b53fa4c188ca9619c6bbeadbfc86513704266
|
||||||
Install:
|
Install:
|
||||||
copy: .
|
Copy: .
|
||||||
^SupportDir|Content/cnc/scores-covertops.mix: SCORES.MIX
|
^SupportDir|Content/cnc/scores-covertops.mix: SCORES.MIX
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ tfd: C&C The First Decade (English)
|
|||||||
data1.hdr: bef3a08c3fc1b1caf28ca0dbb97c1f900005930e
|
data1.hdr: bef3a08c3fc1b1caf28ca0dbb97c1f900005930e
|
||||||
data1.cab: 12ad6113a6890a1b4d5651a75378c963eaf513b9
|
data1.cab: 12ad6113a6890a1b4d5651a75378c963eaf513b9
|
||||||
Install:
|
Install:
|
||||||
extract-iscab: data1.hdr
|
ExtractIscab: data1.hdr
|
||||||
Volumes:
|
Volumes:
|
||||||
2: data2.cab
|
2: data2.cab
|
||||||
3: data3.cab
|
3: data3.cab
|
||||||
@@ -20,7 +20,7 @@ tfd: C&C The First Decade (English)
|
|||||||
^SupportDir|Content/cnc/transit.mix: CnC\\TRANSIT.MIX
|
^SupportDir|Content/cnc/transit.mix: CnC\\TRANSIT.MIX
|
||||||
^SupportDir|Content/cnc/scores-covertops.mix: CnC\covert\SCORES.MIX
|
^SupportDir|Content/cnc/scores-covertops.mix: CnC\covert\SCORES.MIX
|
||||||
^SupportDir|Content/cnc/movies.mix: CnC\\MOVIES.MIX
|
^SupportDir|Content/cnc/movies.mix: CnC\\MOVIES.MIX
|
||||||
extract-raw: ^SupportDir|Content/cnc/movies.mix
|
ExtractRaw: ^SupportDir|Content/cnc/movies.mix
|
||||||
^SupportDir|Content/cnc/movies/airstrk.vqa:
|
^SupportDir|Content/cnc/movies/airstrk.vqa:
|
||||||
Offset: 1266
|
Offset: 1266
|
||||||
Length: 4444442
|
Length: 4444442
|
||||||
@@ -333,4 +333,4 @@ tfd: C&C The First Decade (English)
|
|||||||
^SupportDir|Content/cnc/movies/banner.vqa:
|
^SupportDir|Content/cnc/movies/banner.vqa:
|
||||||
Offset: 751962554
|
Offset: 751962554
|
||||||
Length: 2229408
|
Length: 2229408
|
||||||
delete: ^SupportDir|Content/cnc/movies.mix
|
Delete: ^SupportDir|Content/cnc/movies.mix
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ gdi95: C&C Gold (GDI Disc, English)
|
|||||||
DISK.WAV: 8bef9a6687c0fe0afd57c6561df58fa6e64f145d
|
DISK.WAV: 8bef9a6687c0fe0afd57c6561df58fa6e64f145d
|
||||||
CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30
|
CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30
|
||||||
Install:
|
Install:
|
||||||
copy: .
|
Copy: .
|
||||||
^SupportDir|Content/cnc/conquer.mix: CONQUER.MIX
|
^SupportDir|Content/cnc/conquer.mix: CONQUER.MIX
|
||||||
^SupportDir|Content/cnc/desert.mix: DESERT.MIX
|
^SupportDir|Content/cnc/desert.mix: DESERT.MIX
|
||||||
^SupportDir|Content/cnc/general.mix: GENERAL.MIX
|
^SupportDir|Content/cnc/general.mix: GENERAL.MIX
|
||||||
@@ -11,7 +11,7 @@ gdi95: C&C Gold (GDI Disc, English)
|
|||||||
^SupportDir|Content/cnc/sounds.mix: SOUNDS.MIX
|
^SupportDir|Content/cnc/sounds.mix: SOUNDS.MIX
|
||||||
^SupportDir|Content/cnc/temperat.mix: TEMPERAT.MIX
|
^SupportDir|Content/cnc/temperat.mix: TEMPERAT.MIX
|
||||||
^SupportDir|Content/cnc/winter.mix: WINTER.MIX
|
^SupportDir|Content/cnc/winter.mix: WINTER.MIX
|
||||||
extract-blast: INSTALL/SETUP.Z
|
ExtractBlast: INSTALL/SETUP.Z
|
||||||
^SupportDir|Content/cnc/speech.mix:
|
^SupportDir|Content/cnc/speech.mix:
|
||||||
Offset: 10203213
|
Offset: 10203213
|
||||||
Length: 603293
|
Length: 603293
|
||||||
@@ -21,7 +21,7 @@ gdi95: C&C Gold (GDI Disc, English)
|
|||||||
^SupportDir|Content/cnc/transit.mix:
|
^SupportDir|Content/cnc/transit.mix:
|
||||||
Offset: 11078017
|
Offset: 11078017
|
||||||
Length: 3724462
|
Length: 3724462
|
||||||
extract-raw: MOVIES.MIX
|
ExtractRaw: MOVIES.MIX
|
||||||
^SupportDir|Content/cnc/movies/visor.vqa:
|
^SupportDir|Content/cnc/movies/visor.vqa:
|
||||||
Offset: 786
|
Offset: 786
|
||||||
Length: 4407162
|
Length: 4407162
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ nod95: C&C Gold (Nod Disc, English)
|
|||||||
DISK.WAV: 83a0235525afa5cd6096f2967e3eae032996e38c
|
DISK.WAV: 83a0235525afa5cd6096f2967e3eae032996e38c
|
||||||
CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30
|
CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30
|
||||||
Install:
|
Install:
|
||||||
copy: .
|
Copy: .
|
||||||
^SupportDir|Content/cnc/conquer.mix: CONQUER.MIX
|
^SupportDir|Content/cnc/conquer.mix: CONQUER.MIX
|
||||||
^SupportDir|Content/cnc/desert.mix: DESERT.MIX
|
^SupportDir|Content/cnc/desert.mix: DESERT.MIX
|
||||||
^SupportDir|Content/cnc/general.mix: GENERAL.MIX
|
^SupportDir|Content/cnc/general.mix: GENERAL.MIX
|
||||||
@@ -11,7 +11,7 @@ nod95: C&C Gold (Nod Disc, English)
|
|||||||
^SupportDir|Content/cnc/sounds.mix: SOUNDS.MIX
|
^SupportDir|Content/cnc/sounds.mix: SOUNDS.MIX
|
||||||
^SupportDir|Content/cnc/temperat.mix: TEMPERAT.MIX
|
^SupportDir|Content/cnc/temperat.mix: TEMPERAT.MIX
|
||||||
^SupportDir|Content/cnc/winter.mix: WINTER.MIX
|
^SupportDir|Content/cnc/winter.mix: WINTER.MIX
|
||||||
extract-blast: INSTALL/SETUP.Z
|
ExtractBlast: INSTALL/SETUP.Z
|
||||||
^SupportDir|Content/cnc/speech.mix:
|
^SupportDir|Content/cnc/speech.mix:
|
||||||
Offset: 10203213
|
Offset: 10203213
|
||||||
Length: 603293
|
Length: 603293
|
||||||
@@ -21,7 +21,7 @@ nod95: C&C Gold (Nod Disc, English)
|
|||||||
^SupportDir|Content/cnc/transit.mix:
|
^SupportDir|Content/cnc/transit.mix:
|
||||||
Offset: 11078017
|
Offset: 11078017
|
||||||
Length: 3724462
|
Length: 3724462
|
||||||
extract-raw: MOVIES.MIX
|
ExtractRaw: MOVIES.MIX
|
||||||
^SupportDir|Content/cnc/movies/visor.vqa:
|
^SupportDir|Content/cnc/movies/visor.vqa:
|
||||||
Offset: 738
|
Offset: 738
|
||||||
Length: 4407162
|
Length: 4407162
|
||||||
@@ -204,4 +204,4 @@ nod95: C&C Gold (Nod Disc, English)
|
|||||||
Length: 7803444
|
Length: 7803444
|
||||||
^SupportDir|Content/cnc/movies/airstrk.vqa:
|
^SupportDir|Content/cnc/movies/airstrk.vqa:
|
||||||
Offset: 428091252
|
Offset: 428091252
|
||||||
Length: 4444442
|
Length: 4444442
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ origin: C&C The Ultimate Collection (Origin version, English)
|
|||||||
IDFiles:
|
IDFiles:
|
||||||
CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30
|
CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30
|
||||||
Install:
|
Install:
|
||||||
copy: .
|
Copy: .
|
||||||
^SupportDir|Content/cnc/conquer.mix: CONQUER.MIX
|
^SupportDir|Content/cnc/conquer.mix: CONQUER.MIX
|
||||||
^SupportDir|Content/cnc/desert.mix: DESERT.MIX
|
^SupportDir|Content/cnc/desert.mix: DESERT.MIX
|
||||||
^SupportDir|Content/cnc/general.mix: GENERAL.MIX
|
^SupportDir|Content/cnc/general.mix: GENERAL.MIX
|
||||||
@@ -18,7 +18,7 @@ origin: C&C The Ultimate Collection (Origin version, English)
|
|||||||
^SupportDir|Content/cnc/tempicnh.mix: TEMPICNH.MIX
|
^SupportDir|Content/cnc/tempicnh.mix: TEMPICNH.MIX
|
||||||
^SupportDir|Content/cnc/transit.mix: TRANSIT.MIX
|
^SupportDir|Content/cnc/transit.mix: TRANSIT.MIX
|
||||||
^SupportDir|Content/cnc/scores-covertops.mix: covert/SCORES.MIX
|
^SupportDir|Content/cnc/scores-covertops.mix: covert/SCORES.MIX
|
||||||
extract-raw: movies.mix
|
ExtractRaw: movies.mix
|
||||||
^SupportDir|Content/cnc/movies/akira.vqa:
|
^SupportDir|Content/cnc/movies/akira.vqa:
|
||||||
Offset: 4445708
|
Offset: 4445708
|
||||||
Length: 7803444
|
Length: 7803444
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ d2k-a: Dune 2000 (English)
|
|||||||
MUSIC/AMBUSH.AUD: bd5926a56a83bc0e49f96037e1f909014ac0772a
|
MUSIC/AMBUSH.AUD: bd5926a56a83bc0e49f96037e1f909014ac0772a
|
||||||
SETUP/SETUP.Z: 937f5ceb1236bf3f3d4e43929305ffe5004078e7
|
SETUP/SETUP.Z: 937f5ceb1236bf3f3d4e43929305ffe5004078e7
|
||||||
Install:
|
Install:
|
||||||
copy: MOVIES
|
Copy: MOVIES
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR01_E.VQA: A_BR01_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR01_E.VQA: A_BR01_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR02_E.VQA: A_BR02_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR02_E.VQA: A_BR02_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR03_E.VQA: A_BR03_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR03_E.VQA: A_BR03_E.VQA
|
||||||
@@ -46,7 +46,7 @@ d2k-a: Dune 2000 (English)
|
|||||||
^SupportDir|Content/d2k/v2/Movies/G_PLN2_E.VQA: G_PLN2_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/G_PLN2_E.VQA: G_PLN2_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/G_PLNT_E.VQA: G_PLNT_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/G_PLNT_E.VQA: G_PLNT_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/T_TITL_E.VQA: T_TITL_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/T_TITL_E.VQA: T_TITL_E.VQA
|
||||||
copy: MUSIC
|
Copy: MUSIC
|
||||||
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
||||||
@@ -64,7 +64,7 @@ d2k-a: Dune 2000 (English)
|
|||||||
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
||||||
extract-blast: SETUP/SETUP.Z
|
ExtractBlast: SETUP/SETUP.Z
|
||||||
^SupportDir|Content/d2k/v2/BLOXBAT.R8:
|
^SupportDir|Content/d2k/v2/BLOXBAT.R8:
|
||||||
Offset: 1156652
|
Offset: 1156652
|
||||||
Length: 512750
|
Length: 512750
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ d2k-b: Dune 2000 (English)
|
|||||||
MUSIC/AMBUSH.AUD: bd5926a56a83bc0e49f96037e1f909014ac0772a
|
MUSIC/AMBUSH.AUD: bd5926a56a83bc0e49f96037e1f909014ac0772a
|
||||||
SETUP/SETUP.Z: 029722e70fb7636f8120028f5c9b6ce81627ff90
|
SETUP/SETUP.Z: 029722e70fb7636f8120028f5c9b6ce81627ff90
|
||||||
Install:
|
Install:
|
||||||
copy: MOVIES
|
Copy: MOVIES
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR01_E.VQA: A_BR01_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR01_E.VQA: A_BR01_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR02_E.VQA: A_BR02_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR02_E.VQA: A_BR02_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR03_E.VQA: A_BR03_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR03_E.VQA: A_BR03_E.VQA
|
||||||
@@ -46,7 +46,7 @@ d2k-b: Dune 2000 (English)
|
|||||||
^SupportDir|Content/d2k/v2/Movies/G_PLN2_E.VQA: G_PLN2_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/G_PLN2_E.VQA: G_PLN2_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/G_PLNT_E.VQA: G_PLNT_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/G_PLNT_E.VQA: G_PLNT_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/T_TITL_E.VQA: T_TITL_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/T_TITL_E.VQA: T_TITL_E.VQA
|
||||||
copy: MUSIC
|
Copy: MUSIC
|
||||||
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
||||||
@@ -64,7 +64,7 @@ d2k-b: Dune 2000 (English)
|
|||||||
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
||||||
extract-blast: SETUP/SETUP.Z
|
ExtractBlast: SETUP/SETUP.Z
|
||||||
^SupportDir|Content/d2k/v2/BLOXBAT.R8:
|
^SupportDir|Content/d2k/v2/BLOXBAT.R8:
|
||||||
Offset: 1156877
|
Offset: 1156877
|
||||||
Length: 512750
|
Length: 512750
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ d2k-c: Dune 2000 (English)
|
|||||||
MUSIC/AMBUSH.AUD: bd5926a56a83bc0e49f96037e1f909014ac0772a
|
MUSIC/AMBUSH.AUD: bd5926a56a83bc0e49f96037e1f909014ac0772a
|
||||||
SETUP/SETUP.Z: d939b39bdbc952b259ce2b45c0bbedefa534b7f2
|
SETUP/SETUP.Z: d939b39bdbc952b259ce2b45c0bbedefa534b7f2
|
||||||
Install:
|
Install:
|
||||||
copy: MOVIES
|
Copy: MOVIES
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR01_E.VQA: A_BR01_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR01_E.VQA: A_BR01_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR02_E.VQA: A_BR02_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR02_E.VQA: A_BR02_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR03_E.VQA: A_BR03_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR03_E.VQA: A_BR03_E.VQA
|
||||||
@@ -46,7 +46,7 @@ d2k-c: Dune 2000 (English)
|
|||||||
^SupportDir|Content/d2k/v2/Movies/G_PLN2_E.VQA: G_PLN2_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/G_PLN2_E.VQA: G_PLN2_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/G_PLNT_E.VQA: G_PLNT_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/G_PLNT_E.VQA: G_PLNT_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/T_TITL_E.VQA: T_TITL_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/T_TITL_E.VQA: T_TITL_E.VQA
|
||||||
copy: MUSIC
|
Copy: MUSIC
|
||||||
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
||||||
@@ -64,7 +64,7 @@ d2k-c: Dune 2000 (English)
|
|||||||
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
||||||
extract-blast: SETUP/SETUP.Z
|
ExtractBlast: SETUP/SETUP.Z
|
||||||
^SupportDir|Content/d2k/v2/BLOXBAT.R8:
|
^SupportDir|Content/d2k/v2/BLOXBAT.R8:
|
||||||
Offset: 704502
|
Offset: 704502
|
||||||
Length: 512750
|
Length: 512750
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ d2k-d: Dune 2000 (English)
|
|||||||
MUSIC/AMBUSH.AUD: bd5926a56a83bc0e49f96037e1f909014ac0772a
|
MUSIC/AMBUSH.AUD: bd5926a56a83bc0e49f96037e1f909014ac0772a
|
||||||
SETUP/SETUP.Z: 2411cc5df36954ebd534ceafa3007c8aa9232909
|
SETUP/SETUP.Z: 2411cc5df36954ebd534ceafa3007c8aa9232909
|
||||||
Install:
|
Install:
|
||||||
copy: MOVIES
|
Copy: MOVIES
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR01_E.VQA: A_BR01_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR01_E.VQA: A_BR01_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR02_E.VQA: A_BR02_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR02_E.VQA: A_BR02_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR03_E.VQA: A_BR03_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR03_E.VQA: A_BR03_E.VQA
|
||||||
@@ -46,7 +46,7 @@ d2k-d: Dune 2000 (English)
|
|||||||
^SupportDir|Content/d2k/v2/Movies/G_PLN2_E.VQA: G_PLN2_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/G_PLN2_E.VQA: G_PLN2_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/G_PLNT_E.VQA: G_PLNT_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/G_PLNT_E.VQA: G_PLNT_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/T_TITL_E.VQA: T_TITL_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/T_TITL_E.VQA: T_TITL_E.VQA
|
||||||
copy: MUSIC
|
Copy: MUSIC
|
||||||
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
||||||
@@ -64,7 +64,7 @@ d2k-d: Dune 2000 (English)
|
|||||||
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
||||||
extract-blast: SETUP/SETUP.Z
|
ExtractBlast: SETUP/SETUP.Z
|
||||||
^SupportDir|Content/d2k/v2/BLOXBAT.R8:
|
^SupportDir|Content/d2k/v2/BLOXBAT.R8:
|
||||||
Offset: 702406
|
Offset: 702406
|
||||||
Length: 512750
|
Length: 512750
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ d2k-e: Dune 2000 (English)
|
|||||||
MUSIC/AMBUSH.AUD: bd5926a56a83bc0e49f96037e1f909014ac0772a
|
MUSIC/AMBUSH.AUD: bd5926a56a83bc0e49f96037e1f909014ac0772a
|
||||||
SETUP/SETUP.Z: b476661e82eeb05949e97fa1f75fed2343174be5
|
SETUP/SETUP.Z: b476661e82eeb05949e97fa1f75fed2343174be5
|
||||||
Install:
|
Install:
|
||||||
copy: MOVIES
|
Copy: MOVIES
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR01_E.VQA: A_BR01_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR01_E.VQA: A_BR01_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR02_E.VQA: A_BR02_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR02_E.VQA: A_BR02_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/A_BR03_E.VQA: A_BR03_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/A_BR03_E.VQA: A_BR03_E.VQA
|
||||||
@@ -46,7 +46,7 @@ d2k-e: Dune 2000 (English)
|
|||||||
^SupportDir|Content/d2k/v2/Movies/G_PLN2_E.VQA: G_PLN2_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/G_PLN2_E.VQA: G_PLN2_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/G_PLNT_E.VQA: G_PLNT_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/G_PLNT_E.VQA: G_PLNT_E.VQA
|
||||||
^SupportDir|Content/d2k/v2/Movies/T_TITL_E.VQA: T_TITL_E.VQA
|
^SupportDir|Content/d2k/v2/Movies/T_TITL_E.VQA: T_TITL_E.VQA
|
||||||
copy: MUSIC
|
Copy: MUSIC
|
||||||
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
||||||
@@ -64,7 +64,7 @@ d2k-e: Dune 2000 (English)
|
|||||||
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
||||||
extract-blast: SETUP/SETUP.Z
|
ExtractBlast: SETUP/SETUP.Z
|
||||||
^SupportDir|Content/d2k/v2/BLOXBAT.R8:
|
^SupportDir|Content/d2k/v2/BLOXBAT.R8:
|
||||||
Offset: 702405
|
Offset: 702405
|
||||||
Length: 512750
|
Length: 512750
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ gruntmods: Dune 2000: GruntMods Edition
|
|||||||
Dune 2000/data/BLOXXMAS.R8: afc818feda44f5873e3af07bd2191573ba9965db
|
Dune 2000/data/BLOXXMAS.R8: afc818feda44f5873e3af07bd2191573ba9965db
|
||||||
Dune 2000/data/DATA.R8: 2b229cf4be47104a6214237039a55329f6c45bc9
|
Dune 2000/data/DATA.R8: 2b229cf4be47104a6214237039a55329f6c45bc9
|
||||||
Install:
|
Install:
|
||||||
copy: Dune 2000/data/Music
|
Copy: Dune 2000/data/Music
|
||||||
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
^SupportDir|Content/d2k/v2/Music/AMBUSH.AUD: AMBUSH.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
^SupportDir|Content/d2k/v2/Music/ARAKATAK.AUD: ARAKATAK.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
^SupportDir|Content/d2k/v2/Music/ATREGAIN.AUD: ATREGAIN.AUD
|
||||||
@@ -24,7 +24,7 @@ gruntmods: Dune 2000: GruntMods Edition
|
|||||||
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
^SupportDir|Content/d2k/v2/Music/SPICESCT.AUD: SPICESCT.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
^SupportDir|Content/d2k/v2/Music/UNDERCON.AUD: UNDERCON.AUD
|
||||||
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
^SupportDir|Content/d2k/v2/Music/WAITGAME.AUD: WAITGAME.AUD
|
||||||
copy: Dune 2000/data
|
Copy: Dune 2000/data
|
||||||
^SupportDir|Content/d2k/v2/BLOXBAT.R8: BLOXBAT.R8
|
^SupportDir|Content/d2k/v2/BLOXBAT.R8: BLOXBAT.R8
|
||||||
^SupportDir|Content/d2k/v2/BLOXBASE.R8: BLOXBASE.R8
|
^SupportDir|Content/d2k/v2/BLOXBASE.R8: BLOXBASE.R8
|
||||||
^SupportDir|Content/d2k/v2/BLOXBGBS.R8: BLOXBGBS.R8
|
^SupportDir|Content/d2k/v2/BLOXBGBS.R8: BLOXBGBS.R8
|
||||||
@@ -36,10 +36,10 @@ gruntmods: Dune 2000: GruntMods Edition
|
|||||||
^SupportDir|Content/d2k/v2/MOUSE.R8: MOUSE.R8
|
^SupportDir|Content/d2k/v2/MOUSE.R8: MOUSE.R8
|
||||||
^SupportDir|Content/d2k/v2/FONTCOL.FNT: FONTCOL.FNT
|
^SupportDir|Content/d2k/v2/FONTCOL.FNT: FONTCOL.FNT
|
||||||
^SupportDir|Content/d2k/v2/FONTCOL.FPL: FONTCOL.FPL
|
^SupportDir|Content/d2k/v2/FONTCOL.FPL: FONTCOL.FPL
|
||||||
copy: Dune 2000/data/bin
|
Copy: Dune 2000/data/bin
|
||||||
^SupportDir|Content/d2k/v2/PALETTE.BIN: PALETTE.BIN
|
^SupportDir|Content/d2k/v2/PALETTE.BIN: PALETTE.BIN
|
||||||
^SupportDir|Content/d2k/v2/FONT.BIN: FONT.BIN
|
^SupportDir|Content/d2k/v2/FONT.BIN: FONT.BIN
|
||||||
copy: Dune 2000/data/GAMESFX
|
Copy: Dune 2000/data/GAMESFX
|
||||||
^SupportDir|Content/d2k/v2/GAMESFX/A_ECONF2.AUD: A_ECONF2.AUD
|
^SupportDir|Content/d2k/v2/GAMESFX/A_ECONF2.AUD: A_ECONF2.AUD
|
||||||
^SupportDir|Content/d2k/v2/GAMESFX/A_ECONF1.AUD: A_ECONF1.AUD
|
^SupportDir|Content/d2k/v2/GAMESFX/A_ECONF1.AUD: A_ECONF1.AUD
|
||||||
^SupportDir|Content/d2k/v2/GAMESFX/A_ECONF3.AUD: A_ECONF3.AUD
|
^SupportDir|Content/d2k/v2/GAMESFX/A_ECONF3.AUD: A_ECONF3.AUD
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ aftermath: Aftermath Expansion Disc (English)
|
|||||||
README.TXT: 9902fb74c019df1b76ff5634e68f0371d790b5e0
|
README.TXT: 9902fb74c019df1b76ff5634e68f0371d790b5e0
|
||||||
SETUP/INSTALL/PATCH.RTP: 5bce93f834f9322ddaa7233242e5b6c7fea0bf17
|
SETUP/INSTALL/PATCH.RTP: 5bce93f834f9322ddaa7233242e5b6c7fea0bf17
|
||||||
Install:
|
Install:
|
||||||
extract-raw: SETUP/INSTALL/PATCH.RTP
|
ExtractRaw: SETUP/INSTALL/PATCH.RTP
|
||||||
^SupportDir|Content/ra/v2/expand/expand2.mix:
|
^SupportDir|Content/ra/v2/expand/expand2.mix:
|
||||||
Offset: 4712984
|
Offset: 4712984
|
||||||
Length: 469922
|
Length: 469922
|
||||||
@@ -13,7 +13,7 @@ aftermath: Aftermath Expansion Disc (English)
|
|||||||
^SupportDir|Content/ra/v2/expand/lores1.mix:
|
^SupportDir|Content/ra/v2/expand/lores1.mix:
|
||||||
Offset: 5273320
|
Offset: 5273320
|
||||||
Length: 57076
|
Length: 57076
|
||||||
extract-raw: MAIN.MIX
|
ExtractRaw: MAIN.MIX
|
||||||
^SupportDir|Content/ra/v2/expand/await.aud:
|
^SupportDir|Content/ra/v2/expand/await.aud:
|
||||||
Offset: 158698809
|
Offset: 158698809
|
||||||
Length: 2972788
|
Length: 2972788
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ allied: Red Alert 95 (Allied Disc, English)
|
|||||||
Length: 4096
|
Length: 4096
|
||||||
INSTALL/REDALERT.MIX: 0e58f4b54f44f6cd29fecf8cf379d33cf2d4caef
|
INSTALL/REDALERT.MIX: 0e58f4b54f44f6cd29fecf8cf379d33cf2d4caef
|
||||||
Install:
|
Install:
|
||||||
extract-raw: INSTALL/REDALERT.MIX
|
ExtractRaw: INSTALL/REDALERT.MIX
|
||||||
^SupportDir|Content/ra/v2/hires.mix:
|
^SupportDir|Content/ra/v2/hires.mix:
|
||||||
Offset: 650612
|
Offset: 650612
|
||||||
Length: 5817417
|
Length: 5817417
|
||||||
@@ -17,7 +17,7 @@ allied: Red Alert 95 (Allied Disc, English)
|
|||||||
^SupportDir|Content/ra/v2/speech.mix:
|
^SupportDir|Content/ra/v2/speech.mix:
|
||||||
Offset: 23042864
|
Offset: 23042864
|
||||||
Length: 2003464
|
Length: 2003464
|
||||||
extract-raw: MAIN.MIX
|
ExtractRaw: MAIN.MIX
|
||||||
^SupportDir|Content/ra/v2/conquer.mix:
|
^SupportDir|Content/ra/v2/conquer.mix:
|
||||||
Offset: 236
|
Offset: 236
|
||||||
Length: 2177047
|
Length: 2177047
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ cnc95: C&C Gold (GDI or Nod Disc, English)
|
|||||||
IDFiles:
|
IDFiles:
|
||||||
CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30
|
CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30
|
||||||
Install:
|
Install:
|
||||||
copy: .
|
Copy: .
|
||||||
^SupportDir|Content/ra/v2/cnc/desert.mix: DESERT.MIX
|
^SupportDir|Content/ra/v2/cnc/desert.mix: DESERT.MIX
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ counterstrike: Counterstrike Expansion Disc (English)
|
|||||||
README.TXT: 0efe8087383f0b159a9633f891fb5f53c6097cd4
|
README.TXT: 0efe8087383f0b159a9633f891fb5f53c6097cd4
|
||||||
SETUP/INSTALL/CSTRIKE.RTP: fae8ba82db71574f6ecd8fb4ff4026fcb65d2adc
|
SETUP/INSTALL/CSTRIKE.RTP: fae8ba82db71574f6ecd8fb4ff4026fcb65d2adc
|
||||||
Install:
|
Install:
|
||||||
extract-raw: MAIN.MIX
|
ExtractRaw: MAIN.MIX
|
||||||
^SupportDir|Content/ra/v2/expand/2nd_hand.aud:
|
^SupportDir|Content/ra/v2/expand/2nd_hand.aud:
|
||||||
Offset: 209070947
|
Offset: 209070947
|
||||||
Length: 3070092
|
Length: 3070092
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ tfd: C&C The First Decade (English)
|
|||||||
data1.hdr: bef3a08c3fc1b1caf28ca0dbb97c1f900005930e
|
data1.hdr: bef3a08c3fc1b1caf28ca0dbb97c1f900005930e
|
||||||
data1.cab: 12ad6113a6890a1b4d5651a75378c963eaf513b9
|
data1.cab: 12ad6113a6890a1b4d5651a75378c963eaf513b9
|
||||||
Install:
|
Install:
|
||||||
extract-iscab: data1.hdr
|
ExtractIscab: data1.hdr
|
||||||
Volumes:
|
Volumes:
|
||||||
2: data2.cab
|
2: data2.cab
|
||||||
3: data3.cab
|
3: data3.cab
|
||||||
@@ -16,7 +16,7 @@ tfd: C&C The First Decade (English)
|
|||||||
^SupportDir|Content/ra/v2/expand/lores1.mix: Red Alert\\LORES1.MIX
|
^SupportDir|Content/ra/v2/expand/lores1.mix: Red Alert\\LORES1.MIX
|
||||||
^SupportDir|Content/ra/v2/expand/expand2.mix: Red Alert\\EXPAND2.MIX
|
^SupportDir|Content/ra/v2/expand/expand2.mix: Red Alert\\EXPAND2.MIX
|
||||||
^SupportDir|Content/ra/v2/cnc/desert.mix: CnC\\DESERT.MIX
|
^SupportDir|Content/ra/v2/cnc/desert.mix: CnC\\DESERT.MIX
|
||||||
extract-raw: ^SupportDir|Content/ra/v2/redalert.mix
|
ExtractRaw: ^SupportDir|Content/ra/v2/redalert.mix
|
||||||
^SupportDir|Content/ra/v2/hires.mix:
|
^SupportDir|Content/ra/v2/hires.mix:
|
||||||
Offset: 650612
|
Offset: 650612
|
||||||
Length: 5817417
|
Length: 5817417
|
||||||
@@ -29,8 +29,8 @@ tfd: C&C The First Decade (English)
|
|||||||
^SupportDir|Content/ra/v2/speech.mix:
|
^SupportDir|Content/ra/v2/speech.mix:
|
||||||
Offset: 23042864
|
Offset: 23042864
|
||||||
Length: 2003464
|
Length: 2003464
|
||||||
delete: ^SupportDir|Content/ra/v2/redalert.mix
|
Delete: ^SupportDir|Content/ra/v2/redalert.mix
|
||||||
extract-raw: ^SupportDir|Content/ra/v2/main.mix
|
ExtractRaw: ^SupportDir|Content/ra/v2/main.mix
|
||||||
^SupportDir|Content/ra/v2/movies/aagun.vqa:
|
^SupportDir|Content/ra/v2/movies/aagun.vqa:
|
||||||
Offset: 668669829
|
Offset: 668669829
|
||||||
Length: 3295512
|
Length: 3295512
|
||||||
@@ -445,4 +445,4 @@ tfd: C&C The First Decade (English)
|
|||||||
^SupportDir|Content/ra/v2/expand/myes1.aud:
|
^SupportDir|Content/ra/v2/expand/myes1.aud:
|
||||||
Offset: 844509702
|
Offset: 844509702
|
||||||
Length: 9073
|
Length: 9073
|
||||||
delete: ^SupportDir|Content/ra/v2/main.mix
|
Delete: ^SupportDir|Content/ra/v2/main.mix
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ ra-origin: C&C The Ultimate Collection (Origin version, English)
|
|||||||
IDFiles:
|
IDFiles:
|
||||||
REDALERT.MIX: 0e58f4b54f44f6cd29fecf8cf379d33cf2d4caef
|
REDALERT.MIX: 0e58f4b54f44f6cd29fecf8cf379d33cf2d4caef
|
||||||
Install:
|
Install:
|
||||||
copy: .
|
Copy: .
|
||||||
^SupportDir|Content/ra/v2/expand/2nd_hand.aud: 2nd_hand.aud
|
^SupportDir|Content/ra/v2/expand/2nd_hand.aud: 2nd_hand.aud
|
||||||
^SupportDir|Content/ra/v2/expand/araziod.aud: araziod.aud
|
^SupportDir|Content/ra/v2/expand/araziod.aud: araziod.aud
|
||||||
^SupportDir|Content/ra/v2/expand/await.aud: await.aud
|
^SupportDir|Content/ra/v2/expand/await.aud: await.aud
|
||||||
@@ -27,7 +27,7 @@ ra-origin: C&C The Ultimate Collection (Origin version, English)
|
|||||||
^SupportDir|Content/ra/v2/expand/expand2.mix: EXPAND2.MIX
|
^SupportDir|Content/ra/v2/expand/expand2.mix: EXPAND2.MIX
|
||||||
^SupportDir|Content/ra/v2/expand/hires1.mix: HIRES1.MIX
|
^SupportDir|Content/ra/v2/expand/hires1.mix: HIRES1.MIX
|
||||||
^SupportDir|Content/ra/v2/expand/lores1.mix: LORES1.MIX
|
^SupportDir|Content/ra/v2/expand/lores1.mix: LORES1.MIX
|
||||||
extract-raw: REDALERT.MIX
|
ExtractRaw: REDALERT.MIX
|
||||||
^SupportDir|Content/ra/v2/hires.mix:
|
^SupportDir|Content/ra/v2/hires.mix:
|
||||||
Offset: 650612
|
Offset: 650612
|
||||||
Length: 5817417
|
Length: 5817417
|
||||||
@@ -40,7 +40,7 @@ ra-origin: C&C The Ultimate Collection (Origin version, English)
|
|||||||
^SupportDir|Content/ra/v2/speech.mix:
|
^SupportDir|Content/ra/v2/speech.mix:
|
||||||
Offset: 23042864
|
Offset: 23042864
|
||||||
Length: 2003464
|
Length: 2003464
|
||||||
extract-raw: MAIN.MIX
|
ExtractRaw: MAIN.MIX
|
||||||
^SupportDir|Content/ra/v2/movies/aagun.vqa:
|
^SupportDir|Content/ra/v2/movies/aagun.vqa:
|
||||||
Offset: 668669829
|
Offset: 668669829
|
||||||
Length: 3295512
|
Length: 3295512
|
||||||
@@ -464,5 +464,5 @@ cnc-origin: Command & Conquer (Origin version, English)
|
|||||||
IDFiles:
|
IDFiles:
|
||||||
CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30
|
CONQUER.MIX: 833e02a09aae694659eb312d3838367f681d1b30
|
||||||
Install:
|
Install:
|
||||||
copy: .
|
Copy: .
|
||||||
^SupportDir|Content/ra/v2/cnc/desert.mix: DESERT.MIX
|
^SupportDir|Content/ra/v2/cnc/desert.mix: DESERT.MIX
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ soviet: Red Alert 95 (Soviet Disc, English)
|
|||||||
Length: 4096
|
Length: 4096
|
||||||
INSTALL/REDALERT.MIX: 0e58f4b54f44f6cd29fecf8cf379d33cf2d4caef
|
INSTALL/REDALERT.MIX: 0e58f4b54f44f6cd29fecf8cf379d33cf2d4caef
|
||||||
Install:
|
Install:
|
||||||
extract-raw: INSTALL/REDALERT.MIX
|
ExtractRaw: INSTALL/REDALERT.MIX
|
||||||
^SupportDir|Content/ra/v2/hires.mix:
|
^SupportDir|Content/ra/v2/hires.mix:
|
||||||
Offset: 650612
|
Offset: 650612
|
||||||
Length: 5817417
|
Length: 5817417
|
||||||
@@ -17,7 +17,7 @@ soviet: Red Alert 95 (Soviet Disc, English)
|
|||||||
^SupportDir|Content/ra/v2/speech.mix:
|
^SupportDir|Content/ra/v2/speech.mix:
|
||||||
Offset: 23042864
|
Offset: 23042864
|
||||||
Length: 2003464
|
Length: 2003464
|
||||||
extract-raw: MAIN.MIX
|
ExtractRaw: MAIN.MIX
|
||||||
^SupportDir|Content/ra/v2/conquer.mix:
|
^SupportDir|Content/ra/v2/conquer.mix:
|
||||||
Offset: 236
|
Offset: 236
|
||||||
Length: 2177047
|
Length: 2177047
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ fstorm: Firestorm Expansion Disc (English)
|
|||||||
Install/README.TXT: f2810b540fce8f3880250213ee08c57780d81c20
|
Install/README.TXT: f2810b540fce8f3880250213ee08c57780d81c20
|
||||||
Install/Language.dll: 4df87c1a2289da57dd14d0a7299546f37357fcca
|
Install/Language.dll: 4df87c1a2289da57dd14d0a7299546f37357fcca
|
||||||
Install:
|
Install:
|
||||||
copy: .
|
Copy: .
|
||||||
^SupportDir|Content/ts/firestorm/scores01.mix: scores01.mix
|
^SupportDir|Content/ts/firestorm/scores01.mix: scores01.mix
|
||||||
extract-raw: Install/expand01.mix
|
ExtractRaw: Install/expand01.mix
|
||||||
^SupportDir|Content/ts/firestorm/m_emp.vxl:
|
^SupportDir|Content/ts/firestorm/m_emp.vxl:
|
||||||
Offset: 2187652
|
Offset: 2187652
|
||||||
Length: 24652
|
Length: 24652
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ tfd: C&C The First Decade (English)
|
|||||||
data1.hdr: bef3a08c3fc1b1caf28ca0dbb97c1f900005930e
|
data1.hdr: bef3a08c3fc1b1caf28ca0dbb97c1f900005930e
|
||||||
data1.cab: 12ad6113a6890a1b4d5651a75378c963eaf513b9
|
data1.cab: 12ad6113a6890a1b4d5651a75378c963eaf513b9
|
||||||
Install:
|
Install:
|
||||||
extract-iscab: data1.hdr
|
ExtractIscab: data1.hdr
|
||||||
Volumes:
|
Volumes:
|
||||||
6: data6.cab
|
6: data6.cab
|
||||||
7: data7.cab
|
7: data7.cab
|
||||||
@@ -12,7 +12,7 @@ tfd: C&C The First Decade (English)
|
|||||||
^SupportDir|Content/ts/tibsun.mix: Tiberian Sun\SUN\TIBSUN.MIX
|
^SupportDir|Content/ts/tibsun.mix: Tiberian Sun\SUN\TIBSUN.MIX
|
||||||
^SupportDir|Content/ts/expand01.mix: Tiberian Sun\SUN\expand01.mix
|
^SupportDir|Content/ts/expand01.mix: Tiberian Sun\SUN\expand01.mix
|
||||||
^SupportDir|Content/ts/firestorm/scores01.mix: Tiberian Sun\SUN\scores01.mix
|
^SupportDir|Content/ts/firestorm/scores01.mix: Tiberian Sun\SUN\scores01.mix
|
||||||
extract-raw: ^SupportDir|Content/ts/tibsun.mix
|
ExtractRaw: ^SupportDir|Content/ts/tibsun.mix
|
||||||
^SupportDir|Content/ts/cache.mix:
|
^SupportDir|Content/ts/cache.mix:
|
||||||
Offset: 300
|
Offset: 300
|
||||||
Length: 169176
|
Length: 169176
|
||||||
@@ -55,8 +55,8 @@ tfd: C&C The First Decade (English)
|
|||||||
^SupportDir|Content/ts/temperat.mix:
|
^SupportDir|Content/ts/temperat.mix:
|
||||||
Offset: 73056940
|
Offset: 73056940
|
||||||
Length: 2037606
|
Length: 2037606
|
||||||
delete: ^SupportDir|Content/ts/tibsun.mix
|
Delete: ^SupportDir|Content/ts/tibsun.mix
|
||||||
extract-raw: ^SupportDir|Content/ts/expand01.mix
|
ExtractRaw: ^SupportDir|Content/ts/expand01.mix
|
||||||
^SupportDir|Content/ts/firestorm/m_emp.vxl:
|
^SupportDir|Content/ts/firestorm/m_emp.vxl:
|
||||||
Offset: 2187652
|
Offset: 2187652
|
||||||
Length: 24652
|
Length: 24652
|
||||||
@@ -591,4 +591,4 @@ tfd: C&C The First Decade (English)
|
|||||||
^SupportDir|Content/ts/firestorm/sounds01.mix:
|
^SupportDir|Content/ts/firestorm/sounds01.mix:
|
||||||
Offset: 28229956
|
Offset: 28229956
|
||||||
Length: 990096
|
Length: 990096
|
||||||
delete: ^SupportDir|Content/ts/expand01.mix
|
Delete: ^SupportDir|Content/ts/expand01.mix
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ origin: C&C The Ultimate Collection (Origin version, English)
|
|||||||
IDFiles:
|
IDFiles:
|
||||||
GDFBinary_en_US.dll: 4bb56a449bd0003e7ae67625d90a11ae169319d6
|
GDFBinary_en_US.dll: 4bb56a449bd0003e7ae67625d90a11ae169319d6
|
||||||
Install:
|
Install:
|
||||||
copy: .
|
Copy: .
|
||||||
^SupportDir|Content/ts/scores.mix: SCORES.MIX
|
^SupportDir|Content/ts/scores.mix: SCORES.MIX
|
||||||
^SupportDir|Content/ts/firestorm/scores01.mix: scores01.mix
|
^SupportDir|Content/ts/firestorm/scores01.mix: scores01.mix
|
||||||
extract-raw: TIBSUN.MIX
|
ExtractRaw: TIBSUN.MIX
|
||||||
^SupportDir|Content/ts/cache.mix:
|
^SupportDir|Content/ts/cache.mix:
|
||||||
Offset: 300
|
Offset: 300
|
||||||
Length: 169176
|
Length: 169176
|
||||||
@@ -52,7 +52,7 @@ origin: C&C The Ultimate Collection (Origin version, English)
|
|||||||
^SupportDir|Content/ts/temperat.mix:
|
^SupportDir|Content/ts/temperat.mix:
|
||||||
Offset: 73056940
|
Offset: 73056940
|
||||||
Length: 2037606
|
Length: 2037606
|
||||||
extract-raw: expand01.mix
|
ExtractRaw: expand01.mix
|
||||||
^SupportDir|Content/ts/firestorm/m_emp.vxl:
|
^SupportDir|Content/ts/firestorm/m_emp.vxl:
|
||||||
Offset: 2187652
|
Offset: 2187652
|
||||||
Length: 24652
|
Length: 24652
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ tibsun: Tiberian Sun (GDI or Nod Disc, English)
|
|||||||
README.TXT: 45745c4a0c888317ec900208a426472779c42bf7
|
README.TXT: 45745c4a0c888317ec900208a426472779c42bf7
|
||||||
AUTOPLAY.WAV: 2dfce5d00f98b641849c29942b651f4e98d30e30
|
AUTOPLAY.WAV: 2dfce5d00f98b641849c29942b651f4e98d30e30
|
||||||
Install:
|
Install:
|
||||||
copy: .
|
Copy: .
|
||||||
^SupportDir|Content/ts/scores.mix: SCORES.MIX
|
^SupportDir|Content/ts/scores.mix: SCORES.MIX
|
||||||
extract-raw: INSTALL/TIBSUN.MIX
|
ExtractRaw: INSTALL/TIBSUN.MIX
|
||||||
^SupportDir|Content/ts/cache.mix:
|
^SupportDir|Content/ts/cache.mix:
|
||||||
Offset: 300
|
Offset: 300
|
||||||
Length: 169176
|
Length: 169176
|
||||||
|
|||||||
Reference in New Issue
Block a user