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.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using GarrysMod.AddonCreator.Hashing;
|
using GarrysMod.AddonCreator.Hashing;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using TagLib;
|
||||||
|
using File = System.IO.File;
|
||||||
|
|
||||||
namespace GarrysMod.AddonCreator.Addon
|
namespace GarrysMod.AddonCreator.Addon
|
||||||
{
|
{
|
||||||
|
@ -24,6 +27,7 @@ namespace GarrysMod.AddonCreator.Addon
|
||||||
Files = new Dictionary<string, AddonFileInfo>();
|
Files = new Dictionary<string, AddonFileInfo>();
|
||||||
RequiredContent = new List<string>();
|
RequiredContent = new List<string>();
|
||||||
Version = 1;
|
Version = 1;
|
||||||
|
MinimizeMedia = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -67,6 +71,16 @@ namespace GarrysMod.AddonCreator.Addon
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<string> RequiredContent { get; private set; }
|
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>
|
/// <summary>
|
||||||
/// Imports a gmod addon into this instance.
|
/// Imports a gmod addon into this instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -153,7 +167,7 @@ namespace GarrysMod.AddonCreator.Addon
|
||||||
var fileSize = sr.ReadInt64();
|
var fileSize = sr.ReadInt64();
|
||||||
var fileHash = sr.ReadInt32();
|
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);
|
Debug.Assert(fileId == expectedFileId);
|
||||||
|
|
||||||
expectedFileId++;
|
expectedFileId++;
|
||||||
|
@ -177,7 +191,7 @@ namespace GarrysMod.AddonCreator.Addon
|
||||||
var fileHash = file.Value.Item2;
|
var fileHash = file.Value.Item2;
|
||||||
var filePosition = sr.BaseStream.Position;
|
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];
|
var fileContent = new byte[fileSize];
|
||||||
|
|
||||||
|
@ -226,12 +240,26 @@ namespace GarrysMod.AddonCreator.Addon
|
||||||
|
|
||||||
if (MinimizeLua)
|
if (MinimizeLua)
|
||||||
files = files
|
files = files
|
||||||
// minimize lua code
|
|
||||||
.Select(f => f.Key.EndsWith(".lua", StringComparison.OrdinalIgnoreCase)
|
.Select(f => f.Key.EndsWith(".lua", StringComparison.OrdinalIgnoreCase)
|
||||||
? new KeyValuePair<string, AddonFileInfo>(f.Key, new MinifiedLuaAddonFileInfo(f.Value))
|
? new KeyValuePair<string, AddonFileInfo>(f.Key, new MinifiedLuaAddonFileInfo(f.Value))
|
||||||
: f)
|
: f)
|
||||||
.ToDictionary(i => i.Key, i => i.Value);
|
.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
|
// Check for errors and ignores in addon.json
|
||||||
var addonJson =
|
var addonJson =
|
||||||
JsonConvert.DeserializeObject<AddonJson>(Encoding.UTF8.GetString(Files["addon.json"].GetContents()));
|
JsonConvert.DeserializeObject<AddonJson>(Encoding.UTF8.GetString(Files["addon.json"].GetContents()));
|
||||||
|
@ -311,7 +339,8 @@ namespace GarrysMod.AddonCreator.Addon
|
||||||
uint fileNum = 0;
|
uint fileNum = 0;
|
||||||
foreach (var file in resultingFiles)
|
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++;
|
fileNum++;
|
||||||
sw.Write(fileNum);
|
sw.Write(fileNum);
|
||||||
|
@ -322,14 +351,41 @@ namespace GarrysMod.AddonCreator.Addon
|
||||||
sw.Write((uint) 0); // End of file list
|
sw.Write((uint) 0); // End of file list
|
||||||
|
|
||||||
// File contents
|
// File contents
|
||||||
foreach (var file in resultingFiles)
|
foreach (var file in resultingFiles
|
||||||
|
.Where(file => file.Value.Size != 0))
|
||||||
{
|
{
|
||||||
if (file.Value.Size == 0)
|
#if DEBUG
|
||||||
continue;
|
Console.WriteLine("Packing: {0} ({1})", file.Key,
|
||||||
|
file.Value.GetType().Name.Replace("AddonFileInfo", ""));
|
||||||
|
#else
|
||||||
Console.WriteLine("Packing: {0}", file.Key);
|
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
|
// 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>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>$(SolutionDir)\packages\Newtonsoft.Json.6.0.5\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>$(SolutionDir)\packages\Newtonsoft.Json.6.0.5\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</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" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="taglib-sharp">
|
||||||
|
<HintPath>..\..\packages\taglib.2.1.0.0\lib\taglib-sharp.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Addon\AddonFile.cs" />
|
<Compile Include="Addon\AddonFile.cs" />
|
||||||
|
@ -57,6 +63,7 @@
|
||||||
<Compile Include="Addon\AddonJson.cs" />
|
<Compile Include="Addon\AddonJson.cs" />
|
||||||
<Compile Include="Addon\AddonWhitelist.cs" />
|
<Compile Include="Addon\AddonWhitelist.cs" />
|
||||||
<Compile Include="Addon\MinifiedLuaAddonFileInfo.cs" />
|
<Compile Include="Addon\MinifiedLuaAddonFileInfo.cs" />
|
||||||
|
<Compile Include="Addon\MinifiedMediaAddonFileInfo.cs" />
|
||||||
<Compile Include="Extensions.cs" />
|
<Compile Include="Extensions.cs" />
|
||||||
<Compile Include="Addon\JsonAddonFileInfo.cs" />
|
<Compile Include="Addon\JsonAddonFileInfo.cs" />
|
||||||
<Compile Include="Hashing\Crc32.cs" />
|
<Compile Include="Hashing\Crc32.cs" />
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using GarrysMod.AddonCreator.Addon;
|
using GarrysMod.AddonCreator.Addon;
|
||||||
|
|
||||||
namespace GarrysMod.AddonCreator
|
namespace GarrysMod.AddonCreator
|
||||||
|
@ -12,6 +11,7 @@ namespace GarrysMod.AddonCreator
|
||||||
private static void Main(string[] args)
|
private static void Main(string[] args)
|
||||||
{
|
{
|
||||||
var minimizeLua = false;
|
var minimizeLua = false;
|
||||||
|
var minimizeMedia = true;
|
||||||
|
|
||||||
while (args.Any())
|
while (args.Any())
|
||||||
{
|
{
|
||||||
|
@ -25,6 +25,14 @@ namespace GarrysMod.AddonCreator
|
||||||
minimizeLua = false;
|
minimizeLua = false;
|
||||||
args = args.Skip(1).ToArray();
|
args = args.Skip(1).ToArray();
|
||||||
break;
|
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":
|
case "create":
|
||||||
{
|
{
|
||||||
if (args.Length < 3)
|
if (args.Length < 3)
|
||||||
|
@ -34,7 +42,7 @@ namespace GarrysMod.AddonCreator
|
||||||
|
|
||||||
var folder = new DirectoryInfo(args[1]);
|
var folder = new DirectoryInfo(args[1]);
|
||||||
var output = args[2];
|
var output = args[2];
|
||||||
var addon = new AddonFile {MinimizeLua = minimizeLua};
|
var addon = new AddonFile {MinimizeLua = minimizeLua, MinimizeMedia = minimizeMedia};
|
||||||
|
|
||||||
if (!folder.Exists)
|
if (!folder.Exists)
|
||||||
{
|
{
|
||||||
|
@ -143,7 +151,8 @@ namespace GarrysMod.AddonCreator
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
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();
|
||||||
Console.WriteLine("Commands:");
|
Console.WriteLine("Commands:");
|
||||||
Console.WriteLine("\t{0}\t{1}", "extract", "Extracts a GMA file and shows information about it.");
|
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("\t\tArguments: Input folder path, output GMA file path");
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine("Options:");
|
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}", "--minimize-lua",
|
||||||
Console.WriteLine("\t{0}\t{1}", "--no-minimize-lua", "(default) Will prevent Lua files getting minimized.");
|
"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();
|
Console.WriteLine();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Newtonsoft.Json" version="6.0.5" targetFramework="net40" />
|
<package id="Newtonsoft.Json" version="6.0.5" targetFramework="net40" />
|
||||||
|
<package id="taglib" version="2.1.0.0" targetFramework="net40" />
|
||||||
</packages>
|
</packages>
|
Loading…
Reference in New Issue