From 070a6565e058829691c61d84ebe8094b7d72c570 Mon Sep 17 00:00:00 2001 From: wfowler Date: Mon, 19 Apr 2021 00:33:14 -0600 Subject: [PATCH] Fix incorrect and missing data access in StaticProp. Add constructor to StaticProp to copy another StaticProp using any given format. --- LibBSP/Source/Structs/BSP/StaticProp.cs | 96 ++++++++++++++++++++----- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/LibBSP/Source/Structs/BSP/StaticProp.cs b/LibBSP/Source/Structs/BSP/StaticProp.cs index f916d05..7a12adf 100644 --- a/LibBSP/Source/Structs/BSP/StaticProp.cs +++ b/LibBSP/Source/Structs/BSP/StaticProp.cs @@ -89,16 +89,17 @@ namespace LibBSP { return new Vector3(BitConverter.ToSingle(Data, 0), BitConverter.ToSingle(Data, 4), BitConverter.ToSingle(Data, 8)); } default: { - return new Vector3(float.NaN, float.NaN, float.NaN); + return new Vector3(0, 0, 0); } } } default: { - return new Vector3(float.NaN, float.NaN, float.NaN); + return new Vector3(0, 0, 0); } } } set { + byte[] bytes = value.GetBytes(); switch (MapType) { case MapType.Source17: case MapType.Source18: @@ -123,7 +124,7 @@ namespace LibBSP { case 10: case 11: case 12: { - value.GetBytes().CopyTo(Data, 0); + bytes.CopyTo(Data, 0); break; } } @@ -165,16 +166,17 @@ namespace LibBSP { return new Vector3(BitConverter.ToSingle(Data, 12), BitConverter.ToSingle(Data, 16), BitConverter.ToSingle(Data, 20)); } default: { - return new Vector3(float.NaN, float.NaN, float.NaN); + return new Vector3(0, 0, 0); } } } default: { - return new Vector3(float.NaN, float.NaN, float.NaN); + return new Vector3(0, 0, 0); } } } set { + byte[] bytes = value.GetBytes(); switch (MapType) { case MapType.Source17: case MapType.Source18: @@ -199,7 +201,7 @@ namespace LibBSP { case 10: case 11: case 12: { - value.GetBytes().CopyTo(Data, 12); + bytes.CopyTo(Data, 12); break; } } @@ -863,9 +865,9 @@ namespace LibBSP { } case 9: { if (Data.Length == 76) { - bytes.CopyTo(Data, 36); + bytes.CopyTo(Data, 44); } else { - bytes.CopyTo(Data, 32); + bytes.CopyTo(Data, 40); } break; } @@ -914,12 +916,12 @@ namespace LibBSP { } } default: { - return new Vector3(float.NaN, float.NaN, float.NaN); + return new Vector3(0, 0, 0); } } } default: { - return new Vector3(float.NaN, float.NaN, float.NaN); + return new Vector3(0, 0, 0); } } } @@ -953,9 +955,9 @@ namespace LibBSP { } case 9: { if (Data.Length == 76) { - value.GetBytes().CopyTo(Data, 48); + bytes.CopyTo(Data, 48); } else { - value.GetBytes().CopyTo(Data, 44); + bytes.CopyTo(Data, 44); } break; } @@ -1537,6 +1539,7 @@ namespace LibBSP { } } set { + byte[] bytes = value.GetBytes(); switch (MapType) { case MapType.Source17: case MapType.Source18: @@ -1557,14 +1560,14 @@ namespace LibBSP { case 10: case 11: case 12: { - value.GetBytes().CopyTo(Data, 64); + bytes.CopyTo(Data, 64); break; } case 9: { if (Data.Length == 76) { - value.GetBytes().CopyTo(Data, 69); + bytes.CopyTo(Data, 69); } else { - value.GetBytes().CopyTo(Data, 64); + bytes.CopyTo(Data, 64); } break; } @@ -1666,11 +1669,14 @@ namespace LibBSP { case 5: case 6: { if (Data.Length > 128) { + // Zero out the bytes for (int i = 0; i < 128; ++i) { Data[Data.Length - i - 1] = 0; } - byte[] strBytes = Encoding.ASCII.GetBytes(value); - Array.Copy(strBytes, 0, Data, Data.Length - 128, Math.Min(strBytes.Length, 127)); + if (value != null) { + byte[] strBytes = Encoding.ASCII.GetBytes(value); + Array.Copy(strBytes, 0, Data, Data.Length - 128, Math.Min(strBytes.Length, 127)); + } } break; } @@ -1695,6 +1701,62 @@ namespace LibBSP { Data = data; Parent = parent; } + + /// + /// Creates a new by copying the fields in , using + /// to get and + /// to use when creating the new . + /// If the 's 's is different from + /// the one from , it does not matter, because fields are copied by name. + /// + /// The to copy. + /// + /// The to use as the of the new . + /// Use null to use the 's instead. + /// + public StaticProp(StaticProp source, ILump parent) { + Parent = parent; + + if (parent != null && parent.Bsp != null) { + if (source.Parent != null && source.Parent.Bsp != null && source.Parent.Bsp.version == parent.Bsp.version && source.LumpVersion == parent.LumpInfo.version) { + Data = new byte[source.Data.Length]; + Array.Copy(source.Data, Data, source.Data.Length); + return; + } else { + //Data = new byte[GetStructLength(parent.Bsp.version, parent.LumpInfo.version)]; + } + } else { + //if (source.Parent?.Bsp != null) { + // Data = new byte[GetStructLength(source.Parent.Bsp.version, source.Parent.LumpInfo.version)]; + //} else { + // Data = new byte[GetStructLength(MapType.Undefined, 0)]; + //} + } + + Data = new byte[192]; // Maximum known length. GetStructLength doesn't have enough information currently. + + Origin = source.Origin; + Angles = source.Angles; + ModelIndex = source.ModelIndex; + FirstLeafIndexIndex = source.FirstLeafIndexIndex; + NumLeafIndices = source.NumLeafIndices; + Solidity = source.Solidity; + Flags = source.Flags; + Skin = source.Skin; + MinimumFadeDistance = source.MinimumFadeDistance; + MaximumFadeDistance = source.MaximumFadeDistance; + LightingOrigin = source.LightingOrigin; + ForcedFadeScale = source.ForcedFadeScale; + MinimumDirectXLevel = source.MinimumDirectXLevel; + MaximumDirectXLevel = source.MaximumDirectXLevel; + MinimumCPULevel = source.MinimumCPULevel; + MaximumCPULevel = source.MaximumCPULevel; + MinimumGPULevel = source.MinimumGPULevel; + MaximumGPULevel = source.MaximumGPULevel; + DiffuseModulaton = source.DiffuseModulaton; + Scale = source.Scale; + Name = source.Name; + } /// /// Factory method to parse a byte array into a object.