Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Xml.Serialization;
- namespace gsmake
- {
- [Serializable]
- [XmlType(TypeName = "project")]
- public sealed class Project
- {
- public class CPath
- {
- [XmlAttribute(AttributeName = "path")]
- public string Path;
- }
- [XmlElement(ElementName = "input")]
- public CPath Input;
- [XmlElement(ElementName = "output")]
- public CPath Output;
- public class CTrainz
- {
- [XmlAttribute(AttributeName = "path")]
- public string Path;
- }
- [XmlElement(ElementName = "trainz")]
- public CTrainz Trainz;
- public class CDefine
- {
- [XmlElement(ElementName = "what")]
- public string Pattern;
- [XmlElement(ElementName = "with-file")]
- public string FilePath;
- [XmlElement(ElementName = "with")]
- public string Content;
- }
- public class CParam
- {
- [XmlAttribute(AttributeName = "name")]
- public string Name;
- [XmlText]
- public string Value;
- }
- public class CTarget
- {
- [XmlAttribute(AttributeName = "prefix")]
- public string Prefix;
- [XmlAttribute(AttributeName = "asset-kuid")]
- public string AssetKuid;
- public class Include
- {
- [XmlAttribute(AttributeName = "path")]
- public string Path;
- }
- [XmlElement(ElementName = "include")]
- public Include[] Includes;
- [XmlElement(ElementName = "define")]
- public CDefine[] Defines;
- [XmlElement(ElementName = "param")]
- public CParam[] Params;
- }
- [XmlElement(ElementName = "target")]
- public CTarget[] Targets;
- [XmlElement(ElementName = "replace")]
- public CDefine[] Defines;
- [XmlElement(ElementName = "param")]
- public CParam[] Params;
- public static Project Load()
- {
- var serializer = new XmlSerializer(typeof(Project));
- return (Project)serializer.Deserialize(new StreamReader("gsmake.config.xml"));
- }
- public void Save()
- {
- var serializer = new XmlSerializer(typeof(Project));
- serializer.Serialize(new StreamWriter("gsmake.config2.xml"), this);
- }
- //public void SaveYaml()
- //{
- // var serializer = new YamlSerializer();
- // serializer.Serialize(new StreamWriter("gsmake.config2.xml"), this);
- //}
- }
- class Program
- {
- static Project project;
- class TargetData
- {
- public Project.CTarget Target;
- public List<string> Files;
- }
- static Project.CTarget GetFileTarget(string file)
- {
- var fileName = Path.GetFileName(file);
- var result = project.Targets
- .Where(t => fileName.StartsWith(t.Prefix))
- .Select(t => new { t, l = t != null ? t.Prefix.Length : -1 })
- .OrderByDescending(tl => tl.l)
- .FirstOrDefault();
- return result != null ? result.t : null;
- }
- static TargetData GetTargetData(string targetName)
- {
- if (targetName.EndsWith(".gs"))
- {
- return new TargetData
- {
- Target = GetFileTarget(targetName),
- Files = new List<string> { Path.Combine(Environment.CurrentDirectory, Path.Combine(project.Output.Path, targetName)) }
- };
- }
- var target = GetFileTarget(targetName);
- if (target.Prefix != targetName)
- return null;
- var ret = new TargetData
- {
- Target = GetFileTarget(targetName)
- };
- ret.Files = GetAllOutputFiles().Where(file => GetFileTarget(file) == ret.Target).ToList();
- return ret;
- }
- static IEnumerable<string> GetAllOutputFiles()
- {
- var inputPath = Path.Combine(Environment.CurrentDirectory, project.Input.Path);
- var outputPath = Path.Combine(Environment.CurrentDirectory, project.Output.Path);
- return new DirectoryInfo(inputPath).GetFiles("*.gs").Select(f => Path.Combine(outputPath, f.Name));
- }
- static List<TargetData> GetAllTargetData()
- {
- var ret = new List<TargetData>();
- foreach (var file in GetAllOutputFiles())
- {
- var target = GetFileTarget(file);
- var targetData = ret.Where(td => td.Target == target).FirstOrDefault();
- if (targetData == null)
- ret.Add(new TargetData { Target = target, Files = new List<string> { file } });
- else
- targetData.Files.Add(file);
- }
- return ret;
- }
- static string CallTrainzUtil(string args)
- {
- var trainzutil = new Process
- {
- StartInfo = new ProcessStartInfo
- {
- FileName = Path.Combine(project.Trainz.Path, "bin/trainzutil.exe"),
- Arguments = args,
- CreateNoWindow = true,
- RedirectStandardOutput = true,
- UseShellExecute = false
- }
- };
- trainzutil.Start();
- trainzutil.WaitForExit();
- return trainzutil.StandardOutput.ReadToEnd();
- }
- static void Compile(TargetData target)
- {
- if (target.Files.Count() == 0)
- return;
- var includes = new StringBuilder();
- includes.AppendFormat("-i\"{0}\"", Path.Combine(project.Trainz.Path, "scripts"));
- if (target.Target.Includes != null)
- foreach (var include in target.Target.Includes)
- if (!String.IsNullOrEmpty(include.Path))
- includes.AppendFormat(" -i\"{0}\"", include.Path);
- //var output = String.Format("-p\"{0}\"", Path.Combine(Environment.CurrentDirectory, Path.Combine(project.Output.Path, "a")));
- var output = "";
- foreach (var file in target.Files)
- {
- var fileDir = Path.Combine(Environment.CurrentDirectory, project.Input.Path);
- var filePath = Path.Combine(fileDir, file);
- Console.WriteLine("Compiling {0}:", file);
- Console.Write(CallTrainzUtil(String.Format("compile \"{0}\" {1} {2}", filePath, includes, output)));
- }
- }
- static void Encrypt(TargetData target)
- {
- for (int i = 0; i < target.Files.Count; ++i)
- {
- var file = target.Files[i];
- var encryptedFile = Regex.Replace(file, @"\.gs$", ".gse");
- File.Delete(encryptedFile);
- var output = CallTrainzUtil(String.Format("encrypt \"{0}\"", file));
- if (!File.Exists(encryptedFile))
- Console.Write(output);
- else
- target.Files[i] = encryptedFile;
- }
- }
- static void Install(TargetData target)
- {
- if (target.Files.Count() == 0)
- return;
- var resultRegex = new Regex(@"OK \((\d+) \w+, (\d+) \w+\)");
- var openResult = CallTrainzUtil(String.Format("edit {0}", target.Target.AssetKuid));
- var resultLines = openResult.Split('\n').Where(l => !String.IsNullOrEmpty(l));
- var match = resultRegex.Match(resultLines.Last());
- if (!match.Success || match.Groups[1].Captures[0].Value != "0")
- {
- Console.WriteLine(openResult);
- return;
- }
- var pathLine = resultLines.First();
- var pathKuidStrLength = pathLine.IndexOf('>') + 3;
- var openedPath = pathLine.Substring(pathKuidStrLength).Trim();
- //foreach (var file in new DirectoryInfo(openedPath).GetFiles("*.gs"))
- // File.Delete(file.FullName);
- //foreach (var file in new DirectoryInfo(openedPath).GetFiles("*.gse"))
- // File.Delete(file.FullName);
- foreach (var file in target.Files)
- {
- var fileName = Path.GetFileName(file);
- File.Copy(file, Path.Combine(openedPath, fileName), overwrite: true);
- }
- var commitResult = CallTrainzUtil(String.Format("commit {0}", target.Target.AssetKuid));
- resultLines = commitResult.Split('\n').Where(l => !String.IsNullOrEmpty(l));
- match = resultRegex.Match(resultLines.Last());
- if (!match.Success || match.Groups[1].Captures[0].Value != "0")
- Console.WriteLine(commitResult);
- else
- Console.WriteLine("Installing to <{0}> - OK", target.Target.AssetKuid);
- }
- static void PreprocessDefines(ref string contents, IEnumerable<Project.CDefine> defines)
- {
- if (defines != null)
- contents = defines.Aggregate(contents, (current, define) =>
- current.Replace(define.Pattern, String.IsNullOrEmpty(define.FilePath)
- ? define.Content
- : File.ReadAllText(define.FilePath))
- );
- }
- static void PreprocessParams(ref string contents, Dictionary<string, string> allParams)
- {
- bool anyReplace = false;
- var i = allParams.GetEnumerator();
- while (true)
- {
- if (!i.MoveNext())
- {
- if (anyReplace)
- {
- anyReplace = false;
- i = allParams.GetEnumerator();
- continue;
- }
- break;
- }
- var name = i.Current.Key;
- var value = i.Current.Value;
- var quotedName = GetParamQuotedName(name);
- if (contents.Contains(quotedName))
- {
- anyReplace = true;
- switch (name)
- {
- case "line":
- var paramIndex = contents.IndexOf(quotedName);
- var lineCount = contents.Substring(0, paramIndex).Count(c => c == '\n') + 1;
- contents = contents.Replace(quotedName, lineCount.ToString());
- break;
- default:
- contents = contents.Replace(quotedName, value);
- break;
- }
- }
- }
- }
- static string GetParamQuotedName(string param)
- {
- return String.Format("{{%{0}%}}", param);
- }
- static void PreparePreprocess()
- {
- var allParams = new Dictionary<string, string>(paramsDict);
- var targets = GetAllTargetData();
- if (project.Params != null)
- Array.ForEach(project.Params, p => allParams[p.Name] = p.Value);
- targets.ForEach(td =>
- {
- if (td.Target.Params != null)
- Array.ForEach(td.Target.Params, p => allParams[p.Name] = p.Value);
- });
- foreach (var td in targets)
- {
- foreach (var file in td.Files)
- {
- allParams["file"] = Path.GetFileName(file);
- var contents = File.ReadAllText(file);
- PreprocessDefines(ref contents, defines);
- PreprocessDefines(ref contents, project.Defines);
- PreprocessDefines(ref contents, td.Target.Defines);
- PreprocessParams(ref contents, allParams);
- File.WriteAllText(file, contents);
- }
- }
- }
- static void PrepareFiles()
- {
- var inputPath = Path.Combine(Environment.CurrentDirectory, project.Input.Path);
- var inputFiles = new DirectoryInfo(inputPath).GetFiles("*.gs").Select(f => f.FullName);
- var copyPath = Path.Combine(Environment.CurrentDirectory, project.Output.Path);
- foreach (var file in inputFiles)
- File.Copy(file, Path.Combine(copyPath, Path.GetFileName(file)), overwrite: true);
- }
- static bool preparingDone = false;
- static void Prepare()
- {
- if (!preparingDone)
- {
- PrepareFiles();
- PreparePreprocess();
- preparingDone = true;
- }
- }
- static void Clean()
- {
- var outPath = Path.Combine(Environment.CurrentDirectory, project.Output.Path);
- var dirInfo = new DirectoryInfo(outPath);
- foreach (var fileInfo in dirInfo.GetFiles("*.gs"))
- fileInfo.Delete();
- foreach (var fileInfo in dirInfo.GetFiles("*.gsl"))
- fileInfo.Delete();
- foreach (var fileInfo in dirInfo.GetFiles("*.gse"))
- fileInfo.Delete();
- preparingDone = false;
- }
- static List<Project.CDefine> defines = new List<Project.CDefine>();
- static Dictionary<string, string> paramsDict = new Dictionary<string, string>
- {
- { "date", DateTime.Now.ToString("dd.MM.yyyy") },
- { "time", DateTime.Now.ToString("HH:mm") },
- { "line", "" }
- };
- static bool displayHelp = false;
- static void Main(string[] args)
- {
- try
- {
- var jobs = new List<string>();
- var argsEnum = args.ToList().GetEnumerator();
- while (argsEnum.MoveNext())
- {
- if (!argsEnum.Current.StartsWith("-"))
- {
- jobs.Add(argsEnum.Current);
- }
- else
- {
- do
- {
- var option = argsEnum.Current;
- if (option == "-replace-str")
- {
- if (argsEnum.MoveNext())
- {
- var pattern = argsEnum.Current;
- if (argsEnum.MoveNext())
- {
- var replace = argsEnum.Current;
- defines.Add(new Project.CDefine { Pattern = pattern, Content = replace });
- }
- }
- }
- else if (option == "-replace-file")
- {
- if (argsEnum.MoveNext())
- {
- var pattern = argsEnum.Current;
- if (argsEnum.MoveNext())
- {
- var replaceFile = argsEnum.Current;
- defines.Add(new Project.CDefine { Pattern = pattern, FilePath = replaceFile });
- }
- }
- }
- else if (option == "-param")
- {
- if (argsEnum.MoveNext())
- {
- var name = argsEnum.Current;
- if (argsEnum.MoveNext())
- {
- var value = argsEnum.Current;
- paramsDict[name] = value;
- }
- }
- }
- else if (option == "-help")
- {
- displayHelp = true;
- }
- else
- throw new FormatException(String.Format(@"Bad option '{0}'", option));
- }
- while (argsEnum.MoveNext());
- }
- }
- if (displayHelp)
- return;
- project = Project.Load();
- if (jobs.Count == 0)
- {
- jobs.Add(":c");
- }
- foreach (var job in jobs)
- {
- var jobTokens = job.Split(':');
- string aTarget = jobTokens[0];
- string actions = jobTokens.Length == 2 ? jobTokens[1] : "c";
- var targets = String.IsNullOrEmpty(aTarget)
- ? GetAllTargetData()
- : new List<TargetData> { GetTargetData(aTarget) };
- if (!targets.Any(t => t != null && t.Target != null))
- {
- Console.WriteLine(@"Bad arg '{0}'", job);
- return;
- }
- foreach (var action in actions)
- {
- switch (action)
- {
- case 'c':
- Prepare();
- targets.ForEach(Compile);
- break;
- case 'e':
- Prepare();
- targets.ForEach(Encrypt);
- break;
- case 'i':
- Prepare();
- targets.ForEach(Install);
- break;
- case 'C':
- Clean();
- break;
- default:
- Console.WriteLine(@"Bad action '{0}'", action);
- return;
- }
- }
- }
- }
- catch (FormatException e)
- {
- Console.WriteLine(e.Message);
- displayHelp = true;
- }
- finally
- {
- if (displayHelp)
- {
- Console.WriteLine("gsmake version 0.9.10");
- Console.WriteLine("Usage:");
- Console.WriteLine(" gsmake [OPTIONS] -- compile all targets");
- Console.WriteLine(" gsmake TARGET:ACTION [OPTIONS]");
- Console.WriteLine("Description:");
- Console.WriteLine(" gsmake performs actions to set of GameScript files.");
- Console.WriteLine(" Actions are:");
- Console.WriteLine(" 1. Cleaning output directory");
- Console.WriteLine(" 2. Compiling");
- Console.WriteLine(" 3. Ecnrypting");
- Console.WriteLine(" 4. Installing");
- Console.WriteLine(" Actions are done to sets of files.");
- Console.WriteLine(" They are defined in config.xml file as targets.");
- Console.WriteLine(" It is written as:");
- Console.WriteLine(" targetName:c -- this will compile all files in target targetName");
- Console.WriteLine(" :i -- this will install all targets to assets");
- Console.WriteLine(" target1:i target2:ei -- this will install");
- Console.WriteLine(" target1 as plain files and target2 as ecnrypted files");
- Console.WriteLine(" :i :C -- this will install all targets and then clean output directory");
- Console.WriteLine(" Default action is compile (c).");
- Console.WriteLine(" Cleaning could be done only as global action (means not linked with any target.");
- Console.WriteLine("Options:");
- Console.WriteLine(" -replace-str WHAT WITH: replace in all files with string");
- Console.WriteLine(" -replace-file WHAT FILE: replace in all files with FILE contents");
- Console.WriteLine(" -param PARAM_NAME VALUE: set parameter name to value");
- Console.WriteLine(" -help: show this help text");
- Console.WriteLine("");
- }
- }
- return;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement