Exemple #1
0
 private void PreviewFile(SaveFile F)
 {
     using (var BMP = MapRender.RenderFile(F))
     {
         PreviewImage(BMP, F.SessionName);
     }
 }
        private void RenderSelected()
        {
            if (lvCount.SelectedItems.Count > 0)
            {
                var Selected = lvCount.SelectedItems
                               .OfType <ListViewItem>()
                               .SelectMany(m => MapEntries.Where(n => n.ObjectData.Name == m.Tag.ToString()))
                               .Select(m => new DrawObject(m, Color.Fuchsia, 3))
                               .ToArray();
                if (Selected.Length > 0)
                {
                    Image I = null;
                    try
                    {
                        I = MapRender.Render(Selected);
                    }
                    catch (Exception ex)
                    {
                        Log.Write("{0}: Unable to render selection", GetType().Name);
                        Log.Write(ex);
                        Tools.E(@"Unable to render your selection. This is usually the result of memory constraints or a corrupted executable.
It is highly recommended that you verify the application integrity (check if it has a valid signature in the file properties).
You can try to continue using this application but you might see reduced functionality whenever map drawing is involved.", "Item rendering error");
                        return;
                    }
                    MapRender.MapForm.BackgroundImage.Dispose();
                    MapRender.MapForm.BackgroundImage = I;
                }
                else
                {
                    MessageBox.Show("The selected objects don't have map coordinates.", "No objects to render");
                }
            }
        }
Exemple #3
0
        private void btnMap_Click(object sender, EventArgs e)
        {
            var ItemName = ((ShortName)cbItem.SelectedItem).Long;
            var Items    = F.Entries.Where(m => m.ObjectData.Name == ItemName);

            //Filter if needed
            if (rbRange.Checked)
            {
                Items = Items.Skip((int)nudStart.Value - 1).Take((int)nudCount.Value);
            }
            if (Items.Count() > 0)
            {
                if (Items.First().EntryType == ObjectTypes.OBJECT_TYPE.OBJECT)
                {
                    MapRender.MapForm.BackgroundImage.Dispose();
                    MapRender.MapForm.BackgroundImage = MapRender.Render(Items.Select(m => new DrawObject(m, Color.Yellow, 10)));
                }
                else
                {
                    MessageBox.Show("This type of entry has no map coordinates", "Invalid entry type", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else
            {
                MessageBox.Show("No items to show (0 items selected)", "Invalid entry type", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        private void RedrawMap(IEnumerable <SaveFileEntry> Entries)
        {
            Log.Write("{0}: Redrawing the map. Points: {1}", GetType().Name, Points.Count);
            var I = MapRender.RenderEntries(Entries);

            using (var G = Graphics.FromImage(I))
            {
                //Render points
                if (Points.Count > 2)
                {
                    using (var B = new SolidBrush(Color.FromArgb(100, Color.Lime)))
                    {
                        G.FillPolygon(B, Points
                                      .Select(m => new Point((int)(m.X * I.Width), (int)(m.Y * I.Height)))
                                      .ToArray());
                    }
                }
                using (var F = new Font("Arial", 16))
                {
                    G.DrawString($"Number of points: {Points.Count}", F, Brushes.Red, new PointF(0, 0));
                }
            }
            if (pbMap.Image != null)
            {
                pbMap.Image.Dispose();
            }
            pbMap.Image = I;
            Log.Write("{0}: Redrawing complete", GetType().Name);
        }
 private void RedrawMap()
 {
     Log.Write("{0}: Rendering Map", GetType().Name);
     BackgroundImage.Dispose();
     if (F != null)
     {
         using (var BMP = MapRender.RenderFile(F))
         {
             //Add file info string
             using (var G = Graphics.FromImage(BMP))
             {
                 var Info = string.Format("{0}: {1} {2}",
                                          Path.GetFileName(FileName),
                                          DateTime.Now.ToShortDateString(),
                                          DateTime.Now.ToShortTimeString());
                 using (var F = new Font("Arial", 16))
                 {
                     var Pos = G.MeasureString(Info, F);
                     G.DrawString(
                         Info, F,
                         Brushes.Red,
                         (int)(BMP.Width - Pos.Width),
                         (int)(BMP.Height - Pos.Height));
                 }
             }
             BackgroundImage = new Bitmap(BMP);
             BMP.Save(Path.ChangeExtension(FileName, "png"));
         }
     }
     else
     {
         BackgroundImage = MapRender.GetMap();
     }
 }
 public frmRegionDeleter(SaveFile F)
 {
     this.F    = F;
     HasChange = false;
     Points    = new List <PointF>();
     InitializeComponent();
     pbMap.Image = MapRender.RenderFile(F);
     Tools.SetupEscHandler(this);
 }
Exemple #7
0
        private void btnMap_Click(object sender, EventArgs e)
        {
            var ItemName = ((ShortName)cbObject.SelectedItem).Long;
            var Item     = F.Entries.Where(m => m.ObjectData.Name == ItemName).Skip((int)nudOffset.Value - 1).First();

            if (Item.EntryType == ObjectTypes.OBJECT_TYPE.OBJECT)
            {
                MapRender.MapForm.BackgroundImage.Dispose();
                MapRender.MapForm.BackgroundImage = MapRender.Render(new DrawObject(Item, Color.Yellow, 10));
            }
            else
            {
                MessageBox.Show("This type of entry has no map coordinates", "Invalid entry type", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        private void renderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var Node = GetSelectedFile();

            if (Node != null)
            {
                if (IsValidNode(Node))
                {
                    Log.Write("{0}: Rendering {1}.sav", GetType().Name, Node.Text);
                    using (var FS = File.OpenRead(GetName(Node)))
                    {
                        SaveFile F;
                        try
                        {
                            F = SaveFile.Open(FS);
                        }
                        catch (Exception ex)
                        {
                            Log.Write(new Exception("Attempted to render invalid file", ex));
                            InvalidMessage();
                            return;
                        }
                        using (var BMP = MapRender.RenderFile(F))
                        {
                            using (var frm = new Form())
                            {
                                frm.Text                  = "Preview of " + Node.Text;
                                frm.ShowIcon              = frm.ShowInTaskbar = false;
                                frm.WindowState           = FormWindowState.Maximized;
                                frm.BackgroundImageLayout = ImageLayout.Zoom;
                                frm.BackgroundImage       = BMP;
                                Tools.SetupEscHandler(frm);
                                frm.ShowDialog();
                            }
                        }
                    }
                }
                else
                {
                    InvalidMessage();
                }
            }
        }
Exemple #9
0
        private void RedrawMap(IEnumerable <SaveFileEntry> Entries)
        {
            Log.Write("{0}: Redrawing the map. Points: {1}", GetType().Name, Points.Count);
            Image I = null;

            try
            {
                I = MapRender.RenderEntries(Entries);
            }
            catch (Exception ex)
            {
                Log.Write("{0}: Unable to render image in RedrawMap()", GetType().Name);
                Log.Write(ex);
                Tools.E(@"Unable to render the map image. This is usually the result of memory constraints or a corrupted executable.
It is highly recommended that you verify the application integrity (check if it has a valid signature in the file properties).
You can try to continue using this application but you might see reduced functionality whenever map drawing is involved.", "Item rendering error");
                return;
            }
            using (var G = Graphics.FromImage(I))
            {
                //Render points
                if (Points.Count > 2)
                {
                    using (var B = new SolidBrush(Color.FromArgb(100, Color.Lime)))
                    {
                        G.FillPolygon(B, Points
                                      .Select(m => new Point((int)(m.X * I.Width), (int)(m.Y * I.Height)))
                                      .ToArray());
                    }
                }
                using (var F = new Font("Arial", 16))
                {
                    G.DrawString($"Number of points: {Points.Count}", F, Brushes.Red, new PointF(0, 0));
                }
            }
            if (pbMap.Image != null)
            {
                pbMap.Image.Dispose();
            }
            pbMap.Image = I;
            Log.Write("{0}: Redrawing complete", GetType().Name);
        }
 private void RenderSelected()
 {
     if (lvCount.SelectedItems.Count > 0)
     {
         var Blank    = new Vector3(0, 0, 0);
         var Selected = lvCount.SelectedItems
                        .OfType <ListViewItem>()
                        .SelectMany(m => MapEntries.Where(n => n.ObjectData.Name == m.Tag.ToString()))
                        .Select(m => new DrawObject(m, Color.Fuchsia, 3))
                        .ToArray();
         if (Selected.Length > 0)
         {
             MapRender.MapForm.BackgroundImage.Dispose();
             MapRender.MapForm.BackgroundImage = MapRender.Render(Selected);
         }
         else
         {
             MessageBox.Show("The selected objects don't have map coordinates.", "No objects to render");
         }
     }
 }
        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
        }
        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);
        }
        /// <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
        }
        /// <summary>
        /// Redraws the map
        /// </summary>
        private void RedrawMap()
        {
            Image I = null;

            if (!RenderImage)
            {
                Log.Write("{0}: Map Rendering is disabled in RedrawMap()", GetType().Name);
                return;
            }
            Log.Write("{0}: Rendering Map", GetType().Name);
            if (F != null)
            {
                try
                {
                    I = MapRender.RenderFile(F);
                }
                catch (Exception ex)
                {
                    Log.Write("{0}: Error when rendering bitmap", GetType().Name);
                    Log.Write(ex);
                    DisableImageRendering();
                    return;
                }
                try
                {
                    //Add file info string
                    using (var G = Graphics.FromImage(I))
                    {
                        var Info = string.Format("{0}: {1} {2}",
                                                 Path.GetFileName(FileName),
                                                 DateTime.Now.ToShortDateString(),
                                                 DateTime.Now.ToShortTimeString());
                        using (var F = new Font("Arial", 16))
                        {
                            //Align to the bottom right corner of the image
                            var Pos = G.MeasureString(Info, F);
                            G.DrawString(
                                Info, F,
                                Brushes.Red,
                                (int)(I.Width - Pos.Width),
                                (int)(I.Height - Pos.Height));
                        }
                    }
                    Log.Write("{0}: Setting map image in form", GetType().Name);
                    BackgroundImage.Dispose();
                    BackgroundImage = I;
                }
                catch (Exception ex)
                {
                    Log.Write("{0}: Error when rendering bitmap", GetType().Name);
                    Log.Write(ex);
                    try
                    {
                        I.Dispose();
                    }
                    finally
                    {
                        I = null;
                    }
                    DisableImageRendering();
                }
                if (I != null)
                {
                    //Save image in its own "try" block because if only this fails it's not a rendering error.
                    try
                    {
                        Log.Write("{0}: Saving map image to file", GetType().Name);
                        I.Save(Path.ChangeExtension(FileName, "png"));
                    }
                    catch (Exception ex)
                    {
                        Log.Write("{0}: Unable to save map image to file", GetType().Name);
                        Log.Write(ex);
                    }
                }
            }
            else
            {
                Log.Write("{0}: No file loaded. Drawing empty map", GetType().Name);
                try
                {
                    BackgroundImage.Dispose();
                    BackgroundImage = MapRender.GetMap();
                }
                catch (Exception ex)
                {
                    Log.Write("{0}: Error when rendering bitmap", GetType().Name);
                    Log.Write(ex);
                    DisableImageRendering();
                }
            }
        }