diff --git a/SharpGMad/Main.cs b/SharpGMad/Main.cs index cac2521..618e3ef 100644 --- a/SharpGMad/Main.cs +++ b/SharpGMad/Main.cs @@ -18,6 +18,7 @@ private Main() { InitializeComponent(); UnloadAddon(); + tsbCreateAddon.Enabled = !Program.WhitelistOverridden; } public Main(string[] args) @@ -95,8 +96,30 @@ private void LoadAddon(string path) } catch (WhitelistException e) { - MessageBox.Show(e.Message, "Addon is corrupted", MessageBoxButtons.OK, MessageBoxIcon.Stop); - return; + if (!Program.WhitelistOverridden) + { + DialogResult ovrride = MessageBox.Show("This addon is against the GMA whitelist rules defined by garry!\n" + + e.Message + "\n\nFor datamining purposes, it is still possible to open this addon, HOWEVER " + + "opening this addon is an illegal operation and SharpGMad will prevent further modifications.\n\n" + + "Do you want to enable forced opening of addons by overriding the whitelist?", + "Addon is corrupted", MessageBoxButtons.YesNo, MessageBoxIcon.Question); + + if (ovrride == DialogResult.No) + { + MessageBox.Show(e.Message, "Addon is corrupted", MessageBoxButtons.OK, MessageBoxIcon.Stop); + return; + } + else if (ovrride == DialogResult.Yes) + { + Program.WhitelistOverridden = true; + tsbCreateAddon.Enabled = !Program.WhitelistOverridden; + MessageBox.Show("Restrictions disabled.\nPlease browse for the addon to open it again.", + "Addon is corrupted", MessageBoxButtons.OK, MessageBoxIcon.Information); + this.Text = "! - SharpGMad"; + UpdateStatus("Restrictions disabled by user's request."); + return; + } + } } catch (ArgumentException e) { @@ -123,8 +146,8 @@ private void LoadAddon(string path) UpdateModified(); UpdateStatus("Loaded the addon" + (AddonHandle.CanWrite ? null : " (read-only mode)")); - tsbAddFile.Enabled = AddonHandle.CanWrite; - tsbUpdateMetadata.Enabled = AddonHandle.CanWrite; + tsbAddFile.Enabled = AddonHandle.CanWrite && !Program.WhitelistOverridden; + tsbUpdateMetadata.Enabled = AddonHandle.CanWrite && !Program.WhitelistOverridden; } } @@ -144,10 +167,11 @@ private void UpdateModified() } else { - this.Text = Path.GetFileName(AddonHandle.AddonPath) + (AddonHandle.CanWrite ? null : " (read-only)") + + this.Text = Path.GetFileName(AddonHandle.AddonPath) + (Program.WhitelistOverridden ? "!" : null) + + (AddonHandle.CanWrite ? null : " (read-only)") + (AddonHandle.Modified ? "*" : null) + " - SharpGMad"; - tsbSaveAddon.Enabled = AddonHandle.CanWrite && AddonHandle.Modified; + tsbSaveAddon.Enabled = AddonHandle.CanWrite && AddonHandle.Modified && (!Program.WhitelistOverridden); } } @@ -221,7 +245,8 @@ private void UpdateFileList() foreColor = System.Drawing.SystemColors.ControlText; tsslStatus.ForeColor = foreColor; - tsslStatus.Text = "[" + DateTime.Now.ToString() + "] " + text; + tsslStatus.Text = (Program.WhitelistOverridden ? "!Cannot modify addons because the whitelist had been overridden! " : null) + + "[" + DateTime.Now.ToString() + "] " + text; } /// @@ -279,7 +304,7 @@ private void UnloadAddon() lstFiles.Items.Clear(); lstFiles.Groups.Clear(); - this.Text = "SharpGMad"; + this.Text = "SharpGMad" + (Program.WhitelistOverridden ? "!" : null); tsbSaveAddon.Enabled = false; if (AddonHandle != null) @@ -323,7 +348,7 @@ private void tsmiLegacyExtract_Click(object sender, EventArgs e) private void tsbAddFile_Click(object sender, EventArgs e) { - if (AddonHandle == null) + if (AddonHandle == null || Program.WhitelistOverridden) return; // If there is no value for file filtering, load a file list @@ -390,7 +415,7 @@ private void lstFiles_SelectedIndexChanged(object sender, EventArgs e) { // Allow remove, export and execution tsmFileRemove.Visible = true; - tsmFileRemove.Enabled = AddonHandle.CanWrite; + tsmFileRemove.Enabled = AddonHandle.CanWrite && !Program.WhitelistOverridden; tsmFileExtract.Enabled = true; tsmFileExtract.Visible = true; @@ -404,7 +429,7 @@ private void lstFiles_SelectedIndexChanged(object sender, EventArgs e) if (isExported.Count() == 0) { // Export is the file is not exported - tsmFileExportTo.Enabled = AddonHandle.CanWrite; + tsmFileExportTo.Enabled = AddonHandle.CanWrite && !Program.WhitelistOverridden; tsmFilePull.Enabled = false; tsmFileDropExport.Enabled = false; } @@ -412,7 +437,7 @@ private void lstFiles_SelectedIndexChanged(object sender, EventArgs e) { // Pull (applicable if the file is changed) and drop tsmFileExportTo.Enabled = false; - tsmFilePull.Enabled = isExported.First().Modified && AddonHandle.CanWrite; + tsmFilePull.Enabled = isExported.First().Modified && AddonHandle.CanWrite && !Program.WhitelistOverridden; tsmFileDropExport.Enabled = true; } @@ -426,7 +451,7 @@ private void lstFiles_SelectedIndexChanged(object sender, EventArgs e) else if (((System.Windows.Forms.ListView)sender).SelectedItems.Count > 1) { // Multiple files support remove, extract, but no exec and export-related stuff - tsmFileRemove.Enabled = true; + tsmFileRemove.Enabled = !Program.WhitelistOverridden; tsmFileRemove.Visible = true; tsmFileExtract.Enabled = true; @@ -501,7 +526,7 @@ private void lstFiles_KeyDown(object sender, KeyEventArgs e) private void tsmFileRemove_Click(object sender, EventArgs e) { - if (!AddonHandle.CanWrite) + if (!AddonHandle.CanWrite || Program.WhitelistOverridden) return; if (lstFiles.SelectedItems.Count == 1) @@ -599,7 +624,7 @@ private void tsmFileRemove_Click(object sender, EventArgs e) private void tsbUpdateMetadata_Click(object sender, EventArgs e) { - if (!AddonHandle.CanWrite) + if (!AddonHandle.CanWrite || Program.WhitelistOverridden) return; // Use a toggle mechanism to enable and disable the changing of metadata @@ -708,7 +733,7 @@ private void tsbDiscardMetadataChanges_Click(object sender, EventArgs e) private void tsbSaveAddon_Click(object sender, EventArgs e) { - if (!AddonHandle.CanWrite) + if (!AddonHandle.CanWrite || Program.WhitelistOverridden) return; if (!tsbUpdateMetadata.Checked) @@ -745,7 +770,7 @@ private void tsbSaveAddon_Click(object sender, EventArgs e) private void Main_FormClosing(object sender, FormClosingEventArgs e) { - if (AddonHandle is RealtimeAddon && AddonHandle.Modified) + if (AddonHandle is RealtimeAddon && AddonHandle.Modified && !Program.WhitelistOverridden) { DialogResult yesClose = MessageBox.Show("Save the addon before quitting?", Path.GetFileName(AddonHandle.AddonPath), MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); @@ -774,8 +799,14 @@ private void Main_FormClosing(object sender, FormClosingEventArgs e) private void tsbCreateAddon_Click(object sender, EventArgs e) { + if (Program.WhitelistOverridden) + { + tsbCreateAddon.Enabled = !Program.WhitelistOverridden; + return; + } + DialogResult dropChanges = new DialogResult(); - if (AddonHandle is RealtimeAddon && AddonHandle.Modified) + if (AddonHandle is RealtimeAddon && AddonHandle.Modified && !Program.WhitelistOverridden) { dropChanges = MessageBox.Show("Open an another addon without saving the current one?\nYou'll lose the changes.", "Addon already open", MessageBoxButtons.YesNo, MessageBoxIcon.Question); @@ -823,7 +854,7 @@ private void tsbCreateAddon_Click(object sender, EventArgs e) private void tsmFileExportTo_Click(object sender, EventArgs e) { - if (!AddonHandle.CanWrite) + if (!AddonHandle.CanWrite || Program.WhitelistOverridden) return; if (lstFiles.FocusedItem != null) @@ -1046,7 +1077,7 @@ private void tsbPullAll_Click(object sender, EventArgs e) /// The exported path is known automatically. private void PullFile(string filename) { - if (!AddonHandle.CanWrite) + if (!AddonHandle.CanWrite || Program.WhitelistOverridden) return; try diff --git a/SharpGMad/Program.cs b/SharpGMad/Program.cs index 565a305..bd7a7f2 100644 --- a/SharpGMad/Program.cs +++ b/SharpGMad/Program.cs @@ -11,6 +11,12 @@ namespace SharpGMad /// class Program { + // HACK: This has been just tied into the system to fix opening of illegal GMAs + /// + /// Indicates whether the whitelist was overridden by an illegal action. + /// + public static bool WhitelistOverridden = false; + #if WINDOWS /// /// External method to find a pointer for an attached console window. diff --git a/SharpGMad/Properties/AssemblyInfo.cs b/SharpGMad/Properties/AssemblyInfo.cs index 758f7e5..6eb6f95 100644 --- a/SharpGMad/Properties/AssemblyInfo.cs +++ b/SharpGMad/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.2.1")] -[assembly: AssemblyFileVersion("1.1.2.1")] \ No newline at end of file +[assembly: AssemblyVersion("1.1.2.3")] +[assembly: AssemblyFileVersion("1.1.2.3")] \ No newline at end of file diff --git a/SharpGMad/RealtimeAddon.cs b/SharpGMad/RealtimeAddon.cs index db2060b..060ace5 100644 --- a/SharpGMad/RealtimeAddon.cs +++ b/SharpGMad/RealtimeAddon.cs @@ -135,7 +135,7 @@ public static RealtimeAddon Load(string filename, bool readOnly = false) throw new FileNotFoundException("The specified file " + filename + " does not exist."); } - FileStream fs; + FileStream fs = null; try { if (!readOnly) @@ -145,6 +145,9 @@ public static RealtimeAddon Load(string filename, bool readOnly = false) } catch (IOException) { + if (fs != null) + fs.Dispose(); + throw; } @@ -155,10 +158,12 @@ public static RealtimeAddon Load(string filename, bool readOnly = false) } catch (IOException) { + fs.Dispose(); throw; } catch (ReaderException) { + fs.Dispose(); throw; } @@ -169,14 +174,17 @@ public static RealtimeAddon Load(string filename, bool readOnly = false) } catch (ArgumentException) { + fs.Dispose(); throw; } catch (WhitelistException) { + fs.Dispose(); throw; } catch (IgnoredException) { + fs.Dispose(); throw; } diff --git a/SharpGMad/RealtimeCommandline.cs b/SharpGMad/RealtimeCommandline.cs index 776a0cd..49c191f 100644 --- a/SharpGMad/RealtimeCommandline.cs +++ b/SharpGMad/RealtimeCommandline.cs @@ -53,7 +53,8 @@ public static int Main(string[] args) } else if (AddonHandle is RealtimeAddon) { - Console.Write(Path.GetFileName(AddonHandle.AddonPath) + (AddonHandle.CanWrite ? null : " (read-only)") + + Console.Write(Path.GetFileName(AddonHandle.AddonPath) + (Program.WhitelistOverridden ? "!" : null) + + (AddonHandle.CanWrite ? null : " (read-only)") + (AddonHandle.Modified ? "*" : null) + (AddonHandle.Pullable ? "!" : null)); #if WINDOWS Console.Write("> "); @@ -590,24 +591,25 @@ public static int Main(string[] args) if (AddonHandle == null) { Console.WriteLine("load Loads addon into the memory"); - Console.WriteLine("new Create a new, empty addon named "); + if (!Program.WhitelistOverridden) + Console.WriteLine("new Create a new, empty addon named "); } if (AddonHandle is RealtimeAddon) { - if (AddonHandle.CanWrite) + if (AddonHandle.CanWrite && !Program.WhitelistOverridden) { Console.WriteLine("add Adds to the archive"); Console.WriteLine("addfolder Adds all files from to the archive"); } Console.WriteLine("list Lists the files in the memory"); - if (AddonHandle.CanWrite) + if (AddonHandle.CanWrite && !Program.WhitelistOverridden) { Console.WriteLine("remove Removes from the archive"); } Console.WriteLine("extract [path] Extract (to [path] if specified)"); Console.WriteLine("mget [f2...] Extract all specified files to "); - if (AddonHandle.CanWrite) + if (AddonHandle.CanWrite && !Program.WhitelistOverridden) { Console.WriteLine("export View the list of exported files"); Console.WriteLine("export [path] Export for editing (to [path] if specified)"); @@ -616,7 +618,7 @@ public static int Main(string[] args) Console.WriteLine("drop Drops the export for "); } Console.WriteLine("get Prints the value of metadata "); - if (AddonHandle.CanWrite) + if (AddonHandle.CanWrite && !Program.WhitelistOverridden) { Console.WriteLine("set [value] Sets metadata to the specified [value]"); Console.WriteLine("push Writes the changes to the disk"); @@ -663,6 +665,13 @@ public static int Main(string[] args) } } + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + } + break; case "exit": if (AddonHandle is RealtimeAddon) @@ -694,6 +703,14 @@ public static int Main(string[] args) /// The filename where the addon should be saved to. static void NewAddon(string filename) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (AddonHandle is RealtimeAddon) { Console.ForegroundColor = ConsoleColor.Red; @@ -745,6 +762,14 @@ static void NewAddon(string filename) /// Optional. The new title the addon should have. private static void SetTitle(string title = null) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (!AddonHandle.CanWrite) { Console.ForegroundColor = ConsoleColor.Red; @@ -771,6 +796,14 @@ private static void SetTitle(string title = null) /// Optional. The new description the addon should have. private static void SetDescription(string description = null) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (!AddonHandle.CanWrite) { Console.ForegroundColor = ConsoleColor.Red; @@ -797,6 +830,14 @@ private static void SetDescription(string description = null) /// Optional. The new author the addon should have. private static void SetAuthor(string author = null) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (!AddonHandle.CanWrite) { Console.ForegroundColor = ConsoleColor.Red; @@ -825,6 +866,14 @@ private static void SetAuthor(string author = null) /// Optional. The new type the addon should have. private static void SetType(string type = null) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (!AddonHandle.CanWrite) { Console.ForegroundColor = ConsoleColor.Red; @@ -873,6 +922,14 @@ private static void SetType(string type = null) /// Optional. The new tags the addon should have. private static void SetTags(string[] tagsInput = null) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (!AddonHandle.CanWrite) { Console.ForegroundColor = ConsoleColor.Red; @@ -1003,6 +1060,50 @@ private static void LoadAddon(string filename) { AddonHandle = RealtimeAddon.Load(filename, !FileExtensions.CanWrite(filename)); } + catch (WhitelistException e) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("There was a problem opening the file."); + Console.ResetColor(); + + Console.ForegroundColor = ConsoleColor.Yellow; + Console.Write("This addon is against the GMA whitelist rules defined by garry!\n" + + e.Message + "\n\nFor datamining purposes, it is still possible to open this addon, HOWEVER " + + "opening this addon is an illegal operation and SharpGMad will prevent further modifications."); + Console.ResetColor(); + + bool decided = false; + string decision; + while (!decided) + { + Console.Write("\nDo you want to enable forced opening of addons by overriding the whitelist? (y/n) "); + decision = Console.ReadLine(); + if (decision == "n" || decision == "N") + { + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine("The addon will not be opened."); + Console.ResetColor(); + decided = true; + return; + } + else if (decision == "y" || decision == "Y") + { + Program.WhitelistOverridden = true; + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("All security safeguards and restrictions HAD BEEN DISABLED."); + Console.ResetColor(); + Console.WriteLine("Please type the command again to load the addon."); + decided = true; + CloseAddon(); + return; + } + else + { + decided = false; + Console.WriteLine("Invalid input. Please write y for yes or n for no."); + } + } + } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; @@ -1032,6 +1133,14 @@ private static void LoadAddon(string filename) /// The path of the file to be added. private static void AddFile(string filename) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (AddonHandle == null) { Console.ForegroundColor = ConsoleColor.Red; @@ -1099,6 +1208,14 @@ private static void AddFile(string filename) /// The folder containing the files to be added. private static void AddFolder(string folder) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (!AddonHandle.CanWrite) { Console.ForegroundColor = ConsoleColor.Red; @@ -1147,6 +1264,14 @@ private static void ListFiles() /// The path of the file to be removed. private static void RemoveFile(string filename) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (AddonHandle == null) { Console.ForegroundColor = ConsoleColor.Red; @@ -1233,6 +1358,14 @@ private static void ExtractFile(string filename, string extractPath = null) /// If omitted, the file will be exported to the current working directory. private static void ExportFile(string filename, string exportPath = null) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (AddonHandle == null) { Console.ForegroundColor = ConsoleColor.Red; @@ -1313,6 +1446,14 @@ private static void fsw_Changed(object sender, FileSystemEventArgs e) /// The exported path is known internally. private static void DropExport(string filename) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (AddonHandle == null) { Console.ForegroundColor = ConsoleColor.Red; @@ -1350,6 +1491,14 @@ private static void DropExport(string filename) /// The exported path is known automatically. private static void PullFile(string filename) { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (AddonHandle == null) { Console.ForegroundColor = ConsoleColor.Red; @@ -1394,6 +1543,14 @@ private static void PullFile(string filename) /// private static void Push() { + if (Program.WhitelistOverridden) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Due to opening a whitelist non compliant addon, the restrictions and addon modification capability has been disabled."); + Console.ResetColor(); + return; + } + if (AddonHandle == null) { Console.ForegroundColor = ConsoleColor.Red; diff --git a/SharpGMad/Whitelist.cs b/SharpGMad/Whitelist.cs index c8f984a..49547ab 100644 --- a/SharpGMad/Whitelist.cs +++ b/SharpGMad/Whitelist.cs @@ -29,6 +29,29 @@ static class Whitelist /// A list of string patterns of allowed files. /// private static string[] Wildcard = new string[]{ + "lua/*.lua", + "scenes/*.vcd", + "particles/*.pcf", + "resource/fonts/*.ttf", + "scripts/vehicles/*.txt", + "resource/localization/*/*.properties", + "maps/*.bsp", + "maps/*.nav", + "maps/*.ain", + "maps/thumb/*.png", + "sound/*.wav", + "sound/*.mp3", + "sound/*.ogg", + "materials/*.vmt", + "materials/*.vtf", + "materials/*.png", + "materials/*.jpg", + "materials/*.jpeg", + "models/*.mdl", + "models/*.vtx", + "models/*.phy", + "models/*.ani", + "models/*.vvd", "gamemodes/*/*.txt", "gamemodes/*/*.fgd", "gamemodes/*/logo.png", @@ -62,29 +85,6 @@ static class Whitelist "gamemodes/*/content/sound/*.wav", "gamemodes/*/content/sound/*.mp3", "gamemodes/*/content/sound/*.ogg", - "lua/*.lua", - "scenes/*.vcd", - "particles/*.pcf", - "resource/fonts/*.ttf", - "scripts/vehicles/*.txt", - "resource/localization/*/*.properties", - "maps/*.bsp", - "maps/*.nav", - "maps/*.ain", - "maps/thumb/*.png", - "sound/*.wav", - "sound/*.mp3", - "sound/*.ogg", - "materials/*.vmt", - "materials/*.vtf", - "materials/*.png", - "materials/*.jpg", - "materials/*.jpeg", - "models/*.mdl", - "models/*.vtx", - "models/*.phy", - "models/*.ani", - "models/*.vvd", null }; @@ -130,7 +130,7 @@ static Whitelist() /// True if the file is allowed, false if not. public static bool Check(string path) { - return Wildcard.Any(wildcard => Check(wildcard, path)); + return (Program.WhitelistOverridden || Wildcard.Any(wildcard => Check(wildcard, path))); } ///