DecryptCommand.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text;
  5. using ArcToolkitCLI.Commands.Options;
  6. using ArcToolkitCLI.Util;
  7. using COM3D2.Toolkit.Arc;
  8. using CommandLine;
  9. namespace ArcToolkitCLI.Commands
  10. {
  11. [Verb("decrypt", HelpText = "Decrypts the provided WARP files")]
  12. public class DecryptCommand : ICommand, IInputOptions, IDecryptionOptions, IOutputOptions
  13. {
  14. public int Run()
  15. {
  16. var errCode = Encryption.GetDecryptionKeys(this, out var keysDict);
  17. if (errCode != 0)
  18. return errCode;
  19. Directory.CreateDirectory(Output);
  20. foreach (var file in Glob.EnumerateFiles(Input))
  21. {
  22. if (!file.Exists)
  23. return Errors.Error(Errors.ErrorCodes.NotAFile, file.Name);
  24. using var stream = File.OpenRead(file.FullName);
  25. var header = new byte[4];
  26. stream.Read(header, 0, header.Length);
  27. var headerString = Encoding.ASCII.GetString(header);
  28. stream.Position = 0;
  29. if (headerString == "warc")
  30. Console.WriteLine($"{file.Name} is a WARC file, skipping...");
  31. else if (headerString == "warp")
  32. try
  33. {
  34. var arcStream = WarpArc.DecryptWarp(stream, requestedFile =>
  35. {
  36. if (keysDict.TryGetValue("*", out var key))
  37. return key;
  38. if (keysDict.TryGetValue(requestedFile, out key))
  39. return key;
  40. if (Directory.Exists(ArcDirectory) &&
  41. File.Exists(Path.Combine(ArcDirectory, requestedFile)))
  42. return Encryption.ReadKeyFromFile(Path.Combine(ArcDirectory, requestedFile));
  43. if (File.Exists(WarcFile))
  44. return Encryption.ReadKeyFromFile(WarcFile);
  45. throw new FileNotFoundException("No key found for the requested ARC", requestedFile);
  46. });
  47. Console.WriteLine($"Writing {Path.Combine(Output, file.Name)} with length {arcStream.Length}");
  48. using (var output = File.Create(Path.Combine(Output, file.Name)))
  49. arcStream.CopyTo(output);
  50. }
  51. catch (FileNotFoundException fe)
  52. {
  53. return Errors.Error(Errors.ErrorCodes.NoCorrectKey, file.Name, fe.FileName);
  54. }
  55. else
  56. return Errors.Error(Errors.ErrorCodes.UnknownArcType, file.Name);
  57. }
  58. return 0;
  59. }
  60. public string ArcDirectory { get; set; }
  61. public string DecryptionKey { get; set; }
  62. public string KeyFile { get; set; }
  63. public string WarcFile { get; set; }
  64. public IEnumerable<string> Input { get; set; }
  65. public string Output { get; set; }
  66. }
  67. }