Fixed: lump saving in script editor after editing archive with SLADE.\n Fixed: checking for concurrent modification in script editor while trying to save the lump.

This commit is contained in:
ZZYZX 2017-01-21 03:13:36 +02:00
parent a705e47fb9
commit a5a942c798
8 changed files with 164 additions and 110 deletions

View file

@ -98,11 +98,16 @@ namespace CodeImp.DoomBuilder.Controls
// Find lump, check it's hash // Find lump, check it's hash
bool dosave = true; bool dosave = true;
DataReader reader = source.Resource; DataReader reader = source.Resource;
if(reader.FileExists(source.Filename, source.LumpIndex)) // reload the reader
bool wasReadOnly = reader.IsReadOnly;
reader.Reload(false);
try
{ {
using(MemoryStream ms = reader.LoadFile(source.Filename, source.LumpIndex)) if (reader.FileExists(source.Filename, source.LumpIndex))
{ {
if(MD5Hash.Get(ms) != hash using (MemoryStream ms = reader.LoadFile(source.Filename, source.LumpIndex))
{
if (MD5Hash.Get(ms) != hash
&& MessageBox.Show("Target lump was modified by another application. Do you still want to replace it?", "Warning", MessageBoxButtons.OKCancel) && MessageBox.Show("Target lump was modified by another application. Do you still want to replace it?", "Warning", MessageBoxButtons.OKCancel)
== DialogResult.Cancel) == DialogResult.Cancel)
{ {
@ -111,12 +116,12 @@ namespace CodeImp.DoomBuilder.Controls
} }
} }
if(dosave) if (dosave)
{ {
// Store the lump data // Store the lump data
using(MemoryStream stream = new MemoryStream(editor.GetText())) using (MemoryStream stream = new MemoryStream(editor.GetText()))
{ {
if(reader.SaveFile(stream, source.Filename, source.LumpIndex)) if (reader.SaveFile(stream, source.Filename, source.LumpIndex))
{ {
// Update what must be updated // Update what must be updated
hash = MD5Hash.Get(stream); hash = MD5Hash.Get(stream);
@ -124,6 +129,11 @@ namespace CodeImp.DoomBuilder.Controls
UpdateTitle(); UpdateTitle();
} }
} }
}
}
finally
{
reader.Reload(wasReadOnly);
} }
return dosave; return dosave;

View file

@ -141,13 +141,25 @@ namespace CodeImp.DoomBuilder.Data
// This suspends use of this resource // This suspends use of this resource
public virtual void Suspend() public virtual void Suspend()
{ {
// [ZZ] validate
if (issuspended) throw new Exception("Tried to suspend already suspended resource!");
issuspended = true; issuspended = true;
isreadonly = true;
} }
// This resumes use of this resource // This resumes use of this resource
public virtual void Resume() public virtual void Resume()
{ {
// [ZZ] validate
if (!issuspended) throw new Exception("Tried to resume already resumed resource!");
issuspended = false; issuspended = false;
isreadonly = false;
}
// This reloads the resource (possibly as readonly).
public virtual void Reload(bool newreadonly)
{
} }
#endregion #endregion

View file

@ -35,10 +35,10 @@ namespace CodeImp.DoomBuilder.Data
{ {
#region ================== Variables #region ================== Variables
private readonly DirectoryFilesList files; private /*readonly*/ DirectoryFilesList files;
private IArchive archive; //mxd private IArchive archive; //mxd
private readonly ArchiveType archivetype; //mxd private /*readonly*/ ArchiveType archivetype; //mxd
private readonly Dictionary<string, byte[]> sevenzipentries; //mxd private /*readonly*/ Dictionary<string, byte[]> sevenzipentries; //mxd
private bool bathmode = true; //mxd private bool bathmode = true; //mxd
#endregion #endregion
@ -53,10 +53,15 @@ namespace CodeImp.DoomBuilder.Data
// Constructor // Constructor
public PK3Reader(DataLocation dl, bool asreadonly) : base(dl, asreadonly) public PK3Reader(DataLocation dl, bool asreadonly) : base(dl, asreadonly)
{
LoadFrom(dl, asreadonly);
}
private void LoadFrom(DataLocation dl, bool asreadonly)
{ {
General.WriteLogLine("Opening " + Path.GetExtension(location.location).ToUpper().Replace(".", "") + " resource \"" + location.location + "\""); General.WriteLogLine("Opening " + Path.GetExtension(location.location).ToUpper().Replace(".", "") + " resource \"" + location.location + "\"");
if(!File.Exists(location.location)) if (!File.Exists(location.location))
throw new FileNotFoundException("Could not find the file \"" + location.location + "\"", location.location); throw new FileNotFoundException("Could not find the file \"" + location.location + "\"", location.location);
// Make list of all files // Make list of all files
@ -67,15 +72,15 @@ namespace CodeImp.DoomBuilder.Data
archivetype = archive.Type; archivetype = archive.Type;
// Random access of 7z archives works TERRIBLY slow in SharpCompress // Random access of 7z archives works TERRIBLY slow in SharpCompress
if(archivetype == ArchiveType.SevenZip) if (archivetype == ArchiveType.SevenZip)
{ {
isreadonly = true; // Unsaveable... isreadonly = true; // Unsaveable...
sevenzipentries = new Dictionary<string, byte[]>(StringComparer.Ordinal); sevenzipentries = new Dictionary<string, byte[]>(StringComparer.Ordinal);
IReader reader = archive.ExtractAllEntries(); IReader reader = archive.ExtractAllEntries();
while(reader.MoveToNextEntry()) while (reader.MoveToNextEntry())
{ {
if(reader.Entry.IsDirectory || !CheckInvalidPathChars(reader.Entry.Key)) continue; if (reader.Entry.IsDirectory || !CheckInvalidPathChars(reader.Entry.Key)) continue;
MemoryStream s = new MemoryStream(); MemoryStream s = new MemoryStream();
reader.WriteEntryTo(s); reader.WriteEntryTo(s);
@ -85,9 +90,9 @@ namespace CodeImp.DoomBuilder.Data
} }
else else
{ {
foreach(IArchiveEntry entry in archive.Entries) foreach (IArchiveEntry entry in archive.Entries)
{ {
if(!entry.IsDirectory && CheckInvalidPathChars(entry.Key)) if (!entry.IsDirectory && CheckInvalidPathChars(entry.Key))
fileentries.Add(new DirectoryFileEntry(entry.Key)); fileentries.Add(new DirectoryFileEntry(entry.Key));
} }
} }
@ -151,6 +156,19 @@ namespace CodeImp.DoomBuilder.Data
#endregion #endregion
#region ================== Management
// [ZZ]
// This reloads the resource
public override void Reload(bool newreadonly)
{
if (archive != null)
archive.Dispose();
LoadFrom(location, newreadonly);
}
#endregion
#region ================== Textures #region ================== Textures
// This finds and returns a patch stream // This finds and returns a patch stream

View file

@ -72,6 +72,8 @@ namespace CodeImp.DoomBuilder.Data
// Call this to initialize this class // Call this to initialize this class
protected virtual void Initialize() protected virtual void Initialize()
{ {
// [ZZ] we can have wad files already. dispose if any.
if (wads != null) foreach (WADReader wr in wads) wr.Dispose();
// Load all WAD files in the root as WAD resources // Load all WAD files in the root as WAD resources
string[] wadfiles = GetWadFiles(); string[] wadfiles = GetWadFiles();
wads = new List<WADReader>(wadfiles.Length); wads = new List<WADReader>(wadfiles.Length);

View file

@ -211,17 +211,26 @@ namespace CodeImp.DoomBuilder.Data
public override void Suspend() public override void Suspend()
{ {
file.Dispose(); file.Dispose();
file = null;
base.Suspend(); base.Suspend();
} }
// This resumes use of this resource // This resumes use of this resource
public override void Resume() public override void Resume()
{ {
file = new WAD(location.location, true); Reload(true);
is_iwad = file.IsIWAD;
base.Resume(); base.Resume();
} }
// This reloads the resource
public override void Reload(bool newreadonly)
{
if (file != null) file.Dispose();
file = new WAD(location.location, newreadonly);
is_iwad = file.IsIWAD;
base.Reload(newreadonly);
}
// This fills a ranges list // This fills a ranges list
private void FindRanges(List<LumpRange> ranges, IDictionary rangeinfos, string rangename, string elementname) private void FindRanges(List<LumpRange> ranges, IDictionary rangeinfos, string rangename, string elementname)
{ {

View file

@ -30,6 +30,6 @@ using CodeImp.DoomBuilder;
// Build Number // Build Number
// Revision // Revision
// //
[assembly: AssemblyVersion("2.3.0.2837")] [assembly: AssemblyVersion("2.3.0.2839")]
[assembly: NeutralResourcesLanguageAttribute("en")] [assembly: NeutralResourcesLanguageAttribute("en")]
[assembly: AssemblyHash("30a5edf")] [assembly: AssemblyHash("a705e47")]

View file

@ -212,8 +212,11 @@ namespace CodeImp.DoomBuilder.Windows
} }
} }
// [ZZ] dispose of wadfile
wadfile.Dispose();
//mxd. Bail out if still no dice... //mxd. Bail out if still no dice...
if(config.SelectedIndex == -1 || mapslist.Items.Count == 0) if (config.SelectedIndex == -1 || mapslist.Items.Count == 0)
{ {
General.ShowWarningMessage("Unable to find maps using any game configuration.\nDoes this wad contain any maps at all?..", MessageBoxButtons.OK); General.ShowWarningMessage("Unable to find maps using any game configuration.\nDoes this wad contain any maps at all?..", MessageBoxButtons.OK);
cancel_Click(this, EventArgs.Empty); cancel_Click(this, EventArgs.Empty);

View file

@ -29,5 +29,5 @@ using System.Resources;
// Build Number // Build Number
// Revision // Revision
// //
[assembly: AssemblyVersion("2.3.0.2837")] [assembly: AssemblyVersion("2.3.0.2839")]
[assembly: NeutralResourcesLanguageAttribute("en")] [assembly: NeutralResourcesLanguageAttribute("en")]