Add basic media minifying (only strips tags and checks for corruption).
parent
d247c85ee9
commit
1a4a771697
|
@ -3,9 +3,12 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using GarrysMod.AddonCreator.Hashing;
|
||||
using Newtonsoft.Json;
|
||||
using TagLib;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace GarrysMod.AddonCreator.Addon
|
||||
{
|
||||
|
@ -24,6 +27,7 @@ namespace GarrysMod.AddonCreator.Addon
|
|||
Files = new Dictionary<string, AddonFileInfo>();
|
||||
RequiredContent = new List<string>();
|
||||
Version = 1;
|
||||
MinimizeMedia = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -67,6 +71,16 @@ namespace GarrysMod.AddonCreator.Addon
|
|||
/// </summary>
|
||||
public List<string> RequiredContent { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether Lua files will have comments and unnecessary whitespace stripped out on export.
|
||||
/// </summary>
|
||||
public bool MinimizeLua { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether media files will have all game-irrelevant information (like ID3 tags) stripped out on export.
|
||||
/// </summary>
|
||||
public bool MinimizeMedia { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Imports a gmod addon into this instance.
|
||||
/// </summary>
|
||||
|
@ -153,7 +167,7 @@ namespace GarrysMod.AddonCreator.Addon
|
|||
var fileSize = sr.ReadInt64();
|
||||
var fileHash = sr.ReadInt32();
|
||||
|
||||
Debug.WriteLine("\t#{2} : {0} ({1:0.0} kB)", filePath, (double)fileSize/1024, fileId);
|
||||
Debug.WriteLine("\t#{2} : {0} ({1:0.0} kB)", filePath, (double) fileSize/1024, fileId);
|
||||
Debug.Assert(fileId == expectedFileId);
|
||||
|
||||
expectedFileId++;
|
||||
|
@ -177,7 +191,7 @@ namespace GarrysMod.AddonCreator.Addon
|
|||
var fileHash = file.Value.Item2;
|
||||
var filePosition = sr.BaseStream.Position;
|
||||
|
||||
Debug.WriteLine("Analyzing: {0} ({1:0.00} kB)", filePath, (double)fileSize / 1024);
|
||||
Debug.WriteLine("Analyzing: {0} ({1:0.00} kB)", filePath, (double) fileSize/1024);
|
||||
|
||||
var fileContent = new byte[fileSize];
|
||||
|
||||
|
@ -226,12 +240,26 @@ namespace GarrysMod.AddonCreator.Addon
|
|||
|
||||
if (MinimizeLua)
|
||||
files = files
|
||||
// minimize lua code
|
||||
.Select(f => f.Key.EndsWith(".lua", StringComparison.OrdinalIgnoreCase)
|
||||
? new KeyValuePair<string, AddonFileInfo>(f.Key, new MinifiedLuaAddonFileInfo(f.Value))
|
||||
: f)
|
||||
.ToDictionary(i => i.Key, i => i.Value);
|
||||
|
||||
files = files
|
||||
.Select(f => Assembly.LoadFrom("taglib-sharp.dll")
|
||||
.GetTypes()
|
||||
.Where(t => t.IsSubclassOf(typeof (TagLib.File)))
|
||||
.Any(mediaSupport => mediaSupport.GetCustomAttributes(typeof (SupportedMimeType), false)
|
||||
.Select(t => t as SupportedMimeType)
|
||||
.Any(mediaSupportExt => mediaSupportExt.Extension != null
|
||||
&& f.Key.ToLower().EndsWith("." +
|
||||
(mediaSupportExt.Extension.TrimStart('.')
|
||||
.ToLower()))))
|
||||
? new KeyValuePair<string, AddonFileInfo>(f.Key,
|
||||
new MinifiedMediaAddonFileInfo(f.Value, f.Key.Split('.').Last()) {StripTags = MinimizeMedia})
|
||||
: f)
|
||||
.ToDictionary(i => i.Key, i => i.Value);
|
||||
|
||||
// Check for errors and ignores in addon.json
|
||||
var addonJson =
|
||||
JsonConvert.DeserializeObject<AddonJson>(Encoding.UTF8.GetString(Files["addon.json"].GetContents()));
|
||||
|
@ -311,7 +339,8 @@ namespace GarrysMod.AddonCreator.Addon
|
|||
uint fileNum = 0;
|
||||
foreach (var file in resultingFiles)
|
||||
{
|
||||
Console.WriteLine("Processing: {0} ({1:0.00} kB)", file.Key, (double)file.Value.Size / 1024);
|
||||
Console.Write("Processing: {0}", file.Key);
|
||||
Console.WriteLine(" ({0:0.00} kB)", (double) file.Value.Size/1024);
|
||||
|
||||
fileNum++;
|
||||
sw.Write(fileNum);
|
||||
|
@ -322,14 +351,41 @@ namespace GarrysMod.AddonCreator.Addon
|
|||
sw.Write((uint) 0); // End of file list
|
||||
|
||||
// File contents
|
||||
foreach (var file in resultingFiles)
|
||||
foreach (var file in resultingFiles
|
||||
.Where(file => file.Value.Size != 0))
|
||||
{
|
||||
if (file.Value.Size == 0)
|
||||
continue;
|
||||
|
||||
#if DEBUG
|
||||
Console.WriteLine("Packing: {0} ({1})", file.Key,
|
||||
file.Value.GetType().Name.Replace("AddonFileInfo", ""));
|
||||
#else
|
||||
Console.WriteLine("Packing: {0}", file.Key);
|
||||
#endif
|
||||
|
||||
sw.Write(file.Value.GetContents());
|
||||
byte[] contents;
|
||||
try
|
||||
{
|
||||
contents = file.Value.GetContents();
|
||||
}
|
||||
catch (CorruptFileException e)
|
||||
{
|
||||
var mediaFile = file.Value as MinifiedMediaAddonFileInfo;
|
||||
if (mediaFile == null)
|
||||
{
|
||||
throw new Exception(); // what the fuck logic
|
||||
}
|
||||
|
||||
var oldColor = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
|
||||
Console.Error.WriteLine("Warning: File {0} possibly corrupted - {1}", file.Key, e.Message);
|
||||
|
||||
Console.ForegroundColor = oldColor;
|
||||
|
||||
mediaFile.IgnoreCorrupted = true;
|
||||
contents = mediaFile.GetContents();
|
||||
}
|
||||
|
||||
sw.Write(contents);
|
||||
}
|
||||
|
||||
// Addon CRC
|
||||
|
@ -343,10 +399,5 @@ namespace GarrysMod.AddonCreator.Addon
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether Lua files will have comments and unnecessary whitespace stripped out on export.
|
||||
/// </summary>
|
||||
public bool MinimizeLua { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TagLib;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace GarrysMod.AddonCreator.Addon
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a media addon file with the possibility of stripping tags and checking for corruptions.
|
||||
/// </summary>
|
||||
public class MinifiedMediaAddonFileInfo : AddonFileInfo
|
||||
{
|
||||
private readonly string _tempFile;
|
||||
|
||||
private bool _processed;
|
||||
|
||||
~MinifiedMediaAddonFileInfo()
|
||||
{
|
||||
File.Delete(_tempFile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="MinifiedMediaAddonFileInfo"/> instance using the given addon file.
|
||||
/// </summary>
|
||||
/// <param name="file">The addon file, supposedly a media file</param>
|
||||
public MinifiedMediaAddonFileInfo(AddonFileInfo file, string extension)
|
||||
{
|
||||
_tempFile = Path.GetTempFileName();
|
||||
var dirName = Path.GetDirectoryName(_tempFile);
|
||||
if (dirName == null)
|
||||
throw new InvalidOperationException("Temporary directory is NULL");
|
||||
|
||||
// Fix extension, needed for TagLib to detect file format properly
|
||||
var newTempFile = Path.Combine(
|
||||
dirName,
|
||||
Path.GetFileNameWithoutExtension(_tempFile) + "." + extension);
|
||||
File.Move(_tempFile, newTempFile);
|
||||
_tempFile = newTempFile;
|
||||
|
||||
using (var s = new FileStream(_tempFile, FileMode.OpenOrCreate, FileAccess.Write))
|
||||
{
|
||||
var buffer = file.GetContents();
|
||||
s.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether tags should be stripped or not.
|
||||
/// </summary>
|
||||
public bool StripTags { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether to ignore possible file corruption.
|
||||
/// </summary>
|
||||
public bool IgnoreCorrupted { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Processes the media file, applies any wanted stripping and returns the new file contents.
|
||||
/// </summary>
|
||||
/// <returns>The contents of the media file with optional applied stripping</returns>
|
||||
/// <exception cref="CorruptFileException">Will be thrown when TagLib detects possible media file corruptions</exception>
|
||||
public override byte[] GetContents()
|
||||
{
|
||||
if (_processed)
|
||||
{
|
||||
using (var s = new FileStream(_tempFile, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
var buffer = new byte[s.Length];
|
||||
s.Read(buffer, 0, buffer.Length);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
using (var tags = TagLib.File.Create(_tempFile))
|
||||
{
|
||||
if (tags.PossiblyCorrupt && !IgnoreCorrupted)
|
||||
{
|
||||
throw new CorruptFileException(string.Join("; ", tags.CorruptionReasons));
|
||||
}
|
||||
|
||||
if (StripTags)
|
||||
{
|
||||
tags.RemoveTags(TagTypes.AllTags);
|
||||
}
|
||||
|
||||
tags.Save();
|
||||
}
|
||||
|
||||
_processed = true;
|
||||
|
||||
// This will now return the file contents instead
|
||||
return GetContents();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -48,8 +48,14 @@
|
|||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>$(SolutionDir)\packages\Newtonsoft.Json.6.0.5\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="policy.2.0.taglib-sharp">
|
||||
<HintPath>..\..\packages\taglib.2.1.0.0\lib\policy.2.0.taglib-sharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="taglib-sharp">
|
||||
<HintPath>..\..\packages\taglib.2.1.0.0\lib\taglib-sharp.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Addon\AddonFile.cs" />
|
||||
|
@ -57,6 +63,7 @@
|
|||
<Compile Include="Addon\AddonJson.cs" />
|
||||
<Compile Include="Addon\AddonWhitelist.cs" />
|
||||
<Compile Include="Addon\MinifiedLuaAddonFileInfo.cs" />
|
||||
<Compile Include="Addon\MinifiedMediaAddonFileInfo.cs" />
|
||||
<Compile Include="Extensions.cs" />
|
||||
<Compile Include="Addon\JsonAddonFileInfo.cs" />
|
||||
<Compile Include="Hashing\Crc32.cs" />
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using GarrysMod.AddonCreator.Addon;
|
||||
|
||||
namespace GarrysMod.AddonCreator
|
||||
|
@ -12,6 +11,7 @@ namespace GarrysMod.AddonCreator
|
|||
private static void Main(string[] args)
|
||||
{
|
||||
var minimizeLua = false;
|
||||
var minimizeMedia = true;
|
||||
|
||||
while (args.Any())
|
||||
{
|
||||
|
@ -25,6 +25,14 @@ namespace GarrysMod.AddonCreator
|
|||
minimizeLua = false;
|
||||
args = args.Skip(1).ToArray();
|
||||
break;
|
||||
case "--minimize-media":
|
||||
minimizeMedia = true;
|
||||
args = args.Skip(1).ToArray();
|
||||
break;
|
||||
case "--no-minimize-media":
|
||||
minimizeMedia = false;
|
||||
args = args.Skip(1).ToArray();
|
||||
break;
|
||||
case "create":
|
||||
{
|
||||
if (args.Length < 3)
|
||||
|
@ -34,7 +42,7 @@ namespace GarrysMod.AddonCreator
|
|||
|
||||
var folder = new DirectoryInfo(args[1]);
|
||||
var output = args[2];
|
||||
var addon = new AddonFile {MinimizeLua = minimizeLua};
|
||||
var addon = new AddonFile {MinimizeLua = minimizeLua, MinimizeMedia = minimizeMedia};
|
||||
|
||||
if (!folder.Exists)
|
||||
{
|
||||
|
@ -143,7 +151,8 @@ namespace GarrysMod.AddonCreator
|
|||
}
|
||||
|
||||
default:
|
||||
Console.WriteLine("Usage: {0} <options> <command> <arguments>", Process.GetCurrentProcess().ProcessName);
|
||||
Console.WriteLine("Usage: {0} <options> <command> <arguments>",
|
||||
Process.GetCurrentProcess().ProcessName);
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Commands:");
|
||||
Console.WriteLine("\t{0}\t{1}", "extract", "Extracts a GMA file and shows information about it.");
|
||||
|
@ -152,8 +161,14 @@ namespace GarrysMod.AddonCreator
|
|||
Console.WriteLine("\t\tArguments: Input folder path, output GMA file path");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Options:");
|
||||
Console.WriteLine("\t{0}\t{1}", "--minimize-lua", "Causes exported GMAs to have all Lua comments and unneeded whitespace in Lua stripped out.");
|
||||
Console.WriteLine("\t{0}\t{1}", "--no-minimize-lua", "(default) Will prevent Lua files getting minimized.");
|
||||
Console.WriteLine("\t{0}\t{1}", "--minimize-lua",
|
||||
"Causes exported GMAs to have all Lua comments and unneeded whitespace in Lua stripped out.");
|
||||
Console.WriteLine("\t{0}\t{1}", "--no-minimize-lua",
|
||||
"(default) Will prevent Lua files getting minimized.");
|
||||
Console.WriteLine("\t{0}\t{1}", "--minimize-media",
|
||||
"(default) Causes exported GMAs to have all media tags stripped out.");
|
||||
Console.WriteLine("\t{0}\t{1}", "--no-minimize-media",
|
||||
"Will prevent media files getting minimized.");
|
||||
Console.WriteLine();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="6.0.5" targetFramework="net40" />
|
||||
<package id="taglib" version="2.1.0.0" targetFramework="net40" />
|
||||
</packages>
|
Loading…
Reference in New Issue