Skip to content

Instantly share code, notes, and snippets.

@DatZach
Created January 22, 2018 02:16
Show Gist options
  • Save DatZach/49dfe6ce7f7ff9cc4569907e742f8850 to your computer and use it in GitHub Desktop.
Save DatZach/49dfe6ce7f7ff9cc4569907e742f8850 to your computer and use it in GitHub Desktop.
Igor Interception
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
// References = System, System.Runtime.Serialization, System.XML
namespace WowCompiler
{
public static class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Igor Interception");
var igorArgs = IgorRuntimeConfig.FromCommandLine(args);
var buildOptions = IgorBuildOptions.FromFile(igorArgs.OptionsPath);
//buildOptions.targetFile = "windows2.zip";
//buildOptions.Save();
Console.WriteLine("Project Path = {0}", buildOptions.projectPath);
Igor.Invoke(igorArgs);
}
}
internal static class Igor
{
private static string AssemblyDirectory
{
get
{
var codeBase = Assembly.GetExecutingAssembly().CodeBase;
var uri = new UriBuilder(codeBase);
var path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
}
private static string IgorPath => Path.Combine(AssemblyDirectory, "Igor.Runtime.exe");
public static void Invoke(IgorRuntimeConfig runtimeConfig)
{
if (runtimeConfig == null)
throw new ArgumentNullException(nameof(runtimeConfig));
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = IgorPath,
Arguments = runtimeConfig.ToString(),
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
}
};
process.OutputDataReceived += ReadOutput;
process.ErrorDataReceived += ReadError;
if (!process.Start())
return;
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
}
private static void ReadOutput(object sendingProcess, DataReceivedEventArgs outLine)
{
Console.WriteLine(outLine.Data);
}
private static void ReadError(object sendingProcess, DataReceivedEventArgs outLine)
{
var prevColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(outLine.Data);
Console.ForegroundColor = prevColor;
}
}
internal sealed class IgorRuntimeConfig
{
public string OptionsPath { get; set; }
public string Platform { get; set; }
public string Command { get; set; }
public override string ToString()
{
var builder = new StringBuilder();
builder.AppendFormat("-options=\"{0}\"", OptionsPath);
builder.Append(' ');
builder.Append("--");
builder.Append(' ');
builder.Append(Platform);
builder.Append(' ');
builder.Append(Command);
return builder.ToString();
}
public static IgorRuntimeConfig FromCommandLine(string[] args)
{
if (args == null)
throw new ArgumentNullException(nameof(args));
var optionsArg = args.SingleOrDefault(x => x.StartsWith("-options"));
string[] optionsParts;
if (optionsArg == null || (optionsParts = optionsArg.Split('=')).Length < 2)
throw new ArgumentException("Required '-options' parameter not specified");
var idx = Array.IndexOf(args, "--");
if (idx < 0)
throw new ArgumentException("Required '--' flag missing");
var platform = args.Length > idx + 1 ? args[idx + 1] : null;
var command = args.Length > idx + 2 ? args[idx + 2] : null;
if (platform == null)
throw new ArgumentException("Expected platform to be specified after --");
if (command == null)
throw new ArgumentException("Expected command to be specified after --");
return new IgorRuntimeConfig
{
OptionsPath = string.Join("", optionsParts.Skip(1)),
Platform = platform,
Command = command
};
}
}
[DataContract]
internal sealed class IgorBuildOptions
{
[DataMember]
public string targetFile { get; set; }
[DataMember]
public string assetCompiler { get; set; }
[DataMember]
public string debug { get; set; }
[DataMember]
public string compile_output_file_name { get; set; }
[DataMember]
public string useShaders { get; set; }
[DataMember]
public string steamOptions { get; set; }
[DataMember]
public string config { get; set; }
[DataMember]
public string outputFolder { get; set; }
[DataMember]
public string projectName { get; set; }
[DataMember]
public string projectDir { get; set; }
[DataMember]
public string preferences { get; set; }
[DataMember]
public string projectPath { get; set; }
[DataMember]
public string tempFolder { get; set; }
[DataMember]
public string userDir { get; set; }
[DataMember]
public string runtimeLocation { get; set; }
[DataMember]
public string applicationPath { get; set; }
[DataMember]
public string macros { get; set; }
[DataMember]
public string targetOptions { get; set; }
[DataMember]
public string targetMask { get; set; }
[DataMember]
public string verbose { get; set; }
[DataMember]
public string helpPort { get; set; }
[DataMember]
public string debuggerPort { get; set; }
private string buildOptionsPath;
private IgorBuildOptions()
{
// NOTE Private ctor to enforce factory pattern
}
public void Save()
{
using (var stream = new MemoryStream())
{
var json = CreateSerialize(typeof(IgorBuildOptions));
json.WriteObject(stream, this);
var serializedJson = Encoding.UTF8.GetString(stream.ToArray());
File.WriteAllText(buildOptionsPath, serializedJson);
}
}
public static IgorBuildOptions FromFile(string path)
{
if (path == null)
throw new ArgumentNullException(nameof(path));
using (var stream = File.OpenRead(path))
{
var json = CreateSerialize(typeof(IgorBuildOptions));
var options = (IgorBuildOptions)json.ReadObject(stream);
options.buildOptionsPath = path;
return options;
}
}
private static DataContractJsonSerializer CreateSerialize(Type type)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
return new DataContractJsonSerializer(
type,
new DataContractJsonSerializerSettings()
);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment