diff --git a/Fo76ini/Form1.Designer.cs b/Fo76ini/Form1.Designer.cs index b3f0e86..16cde99 100644 --- a/Fo76ini/Form1.Designer.cs +++ b/Fo76ini/Form1.Designer.cs @@ -95,6 +95,7 @@ private void InitializeComponent() this.checkBoxNWMode = new System.Windows.Forms.CheckBox(); this.checkBoxSkipBackupQuestion = new System.Windows.Forms.CheckBox(); this.checkBoxMultipleGameEditionsUsed = new System.Windows.Forms.CheckBox(); + this.checkBoxDenyNTFSWritePermission = new System.Windows.Forms.CheckBox(); this.checkBoxIgnoreUpdates = new System.Windows.Forms.CheckBox(); this.checkBoxOpenManageModsOnLaunch = new System.Windows.Forms.CheckBox(); this.buttonLaunchGame = new System.Windows.Forms.Button(); @@ -275,7 +276,7 @@ private void InitializeComponent() // checkBoxReadOnly // this.checkBoxReadOnly.AutoSize = true; - this.checkBoxReadOnly.Location = new System.Drawing.Point(6, 42); + this.checkBoxReadOnly.Location = new System.Drawing.Point(10, 65); this.checkBoxReadOnly.Name = "checkBoxReadOnly"; this.checkBoxReadOnly.Size = new System.Drawing.Size(140, 17); this.checkBoxReadOnly.TabIndex = 4; @@ -617,7 +618,7 @@ private void InitializeComponent() this.sliderShadowDistance.Location = new System.Drawing.Point(10, 94); this.sliderShadowDistance.Maximum = 200000; this.sliderShadowDistance.Name = "sliderShadowDistance"; - this.sliderShadowDistance.Size = new System.Drawing.Size(281, 23); + this.sliderShadowDistance.Size = new System.Drawing.Size(273, 23); this.sliderShadowDistance.SmallChange = 1000; this.sliderShadowDistance.TabIndex = 27; this.sliderShadowDistance.Text = "metroTrackBar1"; @@ -658,7 +659,7 @@ private void InitializeComponent() this.sliderLODObjects.Location = new System.Drawing.Point(103, 41); this.sliderLODObjects.Maximum = 600; this.sliderLODObjects.Name = "sliderLODObjects"; - this.sliderLODObjects.Size = new System.Drawing.Size(210, 23); + this.sliderLODObjects.Size = new System.Drawing.Size(202, 23); this.sliderLODObjects.SmallChange = 5; this.sliderLODObjects.TabIndex = 29; this.sliderLODObjects.Text = "metroTrackBar1"; @@ -675,7 +676,7 @@ private void InitializeComponent() this.sliderLODItems.Location = new System.Drawing.Point(104, 70); this.sliderLODItems.Maximum = 600; this.sliderLODItems.Name = "sliderLODItems"; - this.sliderLODItems.Size = new System.Drawing.Size(209, 23); + this.sliderLODItems.Size = new System.Drawing.Size(201, 23); this.sliderLODItems.SmallChange = 5; this.sliderLODItems.TabIndex = 30; this.sliderLODItems.Text = "metroTrackBar2"; @@ -692,7 +693,7 @@ private void InitializeComponent() this.sliderLODActors.Location = new System.Drawing.Point(103, 99); this.sliderLODActors.Maximum = 600; this.sliderLODActors.Name = "sliderLODActors"; - this.sliderLODActors.Size = new System.Drawing.Size(210, 23); + this.sliderLODActors.Size = new System.Drawing.Size(202, 23); this.sliderLODActors.SmallChange = 5; this.sliderLODActors.TabIndex = 32; this.sliderLODActors.Text = "metroTrackBar3"; @@ -723,7 +724,7 @@ private void InitializeComponent() this.sliderGrassFadeDistance.Location = new System.Drawing.Point(9, 66); this.sliderGrassFadeDistance.Maximum = 14000; this.sliderGrassFadeDistance.Name = "sliderGrassFadeDistance"; - this.sliderGrassFadeDistance.Size = new System.Drawing.Size(282, 23); + this.sliderGrassFadeDistance.Size = new System.Drawing.Size(274, 23); this.sliderGrassFadeDistance.SmallChange = 500; this.sliderGrassFadeDistance.TabIndex = 24; this.sliderGrassFadeDistance.Text = "metroTrackBar1"; @@ -974,7 +975,7 @@ private void InitializeComponent() this.sliderTAAPostOverlay.LargeChange = 1; this.sliderTAAPostOverlay.Location = new System.Drawing.Point(9, 41); this.sliderTAAPostOverlay.Name = "sliderTAAPostOverlay"; - this.sliderTAAPostOverlay.Size = new System.Drawing.Size(282, 23); + this.sliderTAAPostOverlay.Size = new System.Drawing.Size(274, 23); this.sliderTAAPostOverlay.TabIndex = 27; this.sliderTAAPostOverlay.Text = "metroTrackBar1"; this.toolTip.SetToolTip(this.sliderTAAPostOverlay, "Sharpens the image.\r\n\r\nRecommended: 0.2\r\nDefault: 0.2\r\n\r\nAffected values: fTAAPos" + @@ -990,7 +991,7 @@ private void InitializeComponent() this.sliderTAAPostSharpen.Location = new System.Drawing.Point(9, 93); this.sliderTAAPostSharpen.Maximum = 200; this.sliderTAAPostSharpen.Name = "sliderTAAPostSharpen"; - this.sliderTAAPostSharpen.Size = new System.Drawing.Size(282, 23); + this.sliderTAAPostSharpen.Size = new System.Drawing.Size(274, 23); this.sliderTAAPostSharpen.TabIndex = 30; this.sliderTAAPostSharpen.Text = "metroTrackBar2"; this.toolTip.SetToolTip(this.sliderTAAPostSharpen, "Sharpens the image.\r\n\r\nDefault: 0.2\r\nRecommended: 0.4\r\n\r\nAffected values: fTAAPos" + @@ -1076,7 +1077,7 @@ private void InitializeComponent() // checkBoxNWMode // this.checkBoxNWMode.AutoSize = true; - this.checkBoxNWMode.Location = new System.Drawing.Point(6, 19); + this.checkBoxNWMode.Location = new System.Drawing.Point(10, 42); this.checkBoxNWMode.Name = "checkBoxNWMode"; this.checkBoxNWMode.Size = new System.Drawing.Size(127, 17); this.checkBoxNWMode.TabIndex = 17; @@ -1101,7 +1102,7 @@ private void InitializeComponent() // checkBoxMultipleGameEditionsUsed // this.checkBoxMultipleGameEditionsUsed.AutoSize = true; - this.checkBoxMultipleGameEditionsUsed.Location = new System.Drawing.Point(6, 64); + this.checkBoxMultipleGameEditionsUsed.Location = new System.Drawing.Point(10, 19); this.checkBoxMultipleGameEditionsUsed.Name = "checkBoxMultipleGameEditionsUsed"; this.checkBoxMultipleGameEditionsUsed.Size = new System.Drawing.Size(186, 17); this.checkBoxMultipleGameEditionsUsed.TabIndex = 18; @@ -1110,6 +1111,19 @@ private void InitializeComponent() "ndexFileList will be saved for every game edition separately."); this.checkBoxMultipleGameEditionsUsed.UseVisualStyleBackColor = true; // + // checkBoxDenyNTFSWritePermission + // + this.checkBoxDenyNTFSWritePermission.AutoSize = true; + this.checkBoxDenyNTFSWritePermission.Location = new System.Drawing.Point(10, 88); + this.checkBoxDenyNTFSWritePermission.Name = "checkBoxDenyNTFSWritePermission"; + this.checkBoxDenyNTFSWritePermission.Size = new System.Drawing.Size(231, 17); + this.checkBoxDenyNTFSWritePermission.TabIndex = 19; + this.checkBoxDenyNTFSWritePermission.Text = "[Experimental] Deny NTFS write permission."; + this.toolTip.SetToolTip(this.checkBoxDenyNTFSWritePermission, "This will deny write permission to the \"Fallout 76\" folder.\r\nUse this, if the rea" + + "d-only option doesn\'t work.\r\n\r\nAffected folder: %UserProfile%\\Documents\\My Games" + + "\\Fallout 76"); + this.checkBoxDenyNTFSWritePermission.UseVisualStyleBackColor = true; + // // checkBoxIgnoreUpdates // this.checkBoxIgnoreUpdates.AutoSize = true; @@ -1437,7 +1451,7 @@ private void InitializeComponent() this.groupBoxTAASharpening.Controls.Add(this.sliderTAAPostOverlay); this.groupBoxTAASharpening.Location = new System.Drawing.Point(9, 655); this.groupBoxTAASharpening.Name = "groupBoxTAASharpening"; - this.groupBoxTAASharpening.Size = new System.Drawing.Size(377, 134); + this.groupBoxTAASharpening.Size = new System.Drawing.Size(369, 134); this.groupBoxTAASharpening.TabIndex = 25; this.groupBoxTAASharpening.TabStop = false; this.groupBoxTAASharpening.Text = "TAA Sharpening"; @@ -1451,7 +1465,7 @@ private void InitializeComponent() 0, 0, 65536}); - this.numTAAPostSharpen.Location = new System.Drawing.Point(297, 93); + this.numTAAPostSharpen.Location = new System.Drawing.Point(289, 93); this.numTAAPostSharpen.Maximum = new decimal(new int[] { 9999999, 0, @@ -1484,7 +1498,7 @@ private void InitializeComponent() 0, 0, 65536}); - this.numTAAPostOverlay.Location = new System.Drawing.Point(297, 41); + this.numTAAPostOverlay.Location = new System.Drawing.Point(289, 41); this.numTAAPostOverlay.Maximum = new decimal(new int[] { 9999999, 0, @@ -1518,7 +1532,7 @@ private void InitializeComponent() this.groupBoxGrass.Controls.Add(this.checkBoxGrass); this.groupBoxGrass.Location = new System.Drawing.Point(9, 555); this.groupBoxGrass.Name = "groupBoxGrass"; - this.groupBoxGrass.Size = new System.Drawing.Size(377, 94); + this.groupBoxGrass.Size = new System.Drawing.Size(369, 94); this.groupBoxGrass.TabIndex = 23; this.groupBoxGrass.TabStop = false; this.groupBoxGrass.Text = "Grass"; @@ -1531,7 +1545,7 @@ private void InitializeComponent() 0, 0, 0}); - this.numGrassFadeDistance.Location = new System.Drawing.Point(297, 68); + this.numGrassFadeDistance.Location = new System.Drawing.Point(289, 68); this.numGrassFadeDistance.Maximum = new decimal(new int[] { 9999999, 0, @@ -1571,7 +1585,7 @@ private void InitializeComponent() this.groupBoxLOD.Controls.Add(this.labelLODObjects); this.groupBoxLOD.Location = new System.Drawing.Point(9, 419); this.groupBoxLOD.Name = "groupBoxLOD"; - this.groupBoxLOD.Size = new System.Drawing.Size(377, 130); + this.groupBoxLOD.Size = new System.Drawing.Size(369, 130); this.groupBoxLOD.TabIndex = 24; this.groupBoxLOD.TabStop = false; this.groupBoxLOD.Text = "LOD"; @@ -1589,7 +1603,7 @@ private void InitializeComponent() // this.numLODActors.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.numLODActors.DecimalPlaces = 1; - this.numLODActors.Location = new System.Drawing.Point(318, 100); + this.numLODActors.Location = new System.Drawing.Point(310, 100); this.numLODActors.Maximum = new decimal(new int[] { 9999999, 0, @@ -1608,7 +1622,7 @@ private void InitializeComponent() // this.numLODItems.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.numLODItems.DecimalPlaces = 1; - this.numLODItems.Location = new System.Drawing.Point(318, 71); + this.numLODItems.Location = new System.Drawing.Point(310, 71); this.numLODItems.Maximum = new decimal(new int[] { 9999999, 0, @@ -1627,7 +1641,7 @@ private void InitializeComponent() // this.numLODObjects.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.numLODObjects.DecimalPlaces = 1; - this.numLODObjects.Location = new System.Drawing.Point(318, 41); + this.numLODObjects.Location = new System.Drawing.Point(310, 41); this.numLODObjects.Maximum = new decimal(new int[] { 9999999, 0, @@ -1676,7 +1690,7 @@ private void InitializeComponent() this.groupBoxLighting.Controls.Add(this.checkBoxGodrays); this.groupBoxLighting.Location = new System.Drawing.Point(9, 233); this.groupBoxLighting.Name = "groupBoxLighting"; - this.groupBoxLighting.Size = new System.Drawing.Size(377, 46); + this.groupBoxLighting.Size = new System.Drawing.Size(369, 46); this.groupBoxLighting.TabIndex = 15; this.groupBoxLighting.TabStop = false; this.groupBoxLighting.Text = "Lighting"; @@ -1694,7 +1708,7 @@ private void InitializeComponent() this.groupBoxShadows.Controls.Add(this.labelShadowTextureResolution); this.groupBoxShadows.Location = new System.Drawing.Point(9, 285); this.groupBoxShadows.Name = "groupBoxShadows"; - this.groupBoxShadows.Size = new System.Drawing.Size(377, 128); + this.groupBoxShadows.Size = new System.Drawing.Size(369, 128); this.groupBoxShadows.TabIndex = 16; this.groupBoxShadows.TabStop = false; this.groupBoxShadows.Text = "Shadows"; @@ -1707,7 +1721,7 @@ private void InitializeComponent() this.comboBoxShadowBlurriness.FormattingEnabled = true; this.comboBoxShadowBlurriness.Location = new System.Drawing.Point(134, 47); this.comboBoxShadowBlurriness.Name = "comboBoxShadowBlurriness"; - this.comboBoxShadowBlurriness.Size = new System.Drawing.Size(237, 21); + this.comboBoxShadowBlurriness.Size = new System.Drawing.Size(229, 21); this.comboBoxShadowBlurriness.TabIndex = 30; // // numShadowDistance @@ -1718,7 +1732,7 @@ private void InitializeComponent() 0, 0, 0}); - this.numShadowDistance.Location = new System.Drawing.Point(297, 97); + this.numShadowDistance.Location = new System.Drawing.Point(289, 97); this.numShadowDistance.Maximum = new decimal(new int[] { 9999999, 0, @@ -1750,7 +1764,7 @@ private void InitializeComponent() this.comboBoxShadowTextureResolution.FormattingEnabled = true; this.comboBoxShadowTextureResolution.Location = new System.Drawing.Point(134, 20); this.comboBoxShadowTextureResolution.Name = "comboBoxShadowTextureResolution"; - this.comboBoxShadowTextureResolution.Size = new System.Drawing.Size(237, 21); + this.comboBoxShadowTextureResolution.Size = new System.Drawing.Size(229, 21); this.comboBoxShadowTextureResolution.TabIndex = 1; // // groupBoxWater @@ -1760,7 +1774,7 @@ private void InitializeComponent() this.groupBoxWater.Controls.Add(this.checkBoxWaterDisplacement); this.groupBoxWater.Location = new System.Drawing.Point(196, 89); this.groupBoxWater.Name = "groupBoxWater"; - this.groupBoxWater.Size = new System.Drawing.Size(190, 44); + this.groupBoxWater.Size = new System.Drawing.Size(182, 44); this.groupBoxWater.TabIndex = 17; this.groupBoxWater.TabStop = false; this.groupBoxWater.Text = "Water"; @@ -1788,7 +1802,7 @@ private void InitializeComponent() this.groupBoxWeather.Controls.Add(this.checkBoxWeatherRainOcclusion); this.groupBoxWeather.Location = new System.Drawing.Point(196, 139); this.groupBoxWeather.Name = "groupBoxWeather"; - this.groupBoxWeather.Size = new System.Drawing.Size(190, 88); + this.groupBoxWeather.Size = new System.Drawing.Size(182, 88); this.groupBoxWeather.TabIndex = 18; this.groupBoxWeather.TabStop = false; this.groupBoxWeather.Text = "Weather"; @@ -1801,7 +1815,7 @@ private void InitializeComponent() this.comboBoxAnisotropicFiltering.FormattingEnabled = true; this.comboBoxAnisotropicFiltering.Location = new System.Drawing.Point(152, 33); this.comboBoxAnisotropicFiltering.Name = "comboBoxAnisotropicFiltering"; - this.comboBoxAnisotropicFiltering.Size = new System.Drawing.Size(234, 21); + this.comboBoxAnisotropicFiltering.Size = new System.Drawing.Size(226, 21); this.comboBoxAnisotropicFiltering.TabIndex = 23; // // comboBoxAntiAliasing @@ -1812,7 +1826,7 @@ private void InitializeComponent() this.comboBoxAntiAliasing.FormattingEnabled = true; this.comboBoxAntiAliasing.Location = new System.Drawing.Point(152, 6); this.comboBoxAntiAliasing.Name = "comboBoxAntiAliasing"; - this.comboBoxAntiAliasing.Size = new System.Drawing.Size(234, 21); + this.comboBoxAntiAliasing.Size = new System.Drawing.Size(226, 21); this.comboBoxAntiAliasing.TabIndex = 8; // // tabPageDisplay @@ -1856,7 +1870,7 @@ private void InitializeComponent() this.groupBoxFieldOfView.Controls.Add(this.numFirstPersonFOV); this.groupBoxFieldOfView.Controls.Add(this.labelWorldFOV); this.groupBoxFieldOfView.Controls.Add(this.labelFirstPersonFOV); - this.groupBoxFieldOfView.Location = new System.Drawing.Point(6, 406); + this.groupBoxFieldOfView.Location = new System.Drawing.Point(6, 397); this.groupBoxFieldOfView.Name = "groupBoxFieldOfView"; this.groupBoxFieldOfView.Size = new System.Drawing.Size(380, 70); this.groupBoxFieldOfView.TabIndex = 20; @@ -2356,7 +2370,7 @@ private void InitializeComponent() this.groupBoxLaunchOptions.Controls.Add(this.labelLaunchOptionTip); this.groupBoxLaunchOptions.Controls.Add(this.radioButtonLaunchViaExecutable); this.groupBoxLaunchOptions.Controls.Add(this.radioButtonLaunchViaLink); - this.groupBoxLaunchOptions.Location = new System.Drawing.Point(6, 366); + this.groupBoxLaunchOptions.Location = new System.Drawing.Point(6, 391); this.groupBoxLaunchOptions.Name = "groupBoxLaunchOptions"; this.groupBoxLaunchOptions.Size = new System.Drawing.Size(376, 93); this.groupBoxLaunchOptions.TabIndex = 25; @@ -2445,7 +2459,7 @@ private void InitializeComponent() // this.buttonForceUpdate.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.buttonForceUpdate.Location = new System.Drawing.Point(6, 603); + this.buttonForceUpdate.Location = new System.Drawing.Point(6, 628); this.buttonForceUpdate.Name = "buttonForceUpdate"; this.buttonForceUpdate.Size = new System.Drawing.Size(376, 23); this.buttonForceUpdate.TabIndex = 23; @@ -2462,7 +2476,7 @@ private void InitializeComponent() this.groupBoxBehavior.Controls.Add(this.checkBoxQuitOnGameLaunch); this.groupBoxBehavior.Controls.Add(this.checkBoxSkipBackupQuestion); this.groupBoxBehavior.Controls.Add(this.checkBoxAutoApply); - this.groupBoxBehavior.Location = new System.Drawing.Point(6, 465); + this.groupBoxBehavior.Location = new System.Drawing.Point(6, 490); this.groupBoxBehavior.Name = "groupBoxBehavior"; this.groupBoxBehavior.Size = new System.Drawing.Size(376, 132); this.groupBoxBehavior.TabIndex = 22; @@ -2531,12 +2545,13 @@ private void InitializeComponent() // this.groupBoxOptions.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this.groupBoxOptions.Controls.Add(this.checkBoxDenyNTFSWritePermission); this.groupBoxOptions.Controls.Add(this.checkBoxMultipleGameEditionsUsed); this.groupBoxOptions.Controls.Add(this.checkBoxNWMode); this.groupBoxOptions.Controls.Add(this.checkBoxReadOnly); this.groupBoxOptions.Location = new System.Drawing.Point(6, 269); this.groupBoxOptions.Name = "groupBoxOptions"; - this.groupBoxOptions.Size = new System.Drawing.Size(376, 91); + this.groupBoxOptions.Size = new System.Drawing.Size(376, 116); this.groupBoxOptions.TabIndex = 15; this.groupBoxOptions.TabStop = false; this.groupBoxOptions.Text = "Options"; @@ -2545,7 +2560,7 @@ private void InitializeComponent() // this.buttonFixIssuesEarlierVersion.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.buttonFixIssuesEarlierVersion.Location = new System.Drawing.Point(6, 632); + this.buttonFixIssuesEarlierVersion.Location = new System.Drawing.Point(6, 657); this.buttonFixIssuesEarlierVersion.Name = "buttonFixIssuesEarlierVersion"; this.buttonFixIssuesEarlierVersion.Size = new System.Drawing.Size(376, 23); this.buttonFixIssuesEarlierVersion.TabIndex = 19; @@ -2840,6 +2855,7 @@ private void InitializeComponent() private System.Windows.Forms.RadioButton radioButtonLaunchViaLink; private System.Windows.Forms.Label labelLaunchOptionTip; private System.Windows.Forms.OpenFileDialog openFileDialogGamePath; + private System.Windows.Forms.CheckBox checkBoxDenyNTFSWritePermission; } } diff --git a/Fo76ini/Form1.cs b/Fo76ini/Form1.cs index df4d143..0f9b7b8 100644 --- a/Fo76ini/Form1.cs +++ b/Fo76ini/Form1.cs @@ -15,7 +15,7 @@ namespace Fo76ini { public partial class Form1 : Form { - public const String VERSION = "1.6.2"; + public const String VERSION = "1.6.3"; protected System.Globalization.CultureInfo enUS = System.Globalization.CultureInfo.CreateSpecificCulture("en-US"); @@ -189,10 +189,7 @@ private void Form1_Load(object sender, EventArgs e) if (IniFiles.Instance.GetBool(IniFile.Config, "Preferences", "bOpenModManagerOnLaunch", false)) - { - Utils.SetFormPosition(this.formMods, this.Location.X + this.Width, this.Location.Y); - this.formMods.Show(); - } + this.formMods.OpenUI(); IniFiles.Instance.LoadWindowState("Form1", this); @@ -294,6 +291,9 @@ private void AddAllEventHandler() IniFiles.Instance.SetINIsReadOnly ); + // Deny NTFS write-permission + uiLoader.LinkBool(this.checkBoxDenyNTFSWritePermission, IniFile.Config, "Preferences", "bDenyNTFSWritePermission", false); + /* * Settings */ @@ -730,7 +730,7 @@ private void AddAllEventHandler() // Fix aim sensitivity uiLoader.LinkCustom(this.checkBoxFixAimSensitivity, - () => IniFiles.Instance.GetFloat("Main", "fIronSightsFOVRotateMult", 0f) - 2.14f < 0.1f, + () => Math.Abs(IniFiles.Instance.GetFloat("Main", "fIronSightsFOVRotateMult", 0f) - 2.14f) < 0.1f, (value) => { if (value) { @@ -888,9 +888,7 @@ private void buttonManageMods_Click(object sender, EventArgs e) IniFiles.Instance.BackupAll("Backup_BeforeManageMods"); // Just to be sure... formModsBackupCreated = true; } - Utils.SetFormPosition(this.formMods, this.Location.X + this.Width, this.Location.Y); - this.formMods.UpdateUI(); - this.formMods.Show(); + this.formMods.OpenUI(); } /*private void linkLabel1_LinkClicked_1(object sender, LinkLabelLinkClickedEventArgs e) @@ -962,11 +960,7 @@ private void checkBoxNWMode_CheckedChanged(object sender, EventArgs e) if (MsgBox.ShowID("nwModeEnabledButModsAreDeployed", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { ManagedMods.Instance.nuclearWinterMode = IniFiles.Instance.nuclearWinterMode; - - Utils.SetFormPosition(this.formMods, this.Location.X + this.Width, this.Location.Y); - this.formMods.Show(); - this.formMods.UpdateUI(); - + this.formMods.OpenUI(); this.formMods.Deploy(); } } diff --git a/Fo76ini/FormModDetails.Designer.cs b/Fo76ini/FormModDetails.Designer.cs index 0f4ae04..cddebff 100644 --- a/Fo76ini/FormModDetails.Designer.cs +++ b/Fo76ini/FormModDetails.Designer.cs @@ -39,15 +39,19 @@ private void InitializeComponent() this.labelModName = new System.Windows.Forms.Label(); this.textBoxModName = new System.Windows.Forms.TextBox(); this.panel1 = new System.Windows.Forms.Panel(); - this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.checkBoxModDetailsEnabled = new System.Windows.Forms.CheckBox(); + this.labelModDetailsBulkFrozenModsWarning = new System.Windows.Forms.Label(); + this.groupBoxSeparateArchivePresets = new System.Windows.Forms.GroupBox(); + this.radioButtonSeparateArchiveCustom = new System.Windows.Forms.RadioButton(); + this.radioButtonSeparateArchiveSounds = new System.Windows.Forms.RadioButton(); + this.radioButtonSeparateArchiveTextures = new System.Windows.Forms.RadioButton(); + this.radioButtonSeparateArchiveGeneral = new System.Windows.Forms.RadioButton(); this.labelModUnfreeze = new System.Windows.Forms.Label(); this.buttonModUnfreeze = new System.Windows.Forms.Button(); this.checkBoxFreezeArchive = new System.Windows.Forms.CheckBox(); - this.labelModDetailsStatus = new System.Windows.Forms.Label(); this.buttonModRepairDDS = new System.Windows.Forms.Button(); this.separator2 = new System.Windows.Forms.Label(); this.separator1 = new System.Windows.Forms.Label(); - this.checkBoxModDetailsEnabled = new System.Windows.Forms.CheckBox(); this.comboBoxModArchiveFormat = new System.Windows.Forms.ComboBox(); this.buttonModOpenFolder = new System.Windows.Forms.Button(); this.labelModFolderName = new System.Windows.Forms.Label(); @@ -55,26 +59,22 @@ private void InitializeComponent() this.textBoxModFolderName = new System.Windows.Forms.TextBox(); this.comboBoxModInstallAs = new System.Windows.Forms.ComboBox(); this.labelModInstallAs = new System.Windows.Forms.Label(); + this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.labelModDetailsStatus = new System.Windows.Forms.Label(); this.buttonModDetailsApply = new System.Windows.Forms.Button(); this.buttonModDetailsOK = new System.Windows.Forms.Button(); this.buttonModDetailsCancel = new System.Windows.Forms.Button(); this.folderBrowserDialogPickRootDir = new System.Windows.Forms.FolderBrowserDialog(); this.toolTip = new System.Windows.Forms.ToolTip(this.components); - this.groupBoxSeparateArchivePresets = new System.Windows.Forms.GroupBox(); - this.radioButtonSeparateArchiveGeneral = new System.Windows.Forms.RadioButton(); - this.radioButtonSeparateArchiveTextures = new System.Windows.Forms.RadioButton(); - this.radioButtonSeparateArchiveSounds = new System.Windows.Forms.RadioButton(); - this.radioButtonSeparateArchiveCustom = new System.Windows.Forms.RadioButton(); - this.labelModDetailsBulkFrozenModsWarning = new System.Windows.Forms.Label(); this.panel1.SuspendLayout(); this.groupBoxSeparateArchivePresets.SuspendLayout(); this.SuspendLayout(); // // textBoxModArchiveName // - this.textBoxModArchiveName.Location = new System.Drawing.Point(112, 174); + this.textBoxModArchiveName.Location = new System.Drawing.Point(125, 174); this.textBoxModArchiveName.Name = "textBoxModArchiveName"; - this.textBoxModArchiveName.Size = new System.Drawing.Size(231, 20); + this.textBoxModArchiveName.Size = new System.Drawing.Size(218, 20); this.textBoxModArchiveName.TabIndex = 7; this.textBoxModArchiveName.TextChanged += new System.EventHandler(this.textBoxModArchiveName_TextChanged); // @@ -110,9 +110,9 @@ private void InitializeComponent() // // textBoxModRootDir // - this.textBoxModRootDir.Location = new System.Drawing.Point(112, 121); + this.textBoxModRootDir.Location = new System.Drawing.Point(125, 121); this.textBoxModRootDir.Name = "textBoxModRootDir"; - this.textBoxModRootDir.Size = new System.Drawing.Size(199, 20); + this.textBoxModRootDir.Size = new System.Drawing.Size(186, 20); this.textBoxModRootDir.TabIndex = 4; this.textBoxModRootDir.TextChanged += new System.EventHandler(this.textBoxModRootDir_TextChanged); // @@ -136,9 +136,9 @@ private void InitializeComponent() // // textBoxModName // - this.textBoxModName.Location = new System.Drawing.Point(112, 29); + this.textBoxModName.Location = new System.Drawing.Point(125, 29); this.textBoxModName.Name = "textBoxModName"; - this.textBoxModName.Size = new System.Drawing.Size(231, 20); + this.textBoxModName.Size = new System.Drawing.Size(218, 20); this.textBoxModName.TabIndex = 1; this.textBoxModName.TextChanged += new System.EventHandler(this.textBoxModName_TextChanged); // @@ -176,13 +176,82 @@ private void InitializeComponent() this.panel1.TabIndex = 44; this.panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.panel1_Paint); // - // progressBar1 + // checkBoxModDetailsEnabled // - this.progressBar1.Location = new System.Drawing.Point(5, 418); - this.progressBar1.MarqueeAnimationSpeed = 15; - this.progressBar1.Name = "progressBar1"; - this.progressBar1.Size = new System.Drawing.Size(349, 23); - this.progressBar1.TabIndex = 58; + this.checkBoxModDetailsEnabled.AutoSize = true; + this.checkBoxModDetailsEnabled.Location = new System.Drawing.Point(10, 7); + this.checkBoxModDetailsEnabled.Name = "checkBoxModDetailsEnabled"; + this.checkBoxModDetailsEnabled.Size = new System.Drawing.Size(101, 17); + this.checkBoxModDetailsEnabled.TabIndex = 0; + this.checkBoxModDetailsEnabled.Text = "Enable this mod"; + this.checkBoxModDetailsEnabled.UseVisualStyleBackColor = true; + this.checkBoxModDetailsEnabled.CheckedChanged += new System.EventHandler(this.checkBoxModDetailsEnabled_CheckedChanged); + // + // labelModDetailsBulkFrozenModsWarning + // + this.labelModDetailsBulkFrozenModsWarning.AutoSize = true; + this.labelModDetailsBulkFrozenModsWarning.ForeColor = System.Drawing.Color.Red; + this.labelModDetailsBulkFrozenModsWarning.Location = new System.Drawing.Point(7, 8); + this.labelModDetailsBulkFrozenModsWarning.Name = "labelModDetailsBulkFrozenModsWarning"; + this.labelModDetailsBulkFrozenModsWarning.Size = new System.Drawing.Size(176, 13); + this.labelModDetailsBulkFrozenModsWarning.TabIndex = 59; + this.labelModDetailsBulkFrozenModsWarning.Text = "NOTE: Frozen mods will be ignored."; + // + // groupBoxSeparateArchivePresets + // + this.groupBoxSeparateArchivePresets.Controls.Add(this.radioButtonSeparateArchiveCustom); + this.groupBoxSeparateArchivePresets.Controls.Add(this.radioButtonSeparateArchiveSounds); + this.groupBoxSeparateArchivePresets.Controls.Add(this.radioButtonSeparateArchiveTextures); + this.groupBoxSeparateArchivePresets.Controls.Add(this.radioButtonSeparateArchiveGeneral); + this.groupBoxSeparateArchivePresets.Location = new System.Drawing.Point(181, 200); + this.groupBoxSeparateArchivePresets.Name = "groupBoxSeparateArchivePresets"; + this.groupBoxSeparateArchivePresets.Size = new System.Drawing.Size(162, 109); + this.groupBoxSeparateArchivePresets.TabIndex = 58; + this.groupBoxSeparateArchivePresets.TabStop = false; + this.groupBoxSeparateArchivePresets.Text = "Presets"; + // + // radioButtonSeparateArchiveCustom + // + this.radioButtonSeparateArchiveCustom.AutoSize = true; + this.radioButtonSeparateArchiveCustom.Location = new System.Drawing.Point(6, 88); + this.radioButtonSeparateArchiveCustom.Name = "radioButtonSeparateArchiveCustom"; + this.radioButtonSeparateArchiveCustom.Size = new System.Drawing.Size(60, 17); + this.radioButtonSeparateArchiveCustom.TabIndex = 3; + this.radioButtonSeparateArchiveCustom.Text = "Custom"; + this.radioButtonSeparateArchiveCustom.UseVisualStyleBackColor = true; + // + // radioButtonSeparateArchiveSounds + // + this.radioButtonSeparateArchiveSounds.AutoSize = true; + this.radioButtonSeparateArchiveSounds.Location = new System.Drawing.Point(6, 65); + this.radioButtonSeparateArchiveSounds.Name = "radioButtonSeparateArchiveSounds"; + this.radioButtonSeparateArchiveSounds.Size = new System.Drawing.Size(61, 17); + this.radioButtonSeparateArchiveSounds.TabIndex = 2; + this.radioButtonSeparateArchiveSounds.Text = "Sounds"; + this.radioButtonSeparateArchiveSounds.UseVisualStyleBackColor = true; + this.radioButtonSeparateArchiveSounds.CheckedChanged += new System.EventHandler(this.radioButtonSeparateArchiveSounds_CheckedChanged); + // + // radioButtonSeparateArchiveTextures + // + this.radioButtonSeparateArchiveTextures.AutoSize = true; + this.radioButtonSeparateArchiveTextures.Location = new System.Drawing.Point(6, 42); + this.radioButtonSeparateArchiveTextures.Name = "radioButtonSeparateArchiveTextures"; + this.radioButtonSeparateArchiveTextures.Size = new System.Drawing.Size(120, 17); + this.radioButtonSeparateArchiveTextures.TabIndex = 1; + this.radioButtonSeparateArchiveTextures.Text = "Textures (*.dds files)"; + this.radioButtonSeparateArchiveTextures.UseVisualStyleBackColor = true; + this.radioButtonSeparateArchiveTextures.CheckedChanged += new System.EventHandler(this.radioButtonSeparateArchiveTextures_CheckedChanged); + // + // radioButtonSeparateArchiveGeneral + // + this.radioButtonSeparateArchiveGeneral.AutoSize = true; + this.radioButtonSeparateArchiveGeneral.Location = new System.Drawing.Point(6, 19); + this.radioButtonSeparateArchiveGeneral.Name = "radioButtonSeparateArchiveGeneral"; + this.radioButtonSeparateArchiveGeneral.Size = new System.Drawing.Size(115, 17); + this.radioButtonSeparateArchiveGeneral.TabIndex = 0; + this.radioButtonSeparateArchiveGeneral.Text = "General / Interface"; + this.radioButtonSeparateArchiveGeneral.UseVisualStyleBackColor = true; + this.radioButtonSeparateArchiveGeneral.CheckedChanged += new System.EventHandler(this.radioButtonSeparateArchiveGeneral_CheckedChanged); // // labelModUnfreeze // @@ -219,17 +288,6 @@ private void InitializeComponent() this.checkBoxFreezeArchive.UseVisualStyleBackColor = true; this.checkBoxFreezeArchive.CheckedChanged += new System.EventHandler(this.checkBoxFreezeArchive_CheckedChanged); // - // labelModDetailsStatus - // - this.labelModDetailsStatus.AutoSize = true; - this.labelModDetailsStatus.ForeColor = System.Drawing.SystemColors.HotTrack; - this.labelModDetailsStatus.Location = new System.Drawing.Point(6, 402); - this.labelModDetailsStatus.Name = "labelModDetailsStatus"; - this.labelModDetailsStatus.Size = new System.Drawing.Size(16, 13); - this.labelModDetailsStatus.TabIndex = 53; - this.labelModDetailsStatus.Text = "..."; - this.labelModDetailsStatus.Visible = false; - // // buttonModRepairDDS // this.buttonModRepairDDS.Location = new System.Drawing.Point(7, 361); @@ -257,24 +315,13 @@ private void InitializeComponent() this.separator1.Size = new System.Drawing.Size(336, 2); this.separator1.TabIndex = 50; // - // checkBoxModDetailsEnabled - // - this.checkBoxModDetailsEnabled.AutoSize = true; - this.checkBoxModDetailsEnabled.Location = new System.Drawing.Point(10, 7); - this.checkBoxModDetailsEnabled.Name = "checkBoxModDetailsEnabled"; - this.checkBoxModDetailsEnabled.Size = new System.Drawing.Size(101, 17); - this.checkBoxModDetailsEnabled.TabIndex = 0; - this.checkBoxModDetailsEnabled.Text = "Enable this mod"; - this.checkBoxModDetailsEnabled.UseVisualStyleBackColor = true; - this.checkBoxModDetailsEnabled.CheckedChanged += new System.EventHandler(this.checkBoxModDetailsEnabled_CheckedChanged); - // // comboBoxModArchiveFormat // this.comboBoxModArchiveFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxModArchiveFormat.FormattingEnabled = true; - this.comboBoxModArchiveFormat.Location = new System.Drawing.Point(112, 147); + this.comboBoxModArchiveFormat.Location = new System.Drawing.Point(125, 147); this.comboBoxModArchiveFormat.Name = "comboBoxModArchiveFormat"; - this.comboBoxModArchiveFormat.Size = new System.Drawing.Size(231, 21); + this.comboBoxModArchiveFormat.Size = new System.Drawing.Size(218, 21); this.comboBoxModArchiveFormat.TabIndex = 6; this.comboBoxModArchiveFormat.SelectedIndexChanged += new System.EventHandler(this.comboBoxModArchiveFormat_SelectedIndexChanged); // @@ -309,9 +356,9 @@ private void InitializeComponent() // // textBoxModFolderName // - this.textBoxModFolderName.Location = new System.Drawing.Point(112, 54); + this.textBoxModFolderName.Location = new System.Drawing.Point(125, 54); this.textBoxModFolderName.Name = "textBoxModFolderName"; - this.textBoxModFolderName.Size = new System.Drawing.Size(231, 20); + this.textBoxModFolderName.Size = new System.Drawing.Size(218, 20); this.textBoxModFolderName.TabIndex = 2; this.textBoxModFolderName.TextChanged += new System.EventHandler(this.textBoxModFolderName_TextChanged); // @@ -319,9 +366,9 @@ private void InitializeComponent() // this.comboBoxModInstallAs.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBoxModInstallAs.FormattingEnabled = true; - this.comboBoxModInstallAs.Location = new System.Drawing.Point(112, 94); + this.comboBoxModInstallAs.Location = new System.Drawing.Point(125, 94); this.comboBoxModInstallAs.Name = "comboBoxModInstallAs"; - this.comboBoxModInstallAs.Size = new System.Drawing.Size(231, 21); + this.comboBoxModInstallAs.Size = new System.Drawing.Size(218, 21); this.comboBoxModInstallAs.TabIndex = 3; this.comboBoxModInstallAs.SelectedIndexChanged += new System.EventHandler(this.comboBoxModInstallAs_SelectedIndexChanged); // @@ -334,6 +381,25 @@ private void InitializeComponent() this.labelModInstallAs.TabIndex = 41; this.labelModInstallAs.Text = "Install as:"; // + // progressBar1 + // + this.progressBar1.Location = new System.Drawing.Point(5, 418); + this.progressBar1.MarqueeAnimationSpeed = 15; + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(349, 23); + this.progressBar1.TabIndex = 58; + // + // labelModDetailsStatus + // + this.labelModDetailsStatus.AutoSize = true; + this.labelModDetailsStatus.ForeColor = System.Drawing.SystemColors.HotTrack; + this.labelModDetailsStatus.Location = new System.Drawing.Point(6, 402); + this.labelModDetailsStatus.Name = "labelModDetailsStatus"; + this.labelModDetailsStatus.Size = new System.Drawing.Size(16, 13); + this.labelModDetailsStatus.TabIndex = 53; + this.labelModDetailsStatus.Text = "..."; + this.labelModDetailsStatus.Visible = false; + // // buttonModDetailsApply // this.buttonModDetailsApply.Location = new System.Drawing.Point(279, 447); @@ -368,72 +434,6 @@ private void InitializeComponent() this.buttonModDetailsCancel.UseVisualStyleBackColor = true; this.buttonModDetailsCancel.Click += new System.EventHandler(this.buttonModDetailsCancel_Click); // - // groupBoxSeparateArchivePresets - // - this.groupBoxSeparateArchivePresets.Controls.Add(this.radioButtonSeparateArchiveCustom); - this.groupBoxSeparateArchivePresets.Controls.Add(this.radioButtonSeparateArchiveSounds); - this.groupBoxSeparateArchivePresets.Controls.Add(this.radioButtonSeparateArchiveTextures); - this.groupBoxSeparateArchivePresets.Controls.Add(this.radioButtonSeparateArchiveGeneral); - this.groupBoxSeparateArchivePresets.Location = new System.Drawing.Point(181, 200); - this.groupBoxSeparateArchivePresets.Name = "groupBoxSeparateArchivePresets"; - this.groupBoxSeparateArchivePresets.Size = new System.Drawing.Size(162, 109); - this.groupBoxSeparateArchivePresets.TabIndex = 58; - this.groupBoxSeparateArchivePresets.TabStop = false; - this.groupBoxSeparateArchivePresets.Text = "Presets"; - // - // radioButtonSeparateArchiveGeneral - // - this.radioButtonSeparateArchiveGeneral.AutoSize = true; - this.radioButtonSeparateArchiveGeneral.Location = new System.Drawing.Point(6, 19); - this.radioButtonSeparateArchiveGeneral.Name = "radioButtonSeparateArchiveGeneral"; - this.radioButtonSeparateArchiveGeneral.Size = new System.Drawing.Size(115, 17); - this.radioButtonSeparateArchiveGeneral.TabIndex = 0; - this.radioButtonSeparateArchiveGeneral.Text = "General / Interface"; - this.radioButtonSeparateArchiveGeneral.UseVisualStyleBackColor = true; - this.radioButtonSeparateArchiveGeneral.CheckedChanged += new System.EventHandler(this.radioButtonSeparateArchiveGeneral_CheckedChanged); - // - // radioButtonSeparateArchiveTextures - // - this.radioButtonSeparateArchiveTextures.AutoSize = true; - this.radioButtonSeparateArchiveTextures.Location = new System.Drawing.Point(6, 42); - this.radioButtonSeparateArchiveTextures.Name = "radioButtonSeparateArchiveTextures"; - this.radioButtonSeparateArchiveTextures.Size = new System.Drawing.Size(120, 17); - this.radioButtonSeparateArchiveTextures.TabIndex = 1; - this.radioButtonSeparateArchiveTextures.Text = "Textures (*.dds files)"; - this.radioButtonSeparateArchiveTextures.UseVisualStyleBackColor = true; - this.radioButtonSeparateArchiveTextures.CheckedChanged += new System.EventHandler(this.radioButtonSeparateArchiveTextures_CheckedChanged); - // - // radioButtonSeparateArchiveSounds - // - this.radioButtonSeparateArchiveSounds.AutoSize = true; - this.radioButtonSeparateArchiveSounds.Location = new System.Drawing.Point(6, 65); - this.radioButtonSeparateArchiveSounds.Name = "radioButtonSeparateArchiveSounds"; - this.radioButtonSeparateArchiveSounds.Size = new System.Drawing.Size(61, 17); - this.radioButtonSeparateArchiveSounds.TabIndex = 2; - this.radioButtonSeparateArchiveSounds.Text = "Sounds"; - this.radioButtonSeparateArchiveSounds.UseVisualStyleBackColor = true; - this.radioButtonSeparateArchiveSounds.CheckedChanged += new System.EventHandler(this.radioButtonSeparateArchiveSounds_CheckedChanged); - // - // radioButtonSeparateArchiveCustom - // - this.radioButtonSeparateArchiveCustom.AutoSize = true; - this.radioButtonSeparateArchiveCustom.Location = new System.Drawing.Point(6, 88); - this.radioButtonSeparateArchiveCustom.Name = "radioButtonSeparateArchiveCustom"; - this.radioButtonSeparateArchiveCustom.Size = new System.Drawing.Size(60, 17); - this.radioButtonSeparateArchiveCustom.TabIndex = 3; - this.radioButtonSeparateArchiveCustom.Text = "Custom"; - this.radioButtonSeparateArchiveCustom.UseVisualStyleBackColor = true; - // - // labelModDetailsBulkFrozenModsWarning - // - this.labelModDetailsBulkFrozenModsWarning.AutoSize = true; - this.labelModDetailsBulkFrozenModsWarning.ForeColor = System.Drawing.Color.Red; - this.labelModDetailsBulkFrozenModsWarning.Location = new System.Drawing.Point(7, 8); - this.labelModDetailsBulkFrozenModsWarning.Name = "labelModDetailsBulkFrozenModsWarning"; - this.labelModDetailsBulkFrozenModsWarning.Size = new System.Drawing.Size(176, 13); - this.labelModDetailsBulkFrozenModsWarning.TabIndex = 59; - this.labelModDetailsBulkFrozenModsWarning.Text = "NOTE: Frozen mods will be ignored."; - // // FormModDetails // this.AcceptButton = this.buttonModDetailsOK; diff --git a/Fo76ini/FormModDetails.cs b/Fo76ini/FormModDetails.cs index 0fcc7cd..95cdada 100644 --- a/Fo76ini/FormModDetails.cs +++ b/Fo76ini/FormModDetails.cs @@ -448,16 +448,17 @@ private void buttonModUnfreeze_Click(object sender, EventArgs e) (text, percent) => { Invoke(() => SetProgress(text, percent)); - }, () => + }, + (success) => { Invoke(() => { this.formMods.ModDetailsFeedback(this.changedMod); UpdateUI(); - SetDone(); - /*this.formMods.ModDetailsClosed(); - Hide(); - this.formMods.Deploy();*/ + if (success) + SetDone(); + else + SetFailed(); }); } ); @@ -512,6 +513,15 @@ private void SetDone() this.progressBar1.Style = ProgressBarStyle.Continuous; } + private void SetFailed() + { + this.labelModDetailsStatus.Visible = true; + this.labelModDetailsStatus.ForeColor = Color.Red; + this.labelModDetailsStatus.Text = "Failed."; + this.progressBar1.Value = 100; + this.progressBar1.Style = ProgressBarStyle.Continuous; + } + private void SetProgress(String text, int percent) { this.labelModDetailsStatus.Text = text; diff --git a/Fo76ini/FormMods.Designer.cs b/Fo76ini/FormMods.Designer.cs index 09fb290..c5f9e53 100644 --- a/Fo76ini/FormMods.Designer.cs +++ b/Fo76ini/FormMods.Designer.cs @@ -52,10 +52,20 @@ private void InitializeComponent() this.tabControl1 = new System.Windows.Forms.TabControl(); this.tabPageModOrder = new System.Windows.Forms.TabPage(); this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this.toolStripButtonAddMod = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonAddModFrozen = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonAddModFolder = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButtonCheckAll = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButtonMoveUp = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonMoveDown = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButtonModEdit = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonUnfreeze = new System.Windows.Forms.ToolStripButton(); + this.toolStripButtonModOpenFolder = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripButtonDeleteMod = new System.Windows.Forms.ToolStripButton(); this.listViewMods = new System.Windows.Forms.ListView(); this.columnHeaderModTitle = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderInstallAs = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); @@ -65,6 +75,9 @@ private void InitializeComponent() this.columnHeaderCompression = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.columnHeaderFrozenState = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.tabPageModsSettings = new System.Windows.Forms.TabPage(); + this.groupBoxModsBehavior = new System.Windows.Forms.GroupBox(); + this.checkBoxModsUseHardlinks = new System.Windows.Forms.CheckBox(); + this.checkBoxAddArchivesAsBundled = new System.Windows.Forms.CheckBox(); this.groupBoxLists = new System.Windows.Forms.GroupBox(); this.buttonModsResetTextboxes = new System.Windows.Forms.Button(); this.buttonModsApplyTextBoxes = new System.Windows.Forms.Button(); @@ -80,21 +93,12 @@ private void InitializeComponent() this.openFileDialogGamePath = new System.Windows.Forms.OpenFileDialog(); this.panel1 = new System.Windows.Forms.Panel(); this.openFileDialogBA2 = new System.Windows.Forms.OpenFileDialog(); - this.toolStripButtonAddMod = new System.Windows.Forms.ToolStripButton(); - this.toolStripButtonAddModFrozen = new System.Windows.Forms.ToolStripButton(); - this.toolStripButtonAddModFolder = new System.Windows.Forms.ToolStripButton(); - this.toolStripButtonCheckAll = new System.Windows.Forms.ToolStripButton(); - this.toolStripButtonMoveUp = new System.Windows.Forms.ToolStripButton(); - this.toolStripButtonMoveDown = new System.Windows.Forms.ToolStripButton(); - this.toolStripButtonModEdit = new System.Windows.Forms.ToolStripButton(); - this.toolStripButtonModOpenFolder = new System.Windows.Forms.ToolStripButton(); - this.toolStripButtonDeleteMod = new System.Windows.Forms.ToolStripButton(); - this.toolStripButtonUnfreeze = new System.Windows.Forms.ToolStripButton(); this.menuStrip1.SuspendLayout(); this.tabControl1.SuspendLayout(); this.tabPageModOrder.SuspendLayout(); this.toolStrip1.SuspendLayout(); this.tabPageModsSettings.SuspendLayout(); + this.groupBoxModsBehavior.SuspendLayout(); this.groupBoxLists.SuspendLayout(); this.panel1.SuspendLayout(); this.SuspendLayout(); @@ -306,34 +310,154 @@ private void InitializeComponent() this.toolStrip1.Location = new System.Drawing.Point(3, 3); this.toolStrip1.Name = "toolStrip1"; this.toolStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System; - this.toolStrip1.Size = new System.Drawing.Size(32, 438); + this.toolStrip1.Size = new System.Drawing.Size(31, 438); this.toolStrip1.TabIndex = 44; this.toolStrip1.Text = "toolStrip1"; // + // toolStripButtonAddMod + // + this.toolStripButtonAddMod.AutoSize = false; + this.toolStripButtonAddMod.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonAddMod.Image = global::Fo76ini.Properties.Resources.plus; + this.toolStripButtonAddMod.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this.toolStripButtonAddMod.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonAddMod.Name = "toolStripButtonAddMod"; + this.toolStripButtonAddMod.Size = new System.Drawing.Size(30, 30); + this.toolStripButtonAddMod.Text = "Add mod (from archive)"; + this.toolStripButtonAddMod.Click += new System.EventHandler(this.toolStripButtonAddMod_Click); + // + // toolStripButtonAddModFrozen + // + this.toolStripButtonAddModFrozen.AutoSize = false; + this.toolStripButtonAddModFrozen.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonAddModFrozen.Image = global::Fo76ini.Properties.Resources.frozen_plus; + this.toolStripButtonAddModFrozen.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this.toolStripButtonAddModFrozen.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonAddModFrozen.Name = "toolStripButtonAddModFrozen"; + this.toolStripButtonAddModFrozen.Size = new System.Drawing.Size(30, 30); + this.toolStripButtonAddModFrozen.Text = "Add mod (from *.ba2 archive)"; + this.toolStripButtonAddModFrozen.Click += new System.EventHandler(this.toolStripButtonAddModFrozen_Click); + // + // toolStripButtonAddModFolder + // + this.toolStripButtonAddModFolder.AutoSize = false; + this.toolStripButtonAddModFolder.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonAddModFolder.Image = global::Fo76ini.Properties.Resources.folder_plus; + this.toolStripButtonAddModFolder.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this.toolStripButtonAddModFolder.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonAddModFolder.Name = "toolStripButtonAddModFolder"; + this.toolStripButtonAddModFolder.Size = new System.Drawing.Size(30, 30); + this.toolStripButtonAddModFolder.Text = "Add mod (from folder)"; + this.toolStripButtonAddModFolder.Click += new System.EventHandler(this.toolStripButtonAddModFolder_Click); + // // toolStripSeparator4 // this.toolStripSeparator4.Margin = new System.Windows.Forms.Padding(0, 8, 0, 8); this.toolStripSeparator4.Name = "toolStripSeparator4"; this.toolStripSeparator4.Size = new System.Drawing.Size(28, 6); // + // toolStripButtonCheckAll + // + this.toolStripButtonCheckAll.AutoSize = false; + this.toolStripButtonCheckAll.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonCheckAll.Image = global::Fo76ini.Properties.Resources.checkbox_checked; + this.toolStripButtonCheckAll.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this.toolStripButtonCheckAll.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonCheckAll.Name = "toolStripButtonCheckAll"; + this.toolStripButtonCheckAll.Size = new System.Drawing.Size(30, 30); + this.toolStripButtonCheckAll.Text = "Check/uncheck all"; + this.toolStripButtonCheckAll.Click += new System.EventHandler(this.toolStripButtonCheckAll_Click); + // // toolStripSeparator2 // this.toolStripSeparator2.Margin = new System.Windows.Forms.Padding(0, 8, 0, 8); this.toolStripSeparator2.Name = "toolStripSeparator2"; this.toolStripSeparator2.Size = new System.Drawing.Size(28, 6); // + // toolStripButtonMoveUp + // + this.toolStripButtonMoveUp.AutoSize = false; + this.toolStripButtonMoveUp.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonMoveUp.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButtonMoveUp.Image"))); + this.toolStripButtonMoveUp.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this.toolStripButtonMoveUp.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonMoveUp.Name = "toolStripButtonMoveUp"; + this.toolStripButtonMoveUp.Size = new System.Drawing.Size(30, 30); + this.toolStripButtonMoveUp.Text = "Move up"; + this.toolStripButtonMoveUp.Click += new System.EventHandler(this.toolStripButtonMoveUp_Click); + // + // toolStripButtonMoveDown + // + this.toolStripButtonMoveDown.AutoSize = false; + this.toolStripButtonMoveDown.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonMoveDown.Image = global::Fo76ini.Properties.Resources.arrow_down; + this.toolStripButtonMoveDown.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this.toolStripButtonMoveDown.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonMoveDown.Name = "toolStripButtonMoveDown"; + this.toolStripButtonMoveDown.Size = new System.Drawing.Size(30, 30); + this.toolStripButtonMoveDown.Text = "Move down"; + this.toolStripButtonMoveDown.Click += new System.EventHandler(this.toolStripButtonMoveDown_Click); + // // toolStripSeparator3 // this.toolStripSeparator3.Margin = new System.Windows.Forms.Padding(0, 8, 0, 8); this.toolStripSeparator3.Name = "toolStripSeparator3"; this.toolStripSeparator3.Size = new System.Drawing.Size(28, 6); // + // toolStripButtonModEdit + // + this.toolStripButtonModEdit.AutoSize = false; + this.toolStripButtonModEdit.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonModEdit.Image = global::Fo76ini.Properties.Resources.pencil; + this.toolStripButtonModEdit.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this.toolStripButtonModEdit.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonModEdit.Name = "toolStripButtonModEdit"; + this.toolStripButtonModEdit.Size = new System.Drawing.Size(30, 30); + this.toolStripButtonModEdit.Text = "Edit mod details"; + this.toolStripButtonModEdit.Click += new System.EventHandler(this.toolStripButtonModEdit_Click); + // + // toolStripButtonUnfreeze + // + this.toolStripButtonUnfreeze.AutoSize = false; + this.toolStripButtonUnfreeze.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonUnfreeze.Image = global::Fo76ini.Properties.Resources.defrost; + this.toolStripButtonUnfreeze.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this.toolStripButtonUnfreeze.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonUnfreeze.Name = "toolStripButtonUnfreeze"; + this.toolStripButtonUnfreeze.Size = new System.Drawing.Size(30, 30); + this.toolStripButtonUnfreeze.Text = "Unfreeze"; + this.toolStripButtonUnfreeze.Click += new System.EventHandler(this.toolStripButtonUnfreeze_Click); + // + // toolStripButtonModOpenFolder + // + this.toolStripButtonModOpenFolder.AutoSize = false; + this.toolStripButtonModOpenFolder.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonModOpenFolder.Image = global::Fo76ini.Properties.Resources.folder_open; + this.toolStripButtonModOpenFolder.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this.toolStripButtonModOpenFolder.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonModOpenFolder.Name = "toolStripButtonModOpenFolder"; + this.toolStripButtonModOpenFolder.Size = new System.Drawing.Size(30, 30); + this.toolStripButtonModOpenFolder.Text = "Open mod folder"; + this.toolStripButtonModOpenFolder.Click += new System.EventHandler(this.toolStripButtonModOpenFolder_Click); + // // toolStripSeparator5 // this.toolStripSeparator5.Margin = new System.Windows.Forms.Padding(0, 8, 0, 8); this.toolStripSeparator5.Name = "toolStripSeparator5"; this.toolStripSeparator5.Size = new System.Drawing.Size(28, 6); // + // toolStripButtonDeleteMod + // + this.toolStripButtonDeleteMod.AutoSize = false; + this.toolStripButtonDeleteMod.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.toolStripButtonDeleteMod.Image = global::Fo76ini.Properties.Resources.bin; + this.toolStripButtonDeleteMod.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; + this.toolStripButtonDeleteMod.ImageTransparentColor = System.Drawing.Color.Magenta; + this.toolStripButtonDeleteMod.Name = "toolStripButtonDeleteMod"; + this.toolStripButtonDeleteMod.Size = new System.Drawing.Size(30, 30); + this.toolStripButtonDeleteMod.Text = "Delete mod"; + this.toolStripButtonDeleteMod.Click += new System.EventHandler(this.toolStripButtonDeleteMod_Click); + // // listViewMods // this.listViewMods.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) @@ -397,6 +521,7 @@ private void InitializeComponent() // // tabPageModsSettings // + this.tabPageModsSettings.Controls.Add(this.groupBoxModsBehavior); this.tabPageModsSettings.Controls.Add(this.groupBoxLists); this.tabPageModsSettings.Location = new System.Drawing.Point(4, 22); this.tabPageModsSettings.Name = "tabPageModsSettings"; @@ -406,6 +531,42 @@ private void InitializeComponent() this.tabPageModsSettings.Text = "Settings"; this.tabPageModsSettings.UseVisualStyleBackColor = true; // + // groupBoxModsBehavior + // + this.groupBoxModsBehavior.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBoxModsBehavior.Controls.Add(this.checkBoxModsUseHardlinks); + this.groupBoxModsBehavior.Controls.Add(this.checkBoxAddArchivesAsBundled); + this.groupBoxModsBehavior.Location = new System.Drawing.Point(6, 6); + this.groupBoxModsBehavior.Name = "groupBoxModsBehavior"; + this.groupBoxModsBehavior.Size = new System.Drawing.Size(480, 69); + this.groupBoxModsBehavior.TabIndex = 60; + this.groupBoxModsBehavior.TabStop = false; + this.groupBoxModsBehavior.Text = "Behavior"; + // + // checkBoxModsUseHardlinks + // + this.checkBoxModsUseHardlinks.AutoSize = true; + this.checkBoxModsUseHardlinks.Location = new System.Drawing.Point(6, 42); + this.checkBoxModsUseHardlinks.Name = "checkBoxModsUseHardlinks"; + this.checkBoxModsUseHardlinks.Size = new System.Drawing.Size(327, 17); + this.checkBoxModsUseHardlinks.TabIndex = 1; + this.checkBoxModsUseHardlinks.Text = "[Experimental] Make hard links instead of copying files manually."; + this.toolTip.SetToolTip(this.checkBoxModsUseHardlinks, "May reduce disk space and deployment time.\r\nDoes not apply to bundled archives."); + this.checkBoxModsUseHardlinks.UseVisualStyleBackColor = true; + this.checkBoxModsUseHardlinks.CheckedChanged += new System.EventHandler(this.checkBoxModsUseHardlinks_CheckedChanged); + // + // checkBoxAddArchivesAsBundled + // + this.checkBoxAddArchivesAsBundled.AutoSize = true; + this.checkBoxAddArchivesAsBundled.Location = new System.Drawing.Point(6, 19); + this.checkBoxAddArchivesAsBundled.Name = "checkBoxAddArchivesAsBundled"; + this.checkBoxAddArchivesAsBundled.Size = new System.Drawing.Size(167, 17); + this.checkBoxAddArchivesAsBundled.TabIndex = 0; + this.checkBoxAddArchivesAsBundled.Text = "Unfreeze *.ba2 files by default"; + this.checkBoxAddArchivesAsBundled.UseVisualStyleBackColor = true; + this.checkBoxAddArchivesAsBundled.CheckedChanged += new System.EventHandler(this.checkBoxAddArchivesAsBundled_CheckedChanged); + // // groupBoxLists // this.groupBoxLists.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) @@ -418,9 +579,9 @@ private void InitializeComponent() this.groupBoxLists.Controls.Add(this.labelsResourceIndexFileList); this.groupBoxLists.Controls.Add(this.textBoxsResourceArchive2List); this.groupBoxLists.Controls.Add(this.labelsResourceArchive2List); - this.groupBoxLists.Location = new System.Drawing.Point(6, 6); + this.groupBoxLists.Location = new System.Drawing.Point(6, 81); this.groupBoxLists.Name = "groupBoxLists"; - this.groupBoxLists.Size = new System.Drawing.Size(480, 432); + this.groupBoxLists.Size = new System.Drawing.Size(480, 357); this.groupBoxLists.TabIndex = 59; this.groupBoxLists.TabStop = false; this.groupBoxLists.Text = "Lists"; @@ -428,7 +589,7 @@ private void InitializeComponent() // buttonModsResetTextboxes // this.buttonModsResetTextboxes.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonModsResetTextboxes.Location = new System.Drawing.Point(243, 403); + this.buttonModsResetTextboxes.Location = new System.Drawing.Point(243, 328); this.buttonModsResetTextboxes.Name = "buttonModsResetTextboxes"; this.buttonModsResetTextboxes.Size = new System.Drawing.Size(98, 23); this.buttonModsResetTextboxes.TabIndex = 60; @@ -439,7 +600,7 @@ private void InitializeComponent() // buttonModsApplyTextBoxes // this.buttonModsApplyTextBoxes.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonModsApplyTextBoxes.Location = new System.Drawing.Point(347, 403); + this.buttonModsApplyTextBoxes.Location = new System.Drawing.Point(347, 328); this.buttonModsApplyTextBoxes.Name = "buttonModsApplyTextBoxes"; this.buttonModsApplyTextBoxes.Size = new System.Drawing.Size(127, 23); this.buttonModsApplyTextBoxes.TabIndex = 59; @@ -455,13 +616,13 @@ private void InitializeComponent() this.textBoxsResourceIndexFileList.Location = new System.Drawing.Point(210, 37); this.textBoxsResourceIndexFileList.Multiline = true; this.textBoxsResourceIndexFileList.Name = "textBoxsResourceIndexFileList"; - this.textBoxsResourceIndexFileList.Size = new System.Drawing.Size(264, 360); + this.textBoxsResourceIndexFileList.Size = new System.Drawing.Size(264, 285); this.textBoxsResourceIndexFileList.TabIndex = 54; // // buttonModsCleanLists // this.buttonModsCleanLists.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.buttonModsCleanLists.Location = new System.Drawing.Point(6, 403); + this.buttonModsCleanLists.Location = new System.Drawing.Point(6, 328); this.buttonModsCleanLists.Name = "buttonModsCleanLists"; this.buttonModsCleanLists.Size = new System.Drawing.Size(98, 23); this.buttonModsCleanLists.TabIndex = 58; @@ -485,7 +646,7 @@ private void InitializeComponent() this.textBoxsResourceArchive2List.Location = new System.Drawing.Point(6, 37); this.textBoxsResourceArchive2List.Multiline = true; this.textBoxsResourceArchive2List.Name = "textBoxsResourceArchive2List"; - this.textBoxsResourceArchive2List.Size = new System.Drawing.Size(198, 360); + this.textBoxsResourceArchive2List.Size = new System.Drawing.Size(198, 285); this.textBoxsResourceArchive2List.TabIndex = 57; // // labelsResourceArchive2List @@ -534,126 +695,6 @@ private void InitializeComponent() this.openFileDialogBA2.Filter = "Archive2|*.ba2"; this.openFileDialogBA2.Title = "Add *.ba2 archive."; // - // toolStripButtonAddMod - // - this.toolStripButtonAddMod.AutoSize = false; - this.toolStripButtonAddMod.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButtonAddMod.Image = global::Fo76ini.Properties.Resources.plus; - this.toolStripButtonAddMod.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; - this.toolStripButtonAddMod.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButtonAddMod.Name = "toolStripButtonAddMod"; - this.toolStripButtonAddMod.Size = new System.Drawing.Size(30, 30); - this.toolStripButtonAddMod.Text = "Add mod (from archive)"; - this.toolStripButtonAddMod.Click += new System.EventHandler(this.toolStripButtonAddMod_Click); - // - // toolStripButtonAddModFrozen - // - this.toolStripButtonAddModFrozen.AutoSize = false; - this.toolStripButtonAddModFrozen.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButtonAddModFrozen.Image = global::Fo76ini.Properties.Resources.frozen_plus; - this.toolStripButtonAddModFrozen.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; - this.toolStripButtonAddModFrozen.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButtonAddModFrozen.Name = "toolStripButtonAddModFrozen"; - this.toolStripButtonAddModFrozen.Size = new System.Drawing.Size(30, 30); - this.toolStripButtonAddModFrozen.Text = "Add mod (from *.ba2 archive)"; - this.toolStripButtonAddModFrozen.Click += new System.EventHandler(this.toolStripButtonAddModFrozen_Click); - // - // toolStripButtonAddModFolder - // - this.toolStripButtonAddModFolder.AutoSize = false; - this.toolStripButtonAddModFolder.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButtonAddModFolder.Image = global::Fo76ini.Properties.Resources.folder_plus; - this.toolStripButtonAddModFolder.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; - this.toolStripButtonAddModFolder.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButtonAddModFolder.Name = "toolStripButtonAddModFolder"; - this.toolStripButtonAddModFolder.Size = new System.Drawing.Size(30, 30); - this.toolStripButtonAddModFolder.Text = "Add mod (from folder)"; - this.toolStripButtonAddModFolder.Click += new System.EventHandler(this.toolStripButtonAddModFolder_Click); - // - // toolStripButtonCheckAll - // - this.toolStripButtonCheckAll.AutoSize = false; - this.toolStripButtonCheckAll.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButtonCheckAll.Image = global::Fo76ini.Properties.Resources.checkbox_checked; - this.toolStripButtonCheckAll.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; - this.toolStripButtonCheckAll.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButtonCheckAll.Name = "toolStripButtonCheckAll"; - this.toolStripButtonCheckAll.Size = new System.Drawing.Size(30, 30); - this.toolStripButtonCheckAll.Text = "Check/uncheck all"; - this.toolStripButtonCheckAll.Click += new System.EventHandler(this.toolStripButtonCheckAll_Click); - // - // toolStripButtonMoveUp - // - this.toolStripButtonMoveUp.AutoSize = false; - this.toolStripButtonMoveUp.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButtonMoveUp.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButtonMoveUp.Image"))); - this.toolStripButtonMoveUp.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; - this.toolStripButtonMoveUp.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButtonMoveUp.Name = "toolStripButtonMoveUp"; - this.toolStripButtonMoveUp.Size = new System.Drawing.Size(30, 30); - this.toolStripButtonMoveUp.Text = "Move up"; - this.toolStripButtonMoveUp.Click += new System.EventHandler(this.toolStripButtonMoveUp_Click); - // - // toolStripButtonMoveDown - // - this.toolStripButtonMoveDown.AutoSize = false; - this.toolStripButtonMoveDown.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButtonMoveDown.Image = global::Fo76ini.Properties.Resources.arrow_down; - this.toolStripButtonMoveDown.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; - this.toolStripButtonMoveDown.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButtonMoveDown.Name = "toolStripButtonMoveDown"; - this.toolStripButtonMoveDown.Size = new System.Drawing.Size(30, 30); - this.toolStripButtonMoveDown.Text = "Move down"; - this.toolStripButtonMoveDown.Click += new System.EventHandler(this.toolStripButtonMoveDown_Click); - // - // toolStripButtonModEdit - // - this.toolStripButtonModEdit.AutoSize = false; - this.toolStripButtonModEdit.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButtonModEdit.Image = global::Fo76ini.Properties.Resources.pencil; - this.toolStripButtonModEdit.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; - this.toolStripButtonModEdit.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButtonModEdit.Name = "toolStripButtonModEdit"; - this.toolStripButtonModEdit.Size = new System.Drawing.Size(30, 30); - this.toolStripButtonModEdit.Text = "Edit mod details"; - this.toolStripButtonModEdit.Click += new System.EventHandler(this.toolStripButtonModEdit_Click); - // - // toolStripButtonModOpenFolder - // - this.toolStripButtonModOpenFolder.AutoSize = false; - this.toolStripButtonModOpenFolder.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButtonModOpenFolder.Image = global::Fo76ini.Properties.Resources.folder_open; - this.toolStripButtonModOpenFolder.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; - this.toolStripButtonModOpenFolder.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButtonModOpenFolder.Name = "toolStripButtonModOpenFolder"; - this.toolStripButtonModOpenFolder.Size = new System.Drawing.Size(30, 30); - this.toolStripButtonModOpenFolder.Text = "Open mod folder"; - this.toolStripButtonModOpenFolder.Click += new System.EventHandler(this.toolStripButtonModOpenFolder_Click); - // - // toolStripButtonDeleteMod - // - this.toolStripButtonDeleteMod.AutoSize = false; - this.toolStripButtonDeleteMod.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButtonDeleteMod.Image = global::Fo76ini.Properties.Resources.bin; - this.toolStripButtonDeleteMod.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; - this.toolStripButtonDeleteMod.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButtonDeleteMod.Name = "toolStripButtonDeleteMod"; - this.toolStripButtonDeleteMod.Size = new System.Drawing.Size(30, 30); - this.toolStripButtonDeleteMod.Text = "Delete mod"; - this.toolStripButtonDeleteMod.Click += new System.EventHandler(this.toolStripButtonDeleteMod_Click); - // - // toolStripButtonUnfreeze - // - this.toolStripButtonUnfreeze.AutoSize = false; - this.toolStripButtonUnfreeze.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this.toolStripButtonUnfreeze.Image = global::Fo76ini.Properties.Resources.defrost; - this.toolStripButtonUnfreeze.ImageScaling = System.Windows.Forms.ToolStripItemImageScaling.None; - this.toolStripButtonUnfreeze.ImageTransparentColor = System.Drawing.Color.Magenta; - this.toolStripButtonUnfreeze.Name = "toolStripButtonUnfreeze"; - this.toolStripButtonUnfreeze.Size = new System.Drawing.Size(30, 30); - this.toolStripButtonUnfreeze.Text = "Unfreeze"; - this.toolStripButtonUnfreeze.Click += new System.EventHandler(this.toolStripButtonUnfreeze_Click); - // // FormMods // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -678,6 +719,8 @@ private void InitializeComponent() this.toolStrip1.ResumeLayout(false); this.toolStrip1.PerformLayout(); this.tabPageModsSettings.ResumeLayout(false); + this.groupBoxModsBehavior.ResumeLayout(false); + this.groupBoxModsBehavior.PerformLayout(); this.groupBoxLists.ResumeLayout(false); this.groupBoxLists.PerformLayout(); this.panel1.ResumeLayout(false); @@ -749,5 +792,8 @@ private void InitializeComponent() private System.Windows.Forms.Button buttonModsResetTextboxes; private System.Windows.Forms.Button buttonModsApplyTextBoxes; private System.Windows.Forms.ToolStripButton toolStripButtonUnfreeze; + private System.Windows.Forms.GroupBox groupBoxModsBehavior; + private System.Windows.Forms.CheckBox checkBoxAddArchivesAsBundled; + private System.Windows.Forms.CheckBox checkBoxModsUseHardlinks; } } \ No newline at end of file diff --git a/Fo76ini/FormMods.cs b/Fo76ini/FormMods.cs index 2cae481..8636386 100644 --- a/Fo76ini/FormMods.cs +++ b/Fo76ini/FormMods.cs @@ -50,6 +50,15 @@ public FormMods() this.listViewMods.MouseUp += listViewMods_MouseUp; } + public void OpenUI() + { + Utils.SetFormPosition(this, Form1.Instance.Location.X + Form1.Instance.Width, Form1.Instance.Location.Y); + this.WindowState = FormWindowState.Normal; + this.UpdateUI(); + this.Show(); + this.Focus(); + } + public void UpdateUI() { UpdateModList(); @@ -256,18 +265,22 @@ private void UpdateSettings() if (!IniFiles.Instance.IsLoaded()) return; this.checkBoxDisableMods.Checked = ManagedMods.Instance.nuclearWinterMode; + this.checkBoxAddArchivesAsBundled.Checked = IniFiles.Instance.GetBool(IniFile.Config, "Mods", "bUnpackBA2ByDefault", false); + this.checkBoxModsUseHardlinks.Checked = IniFiles.Instance.GetBool(IniFile.Config, "Mods", "bUseHardlinks", false); //this.textBoxGamePath.Text = ManagedMods.Instance.GamePath; this.textBoxsResourceArchive2List.Text = String.Join(Environment.NewLine, IniFiles.Instance.GetString(IniFile.F76Custom, "Archive", "sResourceArchive2List", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); this.textBoxsResourceIndexFileList.Text = String.Join(Environment.NewLine, IniFiles.Instance.GetString(IniFile.F76Custom, "Archive", "sResourceIndexFileList", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); } - private void UpdateLabel() + private void UpdateLabel(bool success = true) { if (ManagedMods.Instance.isDeploymentNecessary()) this.DisplayDeploymentNecessary(); - else + else if (success) this.DisplayAllDone(); + else + this.DisplayFailState(); } private void UpdateSelectedIndices() @@ -829,60 +842,6 @@ private void repairddsFilesToolStripMenuItem_Click(object sender, EventArgs e) * Settings */ - // Pick game path - /*private void buttonPickGamePath_Click(object sender, EventArgs e) - { - if (ManagedMods.Instance.isDeploymentNecessary()) - { - MsgBox.ShowID("modsDeploymentNecessary"); - return; - } - if (this.openFileDialogGamePath.ShowDialog() == DialogResult.OK) - { - String path = Path.GetDirectoryName(this.openFileDialogGamePath.FileName); // We want the path where Fallout76.exe resides. - if (Directory.Exists(Path.Combine(path, "Data"))) - { - this.textBoxGamePath.Text = path; - ManagedMods.Instance.GamePath = path; - IniFiles.Instance.Set(IniFile.Config, "Preferences", ManagedMods.Instance.GamePathKey, path); - IniFiles.Instance.SaveConfig(); - ManagedMods.Instance.Load(); - UpdateUI(); - } - else - MsgBox.ShowID("modsGamePathInvalid"); - } - } - - // Game path textbox changed - private void textBoxGamePath_TextChanged(object sender, EventArgs e) - { - if (this.textBoxGamePath.Focused) - { - if (ManagedMods.Instance.isDeploymentNecessary()) - { - if (this.textBoxGamePath.Text != ManagedMods.Instance.GamePath) - this.textBoxGamePath.Text = ManagedMods.Instance.GamePath; - return; - } - else if (Directory.Exists(Path.Combine(this.textBoxGamePath.Text, "Data"))) - { - ManagedMods.Instance.GamePath = this.textBoxGamePath.Text; - IniFiles.Instance.Set(IniFile.Config, "Preferences", ManagedMods.Instance.GamePathKey, this.textBoxGamePath.Text); - IniFiles.Instance.SaveConfig(); - ManagedMods.Instance.Load(); - UpdateUI(); - this.textBoxGamePath.ForeColor = Color.Black; - this.textBoxGamePath.BackColor = Color.White; - } - else - { - this.textBoxGamePath.ForeColor = Color.White; - this.textBoxGamePath.BackColor = Color.Red; - } - } - }*/ - // Clean lists private void buttonModsCleanLists_Click(object sender, EventArgs e) { @@ -940,6 +899,20 @@ public void ChangeGameEdition(GameEdition gameEdition) UpdateUI(); } + // Alternative *.ba2 import method + private void checkBoxAddArchivesAsBundled_CheckedChanged(object sender, EventArgs e) + { + IniFiles.Instance.Set(IniFile.Config, "Mods", "bUnpackBA2ByDefault", this.checkBoxAddArchivesAsBundled.Checked); + IniFiles.Instance.SaveConfig(); + } + + // Hard links + private void checkBoxModsUseHardlinks_CheckedChanged(object sender, EventArgs e) + { + IniFiles.Instance.Set(IniFile.Config, "Mods", "bUseHardlinks", this.checkBoxModsUseHardlinks.Checked); + IniFiles.Instance.SaveConfig(); + } + /* * Threads @@ -953,13 +926,13 @@ private void InstallModArchive(String path) (text, percent) => { Invoke(() => Display(text)); }, - () => { + (success) => { Invoke(() => ProgressBarContinuous(100)); Invoke(() => HideLabel()); Invoke(() => EnableUI()); Invoke(() => selectedIndex = ManagedMods.Instance.Mods.Count - 1); Invoke(() => UpdateModList()); - Invoke(() => UpdateLabel()); + Invoke(() => UpdateLabel(success)); } ); } @@ -972,13 +945,13 @@ private void InstallModArchiveFrozen(String path) (text, percent) => { Invoke(() => Display(text)); }, - () => { + (success) => { Invoke(() => ProgressBarContinuous(100)); Invoke(() => HideLabel()); Invoke(() => EnableUI()); Invoke(() => selectedIndex = ManagedMods.Instance.Mods.Count - 1); Invoke(() => UpdateModList()); - Invoke(() => UpdateLabel()); + Invoke(() => UpdateLabel(success)); } ); } @@ -992,13 +965,13 @@ private void InstallModFolder(String path) Invoke(() => Display(text)); Invoke(() => { if (percent >= 0) { ProgressBarContinuous(percent); } else { ProgressBarMarquee(); } }); }, - () => { + (success) => { Invoke(() => ProgressBarContinuous(100)); Invoke(() => HideLabel()); Invoke(() => EnableUI()); Invoke(() => selectedIndex = ManagedMods.Instance.Mods.Count - 1); Invoke(() => UpdateModList()); - Invoke(() => UpdateLabel()); + Invoke(() => UpdateLabel(success)); } ); } @@ -1007,6 +980,7 @@ private void InstallBulk(String[] files) { foreach (string filePath in files) { + bool unpackBA2ByDefault = IniFiles.Instance.GetBool(IniFile.Config, "Mods", "bUnpackBA2ByDefault", false); String fullFilePath = Path.GetFullPath(filePath); if (fullFilePath.Length > 259 && Directory.Exists(@"\\?\" + fullFilePath)) fullFilePath = @"\\?\" + fullFilePath; @@ -1017,7 +991,12 @@ private void InstallBulk(String[] files) else if ((new String[] { ".zip", ".rar", ".7z", ".tar", ".tar.gz", ".gz" }).Contains(Path.GetExtension(fullFilePath))) InstallModArchive(fullFilePath); else if (Path.GetExtension(fullFilePath).ToLower() == ".ba2") - InstallModArchiveFrozen(fullFilePath); + { + if (unpackBA2ByDefault) + InstallModArchive(fullFilePath); + else + InstallModArchiveFrozen(fullFilePath); + } else MsgBox.Get("modsArchiveTypeNotSupported").FormatText(Path.GetExtension(fullFilePath)).Show(MessageBoxIcon.Error); } @@ -1080,17 +1059,26 @@ public void Deploy() Invoke(() => Display(text)); Invoke(() => { if (percent >= 0) { ProgressBarContinuous(percent); } else { ProgressBarMarquee(); } }); }, - () => { + (success) => { Invoke(() => { UpdateUI(); ProgressBarContinuous(100); - DisplayAllDone(); EnableUI(); - if (ManagedMods.Instance.nuclearWinterMode) - MsgBox.Get("modsDisabledDone").Popup(MessageBoxIcon.Information); + if (success) + { + DisplayAllDone(); + + if (ManagedMods.Instance.nuclearWinterMode) + MsgBox.Get("modsDisabledDone").Popup(MessageBoxIcon.Information); + else + MsgBox.Get("modsDeployedDone").Popup(MessageBoxIcon.Information); + } else - MsgBox.Get("modsDeployedDone").Popup(MessageBoxIcon.Information); + { + DisplayFailState(); + MsgBox.Get("modsDeploymentFailed").Popup(MessageBoxIcon.Information); + } }); } ); @@ -1182,5 +1170,12 @@ private void DisplayAllDone() this.labelModsDeploy.ForeColor = Color.DarkGreen; this.labelModsDeploy.Text = Translation.localizedStrings["modsAllDone"]; } + + private void DisplayFailState() + { + this.labelModsDeploy.Visible = true; + this.labelModsDeploy.ForeColor = Color.Red; + this.labelModsDeploy.Text = Translation.localizedStrings["modsFailed"]; + } } } diff --git a/Fo76ini/FormMods.resx b/Fo76ini/FormMods.resx index 1f5172f..c0381ac 100644 --- a/Fo76ini/FormMods.resx +++ b/Fo76ini/FormMods.resx @@ -123,6 +123,12 @@ 222, 17 + + 132, 17 + + + 222, 17 + diff --git a/Fo76ini/IniFiles.cs b/Fo76ini/IniFiles.cs index 606b067..a6a37eb 100644 --- a/Fo76ini/IniFiles.cs +++ b/Fo76ini/IniFiles.cs @@ -6,6 +6,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Security.AccessControl; +using System.Security.Principal; using System.Text; using System.Windows.Forms; @@ -368,6 +370,8 @@ public void SaveIni(String path, IniData data, bool readOnly = false) if (data == null) return; + SetNTFSWritePermission(true); + if (File.Exists(path)) SetFileReadOnlyAttribute(path, false); @@ -376,6 +380,9 @@ public void SaveIni(String path, IniData data, bool readOnly = false) if (readOnly) SetFileReadOnlyAttribute(path, readOnly); + + if (this.GetBool(IniFile.Config, "Preferences", "bDenyNTFSWritePermission", false)) + SetNTFSWritePermission(false); } @@ -387,6 +394,8 @@ public void SaveIni(String path, IniData data, bool readOnly = false) protected void SetFileReadOnlyAttribute(String path, bool readOnly) { + SetNTFSWritePermission(true); + // https://stackoverflow.com/questions/8081242/c-sharp-make-file-read-write-from-readonly if (File.Exists(path)) { @@ -419,6 +428,46 @@ public bool AreINIsReadOnly() return false; } + public void SetNTFSWritePermission(bool writePermission) + { + // https://stackoverflow.com/questions/7451861/setting-ntfs-permissions-in-c-net + // https://stackoverflow.com/questions/11478917/programmatically-adding-permissions-to-a-folder/11479031 + + // 'Allow' AND 'Deny' are ticked, wtf? + // Explanation: https://answers.microsoft.com/en-us/windows/forum/all/permission-entry-neither-allow-nor-deny-is-checked/5d210777-b466-49e6-855a-6dc1e85563df + + DirectoryInfo dInfo = new DirectoryInfo(this.iniParentPath); + DirectorySecurity dSecurity = dInfo.GetAccessControl(); + + FileSystemRights rights = FileSystemRights.Write; + + // SID: https://support.microsoft.com/en-in/help/243330/well-known-security-identifiers-in-windows-operating-systems + // String account = System.Security.Principal.WindowsIdentity.GetCurrent().Name; + // SecurityIdentifier sidAll = new SecurityIdentifier("S-1-1-0"); + // SecurityIdentifier sidAdmins = new SecurityIdentifier("S-1-5-32-544"); + SecurityIdentifier sidUsers = new SecurityIdentifier("S-1-5-32-545"); + + AccessControlType access = writePermission ? AccessControlType.Allow : AccessControlType.Deny; + + if (writePermission) + { + dSecurity.RemoveAccessRule(new FileSystemAccessRule(sidUsers, rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Deny)); + dSecurity.AddAccessRule(new FileSystemAccessRule(sidUsers, rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); + + //dSecurity.RemoveAccessRule(new FileSystemAccessRule(sidAdmins, rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Deny)); + //dSecurity.AddAccessRule(new FileSystemAccessRule(sidAdmins, rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); + } + else + { + dSecurity.AddAccessRule(new FileSystemAccessRule(sidUsers, rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Deny)); + dSecurity.RemoveAccessRule(new FileSystemAccessRule(sidUsers, rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); + + //dSecurity.AddAccessRule(new FileSystemAccessRule(sidAdmins, rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Deny)); + //dSecurity.RemoveAccessRule(new FileSystemAccessRule(sidAdmins, rights, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); + } + dInfo.SetAccessControl(dSecurity); + } + /* diff --git a/Fo76ini/Mods.cs b/Fo76ini/Mods.cs index ed87851..0551830 100644 --- a/Fo76ini/Mods.cs +++ b/Fo76ini/Mods.cs @@ -146,55 +146,97 @@ public void OverwriteFrozen(bool isFrozen) this.frozen = isFrozen; } - public void Freeze (Action updateProgress = null, Action done = null) + public void Freeze (Action updateProgress = null, Action done = null) { - if (updateProgress != null) - updateProgress($"Freezing {this.Title}", -1); + try + { + // Check if mod is not frozen: + if (this.isFrozen()) + return; - this.frozen = true; - this.freeze = true; + if (updateProgress != null) + updateProgress($"Freezing {this.Title}", -1); - // Create archive: - String tempPath = Path.Combine(ManagedMods.Instance.GamePath, "Mods", "frozen.ba2"); - Archive2.Create(tempPath, GetManagedPath(), Compression, ManagedMods.Instance.DetectArchive2Format(this)); + // Create archive: + String tempPath = Path.Combine(ManagedMods.Instance.GamePath, "Mods", "frozen.ba2"); + Archive2.Create(tempPath, GetManagedPath(), Compression, ManagedMods.Instance.DetectArchive2Format(this)); - // Remove contents of managed folder: - if (Directory.Exists(GetManagedPath())) - Directory.Delete(GetManagedPath(), true); - Directory.CreateDirectory(GetManagedPath()); + // Failed? + if (!File.Exists(tempPath)) + { + ManagedMods.Instance.logFile.WriteLine("Error while freezing mod: Couldn't create *.ba2 file. Please check archive2.log.txt.\n"); + if (done != null) + done(false); + return; + } - // Move frozen.ba2 into folder: - File.Move(tempPath, GetFrozenArchivePath()); + this.frozen = true; + this.freeze = true; - if (done != null) - done(); + // Remove contents of managed folder: + if (Directory.Exists(GetManagedPath())) + Directory.Delete(GetManagedPath(), true); + Directory.CreateDirectory(GetManagedPath()); + + // Move frozen.ba2 into folder: + File.Move(tempPath, GetFrozenArchivePath()); + + if (done != null) + done(true); + + } + catch (Exception ex) + { + ManagedMods.Instance.logFile.WriteLine($"Unhandled exception occured while freezing mod '{this.Title}': {ex.Message}\n{ex.StackTrace}\n"); + if (done != null) + done(false); + } } - public void Unfreeze(Action updateProgress = null, Action done = null) + public void Unfreeze(Action updateProgress = null, Action done = null) { - if (updateProgress != null) - updateProgress($"Unfreezing {this.Title}", -1); + try + { + // Check if mod is frozen: + if (!this.isFrozen()) + { + ManagedMods.Instance.logFile.WriteLine($"Cannot unfreeze a mod ('{this.Title}') which isn't frozen.\n"); + if (done != null) + done(false); + return; + } + + if (updateProgress != null) + updateProgress($"Unfreezing {this.Title}", -1); - this.frozen = false; - this.freeze = false; + this.frozen = false; + this.freeze = false; - // Move frozen.ba2 out of folder: - String tempPath = Path.Combine(ManagedMods.Instance.GamePath, "Mods", "frozen.ba2"); - File.Move(GetFrozenArchivePath(), tempPath); + // Move frozen.ba2 out of folder: + String tempPath = Path.Combine(ManagedMods.Instance.GamePath, "Mods", "frozen.ba2"); + File.Move(GetFrozenArchivePath(), tempPath); - // Remove contents of managed folder: - if (Directory.Exists(GetManagedPath())) - Directory.Delete(GetManagedPath(), true); - Directory.CreateDirectory(GetManagedPath()); + // Remove contents of managed folder: + if (Directory.Exists(GetManagedPath())) + Directory.Delete(GetManagedPath(), true); + Directory.CreateDirectory(GetManagedPath()); - // Extract frozen archive: - Archive2.Extract(tempPath, GetManagedPath()); + // Extract frozen archive: + Archive2.Extract(tempPath, GetManagedPath()); - // Remove frozen archive: - File.Delete(tempPath); + // Remove frozen archive: + File.Delete(tempPath); - if (done != null) - done(); + if (done != null) + done(true); + } + catch (Exception ex) + { + ManagedMods.Instance.logFile.WriteLine($"Unhandled exception occured while unfreezing mod '{this.Title}': {ex.Message}\n{ex.StackTrace}\n"); + if (done != null) + done(false); + return; + } } public String GetFrozenArchivePath() @@ -809,13 +851,14 @@ private bool ExtractModArchive(String archivePath, String managedFolderPath, Act } } - public void InstallModArchiveFrozen(String filePath, Action updateProgress = null, Action done = null) + public void InstallModArchiveFrozen(String filePath, Action updateProgress = null, Action done = null) { // Some conditions have to be met: if (this.gamePath == null) { + this.logFile.WriteLine("Couldn't import *.ba2 file: No game path has been set."); if (done != null) - done(); + done(false); return; } @@ -833,46 +876,57 @@ public void InstallModArchiveFrozen(String filePath, Action updateP } else { + this.logFile.WriteLine($"Error while importing *.ba2 file: Couldn't locate file: {filePath}"); if (done != null) - done(); + done(false); throw new FileNotFoundException(filePath); } } - // Get paths: - filePath = Path.GetFullPath(filePath); - String fileName = Path.GetFileNameWithoutExtension(filePath); - String fileExtension = Path.GetExtension(filePath); - String managedFolderPath = Utils.GetUniquePath(Path.Combine(this.GamePath, "Mods", fileName)); - String managedFolder = Path.GetFileName(managedFolderPath); + try + { + // Get paths: + filePath = Path.GetFullPath(filePath); + String fileName = Path.GetFileNameWithoutExtension(filePath); + String fileExtension = Path.GetExtension(filePath); + String managedFolderPath = Utils.GetUniquePath(Path.Combine(this.GamePath, "Mods", fileName)); + String managedFolder = Path.GetFileName(managedFolderPath); + + // Create a new mod: + Mod mod = new Mod(); + mod.Title = fileName; + mod.ManagedFolder = managedFolder; + mod.RootFolder = "Data"; + mod.ArchiveName = fileName; + mod.Type = Mod.FileType.SeparateBA2; + // TODO: Detect archive format: + // mod.Compression = Archive2.Compression.?? + // mod.Format = Mod.ArchiveFormat.?? + mod.freeze = true; + mod.OverwriteFrozen(true); + mod.isEnabled = false; + + // Copy the archive: + if (updateProgress != null) + updateProgress($"Copying {Path.GetFileName(filePath)}", -1); - // Create a new mod: - Mod mod = new Mod(); - mod.Title = fileName; - mod.ManagedFolder = managedFolder; - mod.RootFolder = "Data"; - mod.ArchiveName = fileName; - mod.Type = Mod.FileType.SeparateBA2; - // TODO: Detect archive format: - // mod.Compression = Archive2.Compression.?? - // mod.Format = Mod.ArchiveFormat.?? - mod.freeze = true; - mod.OverwriteFrozen(true); - mod.isEnabled = false; - - // Copy the archive: - if (updateProgress != null) - updateProgress($"Copying {Path.GetFileName(filePath)}", -1); - - if (!Directory.Exists(managedFolderPath)) - Directory.CreateDirectory(managedFolderPath); - - File.Copy(filePath, Path.Combine(managedFolderPath, "frozen.ba2")); - this.AddInstalledMod(mod); - this.Save(); + if (!Directory.Exists(managedFolderPath)) + Directory.CreateDirectory(managedFolderPath); - if (done != null) - done(); + File.Copy(filePath, Path.Combine(managedFolderPath, "frozen.ba2")); + this.AddInstalledMod(mod); + this.Save(); + + if (done != null) + done(true); + } + catch (Exception ex) + { + this.logFile.WriteLine($"Unhandled exception occured while importing a *.ba2 file: {ex.Message}\n{ex.StackTrace}\n"); + if (done != null) + done(false); + return; + } } /// @@ -882,13 +936,14 @@ public void InstallModArchiveFrozen(String filePath, Action updateP /// Path to archive /// Callback: Progress has been made. /// Callback: It's done. - public void InstallModArchive(String filePath, Action updateProgress = null, Action done = null) + public void InstallModArchive(String filePath, Action updateProgress = null, Action done = null) { // Some conditions have to be met: if (this.gamePath == null) { + this.logFile.WriteLine("Couldn't import *.ba2 file: No game path has been set."); if (done != null) - done(); + done(false); return; } @@ -906,8 +961,9 @@ public void InstallModArchive(String filePath, Action updateProgres } else { + this.logFile.WriteLine($"Error while importing *.ba2 file: Couldn't locate file: {filePath}"); if (done != null) - done(); + done(false); throw new FileNotFoundException(filePath); } } @@ -916,44 +972,55 @@ public void InstallModArchive(String filePath, Action updateProgres if (!Archive2.ValidatePath()) { MsgBox.ShowID("modsArchive2Missing", MessageBoxIcon.Error); + this.logFile.WriteLine("Archive2 is missing."); if (done != null) - done(); + done(false); return; } - // Get paths: - filePath = Path.GetFullPath(filePath); - String fileName = Path.GetFileNameWithoutExtension(filePath); - String fileExtension = Path.GetExtension(filePath); - String managedFolderPath = Utils.GetUniquePath(Path.Combine(this.GamePath, "Mods", fileName)); - String managedFolder = Path.GetFileName(managedFolderPath); - /*if (Directory.Exists(managedFolderPath)) + try { - managedFolder += DateTime.Now.ToString("(yyyy-MM-dd_HH-mm-ss)"); - managedFolderPath = Path.Combine(this.GamePath, "Mods", managedFolder); - }*/ + // Get paths: + filePath = Path.GetFullPath(filePath); + String fileName = Path.GetFileNameWithoutExtension(filePath); + String fileExtension = Path.GetExtension(filePath); + String managedFolderPath = Utils.GetUniquePath(Path.Combine(this.GamePath, "Mods", fileName)); + String managedFolder = Path.GetFileName(managedFolderPath); + /*if (Directory.Exists(managedFolderPath)) + { + managedFolder += DateTime.Now.ToString("(yyyy-MM-dd_HH-mm-ss)"); + managedFolderPath = Path.Combine(this.GamePath, "Mods", managedFolder); + }*/ - // Create a new mod: - Mod mod = new Mod(); - mod.Title = fileName; - mod.ManagedFolder = managedFolder; - mod.RootFolder = "Data"; - mod.ArchiveName = fileName; - mod.Type = Mod.FileType.BundledBA2; - mod.isEnabled = false; - - // Extract the archive: - if (updateProgress != null) - updateProgress($"Extracting {Path.GetFileName(filePath)}", -1); - if (ExtractModArchive(filePath, managedFolderPath, updateProgress)) + // Create a new mod: + Mod mod = new Mod(); + mod.Title = fileName; + mod.ManagedFolder = managedFolder; + mod.RootFolder = "Data"; + mod.ArchiveName = fileName; + mod.Type = Mod.FileType.BundledBA2; + mod.isEnabled = false; + + // Extract the archive: + if (updateProgress != null) + updateProgress($"Extracting {Path.GetFileName(filePath)}", -1); + if (ExtractModArchive(filePath, managedFolderPath, updateProgress)) + { + ManipulateModFolder(mod, managedFolderPath, updateProgress); + this.AddInstalledMod(mod); + this.Save(); + } + + if (done != null) + done(true); + } + catch (Exception ex) { - ManipulateModFolder(mod, managedFolderPath, updateProgress); - this.AddInstalledMod(mod); - this.Save(); + this.logFile.WriteLine($"Unhandled exception occured while importing a *.ba2 file: {ex.Message}\n{ex.StackTrace}\n"); + if (done != null) + done(false); + return; } - - if (done != null) - done(); } /// @@ -963,23 +1030,20 @@ public void InstallModArchive(String filePath, Action updateProgres /// Path to directory /// Callback: "Copying file xyz" and percentage. /// Callback: It's done. - public void InstallModFolder(String folderPath, Action updateProgress = null, Action done = null) + public void InstallModFolder(String folderPath, Action updateProgress = null, Action done = null) { // Some conditions have to be met: if (this.gamePath == null) { + this.logFile.WriteLine("Couldn't import *.ba2 file: No game path has been set."); if (done != null) - done(); + done(false); return; } if (!Directory.Exists(Path.Combine(this.gamePath, "Mods"))) Directory.CreateDirectory(Path.Combine(this.gamePath, "Mods")); - //if (!Directory.Exists(folderPath)) - // throw new FileNotFoundException(folderPath); - - if (!Directory.Exists(folderPath)) { // Path too long? @@ -991,8 +1055,9 @@ public void InstallModFolder(String folderPath, Action updateProgre } else { + this.logFile.WriteLine($"Error while importing a folder: Couldn't locate folder: {folderPath}"); if (done != null) - done(); + done(false); throw new FileNotFoundException(folderPath); } } @@ -1001,62 +1066,69 @@ public void InstallModFolder(String folderPath, Action updateProgre if (!Archive2.ValidatePath()) { MsgBox.ShowID("modsArchive2Missing", MessageBoxIcon.Error); + this.logFile.WriteLine("Archive2 is missing."); if (done != null) - done(); + done(false); return; } - // Get paths: - folderPath = Path.GetFullPath(folderPath); - String folderName = Path.GetFileName(folderPath); - String managedFolderPath = Utils.GetUniquePath(Path.Combine(this.GamePath, "Mods", folderName)); - String managedFolder = Path.GetFileName(managedFolderPath); - /*if (Directory.Exists(managedFolderPath)) - { - managedFolder += DateTime.Now.ToString("(yyyy-MM-dd_HH-mm-ss)"); - managedFolderPath = Path.Combine(this.GamePath, "Mods", managedFolder); - }*/ - - // Create a new mod: - Mod mod = new Mod(); - mod.Title = folderName; - mod.ManagedFolder = managedFolder; - mod.RootFolder = "Data"; - mod.ArchiveName = folderName; - mod.Type = Mod.FileType.BundledBA2; - mod.isEnabled = false; - - // Copy every file found in the folder: - if (updateProgress != null) - updateProgress($"Indexing {folderName}...", -1); - IEnumerable files = Directory.EnumerateFiles(folderPath, "*.*", SearchOption.AllDirectories); - float count = (float)files.Count(); - if (count == 0) - { - if (done != null) - done(); - return; - } - int i = 0; - foreach (String file in files) + try { + // Get paths: + folderPath = Path.GetFullPath(folderPath); + String folderName = Path.GetFileName(folderPath); + String managedFolderPath = Utils.GetUniquePath(Path.Combine(this.GamePath, "Mods", folderName)); + String managedFolder = Path.GetFileName(managedFolderPath); + + // Create a new mod: + Mod mod = new Mod(); + mod.Title = folderName; + mod.ManagedFolder = managedFolder; + mod.RootFolder = "Data"; + mod.ArchiveName = folderName; + mod.Type = Mod.FileType.BundledBA2; + mod.isEnabled = false; + + // Copy every file found in the folder: if (updateProgress != null) - updateProgress($"Copying {Path.GetFileName(file)} ...", Convert.ToInt32((float)i++ / (float)count * 100)); + updateProgress($"Indexing {folderName}...", -1); + IEnumerable files = Directory.EnumerateFiles(folderPath, "*.*", SearchOption.AllDirectories); + float count = (float)files.Count(); + if (count == 0) + { + this.logFile.WriteLine($"Imported folder is empty. Abort."); + if (done != null) + done(false); + return; + } + int i = 0; + foreach (String file in files) + { + if (updateProgress != null) + updateProgress($"Copying {Path.GetFileName(file)} ...", Convert.ToInt32((float)i++ / (float)count * 100)); - // Make a relative path, create directories and copy file: - String destinationPath = Path.Combine(managedFolderPath, Utils.MakeRelativePath(folderPath, file)); - Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)); - File.Copy(file, destinationPath); - } + // Make a relative path, create directories and copy file: + String destinationPath = Path.Combine(managedFolderPath, Utils.MakeRelativePath(folderPath, file)); + Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)); + File.Copy(file, destinationPath); + } - ManipulateModFolder(mod, managedFolderPath, updateProgress); + ManipulateModFolder(mod, managedFolderPath, updateProgress); - // Add to mods: - AddInstalledMod(mod); - this.Save(); + // Add to mods: + AddInstalledMod(mod); + this.Save(); - if (done != null) - done(); + if (done != null) + done(true); + } + catch (Exception ex) + { + this.logFile.WriteLine($"Unhandled exception occured while importing a folder: {ex.Message}\n{ex.StackTrace}\n"); + if (done != null) + done(false); + return; + } } private void AddInstalledMod(Mod mod) @@ -1235,10 +1307,19 @@ public void ImportInstalledMods() if (mod.Type == Mod.FileType.SeparateBA2) installedMods.Remove(mod.ArchiveName); + // Ignore any game files ("SeventySix - *.ba2"): + foreach (String archiveName in sResourceIndexFileList) + if (archiveName.StartsWith("SeventySix")) + installedMods.Remove(archiveName); + foreach (String archiveName in sResourceArchive2List) + if (archiveName.StartsWith("SeventySix")) + installedMods.Remove(archiveName); + // Import every archive: foreach (String archiveName in installedMods) { String path = Path.Combine(this.gamePath, "Data", archiveName); + Console.WriteLine(path); if (File.Exists(path)) { // Import archive: @@ -1368,476 +1449,508 @@ public DeployArchive(String name, String tempFolderPath) } } - public void Deploy(Action updateProgress = null, Action done = null) + public void Deploy(Action updateProgress = null, Action done = null) { - if (!Archive2.ValidatePath()) + try { - MsgBox.ShowID("modsArchive2Missing", MessageBoxIcon.Error); - if (done != null) - done(); - return; - } + this.logFile.WriteTimeStamp(); + this.logFile.WriteLine($"Version {Form1.VERSION}, deploying..."); - if (this.gamePath == null) - { - if (done != null) - done(); - return; - } + if (!Archive2.ValidatePath()) + { + MsgBox.ShowID("modsArchive2Missing", MessageBoxIcon.Error); + this.logFile.WriteLine("Failed: Couldn't find Archive2"); + if (done != null) + done(false); + return; + } - if (!Directory.Exists(Path.Combine(this.gamePath, "Data"))) - { - MsgBox.ShowID("modsGamePathInvalid", MessageBoxIcon.Error); - if (done != null) - done(); - return; - } + if (this.gamePath == null) + { + if (done != null) + done(false); + return; + } - // Check if we don't have multiple mods with the same archive name: - List customArchiveNames = new List(); - foreach (Mod mod in this.changedMods) - { - if (mod.Type == Mod.FileType.SeparateBA2 && mod.isEnabled) + if (!Directory.Exists(Path.Combine(this.gamePath, "Data"))) { - if (customArchiveNames.Contains(mod.ArchiveName.ToLower())) - { - MsgBox.Get("modsSameArchiveName").FormatText(mod.ArchiveName, mod.Title).Show(MessageBoxIcon.Error); - if (done != null) - done(); - return; - } - else + MsgBox.ShowID("modsGamePathInvalid", MessageBoxIcon.Error); + this.logFile.WriteLine("Failed: Game path invalid"); + if (done != null) + done(false); + return; + } + + // Check if we don't have multiple mods with the same archive name: + List customArchiveNames = new List(); + foreach (Mod mod in this.changedMods) + { + if (mod.Type == Mod.FileType.SeparateBA2 && mod.isEnabled) { - customArchiveNames.Add(mod.ArchiveName.ToLower()); + if (customArchiveNames.Contains(mod.ArchiveName.ToLower())) + { + MsgBox.Get("modsSameArchiveName").FormatText(mod.ArchiveName, mod.Title).Show(MessageBoxIcon.Error); + this.logFile.WriteLine($"Conflict: Multiple mods with the same archive name. (1st conflict: '{mod.ArchiveName}', '{mod.Title}')"); + if (done != null) + done(false); + return; + } + else + { + customArchiveNames.Add(mod.ArchiveName.ToLower()); + } } } - } - this.logFile.WriteTimeStamp(); - this.logFile.WriteLine("Deploying."); - - if (this.nuclearWinterMode) { - this.logFile.WriteLine("NOTE: Nuclear Winter mode enabled. (Disable Mods checkbox checked)"); - IniFiles.Instance.Set(IniFile.Config, "Mods", "bDisableMods", this.nuclearWinterMode); - } - else - { - IniFiles.Instance.Set(IniFile.Config, "Mods", "bDisableMods", false); - } + if (this.nuclearWinterMode) + { + this.logFile.WriteLine("NOTE: Nuclear Winter mode enabled. (Disable Mods checkbox checked)"); + IniFiles.Instance.Set(IniFile.Config, "Mods", "bDisableMods", this.nuclearWinterMode); + } + else + { + IniFiles.Instance.Set(IniFile.Config, "Mods", "bDisableMods", false); + } - String tempPath = Path.Combine(this.gamePath, "temp"); - if (Directory.Exists(tempPath)) - Directory.Delete(tempPath, true); - Directory.CreateDirectory(tempPath); - - DeployArchive generalArchive = new DeployArchive("general", tempPath); - DeployArchive texturesArchive = new DeployArchive("textures", tempPath); - texturesArchive.format = Archive2.Format.DDS; - DeployArchive soundsArchive = new DeployArchive("sounds", tempPath); - soundsArchive.compression = Archive2.Compression.None; - var archives = new List() { generalArchive, texturesArchive, soundsArchive }; - /*String tempBA2Path = Path.Combine(tempPath, "ba2"); - String tempBA2TexturesPath = Path.Combine(tempPath, "ba2_tex"); - Directory.CreateDirectory(tempBA2Path); - Directory.CreateDirectory(tempBA2TexturesPath);*/ - - // sResourceIndexFileList, sResourceArchive2List, sResourceDataDirsFinal - List sResourceIndexFileList = new List(IniFiles.Instance.GetString(IniFile.F76Custom, "Archive", "sResourceIndexFileList", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); - sResourceIndexFileList.AddRange(IniFiles.Instance.GetString(IniFile.Config, "Archive", "sResourceIndexFileList", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); - List sResourceDataDirsFinal = new List(IniFiles.Instance.GetString(IniFile.F76Custom, "Archive", "sResourceDataDirsFinal", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); + bool useHardlinks = IniFiles.Instance.GetBool(IniFile.Config, "Mods", "bUseHardlinks", false); + if (useHardlinks) + this.logFile.WriteLine($"NOTE: Experimental feature 'Hard links' enabled."); + + String tempPath = Path.Combine(this.gamePath, "temp"); + if (Directory.Exists(tempPath)) + Directory.Delete(tempPath, true); + Directory.CreateDirectory(tempPath); + + DeployArchive generalArchive = new DeployArchive("general", tempPath); + DeployArchive texturesArchive = new DeployArchive("textures", tempPath); + texturesArchive.format = Archive2.Format.DDS; + DeployArchive soundsArchive = new DeployArchive("sounds", tempPath); + soundsArchive.compression = Archive2.Compression.None; + var archives = new List() { generalArchive, texturesArchive, soundsArchive }; + /*String tempBA2Path = Path.Combine(tempPath, "ba2"); + String tempBA2TexturesPath = Path.Combine(tempPath, "ba2_tex"); + Directory.CreateDirectory(tempBA2Path); + Directory.CreateDirectory(tempBA2TexturesPath);*/ + + // sResourceIndexFileList, sResourceArchive2List, sResourceDataDirsFinal + List sResourceIndexFileList = new List(IniFiles.Instance.GetString(IniFile.F76Custom, "Archive", "sResourceIndexFileList", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); + sResourceIndexFileList.AddRange(IniFiles.Instance.GetString(IniFile.Config, "Archive", "sResourceIndexFileList", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); + List sResourceDataDirsFinal = new List(IniFiles.Instance.GetString(IniFile.F76Custom, "Archive", "sResourceDataDirsFinal", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)); - /* - * Remove any leftover files from previous installations: - */ + /* + * Remove any leftover files from previous installations: + */ - // Remove all loose files: - int i = 0; - foreach (Mod mod in this.mods) - { - if (updateProgress != null) - updateProgress($"[1/4] Removing files of mod {mod.Title} ({i} of {this.mods.Count})", Convert.ToInt32((float)i / (float)this.mods.Count * 20)); + // Remove all loose files: + int i = 0; + foreach (Mod mod in this.mods) + { + if (updateProgress != null) + updateProgress($"[1/4] Removing files of mod {mod.Title} ({i} of {this.mods.Count})", Convert.ToInt32((float)i / (float)this.mods.Count * 20)); - if (!mod.isEnabled) - continue; + if (!mod.isEnabled) + continue; - if (mod.Type == Mod.FileType.Loose) - { - foreach (String relFilePath in mod.LooseFiles) + if (mod.Type == Mod.FileType.Loose) { - String installedFilePath = Path.Combine(this.gamePath, mod.RootFolder, relFilePath).Replace("\\.\\", "\\"); + foreach (String relFilePath in mod.LooseFiles) + { + String installedFilePath = Path.Combine(this.gamePath, mod.RootFolder, relFilePath).Replace("\\.\\", "\\"); - // Delete file, if existing: - if (File.Exists(installedFilePath)) - File.Delete(installedFilePath); + // Delete file, if existing: + if (File.Exists(installedFilePath)) + File.Delete(installedFilePath); - // Use backups, if there are any: - if (File.Exists(installedFilePath + ".old")) - File.Move(installedFilePath + ".old", installedFilePath); - else - { - // Remove empty folders one by one, if existing: - String parent = Path.GetDirectoryName(installedFilePath); - while (Directory.Exists(parent) && Utils.IsDirectoryEmpty(parent)) + // Use backups, if there are any: + if (File.Exists(installedFilePath + ".old")) + File.Move(installedFilePath + ".old", installedFilePath); + else { - Directory.Delete(parent); - parent = Path.GetDirectoryName(parent); + // Remove empty folders one by one, if existing: + String parent = Path.GetDirectoryName(installedFilePath); + while (Directory.Exists(parent) && Utils.IsDirectoryEmpty(parent)) + { + Directory.Delete(parent); + parent = Path.GetDirectoryName(parent); + } } } + this.logFile.WriteLine($"Loose files of mod {mod.Title} removed."); } - this.logFile.WriteLine($"Loose files of mod {mod.Title} removed."); - } - else if (mod.Type == Mod.FileType.SeparateBA2) - { - String path = Path.Combine(this.gamePath, "Data", mod.ArchiveName); - if (File.Exists(path)) - File.Delete(path); - - if (sResourceIndexFileList.Contains(mod.ArchiveName)) + else if (mod.Type == Mod.FileType.SeparateBA2) { - sResourceIndexFileList = sResourceIndexFileList.Distinct().ToList(); - sResourceIndexFileList.Remove(mod.ArchiveName); + String path = Path.Combine(this.gamePath, "Data", mod.ArchiveName); + if (File.Exists(path)) + File.Delete(path); + + if (sResourceIndexFileList.Contains(mod.ArchiveName)) + { + sResourceIndexFileList = sResourceIndexFileList.Distinct().ToList(); + sResourceIndexFileList.Remove(mod.ArchiveName); + } + this.logFile.WriteLine($"*.ba2 archive of mod {mod.Title} removed."); } - this.logFile.WriteLine($"*.ba2 archive of mod {mod.Title} removed."); - } - i++; - } + i++; + } - /* - * Copy all mods - */ - i = 0; - /*int enabledBA2GeneralMods = 0; - int enabledBA2TexturesMods = 0;*/ - int enabledLooseMods = 0; - List allModRelPaths = new List(); - int enabledModsCount = this.changedMods.Count(n => n.isEnabled); - float modPercent = 1f / (float)enabledModsCount * 0.8f; - foreach (Mod mod in this.changedMods) - { /* - * Skip if nuclear winter mode is enabled. - * Skip if mod is disabled. - * Show error if mod folder wasn't found + * Copy all mods */ - if (this.nuclearWinterMode) - break; - - if (!mod.isEnabled) - continue; + i = 0; + /*int enabledBA2GeneralMods = 0; + int enabledBA2TexturesMods = 0;*/ + int enabledLooseMods = 0; + List allModRelPaths = new List(); + int enabledModsCount = this.changedMods.Count(n => n.isEnabled); + float modPercent = 1f / (float)enabledModsCount * 0.8f; + foreach (Mod mod in this.changedMods) + { + /* + * Skip if nuclear winter mode is enabled. + * Skip if mod is disabled. + * Show error if mod folder wasn't found + */ + if (this.nuclearWinterMode) + break; - String progressModName = $"{mod.Title} ({i + 1} of {enabledModsCount})"; - int progressPercent = Convert.ToInt32((float)i / (float)enabledModsCount * 80 + 20); + if (!mod.isEnabled) + continue; - if (updateProgress != null) - updateProgress($"[2/4] Deploying mod {progressModName}", progressPercent); + String progressModName = $"{mod.Title} ({i + 1} of {enabledModsCount})"; + int progressPercent = Convert.ToInt32((float)i / (float)enabledModsCount * 80 + 20); - String managedFolderPath = Path.Combine(this.gamePath, "Mods", mod.ManagedFolder); - if (!Directory.Exists(managedFolderPath)) - { - //MessageBox.Show($"Directory \"{managedFolderPath}\" does not exist.\nPlease restart the mod manager and add the mod again.", $"Mod {mod.Title} couldn't be deployed.", MessageBoxButtons.OK, MessageBoxIcon.Error); - MsgBox.Get("modsDeployErrorModDirNotFound") - .FormatTitle(mod.Title) - .FormatText(managedFolderPath) - .Show(MessageBoxIcon.Error); - continue; - } + if (updateProgress != null) + updateProgress($"[2/4] Deploying mod {progressModName}", progressPercent); - /* - * Copy files into temporary folder for bundled archives - */ - if (mod.Type == Mod.FileType.BundledBA2) - { - // Check if root folder is data: - if (!mod.RootFolder.Contains("Data")) + String managedFolderPath = Path.Combine(this.gamePath, "Mods", mod.ManagedFolder); + if (!Directory.Exists(managedFolderPath)) { - MsgBox.Get("modsDeployErrorBA2RootIsNotData") + //MessageBox.Show($"Directory \"{managedFolderPath}\" does not exist.\nPlease restart the mod manager and add the mod again.", $"Mod {mod.Title} couldn't be deployed.", MessageBoxButtons.OK, MessageBoxIcon.Error); + MsgBox.Get("modsDeployErrorModDirNotFound") .FormatTitle(mod.Title) + .FormatText(managedFolderPath) .Show(MessageBoxIcon.Error); - //MessageBox.Show("The root folder has to be set to \".\\Data\" for mods, that are to be installed as a bundled *.ba2 archive.", $"Mod {mod.Title} couldn't be deployed.", MessageBoxButtons.OK, MessageBoxIcon.Error); continue; } - this.logFile.WriteLine($"[Bundled] Copying files of {mod.Title} to temp folder."); + /* + * Copy files into temporary folder for bundled archives + */ + if (mod.Type == Mod.FileType.BundledBA2) + { + // Check if root folder is data: + if (!mod.RootFolder.Contains("Data")) + { + MsgBox.Get("modsDeployErrorBA2RootIsNotData") + .FormatTitle(mod.Title) + .Show(MessageBoxIcon.Error); + //MessageBox.Show("The root folder has to be set to \".\\Data\" for mods, that are to be installed as a bundled *.ba2 archive.", $"Mod {mod.Title} couldn't be deployed.", MessageBoxButtons.OK, MessageBoxIcon.Error); + continue; + } - int generalFiles = 0; - int DDSFiles = 0; - int soundFiles = 0; + this.logFile.WriteLine($"[Bundled] Copying files of {mod.Title} to temp folder."); - // Copy all files to temp data path: - // String[] files = Directory.GetFiles(managedFolderPath, "*.*", SearchOption.AllDirectories); - IEnumerable files = Directory.EnumerateFiles(managedFolderPath, "*.*", SearchOption.AllDirectories); - int count = files.Count(); - int f = 0; - foreach (String filePath in files) - { - if (updateProgress != null) - updateProgress($"[2/4] Copying file {f} of {count} (\"{Path.GetFileName(filePath)}\") of mod {progressModName}", progressPercent + (int)((float)f++ / (float)count * modPercent * 100)); + int generalFiles = 0; + int DDSFiles = 0; + int soundFiles = 0; - // Make a relative path, create directories and copy file: - String relativePath = Utils.MakeRelativePath(managedFolderPath, filePath); - String destinationPath; - if (relativePath.Trim().ToLower().StartsWith("sound") || relativePath.Trim().ToLower().StartsWith("music")) + // Copy all files to temp data path: + // String[] files = Directory.GetFiles(managedFolderPath, "*.*", SearchOption.AllDirectories); + IEnumerable files = Directory.EnumerateFiles(managedFolderPath, "*.*", SearchOption.AllDirectories); + int count = files.Count(); + int f = 0; + foreach (String filePath in files) { - soundFiles++; - destinationPath = Path.Combine(soundsArchive.tempPath, relativePath); + if (updateProgress != null) + updateProgress($"[2/4] Copying file {f} of {count} (\"{Path.GetFileName(filePath)}\") of mod {progressModName}", progressPercent + (int)((float)f++ / (float)count * modPercent * 100)); + + // Make a relative path, create directories and copy file: + String relativePath = Utils.MakeRelativePath(managedFolderPath, filePath); + String destinationPath; + if (relativePath.Trim().ToLower().StartsWith("sound") || relativePath.Trim().ToLower().StartsWith("music")) + { + soundFiles++; + destinationPath = Path.Combine(soundsArchive.tempPath, relativePath); + } + else if (filePath.ToLower().EndsWith(".dds")) + { + DDSFiles++; + destinationPath = Path.Combine(texturesArchive.tempPath, relativePath); + } + else + { + generalFiles++; + destinationPath = Path.Combine(generalArchive.tempPath, relativePath); + } + Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)); + + if (useHardlinks) + Utils.CreateHardLink(filePath, destinationPath, true); + else + File.Copy(filePath, destinationPath, true); } - else if (filePath.ToLower().EndsWith(".dds")) + + // Increment counter: + if (generalFiles > 0) { - DDSFiles++; - destinationPath = Path.Combine(texturesArchive.tempPath, relativePath); + //enabledBA2GeneralMods++; + generalArchive.count++; + this.logFile.WriteLine($" General files copied: {generalFiles}"); } - else + if (DDSFiles > 0) { - generalFiles++; - destinationPath = Path.Combine(generalArchive.tempPath, relativePath); + //enabledBA2TexturesMods++; + texturesArchive.count++; + this.logFile.WriteLine($" *.dds files copied: {DDSFiles}"); + } + if (soundFiles > 0) + { + //enabledBA2TexturesMods++; + soundsArchive.count++; + this.logFile.WriteLine($" Sound files copied: {soundFiles}"); } - Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)); - File.Copy(filePath, destinationPath, true); - } - - // Increment counter: - if (generalFiles > 0) - { - //enabledBA2GeneralMods++; - generalArchive.count++; - this.logFile.WriteLine($" General files copied: {generalFiles}"); - } - if (DDSFiles > 0) - { - //enabledBA2TexturesMods++; - texturesArchive.count++; - this.logFile.WriteLine($" *.dds files copied: {DDSFiles}"); } - if (soundFiles > 0) + /* + * Install separate archive: + */ + else if (mod.Type == Mod.FileType.SeparateBA2) { - //enabledBA2TexturesMods++; - soundsArchive.count++; - this.logFile.WriteLine($" Sound files copied: {soundFiles}"); - } - } - /* - * Install separate archive: - */ - else if (mod.Type == Mod.FileType.SeparateBA2) - { - // Check if root folder is data: - if (!mod.RootFolder.Contains("Data")) - { - MsgBox.Get("modsDeployErrorBA2RootIsNotData") - .FormatTitle(mod.Title) - .Show(MessageBoxIcon.Error); - //MessageBox.Show("The root folder has to be set to \".\\Data\" for mods, that are to be installed as a bundled *.ba2 archive.", $"Mod {mod.Title} couldn't be deployed.", MessageBoxButtons.OK, MessageBoxIcon.Error); - continue; - } + // Check if root folder is data: + if (!mod.RootFolder.Contains("Data")) + { + MsgBox.Get("modsDeployErrorBA2RootIsNotData") + .FormatTitle(mod.Title) + .Show(MessageBoxIcon.Error); + //MessageBox.Show("The root folder has to be set to \".\\Data\" for mods, that are to be installed as a bundled *.ba2 archive.", $"Mod {mod.Title} couldn't be deployed.", MessageBoxButtons.OK, MessageBoxIcon.Error); + continue; + } - if (mod.freeze) - { - if (mod.isFrozen()) + if (mod.freeze) { - this.logFile.WriteLine($"[Separate] Copying frozen archive of {mod.Title}."); - this.logFile.WriteLine($" Archive name: {mod.ArchiveName}"); + if (mod.isFrozen()) + { + this.logFile.WriteLine($"[Separate] Copying frozen archive of {mod.Title}."); + this.logFile.WriteLine($" Archive name: {mod.ArchiveName}"); + } + else + { + Archive2.Format format = DetectArchive2Format(mod); + + this.logFile.WriteLine($"[Separate] Freezing archive of {mod.Title}."); + this.logFile.WriteLine($" Archive name: {mod.ArchiveName}"); + this.logFile.WriteLine($" Format: {Enum.GetName(typeof(Archive2.Format), (int)format)}"); + this.logFile.WriteLine($" Compression: {Enum.GetName(typeof(Archive2.Compression), (int)mod.Compression)}"); + + if (updateProgress != null) + updateProgress($"[2/4] Creating a *ba2 archive of mod {progressModName}", progressPercent + (int)(modPercent * 100)); + mod.Freeze(); + } + + // Copy archive: + if (updateProgress != null) + updateProgress($"[2/4] Copying frozen *ba2 archive of mod {progressModName}", progressPercent + (int)(modPercent * 100)); + + string frozenPath = mod.GetFrozenArchivePath(); + string destPath = Path.Combine(this.gamePath, "Data", mod.ArchiveName); + if (useHardlinks) + Utils.CreateHardLink(frozenPath, destPath, true); + else + File.Copy(frozenPath, destPath, true); } else { + if (mod.isFrozen()) + { + mod.Unfreeze(); + } + Archive2.Format format = DetectArchive2Format(mod); - this.logFile.WriteLine($"[Separate] Freezing archive of {mod.Title}."); + this.logFile.WriteLine($"[Separate] Creating archive of {mod.Title}."); this.logFile.WriteLine($" Archive name: {mod.ArchiveName}"); this.logFile.WriteLine($" Format: {Enum.GetName(typeof(Archive2.Format), (int)format)}"); this.logFile.WriteLine($" Compression: {Enum.GetName(typeof(Archive2.Compression), (int)mod.Compression)}"); + // Create archive: if (updateProgress != null) updateProgress($"[2/4] Creating a *ba2 archive of mod {progressModName}", progressPercent + (int)(modPercent * 100)); - mod.Freeze(); + Archive2.Create(Path.Combine(this.gamePath, "Data", mod.ArchiveName), managedFolderPath, mod.Compression, format); } - - // Copy archive: - if (updateProgress != null) - updateProgress($"[2/4] Copying frozen *ba2 archive of mod {progressModName}", progressPercent + (int)(modPercent * 100)); - File.Copy(mod.GetFrozenArchivePath(), Path.Combine(this.gamePath, "Data", mod.ArchiveName)); + sResourceIndexFileList.Add(mod.ArchiveName); } - else + /* + * Install loose files: + */ + else if (mod.Type == Mod.FileType.Loose) { - if (mod.isFrozen()) + // Loose files + List modRelPaths = new List(); + // String[] files = Directory.GetFiles(managedFolderPath, "*.*", SearchOption.AllDirectories); + IEnumerable files = Directory.GetFiles(managedFolderPath, "*.*", SearchOption.AllDirectories); + int count = files.Count(); + int f = 0; + foreach (String filePath in files) { - mod.Unfreeze(); + if (updateProgress != null) + updateProgress($"[2/4] Copying file {f} of {count} (\"{Path.GetFileName(filePath)}\") of mod {progressModName}", progressPercent + (int)((float)f++ / (float)count * modPercent * 100)); + String relPath = Utils.MakeRelativePath(managedFolderPath, filePath); + modRelPaths.Add(relPath); + String destinationPath = Path.Combine(this.gamePath, mod.RootFolder, relPath); + Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)); + if (!allModRelPaths.Contains(relPath) && File.Exists(destinationPath) && !File.Exists(destinationPath + ".old")) + File.Move(destinationPath, destinationPath + ".old"); + + if (useHardlinks) + Utils.CreateHardLink(filePath, destinationPath, true); + else + File.Copy(filePath, destinationPath, true); } + mod.LooseFiles = modRelPaths; + allModRelPaths.AddRange(modRelPaths); + enabledLooseMods++; - Archive2.Format format = DetectArchive2Format(mod); - - this.logFile.WriteLine($"[Separate] Creating archive of {mod.Title}."); - this.logFile.WriteLine($" Archive name: {mod.ArchiveName}"); - this.logFile.WriteLine($" Format: {Enum.GetName(typeof(Archive2.Format), (int)format)}"); - this.logFile.WriteLine($" Compression: {Enum.GetName(typeof(Archive2.Compression), (int)mod.Compression)}"); - - // Create archive: - if (updateProgress != null) - updateProgress($"[2/4] Creating a *ba2 archive of mod {progressModName}", progressPercent + (int)(modPercent * 100)); - Archive2.Create(Path.Combine(this.gamePath, "Data", mod.ArchiveName), managedFolderPath, mod.Compression, format); + this.logFile.WriteLine($"[Loose] Files of {mod.Title} copied."); } - sResourceIndexFileList.Add(mod.ArchiveName); + + i++; } + /* - * Install loose files: + * Create all bundled archives */ - else if (mod.Type == Mod.FileType.Loose) + sResourceIndexFileList = sResourceIndexFileList.Distinct().ToList(); + foreach (DeployArchive archive in archives) { - // Loose files - List modRelPaths = new List(); - // String[] files = Directory.GetFiles(managedFolderPath, "*.*", SearchOption.AllDirectories); - IEnumerable files = Directory.GetFiles(managedFolderPath, "*.*", SearchOption.AllDirectories); - int count = files.Count(); - int f = 0; - foreach (String filePath in files) + String bundledArchivePath = Path.Combine(this.gamePath, "Data", archive.archiveName); + if (!this.nuclearWinterMode && archive.count > 0) { if (updateProgress != null) - updateProgress($"[2/4] Copying file {f} of {count} (\"{Path.GetFileName(filePath)}\") of mod {progressModName}", progressPercent + (int)((float)f++ / (float)count * modPercent * 100)); - String relPath = Utils.MakeRelativePath(managedFolderPath, filePath); - modRelPaths.Add(relPath); - String destinationPath = Path.Combine(this.gamePath, mod.RootFolder, relPath); - Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)); - if (!allModRelPaths.Contains(relPath) && File.Exists(destinationPath) && !File.Exists(destinationPath + ".old")) - File.Move(destinationPath, destinationPath + ".old"); - File.Copy(filePath, destinationPath, true); + updateProgress($"[3/4] Creating {archive.archiveName}...", -1); + this.logFile.WriteLine($"Creating {archive.archiveName}"); + Archive2.Create(bundledArchivePath, archive.tempPath, archive.compression, archive.format); + sResourceIndexFileList.Insert(0, archive.archiveName); + } + else + { + this.logFile.WriteLine($"Removing {archive.archiveName}"); + if (File.Exists(bundledArchivePath)) + File.Delete(bundledArchivePath); + sResourceIndexFileList.Remove(archive.archiveName); } - mod.LooseFiles = modRelPaths; - allModRelPaths.AddRange(modRelPaths); - enabledLooseMods++; - - this.logFile.WriteLine($"[Loose] Files of {mod.Title} copied."); } - i++; - } + /* + * Finishing up... + */ + if (updateProgress != null) + updateProgress("[4/4] Finishing up...", -1); + this.logFile.WriteLine($"Finishing up..."); - /* - * Create all bundled archives - */ - sResourceIndexFileList = sResourceIndexFileList.Distinct().ToList(); - foreach (DeployArchive archive in archives) - { - String bundledArchivePath = Path.Combine(this.gamePath, "Data", archive.archiveName); - if (!this.nuclearWinterMode && archive.count > 0) + + // Renaming *.dll files + if (this.nuclearWinterMode) { - if (updateProgress != null) - updateProgress($"[3/4] Creating {archive.archiveName}...", -1); - this.logFile.WriteLine($"Creating {archive.archiveName}"); - Archive2.Create(bundledArchivePath, archive.tempPath, archive.compression, archive.format); - sResourceIndexFileList.Insert(0, archive.archiveName); + // String[] files = Directory.GetFiles(this.GamePath, "*.dll", SearchOption.AllDirectories); + IEnumerable files = Directory.EnumerateFiles(this.GamePath, "*.dll");/*, SearchOption.AllDirectories);*/ // Don't change the *.dll files in the /Mods/ folder!! + this.logFile.WriteLine($" Renaming not \'whitelisted\' \'*.dll\' files to \'*.dll.nwmode\'."); + foreach (String filePath in files) + { + String fileName = Path.GetFileName(filePath); + if (!this.whitelistedDlls.Contains(fileName.ToLower())) + { + if (!File.Exists(filePath + ".nwmode")) + File.Move(filePath, filePath + ".nwmode"); + /*else + File.Delete(filePath);*/ + this.logFile.WriteLine($" Renamed {fileName}"); + } + } } else { - this.logFile.WriteLine($"Removing {archive.archiveName}"); - if (File.Exists(bundledArchivePath)) - File.Delete(bundledArchivePath); - sResourceIndexFileList.Remove(archive.archiveName); + IEnumerable files = Directory.EnumerateFiles(this.GamePath, "*.dll.nwmode");/*, SearchOption.AllDirectories);*/ + int count = files.Count(); + if (count > 0) + { + this.logFile.WriteLine($" Renaming \'*.dll.nwmode\' files to \'*.dll\'. ({count})"); + foreach (String filePath in files) + { + String fileName = Path.GetFileName(filePath); + File.Move(filePath, Path.Combine(Path.GetDirectoryName(filePath), fileName.Replace(".dll.nwmode", ".dll"))); + this.logFile.WriteLine($" Renamed {fileName}"); + } + } } - } - /* - * Finishing up... - */ - if (updateProgress != null) - updateProgress("[4/4] Finishing up...", -1); - this.logFile.WriteLine($"Finishing up..."); - - - // Renaming *.dll files - if (this.nuclearWinterMode) - { - // String[] files = Directory.GetFiles(this.GamePath, "*.dll", SearchOption.AllDirectories); - IEnumerable files = Directory.EnumerateFiles(this.GamePath, "*.dll");/*, SearchOption.AllDirectories);*/ // Don't change the *.dll files in the /Mods/ folder!! - this.logFile.WriteLine($" Renaming not \'whitelisted\' \'*.dll\' files to \'*.dll.nwmode\'."); - foreach (String filePath in files) + // Writing stuff to inis + this.logFile.WriteLine($" Changing values in *.ini files..."); + if (this.nuclearWinterMode) { - String fileName = Path.GetFileName(filePath); - if (!this.whitelistedDlls.Contains(fileName.ToLower())) + if (sResourceIndexFileList.Count() > 0) { - if (!File.Exists(filePath + ".nwmode")) - File.Move(filePath, filePath + ".nwmode"); - /*else - File.Delete(filePath);*/ - this.logFile.WriteLine($" Renamed {fileName}"); + IniFiles.Instance.Set(IniFile.Config, "Archive", "sResourceIndexFileList", String.Join(",", sResourceIndexFileList.Distinct())); + this.logFile.WriteLine($" sResourceIndexFileList copied to QuickConfiguration.ini."); } + else + IniFiles.Instance.Remove(IniFile.Config, "Archive", "sResourceIndexFileList"); + IniFiles.Instance.Remove(IniFile.F76Custom, "Archive", "sResourceIndexFileList"); } - } - else - { - IEnumerable files = Directory.EnumerateFiles(this.GamePath, "*.dll.nwmode");/*, SearchOption.AllDirectories);*/ - int count = files.Count(); - if (count > 0) + else { - this.logFile.WriteLine($" Renaming \'*.dll.nwmode\' files to \'*.dll\'. ({count})"); - foreach (String filePath in files) + if (sResourceIndexFileList.Count() > 0) { - String fileName = Path.GetFileName(filePath); - File.Move(filePath, Path.Combine(Path.GetDirectoryName(filePath), fileName.Replace(".dll.nwmode", ".dll"))); - this.logFile.WriteLine($" Renamed {fileName}"); + IniFiles.Instance.Set(IniFile.F76Custom, "Archive", "sResourceIndexFileList", String.Join(",", sResourceIndexFileList.Distinct())); + this.logFile.WriteLine($" sResourceIndexFileList={String.Join(",", sResourceIndexFileList.Distinct())}"); } + else + { + IniFiles.Instance.Remove(IniFile.F76Custom, "Archive", "sResourceIndexFileList"); + this.logFile.WriteLine($" sResourceIndexFileList removed."); + } + IniFiles.Instance.Remove(IniFile.Config, "Archive", "sResourceIndexFileList"); } - } - // Writing stuff to inis - this.logFile.WriteLine($" Changing values in *.ini files..."); - if (this.nuclearWinterMode) - { - if (sResourceIndexFileList.Count() > 0) + // sResourceDataDirsFinal + sResourceDataDirsFinal.Clear(); + String[] resourceFolders = new string[] { "meshes", "strings", "music", "sound", "textures", "materials", "interface", "geoexporter", "programs", "vis", "scripts", "misc", "shadersfx", "lodsettings" }; + foreach (String folder in Directory.GetDirectories(Path.Combine(this.gamePath, "Data"))) { - IniFiles.Instance.Set(IniFile.Config, "Archive", "sResourceIndexFileList", String.Join(",", sResourceIndexFileList.Distinct())); - this.logFile.WriteLine($" sResourceIndexFileList copied to QuickConfiguration.ini."); + String folderName = Path.GetFileName(folder); + if (resourceFolders.Contains(folderName.ToLower())) + sResourceDataDirsFinal.Add(folderName.ToUpper() + "\\"); } - else - IniFiles.Instance.Remove(IniFile.Config, "Archive", "sResourceIndexFileList"); - IniFiles.Instance.Remove(IniFile.F76Custom, "Archive", "sResourceIndexFileList"); - } - else - { - if (sResourceIndexFileList.Count() > 0) + if (sResourceDataDirsFinal.Count() > 0) { - IniFiles.Instance.Set(IniFile.F76Custom, "Archive", "sResourceIndexFileList", String.Join(",", sResourceIndexFileList.Distinct())); - this.logFile.WriteLine($" sResourceIndexFileList={String.Join(",", sResourceIndexFileList.Distinct())}"); + IniFiles.Instance.Set(IniFile.F76Custom, "Archive", "sResourceDataDirsFinal", String.Join(",", sResourceDataDirsFinal.Distinct())); + IniFiles.Instance.Set(IniFile.F76Custom, "Archive", "bInvalidateOlderFiles", true); } else { - IniFiles.Instance.Remove(IniFile.F76Custom, "Archive", "sResourceIndexFileList"); - this.logFile.WriteLine($" sResourceIndexFileList removed."); + IniFiles.Instance.Remove(IniFile.F76Custom, "Archive", "sResourceDataDirsFinal"); + IniFiles.Instance.Remove(IniFile.F76Custom, "Archive", "bInvalidateOlderFiles"); } - IniFiles.Instance.Remove(IniFile.Config, "Archive", "sResourceIndexFileList"); - } - // sResourceDataDirsFinal - sResourceDataDirsFinal.Clear(); - String[] resourceFolders = new string[] { "meshes", "strings", "music", "sound", "textures", "materials", "interface", "geoexporter", "programs", "vis", "scripts", "misc", "shadersfx", "lodsettings" }; - foreach (String folder in Directory.GetDirectories(Path.Combine(this.gamePath, "Data"))) - { - String folderName = Path.GetFileName(folder); - if (resourceFolders.Contains(folderName.ToLower())) - sResourceDataDirsFinal.Add(folderName.ToUpper() + "\\"); - } - if (sResourceDataDirsFinal.Count() > 0) - { - IniFiles.Instance.Set(IniFile.F76Custom, "Archive", "sResourceDataDirsFinal", String.Join(",", sResourceDataDirsFinal.Distinct())); - IniFiles.Instance.Set(IniFile.F76Custom, "Archive", "bInvalidateOlderFiles", true); - } - else - { - IniFiles.Instance.Remove(IniFile.F76Custom, "Archive", "sResourceDataDirsFinal"); - IniFiles.Instance.Remove(IniFile.F76Custom, "Archive", "bInvalidateOlderFiles"); - } + CopyINILists(); - CopyINILists(); + this.logFile.WriteLine($" Saving."); + IniFiles.Instance.SaveAll(); + this.mods = CreateDeepCopy(this.changedMods); + this.Save(); + Directory.Delete(tempPath, true); - this.logFile.WriteLine($" Saving."); - IniFiles.Instance.SaveAll(); - this.mods = CreateDeepCopy(this.changedMods); - this.Save(); - Directory.Delete(tempPath, true); - if (done != null) - done(); + this.logFile.WriteLine("Done.\n"); - this.logFile.WriteLine("Done.\n"); + if (done != null) + done(true); + } + catch (Exception ex) + { + this.logFile.WriteLine($"Unhandled exception occured: {ex.Message}\n{ex.StackTrace}"); + if (done != null) + done(false); + } } public void CopyINILists() diff --git a/Fo76ini/Translation.cs b/Fo76ini/Translation.cs index 9cd6662..2f47d11 100644 --- a/Fo76ini/Translation.cs +++ b/Fo76ini/Translation.cs @@ -19,6 +19,7 @@ static Translation() localizedStrings["newVersionAvailable"] = "There is a newer version available: {0}"; localizedStrings["modsDeploymentNecessary"] = "Deployment necessary"; localizedStrings["modsAllDone"] = "All set"; + localizedStrings["modsFailed"] = "Something went wrong, see log files for details."; localizedStrings["modsTableFormatGeneral"] = "General"; localizedStrings["modsTableFormatTextures"] = "Textures"; localizedStrings["modsTableFormatAutoDetect"] = "Auto"; diff --git a/Fo76ini/Utils.cs b/Fo76ini/Utils.cs index bfb76fc..a399518 100644 --- a/Fo76ini/Utils.cs +++ b/Fo76ini/Utils.cs @@ -102,6 +102,7 @@ public static string MakeRelativePath(string workingDirectory, string fullPath) public static void DeleteDirectory(string targetDir) { // https://stackoverflow.com/questions/1157246/unauthorizedaccessexception-trying-to-delete-a-file-in-a-folder-where-i-can-dele + IniFiles.Instance.SetNTFSWritePermission(true); File.SetAttributes(targetDir, FileAttributes.Normal); string[] files = Directory.GetFiles(targetDir); @@ -538,5 +539,30 @@ public static bool IsProcessRunning(string name) return false; } + + // https://stackoverflow.com/questions/3387690/how-to-create-a-hardlink-in-c + [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] + private static extern bool CreateHardLink( + string lpFileName, + string lpExistingFileName, + IntPtr lpSecurityAttributes + ); + + public static bool CreateHardLink(String originalFilePath, String newLinkPath) + { + return Utils.CreateHardLink(newLinkPath, originalFilePath, IntPtr.Zero); + } + + public static bool CreateHardLink(String originalFilePath, String newLinkPath, bool overwrite) + { + if (File.Exists(newLinkPath)) + { + if (overwrite) + File.Delete(newLinkPath); + else + throw new Exception($"Trying to create a hardlink in \"{newLinkPath}\" but this file already exists."); + } + return Utils.CreateHardLink(newLinkPath, originalFilePath, IntPtr.Zero); + } } } diff --git a/Fo76ini/languages/de-DE.xml b/Fo76ini/languages/de-DE.xml index 7a5fde5..c6b9adf 100644 --- a/Fo76ini/languages/de-DE.xml +++ b/Fo76ini/languages/de-DE.xml @@ -1,9 +1,10 @@  - + + @@ -103,6 +104,8 @@ Einige UI-Elemente könnten unter Umständen nicht korrekt funktionieren. {0} Mods wurden deaktiviert und vom Spiel entfernt. Mods wurden installiert. + Mods könnten nicht installiert worden sein. +Siehe Logdateien für mehr Details. .\Archive2\Archive2.exe fehlt. Bitte lade das Tool erneut herunter oder installiere Archive2 manuell. Bitte setze den Spielpfad (im Ordner sollte Fallout76.exe sein). @@ -191,6 +194,12 @@ So braucht man nicht mehr auf "Anwenden" zu drücken.