You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
4.4 KiB

  1. using Mono.Cecil;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. namespace CollectDependencies
  7. {
  8. static class Program
  9. {
  10. static void Main(string[] args)
  11. {
  12. string depsfile = File.ReadAllText(args[0]);
  13. string fdir = Path.GetDirectoryName(args[0]);
  14. List<string> files = new List<string>();
  15. { // Create files from stuff in depsfile
  16. Stack<string> fstack = new Stack<string>();
  17. void Push(string val)
  18. {
  19. string pre = "";
  20. if (fstack.Count > 0)
  21. pre = fstack.First();
  22. fstack.Push(pre + val);
  23. }
  24. string Pop() => fstack.Pop();
  25. string Replace(string val)
  26. {
  27. var v2 = Pop();
  28. Push(val);
  29. return v2;
  30. }
  31. foreach (var line in depsfile.Split(new[] { Environment.NewLine }, StringSplitOptions.None))
  32. {
  33. var parts = line.Split('"');
  34. var path = parts.Last();
  35. var level = parts.Length - 1;
  36. if (path.StartsWith("::"))
  37. { // pseudo-command
  38. parts = path.Split(' ');
  39. var command = parts[0].Substring(2);
  40. parts = parts.Skip(1).ToArray();
  41. var arglist = string.Join(" ", parts);
  42. if (command == "from")
  43. { // an "import" type command
  44. path = File.ReadAllText(Path.Combine(fdir ?? throw new InvalidOperationException(), arglist));
  45. }
  46. else if (command == "prompt")
  47. {
  48. Console.Write(arglist);
  49. path = Console.ReadLine();
  50. }
  51. else
  52. {
  53. path = "";
  54. Console.Error.WriteLine($"Invalid command {command}");
  55. }
  56. }
  57. if (level > fstack.Count - 1)
  58. Push(path);
  59. else if (level == fstack.Count - 1)
  60. files.Add(Replace(path));
  61. else if (level < fstack.Count - 1)
  62. {
  63. files.Add(Pop());
  64. while (level < fstack.Count)
  65. Pop();
  66. Push(path);
  67. }
  68. }
  69. files.Add(Pop());
  70. }
  71. foreach (var file in files)
  72. {
  73. var fparts = file.Split('?');
  74. var fname = fparts[0];
  75. if (fname == "") continue;
  76. var outp = Path.Combine(fdir ?? throw new InvalidOperationException(), Path.GetFileName(fname) ?? throw new InvalidOperationException());
  77. Console.WriteLine($"Copying \"{fname}\" to \"{outp}\"");
  78. if (File.Exists(outp)) File.Delete(outp);
  79. if (Path.GetExtension(fname)?.ToLower() == ".dll")
  80. {
  81. // ReSharper disable once StringLiteralTypo
  82. if (fparts.Length > 1 && fparts[1] == "virt")
  83. {
  84. var module = VirtualizedModule.Load(fname);
  85. module.Virtualize(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName(), Path.GetFileName(fname) ?? throw new InvalidOperationException()));
  86. }
  87. var modl = ModuleDefinition.ReadModule(fparts[0]);
  88. foreach (var t in modl.Types)
  89. {
  90. foreach (var m in t.Methods)
  91. {
  92. if (m.Body != null)
  93. {
  94. m.Body.Instructions.Clear();
  95. m.Body.InitLocals = false;
  96. m.Body.Variables.Clear();
  97. }
  98. }
  99. }
  100. modl.Write(outp);
  101. }
  102. else
  103. {
  104. File.Copy(fname, outp);
  105. }
  106. }
  107. }
  108. }
  109. }