From 2aedd732d3aeecdd40ef57c4504caa793b0f961f Mon Sep 17 00:00:00 2001 From: codeimp Date: Fri, 9 Jan 2009 21:25:15 +0000 Subject: [PATCH] added checks to allow opening maps with missing sidedefs, sectors or vertices (in these cases, the element requiring the missing element will be removed from the map during loading) --- Source/IO/DoomMapSetIO.cs | 101 +++++++++++++++++++---------- Source/IO/HexenMapSetIO.cs | 101 +++++++++++++++++++---------- Source/IO/UniversalStreamReader.cs | 53 +++++++++++---- 3 files changed, 176 insertions(+), 79 deletions(-) diff --git a/Source/IO/DoomMapSetIO.cs b/Source/IO/DoomMapSetIO.cs index df6712d2..452e4833 100644 --- a/Source/IO/DoomMapSetIO.cs +++ b/Source/IO/DoomMapSetIO.cs @@ -272,43 +272,78 @@ namespace CodeImp.DoomBuilder.IO if(int.TryParse(f.Key, out fnum)) stringflags[f.Key] = ((flags & fnum) == fnum); } - // Create new item - l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); - l.Update(stringflags, 0, tag, action, new int[Linedef.NUM_ARGS]); - l.UpdateCache(); - - // Line has a front side? - if(s1 != ushort.MaxValue) + // Create new linedef + if(vertexlink.ContainsKey(v1) && vertexlink.ContainsKey(v2)) { - // Read front sidedef - sidedefsmem.Seek(s1 * 30, SeekOrigin.Begin); - offsetx = readside.ReadInt16(); - offsety = readside.ReadInt16(); - thigh = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - tlow = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - tmid = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - sc = readside.ReadUInt16(); + l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); + l.Update(stringflags, 0, tag, action, new int[Linedef.NUM_ARGS]); + l.UpdateCache(); - // Create front sidedef - s = map.CreateSidedef(l, true, sectorlink[sc]); - s.Update(offsetx, offsety, thigh, tmid, tlow); + // Line has a front side? + if(s1 != ushort.MaxValue) + { + // Read front sidedef + if((s1 * 30L) <= (sidedefsmem.Length - 30L)) + { + sidedefsmem.Seek(s1 * 30, SeekOrigin.Begin); + offsetx = readside.ReadInt16(); + offsety = readside.ReadInt16(); + thigh = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + tlow = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + tmid = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + sc = readside.ReadUInt16(); + + // Create front sidedef + if(sectorlink.ContainsKey(sc)) + { + s = map.CreateSidedef(l, true, sectorlink[sc]); + s.Update(offsetx, offsety, thigh, tmid, tlow); + } + else + { + General.WriteLogLine("WARNING: Sidedef references invalid sector " + sc + "! Sidedef has been removed."); + } + } + else + { + General.WriteLogLine("WARNING: Linedef references invalid sidedef! Sidedef has been removed."); + } + } + + // Line has a back side? + if(s2 != ushort.MaxValue) + { + // Read back sidedef + if((s2 * 30L) <= (sidedefsmem.Length - 30L)) + { + sidedefsmem.Seek(s2 * 30, SeekOrigin.Begin); + offsetx = readside.ReadInt16(); + offsety = readside.ReadInt16(); + thigh = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + tlow = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + tmid = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + sc = readside.ReadUInt16(); + + // Create back sidedef + if(sectorlink.ContainsKey(sc)) + { + s = map.CreateSidedef(l, false, sectorlink[sc]); + s.Update(offsetx, offsety, thigh, tmid, tlow); + } + else + { + General.WriteLogLine("WARNING: Sidedef references invalid sector " + sc + "! Sidedef has been removed."); + } + } + else + { + General.WriteLogLine("WARNING: Linedef references invalid sidedef! Sidedef has been removed."); + } + } } - - // Line has a back side? - if(s2 != ushort.MaxValue) + else { - // Read back sidedef - sidedefsmem.Seek(s2 * 30, SeekOrigin.Begin); - offsetx = readside.ReadInt16(); - offsety = readside.ReadInt16(); - thigh = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - tlow = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - tmid = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - sc = readside.ReadUInt16(); - - // Create back sidedef - s = map.CreateSidedef(l, false, sectorlink[sc]); - s.Update(offsetx, offsety, thigh, tmid, tlow); + General.WriteLogLine("WARNING: Linedef references one or more invalid vertices! Linedef has been removed."); } } diff --git a/Source/IO/HexenMapSetIO.cs b/Source/IO/HexenMapSetIO.cs index 6e60a421..f20a593a 100644 --- a/Source/IO/HexenMapSetIO.cs +++ b/Source/IO/HexenMapSetIO.cs @@ -287,43 +287,78 @@ namespace CodeImp.DoomBuilder.IO if(int.TryParse(f.Key, out fnum)) stringflags[f.Key] = ((flags & fnum) == fnum); } - // Create new item - l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); - l.Update(stringflags, (flags & manager.Config.LinedefActivationsFilter), 0, action, args); - l.UpdateCache(); - - // Line has a front side? - if(s1 != ushort.MaxValue) + // Create new linedef + if(vertexlink.ContainsKey(v1) && vertexlink.ContainsKey(v2)) { - // Read front sidedef - sidedefsmem.Seek(s1 * 30, SeekOrigin.Begin); - offsetx = readside.ReadInt16(); - offsety = readside.ReadInt16(); - thigh = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - tlow = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - tmid = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - sc = readside.ReadUInt16(); + l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); + l.Update(stringflags, (flags & manager.Config.LinedefActivationsFilter), 0, action, args); + l.UpdateCache(); - // Create front sidedef - s = map.CreateSidedef(l, true, sectorlink[sc]); - s.Update(offsetx, offsety, thigh, tmid, tlow); + // Line has a front side? + if(s1 != ushort.MaxValue) + { + // Read front sidedef + sidedefsmem.Seek(s1 * 30, SeekOrigin.Begin); + if((s1 * 30L) <= (sidedefsmem.Length - 30L)) + { + offsetx = readside.ReadInt16(); + offsety = readside.ReadInt16(); + thigh = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + tlow = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + tmid = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + sc = readside.ReadUInt16(); + + // Create front sidedef + if(sectorlink.ContainsKey(sc)) + { + s = map.CreateSidedef(l, true, sectorlink[sc]); + s.Update(offsetx, offsety, thigh, tmid, tlow); + } + else + { + General.WriteLogLine("WARNING: Sidedef references invalid sector " + sc + "! Sidedef has been removed."); + } + } + else + { + General.WriteLogLine("WARNING: Linedef references invalid sidedef! Sidedef has been removed."); + } + } + + // Line has a back side? + if(s2 != ushort.MaxValue) + { + // Read back sidedef + sidedefsmem.Seek(s2 * 30, SeekOrigin.Begin); + if((s2 * 30L) <= (sidedefsmem.Length - 30L)) + { + offsetx = readside.ReadInt16(); + offsety = readside.ReadInt16(); + thigh = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + tlow = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + tmid = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); + sc = readside.ReadUInt16(); + + // Create back sidedef + if(sectorlink.ContainsKey(sc)) + { + s = map.CreateSidedef(l, false, sectorlink[sc]); + s.Update(offsetx, offsety, thigh, tmid, tlow); + } + else + { + General.WriteLogLine("WARNING: Sidedef references invalid sector " + sc + "! Sidedef has been removed."); + } + } + else + { + General.WriteLogLine("WARNING: Linedef references invalid sidedef! Sidedef has been removed."); + } + } } - - // Line has a back side? - if(s2 != ushort.MaxValue) + else { - // Read back sidedef - sidedefsmem.Seek(s2 * 30, SeekOrigin.Begin); - offsetx = readside.ReadInt16(); - offsety = readside.ReadInt16(); - thigh = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - tlow = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - tmid = Lump.MakeNormalName(readside.ReadBytes(8), WAD.ENCODING); - sc = readside.ReadUInt16(); - - // Create back sidedef - s = map.CreateSidedef(l, false, sectorlink[sc]); - s.Update(offsetx, offsety, thigh, tmid, tlow); + General.WriteLogLine("WARNING: Linedef references one or more invalid vertices! Linedef has been removed."); } } diff --git a/Source/IO/UniversalStreamReader.cs b/Source/IO/UniversalStreamReader.cs index 3cf786e4..b7011e0e 100644 --- a/Source/IO/UniversalStreamReader.cs +++ b/Source/IO/UniversalStreamReader.cs @@ -232,17 +232,37 @@ namespace CodeImp.DoomBuilder.IO foreach(LinedefActivateInfo activate in General.Map.Config.LinedefActivates) stringflags[activate.Key] = GetCollectionEntry(lc, activate.Key, false, false); - // Create new item - Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); - l.Update(stringflags, 0, tag, special, args); - l.UpdateCache(); + // Create new linedef + if(vertexlink.ContainsKey(v1) && vertexlink.ContainsKey(v2)) + { + Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); + l.Update(stringflags, 0, tag, special, args); + l.UpdateCache(); - // Custom fields - ReadCustomFields(lc, l, "linedef"); + // Custom fields + ReadCustomFields(lc, l, "linedef"); - // Read sidedefs and connect them to the line - if(s1 > -1) ReadSidedef(map, sidescolls[s1], l, true, sectorlink); - if(s2 > -1) ReadSidedef(map, sidescolls[s2], l, false, sectorlink); + // Read sidedefs and connect them to the line + if(s1 > -1) + { + if(s1 < sidescolls.Count) + ReadSidedef(map, sidescolls[s1], l, true, sectorlink); + else + General.WriteLogLine("WARNING: Linedef references invalid sidedef! Sidedef has been removed."); + } + + if(s2 > -1) + { + if(s2 < sidescolls.Count) + ReadSidedef(map, sidescolls[s2], l, false, sectorlink); + else + General.WriteLogLine("WARNING: Linedef references invalid sidedef! Sidedef has been removed."); + } + } + else + { + General.WriteLogLine("WARNING: Linedef references one or more invalid vertices! Linedef has been removed."); + } } } @@ -259,11 +279,18 @@ namespace CodeImp.DoomBuilder.IO int sector = GetCollectionEntry(sc, "sector", true, 0); // Create sidedef - Sidedef s = map.CreateSidedef(ld, front, sectorlink[sector]); - s.Update(offsetx, offsety, thigh, tmid, tlow); + if(sectorlink.ContainsKey(sector)) + { + Sidedef s = map.CreateSidedef(ld, front, sectorlink[sector]); + s.Update(offsetx, offsety, thigh, tmid, tlow); - // Custom fields - ReadCustomFields(sc, s, "sidedef"); + // Custom fields + ReadCustomFields(sc, s, "sidedef"); + } + else + { + General.WriteLogLine("WARNING: Sidedef references invalid sector " + sector + "! Sidedef has been removed."); + } } // This reads the sectors