private static int HandleArguments(string[] args) { var Ops = new List <Modes>(); string Filename = null; string SessionName = null; if (args.Contains("/?")) { Help(); return(RET.HELP); } for (var i = 0; i < args.Length; i++) { var arg = args[i]; Log.Write("{0}: processing argument: {1}", nameof(HandleArguments), arg); switch (arg.ToLower()) { case "/verify": Ops.Add(Modes.Verify); break; case "/list": Ops.Add(Modes.List); break; case "/pack": Ops.Add(Modes.Pack); break; case "/render": Ops.Add(Modes.Render); break; case "/info": Ops.Add(Modes.Info); break; case "/rename": Ops.Add(Modes.RenameSession); if (i < args.Length - 1) { SessionName = args[++i]; } else { Log.Write("{0}: /rename requires a new session name", nameof(HandleArguments)); Console.WriteLine("/rename requires a new session name"); return(RET.ARG); } break; default: if (string.IsNullOrEmpty(Filename)) { Filename = arg; } else { Log.Write("{0}: unknown argument: {1}", nameof(HandleArguments), arg); Console.WriteLine("Unknown argument: {0}", arg); return(RET.ARG); } break; } } if (Ops.Count == 0 && args.Length < 2) { return(RET.UI); } Tools.AllocConsole(); if (string.IsNullOrEmpty(Filename)) { Log.Write("{0}: No file name argument supplied", nameof(HandleArguments)); Console.WriteLine("No file name argument supplied"); return(RET.ARG); } Ops = Ops.Distinct().ToList(); var Changes = false; var IsGz = false; SaveFile SF = null; FileStream FS = null; try { FS = File.Open(Filename, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); } catch (Exception ex) { Console.WriteLine("Unable to open input file"); Log.Write("{0}: Unable to open input file", nameof(HandleArguments)); Log.Write(ex); return(RET.IO); } using (FS) { IsGz = Tools.IsGzFile(FS); try { SF = SaveFile.Open(FS); if (SF == null) { throw new InvalidDataException("The file is not a valid satisfactory save game"); } } catch (Exception ex) { Console.WriteLine("Invalid game file"); Log.Write("{0}: Invalid game file", nameof(HandleArguments)); Log.Write(ex); return(RET.IO); } if (Ops.Contains(Modes.Verify)) { Log.Write("{0}: Verifying file", nameof(HandleArguments)); //Verify does nothing on its own Check(SF.PlayTime.Ticks >= 0, "Positive play time"); Check(Tools.IsMatch(SF.SessionName, @"^[\w\.\- ]{1,31}$"), "Non-Problematic Session Name"); Check(SF.LevelType == SaveFile.DEFAULT_LEVEL_TYPE, $"Level type is '{SaveFile.DEFAULT_LEVEL_TYPE}'"); Check(SF.SaveDate.ToUniversalTime() < DateTime.UtcNow, "Date in past"); foreach (var key in "sessionName Visibility startloc".Split(' ')) { Check(SF.Properties.ContainsKey(key), $"Header contains field '{key}'"); } //Don't double error with the previous one if (SF.Properties.ContainsKey("sessionName")) { Check(SF.Properties["sessionName"] == SF.SessionName, "Both session names match"); } else { Console.WriteLine("[SKIP]: Both session names match"); } } if (Ops.Contains(Modes.List)) { Log.Write("{0}: Printing item list", nameof(HandleArguments)); foreach (var e in SF.Entries.GroupBy(m => m.ObjectData.Name).OrderBy(m => m.Key)) { Console.WriteLine("{1}\t{0}", e.Key, e.Count()); } } if (Ops.Contains(Modes.Render)) { var ImgFile = Path.ChangeExtension(Filename, ".png"); Log.Write("{0}: Rendering map as original size to {1}", nameof(HandleArguments), ImgFile); Console.WriteLine("Initializing image..."); MapRender.Init(-1, -1); Console.WriteLine("Rendering file..."); using (var IMG = MapRender.RenderFile(SF, 8.192)) { Console.WriteLine("Saving image..."); IMG.Save(ImgFile); } } if (Ops.Contains(Modes.Info)) { Log.Write("{0}: Showing game info", nameof(HandleArguments)); Console.WriteLine("Save File Size:\t{0}", FS.Position); Console.WriteLine("Build Version:\t{0}", SF.BuildVersion); Console.WriteLine("Save Version:\t{0}", SF.SaveVersion); Console.WriteLine("Header Version:\t{0}", SF.SaveHeaderVersion); Console.WriteLine("Session Name:\t{0}", SF.SessionName); Console.WriteLine("Save Date:\t{0}", SF.SaveDate); Console.WriteLine("Play Time:\t{0}", SF.PlayTime); foreach (var KV in SF.Properties) { Console.WriteLine("{0}:\t{1}", KV.Key, KV.Value); } Console.WriteLine("Object Count:\t{0}", SF.Entries.Count); Console.WriteLine("String List:\t{0}", SF.StringList.Count); } if (Ops.Contains(Modes.RenameSession)) { Log.Write("{0}: Renaming session to {1}", nameof(HandleArguments), SessionName); SF.SetSessionName(SessionName); Changes = true; } if (Ops.Contains(Modes.Pack)) { string NewFile; FileStream OUT; FS.Seek(0, SeekOrigin.Begin); if (IsGz) { if (Filename.ToLower().EndsWith(".sav.gz")) { NewFile = Path.ChangeExtension(Filename, null); } else { NewFile = Path.ChangeExtension(Filename, ".sav"); } } else { NewFile = Filename + ".gz"; } try { OUT = File.Create(NewFile); } catch (Exception ex) { Console.WriteLine("Can't create output file"); Log.Write("{0}: Can't create {1}", nameof(HandleArguments), NewFile); Log.Write(ex); return(RET.IO); } Log.Write("{0}: {1} file", nameof(HandleArguments), IsGz ? "Compressing" : "Decompressing"); using (OUT) { if (IsGz) { Compression.DecompressStream(FS, OUT); } else { Compression.CompressStream(FS, OUT); } } Log.Write("{0}: {1} file OK", nameof(HandleArguments), IsGz ? "Compressing" : "Decompressing"); } if (Changes) { Log.Write("{0}: Writing back changes", nameof(HandleArguments)); FS.Seek(0, SeekOrigin.Begin); SF.Export(FS); FS.Flush(); FS.SetLength(FS.Position); } } return(RET.SUCCESS); }
public frmMain(string InitialFile = null) { SettingsFile = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "settings.xml"); if (File.Exists(SettingsFile)) { try { S = Settings.Load(File.ReadAllText(SettingsFile)); } catch (Exception ex) { Log.Write(new Exception("Unable to load the settings", ex)); Tools.E($"Unable to load your settings. Defaults will be applied. Reason:\r\n{ex.Message}", "Settings Loader"); S = new Settings(); } } else { Log.Write("{0}: Creating settings for first run", GetType().Name); S = new Settings(); } InitializeComponent(); MapRender.MapForm = this; //Don't block the application startup with the image rendering stuff Thread T = new Thread(delegate() { Log.Write("{0}: Rendering map", GetType().Name); MapRender.Init(); var img = MapRender.GetMap(); Invoke((MethodInvoker) delegate { BackgroundImage = img; if (S.ShowWelcomeMessage) { S.ShowWelcomeMessage = false; Tools.ShowHelp("Welcome"); } if (!string.IsNullOrEmpty(InitialFile)) { try { OpenFile(InitialFile); } catch (Exception ex) { Log.Write(new Exception("Unable to load file from command line argument", ex)); Tools.E($"Unable to open {InitialFile}\r\n{ex.Message}", "File error"); } } Log.Write("{0}: Initializer complete", GetType().Name); }); }); T.Start(); SFD.InitialDirectory = OFD.InitialDirectory = Program.SaveDirectory; Tools.SetupEscHandler(this); #if DEBUG Log.Write("{0}: Enabling debug menu items", GetType().Name); //Enable not fully implemented items inventoriesToolStripMenuItem.Visible = true; #endif }
/// <summary> /// Form constructor /// </summary> /// <param name="InitialFile">Optional file to open after startup</param> public frmMain(string InitialFile = null) { RespectManagerSetting = string.IsNullOrEmpty(InitialFile); SettingsFile = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "settings.xml"); if (File.Exists(SettingsFile)) { try { S = Settings.Load(File.ReadAllText(SettingsFile)); } catch (Exception ex) { Log.Write(new Exception("Unable to load the settings", ex)); Tools.E($"Unable to load your settings. Defaults will be applied. Reason:\r\n{ex.Message}", "Settings Loader"); S = new Settings(); } } else { Log.Write("{0}: Creating settings for first run", GetType().Name); S = new Settings(); } //Set up feature reporter if (!S.DisableUsageReport) { if (S.ReportId == Guid.Empty || S.UseRandomId) { S.ReportId = Guid.NewGuid(); } FeatureReport.Id = S.ReportId; } else { //Make sure the Id id is always unset FeatureReport.Id = S.ReportId = Guid.Empty; } InitializeComponent(); //!!!Read+Write form components only after this line!!! //Always start from the save file directory //We can't set this directly in the properties because the path is dynamic OFD.InitialDirectory = Program.SaveDirectory; OriginalTitle = Text; //Enable the audio extractor only if QuickPlay is present if (QuickPlay.HasQuickPlay) { extractAudioToolStripMenuItem.Enabled = true; } //Register this as the map rendering form MapRender.MapForm = this; //Don't block the application startup with the image rendering stuff Thread T = new Thread(delegate() { Log.Write("{0}: Rendering initial map", GetType().Name); try { MapRender.Init(); } catch (Exception ex) { Log.Write("{0}: Rendering initial map failed", GetType().Name); Log.Write(ex); BackgroundImage = new Bitmap(1, 1); DisableImageRendering(); return; } var img = MapRender.GetMap(); Invoke((MethodInvoker) delegate { BackgroundImage = img; //Open initial file if supplied if (!string.IsNullOrEmpty(InitialFile)) { try { FeatureReport.Used(FeatureReport.Feature.OpenByCommandLine); OpenFile(InitialFile); } catch (Exception ex) { Log.Write(new Exception("Unable to load file from command line argument", ex)); Tools.E($"Unable to open {InitialFile}\r\n{ex.Message}", "File error"); } } Log.Write("{0}: Initializer complete", GetType().Name); }); }); T.Start(); SFD.InitialDirectory = OFD.InitialDirectory = Program.SaveDirectory; Tools.SetupKeyHandlers(this); HandleSettingsChange(); #if DEBUG Log.Write("{0}: Enabling debug menu items", GetType().Name); //Enable not fully implemented items inventoriesToolStripMenuItem.Visible = true; removeRocksToolStripMenuItem.Visible = true; #endif }