From 07d715b332acef4674a1d675cd99c624b5350399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sat, 12 Sep 2020 03:01:05 +0200 Subject: [PATCH 01/27] Remove netstandard2.0 errors --- GBX.NET.Json/GBX.NET.Json.csproj | 18 +- GBX.NET/Chunk.cs | 12 +- .../Engines/Game/CGameCtnAnchoredObject.cs | 10 +- GBX.NET/Engines/Game/CGameCtnChallenge.cs | 137 +++-- GBX.NET/Engines/Game/CGameCtnGhost.cs | 4 +- .../Engines/Game/CGameCtnMacroBlockInfo.cs | 466 +++++++------- .../Game/CGameCtnMediaBlockCameraCustom.cs | 566 +++++++++--------- .../Game/CGameCtnMediaBlockCameraPath.cs | 394 ++++++------ .../Game/CGameCtnMediaBlockTransitionFade.cs | 2 +- .../Engines/Game/CGameCtnMediaClipGroup.cs | 6 +- GBX.NET/Engines/Game/CGameCtnReplayRecord.cs | 10 +- GBX.NET/Engines/Game/CGameGhost.cs | 258 ++++---- GBX.NET/Engines/GameData/CGameItemModel.cs | 2 +- GBX.NET/Engines/Plug/CPlugCrystal.cs | 18 +- .../Engines/Script/CScriptTraitsMetadata.cs | 28 +- GBX.NET/FreeBlock.cs | 6 +- GBX.NET/GBX.NET.csproj | 3 +- GBX.NET/GameBox.cs | 230 +++---- GBX.NET/GameBoxBody.cs | 32 +- GBX.NET/GameBoxHeader.cs | 173 +++--- GBX.NET/GameBoxReader.cs | 21 +- GBX.NET/GameBoxReaderWriter.cs | 172 +++--- GBX.NET/GameBoxWriter.cs | 7 +- GBX.NET/Int3.cs | 2 +- GBX.NET/Item.cs | 6 +- GBX.NET/Log.cs | 4 +- GBX.NET/Node.cs | 92 +-- GBX.NET/SkippableChunk.cs | 27 +- GBX.NET/Vec2.cs | 33 + GBX.NET/Vec3.cs | 37 ++ IslandConverter/ConverterForm.Designer.cs | 121 ++-- IslandConverter/ConverterForm.cs | 5 +- IslandConverter/ConverterForm.resx | 75 ++- IslandConverter/IslandConverter.cs | 154 +++-- IslandConverter/IslandConverter.csproj | 11 +- IslandConverter/Program.cs | 2 +- 36 files changed, 1678 insertions(+), 1466 deletions(-) create mode 100644 GBX.NET/Vec2.cs create mode 100644 GBX.NET/Vec3.cs diff --git a/GBX.NET.Json/GBX.NET.Json.csproj b/GBX.NET.Json/GBX.NET.Json.csproj index 974dacffc..fb555fd79 100644 --- a/GBX.NET.Json/GBX.NET.Json.csproj +++ b/GBX.NET.Json/GBX.NET.Json.csproj @@ -1,7 +1,16 @@  - netstandard2.1 + netstandard2.0 + 0.1.0 + true + true + A wrapper for better JSON serialization of GBX, useful for comparing data. + License.txt + https://github.com/BigBang1112/gbx-net + https://github.com/BigBang1112/gbx-net + gbx, trackmania, maniaplanet, gamebox, net, chunk, x86 + BigBang1112 @@ -20,4 +29,11 @@ + + + True + + + + diff --git a/GBX.NET/Chunk.cs b/GBX.NET/Chunk.cs index e4e4a3bda..caebc50d6 100644 --- a/GBX.NET/Chunk.cs +++ b/GBX.NET/Chunk.cs @@ -177,11 +177,13 @@ public byte[] ToByteArray() lookbackable = l; } - using var ms = new MemoryStream(); - using var w = new GameBoxWriter(ms, lookbackable); - var rw = new GameBoxReaderWriter(w); - ReadWrite(Node, rw); - return ms.ToArray(); + using (var ms = new MemoryStream()) + using (var w = new GameBoxWriter(ms, lookbackable)) + { + var rw = new GameBoxReaderWriter(w); + ReadWrite(Node, rw);System.Globalization.CultureInfo.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; + return ms.ToArray(); + } } } } diff --git a/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs b/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs index 8069732c1..a26c0e7db 100644 --- a/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs +++ b/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs @@ -13,11 +13,11 @@ public class CGameCtnAnchoredObject : Node { public Meta ItemModel { get; set; } - public Vector3? PitchYawRoll { get; set; } + public Vec3? PitchYawRoll { get; set; } public Byte3 BlockUnitCoord { get; set; } - public Vector3? AbsolutePositionInMap { get; set; } + public Vec3? AbsolutePositionInMap { get; set; } public CGameWaypointSpecialProperty WaypointSpecialProperty { get; set; } @@ -25,7 +25,7 @@ public class CGameCtnAnchoredObject : Node public float Scale { get; set; } = 1; - public Vector3 PivotPosition { get; set; } + public Vec3 PivotPosition { get; set; } public int Variant { @@ -66,8 +66,8 @@ public class Chunk03101002 : Chunk public int Version { get; set; } = 7; public int Unknown1 { get; set; } = -1; - public Vector3 Unknown3 { get; set; } - public Vector3 Unknown4 { get; set; } + public Vec3 Unknown3 { get; set; } + public Vec3 Unknown4 { get; set; } public override void Read(CGameCtnAnchoredObject n, GameBoxReader r, GameBoxWriter unknownW) { diff --git a/GBX.NET/Engines/Game/CGameCtnChallenge.cs b/GBX.NET/Engines/Game/CGameCtnChallenge.cs index 6c240b52f..af55b0fdb 100644 --- a/GBX.NET/Engines/Game/CGameCtnChallenge.cs +++ b/GBX.NET/Engines/Game/CGameCtnChallenge.cs @@ -161,8 +161,8 @@ public enum AILevel : byte private PlayMode? mode; private byte[] hashedPassword; private uint? crc32; - private Vector3? thumbnailPosition; - private Vector3? thumbnailPitchYawRoll; + private Vec3? thumbnailPosition; + private Vec3? thumbnailPitchYawRoll; private float? thumbnailFOV; private List items; private CScriptTraitsMetadata metadataTraits; @@ -244,12 +244,12 @@ public string Collection /// /// Origin of the map. /// - public Vector2? MapOrigin { get; set; } + public Vec2? MapOrigin { get; set; } /// /// Target of the map. /// - public Vector2? MapTarget { get; set; } + public Vec2? MapTarget { get; set; } /// /// Title pack the map was built in. @@ -419,7 +419,7 @@ public uint? CRC32 /// /// Position of the thumnail camera. /// - public Vector3? ThumbnailPosition + public Vec3? ThumbnailPosition { get { @@ -432,7 +432,7 @@ public Vector3? ThumbnailPosition /// /// Pitch, yaw and roll of the thumbnail camera in radians. /// - public Vector3? ThumbnailPitchYawRoll + public Vec3? ThumbnailPitchYawRoll { get { @@ -568,7 +568,7 @@ public void NewPassword(string password) HashedPassword = md5.ComputeHash(Encoding.UTF8.GetBytes(password)); Crc32 crc32 = new Crc32(); - crc32.Update(Encoding.ASCII.GetBytes("0x" + BitConverter.ToInt16(HashedPassword).ToString() + "???" + MapUid)); + crc32.Update(Encoding.ASCII.GetBytes("0x" + BitConverter.ToInt16(HashedPassword, 0).ToString() + "???" + MapUid)); CRC32 = Convert.ToUInt32(crc32.Value); } @@ -580,7 +580,7 @@ public void CrackPassword() RemoveChunk(); } - public void PlaceItem(Meta itemModel, Vector3 absolutePosition, Vector3 pitchYawRoll, Byte3 blockUnitCoord, Vector3 offsetPivot, int variant = 0) + public void PlaceItem(Meta itemModel, Vec3 absolutePosition, Vec3 pitchYawRoll, Byte3 blockUnitCoord, Vec3 offsetPivot, int variant = 0) { var chunkItems = CreateChunk(); @@ -599,7 +599,7 @@ public void PlaceItem(Meta itemModel, Vector3 absolutePosition, Vector3 pitchYaw Items.Add(it); } - public FreeBlock PlaceFreeBlock(string name, Vector3 position, Vector3 pitchYawRoll) + public FreeBlock PlaceFreeBlock(string name, Vec3 position, Vec3 pitchYawRoll) { var block = new Block(name, Direction.North, (0, 0, 0), 0x20000000, null, null, null); var freeBlock = new FreeBlock(block) @@ -706,7 +706,7 @@ void ConvertMediaTrack(CGameCtnMediaTrack node) return true; } - public void OffsetMediaTrackerCameras(Vector3 offset) + public void OffsetMediaTrackerCameras(Vec3 offset) { OffsetCamerasInClip(ClipIntro); OffsetCamerasInClipGroup(ClipGroupInGame); @@ -1160,12 +1160,12 @@ public class Chunk03043003 : HeaderChunk /// /// Origin of the map. Can be if < . /// - public Vector2? MapOrigin { get; set; } + public Vec2? MapOrigin { get; set; } /// /// Target of the map. Can be if < . /// - public Vector2? MapTarget { get; set; } + public Vec2? MapTarget { get; set; } /// /// Name of the map type script. @@ -1327,30 +1327,32 @@ public override void ReadWrite(GameBoxReaderWriter rw) if (Version != 0) { - using var ms = new MemoryStream(); - if (rw.Mode == GameBoxReaderWriterMode.Write) + using (var ms = new MemoryStream()) { - Thumbnail.Result.RotateFlip(RotateFlipType.Rotate180FlipX); - ExportThumbnail(ms, ImageFormat.Jpeg); - } + if (rw.Mode == GameBoxReaderWriterMode.Write) + { + Thumbnail.Result.RotateFlip(RotateFlipType.Rotate180FlipX); + ExportThumbnail(ms, ImageFormat.Jpeg); + } - var thumbnailSize = rw.Int32((int)ms.Length); - rw.Bytes(Encoding.UTF8.GetBytes(""), "".Length); // Because the string is purely ASCII anyway, Length is usable - var thumbnailData = rw.Bytes(ms.ToArray(), thumbnailSize); - rw.Bytes(Encoding.UTF8.GetBytes(""), "".Length); - rw.Bytes(Encoding.UTF8.GetBytes(""), "".Length); - Comments = rw.String(Comments); - rw.Bytes(Encoding.UTF8.GetBytes(""), "".Length); + var thumbnailSize = rw.Int32((int)ms.Length); + rw.Bytes(Encoding.UTF8.GetBytes(""), "".Length); // Because the string is purely ASCII anyway, Length is usable + var thumbnailData = rw.Bytes(ms.ToArray(), thumbnailSize); + rw.Bytes(Encoding.UTF8.GetBytes(""), "".Length); + rw.Bytes(Encoding.UTF8.GetBytes(""), "".Length); + Comments = rw.String(Comments); + rw.Bytes(Encoding.UTF8.GetBytes(""), "".Length); - if (rw.Mode == GameBoxReaderWriterMode.Read && thumbnailData.Length > 0) - { - Thumbnail = Task.Run(() => + if (rw.Mode == GameBoxReaderWriterMode.Read && thumbnailData.Length > 0) { - msT = new MemoryStream(thumbnailData); - var bitmap = (Bitmap)Image.FromStream(msT); - bitmap.RotateFlip(RotateFlipType.Rotate180FlipX); - return bitmap; - }); + Thumbnail = Task.Run(() => + { + msT = new MemoryStream(thumbnailData); + var bitmap = (Bitmap)Image.FromStream(msT); + bitmap.RotateFlip(RotateFlipType.Rotate180FlipX); + return bitmap; + }); + } } } } @@ -1917,9 +1919,9 @@ public override void ReadWrite(CGameCtnChallenge n, GameBoxReaderWriter rw) public class Chunk03043027 : Chunk { public bool ArchiveGmCamVal { get; set; } - public Vector3? Vec1 { get; set; } - public Vector3? Vec2 { get; set; } - public Vector3? Vec3 { get; set; } + public Vec3? Vec1 { get; set; } + public Vec3? Vec2 { get; set; } + public Vec3? Vec3 { get; set; } public override void ReadWrite(CGameCtnChallenge n, GameBoxReaderWriter rw) { @@ -2077,10 +2079,10 @@ public override void Read(CGameCtnChallenge n, GameBoxReader r, GameBoxWriter un n.LightmapCache = Task.Run(() => { - using var ms = new MemoryStream(data); - using var zlib = new InflaterInputStream(ms); - using var gbxr = new GameBoxReader(zlib); - return (CHmsLightMapCache)Parse(Node.Body, 0x06022000, gbxr); + using (var ms = new MemoryStream(data)) + using (var zlib = new InflaterInputStream(ms)) + using (var gbxr = new GameBoxReader(zlib)) + return (CHmsLightMapCache)Parse(Node.Body, 0x06022000, gbxr); }); } } @@ -2135,22 +2137,24 @@ public override void Write(CGameCtnChallenge n, GameBoxWriter w, GameBoxReader u { w.Write(Unknown1); - using var itemMs = new MemoryStream(); - using var wr = new GameBoxWriter(itemMs, w.Lookbackable); + using (var itemMs = new MemoryStream()) + using (var wr = new GameBoxWriter(itemMs, w.Lookbackable)) + { - wr.Write(Unknown2); - wr.Write(n.items.Count); + wr.Write(Unknown2); + wr.Write(n.items.Count); - foreach (var item in n.items) - { - wr.Write(item.ID); - item.Write(wr); - } + foreach (var item in n.items) + { + wr.Write(item.ID); + item.Write(wr); + } - wr.Write(Unknown3); + wr.Write(Unknown3); - w.Write((int)itemMs.Length); - w.Write(itemMs.ToArray(), 0, (int)itemMs.Length); + w.Write((int)itemMs.Length); + w.Write(itemMs.ToArray(), 0, (int)itemMs.Length); + } } } } @@ -2206,10 +2210,9 @@ public override void Read(CGameCtnChallenge n, GameBoxReader r, GameBoxWriter un n.Genealogies = Task.Run(() => { - using var ms = new MemoryStream(Data); - using var r2 = new GameBoxReader(ms, this); - - return ParseArray(this, r2); + using (var ms = new MemoryStream(Data)) + using (var r2 = new GameBoxReader(ms, this)) + return ParseArray(this, r2); }); } @@ -2217,17 +2220,19 @@ public override void Write(CGameCtnChallenge n, GameBoxWriter w, GameBoxReader u { w.Write(Version); - using var ms = new MemoryStream(); - using var w2 = new GameBoxWriter(ms); - - w2.Write(n.Genealogies.Result, x => + using (var ms = new MemoryStream()) + using (var w2 = new GameBoxWriter(ms)) { - w2.Write(0x0311D000); - x.Write(w2); - }); - w.Write((int)ms.Length); - w.Write(ms.ToArray()); + w2.Write(n.Genealogies.Result, x => + { + w2.Write(0x0311D000); + x.Write(w2); + }); + + w.Write((int)ms.Length); + w.Write(ms.ToArray()); + } } } @@ -2411,7 +2416,7 @@ public class Chunk0304305F : SkippableChunk /// /// List of vectors that can't be directly figured out without information from . /// - public List Vectors { get; set; } = new List(); + public List Vectors { get; set; } = new List(); [IgnoreDataMember] public ReadOnlyCollection FreeBlocks @@ -2449,7 +2454,7 @@ public override void Read(CGameCtnChallenge n, GameBoxReader r, GameBoxWriter un Vectors.Clear(); while (r.BaseStream.Position < r.BaseStream.Length) - Vectors.Add(new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle())); + Vectors.Add(new Vec3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle())); } public override void Write(CGameCtnChallenge n, GameBoxWriter w, GameBoxReader unknownR) diff --git a/GBX.NET/Engines/Game/CGameCtnGhost.cs b/GBX.NET/Engines/Game/CGameCtnGhost.cs index e6dd06f90..4d293be20 100644 --- a/GBX.NET/Engines/Game/CGameCtnGhost.cs +++ b/GBX.NET/Engines/Game/CGameCtnGhost.cs @@ -23,7 +23,7 @@ public class CGameCtnGhost : CGameGhost private string recordingContext; private TimeSpan? raceTime; private int? respawns; - private Vector3? lightTrailColor; + private Vec3? lightTrailColor; private int? stuntScore; private TimeSpan[] checkpoints; @@ -101,7 +101,7 @@ public int? Respawns set => respawns = value; } - public Vector3? LightTrailColor + public Vec3? LightTrailColor { get { diff --git a/GBX.NET/Engines/Game/CGameCtnMacroBlockInfo.cs b/GBX.NET/Engines/Game/CGameCtnMacroBlockInfo.cs index f5b9a3d15..aa0d3c128 100644 --- a/GBX.NET/Engines/Game/CGameCtnMacroBlockInfo.cs +++ b/GBX.NET/Engines/Game/CGameCtnMacroBlockInfo.cs @@ -1,280 +1,280 @@ -using GBX.NET.Engines.GameData; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using GBX.NET.Engines.GameData; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// Macroblock (0x0310D000) - /// - [Node(0x0310D000)] - public class CGameCtnMacroBlockInfo : CGameCtnCollector - { - public Block[] Blocks { get; set; } - - public Item[] Items { get; set; } - - public List FreeBlocks { get; set; } = new List(); - - public CGameCtnMacroBlockInfo(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - + /// + [Node(0x0310D000)] + public class CGameCtnMacroBlockInfo : CGameCtnCollector + { + public Block[] Blocks { get; set; } + + public Item[] Items { get; set; } + + public List FreeBlocks { get; set; } = new List(); + + public CGameCtnMacroBlockInfo(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) + { + } - #region Chunks + #region Chunks - #region 0x000 chunk (blocks) + #region 0x000 chunk (blocks) /// /// CGameCtnMacroBlockInfo 0x000 chunk (blocks) - /// - [Chunk(0x0310D000, "blocks")] - public class Chunk0310D000 : Chunk - { - public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) - { - n.Blocks = r.ReadArray(i => - { - Int3? coord = null; - Direction? dir = null; - Vector3? position = null; - Vector3? pitchYawRoll = null; - - var ver = r.ReadInt32(); - var meta = r.ReadMeta(); - int flags = 0; - - if(ver >= 2) - { - if(ver < 5) - { - - } - - flags = r.ReadInt32(); - - if (ver >= 4) - { - if ((flags & (1 << 26)) != 0) // free block - { - position = r.ReadVec3(); - pitchYawRoll = r.ReadVec3(); - } - else - { - coord = (Int3)r.ReadByte3(); - dir = (Direction)r.ReadByte(); - } - } - } - - if (ver >= 3) - r.ReadNodeRef(); - - if (ver >= 4) - r.ReadNodeRef(); - - var block = new Block() { Meta = meta, Coord = coord.GetValueOrDefault(), Direction = dir.GetValueOrDefault(), Flags = flags }; - - if (position.HasValue && pitchYawRoll.HasValue) - { - n.FreeBlocks.Add(new FreeBlock(block) { Position = position.Value, PitchYawRoll = pitchYawRoll.Value }); - return null; - } - - return block; - }).Where(x => x != null).ToArray(); - } + /// + [Chunk(0x0310D000, "blocks")] + public class Chunk0310D000 : Chunk + { + public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) + { + n.Blocks = r.ReadArray(i => + { + Int3? coord = null; + Direction? dir = null; + Vec3? position = null; + Vec3? pitchYawRoll = null; + + var ver = r.ReadInt32(); + var meta = r.ReadMeta(); + int flags = 0; + + if(ver >= 2) + { + if(ver < 5) + { + + } + + flags = r.ReadInt32(); + + if (ver >= 4) + { + if ((flags & (1 << 26)) != 0) // free block + { + position = r.ReadVec3(); + pitchYawRoll = r.ReadVec3(); + } + else + { + coord = (Int3)r.ReadByte3(); + dir = (Direction)r.ReadByte(); + } + } + } + + if (ver >= 3) + r.ReadNodeRef(); + + if (ver >= 4) + r.ReadNodeRef(); + + var block = new Block() { Meta = meta, Coord = coord.GetValueOrDefault(), Direction = dir.GetValueOrDefault(), Flags = flags }; + + if (position.HasValue && pitchYawRoll.HasValue) + { + n.FreeBlocks.Add(new FreeBlock(block) { Position = position.Value, PitchYawRoll = pitchYawRoll.Value }); + return null; + } + + return block; + }).Where(x => x != null).ToArray(); + } } - #endregion + #endregion - #region 0x001 chunk + #region 0x001 chunk /// /// CGameCtnMacroBlockInfo 0x001 chunk /// - [Chunk(0x0310D001)] - public class Chunk0310D001 : Chunk - { - public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) - { - var unknown = r.ReadArray(i => - { - var version = r.ReadInt32(); - r.ReadNodeRef(); - - if(version == 0) - { - r.ReadInt32(); - r.ReadInt32(); - r.ReadInt32(); - } - - r.ReadInt32(); - - return new object(); - }); - } + [Chunk(0x0310D001)] + public class Chunk0310D001 : Chunk + { + public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) + { + var unknown = r.ReadArray(i => + { + var version = r.ReadInt32(); + r.ReadNodeRef(); + + if(version == 0) + { + r.ReadInt32(); + r.ReadInt32(); + r.ReadInt32(); + } + + r.ReadInt32(); + + return new object(); + }); + } } - #endregion + #endregion - #region 0x002 chunk + #region 0x002 chunk /// /// CGameCtnMacroBlockInfo 0x002 chunk /// - [Chunk(0x0310D002)] - public class Chunk0310D002 : Chunk - { - public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) - { - var unknown = r.ReadArray(i => - { - r.ReadInt32(); - var dsgds = r.ReadArray(i => r.ReadMeta()); - - r.ReadInt32(); - r.ReadInt32(); - r.ReadInt32(); - - return new object(); - }); - } + [Chunk(0x0310D002)] + public class Chunk0310D002 : Chunk + { + public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) + { + var unknown = r.ReadArray(i => + { + r.ReadInt32(); + r.ReadArray(j => r.ReadMeta()); + + r.ReadInt32(); + r.ReadInt32(); + r.ReadInt32(); + + return new object(); + }); + } } - #endregion + #endregion - #region 0x006 chunk + #region 0x006 chunk /// /// CGameCtnMacroBlockInfo 0x006 chunk /// - [Chunk(0x0310D006)] - public class Chunk0310D006 : Chunk - { - public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) - { - var version = r.ReadInt32(); - var arrayLength = r.ReadInt32(); - } + [Chunk(0x0310D006)] + public class Chunk0310D006 : Chunk + { + public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) + { + var version = r.ReadInt32(); + var arrayLength = r.ReadInt32(); + } } - #endregion + #endregion - #region 0x008 chunk + #region 0x008 chunk /// /// CGameCtnMacroBlockInfo 0x008 chunk /// - [Chunk(0x0310D008)] - public class Chunk0310D008 : Chunk - { - public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) - { - var version = r.ReadInt32(); - var nodrefs = r.ReadArray(i => r.ReadNodeRef()); - r.ReadArray(2); - } + [Chunk(0x0310D008)] + public class Chunk0310D008 : Chunk + { + public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) + { + var version = r.ReadInt32(); + var nodrefs = r.ReadArray(i => r.ReadNodeRef()); + r.ReadArray(2); + } } - #endregion - - #region 0x00E chunk (items) - - /// - /// CGameCtnMacroBlockInfo 0x00E chunk (items) - /// - [Chunk(0x0310D00E)] - public class Chunk0310D00E : Chunk - { - public int Version { get; set; } - - public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) - { - Version = r.ReadInt32(); - - n.Items = r.ReadArray(i => - { - var v = r.ReadInt32(); - - var meta = r.ReadMeta(); - - Vector3? pitchYawRoll = null; - Vector3? pivotPosition = null; - float? scale = null; - - if (v < 3) - { - var quarterY = r.ReadByte(); - - if (v != 0) - { - var additionalDir = r.ReadByte(); - } - } - else - { - pitchYawRoll = r.ReadVec3(); - } - - var blockCoord = r.ReadInt3(); - r.ReadLookbackString(); - var pos = r.ReadVec3(); - - if (v < 5) - r.ReadInt32(); - if (v < 6) - r.ReadInt32(); - if (v >= 6) - r.ReadInt16(); // 0 - if (v >= 7) - pivotPosition = r.ReadVec3(); - if (v >= 8) - r.ReadNodeRef(); // probably waypoint - if (v >= 9) - scale = r.ReadSingle(); // 1 - if (v >= 10) - r.ReadArray(3); // 0 1 -1 - - return new Item() - { - Meta = meta, - PitchYawRoll = pitchYawRoll, - BlockCoord = blockCoord, - Position = pos, - PivotPosition = pivotPosition, - Scale = scale, - }; - }); - - r.ReadInt32(); - } + #endregion + + #region 0x00E chunk (items) + + /// + /// CGameCtnMacroBlockInfo 0x00E chunk (items) + /// + [Chunk(0x0310D00E)] + public class Chunk0310D00E : Chunk + { + public int Version { get; set; } + + public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) + { + Version = r.ReadInt32(); + + n.Items = r.ReadArray(i => + { + var v = r.ReadInt32(); + + var meta = r.ReadMeta(); + + Vec3? pitchYawRoll = null; + Vec3? pivotPosition = null; + float? scale = null; + + if (v < 3) + { + var quarterY = r.ReadByte(); + + if (v != 0) + { + var additionalDir = r.ReadByte(); + } + } + else + { + pitchYawRoll = r.ReadVec3(); + } + + var blockCoord = r.ReadInt3(); + r.ReadLookbackString(); + var pos = r.ReadVec3(); + + if (v < 5) + r.ReadInt32(); + if (v < 6) + r.ReadInt32(); + if (v >= 6) + r.ReadInt16(); // 0 + if (v >= 7) + pivotPosition = r.ReadVec3(); + if (v >= 8) + r.ReadNodeRef(); // probably waypoint + if (v >= 9) + scale = r.ReadSingle(); // 1 + if (v >= 10) + r.ReadArray(3); // 0 1 -1 + + return new Item() + { + Meta = meta, + PitchYawRoll = pitchYawRoll, + BlockCoord = blockCoord, + Position = pos, + PivotPosition = pivotPosition, + Scale = scale, + }; + }); + + r.ReadInt32(); + } } - #endregion + #endregion - #region 0x00F chunk + #region 0x00F chunk /// /// CGameCtnMacroBlockInfo 0x00F chunk /// - [Chunk(0x0310D00F)] - public class Chunk0310D00F : Chunk - { - public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) - { - var version = r.ReadInt32(); - _ = r.ReadArray(7); - } + [Chunk(0x0310D00F)] + public class Chunk0310D00F : Chunk + { + public override void Read(CGameCtnMacroBlockInfo n, GameBoxReader r, GameBoxWriter unknownW) + { + var version = r.ReadInt32(); + _ = r.ReadArray(7); + } } - #endregion - - #endregion - } -} + #endregion + + #endregion + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraCustom.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraCustom.cs index b04b3e2c9..6aeb45390 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraCustom.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraCustom.cs @@ -1,287 +1,287 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Numerics; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Numerics; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// MediaTracker block (0x030A2000) - /// - [Node(0x030A2000)] - public class CGameCtnMediaBlockCameraCustom : CGameCtnMediaBlockCamera - { - public List Keys { get; set; } = new List(); - - public CGameCtnMediaBlockCameraCustom(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - - #region Chunks - - #region 0x002 chunk - + /// + [Node(0x030A2000)] + public class CGameCtnMediaBlockCameraCustom : CGameCtnMediaBlockCamera + { + public List Keys { get; set; } = new List(); + + public CGameCtnMediaBlockCameraCustom(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) + { + + } + + #region Chunks + + #region 0x002 chunk + /// /// CGameCtnMediaBlockCameraCustom 0x002 chunk - /// - [Chunk(0x030A2002)] - public class Chunk030A2002 : Chunk - { - public override void Read(CGameCtnMediaBlockCameraCustom n, GameBoxReader r, GameBoxWriter unknownW) - { - n.Keys = r.ReadArray(i => - { - var time = r.ReadSingle(); - var a = r.ReadInt32(); // 1 - var b = r.ReadInt32(); // 0 - var c = r.ReadInt32(); // 0 - var position = r.ReadVec3(); - var pitchYawRoll = r.ReadVec3(); // in radians - var fov = r.ReadSingle(); - var d = r.ReadInt32(); // 0 - var e = r.ReadInt32(); // -1 - var f = r.ReadInt32(); // 1 - var g = r.ReadInt32(); // -1 - var targetPosition = r.ReadVec3(); - var leftTangent = r.ReadVec3(); - var rightTangent = r.ReadVec3(); - - return new Key() - { - Time = time, - Position = position, - PitchYawRoll = pitchYawRoll, - FOV = fov, - TargetPosition = targetPosition, - LeftTangent = leftTangent, - RightTangent = rightTangent, - - Unknown = new object[] - { - a, b, c, d, e, f, g - } - }; - }).ToList(); - } - - public override void Write(CGameCtnMediaBlockCameraCustom n, GameBoxWriter w, GameBoxReader unknownR) - { - w.Write(n.Keys?.ToArray(), x => - { - w.Write(x.Time); - w.Write((int)x.Unknown.ElementAtOrDefault(0)); - w.Write((int)x.Unknown.ElementAtOrDefault(1)); - w.Write((int)x.Unknown.ElementAtOrDefault(2)); - w.Write(x.Position); - w.Write(x.PitchYawRoll); - w.Write(x.FOV); - w.Write((int)x.Unknown.ElementAtOrDefault(3)); - w.Write((int)x.Unknown.ElementAtOrDefault(4)); - w.Write((int)x.Unknown.ElementAtOrDefault(5)); - w.Write((int)x.Unknown.ElementAtOrDefault(6)); - w.Write(x.TargetPosition.GetValueOrDefault()); - w.Write(x.LeftTangent); - w.Write(x.RightTangent); - }); - } - } - - #endregion - - #region 0x005 chunk - - /// - /// CGameCtnMediaBlockCameraCustom 0x005 chunk (TMUF) - /// - [Chunk(0x030A2005, "TMUF")] - public class Chunk030A2005 : Chunk - { - public int Version { get; set; } - - public override void Read(CGameCtnMediaBlockCameraCustom n, GameBoxReader r, GameBoxWriter unknownW) - { - n.Keys = r.ReadArray(i => - { - var time = r.ReadSingle(); - var a = r.ReadInt32(); // 1 - var b = r.ReadInt32(); // 0 - var c = r.ReadInt32(); // 0 - var position = r.ReadVec3(); - var pitchYawRoll = r.ReadVec3(); // in radians - var fov = r.ReadSingle(); - var d = r.ReadInt32(); // 0 - var anchor = r.ReadInt32(); // -1 if not set, 0 for local player - var f = r.ReadInt32(); // 1 - var target = r.ReadInt32(); // -1 if not set, 0 for local player - var targetPosition = r.ReadVec3(); - var leftTangent = r.ReadVec3(); - var rightTangent = r.ReadVec3(); - - return new Key() - { - Time = time, - Position = position, - PitchYawRoll = pitchYawRoll, - FOV = fov, - Anchor = anchor, - Target = target, - TargetPosition = targetPosition, - LeftTangent = leftTangent, - RightTangent = rightTangent, - - Unknown = new object[] - { - a, b, c, d, f - } - }; - }).ToList(); - } - - public override void Write(CGameCtnMediaBlockCameraCustom n, GameBoxWriter w, GameBoxReader unknownR) - { - w.Write(n.Keys.ToArray(), x => - { - w.Write(x.Time); - w.Write((int)x.Unknown.ElementAtOrDefault(0)); - w.Write((int)x.Unknown.ElementAtOrDefault(1)); - w.Write((int)x.Unknown.ElementAtOrDefault(2)); - w.Write(x.Position); - w.Write(x.PitchYawRoll); - w.Write(x.FOV); - w.Write((int)x.Unknown.ElementAtOrDefault(3)); - w.Write(x.Anchor); - w.Write((int)x.Unknown.ElementAtOrDefault(4)); - w.Write(x.Target); - w.Write(x.TargetPosition.GetValueOrDefault()); - w.Write(x.LeftTangent); - w.Write(x.RightTangent); - }); - } - } - - #endregion - - #region 0x006 chunk - - /// - /// CGameCtnMediaBlockCameraCustom 0x006 chunk (ManiaPlanet) - /// - [Chunk(0x030A2006, "ManiaPlanet")] - public class Chunk030A2006 : Chunk - { - public int Version { get; set; } = 3; - - /// - /// Constructs a new 0x030A2006 chunk with version 3. - /// - /// - public Chunk030A2006() : this(3) - { - - } - - public Chunk030A2006(int version) - { - Version = version; - } - - public override void Read(CGameCtnMediaBlockCameraCustom n, GameBoxReader r, GameBoxWriter unknownW) - { - Version = r.ReadInt32(); - n.Keys = r.ReadArray(i => - { - var time = r.ReadSingle(); - var a = r.ReadInt32(); // 1 - var anchorRot = r.ReadBoolean(); // 0 - var anchor = r.ReadInt32(); // -1 if not set, 0 for local player - var anchorVis = r.ReadBoolean(); // 1 - var target = r.ReadInt32(); // -1 - var position = r.ReadVec3(); - var pitchYawRoll = r.ReadVec3(); // in radians - var fov = r.ReadSingle(); - var f = r.ReadInt32(); // 0 - var g = r.ReadInt32(); // 0 - var h = r.ReadInt32(); // 0 - var zIndex = r.ReadSingle(); - var leftTangent = r.ReadVec3(); - var ii = r.ReadArray(8); - var rightTangent = r.ReadVec3(); - var j = r.ReadArray(8); - - return new Key() - { - Time = time, - AnchorRot = anchorRot, - Anchor = anchor, - AnchorVis = anchorVis, - Target = target, - Position = position, - PitchYawRoll = pitchYawRoll, - FOV = fov, - ZIndex = zIndex, - LeftTangent = leftTangent, - RightTangent = rightTangent, - - Unknown = new object[] - { - a, f, g, h, ii, j - } - }; - }).ToList(); - } - - public override void Write(CGameCtnMediaBlockCameraCustom n, GameBoxWriter w, GameBoxReader unknownR) - { - w.Write(Version); - - w.Write(n.Keys?.ToArray(), x => - { - w.Write(x.Time); - w.Write((int)x.Unknown.ElementAtOrDefault(0)); - w.Write(x.AnchorRot); - w.Write(x.Anchor); - w.Write(x.AnchorVis); - w.Write(x.Target); - w.Write(x.Position); - w.Write(x.PitchYawRoll); - w.Write(x.FOV); - w.Write((int)x.Unknown.ElementAtOrDefault(1)); - w.Write((int)x.Unknown.ElementAtOrDefault(2)); - w.Write((int)x.Unknown.ElementAtOrDefault(3)); - w.Write(x.ZIndex.GetValueOrDefault()); - w.Write(x.LeftTangent); - w.Write((float[])x.Unknown.ElementAtOrDefault(4)); - w.Write(x.RightTangent); - w.Write((float[])x.Unknown.ElementAtOrDefault(5)); - }); - } - } - - #endregion - - #endregion - - public class Key : MediaBlockKey - { - public Vector3 Position { get; set; } - /// - /// Pitch, yaw and roll in radians. - /// - public Vector3 PitchYawRoll { get; set; } - public float FOV { get; set; } - public float? ZIndex { get; set; } - public Vector3? TargetPosition { get; set; } - public Vector3 LeftTangent { get; set; } - public Vector3 RightTangent { get; set; } - public int Anchor { get; set; } - public int Target { get; set; } - public bool AnchorVis { get; set; } - public bool AnchorRot { get; set; } - - public object[] Unknown { get; set; } - } - } -} + /// + [Chunk(0x030A2002)] + public class Chunk030A2002 : Chunk + { + public override void Read(CGameCtnMediaBlockCameraCustom n, GameBoxReader r, GameBoxWriter unknownW) + { + n.Keys = r.ReadArray(i => + { + var time = r.ReadSingle(); + var a = r.ReadInt32(); // 1 + var b = r.ReadInt32(); // 0 + var c = r.ReadInt32(); // 0 + var position = r.ReadVec3(); + var pitchYawRoll = r.ReadVec3(); // in radians + var fov = r.ReadSingle(); + var d = r.ReadInt32(); // 0 + var e = r.ReadInt32(); // -1 + var f = r.ReadInt32(); // 1 + var g = r.ReadInt32(); // -1 + var targetPosition = r.ReadVec3(); + var leftTangent = r.ReadVec3(); + var rightTangent = r.ReadVec3(); + + return new Key() + { + Time = time, + Position = position, + PitchYawRoll = pitchYawRoll, + FOV = fov, + TargetPosition = targetPosition, + LeftTangent = leftTangent, + RightTangent = rightTangent, + + Unknown = new object[] + { + a, b, c, d, e, f, g + } + }; + }).ToList(); + } + + public override void Write(CGameCtnMediaBlockCameraCustom n, GameBoxWriter w, GameBoxReader unknownR) + { + w.Write(n.Keys?.ToArray(), x => + { + w.Write(x.Time); + w.Write((int)x.Unknown.ElementAtOrDefault(0)); + w.Write((int)x.Unknown.ElementAtOrDefault(1)); + w.Write((int)x.Unknown.ElementAtOrDefault(2)); + w.Write(x.Position); + w.Write(x.PitchYawRoll); + w.Write(x.FOV); + w.Write((int)x.Unknown.ElementAtOrDefault(3)); + w.Write((int)x.Unknown.ElementAtOrDefault(4)); + w.Write((int)x.Unknown.ElementAtOrDefault(5)); + w.Write((int)x.Unknown.ElementAtOrDefault(6)); + w.Write(x.TargetPosition.GetValueOrDefault()); + w.Write(x.LeftTangent); + w.Write(x.RightTangent); + }); + } + } + + #endregion + + #region 0x005 chunk + + /// + /// CGameCtnMediaBlockCameraCustom 0x005 chunk (TMUF) + /// + [Chunk(0x030A2005, "TMUF")] + public class Chunk030A2005 : Chunk + { + public int Version { get; set; } + + public override void Read(CGameCtnMediaBlockCameraCustom n, GameBoxReader r, GameBoxWriter unknownW) + { + n.Keys = r.ReadArray(i => + { + var time = r.ReadSingle(); + var a = r.ReadInt32(); // 1 + var b = r.ReadInt32(); // 0 + var c = r.ReadInt32(); // 0 + var position = r.ReadVec3(); + var pitchYawRoll = r.ReadVec3(); // in radians + var fov = r.ReadSingle(); + var d = r.ReadInt32(); // 0 + var anchor = r.ReadInt32(); // -1 if not set, 0 for local player + var f = r.ReadInt32(); // 1 + var target = r.ReadInt32(); // -1 if not set, 0 for local player + var targetPosition = r.ReadVec3(); + var leftTangent = r.ReadVec3(); + var rightTangent = r.ReadVec3(); + + return new Key() + { + Time = time, + Position = position, + PitchYawRoll = pitchYawRoll, + FOV = fov, + Anchor = anchor, + Target = target, + TargetPosition = targetPosition, + LeftTangent = leftTangent, + RightTangent = rightTangent, + + Unknown = new object[] + { + a, b, c, d, f + } + }; + }).ToList(); + } + + public override void Write(CGameCtnMediaBlockCameraCustom n, GameBoxWriter w, GameBoxReader unknownR) + { + w.Write(n.Keys.ToArray(), x => + { + w.Write(x.Time); + w.Write((int)x.Unknown.ElementAtOrDefault(0)); + w.Write((int)x.Unknown.ElementAtOrDefault(1)); + w.Write((int)x.Unknown.ElementAtOrDefault(2)); + w.Write(x.Position); + w.Write(x.PitchYawRoll); + w.Write(x.FOV); + w.Write((int)x.Unknown.ElementAtOrDefault(3)); + w.Write(x.Anchor); + w.Write((int)x.Unknown.ElementAtOrDefault(4)); + w.Write(x.Target); + w.Write(x.TargetPosition.GetValueOrDefault()); + w.Write(x.LeftTangent); + w.Write(x.RightTangent); + }); + } + } + + #endregion + + #region 0x006 chunk + + /// + /// CGameCtnMediaBlockCameraCustom 0x006 chunk (ManiaPlanet) + /// + [Chunk(0x030A2006, "ManiaPlanet")] + public class Chunk030A2006 : Chunk + { + public int Version { get; set; } = 3; + + /// + /// Constructs a new 0x030A2006 chunk with version 3. + /// + /// + public Chunk030A2006() : this(3) + { + + } + + public Chunk030A2006(int version) + { + Version = version; + } + + public override void Read(CGameCtnMediaBlockCameraCustom n, GameBoxReader r, GameBoxWriter unknownW) + { + Version = r.ReadInt32(); + n.Keys = r.ReadArray(i => + { + var time = r.ReadSingle(); + var a = r.ReadInt32(); // 1 + var anchorRot = r.ReadBoolean(); // 0 + var anchor = r.ReadInt32(); // -1 if not set, 0 for local player + var anchorVis = r.ReadBoolean(); // 1 + var target = r.ReadInt32(); // -1 + var position = r.ReadVec3(); + var pitchYawRoll = r.ReadVec3(); // in radians + var fov = r.ReadSingle(); + var f = r.ReadInt32(); // 0 + var g = r.ReadInt32(); // 0 + var h = r.ReadInt32(); // 0 + var zIndex = r.ReadSingle(); + var leftTangent = r.ReadVec3(); + var ii = r.ReadArray(8); + var rightTangent = r.ReadVec3(); + var j = r.ReadArray(8); + + return new Key() + { + Time = time, + AnchorRot = anchorRot, + Anchor = anchor, + AnchorVis = anchorVis, + Target = target, + Position = position, + PitchYawRoll = pitchYawRoll, + FOV = fov, + ZIndex = zIndex, + LeftTangent = leftTangent, + RightTangent = rightTangent, + + Unknown = new object[] + { + a, f, g, h, ii, j + } + }; + }).ToList(); + } + + public override void Write(CGameCtnMediaBlockCameraCustom n, GameBoxWriter w, GameBoxReader unknownR) + { + w.Write(Version); + + w.Write(n.Keys?.ToArray(), x => + { + w.Write(x.Time); + w.Write((int)x.Unknown.ElementAtOrDefault(0)); + w.Write(x.AnchorRot); + w.Write(x.Anchor); + w.Write(x.AnchorVis); + w.Write(x.Target); + w.Write(x.Position); + w.Write(x.PitchYawRoll); + w.Write(x.FOV); + w.Write((int)x.Unknown.ElementAtOrDefault(1)); + w.Write((int)x.Unknown.ElementAtOrDefault(2)); + w.Write((int)x.Unknown.ElementAtOrDefault(3)); + w.Write(x.ZIndex.GetValueOrDefault()); + w.Write(x.LeftTangent); + w.Write((float[])x.Unknown.ElementAtOrDefault(4)); + w.Write(x.RightTangent); + w.Write((float[])x.Unknown.ElementAtOrDefault(5)); + }); + } + } + + #endregion + + #endregion + + public class Key : MediaBlockKey + { + public Vec3 Position { get; set; } + /// + /// Pitch, yaw and roll in radians. + /// + public Vec3 PitchYawRoll { get; set; } + public float FOV { get; set; } + public float? ZIndex { get; set; } + public Vec3? TargetPosition { get; set; } + public Vec3 LeftTangent { get; set; } + public Vec3 RightTangent { get; set; } + public int Anchor { get; set; } + public int Target { get; set; } + public bool AnchorVis { get; set; } + public bool AnchorRot { get; set; } + + public object[] Unknown { get; set; } + } + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraPath.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraPath.cs index 2f8a01dac..1aa46a574 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraPath.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraPath.cs @@ -1,222 +1,222 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Numerics; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.IO; +using System.Numerics; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// MediaTracker block - Camera path - /// - [Node(0x030A1000)] - public class CGameCtnMediaBlockCameraPath : CGameCtnMediaBlockCamera - { - public Key[] Keys { get; set; } - - public CGameCtnMediaBlockCameraPath(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - + /// + [Node(0x030A1000)] + public class CGameCtnMediaBlockCameraPath : CGameCtnMediaBlockCamera + { + public Key[] Keys { get; set; } + + public CGameCtnMediaBlockCameraPath(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) + { + } - #region Chunks + #region Chunks - #region 0x000 chunk + #region 0x000 chunk /// /// CGameCtnMediaBlockCameraPath 0x000 chunk /// - [Chunk(0x030A1000)] - public class Chunk030A1000 : Chunk - { - public override void Read(CGameCtnMediaBlockCameraPath n, GameBoxReader r, GameBoxWriter unknownW) - { - n.Keys = r.ReadArray(i => - { - var time = r.ReadSingle(); - var position = r.ReadVec3(); - var pitchYawRoll = r.ReadVec3(); // in radians - var fov = r.ReadSingle(); - var anchorRot = r.ReadBoolean(); - var anchor = r.ReadInt32(); - var anchorVis = r.ReadBoolean(); - var target = r.ReadInt32(); - var targetPosition = r.ReadVec3(); - var a = r.ReadSingle(); // 1 - var b = r.ReadSingle(); // -0.48 - var c = r.ReadSingle(); // 0 - var d = r.ReadSingle(); // 0 - var e = r.ReadSingle(); - - return new Key() - { - Time = time, - Position = position, - PitchYawRoll = pitchYawRoll, - FOV = fov, - AnchorRot = anchorRot, - Anchor = anchor, - AnchorVis = anchorVis, - Target = target, - TargetPosition = targetPosition, - Unknown = new object[] { a, b, c, d, e } - }; - }); - } - - public override void Write(CGameCtnMediaBlockCameraPath n, GameBoxWriter w, GameBoxReader unknownR) - { - w.Write(n.Keys, x => - { - w.Write(x.Time); - w.Write(x.Position); - w.Write(x.PitchYawRoll); - w.Write(x.FOV); - w.Write(x.AnchorRot); - w.Write(x.Anchor); - w.Write(x.AnchorVis); - w.Write(x.Target); - w.Write(x.TargetPosition); - w.Write((float)x.Unknown[0]); - w.Write((float)x.Unknown[1]); - w.Write((float)x.Unknown[2]); - w.Write((float)x.Unknown[3]); - w.Write((float)x.Unknown[4]); - }); - } + [Chunk(0x030A1000)] + public class Chunk030A1000 : Chunk + { + public override void Read(CGameCtnMediaBlockCameraPath n, GameBoxReader r, GameBoxWriter unknownW) + { + n.Keys = r.ReadArray(i => + { + var time = r.ReadSingle(); + var position = r.ReadVec3(); + var pitchYawRoll = r.ReadVec3(); // in radians + var fov = r.ReadSingle(); + var anchorRot = r.ReadBoolean(); + var anchor = r.ReadInt32(); + var anchorVis = r.ReadBoolean(); + var target = r.ReadInt32(); + var targetPosition = r.ReadVec3(); + var a = r.ReadSingle(); // 1 + var b = r.ReadSingle(); // -0.48 + var c = r.ReadSingle(); // 0 + var d = r.ReadSingle(); // 0 + var e = r.ReadSingle(); + + return new Key() + { + Time = time, + Position = position, + PitchYawRoll = pitchYawRoll, + FOV = fov, + AnchorRot = anchorRot, + Anchor = anchor, + AnchorVis = anchorVis, + Target = target, + TargetPosition = targetPosition, + Unknown = new object[] { a, b, c, d, e } + }; + }); + } + + public override void Write(CGameCtnMediaBlockCameraPath n, GameBoxWriter w, GameBoxReader unknownR) + { + w.Write(n.Keys, x => + { + w.Write(x.Time); + w.Write(x.Position); + w.Write(x.PitchYawRoll); + w.Write(x.FOV); + w.Write(x.AnchorRot); + w.Write(x.Anchor); + w.Write(x.AnchorVis); + w.Write(x.Target); + w.Write(x.TargetPosition); + w.Write((float)x.Unknown[0]); + w.Write((float)x.Unknown[1]); + w.Write((float)x.Unknown[2]); + w.Write((float)x.Unknown[3]); + w.Write((float)x.Unknown[4]); + }); + } } - #endregion + #endregion - #region 0x002 chunk + #region 0x002 chunk /// /// CGameCtnMediaBlockCameraPath 0x002 chunk /// - [Chunk(0x030A1002)] - public class Chunk030A1002 : Chunk - { - public override void Read(CGameCtnMediaBlockCameraPath n, GameBoxReader r, GameBoxWriter unknownW) - { - n.Keys = r.ReadArray(i => - { - var time = r.ReadSingle(); - var position = r.ReadVec3(); - var pitchYawRoll = r.ReadVec3(); // in radians - var fov = r.ReadSingle(); - var anchorRot = r.ReadBoolean(); - var anchor = r.ReadInt32(); - var anchorVis = r.ReadBoolean(); - var target = r.ReadInt32(); - var targetPosition = r.ReadVec3(); - var a = r.ReadSingle(); // 1 - var b = r.ReadSingle(); // -0.48 - var c = r.ReadSingle(); // 0 - var d = r.ReadSingle(); // 0 - var e = r.ReadSingle(); - - return new Key() - { - Time = time, - Position = position, - PitchYawRoll = pitchYawRoll, - FOV = fov, - AnchorRot = anchorRot, - Anchor = anchor, - AnchorVis = anchorVis, - Target = target, - TargetPosition = targetPosition, - Unknown = new object[] { a, b, c, d, e } - }; - }); - } - - public override void Write(CGameCtnMediaBlockCameraPath n, GameBoxWriter w, GameBoxReader unknownR) - { - w.Write(n.Keys, x => - { - w.Write(x.Time); - w.Write(x.Position); - w.Write(x.PitchYawRoll); - w.Write(x.FOV); - w.Write(x.AnchorRot); - w.Write(x.Anchor); - w.Write(x.AnchorVis); - w.Write(x.Target); - w.Write(x.TargetPosition); - w.Write((float)x.Unknown[0]); - w.Write((float)x.Unknown[1]); - w.Write((float)x.Unknown[2]); - w.Write((float)x.Unknown[3]); - w.Write((float)x.Unknown[4]); - }); - } + [Chunk(0x030A1002)] + public class Chunk030A1002 : Chunk + { + public override void Read(CGameCtnMediaBlockCameraPath n, GameBoxReader r, GameBoxWriter unknownW) + { + n.Keys = r.ReadArray(i => + { + var time = r.ReadSingle(); + var position = r.ReadVec3(); + var pitchYawRoll = r.ReadVec3(); // in radians + var fov = r.ReadSingle(); + var anchorRot = r.ReadBoolean(); + var anchor = r.ReadInt32(); + var anchorVis = r.ReadBoolean(); + var target = r.ReadInt32(); + var targetPosition = r.ReadVec3(); + var a = r.ReadSingle(); // 1 + var b = r.ReadSingle(); // -0.48 + var c = r.ReadSingle(); // 0 + var d = r.ReadSingle(); // 0 + var e = r.ReadSingle(); + + return new Key() + { + Time = time, + Position = position, + PitchYawRoll = pitchYawRoll, + FOV = fov, + AnchorRot = anchorRot, + Anchor = anchor, + AnchorVis = anchorVis, + Target = target, + TargetPosition = targetPosition, + Unknown = new object[] { a, b, c, d, e } + }; + }); + } + + public override void Write(CGameCtnMediaBlockCameraPath n, GameBoxWriter w, GameBoxReader unknownR) + { + w.Write(n.Keys, x => + { + w.Write(x.Time); + w.Write(x.Position); + w.Write(x.PitchYawRoll); + w.Write(x.FOV); + w.Write(x.AnchorRot); + w.Write(x.Anchor); + w.Write(x.AnchorVis); + w.Write(x.Target); + w.Write(x.TargetPosition); + w.Write((float)x.Unknown[0]); + w.Write((float)x.Unknown[1]); + w.Write((float)x.Unknown[2]); + w.Write((float)x.Unknown[3]); + w.Write((float)x.Unknown[4]); + }); + } } - #endregion + #endregion - #region 0x003 chunk + #region 0x003 chunk /// /// CGameCtnMediaBlockCameraPath 0x003 chunk /// - [Chunk(0x030A1003)] - public class Chunk030A1003 : Chunk - { - public int Version { get; set; } - - public override void Read(CGameCtnMediaBlockCameraPath n, GameBoxReader r, GameBoxWriter unknownW) - { - Version = r.ReadInt32(); - - n.Keys = r.ReadArray(i => - { - var time = r.ReadSingle(); - var position = r.ReadVec3(); - var pitchYawRoll = r.ReadVec3(); // in radians - var fov = r.ReadSingle(); - var zIndex = r.ReadSingle(); - - var a = r.ReadArray(7); - var b = r.ReadArray(5); - var c = r.ReadArray(2); - - return new Key() - { - Time = time, - Position = position, - PitchYawRoll = pitchYawRoll, - FOV = fov, - ZIndex = zIndex - }; - }); - } + [Chunk(0x030A1003)] + public class Chunk030A1003 : Chunk + { + public int Version { get; set; } + + public override void Read(CGameCtnMediaBlockCameraPath n, GameBoxReader r, GameBoxWriter unknownW) + { + Version = r.ReadInt32(); + + n.Keys = r.ReadArray(i => + { + var time = r.ReadSingle(); + var position = r.ReadVec3(); + var pitchYawRoll = r.ReadVec3(); // in radians + var fov = r.ReadSingle(); + var zIndex = r.ReadSingle(); + + var a = r.ReadArray(7); + var b = r.ReadArray(5); + var c = r.ReadArray(2); + + return new Key() + { + Time = time, + Position = position, + PitchYawRoll = pitchYawRoll, + FOV = fov, + ZIndex = zIndex + }; + }); + } } - #endregion - - #endregion - - public class Key : MediaBlockKey - { - public int Anchor { get; set; } - public bool AnchorVis { get; set; } - public bool AnchorRot { get; set; } - public int Target { get; set; } - - public Vector3 Position { get; set; } - /// - /// Pitch, yaw and roll in radians - /// - public Vector3 PitchYawRoll { get; set; } - public float FOV { get; set; } - public float? ZIndex { get; set; } - - public Vector3 TargetPosition { get; set; } - public Vector3 LeftTangent { get; set; } - public Vector3 RightTangent { get; set; } - - public object[] Unknown { get; set; } - } - } -} + #endregion + + #endregion + + public class Key : MediaBlockKey + { + public int Anchor { get; set; } + public bool AnchorVis { get; set; } + public bool AnchorRot { get; set; } + public int Target { get; set; } + + public Vec3 Position { get; set; } + /// + /// Pitch, yaw and roll in radians + /// + public Vec3 PitchYawRoll { get; set; } + public float FOV { get; set; } + public float? ZIndex { get; set; } + + public Vec3 TargetPosition { get; set; } + public Vec3 LeftTangent { get; set; } + public Vec3 RightTangent { get; set; } + + public object[] Unknown { get; set; } + } + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockTransitionFade.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockTransitionFade.cs index c4dc93215..50989f7cc 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockTransitionFade.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockTransitionFade.cs @@ -11,7 +11,7 @@ public class CGameCtnMediaBlockTransitionFade : CGameCtnMediaBlock { public Key[] Keys { get; set; } - public Vector3 Color { get; set; } + public Vec3 Color { get; set; } public CGameCtnMediaBlockTransitionFade(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaClipGroup.cs b/GBX.NET/Engines/Game/CGameCtnMediaClipGroup.cs index 59bddce23..4eabc5ced 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaClipGroup.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaClipGroup.cs @@ -33,7 +33,7 @@ public override void ReadWrite(CGameCtnMediaClipGroup n, GameBoxReaderWriter rw) n.Triggers = rw.Array(n.Triggers, i => { - var coords = rw.Reader.ReadArray(i => rw.Reader.ReadInt3()); + var coords = rw.Reader.ReadArray(j => rw.Reader.ReadInt3()); var unknown1 = rw.Reader.ReadInt32(); var unknown2 = rw.Reader.ReadInt32(); var unknown3 = rw.Reader.ReadInt32(); @@ -50,7 +50,7 @@ public override void ReadWrite(CGameCtnMediaClipGroup n, GameBoxReaderWriter rw) }, x => { - rw.Writer.Write(x.Coords, x => rw.Writer.Write(x)); + rw.Writer.Write(x.Coords, y => rw.Writer.Write(y)); rw.Writer.Write(x.Unknown1); rw.Writer.Write(x.Unknown2); rw.Writer.Write(x.Unknown3); @@ -77,7 +77,7 @@ public override void Read(CGameCtnMediaClipGroup n, GameBoxReader r, GameBoxWrit var unknown4 = r.ReadInt32(); var unknown5 = r.ReadInt32(); var unknown6 = r.ReadInt32(); - var coords = r.ReadArray(i => r.ReadInt3()); + var coords = r.ReadArray(j => r.ReadInt3()); return new Trigger() { diff --git a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs index ac5878594..a41e19279 100644 --- a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs +++ b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs @@ -125,10 +125,12 @@ public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter n.Track = Task.Run(() => { - using var ms = new MemoryStream(trackGbx); - var gbx = new GameBox(); - gbx.Read(ms); - return gbx; + using (var ms = new MemoryStream(trackGbx)) + { + var gbx = new GameBox(); + gbx.Read(ms); + return gbx; + } }); } } diff --git a/GBX.NET/Engines/Game/CGameGhost.cs b/GBX.NET/Engines/Game/CGameGhost.cs index 1f9bcf43a..0dc672a0c 100644 --- a/GBX.NET/Engines/Game/CGameGhost.cs +++ b/GBX.NET/Engines/Game/CGameGhost.cs @@ -1,147 +1,149 @@ using ICSharpCode.SharpZipLib.Zip.Compression.Streams; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace GBX.NET.Engines.Game -{ - [Node(0x0303F000)] - public class CGameGhost : Node - { - public bool IsReplaying { get; set; } - - public CGameGhost(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - - #region Chunks - - #region 0x003 chunk - - [Chunk(0x0303F003)] - public class Chunk0303F003 : Chunk - { - public byte[] Data { get; set; } - public int[] Samples { get; set; } - - public override void ReadWrite(CGameGhost n, GameBoxReaderWriter rw) +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace GBX.NET.Engines.Game +{ + [Node(0x0303F000)] + public class CGameGhost : Node + { + public bool IsReplaying { get; set; } + + public CGameGhost(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) + { + + } + + #region Chunks + + #region 0x003 chunk + + [Chunk(0x0303F003)] + public class Chunk0303F003 : Chunk + { + public byte[] Data { get; set; } + public int[] Samples { get; set; } + + public override void ReadWrite(CGameGhost n, GameBoxReaderWriter rw) { - Data = rw.Bytes(Data); - Samples = rw.Array(Samples); - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - } + Data = rw.Bytes(Data); + Samples = rw.Array(Samples); + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + } } - #endregion - - #region 0x004 chunk - - [Chunk(0x0303F004)] - public class Chunk0303F004 : Chunk - { - public override void ReadWrite(CGameGhost n, GameBoxReaderWriter rw) - { - rw.Reader.ReadInt32(); // 0x0A103000 - } - } - - #endregion - - #region 0x005 chunk - - [Chunk(0x0303F005)] - public class Chunk0303F005 : Chunk - { - public int UncompressedSize { get; set; } - public int CompressedSize { get; set; } - public byte[] Data { get; set; } - - public override void ReadWrite(CGameGhost n, GameBoxReaderWriter rw) - { - UncompressedSize = rw.Int32(UncompressedSize); - CompressedSize = rw.Int32(CompressedSize); - Data = rw.Bytes(Data, CompressedSize); + #endregion + + #region 0x004 chunk - #if DEBUG + [Chunk(0x0303F004)] + public class Chunk0303F004 : Chunk + { + public override void ReadWrite(CGameGhost n, GameBoxReaderWriter rw) + { + rw.Reader.ReadInt32(); // 0x0A103000 + } + } - using var ms = new MemoryStream(Data); - using var zlib = new InflaterInputStream(ms); - using var gbxr = new GameBoxReader(zlib); + #endregion - var classID = gbxr.ReadInt32(); // CSceneVehicleCar - if (classID != -1) - { - var bSkipList2 = gbxr.ReadBoolean(); - gbxr.ReadInt32(); - var samplePeriod = gbxr.ReadInt32(); - gbxr.ReadInt32(); + #region 0x005 chunk + + [Chunk(0x0303F005)] + public class Chunk0303F005 : Chunk + { + public int UncompressedSize { get; set; } + public int CompressedSize { get; set; } + public byte[] Data { get; set; } + + public override void ReadWrite(CGameGhost n, GameBoxReaderWriter rw) + { + UncompressedSize = rw.Int32(UncompressedSize); + CompressedSize = rw.Int32(CompressedSize); + Data = rw.Bytes(Data, CompressedSize); - var size = gbxr.ReadInt32(); - var sampleData = gbxr.ReadBytes(size); +#if DEBUG - var numSamples = gbxr.ReadInt32(); - if (numSamples > 0) + using (var ms = new MemoryStream(Data)) + using (var zlib = new InflaterInputStream(ms)) + using (var gbxr = new GameBoxReader(zlib)) + { + var classID = gbxr.ReadInt32(); // CSceneVehicleCar + if (classID != -1) { - var firstSampleOffset = gbxr.ReadInt32(); - if (numSamples > 1) + var bSkipList2 = gbxr.ReadBoolean(); + gbxr.ReadInt32(); + var samplePeriod = gbxr.ReadInt32(); + gbxr.ReadInt32(); + + var size = gbxr.ReadInt32(); + var sampleData = gbxr.ReadBytes(size); + + var numSamples = gbxr.ReadInt32(); + if (numSamples > 0) { - var sizePerSample = gbxr.ReadInt32(); - if (sizePerSample == -1) + var firstSampleOffset = gbxr.ReadInt32(); + if (numSamples > 1) { - var sampleSizes = gbxr.ReadArray(numSamples - 1); + var sizePerSample = gbxr.ReadInt32(); + if (sizePerSample == -1) + { + var sampleSizes = gbxr.ReadArray(numSamples - 1); + } } } - } - if (!bSkipList2) - { - var num = gbxr.ReadInt32(); - var sampleTimes = gbxr.ReadArray(num); - } - - using var msSampleData = new MemoryStream(sampleData); - using var gbxrSampleData = new GameBoxReader(msSampleData); + if (!bSkipList2) + { + var num = gbxr.ReadInt32(); + var sampleTimes = gbxr.ReadArray(num); + } - for (var i = 0; i < numSamples; i++) - { - var pos = gbxrSampleData.ReadVec3(); - var angle = gbxrSampleData.ReadInt16(); - var axisHeading = gbxrSampleData.ReadInt16(); - var axisPitch = gbxrSampleData.ReadInt16(); - var speed = MathF.Exp(gbxrSampleData.ReadInt16() / 1000); - var velocityHeading = gbxrSampleData.ReadByte(); - var velocityPitch = gbxrSampleData.ReadByte(); - gbxrSampleData.ReadArray(12); + using (var msSampleData = new MemoryStream(sampleData)) + using (var gbxrSampleData = new GameBoxReader(msSampleData)) + { + for (var i = 0; i < numSamples; i++) + { + var pos = gbxrSampleData.ReadVec3(); + var angle = gbxrSampleData.ReadInt16(); + var axisHeading = gbxrSampleData.ReadInt16(); + var axisPitch = gbxrSampleData.ReadInt16(); + var speed = (float)Math.Exp(gbxrSampleData.ReadInt16() / 1000); + var velocityHeading = gbxrSampleData.ReadByte(); + var velocityPitch = gbxrSampleData.ReadByte(); + gbxrSampleData.ReadArray(12); + } + } } } - #endif - } - } - - #endregion - - #region 0x006 chunk - - [Chunk(0x0303F006)] - public class Chunk0303F006 : Chunk - { - public Chunk0303F005 Chunk005 { get; } = new Chunk0303F005(); - - public override void ReadWrite(CGameGhost n, GameBoxReaderWriter rw) - { - n.IsReplaying = rw.Boolean(n.IsReplaying); - Chunk005.ReadWrite(n, rw); - } - } - - #endregion - - #endregion - } -} + #endif + } + } + + #endregion + + #region 0x006 chunk + + [Chunk(0x0303F006)] + public class Chunk0303F006 : Chunk + { + public Chunk0303F005 Chunk005 { get; } = new Chunk0303F005(); + + public override void ReadWrite(CGameGhost n, GameBoxReaderWriter rw) + { + n.IsReplaying = rw.Boolean(n.IsReplaying); + Chunk005.ReadWrite(n, rw); + } + } + + #endregion + + #endregion + } +} diff --git a/GBX.NET/Engines/GameData/CGameItemModel.cs b/GBX.NET/Engines/GameData/CGameItemModel.cs index a9c701e25..32c70585a 100644 --- a/GBX.NET/Engines/GameData/CGameItemModel.cs +++ b/GBX.NET/Engines/GameData/CGameItemModel.cs @@ -35,7 +35,7 @@ public enum ItemType : int public Node[] NadeoSkinFids { get; set; } public Node[] Cameras { get; set; } public Node RaceInterfaceFid { get; set; } - public Vector3 GroundPoint { get; set; } + public Vec3 GroundPoint { get; set; } public float PainterGroundMargin { get; set; } public float OrbitalCenterHeightFromGround { get; set; } public float OrbitalRadiusBase { get; set; } diff --git a/GBX.NET/Engines/Plug/CPlugCrystal.cs b/GBX.NET/Engines/Plug/CPlugCrystal.cs index 98062b354..a234a885a 100644 --- a/GBX.NET/Engines/Plug/CPlugCrystal.cs +++ b/GBX.NET/Engines/Plug/CPlugCrystal.cs @@ -100,16 +100,16 @@ public override void ReadWrite(CPlugCrystal n, GameBoxReaderWriter rw) } var uP = rw.Reader.ReadInt32(); - var verticies = rw.Reader.ReadArray(i => rw.Reader.ReadVec3()); - var indicies = rw.Reader.ReadArray(i => rw.Reader.ReadInt2()); + var verticies = rw.Reader.ReadArray(j => rw.Reader.ReadVec3()); + var indicies = rw.Reader.ReadArray(j => rw.Reader.ReadInt2()); - var uvmaps = rw.Reader.ReadArray(i => + var uvmaps = rw.Reader.ReadArray(j => { var uvVerticies = rw.Reader.ReadInt32(); var inds = rw.Reader.ReadArray(uvVerticies); - var xy = new Vector2[uvVerticies]; - for (var j = 0; j < uvVerticies; j++) - xy[j] = rw.Reader.ReadVec2(); + var xy = new Vec2[uvVerticies]; + for (var k = 0; k < uvVerticies; k++) + xy[k] = rw.Reader.ReadVec2(); var one = rw.Reader.ReadInt32(); var two = rw.Reader.ReadInt32(); @@ -166,7 +166,7 @@ public override void ReadWrite(CPlugCrystal n, GameBoxReaderWriter rw) public class Chunk09003006 : Chunk { public int Version { get; set; } - public Vector2[] Vectors { get; set; } + public Vec2[] Vectors { get; set; } public override void ReadWrite(CPlugCrystal n, GameBoxReaderWriter rw) { @@ -196,7 +196,7 @@ public class Layer { public string LayerID { get; set; } public string LayerName { get; set; } - public Vector3[] Verticies { get; set; } + public Vec3[] Verticies { get; set; } public Int2[] Indicies { get; set; } public UVMap[] UVs { get; set; } public object[] Unknown { get; set; } @@ -206,7 +206,7 @@ public class UVMap { public int VertCount { get; set; } public int[] Inds { get; set; } - public Vector2[] XY { get; set; } + public Vec2[] XY { get; set; } public int Unknown1 { get; set; } public int Unknown2 { get; set; } diff --git a/GBX.NET/Engines/Script/CScriptTraitsMetadata.cs b/GBX.NET/Engines/Script/CScriptTraitsMetadata.cs index 7c7f7a1d4..4f6a0860a 100644 --- a/GBX.NET/Engines/Script/CScriptTraitsMetadata.cs +++ b/GBX.NET/Engines/Script/CScriptTraitsMetadata.cs @@ -73,13 +73,13 @@ public void Declare(string name, string value) Metadata.Add(new ScriptVariable(ScriptType.Text) { Name = name, Value = value }); } - public void Declare(string name, Vector2 value) + public void Declare(string name, Vec2 value) { Remove(name); Metadata.Add(new ScriptVariable(ScriptType.Vec2) { Name = name, Value = value }); } - public void Declare(string name, Vector3 value) + public void Declare(string name, Vec3 value) { Remove(name); Metadata.Add(new ScriptVariable(ScriptType.Vec3) { Name = name, Value = value }); @@ -125,12 +125,18 @@ public void Read(GameBoxReader r) { var varType = r.ReadByte(); - types[i] = ((ScriptType)varType) switch + switch ((ScriptType)varType) { - ScriptType.Array => ReadScriptArray(), - ScriptType.Struct => ReadScriptStruct(out int defaultLength), - _ => new ScriptVariable((ScriptType)varType), - }; + case ScriptType.Array: + types[i] = ReadScriptArray(); + break; + case ScriptType.Struct: + types[i] = ReadScriptStruct(out int defaultLength); + break; + default: + types[i] = new ScriptVariable((ScriptType)varType); + break; + } } var varCount = r.ReadByte(); @@ -435,10 +441,10 @@ void WriteScriptStruct(ScriptStruct variable) w.Write(0f); break; case ScriptType.Vec2: - w.Write(new Vector2()); + w.Write(new Vec2()); break; case ScriptType.Vec3: - w.Write(new Vector3()); + w.Write(new Vec3()); break; case ScriptType.Int3: w.Write(new Int3()); @@ -477,10 +483,10 @@ void WriteType(ScriptVariable type) w.Write((string)type.Value, StringLengthPrefix.Byte); break; case ScriptType.Vec2: - w.Write((Vector2)type.Value); + w.Write((Vec2)type.Value); break; case ScriptType.Vec3: - w.Write((Vector3)type.Value); + w.Write((Vec3)type.Value); break; case ScriptType.Int3: w.Write((Int3)type.Value); diff --git a/GBX.NET/FreeBlock.cs b/GBX.NET/FreeBlock.cs index 9c3860e24..9ceaec74f 100644 --- a/GBX.NET/FreeBlock.cs +++ b/GBX.NET/FreeBlock.cs @@ -8,9 +8,9 @@ namespace GBX.NET public class FreeBlock { public Block Block { get; set; } - public Vector3 Position { get; set; } - public Vector3 PitchYawRoll { get; set; } - public Vector3[] SnapPoints { get; set; } + public Vec3 Position { get; set; } + public Vec3 PitchYawRoll { get; set; } + public Vec3[] SnapPoints { get; set; } public FreeBlock(Block block) { diff --git a/GBX.NET/GBX.NET.csproj b/GBX.NET/GBX.NET.csproj index 15216df28..f5c01302b 100644 --- a/GBX.NET/GBX.NET.csproj +++ b/GBX.NET/GBX.NET.csproj @@ -1,7 +1,7 @@  - netstandard2.1 + netstandard2.0 A completely open source GBX file interaction library for .NET. BigBang1112 BigBang1112 @@ -13,6 +13,7 @@ LICENSE.txt gbx, trackmania, maniaplanet, gamebox, net, chunk, x86 https://github.com/BigBang1112/gbx-net + https://github.com/BigBang1112/gbx-net diff --git a/GBX.NET/GameBox.cs b/GBX.NET/GameBox.cs index 1d06c6a12..75869150a 100644 --- a/GBX.NET/GameBox.cs +++ b/GBX.NET/GameBox.cs @@ -74,122 +74,124 @@ public void DiscoverAllChunks() public override bool Read(Stream stream, bool withoutBody) { - using var gbxr = new GameBoxReader(stream); + using (var gbxr = new GameBoxReader(stream)) + { - // Header + // Header - Log.Write("Reading the header..."); + Log.Write("Reading the header..."); - var parameters = new GameBoxHeaderParameters(); - if (!parameters.Read(gbxr)) return false; + var parameters = new GameBoxHeaderParameters(); + if (!parameters.Read(gbxr)) return false; - Log.Write("Working out the header chunks in the background..."); + Log.Write("Working out the header chunks in the background..."); - Header = Task.Run(() => new GameBoxHeader(this, parameters)); - Header.ContinueWith(x => - { - if (x.IsCompletedSuccessfully) - Log.Write("Header chunks parsed without any exceptions.", ConsoleColor.Green); - else - Log.Write("Header chunks parsed with exceptions.", ConsoleColor.Red); - }); + Header = Task.Run(() => new GameBoxHeader(this, parameters)); + Header.ContinueWith(x => + { + if (x.Exception == null) + Log.Write("Header chunks parsed without any exceptions.", ConsoleColor.Green); + else + Log.Write("Header chunks parsed with exceptions.", ConsoleColor.Red); + }); - // Reference table + // Reference table - Log.Write("Reading the reference table..."); + Log.Write("Reading the reference table..."); - var numExternalNodes = gbxr.ReadInt32(); + var numExternalNodes = gbxr.ReadInt32(); - if (numExternalNodes > 0) - { - var ancestorLevel = gbxr.ReadInt32(); + if (numExternalNodes > 0) + { + var ancestorLevel = gbxr.ReadInt32(); - GameBoxRefTableFolder rootFolder = new GameBoxRefTableFolder("Root"); + GameBoxRefTableFolder rootFolder = new GameBoxRefTableFolder("Root"); - var numSubFolders = gbxr.ReadInt32(); - ReadRefTableFolders(numSubFolders, ref rootFolder); + var numSubFolders = gbxr.ReadInt32(); + ReadRefTableFolders(numSubFolders, ref rootFolder); - void ReadRefTableFolders(int n, ref GameBoxRefTableFolder folder) - { - for (var i = 0; i < n; i++) + void ReadRefTableFolders(int n, ref GameBoxRefTableFolder folder) { - var name = gbxr.ReadString(); - var numSubFolders = gbxr.ReadInt32(); + for (var i = 0; i < n; i++) + { + var name = gbxr.ReadString(); + var numSubSubFolders = gbxr.ReadInt32(); - var f = new GameBoxRefTableFolder(name, folder); - folder.Folders.Add(f); + var f = new GameBoxRefTableFolder(name, folder); + folder.Folders.Add(f); - ReadRefTableFolders(numSubFolders, ref f); + ReadRefTableFolders(numSubSubFolders, ref f); + } } - } - var externalNodes = new ExternalNode[numExternalNodes]; + var externalNodes = new ExternalNode[numExternalNodes]; - for (var i = 0; i < numExternalNodes; i++) - { - string fileName = null; - int? resourceIndex = null; - bool? useFile = null; - int? folderIndex = null; - - var flags = gbxr.ReadInt32(); + for (var i = 0; i < numExternalNodes; i++) + { + string fileName = null; + int? resourceIndex = null; + bool? useFile = null; + int? folderIndex = null; - if ((flags & 4) == 0) - fileName = gbxr.ReadString(); - else - resourceIndex = gbxr.ReadInt32(); + var flags = gbxr.ReadInt32(); - var nodeIndex = gbxr.ReadInt32(); + if ((flags & 4) == 0) + fileName = gbxr.ReadString(); + else + resourceIndex = gbxr.ReadInt32(); - if (parameters.Version >= 5) - useFile = gbxr.ReadBoolean(); + var nodeIndex = gbxr.ReadInt32(); - if ((flags & 4) == 0) - folderIndex = gbxr.ReadInt32(); + if (parameters.Version >= 5) + useFile = gbxr.ReadBoolean(); - var extNode = new ExternalNode(flags, fileName, resourceIndex, nodeIndex, useFile, folderIndex); - externalNodes[i] = extNode; - } + if ((flags & 4) == 0) + folderIndex = gbxr.ReadInt32(); - var refTable = new GameBoxRefTable(rootFolder, externalNodes); - RefTable = refTable; - } - else - { - Log.Write("No external nodes found, reference table completed.", ConsoleColor.Green); - } + var extNode = new ExternalNode(flags, fileName, resourceIndex, nodeIndex, useFile, folderIndex); + externalNodes[i] = extNode; + } - // Body + var refTable = new GameBoxRefTable(rootFolder, externalNodes); + RefTable = refTable; + } + else + { + Log.Write("No external nodes found, reference table completed.", ConsoleColor.Green); + } - if (!withoutBody) - { - Log.Write("Reading the body..."); + // Body - switch (parameters.BodyCompression) + if (!withoutBody) { - case 'C': - var uncompressedSize = gbxr.ReadInt32(); - var compressedSize = gbxr.ReadInt32(); - - var data = gbxr.ReadBytes(compressedSize); - - Body = GameBoxBody.DecompressAndConstruct(this, parameters.ClassID.GetValueOrDefault(), data, compressedSize, uncompressedSize); - break; - case 'U': - var uncompressedData = gbxr.ReadBytes((int)(stream.Length - stream.Position)); - Body = new GameBoxBody(this, parameters.ClassID.GetValueOrDefault(), uncompressedData, null, uncompressedData.Length); - break; - default: - Task.WaitAll(Header); - return false; - } + Log.Write("Reading the body..."); + + switch (parameters.BodyCompression) + { + case 'C': + var uncompressedSize = gbxr.ReadInt32(); + var compressedSize = gbxr.ReadInt32(); + + var data = gbxr.ReadBytes(compressedSize); + + Body = GameBoxBody.DecompressAndConstruct(this, parameters.ClassID.GetValueOrDefault(), data, compressedSize, uncompressedSize); + break; + case 'U': + var uncompressedData = gbxr.ReadBytes((int)(stream.Length - stream.Position)); + Body = new GameBoxBody(this, parameters.ClassID.GetValueOrDefault(), uncompressedData, null, uncompressedData.Length); + break; + default: + Task.WaitAll(Header); + return false; + } - Log.Write("Body completed!"); + Log.Write("Body completed!"); - Task.WaitAll(Header); + Task.WaitAll(Header); + } + else + Task.WaitAll(Header); } - else - Task.WaitAll(Header); return true; } @@ -219,11 +221,13 @@ public void Write(GameBoxWriter w) public void Save(string fileName, ClassIDRemap remap) { - using var ms = new MemoryStream(); - using var w = new GameBoxWriter(ms); - Write(w, remap); - ms.Position = 0; - File.WriteAllBytes(fileName, ms.ToArray()); + using (var ms = new MemoryStream()) + using (var w = new GameBoxWriter(ms)) + { + Write(w, remap); + ms.Position = 0; + File.WriteAllBytes(fileName, ms.ToArray()); + } } public void Save(string fileName) @@ -257,21 +261,23 @@ public class GameBox : IGameBox public virtual bool Read(Stream stream, bool withoutBody) { - using var gbxr = new GameBoxReader(stream); + using (var gbxr = new GameBoxReader(stream)) + { - var parameters = new GameBoxHeaderParameters(); - if (!parameters.Read(gbxr)) return false; + var parameters = new GameBoxHeaderParameters(); + if (!parameters.Read(gbxr)) return false; - Log.Write("Working out the header chunks in the background..."); + Log.Write("Working out the header chunks in the background..."); - Header = Task.Run(() => new GameBoxHeader(this, parameters)); - Header.ContinueWith(x => - { - if(x.IsCompletedSuccessfully) - Log.Write("Header chunks parsed without any exceptions."); - else - Log.Write("Header chunks parsed with exceptions."); - }); + Header = Task.Run(() => new GameBoxHeader(this, parameters)); + Header.ContinueWith(x => + { + if (x.Exception == null) + Log.Write("Header chunks parsed without any exceptions."); + else + Log.Write("Header chunks parsed with exceptions."); + }); + } return true; } @@ -288,13 +294,15 @@ public bool Load(string fileName) FileName = fileName; - using var fs = File.OpenRead(fileName); - var success = Read(fs); + using (var fs = File.OpenRead(fileName)) + { + var success = Read(fs); - if(success) Log.Write($"Loaded {fileName}!", ConsoleColor.Green); - else Log.Write($"File {fileName} has't loaded successfully.", ConsoleColor.Red); + if (success) Log.Write($"Loaded {fileName}!", ConsoleColor.Green); + else Log.Write($"File {fileName} has't loaded successfully.", ConsoleColor.Red); - return success; + return success; + } } [Obsolete] @@ -302,8 +310,8 @@ public bool Load(string fileName, bool loadToMemory) { if (loadToMemory) { - using var ms = new MemoryStream(File.ReadAllBytes(fileName)); - return Read(ms); + using (var ms = new MemoryStream(File.ReadAllBytes(fileName))) + return Read(ms); } return Load(fileName); @@ -358,7 +366,7 @@ public static GameBox Parse(string fileName) } } - static Type GetBaseType(Type t) + Type GetBaseType(Type t) { if (t == null) return null; @@ -394,7 +402,7 @@ public static Type GetGameBoxType(Stream stream) return typeof(GameBox<>).MakeGenericType(availableClass); } - static Type GetBaseType(Type t) + Type GetBaseType(Type t) { if (t == null) return null; diff --git a/GBX.NET/GameBoxBody.cs b/GBX.NET/GameBoxBody.cs index 5e1ef8690..6675d6750 100644 --- a/GBX.NET/GameBoxBody.cs +++ b/GBX.NET/GameBoxBody.cs @@ -28,14 +28,16 @@ public GameBoxBody(GameBox gbx, uint mainNodeID, byte[] data, int? compressed CompressedSize = compressedSize; UncompressedSize = uncompressedSize; - using var s = new MemoryStream(data); - using var gbxr = new GameBoxReader(s, this); - gbx.MainNode = (T)Node.Parse(this, mainNodeID, gbxr); - Debug.WriteLine("Amount read: " + (s.Position / (float)s.Length).ToString("P")); + using (var s = new MemoryStream(data)) + using (var gbxr = new GameBoxReader(s, this)) + { + gbx.MainNode = (T)Node.Parse(this, mainNodeID, gbxr); + Debug.WriteLine("Amount read: " + (s.Position / (float)s.Length).ToString("P")); - byte[] restBuffer = new byte[s.Length - s.Position]; - gbxr.Read(restBuffer, 0, restBuffer.Length); - Rest = restBuffer; + byte[] restBuffer = new byte[s.Length - s.Position]; + gbxr.Read(restBuffer, 0, restBuffer.Length); + Rest = restBuffer; + } Chunks.Node = gbx.MainNode; } @@ -56,15 +58,17 @@ public void Write(GameBoxWriter w, ClassIDRemap remap) { if(GBX.Header.Result.BodyCompression == 'C') { - using var msBody = new MemoryStream(); - using var gbxwBody = new GameBoxWriter(msBody, this); + using (var msBody = new MemoryStream()) + using (var gbxwBody = new GameBoxWriter(msBody, this)) + { - GBX.MainNode.Write(gbxwBody, remap); - MiniLZO.Compress(msBody.ToArray(), out byte[] output); + GBX.MainNode.Write(gbxwBody, remap); + MiniLZO.Compress(msBody.ToArray(), out byte[] output); - w.Write((int)msBody.Length); // Uncompressed - w.Write(output.Length); // Compressed - w.Write(output, 0, output.Length); // Compressed body data + w.Write((int)msBody.Length); // Uncompressed + w.Write(output.Length); // Compressed + w.Write(output, 0, output.Length); // Compressed body data + } } else GBX.MainNode.Write(w); diff --git a/GBX.NET/GameBoxHeader.cs b/GBX.NET/GameBoxHeader.cs index ae9a3dd6a..392b29a9f 100644 --- a/GBX.NET/GameBoxHeader.cs +++ b/GBX.NET/GameBoxHeader.cs @@ -71,78 +71,79 @@ List GetInheritance(Type t) availableChunkClasses[chunkType.Key + cls] = chunkType.Value; } - using var ms = new MemoryStream(parameters.UserData); - using var r = new GameBoxReader(ms, this); - - var numHeaderChunks = r.ReadInt32(); - - var chunks = new Chunk[numHeaderChunks]; - - var chunkList = new Dictionary(); - - for (var i = 0; i < numHeaderChunks; i++) + using (var ms = new MemoryStream(parameters.UserData)) + using (var r = new GameBoxReader(ms, this)) { - var chunkID = r.ReadUInt32(); - var chunkSize = r.ReadUInt32(); + var numHeaderChunks = r.ReadInt32(); - var chId = chunkID & 0xFFF; - var clId = chunkID & 0xFFFFF000; + var chunks = new Chunk[numHeaderChunks]; - chunkList[clId + chId] = ((int)(chunkSize & ~0x80000000), (chunkSize & (1 << 31)) != 0); - } + var chunkList = new Dictionary(); - Log.Write("Header data chunk list:"); + for (var i = 0; i < numHeaderChunks; i++) + { + var chunkID = r.ReadUInt32(); + var chunkSize = r.ReadUInt32(); - foreach(var c in chunkList) - { - if(c.Value.Item2) - Log.Write($"| 0x{c.Key:x8} | {c.Value.Item1} B (Heavy)"); - else - Log.Write($"| 0x{c.Key:x8} | {c.Value.Item1} B"); - } + var chId = chunkID & 0xFFF; + var clId = chunkID & 0xFFFFF000; - int counter = 0; - foreach (var chunk in chunkList) - { - var chunkId = chunk.Key; - if (Node.Mappings.TryGetValue(chunk.Key & 0xFFFFF000, out uint remapped)) - chunkId = remapped + (chunkId & 0xFFF); + chunkList[clId + chId] = ((int)(chunkSize & ~0x80000000), (chunkSize & (1 << 31)) != 0); + } - var d = r.ReadBytes(chunk.Value.Item1); + Log.Write("Header data chunk list:"); - if (availableChunkClasses.TryGetValue(chunkId, out Type type)) + foreach (var c in chunkList) { - var constructor = type.GetConstructors().First(); - var constructorParams = constructor.GetParameters(); - if (constructorParams.Length == 0) - { - dynamic headerChunk = constructor.Invoke(new object[0]); - headerChunk.Node = GBX.MainNode; - headerChunk.Part = this; - headerChunk.Stream = new MemoryStream(d, 0, d.Length, false); - if (d == null || d.Length == 0) - headerChunk.Discovered = true; - chunks[counter] = headerChunk; - } - else if (constructorParams.Length == 2) - chunks[counter] = (HeaderChunk)constructor.Invoke(new object[] { GBX.MainNode, d }); - else throw new ArgumentException($"{type.FullName} has an invalid amount of parameters."); + if (c.Value.Item2) + Log.Write($"| 0x{c.Key:x8} | {c.Value.Item1} B (Heavy)"); + else + Log.Write($"| 0x{c.Key:x8} | {c.Value.Item1} B"); + } + + int counter = 0; + foreach (var chunk in chunkList) + { + var chunkId = chunk.Key; + if (Node.Mappings.TryGetValue(chunk.Key & 0xFFFFF000, out uint remapped)) + chunkId = remapped + (chunkId & 0xFFF); + + var d = r.ReadBytes(chunk.Value.Item1); - using (var msChunk = new MemoryStream(d)) - using (var rChunk = new GameBoxReader(msChunk, this)) + if (availableChunkClasses.TryGetValue(chunkId, out Type type)) { - ((IHeaderChunk)chunks[counter]).ReadWrite(new GameBoxReaderWriter(rChunk)); - ((ISkippableChunk)chunks[counter]).Discovered = true; + var constructor = type.GetConstructors().First(); + var constructorParams = constructor.GetParameters(); + if (constructorParams.Length == 0) + { + dynamic headerChunk = constructor.Invoke(new object[0]); + headerChunk.Node = GBX.MainNode; + headerChunk.Part = this; + headerChunk.Stream = new MemoryStream(d, 0, d.Length, false); + if (d == null || d.Length == 0) + headerChunk.Discovered = true; + chunks[counter] = headerChunk; + } + else if (constructorParams.Length == 2) + chunks[counter] = (HeaderChunk)constructor.Invoke(new object[] { GBX.MainNode, d }); + else throw new ArgumentException($"{type.FullName} has an invalid amount of parameters."); + + using (var msChunk = new MemoryStream(d)) + using (var rChunk = new GameBoxReader(msChunk, this)) + { + ((IHeaderChunk)chunks[counter]).ReadWrite(new GameBoxReaderWriter(rChunk)); + ((ISkippableChunk)chunks[counter]).Discovered = true; + } + + ((IHeaderChunk)chunks[counter]).IsHeavy = chunk.Value.Item2; } + else + chunks[counter] = new HeaderChunk(GBX.MainNode, chunkId, d); - ((IHeaderChunk)chunks[counter]).IsHeavy = chunk.Value.Item2; + counter++; } - else - chunks[counter] = new HeaderChunk(GBX.MainNode, chunkId, d); - - counter++; + Chunks = new ChunkList(chunks); } - Chunks = new ChunkList(chunks); } } } @@ -172,43 +173,45 @@ public void Write(GameBoxWriter w, int numNodes, ClassIDRemap remap) if (Version >= 6) { - using var userData = new MemoryStream(); - using var gbxw = new GameBoxWriter(userData, this); - var gbxrw = new GameBoxReaderWriter(gbxw); - - Dictionary lengths = new Dictionary(); - - foreach (var chunk in Chunks) + using (var userData = new MemoryStream()) + using (var gbxw = new GameBoxWriter(userData, this)) { - chunk.Unknown.Position = 0; + var gbxrw = new GameBoxReaderWriter(gbxw); - var pos = userData.Position; - if (((ISkippableChunk)chunk).Discovered) + Dictionary lengths = new Dictionary(); + + foreach (var chunk in Chunks) { - ((IHeaderChunk)chunk).ReadWrite(gbxrw); + chunk.Unknown.Position = 0; + + var pos = userData.Position; + if (((ISkippableChunk)chunk).Discovered) + { + ((IHeaderChunk)chunk).ReadWrite(gbxrw); + } + else + ((ISkippableChunk)chunk).Write(gbxw); + + lengths[chunk.ID] = (int)(userData.Position - pos); } - else - ((ISkippableChunk)chunk).Write(gbxw); - lengths[chunk.ID] = (int)(userData.Position - pos); - } + // Actual data size plus the class id (4 bytes) and each length (4 bytes) plus the number of chunks integer + w.Write((int)userData.Length + Chunks.Count * 8 + 4); - // Actual data size plus the class id (4 bytes) and each length (4 bytes) plus the number of chunks integer - w.Write((int)userData.Length + Chunks.Count * 8 + 4); + // Write number of header chunks integer + w.Write(Chunks.Count); - // Write number of header chunks integer - w.Write(Chunks.Count); + foreach (Chunk chunk in Chunks) + { + w.Write(Chunk.Remap(chunk.ID, remap)); + var length = lengths[chunk.ID]; + if (((IHeaderChunk)chunk).IsHeavy) + length |= 1 << 31; + w.Write(length); + } - foreach (Chunk chunk in Chunks) - { - w.Write(Chunk.Remap(chunk.ID, remap)); - var length = lengths[chunk.ID]; - if (((IHeaderChunk)chunk).IsHeavy) - length |= 1 << 31; - w.Write(length); + w.Write(userData.ToArray(), 0, (int)userData.Length); } - - w.Write(userData.ToArray(), 0, (int)userData.Length); } w.Write(numNodes); diff --git a/GBX.NET/GameBoxReader.cs b/GBX.NET/GameBoxReader.cs index 13e8ed71b..8823d8686 100644 --- a/GBX.NET/GameBoxReader.cs +++ b/GBX.NET/GameBoxReader.cs @@ -84,12 +84,15 @@ public LookbackString ReadLookbackString(ILookbackable lookbackable) } else if ((index & 0x3FFF) == 0x3FFF) { - return (index >> 30) switch + switch(index >> 30) { - 2 => new LookbackString("Unassigned", lookbackable), - 3 => new LookbackString("", lookbackable), - _ => throw new Exception(), - }; + case 2: + return new LookbackString("Unassigned", lookbackable); + case 3: + return new LookbackString("", lookbackable); + default: + throw new Exception(); + } } else if (index >> 30 == 0) { @@ -242,16 +245,16 @@ public T[] ReadArray(Func forLoop) return result; } - public Vector2 ReadVec2() + public Vec2 ReadVec2() { var floats = ReadArray(2); - return new Vector2(floats[0], floats[1]); + return new Vec2(floats[0], floats[1]); } - public Vector3 ReadVec3() + public Vec3 ReadVec3() { var floats = ReadArray(3); - return new Vector3(floats[0], floats[1], floats[2]); + return new Vec3(floats[0], floats[1], floats[2]); } public Int3 ReadInt3() diff --git a/GBX.NET/GameBoxReaderWriter.cs b/GBX.NET/GameBoxReaderWriter.cs index d64076220..4d103fe98 100644 --- a/GBX.NET/GameBoxReaderWriter.cs +++ b/GBX.NET/GameBoxReaderWriter.cs @@ -56,14 +56,16 @@ public void Array(Stream stream, int count) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadArray(count)); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadArray(count)); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadArray(count)); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadArray(count)); } } @@ -90,14 +92,16 @@ public void Boolean(Stream stream) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadBoolean()); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadBoolean()); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadBoolean()); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadBoolean()); } } @@ -112,14 +116,16 @@ public void Byte(Stream stream) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadByte()); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadByte()); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadByte()); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadByte()); } } @@ -152,14 +158,16 @@ public void Bytes(Stream stream, int count) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadBytes(count)); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadBytes(count)); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadBytes(count)); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadBytes(count)); } } @@ -174,14 +182,16 @@ public void FileRef(Stream stream) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadFileRef()); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadFileRef()); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadFileRef()); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadFileRef()); } } @@ -196,14 +206,16 @@ public void Int16(Stream stream) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadInt16()); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadInt16()); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadInt16()); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadInt16()); } } @@ -218,14 +230,16 @@ public void Int32(Stream stream) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadInt32()); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadInt32()); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadInt32()); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadInt32()); } } @@ -240,14 +254,16 @@ public void Int64(Stream stream) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadInt64()); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadInt64()); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadInt64()); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadInt64()); } } @@ -269,14 +285,16 @@ public void UInt32(Stream stream) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadUInt32()); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadUInt32()); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadUInt32()); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadUInt32()); } } @@ -319,14 +337,16 @@ public void LookbackString(Stream stream, ILookbackable lookbackable) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write((string)Reader.ReadLookbackString(lookbackable)); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write((string)Reader.ReadLookbackString(lookbackable)); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(new LookbackString(r.ReadString(), lookbackable)); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(new LookbackString(r.ReadString(), lookbackable)); } } @@ -369,14 +389,16 @@ public void NodeRef(Stream stream, GameBoxBody body) { if (Reader != null) { - using var w = new GameBoxWriter(stream, body); - w.Write(Reader.ReadNodeRef(), body); - w.Flush(); + using (var w = new GameBoxWriter(stream, body)) + { + w.Write(Reader.ReadNodeRef(), body); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, body); - Writer.Write(r.ReadNodeRef(), body); + using (var r = new GameBoxReader(stream, body)) + Writer.Write(r.ReadNodeRef(), body); } } @@ -417,14 +439,16 @@ public void Single(Stream stream) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadSingle()); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadSingle()); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadSingle()); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadSingle()); } } @@ -444,25 +468,27 @@ public void String(Stream stream) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadString()); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadString()); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadString()); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadString()); } } - public Vector2 Vec2(Vector2 variable) + public Vec2 Vec2(Vec2 variable) { if (Reader != null) return Reader.ReadVec2(); else if (Writer != null) Writer.Write(variable); return variable; } - public Vector3 Vec3(Vector3 variable) + public Vec3 Vec3(Vec3 variable) { if (Reader != null) return Reader.ReadVec3(); else if (Writer != null) Writer.Write(variable); @@ -473,14 +499,16 @@ public void Vec3(Stream stream) { if (Reader != null) { - using var w = new GameBoxWriter(stream, Reader.Lookbackable); - w.Write(Reader.ReadVec3()); - w.Flush(); + using (var w = new GameBoxWriter(stream, Reader.Lookbackable)) + { + w.Write(Reader.ReadVec3()); + w.Flush(); + } } else if (Writer != null) { - using var r = new GameBoxReader(stream, Writer.Lookbackable); - Writer.Write(r.ReadVec3()); + using (var r = new GameBoxReader(stream, Writer.Lookbackable)) + Writer.Write(r.ReadVec3()); } } diff --git a/GBX.NET/GameBoxWriter.cs b/GBX.NET/GameBoxWriter.cs index 1677e6ee9..9571f1d20 100644 --- a/GBX.NET/GameBoxWriter.cs +++ b/GBX.NET/GameBoxWriter.cs @@ -95,12 +95,12 @@ public void Write(T[] array, Action forLoop) } } - public void Write(Vector3 value) + public void Write(Vec3 value) { Write(new float[] { value.X, value.Y, value.Z }); } - public void Write(Vector2 value) + public void Write(Vec2 value) { Write(new float[] { value.X, value.Y }); } @@ -117,7 +117,8 @@ public void Write(Int2 value) public void Write(Byte3 value) { - Write(new ReadOnlySpan(new byte[] { value.X, value.Y, value.Z })); + var bytes = new byte[] { value.X, value.Y, value.Z }; + Write(bytes, 0, bytes.Length); } public void Write(FileRef fileRef) diff --git a/GBX.NET/Int3.cs b/GBX.NET/Int3.cs index a554512ff..6fc867ddb 100644 --- a/GBX.NET/Int3.cs +++ b/GBX.NET/Int3.cs @@ -61,7 +61,7 @@ public override int GetHashCode() public static explicit operator Int3(Byte3 a) => new Int3(a.X, a.Y, a.Z); public static explicit operator Int3(Int2 a) => new Int3(a.X, 0, a.Y); - public static implicit operator Vector3(Int3 a) => new Vector3(a.X, a.Y, a.Z); + public static implicit operator Vec3(Int3 a) => new Vec3(a.X, a.Y, a.Z); public static explicit operator Int3(Direction a) { diff --git a/GBX.NET/Item.cs b/GBX.NET/Item.cs index e5b7a463d..7282bb241 100644 --- a/GBX.NET/Item.cs +++ b/GBX.NET/Item.cs @@ -8,10 +8,10 @@ namespace GBX.NET public class Item { public Meta Meta { get; set; } - public Vector3? PitchYawRoll { get; set; } + public Vec3? PitchYawRoll { get; set; } public Int3 BlockCoord { get; set; } - public Vector3 Position { get; set; } - public Vector3? PivotPosition { get; set; } + public Vec3 Position { get; set; } + public Vec3? PivotPosition { get; set; } public float? Scale { get; set; } } } diff --git a/GBX.NET/Log.cs b/GBX.NET/Log.cs index 28cd1b533..8c520c53f 100644 --- a/GBX.NET/Log.cs +++ b/GBX.NET/Log.cs @@ -21,7 +21,9 @@ static Log() public static bool Start(string fileName) { - return AlternativeLogs.TryAdd(fileName, new StringWriter()); + if (AlternativeLogs.ContainsKey(fileName)) return false; + AlternativeLogs[fileName] = new StringWriter(); + return true; } public static void End(string fileName) diff --git a/GBX.NET/Node.cs b/GBX.NET/Node.cs index 21c300a95..ac967734d 100644 --- a/GBX.NET/Node.cs +++ b/GBX.NET/Node.cs @@ -155,7 +155,7 @@ private static Node Parse(Type type, ILookbackable body, GameBoxReader r, out Li { inheritanceClasses = GetInheritance(type); - static List GetInheritance(Type t) + List GetInheritance(Type t) { List classes = new List(); @@ -275,13 +275,16 @@ private static Node Parse(Type type, ILookbackable body, GameBoxReader r, List 0) className = line[6..]; + if (line.Length - 6 > 0) className = line.Substring(6); var classIDString = $"{en}{cl}{ch}"; @@ -493,7 +498,7 @@ static Node() else { en = line.Substring(0, 2); - if (line.Length - 3 > 0) engineName = line[3..]; + if (line.Length - 3 > 0) engineName = line.Substring(3); } } } @@ -649,20 +654,21 @@ public static T FromGBX(GameBox loadedGbx) where T : Node public static T FromGBX(string gbxFile) where T : Node { - using var fs = File.OpenRead(gbxFile); - - var type = GameBox.GetGameBoxType(fs); - fs.Seek(0, SeekOrigin.Begin); + using (var fs = File.OpenRead(gbxFile)) + { + var type = GameBox.GetGameBoxType(fs); + fs.Seek(0, SeekOrigin.Begin); - GameBox gbx; - if (type == null) - gbx = new GameBox(); - else - gbx = (GameBox)Activator.CreateInstance(type); + GameBox gbx; + if (type == null) + gbx = new GameBox(); + else + gbx = (GameBox)Activator.CreateInstance(type); - if (gbx.Read(fs)) - return FromGBX((GameBox)gbx); - return default; + if (gbx.Read(fs)) + return FromGBX((GameBox)gbx); + return default; + } } } } diff --git a/GBX.NET/SkippableChunk.cs b/GBX.NET/SkippableChunk.cs index 349d5cb1f..c85e8b7c5 100644 --- a/GBX.NET/SkippableChunk.cs +++ b/GBX.NET/SkippableChunk.cs @@ -46,25 +46,26 @@ public void Discover() if (Discovered) return; Discovered = true; - using var gbxr = new GameBoxReader(Stream, Lookbackable); - - GameBoxReaderWriter gbxrw = new GameBoxReaderWriter(gbxr); - - try - { - ReadWrite(Node, gbxrw); - } - catch (NotImplementedException) + using (var gbxr = new GameBoxReader(Stream, Lookbackable)) { - var unknownGbxw = new GameBoxWriter(Unknown, Lookbackable); + GameBoxReaderWriter gbxrw = new GameBoxReaderWriter(gbxr); try { - Read(Node, gbxr, unknownGbxw); + ReadWrite(Node, gbxrw); } - catch (NotImplementedException e) + catch (NotImplementedException) { - Debug.WriteLine(e.Message); + var unknownGbxw = new GameBoxWriter(Unknown, Lookbackable); + + try + { + Read(Node, gbxr, unknownGbxw); + } + catch (NotImplementedException e) + { + Debug.WriteLine(e.Message); + } } } diff --git a/GBX.NET/Vec2.cs b/GBX.NET/Vec2.cs new file mode 100644 index 000000000..d1a730df8 --- /dev/null +++ b/GBX.NET/Vec2.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBX.NET +{ + public struct Vec2 + { + public float X { get; } + public float Y { get; } + + public Vec2(float x, float y) + { + X = x; + Y = y; + } + + public override string ToString() + { + return $"({X}, {Y})"; + } + + public static implicit operator Vec2((float x, float y) v) + { + return new Vec2(v.x, v.y); + } + + public static implicit operator (float x, float y)(Vec2 v) + { + return (v.X, v.Y); + } + } +} diff --git a/GBX.NET/Vec3.cs b/GBX.NET/Vec3.cs new file mode 100644 index 000000000..25f36b49a --- /dev/null +++ b/GBX.NET/Vec3.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBX.NET +{ + public struct Vec3 + { + public float X { get; } + public float Y { get; } + public float Z { get; } + + public Vec3(float x, float y, float z) + { + X = x; + Y = y; + Z = z; + } + + public override string ToString() + { + return $"({X}, {Y})"; + } + + public static implicit operator Vec3((float x, float y, float z) v) + { + return new Vec3(v.x, v.y, v.z); + } + + public static implicit operator (float x, float y, float z)(Vec3 v) + { + return (v.X, v.Y, v.Z); + } + + public static Vec3 operator +(Vec3 a, Vec3 b) => new Vec3(a.X + b.X, a.Y + b.Y, a.Z + b.Z); + } +} diff --git a/IslandConverter/ConverterForm.Designer.cs b/IslandConverter/ConverterForm.Designer.cs index cda565b01..974b721bf 100644 --- a/IslandConverter/ConverterForm.Designer.cs +++ b/IslandConverter/ConverterForm.Designer.cs @@ -95,10 +95,9 @@ private void InitializeComponent() // this.pbThumbnail.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.pbThumbnail.Location = new System.Drawing.Point(8, 255); - this.pbThumbnail.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.pbThumbnail.Location = new System.Drawing.Point(7, 221); this.pbThumbnail.Name = "pbThumbnail"; - this.pbThumbnail.Size = new System.Drawing.Size(245, 238); + this.pbThumbnail.Size = new System.Drawing.Size(210, 206); this.pbThumbnail.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; this.pbThumbnail.TabIndex = 1; this.pbThumbnail.TabStop = false; @@ -109,11 +108,10 @@ private void InitializeComponent() this.bConvertAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.bConvertAll.Enabled = false; this.bConvertAll.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.bConvertAll.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); - this.bConvertAll.Location = new System.Drawing.Point(495, 258); - this.bConvertAll.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.bConvertAll.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold); + this.bConvertAll.Location = new System.Drawing.Point(424, 264); this.bConvertAll.Name = "bConvertAll"; - this.bConvertAll.Size = new System.Drawing.Size(188, 39); + this.bConvertAll.Size = new System.Drawing.Size(161, 34); this.bConvertAll.TabIndex = 2; this.bConvertAll.Text = "Convert all maps"; this.bConvertAll.UseVisualStyleBackColor = true; @@ -138,12 +136,10 @@ private void InitializeComponent() this.groupBox1.Controls.Add(this.lUID); this.groupBox1.Controls.Add(this.lMapName); this.groupBox1.Controls.Add(this.pbThumbnail); - this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F); this.groupBox1.Location = new System.Drawing.Point(0, 0); - this.groupBox1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox1.Size = new System.Drawing.Size(262, 501); + this.groupBox1.Size = new System.Drawing.Size(225, 434); this.groupBox1.TabIndex = 3; this.groupBox1.TabStop = false; this.groupBox1.Text = "Selected map"; @@ -152,7 +148,7 @@ private void InitializeComponent() // this.lBlockRange.Anchor = System.Windows.Forms.AnchorStyles.Top; this.lBlockRange.AutoSize = true; - this.lBlockRange.Location = new System.Drawing.Point(13, 212); + this.lBlockRange.Location = new System.Drawing.Point(11, 184); this.lBlockRange.Name = "lBlockRange"; this.lBlockRange.Size = new System.Drawing.Size(75, 15); this.lBlockRange.TabIndex = 4; @@ -162,7 +158,7 @@ private void InitializeComponent() // this.lMapType.Anchor = System.Windows.Forms.AnchorStyles.Top; this.lMapType.AutoSize = true; - this.lMapType.Location = new System.Drawing.Point(13, 197); + this.lMapType.Location = new System.Drawing.Point(11, 171); this.lMapType.Name = "lMapType"; this.lMapType.Size = new System.Drawing.Size(60, 15); this.lMapType.TabIndex = 4; @@ -172,7 +168,7 @@ private void InitializeComponent() // this.lBronzeM.Anchor = System.Windows.Forms.AnchorStyles.Top; this.lBronzeM.AutoSize = true; - this.lBronzeM.Location = new System.Drawing.Point(21, 182); + this.lBronzeM.Location = new System.Drawing.Point(18, 158); this.lBronzeM.Name = "lBronzeM"; this.lBronzeM.Size = new System.Drawing.Size(49, 15); this.lBronzeM.TabIndex = 4; @@ -182,7 +178,7 @@ private void InitializeComponent() // this.lSilverM.Anchor = System.Windows.Forms.AnchorStyles.Top; this.lSilverM.AutoSize = true; - this.lSilverM.Location = new System.Drawing.Point(21, 167); + this.lSilverM.Location = new System.Drawing.Point(18, 145); this.lSilverM.Name = "lSilverM"; this.lSilverM.Size = new System.Drawing.Size(40, 15); this.lSilverM.TabIndex = 4; @@ -192,7 +188,7 @@ private void InitializeComponent() // this.lGoldM.Anchor = System.Windows.Forms.AnchorStyles.Top; this.lGoldM.AutoSize = true; - this.lGoldM.Location = new System.Drawing.Point(21, 152); + this.lGoldM.Location = new System.Drawing.Point(18, 132); this.lGoldM.Name = "lGoldM"; this.lGoldM.Size = new System.Drawing.Size(36, 15); this.lGoldM.TabIndex = 4; @@ -202,7 +198,7 @@ private void InitializeComponent() // this.lAuthorM.Anchor = System.Windows.Forms.AnchorStyles.Top; this.lAuthorM.AutoSize = true; - this.lAuthorM.Location = new System.Drawing.Point(21, 137); + this.lAuthorM.Location = new System.Drawing.Point(18, 119); this.lAuthorM.Name = "lAuthorM"; this.lAuthorM.Size = new System.Drawing.Size(45, 15); this.lAuthorM.TabIndex = 4; @@ -212,7 +208,7 @@ private void InitializeComponent() // this.lMedals.Anchor = System.Windows.Forms.AnchorStyles.Top; this.lMedals.AutoSize = true; - this.lMedals.Location = new System.Drawing.Point(13, 122); + this.lMedals.Location = new System.Drawing.Point(11, 106); this.lMedals.Name = "lMedals"; this.lMedals.Size = new System.Drawing.Size(51, 15); this.lMedals.TabIndex = 4; @@ -222,7 +218,7 @@ private void InitializeComponent() // this.lDecoration.Anchor = System.Windows.Forms.AnchorStyles.Top; this.lDecoration.AutoSize = true; - this.lDecoration.Location = new System.Drawing.Point(13, 105); + this.lDecoration.Location = new System.Drawing.Point(11, 91); this.lDecoration.Name = "lDecoration"; this.lDecoration.Size = new System.Drawing.Size(70, 15); this.lDecoration.TabIndex = 4; @@ -232,7 +228,7 @@ private void InitializeComponent() // this.lSize.Anchor = System.Windows.Forms.AnchorStyles.Top; this.lSize.AutoSize = true; - this.lSize.Location = new System.Drawing.Point(13, 90); + this.lSize.Location = new System.Drawing.Point(11, 78); this.lSize.Name = "lSize"; this.lSize.Size = new System.Drawing.Size(34, 15); this.lSize.TabIndex = 4; @@ -242,7 +238,7 @@ private void InitializeComponent() // this.lAuthor.Anchor = System.Windows.Forms.AnchorStyles.Top; this.lAuthor.AutoSize = true; - this.lAuthor.Location = new System.Drawing.Point(13, 75); + this.lAuthor.Location = new System.Drawing.Point(11, 65); this.lAuthor.Name = "lAuthor"; this.lAuthor.Size = new System.Drawing.Size(45, 15); this.lAuthor.TabIndex = 4; @@ -252,7 +248,7 @@ private void InitializeComponent() // this.lUID.Anchor = System.Windows.Forms.AnchorStyles.Top; this.lUID.AutoSize = true; - this.lUID.Location = new System.Drawing.Point(13, 60); + this.lUID.Location = new System.Drawing.Point(11, 52); this.lUID.Name = "lUID"; this.lUID.Size = new System.Drawing.Size(31, 15); this.lUID.TabIndex = 3; @@ -261,10 +257,10 @@ private void InitializeComponent() // lMapName // this.lMapName.Anchor = System.Windows.Forms.AnchorStyles.Top; - this.lMapName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.lMapName.Location = new System.Drawing.Point(13, 27); + this.lMapName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F); + this.lMapName.Location = new System.Drawing.Point(11, 23); this.lMapName.Name = "lMapName"; - this.lMapName.Size = new System.Drawing.Size(235, 23); + this.lMapName.Size = new System.Drawing.Size(201, 20); this.lMapName.TabIndex = 2; this.lMapName.Text = "[MAP NAME]"; this.lMapName.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; @@ -278,10 +274,9 @@ private void InitializeComponent() this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.panel1.Controls.Add(this.lbLog); this.panel1.ForeColor = System.Drawing.SystemColors.ControlLightLight; - this.panel1.Location = new System.Drawing.Point(7, 22); - this.panel1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.panel1.Location = new System.Drawing.Point(6, 19); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(669, 167); + this.panel1.Size = new System.Drawing.Size(574, 105); this.panel1.TabIndex = 4; // // lbLog @@ -292,7 +287,7 @@ private void InitializeComponent() this.lbLog.ItemHeight = 15; this.lbLog.Location = new System.Drawing.Point(0, 0); this.lbLog.Name = "lbLog"; - this.lbLog.Size = new System.Drawing.Size(667, 165); + this.lbLog.Size = new System.Drawing.Size(572, 103); this.lbLog.TabIndex = 0; // // groupBox2 @@ -301,12 +296,10 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.groupBox2.Controls.Add(this.panel1); - this.groupBox2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.groupBox2.Location = new System.Drawing.Point(7, 0); - this.groupBox2.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.groupBox2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F); + this.groupBox2.Location = new System.Drawing.Point(6, 0); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox2.Size = new System.Drawing.Size(683, 196); + this.groupBox2.Size = new System.Drawing.Size(585, 130); this.groupBox2.TabIndex = 5; this.groupBox2.TabStop = false; this.groupBox2.Text = "Output"; @@ -321,9 +314,8 @@ private void InitializeComponent() this.toolStripMenuItem2}); this.ProgramMenuStrip.Location = new System.Drawing.Point(0, 0); this.ProgramMenuStrip.Name = "ProgramMenuStrip"; - this.ProgramMenuStrip.Padding = new System.Windows.Forms.Padding(7, 2, 0, 2); this.ProgramMenuStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; - this.ProgramMenuStrip.Size = new System.Drawing.Size(960, 24); + this.ProgramMenuStrip.Size = new System.Drawing.Size(823, 24); this.ProgramMenuStrip.TabIndex = 5; this.ProgramMenuStrip.Text = "File"; // @@ -403,11 +395,10 @@ private void InitializeComponent() // this.bOpenFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.bOpenFolder.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.bOpenFolder.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.bOpenFolder.Location = new System.Drawing.Point(14, 258); - this.bOpenFolder.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.bOpenFolder.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F); + this.bOpenFolder.Location = new System.Drawing.Point(12, 264); this.bOpenFolder.Name = "bOpenFolder"; - this.bOpenFolder.Size = new System.Drawing.Size(188, 39); + this.bOpenFolder.Size = new System.Drawing.Size(161, 34); this.bOpenFolder.TabIndex = 7; this.bOpenFolder.Text = "Open Maps folder"; this.bOpenFolder.UseVisualStyleBackColor = true; @@ -420,12 +411,10 @@ private void InitializeComponent() this.groupBox3.Controls.Add(this.x45Button); this.groupBox3.Controls.Add(this.x32Button); this.groupBox3.Controls.Add(this.x31Button); - this.groupBox3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.groupBox3.Location = new System.Drawing.Point(7, 110); - this.groupBox3.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.groupBox3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F); + this.groupBox3.Location = new System.Drawing.Point(6, 135); this.groupBox3.Name = "groupBox3"; - this.groupBox3.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.groupBox3.Size = new System.Drawing.Size(679, 114); + this.groupBox3.Size = new System.Drawing.Size(582, 99); this.groupBox3.TabIndex = 8; this.groupBox3.TabStop = false; this.groupBox3.Text = "Map base size"; @@ -434,8 +423,7 @@ private void InitializeComponent() // this.x45Button.AutoSize = true; this.x45Button.Checked = true; - this.x45Button.Location = new System.Drawing.Point(7, 82); - this.x45Button.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.x45Button.Location = new System.Drawing.Point(6, 71); this.x45Button.Name = "x45Button"; this.x45Button.Size = new System.Drawing.Size(592, 19); this.x45Button.TabIndex = 6; @@ -448,8 +436,7 @@ private void InitializeComponent() // x32Button // this.x32Button.AutoSize = true; - this.x32Button.Location = new System.Drawing.Point(7, 52); - this.x32Button.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.x32Button.Location = new System.Drawing.Point(6, 45); this.x32Button.Name = "x32Button"; this.x32Button.Size = new System.Drawing.Size(612, 19); this.x32Button.TabIndex = 6; @@ -462,8 +449,7 @@ private void InitializeComponent() // x31Button // this.x31Button.AutoSize = true; - this.x31Button.Location = new System.Drawing.Point(7, 23); - this.x31Button.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.x31Button.Location = new System.Drawing.Point(6, 20); this.x31Button.Name = "x31Button"; this.x31Button.Size = new System.Drawing.Size(527, 19); this.x31Button.TabIndex = 6; @@ -478,11 +464,10 @@ private void InitializeComponent() this.bConvertSelected.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.bConvertSelected.Enabled = false; this.bConvertSelected.FlatStyle = System.Windows.Forms.FlatStyle.System; - this.bConvertSelected.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.bConvertSelected.Location = new System.Drawing.Point(299, 258); - this.bConvertSelected.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + this.bConvertSelected.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F); + this.bConvertSelected.Location = new System.Drawing.Point(256, 264); this.bConvertSelected.Name = "bConvertSelected"; - this.bConvertSelected.Size = new System.Drawing.Size(188, 39); + this.bConvertSelected.Size = new System.Drawing.Size(161, 34); this.bConvertSelected.TabIndex = 2; this.bConvertSelected.Text = "Convert selected maps"; this.bConvertSelected.UseVisualStyleBackColor = true; @@ -494,7 +479,6 @@ private void InitializeComponent() this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; this.splitContainer1.Location = new System.Drawing.Point(0, 0); - this.splitContainer1.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); this.splitContainer1.Name = "splitContainer1"; this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; // @@ -514,9 +498,8 @@ private void InitializeComponent() // this.splitContainer1.Panel2.Controls.Add(this.groupBox2); this.splitContainer1.Panel2MinSize = 100; - this.splitContainer1.Size = new System.Drawing.Size(690, 508); + this.splitContainer1.Size = new System.Drawing.Size(591, 440); this.splitContainer1.SplitterDistance = 300; - this.splitContainer1.SplitterWidth = 5; this.splitContainer1.TabIndex = 9; // // cbIgnoreMediaTracker @@ -524,9 +507,9 @@ private void InitializeComponent() this.cbIgnoreMediaTracker.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.cbIgnoreMediaTracker.AutoSize = true; this.cbIgnoreMediaTracker.CheckAlign = System.Drawing.ContentAlignment.MiddleRight; - this.cbIgnoreMediaTracker.Location = new System.Drawing.Point(550, 232); + this.cbIgnoreMediaTracker.Location = new System.Drawing.Point(460, 241); this.cbIgnoreMediaTracker.Name = "cbIgnoreMediaTracker"; - this.cbIgnoreMediaTracker.Size = new System.Drawing.Size(133, 19); + this.cbIgnoreMediaTracker.Size = new System.Drawing.Size(125, 17); this.cbIgnoreMediaTracker.TabIndex = 10; this.cbIgnoreMediaTracker.Text = "Ignore MediaTracker"; this.cbIgnoreMediaTracker.UseVisualStyleBackColor = true; @@ -536,9 +519,9 @@ private void InitializeComponent() this.cbCutoff.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.cbCutoff.AutoSize = true; this.cbCutoff.Enabled = false; - this.cbCutoff.Location = new System.Drawing.Point(14, 232); + this.cbCutoff.Location = new System.Drawing.Point(12, 241); this.cbCutoff.Name = "cbCutoff"; - this.cbCutoff.Size = new System.Drawing.Size(236, 19); + this.cbCutoff.Size = new System.Drawing.Size(216, 17); this.cbCutoff.TabIndex = 10; this.cbCutoff.Text = "Remove blocks outside of the map base"; this.cbCutoff.UseVisualStyleBackColor = true; @@ -553,9 +536,9 @@ private void InitializeComponent() this.lvMaps.Items.AddRange(new System.Windows.Forms.ListViewItem[] { listViewItem1}); this.lvMaps.LargeImageList = this.ilThumbnails; - this.lvMaps.Location = new System.Drawing.Point(7, 6); + this.lvMaps.Location = new System.Drawing.Point(6, 5); this.lvMaps.Name = "lvMaps"; - this.lvMaps.Size = new System.Drawing.Size(679, 98); + this.lvMaps.Size = new System.Drawing.Size(583, 125); this.lvMaps.TabIndex = 9; this.lvMaps.UseCompatibleStateImageBehavior = false; this.lvMaps.View = System.Windows.Forms.View.Tile; @@ -586,23 +569,23 @@ private void InitializeComponent() // this.splitContainer2.Panel2.Controls.Add(this.groupBox1); this.splitContainer2.Panel2MinSize = 260; - this.splitContainer2.Size = new System.Drawing.Size(960, 508); + this.splitContainer2.Size = new System.Drawing.Size(823, 437); this.splitContainer2.SplitterDistance = 690; + this.splitContainer2.SplitterWidth = 3; this.splitContainer2.TabIndex = 10; this.splitContainer2.Text = "splitContainer2"; // // ConverterForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScroll = true; - this.ClientSize = new System.Drawing.Size(960, 532); + this.ClientSize = new System.Drawing.Size(823, 461); this.Controls.Add(this.splitContainer2); this.Controls.Add(this.ProgramMenuStrip); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MainMenuStrip = this.ProgramMenuStrip; - this.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - this.MinimumSize = new System.Drawing.Size(976, 571); + this.MinimumSize = new System.Drawing.Size(839, 500); this.Name = "ConverterForm"; this.Text = "Island Converter by BigBang1112"; ((System.ComponentModel.ISupportInitialize)(this.pbThumbnail)).EndInit(); diff --git a/IslandConverter/ConverterForm.cs b/IslandConverter/ConverterForm.cs index 14f8a65f4..590dab5ed 100644 --- a/IslandConverter/ConverterForm.cs +++ b/IslandConverter/ConverterForm.cs @@ -100,7 +100,8 @@ void LoadMaps(params string[] fileNames) if (Maps.ContainsKey(mapUid)) containsMap = false; - Maps.TryAdd(mapUid, gbx); + if(!Maps.ContainsKey(mapUid)) + Maps.Add(mapUid, gbx); item.Name = mapUid; @@ -407,7 +408,7 @@ string SetOpenFolder() folderName = ofd.FileName; Serializer s = new Serializer(); - var output = s.Serialize(new Dictionary(new KeyValuePair[] { new KeyValuePair("ManiaPlanetMapsFolder", folderName) })); + var output = s.Serialize(new Dictionary { { "ManiaPlanetMapsFolder", folderName } }); File.WriteAllText("Config.yaml", output); } } diff --git a/IslandConverter/ConverterForm.resx b/IslandConverter/ConverterForm.resx index dfe6cdf79..78d3fcd33 100644 --- a/IslandConverter/ConverterForm.resx +++ b/IslandConverter/ConverterForm.resx @@ -1,4 +1,64 @@ - + + + @@ -57,8 +117,17 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - + + 17, 17 + + + 172, 17 + + + 292, 17 + + + AAABAAUAEBAAAAEAIABoBAAAVgAAABgYAAABACAAiAkAAL4EAAAgIAAAAQAgAKgQAABGDgAAMDAAAAEA IACoJQAA7h4AAAAAAAABACAATOwAAJZEAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAANCwAADQsAAAAA diff --git a/IslandConverter/IslandConverter.cs b/IslandConverter/IslandConverter.cs index fc8f56126..bbe5170a8 100644 --- a/IslandConverter/IslandConverter.cs +++ b/IslandConverter/IslandConverter.cs @@ -150,7 +150,7 @@ internal static List CreateWaterBlocks(Int3 mapSize, List islandBl blocks.Add(new Block("StadiumPool2", dir, (x, yOffset, z), flag, null, null, null)); } - else if (islandBlockDictionary.TryGetValue(new Int3(Convert.ToInt32(MathF.Floor(x / 2f) - 1), 0, Convert.ToInt32(MathF.Floor(z / 2f) - 1)), out Block bl)) + else if (islandBlockDictionary.TryGetValue(new Int3(Convert.ToInt32(Math.Floor(x / 2f) - 1), 0, Convert.ToInt32(Math.Floor(z / 2f) - 1)), out Block bl)) { blocks.Add(new Block("RemoveGrass.Block.Gbx_CustomBlock", Direction.North, (x, yOffset, z), 135168, null, null, null)); } @@ -183,22 +183,18 @@ internal static void ConvertToTM2Island(GameBox gbx, TimeSpan Log.Write("Setting player model..."); - var carTranslations = new Dictionary( - new KeyValuePair[] - { - KeyValuePair.Create("", "IslandCar"), - KeyValuePair.Create("American", "DesertCar"), - KeyValuePair.Create("DesertCar", "DesertCar"), - KeyValuePair.Create("Rally", "RallyCar"), - KeyValuePair.Create("RallyCar", "RallyCar"), - KeyValuePair.Create("SnowCar", "SnowCar"), - KeyValuePair.Create("SportCar", "IslandCar"), - KeyValuePair.Create("IslandCar", "IslandCar"), - KeyValuePair.Create("CoastCar", "CoastCar"), - KeyValuePair.Create("BayCar", "BayCar"), - KeyValuePair.Create("StadiumCar", ""), - } - ); + var carTranslations = new Dictionary(); + carTranslations[""] = "IslandCar"; + carTranslations["American"] = "DesertCar"; + carTranslations["DesertCar"] = "DesertCar"; + carTranslations["Rally"] = "RallyCar"; + carTranslations["RallyCar"] = "RallyCar"; + carTranslations["SnowCar"] = "SnowCar"; + carTranslations["SportCar"] = "IslandCar"; + carTranslations["IslandCar"] = "IslandCar"; + carTranslations["CoastCar"] = "CoastCar"; + carTranslations["BayCar"] = "BayCar"; + carTranslations["StadiumCar"] = ""; var chunk00D = map.GetChunk(); @@ -302,23 +298,23 @@ internal static void ConvertToTM2Island(GameBox gbx, TimeSpan Log.Write("All additional terrain blocks removed!"); - static bool RemoveGroundBlocks(Block block, Block block2, BlockConversion variantGround, int[] unit) + bool RemoveGroundBlocks(Block block, Block block2, BlockConversion variantGround, int[] unit) { if (unit.Length < 3) throw new FormatException(); - Vector3 centerFromCoord = default; + Vec3 centerFromCoord = default; if (variantGround.CenterFromCoord != null) if (variantGround.CenterFromCoord.Length >= 3) - centerFromCoord = new Vector3(variantGround.CenterFromCoord[0], variantGround.CenterFromCoord[1], variantGround.CenterFromCoord[2]); + centerFromCoord = new Vec3(variantGround.CenterFromCoord[0], variantGround.CenterFromCoord[1], variantGround.CenterFromCoord[2]); - var radians = (((int)block.Direction + variantGround.OffsetDirection.GetValueOrDefault()) % 4) * (MathF.PI / 2); + var radians = (((int)block.Direction + variantGround.OffsetDirection.GetValueOrDefault()) % 4) * ((float)Math.PI / 2); - var unit2 = (Convert.ToInt32(MathF.Cos(radians) * (unit[0] - centerFromCoord.X) - - MathF.Sin(radians) * (unit[2] - centerFromCoord.Z) + centerFromCoord.X), + var unit2 = (Convert.ToInt32(Math.Cos(radians) * (unit[0] - centerFromCoord.X) - + Math.Sin(radians) * (unit[2] - centerFromCoord.Z) + centerFromCoord.X), unit[1], // not supported yet - Convert.ToInt32(MathF.Sin(radians) * (unit[0] - centerFromCoord.X) + - MathF.Cos(radians) * (unit[2] - centerFromCoord.Z) + centerFromCoord.Z)); + Convert.ToInt32(Math.Sin(radians) * (unit[0] - centerFromCoord.X) + + Math.Cos(radians) * (unit[2] - centerFromCoord.Z) + centerFromCoord.Z)); if (block.Name == "IslandHills6DecoRock" && block2.Name == "IslandHills6") { @@ -424,7 +420,7 @@ static bool RemoveGroundBlocks(Block block, Block block2, BlockConversion varian { gbx.MainNode.TransferMediaTrackerTo049(6); - var xzCameraOffset = new Vector3(); + var xzCameraOffset = new Vec3(); var xzTriggerOffset = new Int3(); if (size == MapSize.X45WithSmallBorder) @@ -433,7 +429,7 @@ static bool RemoveGroundBlocks(Block block, Block block2, BlockConversion varian } else { - xzCameraOffset = new Vector3(offset.X * 64 - 128, offset.Y * 64, offset.Z * 64 - 192); + xzCameraOffset = new Vec3(offset.X * 64 - 128, offset.Y * 64, offset.Z * 64 - 192); xzTriggerOffset = (6 + offset.X * 6, -3, 6 + offset.X * 6); if (size == MapSize.X31WithSmallBorder) xzTriggerOffset += (0, 1, 0); @@ -441,7 +437,7 @@ static bool RemoveGroundBlocks(Block block, Block block2, BlockConversion varian gbx.MainNode.OffsetMediaTrackerTriggers(xzTriggerOffset); - gbx.MainNode.OffsetMediaTrackerCameras(new Vector3(64, -6 - offsetHeight, 64) + xzCameraOffset); + gbx.MainNode.OffsetMediaTrackerCameras(new Vec3(64, -6 - offsetHeight, 64) + xzCameraOffset); } var chunk003 = gbx.Header.Result.GetChunk(); @@ -489,11 +485,11 @@ static bool RemoveGroundBlocks(Block block, Block block2, BlockConversion varian { case MapSize.X32WithBigBorder: Log.Write("Placing the background item..."); - gbx.MainNode.PlaceItem(("Island\\8Terrain\\7BackGround\\Background.Item.gbx", "10003", "adamkooo"), new Vector3(), new Vector3(), new Byte3(), new Vector3(1024, 9, 1024)); + gbx.MainNode.PlaceItem(("Island\\8Terrain\\7BackGround\\Background.Item.gbx", "10003", "adamkooo"), new Vec3(), new Vec3(), new Byte3(), new Vec3(1024, 9, 1024)); break; case MapSize.X45WithSmallBorder: Log.Write("Placing the background item..."); - gbx.MainNode.PlaceItem(("Island\\8Terrain\\6BigBackground\\Background_45x45.Item.gbx", "10003", "adamkooo"), new Vector3(), new Vector3(), new Byte3(), new Vector3(1504, 17, 1504)); + gbx.MainNode.PlaceItem(("Island\\8Terrain\\6BigBackground\\Background_45x45.Item.gbx", "10003", "adamkooo"), new Vec3(), new Vec3(), new Byte3(), new Vec3(1504, 17, 1504)); break; default: Log.Write($"Island background is not supported for {size}.", ConsoleColor.Yellow); @@ -555,74 +551,74 @@ static bool RemoveGroundBlocks(Block block, Block block2, BlockConversion varian else DoConversion(variant); - void DoConversion(BlockConversion conversion, bool? isItemGround = null) + void DoConversion(BlockConversion conv, bool? isItemGround = null) { - if (conversion.ItemModel.Length > 0 && !string.IsNullOrEmpty(conversion.ItemModel[0])) + if (conv.ItemModel.Length > 0 && !string.IsNullOrEmpty(conv.ItemModel[0])) { var modelToChoose = 0; - if (conversion.Clip != null) + if (conv.Clip != null) { } else - modelToChoose = randomizer.Next(0, conversion.ItemModel.Length); + modelToChoose = randomizer.Next(0, conv.ItemModel.Length); - var itemModel = conversion.ItemModel[modelToChoose]; + var itemModel = conv.ItemModel[modelToChoose]; var itemModelSplit = itemModel.Split(' '); var meta = new Meta("Island\\" + itemModelSplit[0], itemModelSplit.Length > 1 ? itemModelSplit[1] : "10003", itemModelSplit.Length > 2 ? itemModelSplit[2] : "adamkooo"); - Vector3 offsetAbsolutePosition = new Vector3(block.Coord.X * 64 + 96, block.Coord.Y * 8 - offsetHeight, block.Coord.Z * 64 + 96); - if (conversion.OffsetAbsolutePosition != null) + Vec3 offsetAbsolutePosition = new Vec3(block.Coord.X * 64 + 96, block.Coord.Y * 8 - offsetHeight, block.Coord.Z * 64 + 96); + if (conv.OffsetAbsolutePosition != null) { - if (conversion.OffsetAbsolutePosition.Length >= 3) - offsetAbsolutePosition += new Vector3( - conversion.OffsetAbsolutePosition[0], - conversion.OffsetAbsolutePosition[1], - conversion.OffsetAbsolutePosition[2]); - else if (conversion.OffsetAbsolutePosition.Length != 0) - throw new FormatException($"Wrong format of OffsetAbsolutePosition: {block.Name} -> index {block.Variant} -> [{string.Join(", ", conversion.OffsetAbsolutePosition)}]"); + if (conv.OffsetAbsolutePosition.Length >= 3) + offsetAbsolutePosition += new Vec3( + conv.OffsetAbsolutePosition[0], + conv.OffsetAbsolutePosition[1], + conv.OffsetAbsolutePosition[2]); + else if (conv.OffsetAbsolutePosition.Length != 0) + throw new FormatException($"Wrong format of OffsetAbsolutePosition: {block.Name} -> index {block.Variant} -> [{string.Join(", ", conv.OffsetAbsolutePosition)}]"); } - Vector3 offsetPivot = new Vector3(0, 2, 0); - if (conversion.OffsetPivot != null) + Vec3 offsetPivot = new Vec3(0, 2, 0); + if (conv.OffsetPivot != null) { - if (conversion.OffsetPivot.Length >= 3) - offsetPivot += new Vector3( - conversion.OffsetPivot[0], - conversion.OffsetPivot[1], - conversion.OffsetPivot[2]); - else if (conversion.OffsetPivot.Length != 0) - throw new FormatException($"Wrong format of OffsetPivot: {block.Name} -> index {block.Variant} -> [{string.Join(", ", conversion.OffsetPivot)}]"); + if (conv.OffsetPivot.Length >= 3) + offsetPivot += new Vec3( + conv.OffsetPivot[0], + conv.OffsetPivot[1], + conv.OffsetPivot[2]); + else if (conv.OffsetPivot.Length != 0) + throw new FormatException($"Wrong format of OffsetPivot: {block.Name} -> index {block.Variant} -> [{string.Join(", ", conv.OffsetPivot)}]"); } var offsetDirection = 0; - if (conversion.OffsetDirection.HasValue) + if (conv.OffsetDirection.HasValue) { - if (conversion.OffsetDirection.Value >= 0 && conversion.OffsetDirection.Value < 4) - offsetDirection = conversion.OffsetDirection.Value; + if (conv.OffsetDirection.Value >= 0 && conv.OffsetDirection.Value < 4) + offsetDirection = conv.OffsetDirection.Value; else - throw new FormatException($"Wrong format of OffsetDirection: {block.Name} -> index {block.Variant} -> {conversion.OffsetDirection}"); + throw new FormatException($"Wrong format of OffsetDirection: {block.Name} -> index {block.Variant} -> {conv.OffsetDirection}"); } var dir = 3 - (((int)block.Direction + offsetDirection) % 4); - if (conversion.InverseDirection.GetValueOrDefault() == true) + if (conv.InverseDirection.GetValueOrDefault() == true) dir = 3 - dir; - if (conversion.Directions != null) + if (conv.Directions != null) { - for (var i = 0; i < conversion.Directions.Length; i++) + for (var i = 0; i < conv.Directions.Length; i++) { - var direction = conversion.Directions[i]; + var direction = conv.Directions[i]; if (direction != null) { if (i == dir && direction.OffsetAbsolutePosition != null && direction.OffsetAbsolutePosition.Length >= 3) - offsetAbsolutePosition += new Vector3( + offsetAbsolutePosition += new Vec3( direction.OffsetAbsolutePosition[0], direction.OffsetAbsolutePosition[1], direction.OffsetAbsolutePosition[2]); if (i == dir && direction.OffsetPivot != null && direction.OffsetPivot.Length >= 3) - offsetPivot += new Vector3( + offsetPivot += new Vec3( direction.OffsetPivot[0], direction.OffsetPivot[1], direction.OffsetPivot[2]); @@ -630,33 +626,33 @@ void DoConversion(BlockConversion conversion, bool? isItemGround = null) } } - Vector3 offsetPitchYawRoll = new Vector3(dir * 90f / 180 * MathF.PI, 0, 0); - if (conversion.OffsetPitchYawRoll != null) + Vec3 offsetPitchYawRoll = new Vec3(dir * 90f / 180 * (float)Math.PI, 0, 0); + if (conv.OffsetPitchYawRoll != null) { - if (conversion.OffsetPitchYawRoll.Length >= 3) - offsetPitchYawRoll = new Vector3( - conversion.OffsetPitchYawRoll[0] / 180 * MathF.PI, - conversion.OffsetPitchYawRoll[1] / 180 * MathF.PI, - conversion.OffsetPitchYawRoll[2] / 180 * MathF.PI); - else if (conversion.OffsetPitchYawRoll.Length != 0) - throw new FormatException($"Wrong format of OffsetPitchYawRoll: {block.Name} -> index {block.Variant} -> [{string.Join(", ", conversion.OffsetPitchYawRoll)}]"); + if (conv.OffsetPitchYawRoll.Length >= 3) + offsetPitchYawRoll = new Vec3( + conv.OffsetPitchYawRoll[0] / 180 * (float)Math.PI, + conv.OffsetPitchYawRoll[1] / 180 * (float)Math.PI, + conv.OffsetPitchYawRoll[2] / 180 * (float)Math.PI); + else if (conv.OffsetPitchYawRoll.Length != 0) + throw new FormatException($"Wrong format of OffsetPitchYawRoll: {block.Name} -> index {block.Variant} -> [{string.Join(", ", conv.OffsetPitchYawRoll)}]"); } gbx.MainNode.PlaceItem(meta, offsetAbsolutePosition, offsetPitchYawRoll, (0, 0, 0), offsetPivot); - Vector3 skinPosOffset = default; - if (conversion.SkinPositionOffset != null) - if (conversion.SkinPositionOffset.Length >= 3) - skinPosOffset = new Vector3(conversion.SkinPositionOffset[0], conversion.SkinPositionOffset[1], conversion.SkinPositionOffset[2]); + Vec3 skinPosOffset = default; + if (conv.SkinPositionOffset != null) + if (conv.SkinPositionOffset.Length >= 3) + skinPosOffset = new Vec3(conv.SkinPositionOffset[0], conv.SkinPositionOffset[1], conv.SkinPositionOffset[2]); - if (conversion.SkinSignSet != null && block.Skin != null && block.Skin != null && block.Skin.PackDesc != null) + if (conv.SkinSignSet != null && block.Skin != null && block.Skin != null && block.Skin.PackDesc != null) { - if (skinInfo.TryGetValue(conversion.SkinSignSet, out Dictionary skinDic)) + if (skinInfo.TryGetValue(conv.SkinSignSet, out Dictionary skinDic)) { if (skinDic.TryGetValue(block.Skin.PackDesc.FilePath, out string itemFile)) gbx.MainNode.PlaceItem(new Meta("Island\\" + itemFile, "10003", "adamkooo"), offsetAbsolutePosition + skinPosOffset, - offsetPitchYawRoll + new Vector3(-conversion.SkinDirectionOffset % 4 * 90f / 180 * MathF.PI, 0, 0), (0, 0, 0), offsetPivot); + offsetPitchYawRoll + new Vec3(-conv.SkinDirectionOffset % 4 * 90f / 180 * (float)Math.PI, 0, 0), (0, 0, 0), offsetPivot); else { Log.Write($"Could not find item alternative for {block.Skin.PackDesc.FilePath}. Default sign will be used instead.", ConsoleColor.DarkYellow); diff --git a/IslandConverter/IslandConverter.csproj b/IslandConverter/IslandConverter.csproj index 29838d484..c2864f8a2 100644 --- a/IslandConverter/IslandConverter.csproj +++ b/IslandConverter/IslandConverter.csproj @@ -2,9 +2,9 @@ Exe - netcoreapp3.1 + v4.6.1 true - 0.3.0 + 0.4.0 BigBang1112 Island Converter @@ -14,13 +14,16 @@ + net461 x86 true + false - x86 - true + net461 + x86 + true diff --git a/IslandConverter/Program.cs b/IslandConverter/Program.cs index 0627edc31..858f58433 100644 --- a/IslandConverter/Program.cs +++ b/IslandConverter/Program.cs @@ -92,7 +92,7 @@ static void Main(string[] args) if (arguments.Count() > 0) { - Console.WriteLine($"Specified optional arguments: {string.Join(' ', arguments)}"); + Console.WriteLine($"Specified optional arguments: {string.Join(" ", arguments)}"); var enumerator = arguments.GetEnumerator(); while (enumerator.MoveNext()) From 39ed12579fc520085f707c3b8593a87a511654ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sat, 12 Sep 2020 13:19:00 +0200 Subject: [PATCH 02/27] Remove something that shouldn't been there --- GBX.NET/Chunk.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GBX.NET/Chunk.cs b/GBX.NET/Chunk.cs index caebc50d6..f5721ea2e 100644 --- a/GBX.NET/Chunk.cs +++ b/GBX.NET/Chunk.cs @@ -181,7 +181,7 @@ public byte[] ToByteArray() using (var w = new GameBoxWriter(ms, lookbackable)) { var rw = new GameBoxReaderWriter(w); - ReadWrite(Node, rw);System.Globalization.CultureInfo.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; + ReadWrite(Node, rw); return ms.ToArray(); } } From 7d6940eb4a49d5e59c91d3d87f5b8689a90ad30c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sat, 12 Sep 2020 15:11:10 +0200 Subject: [PATCH 03/27] Improve data types --- GBX.NET/Byte3.cs | 53 ++++++++++++++++-------------------------------- GBX.NET/Int2.cs | 31 +++++++++++++++++----------- GBX.NET/Int3.cs | 51 ++++++++++++++++------------------------------ GBX.NET/Meta.cs | 25 ++++++++--------------- GBX.NET/Vec2.cs | 42 ++++++++++++++++++++++---------------- GBX.NET/Vec3.cs | 52 ++++++++++++++++++++++++++++++++--------------- 6 files changed, 122 insertions(+), 132 deletions(-) diff --git a/GBX.NET/Byte3.cs b/GBX.NET/Byte3.cs index f2007baa3..43adbf1fd 100644 --- a/GBX.NET/Byte3.cs +++ b/GBX.NET/Byte3.cs @@ -1,14 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace GBX.NET +namespace GBX.NET { public struct Byte3 { - public byte X { get; set; } - public byte Y { get; set; } - public byte Z { get; set; } + public byte X { get; } + public byte Y { get; } + public byte Z { get; } public Byte3(byte x, byte y, byte z) { @@ -17,39 +13,24 @@ public Byte3(byte x, byte y, byte z) Z = z; } - public override string ToString() - { - return $"({X}, {Y}, {Z})"; - } - - public static implicit operator Byte3((byte, byte, byte) v) - { - return new Byte3(v.Item1, v.Item2, v.Item3); - } - - public static implicit operator (byte, byte, byte)(Byte3 v) - { - return (v.X, v.Y, v.Z); - } - - public override bool Equals(object obj) - { - if (!(obj is Byte3)) return false; - return X == ((Byte3)obj).X && Y == ((Byte3)obj).Y && Z == ((Byte3)obj).Z; - } + public override string ToString() => $"({X}, {Y}, {Z})"; + public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); + public override bool Equals(object obj) => obj is Byte3 a && a == this; - public override int GetHashCode() - { - return X ^ Y ^ Z; - } + public static bool operator ==(Byte3 a, Byte3 b) => a.X == b.X && b.Y == b.Y && b.Z == b.Z; + public static bool operator !=(Byte3 a, Byte3 b) => !(a.X == b.X && b.Y == b.Y && b.Z == b.Z); public static Byte3 operator +(Byte3 a, Byte3 b) => new Byte3((byte)(a.X + b.X), (byte)(a.Y + b.Y), (byte)(a.Z + b.Z)); + public static Byte3 operator +(Byte3 a, byte b) => new Byte3((byte)(a.X + b), (byte)(a.Y + b), (byte)(a.Z + b)); + public static Byte3 operator -(Byte3 a, Byte3 b) => new Byte3((byte)(a.X - b.X), (byte)(a.Y - b.Y), (byte)(a.Z - b.Z)); - public static bool operator ==(Byte3 a, Byte3 b) => a.Equals(b); - public static bool operator !=(Byte3 a, Byte3 b) => !a.Equals(b); + public static Byte3 operator -(Byte3 a, byte b) => new Byte3((byte)(a.X - b), (byte)(a.Y - b), (byte)(a.Z - b)); + + public static Byte3 operator *(Byte3 a, Byte3 b) => new Byte3((byte)(a.X * b.X), (byte)(a.Y * b.Y), (byte)(a.Z * b.Z)); + public static Byte3 operator *(Byte3 a, byte b) => new Byte3((byte)(a.X * b), (byte)(a.Y * b), (byte)(a.Z * b)); - public static Byte3 operator +(Byte3 a, (int, int, int) b) => new Byte3((byte)(a.X + b.Item1), (byte)(a.Y + b.Item2), (byte)(a.Z + b.Item3)); - public static Byte3 operator -(Byte3 a, (int, int, int) b) => new Byte3((byte)(a.X - b.Item1), (byte)(a.Y - b.Item2), (byte)(a.Z - b.Item3)); + public static implicit operator Byte3((byte X, byte Y, byte Z) v) => new Byte3(v.X, v.Y, v.Z); + public static implicit operator (byte X, byte Y, byte Z)(Byte3 v) => (v.X, v.Y, v.Z); public static explicit operator Byte3(Int3 a) => new Byte3((byte)a.X, (byte)a.Y, (byte)a.Z); } diff --git a/GBX.NET/Int2.cs b/GBX.NET/Int2.cs index 9377ba3f9..c09da4509 100644 --- a/GBX.NET/Int2.cs +++ b/GBX.NET/Int2.cs @@ -11,19 +11,26 @@ public Int2(int x, int y) Y = y; } - public override string ToString() - { - return $"({X}, {Y})"; - } + public override string ToString() => $"({X}, {Y})"; + public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode(); + public override bool Equals(object obj) => obj is Int2 a && a == this; - public static implicit operator Int2((int, int) v) - { - return new Int2(v.Item1, v.Item2); - } + public static bool operator ==(Int2 a, Int2 b) => a.X == b.X && a.Y == b.Y; + public static bool operator !=(Int2 a, Int2 b) => !(a.X == b.X && a.Y == b.Y); - public static implicit operator (int, int)(Int2 v) - { - return (v.X, v.Y); - } + public static Int2 operator +(Int2 a, Int2 b) => new Int2(a.X + b.X, a.Y + b.Y); + public static Int2 operator +(Int2 a, int b) => new Int2(a.X + b, a.Y + b); + + public static Int2 operator -(Int2 a, Int2 b) => new Int2(a.X - b.X, a.Y - b.Y); + public static Int2 operator -(Int2 a, int b) => new Int2(a.X - b, a.Y - b); + + public static Int2 operator *(Int2 a, Int2 b) => new Int2(a.X * b.X, a.Y * b.Y); + public static Int2 operator *(Int2 a, int b) => new Int2(a.X * b, a.Y * b); + + public static Int2 operator ^(Int2 a, Int2 b) => new Int2(a.X ^ b.X, a.Y ^ b.Y); + public static Int2 operator ^(Int2 a, int b) => new Int2(a.X ^ b, a.Y ^ b); + + public static implicit operator Int2((int X, int Y) v) => new Int2(v.X, v.Y); + public static implicit operator (int X, int Y)(Int2 v) => (v.X, v.Y); } } \ No newline at end of file diff --git a/GBX.NET/Int3.cs b/GBX.NET/Int3.cs index 6fc867ddb..d878c43fa 100644 --- a/GBX.NET/Int3.cs +++ b/GBX.NET/Int3.cs @@ -1,6 +1,4 @@ -using System; -using System.Numerics; -using System.Runtime.Serialization; +using System.Runtime.Serialization; namespace GBX.NET { @@ -20,49 +18,34 @@ public Int3(int x, int y, int z) Z = z; } - public override string ToString() - { - return $"({X}, {Y}, {Z})"; - } - - public static implicit operator Int3((int X, int Y, int Z) v) - { - return new Int3(v.X, v.Y, v.Z); - } - - public static implicit operator (int X, int Y, int Z)(Int3 v) - { - return (v.X, v.Y, v.Z); - } + public override string ToString() => $"({X}, {Y}, {Z})"; + public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); + public override bool Equals(object obj) => obj is Int3 a && a == this; - public override bool Equals(object obj) - { - if(obj is Int3 int3) - return X == int3.X && Y == int3.Y && Z == int3.Z; - return base.Equals(obj); - } - - public override int GetHashCode() - { - return X ^ Y ^ Z; - } + public static bool operator ==(Int3 a, Int3 b) => a.X == b.X && a.Y == b.Y && a.Z == b.Z; + public static bool operator !=(Int3 a, Int3 b) => !(a.X == b.X && a.Y == b.Y && a.Z == b.Z); public static Int3 operator +(Int3 a, Int3 b) => new Int3(a.X + b.X, a.Y + b.Y, a.Z + b.Z); - public static Int3 operator +(Int3 a, int b) => new Int3(a.X * b, a.Y * b, a.Z * b); + public static Int3 operator +(Int3 a, Int2 b) => new Int3(a.X + b.X, a.Y + b.Y, a.Z); + public static Int3 operator +(Int3 a, int b) => new Int3(a.X + b, a.Y + b, a.Z + b); public static Int3 operator -(Int3 a, Int3 b) => new Int3(a.X - b.X, a.Y - b.Y, a.Z - b.Z); + public static Int3 operator -(Int3 a, Int2 b) => new Int3(a.X - b.X, a.Y - b.Y, a.Z); + public static Int3 operator -(Int3 a, int b) => new Int3(a.X - b, a.Y - b, a.Z - b); public static Int3 operator *(Int3 a, Int3 b) => new Int3(a.X * b.X, a.Y * b.Y, a.Z * b.Z); + public static Int3 operator *(Int3 a, Int2 b) => new Int3(a.X * b.X, a.Y * b.Y, a.Z); public static Int3 operator *(Int3 a, int b) => new Int3(a.X * b, a.Y * b, a.Z * b); - public static bool operator ==(Int3 a, Int3 b) => a.Equals(b); - public static bool operator !=(Int3 a, Int3 b) => !a.Equals(b); + public static Int3 operator ^(Int3 a, Int3 b) => new Int3(a.X ^ b.X, a.Y ^ b.Y, a.Z ^ b.Z); + public static Int3 operator ^(Int3 a, Int2 b) => new Int3(a.X ^ b.X, a.Y ^ b.Y, a.Z); + public static Int3 operator ^(Int3 a, int b) => new Int3(a.X ^ b, a.Y ^ b, a.Z^ b); + + public static implicit operator Int3((int X, int Y, int Z) v) => new Int3(v.X, v.Y, v.Z); + public static implicit operator (int X, int Y, int Z)(Int3 v) => (v.X, v.Y, v.Z); public static explicit operator Int3(Byte3 a) => new Int3(a.X, a.Y, a.Z); public static explicit operator Int3(Int2 a) => new Int3(a.X, 0, a.Y); - - public static implicit operator Vec3(Int3 a) => new Vec3(a.X, a.Y, a.Z); - public static explicit operator Int3(Direction a) { switch (a) diff --git a/GBX.NET/Meta.cs b/GBX.NET/Meta.cs index 81ea0ab13..30ae802a3 100644 --- a/GBX.NET/Meta.cs +++ b/GBX.NET/Meta.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace GBX.NET +namespace GBX.NET { public class Meta { @@ -27,19 +23,14 @@ public Meta(string id, string collection, string author) Author = author; } - public override string ToString() - { - return $"(\"{ID}\", \"{Collection}\", \"{Author}\")"; - } + public override string ToString() => $"(\"{ID}\", \"{Collection}\", \"{Author}\")"; + public override int GetHashCode() => ID.GetHashCode() ^ Collection.GetHashCode() ^ Author.GetHashCode(); + public override bool Equals(object obj) => this is Meta m && this == m; - public static implicit operator Meta((string ID, string Collection, string Author) v) - { - return new Meta(v.Item1, v.Item2, v.Item3); - } + public static bool operator ==(Meta a, Meta b) => a.ID == b.ID && a.Collection == b.Collection && a.Author == b.Author; + public static bool operator !=(Meta a, Meta b) => !(a.ID == b.ID && a.Collection == b.Collection && a.Author == b.Author); - public static implicit operator (string ID, string Collection, string Author)(Meta v) - { - return (v.ID, v.Collection, v.Author); - } + public static implicit operator Meta((string ID, string Collection, string Author) v) => new Meta(v.ID, v.Collection, v.Author); + public static implicit operator (string ID, string Collection, string Author)(Meta v) => (v.ID, v.Collection, v.Author); } } diff --git a/GBX.NET/Vec2.cs b/GBX.NET/Vec2.cs index d1a730df8..4f2f45a9d 100644 --- a/GBX.NET/Vec2.cs +++ b/GBX.NET/Vec2.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace GBX.NET +namespace GBX.NET { public struct Vec2 { @@ -15,19 +11,31 @@ public Vec2(float x, float y) Y = y; } - public override string ToString() - { - return $"({X}, {Y})"; - } + public override string ToString() => $"({X}, {Y})"; + public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode(); + public override bool Equals(object obj) => obj is Vec2 a && a == this; - public static implicit operator Vec2((float x, float y) v) - { - return new Vec2(v.x, v.y); - } + public static bool operator ==(Vec2 a, Vec2 b) => a.X == b.X && a.Y == b.Y; + public static bool operator !=(Vec2 a, Vec2 b) => !(a.X == b.X && a.Y == b.Y); - public static implicit operator (float x, float y)(Vec2 v) - { - return (v.X, v.Y); - } + public static Vec2 operator +(Vec2 a, Vec2 b) => new Vec2(a.X + b.X, a.Y + b.Y); + public static Vec2 operator +(Vec2 a, Int2 b) => new Vec2(a.X + b.X, a.Y + b.Y); + public static Vec2 operator +(Vec2 a, int b) => new Vec2(a.X + b, a.Y + b); + public static Vec2 operator +(Vec2 a, float b) => new Vec2(a.X + b, a.Y + b); + + public static Vec2 operator -(Vec2 a) => new Vec2(-a.X, -a.Y); + public static Vec2 operator -(Vec2 a, Vec2 b) => new Vec2(a.X - b.X, a.Y - b.Y); + public static Vec2 operator -(Vec2 a, Int2 b) => new Vec2(a.X - b.X, a.Y - b.Y); + public static Vec2 operator -(Vec2 a, int b) => new Vec2(a.X - b, a.Y - b); + public static Vec2 operator -(Vec2 a, float b) => new Vec2(a.X - b, a.Y - b); + + public static Vec2 operator *(Vec2 a, Vec2 b) => new Vec2(a.X * b.X, a.Y * b.Y); + public static Vec2 operator *(Vec2 a, Int2 b) => new Vec2(a.X * b.X, a.Y * b.Y); + public static Vec2 operator *(Vec2 a, int b) => new Vec2(a.X * b, a.Y * b); + public static Vec2 operator *(Vec2 a, float b) => new Vec2(a.X * b, a.Y * b); + + public static implicit operator Vec2(Int2 a) => new Vec2(a.X, a.Y); + public static implicit operator Vec2((float X, float Y) v) => new Vec2(v.X, v.Y); + public static implicit operator (float X, float Y)(Vec2 v) => (v.X, v.Y); } } diff --git a/GBX.NET/Vec3.cs b/GBX.NET/Vec3.cs index 25f36b49a..4e882c535 100644 --- a/GBX.NET/Vec3.cs +++ b/GBX.NET/Vec3.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Runtime.Serialization; namespace GBX.NET { @@ -10,6 +8,9 @@ public struct Vec3 public float Y { get; } public float Z { get; } + [IgnoreDataMember] + public Vec3 XZ => new Vec3(X, 0, Z); + public Vec3(float x, float y, float z) { X = x; @@ -17,21 +18,40 @@ public Vec3(float x, float y, float z) Z = z; } - public override string ToString() - { - return $"({X}, {Y})"; - } - - public static implicit operator Vec3((float x, float y, float z) v) - { - return new Vec3(v.x, v.y, v.z); - } + public override string ToString() => $"({X}, {Y}, {Z})"; + public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); + public override bool Equals(object obj) => obj is Vec3 a && a == this; - public static implicit operator (float x, float y, float z)(Vec3 v) - { - return (v.X, v.Y, v.Z); - } + public static bool operator ==(Vec3 a, Vec3 b) => a.X == b.X && a.Y == b.Y && a.Z == b.Z; + public static bool operator !=(Vec3 a, Vec3 b) => !(a.X == b.X && a.Y == b.Y && a.Z == b.Z); public static Vec3 operator +(Vec3 a, Vec3 b) => new Vec3(a.X + b.X, a.Y + b.Y, a.Z + b.Z); + public static Vec3 operator +(Vec3 a, Int3 b) => new Vec3(a.X + b.X, a.Y + b.Y, a.Z + b.Z); + public static Vec3 operator +(Vec3 a, Vec2 b) => new Vec3(a.X + b.X, a.Y + b.Y, a.Z); + public static Vec3 operator +(Vec3 a, Int2 b) => new Vec3(a.X + b.X, a.Y + b.Y, a.Z); + public static Vec3 operator +(Vec3 a, int b) => new Vec3(a.X + b, a.Y + b, a.Z + b); + public static Vec3 operator +(Vec3 a, float b) => new Vec3(a.X + b, a.Y + b, a.Z + b); + + public static Vec3 operator -(Vec3 a) => new Vec3(-a.X, -a.Y, -a.Z); + public static Vec3 operator -(Vec3 a, Vec3 b) => new Vec3(a.X - b.X, a.Y - b.Y, a.Z - b.Z); + public static Vec3 operator -(Vec3 a, Int3 b) => new Vec3(a.X - b.X, a.Y - b.Y, a.Z - b.Z); + public static Vec3 operator -(Vec3 a, Vec2 b) => new Vec3(a.X - b.X, a.Y - b.Y, a.Z); + public static Vec3 operator -(Vec3 a, Int2 b) => new Vec3(a.X - b.X, a.Y - b.Y, a.Z); + public static Vec3 operator -(Vec3 a, int b) => new Vec3(a.X - b, a.Y - b, a.Z - b); + public static Vec3 operator -(Vec3 a, float b) => new Vec3(a.X - b, a.Y - b, a.Z - b); + + public static Vec3 operator *(Vec3 a, Vec3 b) => new Vec3(a.X * b.X, a.Y * b.Y, a.Z * b.Z); + public static Vec3 operator *(Vec3 a, Int3 b) => new Vec3(a.X * b.X, a.Y * b.Y, a.Z * b.Z); + public static Vec3 operator *(Vec3 a, Vec2 b) => new Vec3(a.X * b.X, a.Y * b.Y, a.Z); + public static Vec3 operator *(Vec3 a, Int2 b) => new Vec3(a.X * b.X, a.Y * b.Y, a.Z); + public static Vec3 operator *(Vec3 a, int b) => new Vec3(a.X * b, a.Y * b, a.Z * b); + public static Vec3 operator *(Vec3 a, float b) => new Vec3(a.X * b, a.Y * b, a.Z * b); + + public static implicit operator Vec3(Int3 a) => new Vec3(a.X, a.Y, a.Z); + public static implicit operator Vec3((float X, float Y, float Z) v) => new Vec3(v.X, v.Y, v.Z); + public static implicit operator (float X, float Y, float Z)(Vec3 v) => (v.X, v.Y, v.Z); + + public static explicit operator Vec3(Byte3 a) => new Vec3(a.X, a.Y, a.Z); + public static explicit operator Vec3(Int2 a) => new Vec3(a.X, 0, a.Y); } } From 28669b22a5692e270f10156162de56907eb0cb57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sat, 12 Sep 2020 15:52:34 +0200 Subject: [PATCH 04/27] Rename ChunkList to ChunkSet --- GBX.NET/{ChunkList.cs => ChunkSet.cs} | 6 +++--- GBX.NET/Engines/Game/CGameCtnChallenge.cs | 2 +- GBX.NET/GBX.NET.csproj | 2 +- GBX.NET/GameBoxBody.cs | 2 +- GBX.NET/GameBoxHeader.cs | 4 ++-- GBX.NET/Node.cs | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) rename GBX.NET/{ChunkList.cs => ChunkSet.cs} (97%) diff --git a/GBX.NET/ChunkList.cs b/GBX.NET/ChunkSet.cs similarity index 97% rename from GBX.NET/ChunkList.cs rename to GBX.NET/ChunkSet.cs index 9956deeeb..f84d4e640 100644 --- a/GBX.NET/ChunkList.cs +++ b/GBX.NET/ChunkSet.cs @@ -7,17 +7,17 @@ namespace GBX.NET { - public class ChunkList : SortedSet + public class ChunkSet : SortedSet { [IgnoreDataMember] public Node Node { get; set; } - public ChunkList() : base() + public ChunkSet() : base() { } - public ChunkList(IEnumerable collection) : base(collection) + public ChunkSet(IEnumerable collection) : base(collection) { } diff --git a/GBX.NET/Engines/Game/CGameCtnChallenge.cs b/GBX.NET/Engines/Game/CGameCtnChallenge.cs index af55b0fdb..b08f46423 100644 --- a/GBX.NET/Engines/Game/CGameCtnChallenge.cs +++ b/GBX.NET/Engines/Game/CGameCtnChallenge.cs @@ -593,7 +593,7 @@ public void PlaceItem(Meta itemModel, Vec3 absolutePosition, Vec3 pitchYawRoll, PivotPosition = offsetPivot, Variant = variant }; - it.Chunks = new ChunkList(); + it.Chunks = new ChunkSet(); it.CreateChunk(); it.CreateChunk(); Items.Add(it); diff --git a/GBX.NET/GBX.NET.csproj b/GBX.NET/GBX.NET.csproj index f5c01302b..b2b4b4a88 100644 --- a/GBX.NET/GBX.NET.csproj +++ b/GBX.NET/GBX.NET.csproj @@ -6,7 +6,7 @@ BigBang1112 BigBang1112 - 0.1.0 + 0.2.0 true true diff --git a/GBX.NET/GameBoxBody.cs b/GBX.NET/GameBoxBody.cs index 6675d6750..e389b0dc3 100644 --- a/GBX.NET/GameBoxBody.cs +++ b/GBX.NET/GameBoxBody.cs @@ -11,7 +11,7 @@ public class GameBoxBody : GameBoxBody where T : Node { public int? CompressedSize { get; } public int UncompressedSize { get; } - public ChunkList Chunks { get; set; } = new ChunkList(); + public ChunkSet Chunks { get; set; } = new ChunkSet(); public byte[] Rest { get; } public bool Aborting { get; private set; } diff --git a/GBX.NET/GameBoxHeader.cs b/GBX.NET/GameBoxHeader.cs index 392b29a9f..50cf51db6 100644 --- a/GBX.NET/GameBoxHeader.cs +++ b/GBX.NET/GameBoxHeader.cs @@ -14,7 +14,7 @@ public class GameBoxHeader : GameBoxHeader, ILookbackable where T : Node public new GameBox GBX => (GameBox)base.GBX; - public ChunkList Chunks { get; set; } + public ChunkSet Chunks { get; set; } public GameBoxHeader(GameBox gbx, GameBoxHeaderParameters parameters) : base(gbx, parameters) { @@ -142,7 +142,7 @@ List GetInheritance(Type t) counter++; } - Chunks = new ChunkList(chunks); + Chunks = new ChunkSet(chunks); } } } diff --git a/GBX.NET/Node.cs b/GBX.NET/Node.cs index ac967734d..59bdc5f2d 100644 --- a/GBX.NET/Node.cs +++ b/GBX.NET/Node.cs @@ -18,7 +18,7 @@ public class Node [IgnoreDataMember] public GameBox GBX => Body?.GBX; - public ChunkList Chunks { get; internal set; } + public ChunkSet Chunks { get; internal set; } /// /// Chunk where the aux node appeared @@ -227,7 +227,7 @@ private static Node Parse(Type type, ILookbackable body, GameBoxReader r, List().ID); - var chunks = new ChunkList(); + var chunks = new ChunkSet(); chunks.Node = node; uint? previousChunk = null; From f01ebfe20ba01bed83e9ce76a632c232d68dd177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sun, 13 Sep 2020 01:26:28 +0200 Subject: [PATCH 05/27] Moved body chunks to its node --- GBX.NET.Json/GBX.NET.Json.csproj | 3 +- .../Engines/Game/CGameCtnAnchoredObject.cs | 2 +- GBX.NET/Engines/Game/CGameCtnBlockSkin.cs | 185 +++++++++--------- GBX.NET/GameBox.cs | 8 +- GBX.NET/GameBoxBody.cs | 27 ++- GBX.NET/GameBoxReader.cs | 4 +- GBX.NET/Node.cs | 86 +++----- IslandConverter/IslandConverter.cs | 2 +- 8 files changed, 142 insertions(+), 175 deletions(-) diff --git a/GBX.NET.Json/GBX.NET.Json.csproj b/GBX.NET.Json/GBX.NET.Json.csproj index fb555fd79..1feff9ae1 100644 --- a/GBX.NET.Json/GBX.NET.Json.csproj +++ b/GBX.NET.Json/GBX.NET.Json.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 0.1.0 + 0.1.1 true true A wrapper for better JSON serialization of GBX, useful for comparing data. @@ -11,6 +11,7 @@ https://github.com/BigBang1112/gbx-net gbx, trackmania, maniaplanet, gamebox, net, chunk, x86 BigBang1112 + Compatiblity change to .NET Standard 2.0 diff --git a/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs b/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs index a26c0e7db..6f37b9532 100644 --- a/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs +++ b/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs @@ -79,7 +79,7 @@ public override void Read(CGameCtnAnchoredObject n, GameBoxReader r, GameBoxWrit n.AbsolutePositionInMap = r.ReadVec3(); var specialWaypoint = r.ReadInt32(); if(specialWaypoint != -1) - n.WaypointSpecialProperty = Parse(Node.Body, r, true); + n.WaypointSpecialProperty = Parse(Node.Body, r); n.Flags = r.ReadInt16(); n.PivotPosition = r.ReadVec3(); n.Scale = r.ReadSingle(); diff --git a/GBX.NET/Engines/Game/CGameCtnBlockSkin.cs b/GBX.NET/Engines/Game/CGameCtnBlockSkin.cs index 24f62a5dc..2f5790f22 100644 --- a/GBX.NET/Engines/Game/CGameCtnBlockSkin.cs +++ b/GBX.NET/Engines/Game/CGameCtnBlockSkin.cs @@ -1,109 +1,114 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// Skin for a block (0x03059000) - /// - [Node(0x03059000)] - public class CGameCtnBlockSkin : Node - { - public string Text { get; set; } - - public FileRef PackDesc { get; set; } = new FileRef(); - - public FileRef ParentPackDesc { get; set; } = new FileRef(); - - public FileRef SecondaryPackDesc { get; set; } - - public CGameCtnBlockSkin(ILookbackable lookbackable) : this(lookbackable, 0x03059000) - { - - } - - public CGameCtnBlockSkin(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - + /// + [Node(0x03059000)] + public class CGameCtnBlockSkin : Node + { + public string Text { get; set; } + + public FileRef PackDesc { get; set; } = new FileRef(); + + public FileRef ParentPackDesc { get; set; } = new FileRef(); + + public FileRef SecondaryPackDesc { get; set; } + + public CGameCtnBlockSkin(ILookbackable lookbackable) : this(lookbackable, 0x03059000) + { + } - #region Chunks + public CGameCtnBlockSkin(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) + { - #region 0x000 chunk + } + + public CGameCtnBlockSkin(Chunk chunk) : base(chunk) + { + + } + + #region Chunks + + #region 0x000 chunk /// /// CGameCtnBlockSkin 0x000 chunk - /// - [Chunk(0x03059000)] - public class Chunk03059000 : Chunk - { - public string Ignored { get; set; } - - public override void ReadWrite(CGameCtnBlockSkin n, GameBoxReaderWriter rw) - { - n.Text = rw.String(n.Text); - Ignored = rw.String(Ignored); - } + /// + [Chunk(0x03059000)] + public class Chunk03059000 : Chunk + { + public string Ignored { get; set; } + + public override void ReadWrite(CGameCtnBlockSkin n, GameBoxReaderWriter rw) + { + n.Text = rw.String(n.Text); + Ignored = rw.String(Ignored); + } } - #endregion + #endregion #region 0x001 chunk /// /// CGameCtnBlockSkin 0x001 chunk - /// - [Chunk(0x03059001)] - public class Chunk03059001 : Chunk - { - public override void ReadWrite(CGameCtnBlockSkin n, GameBoxReaderWriter rw) - { - n.Text = rw.String(n.Text); - n.PackDesc = rw.FileRef(n.PackDesc); - } - } - - #endregion - - #region 0x002 chunk - + /// + [Chunk(0x03059001)] + public class Chunk03059001 : Chunk + { + public override void ReadWrite(CGameCtnBlockSkin n, GameBoxReaderWriter rw) + { + n.Text = rw.String(n.Text); + n.PackDesc = rw.FileRef(n.PackDesc); + } + } + + #endregion + + #region 0x002 chunk + /// /// CGameCtnBlockSkin 0x002 chunk (skin) - /// - [Chunk(0x03059002, "skin")] - public class Chunk03059002 : Chunk - { - public override void ReadWrite(CGameCtnBlockSkin n, GameBoxReaderWriter rw) - { - n.Text = rw.String(n.Text); - n.PackDesc = rw.FileRef(n.PackDesc); - n.ParentPackDesc = rw.FileRef(n.ParentPackDesc); - } - } - - #endregion - - #region 0x003 chunk (secondary skin) - + /// + [Chunk(0x03059002, "skin")] + public class Chunk03059002 : Chunk + { + public override void ReadWrite(CGameCtnBlockSkin n, GameBoxReaderWriter rw) + { + n.Text = rw.String(n.Text); + n.PackDesc = rw.FileRef(n.PackDesc); + n.ParentPackDesc = rw.FileRef(n.ParentPackDesc); + } + } + + #endregion + + #region 0x003 chunk (secondary skin) + /// /// CGameCtnBlockSkin 0x003 chunk (secondary skin) - /// - [Chunk(0x03059003, "secondary skin")] - public class Chunk03059003 : Chunk - { - public int Version { get; set; } - - public override void ReadWrite(CGameCtnBlockSkin n, GameBoxReaderWriter rw) - { - Version = rw.Int32(Version); - n.SecondaryPackDesc = rw.FileRef(n.SecondaryPackDesc); - } - } - - #endregion - - #endregion - } -} + /// + [Chunk(0x03059003, "secondary skin")] + public class Chunk03059003 : Chunk + { + public int Version { get; set; } + + public override void ReadWrite(CGameCtnBlockSkin n, GameBoxReaderWriter rw) + { + Version = rw.Int32(Version); + n.SecondaryPackDesc = rw.FileRef(n.SecondaryPackDesc); + } + } + + #endregion + + #endregion + } +} diff --git a/GBX.NET/GameBox.cs b/GBX.NET/GameBox.cs index 75869150a..dcf6edfef 100644 --- a/GBX.NET/GameBox.cs +++ b/GBX.NET/GameBox.cs @@ -45,7 +45,7 @@ public bool RemoveHeaderChunk() where TChunk : HeaderChunk public TChunk CreateBodyChunk(byte[] data) where TChunk : Chunk { - return Body.Chunks.Create(data); + return MainNode.Chunks.Create(data); } public TChunk CreateBodyChunk() where TChunk : Chunk @@ -55,19 +55,19 @@ public TChunk CreateBodyChunk() where TChunk : Chunk public void RemoveAllBodyChunks() { - Body.Chunks.Clear(); + MainNode.Chunks.Clear(); } public bool RemoveBodyChunk() where TChunk : Chunk { - return Body.Chunks.Remove(); + return MainNode.Chunks.Remove(); } public void DiscoverAllChunks() { //foreach (var chunk in Header.Result.Chunks.Values) // chunk.Discover(); - foreach (var chunk in Body.Chunks) + foreach (var chunk in MainNode.Chunks) if(chunk is ISkippableChunk s) s.Discover(); } diff --git a/GBX.NET/GameBoxBody.cs b/GBX.NET/GameBoxBody.cs index e389b0dc3..f88861b09 100644 --- a/GBX.NET/GameBoxBody.cs +++ b/GBX.NET/GameBoxBody.cs @@ -11,7 +11,6 @@ public class GameBoxBody : GameBoxBody where T : Node { public int? CompressedSize { get; } public int UncompressedSize { get; } - public ChunkSet Chunks { get; set; } = new ChunkSet(); public byte[] Rest { get; } public bool Aborting { get; private set; } @@ -38,8 +37,6 @@ public GameBoxBody(GameBox gbx, uint mainNodeID, byte[] data, int? compressed gbxr.Read(restBuffer, 0, restBuffer.Length); Rest = restBuffer; } - - Chunks.Node = gbx.MainNode; } public static GameBoxBody DecompressAndConstruct(GameBox gbx, uint mainNodeID, byte[] data, int compressedSize, int uncompressedSize) @@ -84,7 +81,7 @@ public void Abort() public new TChunk CreateChunk(byte[] data) where TChunk : Chunk { - return Chunks.Create(data); + return GBX.MainNode.Chunks.Create(data); } public new TChunk CreateChunk() where TChunk : Chunk @@ -94,19 +91,19 @@ public void Abort() public void InsertChunk(Chunk chunk) { - Chunks.Add(chunk); + GBX.MainNode.Chunks.Add(chunk); } public new void DiscoverChunk() where TChunk : SkippableChunk { - foreach (var chunk in Chunks) + foreach (var chunk in GBX.MainNode.Chunks) if (chunk is TChunk c) c.Discover(); } public new void DiscoverChunks() where TChunk1 : SkippableChunk where TChunk2 : SkippableChunk { - foreach (var chunk in Chunks) + foreach (var chunk in GBX.MainNode.Chunks) { if (chunk is TChunk1 c1) c1.Discover(); @@ -120,7 +117,7 @@ public void InsertChunk(Chunk chunk) where TChunk2 : SkippableChunk where TChunk3 : SkippableChunk { - foreach (var chunk in Chunks) + foreach (var chunk in GBX.MainNode.Chunks) { if (chunk is TChunk1 c1) c1.Discover(); @@ -137,7 +134,7 @@ public void InsertChunk(Chunk chunk) where TChunk3 : SkippableChunk where TChunk4 : SkippableChunk { - foreach (var chunk in Chunks) + foreach (var chunk in GBX.MainNode.Chunks) { if (chunk is TChunk1 c1) c1.Discover(); @@ -157,7 +154,7 @@ public void InsertChunk(Chunk chunk) where TChunk4 : SkippableChunk where TChunk5 : SkippableChunk { - foreach (var chunk in Chunks) + foreach (var chunk in GBX.MainNode.Chunks) { if (chunk is TChunk1 c1) c1.Discover(); @@ -180,7 +177,7 @@ public void InsertChunk(Chunk chunk) where TChunk5 : SkippableChunk where TChunk6 : SkippableChunk { - foreach (var chunk in Chunks) + foreach (var chunk in GBX.MainNode.Chunks) { if (chunk is TChunk1 c1) c1.Discover(); @@ -199,14 +196,14 @@ public void InsertChunk(Chunk chunk) public new void DiscoverAllChunks() { - foreach (var chunk in Chunks) + foreach (var chunk in GBX.MainNode.Chunks) if (chunk is SkippableChunk s) s.Discover(); } public new TChunk GetChunk() where TChunk : Chunk { - foreach (var chunk in Chunks) + foreach (var chunk in GBX.MainNode.Chunks) { if (chunk is TChunk t) { @@ -225,12 +222,12 @@ public void InsertChunk(Chunk chunk) public void RemoveAllChunks() { - Chunks.Clear(); + GBX.MainNode.Chunks.Clear(); } public new bool RemoveChunk() where TChunk : Chunk { - return Chunks.Remove(); + return GBX.MainNode.Chunks.Remove(); } } diff --git a/GBX.NET/GameBoxReader.cs b/GBX.NET/GameBoxReader.cs index 8823d8686..ab492beec 100644 --- a/GBX.NET/GameBoxReader.cs +++ b/GBX.NET/GameBoxReader.cs @@ -168,9 +168,9 @@ public T ReadNodeRef(bool hasInheritance, GameBoxBody body) where T : Node Node node; if (hasInheritance) - node = Node.Parse(body, classID, this, true); + node = Node.Parse(body, classID, this); else - node = Node.Parse(body, this, true); + node = Node.Parse(body, this); if (index >= body.AuxilaryNodes.Count) body.AuxilaryNodes.Add(node); diff --git a/GBX.NET/Node.cs b/GBX.NET/Node.cs index 59bdc5f2d..2d86035b8 100644 --- a/GBX.NET/Node.cs +++ b/GBX.NET/Node.cs @@ -117,9 +117,9 @@ public static Node[] ParseArray(Type type, ILookbackable body, GameBoxReader r) _ = r.ReadUInt32(); if (i == 0) - array[i] = Parse(type, body, r, out inheritanceClasses, out availableChunkClasses, true); + array[i] = Parse(type, body, r, out inheritanceClasses, out availableChunkClasses); else - array[i] = Parse(type, body, r, inheritanceClasses, availableChunkClasses, true); + array[i] = Parse(type, body, r, inheritanceClasses, availableChunkClasses); } return array; @@ -130,7 +130,7 @@ public static T[] ParseArray(ILookbackable body, GameBoxReader r) where T : N return ParseArray(typeof(T), body, r).Cast().ToArray(); } - public static Node Parse(ILookbackable body, uint classID, GameBoxReader r, bool isAux = false) + public static Node Parse(ILookbackable body, uint classID, GameBoxReader r) { var hasNewerID = Mappings.TryGetValue(classID, out uint newerClassID); if (!hasNewerID) newerClassID = classID; @@ -148,10 +148,10 @@ public static Node Parse(ILookbackable body, uint classID, GameBoxReader r, bool if (availableClass == null) throw new Exception("Unknown node: 0x" + classID.ToString("x8")); - return Parse(availableClass, body, r, isAux); + return Parse(availableClass, body, r); } - private static Node Parse(Type type, ILookbackable body, GameBoxReader r, out List inheritanceClasses, out Dictionary availableChunkClasses, bool isAux = false) + private static Node Parse(Type type, ILookbackable body, GameBoxReader r, out List inheritanceClasses, out Dictionary availableChunkClasses) { inheritanceClasses = GetInheritance(type); @@ -208,27 +208,29 @@ List GetInheritance(Type t) AvailableChunkClasses.Add(type, availableChunkClasses); } - return Parse(type, body, r, inheritanceClasses, availableChunkClasses, isAux); + return Parse(type, body, r, inheritanceClasses, availableChunkClasses); } - public static Node Parse(Type type, ILookbackable body, GameBoxReader r, bool isAux = false) + public static Node Parse(Type type, ILookbackable body, GameBoxReader r) { - return Parse(type, body, r, out List _, out Dictionary _, isAux); + return Parse(type, body, r, out List _, out Dictionary _); } - public static T Parse(ILookbackable body, GameBoxReader r, bool isAux = false) where T : Node + public static T Parse(ILookbackable body, GameBoxReader r) where T : Node { - return (T)Parse(typeof(T), body, r, isAux); + return (T)Parse(typeof(T), body, r); } - private static Node Parse(Type type, ILookbackable body, GameBoxReader r, List inheritanceClasses, Dictionary availableChunkClasses, bool isAux = false) + private static Node Parse(Type type, ILookbackable body, GameBoxReader r, List inheritanceClasses, Dictionary availableChunkClasses) { var readNodeStart = DateTime.Now; Node node = (Node)Activator.CreateInstance(type, body, type.GetCustomAttribute().ID); - var chunks = new ChunkSet(); - chunks.Node = node; + var chunks = new ChunkSet + { + Node = node + }; uint? previousChunk = null; @@ -376,10 +378,7 @@ private static Node Parse(Type type, ILookbackable body, GameBoxReader r, List() where T : Chunk { - if (Chunks != null) - return Chunks.Get(); - else - return ((dynamic)Body).GetChunk(); + return Chunks.Get(); } public T CreateChunk() where T : Chunk { - if (Chunks != null) - return Chunks.Create(); - else - return ((dynamic)Body).CreateChunk(); + return Chunks.Create(); } public bool RemoveChunk() where T : Chunk { - if (Chunks != null) - return Chunks.Remove(); - else - return ((dynamic)Body).RemoveChunk(); + return Chunks.Remove(); } public bool TryGetChunk(out T chunk) where T : Chunk { - if (Chunks != null) - return Chunks.TryGet(out chunk); - else - { - chunk = ((dynamic)Body).GetChunk(); - return chunk != default; - } + return Chunks.TryGet(out chunk); } public void DiscoverChunk() where T : ISkippableChunk { - if (Chunks != null) - Chunks.Discover(); - else if (typeof(T).GetInterface("IHeaderChunk") != null) - ((dynamic)GBX).Header.Result.DiscoverChunk(); - else - ((dynamic)Body).DiscoverChunk(); + Chunks.Discover(); } public void DiscoverChunks() where T1 : ISkippableChunk where T2 : ISkippableChunk { - if (Chunks != null) - Chunks.Discover(); - else if (typeof(T1).GetInterface("IHeaderChunk") != null - && typeof(T2).GetInterface("IHeaderChunk") != null) - ((dynamic)GBX).Header.Result.DiscoverChunks(); - else - ((dynamic)Body).DiscoverChunks(); + Chunks.Discover(); } public void DiscoverChunks() where T1 : ISkippableChunk where T2 : ISkippableChunk where T3 : ISkippableChunk @@ -599,10 +572,7 @@ public void DiscoverChunks() where T3 : ISkippableChunk where T4 : ISkippableChunk { - if (Chunks != null) - Chunks.Discover(); - else - ((dynamic)Body).DiscoverChunks(); + Chunks.Discover(); } public void DiscoverChunks() @@ -612,10 +582,7 @@ public void DiscoverChunks() where T4 : ISkippableChunk where T5 : ISkippableChunk { - if (Chunks != null) - Chunks.Discover(); - else - ((dynamic)Body).DiscoverChunks(); + Chunks.Discover(); } public void DiscoverChunks() @@ -626,10 +593,7 @@ public void DiscoverChunks() where T5 : ISkippableChunk where T6 : ISkippableChunk { - if (Chunks != null) - Chunks.Discover(); - else - ((dynamic)Body).DiscoverChunks(); + Chunks.Discover(); } public void DiscoverAllChunks() diff --git a/IslandConverter/IslandConverter.cs b/IslandConverter/IslandConverter.cs index bbe5170a8..2d84dd03f 100644 --- a/IslandConverter/IslandConverter.cs +++ b/IslandConverter/IslandConverter.cs @@ -224,7 +224,7 @@ internal static void ConvertToTM2Island(GameBox gbx, TimeSpan if (size == MapSize.X32WithBigBorder) { Log.Write("Importing chunk 0x03043043 for water on ground..."); - var chunk = gbx.Body.Chunks.Create(File.ReadAllBytes("0x03043043.dat")); + var chunk = gbx.CreateBodyChunk(File.ReadAllBytes("0x03043043.dat")); } Log.Write("Cracking the map password if presented..."); From 5bde9073a3ea03d01165a339226c72200edc8fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sun, 13 Sep 2020 01:32:43 +0200 Subject: [PATCH 06/27] Update Node Write --- GBX.NET/Node.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/GBX.NET/Node.cs b/GBX.NET/Node.cs index 2d86035b8..6f07a6b8a 100644 --- a/GBX.NET/Node.cs +++ b/GBX.NET/Node.cs @@ -397,13 +397,7 @@ public void Write(GameBoxWriter w, ClassIDRemap remap) { int counter = 0; - dynamic chunks; - if (Chunks == null) - chunks = ((dynamic)Body).Chunks; - else - chunks = Chunks; - - foreach (dynamic chunk in chunks) + foreach (dynamic chunk in Chunks) { counter += 1; From 71356e66ae58d6f779e209b118b6b371afae5c0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sun, 13 Sep 2020 01:42:43 +0200 Subject: [PATCH 07/27] Fix Meta equal operators --- GBX.NET/Meta.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GBX.NET/Meta.cs b/GBX.NET/Meta.cs index 30ae802a3..71176a9ec 100644 --- a/GBX.NET/Meta.cs +++ b/GBX.NET/Meta.cs @@ -27,8 +27,8 @@ public Meta(string id, string collection, string author) public override int GetHashCode() => ID.GetHashCode() ^ Collection.GetHashCode() ^ Author.GetHashCode(); public override bool Equals(object obj) => this is Meta m && this == m; - public static bool operator ==(Meta a, Meta b) => a.ID == b.ID && a.Collection == b.Collection && a.Author == b.Author; - public static bool operator !=(Meta a, Meta b) => !(a.ID == b.ID && a.Collection == b.Collection && a.Author == b.Author); + public static bool operator ==(Meta a, Meta b) => a?.ID == b?.ID && a?.Collection == b?.Collection && a?.Author == b?.Author; + public static bool operator !=(Meta a, Meta b) => !(a?.ID == b?.ID && a?.Collection == b?.Collection && a?.Author == b?.Author); public static implicit operator Meta((string ID, string Collection, string Author) v) => new Meta(v.ID, v.Collection, v.Author); public static implicit operator (string ID, string Collection, string Author)(Meta v) => (v.ID, v.Collection, v.Author); From eca8fb108fcdc2d468527d0da2d79a6c680f1643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sun, 13 Sep 2020 21:37:55 +0200 Subject: [PATCH 08/27] Update kompatibility in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f1cf9aee..831eb8d61 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Reading PAK file isn't currently supported. ## Compatibility -GBX.NET is currently compatible with .NET Standard 2.1. At the moment you can't use the library in .NET Framework projects or .NET Core 2 or lower. Wider compatibility is planned for the future. +GBX.NET is compatible with .NET Standard 2.0 since version 0.2.0. Earlier versions are built on .NET Standard 2.1. The library is also set to x86 assembly due to LZO compression problems in x64. It is unsure whenever this will be resolved. From 2da9d7676f51e2e442c6e18417f16e046b961b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sun, 13 Sep 2020 22:33:26 +0200 Subject: [PATCH 09/27] Add shields --- README.md | 5 +++++ logo.png | Bin 6805 -> 6708 bytes 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index 831eb8d61..41cf824d4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ ![GBX.NET](logo.png) +![Nuget](https://img.shields.io/nuget/v/GBX.NET?style=for-the-badge) +![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/BigBang1112/gbx-net?include_prereleases&style=for-the-badge) +![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/BigBang1112/gbx-net?style=for-the-badge) +![GitHub](https://img.shields.io/github/license/BigBang1112/gbx-net?style=for-the-badge) + GBX.NET is a .NET GBX file parser library written in C#. GBX (or GameBox) is a file type available in many of the Nadeo games. This GBX parser can recognize the entire GBX file. Modification of some GBX types is supported. diff --git a/logo.png b/logo.png index 3156efe2ddb8ae06ae8ab21a35166edadec182b5..9fa1b654ed26bc6f36f3861f3a456a7afc7865f1 100644 GIT binary patch delta 6023 zcmV;27kKEEHMBI47Yc3&1^@s6(Olshks&A!zyJUazyWI3i3tDz8Of1XTLOE{k+foe zm=*Y;`Eg48q;#jbZZF+b+ELm;+D7`ebiMT7(pRJ}Nmoi&%=N!gEBvUme;RK2zqueD z%W-^NlN+RKq_5A9U9zoofb=bi-wU6eYpndTbQ5ViiND*+rB6tUWDn`5CB8dj{=E5& z@0Er#u9hxM!%cDj`Ekg6NaESJ7JgoTx^)^(hWE~orXzk_dXV&5=~GfPZ0i+<{@8VeBUAJ9@1JlO-mJNCb+*>+N zTJ8fcg|T6^^Y79{(!WZVNmohh{o}hp`ZZ~h48fphv7&pVR1;i!cunH(d9E}TepX`J zCtlxUrM@T)IyzYz8(kT6769>oeTOI;^p(}SK_Al|`t79Sq=(F2{UAK}FO)F$AC)lT zTiXM~U4MtU?kKSmXV03w>y>z?^t%%K?p=dH|6&@>IA1y@4L1y5%zRwSI72ML&7^&# zUy|-8E%*I;xpcG?|KH8?!e#S`@oVf18Fg{!%(M4HpJB z#%uzN#`C1_O4-;%oh=VieA&@bT!rYbDz;(dF8WCjF( zc(}UbO+-YhGdsJj)Ftc-h3PwJ zaiiejiP!RFiRkjalO_ZwQx*wE`v{2#Z+Skfth$Ow9)dv!(#&2h#dAftYHM*z>2p$i ze^$9ekmq#)(xFS7<49_rY<(<1LbK_`Oss9@Bpb#lb{4Q ze`gT}oo9ln3$ae|zS*D;fHEf+k<8yx0RsY;{zr=E*o9Fann8zmN%5S|m1^>2DZW1w zzq?37pv=x77^@{pgZ^OY*y3ksNRz1L=*pl|a4ElMjY2i%#@L__3?gjf4MRjtx5&Oy z>4Il38TWH7hG@`Pg;IDXp7#M#P0Dl`f6@^7tXk&9QaooK_^r9GOM_0qCio{Q{v22Q z-KC*ogFZ~iM2h##2EAdZIu>sh`a`K@m@$%n9nYD_?^+Depu-cSc;2kqYeED)K}Yd- zkkZ#GWKG0#B^sJw!q!;Hpp#-p8QS=7#51%I$hQ#|VbDpNHFdE;9|#nSAvGr6f2^lV zL*TB`H>7y(HF8>Es0JN)pv7~qZNMnX5+9(b=47fCWMY)(i7UHBN`oE?DKU8^yCnYm z#nO*RL!&E${xvDT=g0YhsS5Ep@xIxhHwb@R6i02AztOrY<(xD`!+d)UbFmWZ7AdSoHU%lKI5Sh5wt@DH#;d+k>lsbsS;P^?6tlLBxP+8 z4Ntm+#x3N`Q&8nkC3>n)nQ|WymsuB3b033AZGa3-UC5zcG#ItAnaty*G3}|ct?^Ka z{t6k&!j{)PWyaJPs}&~ynYL=se?ua&J@YRTwb{o2u2v$jnV?X*e|E~?wTO_T-WBXw zmaRu$ByD!vV?FS|IZKM^Tr`%69ioQBN-K0A&-xK*xCCAJqGw`i#LvqH-BhPVgO2O< zWobBrKZ2oGo{EsJHFZOti7hIDPIg_wUOJwU2-VmYRr{Yk=-8Ev{`e!&y$1C*t60s$oB(Z;<`5VcdiN;BEfx{w`VF*Hh76FBQCk&{@k09mr6@8}Yr_s|2ZGLya9Urb${e=!egb z8G2}&@lv{fT^BidqaSq{n?cbc`jOX!;xTaxiQvu?({S*t)u6*A(qqza2`c%OF%4tJ zF86Nn3VnWT0n&M54Qn2_1Pz(-5<7BzU;1DgE{v0<=nCIPdb?E16-@J>xKB>xcNboO zp}>l~oXoJr_UJU66gKGfu|c07TY$Xacs^rEQ!^`n6KjDJ{ZA8{MT3E5^_U^0tVUU0 zR-Z9jgDPRT`6(hZ7S^*u&+vJZh8j6Zq7L_zut7J~Y002dT`F?s{Ak7r#x1Ud`zl+D zXMj~S`|6qdNSkp5(|Ct;xX7cVGEHx)FnOopQik{fg5=0J7&CUccZ*l(^JCxOZjXgz z2pEcgfAD5}JaK-^)L0d76e6%OG7((CWnq-HfZLuRxLeF#C1?fJRGYZv&dW#BB;=)`M5*^JCwCP!cjy7NRiYqRjcGt6mEnC!LXoGjIj7 z+TL;YYU>;(#a5v-grOJySlQ?bJ@W>sjFlmfkkZd%#4dN!DXkcEx=&@uRb}>W#tH7{ zSpJk|HSbHqCScVVTU-8|bZQ!|3dLy%?#dA0hg*4Q9n=;L`Tu2h1F3#@OvBM)gI*th zuh8emK4H%>x+p&`l_f#VI3TJ$R{r~%#HzL>`0indW7RtL*JCT+lAB4aa<|ce@cpVw8=j=<70n`z_<7yqmWQ63EB!* zNM#We_Q6R-TaGtL1a)O-!s04uYlpfN_OS*9>>-_&hNHnQ_iphDeSYkdld%g?H1(Cs zy%MBu{kas+5xr0v3QR=exzqWN7Qeu%GX5LhhA}rB!SfKWm+X|BeIPWY$LM za&J-BOJm5z{vBz#>qBL)^RZI?trF&>{PgVAu=sU}_No!w z>{DrpTDsg>p_iT0YQq*1jcp?Lm(EMWPUy-#oH`T-!G#*L z8IF{2$+rUg{_OEbULw&|EkdU-0vj_tL>67DbV^Vfnj$k10xx58oFU-VWPK+8nYQBQ zqzYGt!ZNWUml-GDl4!nx3p+#LTv?Z(52)4tR_WHWSBdvXrOOwn7=K55)d;CpM8%u> z@Vy~@Ft)cPc7glV`U9O+W5x#ERHqe#9&=fVT)kTwnvp{p*jV1!x=kEA>aK{RzCUZIS0 zc#TApjux@YeX)3j-V^MLQ4%ymYSZp%XeIzr#Bom)!?)p&?J4(2;(!T0QtK z;QJRRk+ko8W*V*wR_M6xBmW@XCJjwxu9Y4v#o$T`6%i!Y8eXBBPHD-Yzgvp?luwfU zrJoMbptFZg?|K@*2xO~VK_cw%_m$F#MB7a=e446Vei=G-Yt{=Oj|SPS4!~@l2w|kZcPKq-^O6FTg;DLK>-_r z;9|G8Go)9iVHK8h-7{(3Ck;&pJWeWm?X!Ak+oL6H(7VSj_Xa3yVY3(6;(40-#MH&E zyY8{QQ-5|)dvY39TgV>?W|LZ2U7<0^^HRvC(Zygm&_gX?_Xm^;mn znXk-`HDOZt<}_S_$>Jh%mamtnfEXt#)U9__#O`>GL{psz-oHhrM6QG<4fU}>pC4O< z*?;vVX*h%6xWm(M@Q@>0x&)_A`H=nS{8$S*sIhk)gQIxZFS2JcUI6NiN9fFUhcq-D zz>1vaIvJjM6#8M2uo7Jv2D{uBi(T#w!5%8bB5010AwX{Eo!D+Cy+exo#b(QvL*~cK zN9M;`5M6%fG@L<3McJ`y5u77M?-SnxJbwiC*mMJ)9)jd3FP$NVf#N@XVuM~Ef2ITA zNQs$N*5{<5?x)ip^s`dD9z@F4M%YD)?=#eDWJI(xam&}iLzoqHE!ZQEpA+uy(#5}M z=oS{wsc!?b7G5F6bEZV^P#~Qxo;#w`-*W6B#s97>OTAI9kn(#*uYsw<0aCngM}JGE zK~9$9jUu?H>$IlYuqwdi8m}X3>IVI#QoIiCcP;jl=;#*TzlGv1$q;GU)Vi&+qveeqgF{pcL;LF%+gjC<1~DHr}iu8Fk9o@&}yHoqTKD z?)mkU4La9A+E~1fTK(|ZCoPTU34c;6;3XiNBc2~o_^mQ@gASDAjo0v9X>Tb)1;O~= zbYal()S0?W-k`U9xg>=x{X8(!%b(e7KitH>wh!(&vYmT z9cY$8?k*{98I1ZxQVe!#i6f-XDxwF?DUGE!(oNiK-;(H$@wGQ8DR*&(#Ykvjrk>meNiCXn# z-|+P?CW8(%;)&OTSiKYT5`R|9pwqWKzh~^iXX;>sK45m1&XwW~M686lk&Djj-Cd#z zS$RGeOK~4JGgX65EW|ZZJa1mtD6T^AWPE6%zm|r=eWiHrMCaG2YW74azVAjEn?YyG zkyg3!nsCKay)XW(3x9*Y*?#-x2O%~o-Z!`39vJLHJy*gY#v6&)Yv)0>ozx}!N;KMF zZ?-%K(y<7-S&pe0bc}88cOS(A^Z`;0-X_KO{)80k!w&(z&+!@v;M#0wHXHPnp%WX= zig;b+mR=VIotO?&7ZwZgzS*D;6pZR}E_j3+6XQuyms(&Xh<}!isb^8Rk4d3ejj0%P zCNzgiF>NpFYKbmbHK2$@d~a%|vllu<2+)exLN>={ut8rPydV@Ciq{rZ%b+vC%bg>GHkz|x%?McNXpW}=;UlGX}AOB5(MOgdX4jc&R3XSGSQ4_2dFW2^=p zHzwyrxy|Dw9)Dc%9J6SXTg%{*{ZPLD!=$0Yc2dk)MtqhV#Rh%r&hd9gE3bEDZ7)5(O#N zN*4y5J=gC^)WK&908vtv_eXptTnj;Ch=~aq0*Hw7>wo6DR-)JoVx`L@2@#+0)ww9o zT8jUk-yhGZ6zB0mX1XQPbWpfkxNh&5g#s%6ku+7=v|S~ci+1><=RA-kn2LnYz-y|xRN7hN!+I~ffs^% zj4{s;B)6VGIa&_KCM3tqkL%?CDXz*Xely0J_9nEye)c zUJ;`DWQOh3_otzmB6uunw(T^NAsSE`rbo7H`F}slOUmL${kQ-C002ovPDHLkV1i%a Brp*8V delta 6076 zcmZWtcRbYb|E~z)Y~d7_#&;cREi%*f1{XK%7OGRlrn zbjb|y^Zh;^-@kr;y#IW^9go@(Il`Bv=Prcxi|-+5k^Wt8UHACPgf=DR*8}y$tHcJrKr#Q$ExA6_A zd{kELeE3tfVdF;$fd&=;c?Ec1Q0YP$_d9xuJdRpJ@w^gVh~Iqxwf=Tg_^;q014#ZP zqPA5^#%3NqorU2ueCOF4Nc$BhNPWQS!F>}8mO>Rx0d4#D!l9$r?z90U28YnL>YMK4{k7qN z3S0NKcxp_Qsp!vXAkqIcA<@UvhgZC2mTW5(kmWsdHI5`-$RhM#Wlx*mjLmp^8U{X^ z8mrX}>Slv;&q$6kM0vtpxVKUZPA~myw-&t(>%DjbSJd&<28(uDLymktRsC`B3pb0S z?c0O85E#Tafib;q&RvlkV#8(~x$udxv#fnf7Xnm#Q#k=sv(w&9^wjs)vE!+|d6Y6?U7p43Wrc;4o1H8?4%ohPl)A59p} zBnj`gr&veydEL zaC7R}Qy0*ZhPG3pZExPLB^dnv-Shl!wL0o=zWG4z-E#^vo|xcDT6xjAv+N%3w5Iqv z7E&e%$3RYNbVB|<;B8N6gCe(yiPb|s`p#T37srn&tBt%*>gouE`*P4W<+AxaFQ>?< zPw3kcVXg^D6#o=@f6^lhra@UswDQb)Mr@q>!GEMm{5SEc=%88z&VyVQD5eh`g?CPc znH8g#+{P&%q~oFx-#to#t_Evg-0gj}-SvTfB)7Y{06n^al=i7+S;~oAvMS)wcXVQi z{>)UU0#u>gcHvS5T2n7k4&zWl(o&5^9{830r7a4^`dti9ev##~rzNP)n$+mi#+zzV zo8_udMdq>7D<%96O|*bZgue-F&kmXmr$3vXpD9!+wqZWQu>i5c=f8;hcolB`XS}_q zj-iX<#`3#3Waqv=RzPe$XRYR6ZDa!J zirYRfe>Sd#e^2}3Om>ySf@D;wmJ48&REbw!S$UrFD2SKy_V&0js zm#R>5Iq%Lt=M=|Q_fQI!%B7cHPiJ5ESsipwAm;X~B6X|>L?bT(@%wj)i58c7H{3dL(KUe{q+by80jHo?Ijc;%zrHxMu*FzUx}YKuDd0%X_hhS;|qPydwO zv<>-h{@5MV6)H}fM5c%k1?{Aam>D&nsS$DDStuPT;ZI{tp=!y3=<=(`9Of6EYzyfz zx6aUdN!LakR4g4}6t@R;C`zvzGNA=8Yuqlheze_uu)~t8^RmSQ2j7$)@|ea*299ZU zb8N%8gcwy6)IDo(hOBadf$xO89*<}S9Xu>F9FzGac zFx(WBamudaO7_h8hbo=-lFihhqhwraUv2SVeV-cSMEIE?jivQb5{Hp}xk=iY)0a|} z3sB^z!{K(slp{A8!6LH5F+_Fi3jhtB;Z=?GHLY?oujdL#sGWNechEt$Ap$LWHDSj8 zIs(ijTrnQ3_*1iBg$cD1l^t2as4T{bGRnFMlCPXeEnJ~Jr@~nK2&pzrPl0^+>pzgo z&w1bQ+d^yb8r%OYJ5=@?#|v}(I|7tJngf=F#2|QHAzkMbUgcw)>E@n2qqd@!-G$>QYJy9odF?&l$fJ)pyvCE$ub{qp2B&kr++P;7js>1=mB@ zjM?0oe&PMUc-GC7dMEJc9n;f4Qc`yd=HVpa!Bf|*J5Y)jD-=caJ}=U0$BD8g4{C5vo_XV({D)_G%bum|#w%56u;QgeCW)^?he zByDb;?!|lN*vj883L3QQo^(plV^7!A1K+G%XQwXzG&DeK=@zHgtz{c(&CPik#Pv@! zu^aFdDd`$X0Dtq|#Dx@oi<4HQte+O@AU*h}`XqV|Y<#18!zABs57c-VAHT6l0 z$(vC87SvRtr%jRd!!QB9p$XR$clUy{e5kHNQSz-U}LxNJ2>m0U)HKSY=y z5?y`M^D8s?o2a=ma**AqZnptGfmNPiVeD<}fHB5SySR9TuS!MsvrBJo4KMbor{hn@ zmTiIid?2THVz8#usW2kZAjRqHg6@F(8@0qORkkl`pJGHKYAqsAZs#?3T>IIT%#*sfS$ZG$TVzKiu{cO z)$i^K#acSo0JU=X%!?onr?EKtl`_QawPys79{$14!3b#Z;MN& zhV;sRS@XJyZM7IBf$2f>=w#Y z^i50LZh+;@BVXsLw1^p-)YEGb0r@Lm_ug|*$|eYMbu9`mrsj41Z5IMS9zFd9P6aD# z%XxFG=&ixQfN&&wKU!jFJY*<~pM7d%R6mz&20tfXICLN9^r0%{n+1>(SN4ySSt|M% zsXxs|cDyxLX1n{7Y3K1>!dx+tsSedxqbjCQ{22q|1AkTjC6<+n$r?`{%3_sYI9nEq z3^K^>{43Y8=#}dEG#r=)fy=LRh<ZpGRa>-dU)$||L)F!8m>F>k9pM44PO^PdmwSj4&&%+a@tZ3W{2;S4`F>bXBExS#k>;+P>qP=e5ly+SITcfh|+u z_3T^NfcX_W==o{df`8P@Momwk|J8%K$&IF$jo-2c0g~41wek1gk1ZvKpc<0HQ3Qt z-Cka8v1xpWga%S>UHKHagN#4*H3pB)n)5zgV4ie8PBQ);R>N@bK8P|H|k6 zF>q(lt+G2AO$;CP`{Y_Q^0hRhE_q1II!}!1uvhR#22Y*Kk(3m3kl-po0BgI=$qz6Q z2JGj)%pi*kS2FI*#tl$~IZ7tU@LMdR$d;0;L%F4|zSiw_{2wjTB$e9G~}U@$D$&q+@=Du*$oieo{s>XsH>cKQE-zmLMdmJ|rKg!SAUne+zXYGGWo*7_=U zhx&+->NJY1aT7?yXfH#}dk$kHX!0PTbc(-M%S*Sz-TJi6MG63VHtELI;-VF%B;Sh9 zOi9KKvs!V9?K0vEUeP`0K5Hynzg!5O+b>Be13*y)$NuH|LpdNc^0=Ys>bi%$_#Ete ze`RhENW~NX^(zOlY_f`asPR{N?Jpdrh>S}hx%JSzwPt66NoI55l1<5y>Z<0V+;$ap z1MGg-%~&1HE&@=65BKFjWq)`g9|M>!Ege1!lDMp~a}5&Gcu%fib;;L`{Y1Q8X7gZ| zIv~(3l3p9X%KU;UCj;ZSwk@vQ1=_P`v$5e$z`zmd3JBhva+*&uv0ENe7rEW_R+Yw0t%Nq;cQhg|51V+59b|p>99j3 z=yc;h`Yr#*)0E375NiHDm!c*iSF>=Xbas}G`Q!LT|1<%aU-KA~&;9XH_r$XNlI(ZA zJ^Sy%d-l3%ENyb2RGaEq&Cx#xOsovw)Wez%DzUS-#}b@NnLAHsoRDisG*SP*(&k|r zVD&T+1E-2rPy|uZ%T*U@d;UnGpNkuftIG`q`^`w)!-fas+{f)+)AvwRb*fh=$lJOc zH&QbLzlYzC(?`8c-W(MF55iwJ%98tiV2R3=)4*J5%zIbGmz6?-HPFpr;+n9b?0^`JJ59}!=y{*YqolTr#pdO)Jn+;eRhlylQ z=7WYU&|xfN=}fI^!KixluLwP02p`UJ(OfNZpwXy0NaARvD59f8?6%zoVCfWc=2%(m za(?AxhHH1}mDJ~#+)~21pNia-CoI*?KFWV@>3?w(+Z^vSrglHul%{pr)czC2?ccw9 z_cV>EMYaZWC;RWWZ#Z4<-Gjk~Egn7kX%u->RHC!!8qBjPsQnPPr_!506<*C7Ge$C- zPsm*Ccja9Vx}9=rr7{EnL`6_)kXtM|P<^Fga2zDBA1iC!{id+BkcyT38!#EB(r@JS zL((U7@eh~p+p}d#Es45_{5vF^1<9_i9hKKZeH$Ibyv#;+UNpRGSU&wa8>Iqv2lL-+ zzC;kVrFJUk-O0fivKw-5RVKi-in#3i9=Y1YIqa{$Z zLfb+Ot3SU*^EAb|0sQmHvR#}6trZ7_Nel<){;$ZK1{aq6o*U6om8`T5+Mn0VyxK0A z9HBMnhveYR+5_5kC)Q&#aTVd{^Sb#Jos88}UPVZSs+^gk%&xzs+dnyqR6k7Z1R5sj z#Jvse&6#=GI2k0^E-)r;luC)*ZL8zL*?nJ5ENHQB@!8BGRuXw_A0v>)ieee4ZOFqS zxA8fJ@9@ZtQR_FTRu7h!O^D0X6>)N9a}EE|KHjeqVex+_&x@Rd%nhJpYSuEw!+ng0!0GV-Z;_=wv#N)4HYp!+&DnD-!Kd?zud;C|wih-@kAD zqAx4#`OX4UYiVRvAYT0oOXEZ_!U@S8FFrN&@4}pY4bDexSe|_O)vt01_aSub=9T;c zAyVA24&i1<9|JS9Bsl})#tbmxU7?O=>p`Y!G4U#`l)W;@u4B2l->#f(1RebrMyxjk z{ccIZ-BbFSr>1lDh}U|ilc-Up@|1JGB5o%2bC}A8hxdoByI*)^Ht$l{YYJ2(n?y*z zWwdANP@4DM>dI{p;b*Jus4$lb^Ch7iqT0i|r0iED3|nOQZ8>jn@mT;$ZDSf7%_>fb zS`5!yG>nIGKi0zTN!7WI?^5^e-BNw6{TO3x=GeMSw1Xht%E4t#b_#GWZXT{l=%^bf z^1dlw`&YGYo3FaUU7ELRo^Wbev$oDz7(n!-Ahkx&xmu}^+*=-|??B!-{-op2Lj8M1 z-o(LYRBoc~E$5iFriueNN0mhXjzyTH`12F;y%fIv;Y*8R%1RxLYrOKwu`wq}IDMrk z&;VRXGulvSF8C|p$$mtH^^YBosnaUyv^&el*mn@GoIY}Es$UX)ifZxmzSq{BbZS#k8M-7k<;FIuF88X1D6t$vpiSBY)sH>W!9iFpk(| x{D-;vN!&OG62}0h{{Qdlb+BV3%<`OjO Date: Sun, 13 Sep 2020 22:40:05 +0200 Subject: [PATCH 10/27] Fix links --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 41cf824d4..cfa9ebb7b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ ![GBX.NET](logo.png) -![Nuget](https://img.shields.io/nuget/v/GBX.NET?style=for-the-badge) -![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/BigBang1112/gbx-net?include_prereleases&style=for-the-badge) -![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/BigBang1112/gbx-net?style=for-the-badge) -![GitHub](https://img.shields.io/github/license/BigBang1112/gbx-net?style=for-the-badge) +[![Nuget](https://img.shields.io/nuget/v/GBX.NET?style=for-the-badge)](https://www.nuget.org/packages/GBX.NET/) +[![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/BigBang1112/gbx-net?include_prereleases&style=for-the-badge)](https://github.com/BigBang1112/gbx-net/releases/latest) +[![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/BigBang1112/gbx-net?style=for-the-badge)](#) +[![GitHub](https://img.shields.io/github/license/BigBang1112/gbx-net?style=for-the-badge)](#) GBX.NET is a .NET GBX file parser library written in C#. GBX (or GameBox) is a file type available in many of the Nadeo games. From 0e0590fb3fce29cde0fc249a2fc8de3714403e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Mon, 14 Sep 2020 23:57:20 +0200 Subject: [PATCH 11/27] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cfa9ebb7b..ac046db5b 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,16 @@ [![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/BigBang1112/gbx-net?style=for-the-badge)](#) [![GitHub](https://img.shields.io/github/license/BigBang1112/gbx-net?style=for-the-badge)](#) -GBX.NET is a .NET GBX file parser library written in C#. GBX (or GameBox) is a file type available in many of the Nadeo games. +GBX.NET is a GameBox (.Gbx) file parser library written in C# for .NET software framework. This file type can be in many of the Nadeo games - TrackMania, ShootMania, Virtual Skipper... -This GBX parser can recognize the entire GBX file. Modification of some GBX types is supported. -All versions of GBX are supported: ranging from TM1.0 to TM®. - -Reading PAK file isn't currently supported. +- Can recognize **entire GBX files**, however **can't read all possible files**. GBX file is basically a serialized class from the GameBox engine, and all of these classes must be known to read. This is where you can help contributing to the project, by exploring new chunks. How to do it will be documented soon. +- Can write GBX files which can be read by the parser, however this does not apply to all readable GBXs. +- All versions of GBX are supported: ranging from TM1.0 to TM®. +- Reading PAK file isn't currently supported. ## Compatibility -GBX.NET is compatible with .NET Standard 2.0 since version 0.2.0. Earlier versions are built on .NET Standard 2.1. +GBX.NET is compatible with **.NET Standard 2.0** since version 0.2.0. Earlier versions are built on .NET Standard 2.1. The library is also set to x86 assembly due to LZO compression problems in x64. It is unsure whenever this will be resolved. From a6e64ddda271d53ceebe92ca6e3b5e4e26ebcf28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Tue, 15 Sep 2020 22:11:36 +0200 Subject: [PATCH 12/27] Improve Node parsing algorithm --- GBX.NET/Node.cs | 153 +++++++++++++++++++++++------------------------- 1 file changed, 74 insertions(+), 79 deletions(-) diff --git a/GBX.NET/Node.cs b/GBX.NET/Node.cs index 6f07a6b8a..334802441 100644 --- a/GBX.NET/Node.cs +++ b/GBX.NET/Node.cs @@ -69,6 +69,7 @@ public uint[] ChunkIDs } public static Dictionary AvailableClasses { get; } = new Dictionary(); + public static Dictionary> AvailableInheritanceClasses { get; } = new Dictionary>(); public static Dictionary> AvailableChunkClasses { get; } = new Dictionary>(); /// @@ -109,17 +110,11 @@ public static Node[] ParseArray(Type type, ILookbackable body, GameBoxReader r) var count = r.ReadInt32(); var array = new Node[count]; - List inheritanceClasses = null; - Dictionary availableChunkClasses = null; - for (var i = 0; i < count; i++) { _ = r.ReadUInt32(); - if (i == 0) - array[i] = Parse(type, body, r, out inheritanceClasses, out availableChunkClasses); - else - array[i] = Parse(type, body, r, inheritanceClasses, availableChunkClasses); + array[i] = Parse(type, body, r); } return array; @@ -137,10 +132,7 @@ public static Node Parse(ILookbackable body, uint classID, GameBoxReader r) if (!AvailableClasses.TryGetValue(newerClassID, out Type availableClass)) { - availableClass = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass - && x.Namespace.StartsWith("GBX.NET.Engines") && GetBaseType(x) == typeof(Node) - && (x.GetCustomAttribute().ID == newerClassID)).FirstOrDefault(); - AvailableClasses.Add(newerClassID, availableClass); + } var inheritanceClasses = new List(); @@ -151,77 +143,12 @@ public static Node Parse(ILookbackable body, uint classID, GameBoxReader r) return Parse(availableClass, body, r); } - private static Node Parse(Type type, ILookbackable body, GameBoxReader r, out List inheritanceClasses, out Dictionary availableChunkClasses) - { - inheritanceClasses = GetInheritance(type); - - List GetInheritance(Type t) - { - List classes = new List(); - - Type cur = t.BaseType; - - while (cur != typeof(Node)) - { - classes.Add(cur.GetCustomAttribute().ID); - cur = cur.BaseType; - } - - return classes; - } - - var chunkType = typeof(Chunk<>).MakeGenericType(type); - var skippableChunkType = typeof(SkippableChunk<>).MakeGenericType(type); - - if (!AvailableChunkClasses.TryGetValue(type, out availableChunkClasses)) - { - availableChunkClasses = type.GetNestedTypes().Where(x => - { - var isChunk = x.IsClass - && x.Namespace.StartsWith("GBX.NET.Engines") - && (x.BaseType == chunkType || x.BaseType == skippableChunkType); - if (!isChunk) return false; - - var chunkAttribute = x.GetCustomAttribute(); - if (chunkAttribute == null) throw new Exception($"Chunk {x.FullName} doesn't have a ChunkAttribute."); - - var attributesMet = chunkAttribute.ClassID == type.GetCustomAttribute().ID; - return isChunk && attributesMet; - }).ToDictionary(x => x.GetCustomAttribute().ChunkID); - - foreach (var cls in inheritanceClasses) - { - var availableInheritanceClass = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass - && x.Namespace.StartsWith("GBX.NET.Engines") && (GetBaseType(x) == typeof(Node)) - && (x.GetCustomAttribute().ID == cls)).FirstOrDefault(); - - var inheritChunkType = typeof(Chunk<>).MakeGenericType(availableInheritanceClass); - var inheritSkippableChunkType = typeof(SkippableChunk<>).MakeGenericType(availableInheritanceClass); - - foreach (var chunkT in availableInheritanceClass.GetNestedTypes().Where(x => x.IsClass - && x.Namespace.StartsWith("GBX.NET.Engines") && (x.BaseType == inheritChunkType || x.BaseType == inheritSkippableChunkType) - && (x.GetCustomAttribute().ClassID == cls)).ToDictionary(x => x.GetCustomAttribute().ChunkID)) - { - availableChunkClasses[chunkT.Key + cls] = chunkT.Value; - } - } - AvailableChunkClasses.Add(type, availableChunkClasses); - } - - return Parse(type, body, r, inheritanceClasses, availableChunkClasses); - } - - public static Node Parse(Type type, ILookbackable body, GameBoxReader r) - { - return Parse(type, body, r, out List _, out Dictionary _); - } - public static T Parse(ILookbackable body, GameBoxReader r) where T : Node { return (T)Parse(typeof(T), body, r); } - private static Node Parse(Type type, ILookbackable body, GameBoxReader r, List inheritanceClasses, Dictionary availableChunkClasses) + private static Node Parse(Type type, ILookbackable body, GameBoxReader r) { var readNodeStart = DateTime.Now; @@ -256,8 +183,8 @@ private static Node Parse(Type type, ILookbackable body, GameBoxReader r, List); @@ -520,6 +447,74 @@ static Node() } Debug.WriteLine("Mappings defined in " + (DateTime.Now - startTimestamp).TotalMilliseconds + "ms"); + + startTimestamp = DateTime.Now; + + foreach (var nodeType in Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass + && x.Namespace.StartsWith("GBX.NET.Engines") && GetBaseType(x) == typeof(Node))) + { + var nodeID = nodeType.GetCustomAttribute().ID; + + AvailableClasses.Add(nodeID, nodeType); + + var inheritanceClasses = GetInheritance(nodeType); + AvailableInheritanceClasses[nodeType] = inheritanceClasses; + + List GetInheritance(Type t) + { + List classes = new List(); + + Type cur = t.BaseType; + + while (cur != typeof(Node)) + { + classes.Add(cur.GetCustomAttribute().ID); + cur = cur.BaseType; + } + + return classes; + } + + var chunkType = typeof(Chunk<>).MakeGenericType(nodeType); + var skippableChunkType = typeof(SkippableChunk<>).MakeGenericType(nodeType); + + if (!AvailableChunkClasses.TryGetValue(nodeType, out Dictionary availableChunkClasses)) + { + availableChunkClasses = nodeType.GetNestedTypes().Where(x => + { + var isChunk = x.IsClass + && x.Namespace.StartsWith("GBX.NET.Engines") + && (x.BaseType == chunkType || x.BaseType == skippableChunkType); + if (!isChunk) return false; + + var chunkAttribute = x.GetCustomAttribute(); + if (chunkAttribute == null) throw new Exception($"Chunk {x.FullName} doesn't have a ChunkAttribute."); + + var attributesMet = chunkAttribute.ClassID == nodeID; + return isChunk && attributesMet; + }).ToDictionary(x => x.GetCustomAttribute().ChunkID); + + foreach (var cls in inheritanceClasses) + { + var availableInheritanceClass = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass + && x.Namespace.StartsWith("GBX.NET.Engines") && (GetBaseType(x) == typeof(Node)) + && (x.GetCustomAttribute().ID == cls)).FirstOrDefault(); + + var inheritChunkType = typeof(Chunk<>).MakeGenericType(availableInheritanceClass); + var inheritSkippableChunkType = typeof(SkippableChunk<>).MakeGenericType(availableInheritanceClass); + + foreach (var chunkT in availableInheritanceClass.GetNestedTypes().Where(x => x.IsClass + && x.Namespace.StartsWith("GBX.NET.Engines") && (x.BaseType == inheritChunkType || x.BaseType == inheritSkippableChunkType) + && (x.GetCustomAttribute().ClassID == cls)).ToDictionary(x => x.GetCustomAttribute().ChunkID)) + { + availableChunkClasses[chunkT.Key + cls] = chunkT.Value; + } + } + AvailableChunkClasses.Add(nodeType, availableChunkClasses); + } + } + + Debug.WriteLine("Types defined in " + (DateTime.Now - startTimestamp).TotalMilliseconds + "ms"); } public T GetChunk() where T : Chunk From b43c8b0716bd613a10da002a56bdcba77bfa7ea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Tue, 15 Sep 2020 23:20:36 +0200 Subject: [PATCH 13/27] Eliminate dynamic declaration while reading --- GBX.NET/Chunk.cs | 13 +++- GBX.NET/Engines/Game/CGameCtnChallenge.cs | 2 +- .../Engines/Game/CGameCtnMediaBlockGhost.cs | 4 +- GBX.NET/Engines/Game/CGameCtnMediaTrack.cs | 2 +- GBX.NET/Engines/Game/CGameCtnReplayRecord.cs | 4 +- .../Engines/GameData/CGameCtnAutoTerrain.cs | 5 +- GBX.NET/GameBoxBody.cs | 2 +- GBX.NET/GameBoxHeader.cs | 4 +- GBX.NET/GameBoxReader.cs | 53 +++------------ GBX.NET/GameBoxReaderWriter.cs | 15 ++--- GBX.NET/IChunk.cs | 15 +++++ GBX.NET/ISkippableChunk.cs | 2 +- GBX.NET/Node.cs | 65 +++++++------------ 13 files changed, 76 insertions(+), 110 deletions(-) create mode 100644 GBX.NET/IChunk.cs diff --git a/GBX.NET/Chunk.cs b/GBX.NET/Chunk.cs index f5721ea2e..b6531983e 100644 --- a/GBX.NET/Chunk.cs +++ b/GBX.NET/Chunk.cs @@ -10,7 +10,6 @@ namespace GBX.NET public abstract class Chunk : IComparable { public virtual uint ID => GetType().GetCustomAttribute().ID; - public int Progress { get; internal set; } /// /// Stream of unknown bytes /// @@ -37,6 +36,7 @@ public virtual ILookbackable Lookbackable } } + [IgnoreDataMember] public GameBoxPart Part { get; set; } public Chunk() @@ -89,10 +89,17 @@ public int CompareTo(Chunk other) } } - public abstract class Chunk : Chunk where T : Node + public abstract class Chunk : Chunk, IChunk where T : Node { [IgnoreDataMember] public T Node { get; internal set; } + public int Progress { get; set; } + + Node IChunk.Node + { + get => Node; + set => Node = (T)value; + } public bool IsHeader => Lookbackable is GameBoxHeader; public bool IsBody => Lookbackable is GameBoxBody; @@ -166,6 +173,8 @@ public virtual void ReadWrite(T n, GameBoxReaderWriter rw) } } + void IChunk.ReadWrite(Node n, GameBoxReaderWriter rw) => ReadWrite((T)n, rw); + public byte[] ToByteArray() { var lookbackable = Lookbackable; diff --git a/GBX.NET/Engines/Game/CGameCtnChallenge.cs b/GBX.NET/Engines/Game/CGameCtnChallenge.cs index b08f46423..ef06d37d8 100644 --- a/GBX.NET/Engines/Game/CGameCtnChallenge.cs +++ b/GBX.NET/Engines/Game/CGameCtnChallenge.cs @@ -2082,7 +2082,7 @@ public override void Read(CGameCtnChallenge n, GameBoxReader r, GameBoxWriter un using (var ms = new MemoryStream(data)) using (var zlib = new InflaterInputStream(ms)) using (var gbxr = new GameBoxReader(zlib)) - return (CHmsLightMapCache)Parse(Node.Body, 0x06022000, gbxr); + return Parse(Node.Body, gbxr); }); } } diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockGhost.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockGhost.cs index 5ef9a6370..51cf5daaf 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockGhost.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockGhost.cs @@ -35,7 +35,7 @@ public override void ReadWrite(CGameCtnMediaBlockGhost n, GameBoxReaderWriter rw { n.Start = rw.Single(n.Start.GetValueOrDefault()); n.End = rw.Single(n.End.GetValueOrDefault(3)); - n.Ghost = rw.NodeRef(n.Ghost, true); + n.Ghost = rw.NodeRef(n.Ghost); n.Offset = rw.Single(n.Offset.GetValueOrDefault()); } } @@ -60,7 +60,7 @@ public override void ReadWrite(CGameCtnMediaBlockGhost n, GameBoxReaderWriter rw rw.Writer.Write(x.Unknown); }); - n.Ghost = rw.NodeRef(n.Ghost, true); + n.Ghost = rw.NodeRef(n.Ghost); n.Offset = rw.Single(n.Offset.GetValueOrDefault()); n.NoDamage = rw.Boolean(n.NoDamage); n.ForceLight = rw.Boolean(n.ForceLight); diff --git a/GBX.NET/Engines/Game/CGameCtnMediaTrack.cs b/GBX.NET/Engines/Game/CGameCtnMediaTrack.cs index 0ac9f79bf..3351e9e47 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaTrack.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaTrack.cs @@ -39,7 +39,7 @@ public override void ReadWrite(CGameCtnMediaTrack n, GameBoxReaderWriter rw) n.Name = rw.String(n.Name); Unknown1 = rw.Int32(Unknown1); // 10, probably version n.Blocks = rw.Array(n.Blocks?.ToArray(), - i => rw.Reader.ReadNodeRef(true), + i => rw.Reader.ReadNodeRef(), x => rw.Writer.Write(x))?.ToList(); Unknown2 = rw.Int32(Unknown2); } diff --git a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs index a41e19279..ab60aac3d 100644 --- a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs +++ b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs @@ -175,7 +175,7 @@ public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter r.ReadInt32(); r.ReadInt32(); - n.Ghosts = r.ReadArray(i => r.ReadNodeRef(true)); + n.Ghosts = r.ReadArray(i => r.ReadNodeRef()); r.ReadInt32(); r.ReadInt32(); @@ -260,7 +260,7 @@ public class Chunk03093014 : Chunk public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) { Version = r.ReadInt32(); - n.Ghosts = r.ReadArray(i => r.ReadNodeRef(true)); + n.Ghosts = r.ReadArray(i => r.ReadNodeRef()); Unknown1 = r.ReadInt32(); n.Extras = r.ReadArray(i => r.ReadInt64()); } diff --git a/GBX.NET/Engines/GameData/CGameCtnAutoTerrain.cs b/GBX.NET/Engines/GameData/CGameCtnAutoTerrain.cs index 4e1afd246..59f319545 100644 --- a/GBX.NET/Engines/GameData/CGameCtnAutoTerrain.cs +++ b/GBX.NET/Engines/GameData/CGameCtnAutoTerrain.cs @@ -1,4 +1,5 @@ -using System; +using GBX.NET.Engines.Game; +using System; using System.Collections.Generic; using System.Text; @@ -18,7 +19,7 @@ public class Chunk03120001 : Chunk public override void Read(CGameCtnAutoTerrain n, GameBoxReader r, GameBoxWriter unknownW) { var offset = r.ReadInt3(); - var genealogy = r.ReadNodeRef(); + var genealogy = r.ReadNodeRef(); } } } diff --git a/GBX.NET/GameBoxBody.cs b/GBX.NET/GameBoxBody.cs index f88861b09..cdf079612 100644 --- a/GBX.NET/GameBoxBody.cs +++ b/GBX.NET/GameBoxBody.cs @@ -30,7 +30,7 @@ public GameBoxBody(GameBox gbx, uint mainNodeID, byte[] data, int? compressed using (var s = new MemoryStream(data)) using (var gbxr = new GameBoxReader(s, this)) { - gbx.MainNode = (T)Node.Parse(this, mainNodeID, gbxr); + gbx.MainNode = Node.Parse(this, gbxr, mainNodeID); Debug.WriteLine("Amount read: " + (s.Position / (float)s.Length).ToString("P")); byte[] restBuffer = new byte[s.Length - s.Position]; diff --git a/GBX.NET/GameBoxHeader.cs b/GBX.NET/GameBoxHeader.cs index 50cf51db6..91c84cbac 100644 --- a/GBX.NET/GameBoxHeader.cs +++ b/GBX.NET/GameBoxHeader.cs @@ -116,13 +116,13 @@ List GetInheritance(Type t) var constructorParams = constructor.GetParameters(); if (constructorParams.Length == 0) { - dynamic headerChunk = constructor.Invoke(new object[0]); + ISkippableChunk headerChunk = (ISkippableChunk)constructor.Invoke(new object[0]); headerChunk.Node = GBX.MainNode; headerChunk.Part = this; headerChunk.Stream = new MemoryStream(d, 0, d.Length, false); if (d == null || d.Length == 0) headerChunk.Discovered = true; - chunks[counter] = headerChunk; + chunks[counter] = (Chunk)headerChunk; } else if (constructorParams.Length == 2) chunks[counter] = (HeaderChunk)constructor.Invoke(new object[] { GBX.MainNode, d }); diff --git a/GBX.NET/GameBoxReader.cs b/GBX.NET/GameBoxReader.cs index ab492beec..c35144015 100644 --- a/GBX.NET/GameBoxReader.cs +++ b/GBX.NET/GameBoxReader.cs @@ -126,16 +126,13 @@ public Meta ReadMeta() return ReadMeta(Lookbackable); } - public Node ReadNodeRef(GameBoxBody body) + public T ReadNodeRef(GameBoxBody body) where T : Node { var index = ReadInt32() - 1; // GBX seems to start the index at 1 if (index >= 0 && body.AuxilaryNodes.ElementAtOrDefault(index) == null) // If index is 0 or bigger and the node wasn't read yet { - var classID = ReadUInt32(); - Debug.WriteLine("Node ref class: " + classID.ToString("x8")); - - Node node = Node.Parse(body, classID, this); + T node = Node.Parse(body, this); if (index >= body.AuxilaryNodes.Count) body.AuxilaryNodes.Add(node); @@ -145,56 +142,26 @@ public Node ReadNodeRef(GameBoxBody body) if (index < 0) // If aux node index is below 0 then there's not much to solve return null; - var nod = body.AuxilaryNodes.ElementAtOrDefault(index); // Tries to get the available node from index + var nod = (T)body.AuxilaryNodes.ElementAtOrDefault(index); // Tries to get the available node from index if (nod == null) // But sometimes it indexes the node reference that is further in the expected indexes - return body.AuxilaryNodes.Last(); // So it grabs the last one instead, needs to be further tested + return (T)body.AuxilaryNodes.Last(); // So it grabs the last one instead, needs to be further tested else // If the node is presented at the index, then it's simple return nod; } - public Node ReadNodeRef() - { - return ReadNodeRef((GameBoxBody)Lookbackable); - } - - public T ReadNodeRef(bool hasInheritance, GameBoxBody body) where T : Node + public T ReadNodeRef() where T : Node { - var index = ReadInt32() - 1; // GBX seems to start the index at 1 - - if (index >= 0 && body.AuxilaryNodes.ElementAtOrDefault(index) == null) // If index is 0 or bigger and the node wasn't read yet - { - var classID = ReadUInt32(); - Debug.WriteLine("Node ref class: " + classID.ToString("x8")); - - Node node; - if (hasInheritance) - node = Node.Parse(body, classID, this); - else - node = Node.Parse(body, this); - - if (index >= body.AuxilaryNodes.Count) - body.AuxilaryNodes.Add(node); - else - body.AuxilaryNodes.Insert(index, node); - } - - if (index < 0) // If aux node index is below 0 then there's not much to solve - return null; - var nod = (T)body.AuxilaryNodes.ElementAtOrDefault(index); // Tries to get the available node from index - if (nod == null) // But sometimes it indexes the node reference that is further in the expected indexes - return (T)body.AuxilaryNodes.Last(); // So it grabs the last one instead, needs to be further tested - else // If the node is presented at the index, then it's simple - return nod; + return ReadNodeRef((GameBoxBody)Lookbackable); } - public T ReadNodeRef(bool hasInheritance) where T : Node + public Node ReadNodeRef(GameBoxBody body) { - return ReadNodeRef(hasInheritance, (GameBoxBody)Lookbackable); + return ReadNodeRef(body); } - public T ReadNodeRef() where T : Node + public Node ReadNodeRef() { - return ReadNodeRef(false); + return ReadNodeRef((GameBoxBody)Lookbackable); } public FileRef ReadFileRef() diff --git a/GBX.NET/GameBoxReaderWriter.cs b/GBX.NET/GameBoxReaderWriter.cs index 4d103fe98..8746b814e 100644 --- a/GBX.NET/GameBoxReaderWriter.cs +++ b/GBX.NET/GameBoxReaderWriter.cs @@ -409,23 +409,18 @@ public void NodeRef(Stream stream) else throw new Exception(); } - public T NodeRef(Node variable, bool hasInheritance, GameBoxBody body) where T : Node + public T NodeRef(Node variable, GameBoxBody body) where T : Node { - if (Reader != null) return Reader.ReadNodeRef(hasInheritance, body); + if (Reader != null) return Reader.ReadNodeRef(body); else if (Writer != null) Writer.Write(variable, body); return (T)variable; } - public T NodeRef(Node variable, bool hasInheritance) where T : Node - { - if (Reader != null) return NodeRef(variable, hasInheritance, (GameBoxBody)Reader.Lookbackable); - else if (Writer != null) return NodeRef(variable, hasInheritance, (GameBoxBody)Writer.Lookbackable); - else throw new Exception(); - } - public T NodeRef(Node variable) where T : Node { - return NodeRef(variable, false); + if (Reader != null) return NodeRef(variable, (GameBoxBody)Reader.Lookbackable); + else if (Writer != null) return NodeRef(variable, (GameBoxBody)Writer.Lookbackable); + else throw new Exception(); } public float Single(float variable) diff --git a/GBX.NET/IChunk.cs b/GBX.NET/IChunk.cs new file mode 100644 index 000000000..cacf6fca6 --- /dev/null +++ b/GBX.NET/IChunk.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBX.NET +{ + public interface IChunk + { + Node Node { get; set; } + GameBoxPart Part { get; set; } + int Progress { get; set; } + void OnLoad(); + void ReadWrite(Node n, GameBoxReaderWriter rw); + } +} diff --git a/GBX.NET/ISkippableChunk.cs b/GBX.NET/ISkippableChunk.cs index 9a085f13a..79efb0bba 100644 --- a/GBX.NET/ISkippableChunk.cs +++ b/GBX.NET/ISkippableChunk.cs @@ -5,7 +5,7 @@ namespace GBX.NET { - public interface ISkippableChunk + public interface ISkippableChunk : IChunk { bool Discovered { get; set; } MemoryStream Stream { get; set; } diff --git a/GBX.NET/Node.cs b/GBX.NET/Node.cs index 334802441..39fb721a7 100644 --- a/GBX.NET/Node.cs +++ b/GBX.NET/Node.cs @@ -105,54 +105,33 @@ static Type GetBaseType(Type t) return GetBaseType(t.BaseType); } - public static Node[] ParseArray(Type type, ILookbackable body, GameBoxReader r) + public static T[] ParseArray(ILookbackable body, GameBoxReader r) where T : Node { var count = r.ReadInt32(); - var array = new Node[count]; + var array = new T[count]; for (var i = 0; i < count; i++) { _ = r.ReadUInt32(); - array[i] = Parse(type, body, r); + array[i] = Parse(body, r); } return array; } - public static T[] ParseArray(ILookbackable body, GameBoxReader r) where T : Node - { - return ParseArray(typeof(T), body, r).Cast().ToArray(); - } - - public static Node Parse(ILookbackable body, uint classID, GameBoxReader r) + public static T Parse(ILookbackable body, GameBoxReader r, uint? classID = null) where T : Node { - var hasNewerID = Mappings.TryGetValue(classID, out uint newerClassID); - if (!hasNewerID) newerClassID = classID; - - if (!AvailableClasses.TryGetValue(newerClassID, out Type availableClass)) - { - - } - - var inheritanceClasses = new List(); + var readNodeStart = DateTime.Now; - if (availableClass == null) - throw new Exception("Unknown node: 0x" + classID.ToString("x8")); + if (classID == null) + classID = r.ReadUInt32(); + if (Mappings.TryGetValue(classID.Value, out uint newerClassID)) + classID = newerClassID; - return Parse(availableClass, body, r); - } - - public static T Parse(ILookbackable body, GameBoxReader r) where T : Node - { - return (T)Parse(typeof(T), body, r); - } - - private static Node Parse(Type type, ILookbackable body, GameBoxReader r) - { - var readNodeStart = DateTime.Now; + var type = AvailableClasses[classID.Value]; - Node node = (Node)Activator.CreateInstance(type, body, type.GetCustomAttribute().ID); + T node = (T)Activator.CreateInstance(type, body, type.GetCustomAttribute().ID); var chunks = new ChunkSet { @@ -229,14 +208,14 @@ private static Node Parse(Type type, ILookbackable body, GameBoxReader r) if (reflected && chunkClass.GetCustomAttribute() == null) { - dynamic c; + ISkippableChunk c; var constructor = chunkClass.GetConstructors().First(); var constructorParams = constructor.GetParameters(); if (constructorParams.Length == 0) { - c = constructor.Invoke(new object[0]); - c.Node = (dynamic)node; + c = (ISkippableChunk)constructor.Invoke(new object[0]); + c.Node = node; c.Part = (GameBoxPart)body; c.Stream = new MemoryStream(chunkData, 0, chunkData.Length, false); if (chunkData == null || chunkData.Length == 0) @@ -244,10 +223,10 @@ private static Node Parse(Type type, ILookbackable body, GameBoxReader r) c.OnLoad(); } else if (constructorParams.Length == 2) - c = constructor.Invoke(new object[] { node, chunkData }); + c = (ISkippableChunk)constructor.Invoke(new object[] { node, chunkData }); else throw new ArgumentException($"{type.FullName} has an invalid amount of parameters."); - chunks.Add(c); + chunks.Add((Chunk)c); if (chunkClass.GetCustomAttribute().ProcessSync) c.Discover(); @@ -269,30 +248,30 @@ private static Node Parse(Type type, ILookbackable body, GameBoxReader r) var chunkDataSize = r.ReadInt32(); } - dynamic chunk; + IChunk chunk; var constructor = chunkClass.GetConstructors().First(); var constructorParams = constructor.GetParameters(); if (constructorParams.Length == 0) { - chunk = constructor.Invoke(new object[0]); - chunk.Node = (dynamic)node; + chunk = (IChunk)constructor.Invoke(new object[0]); + chunk.Node = node; chunk.Part = (GameBoxPart)body; chunk.OnLoad(); } else if (constructorParams.Length == 1) { - chunk = constructor.Invoke(new object[] { node }); + chunk = (IChunk)constructor.Invoke(new object[] { node }); chunk.Part = (GameBoxPart)body; chunk.OnLoad(); } else throw new ArgumentException($"{type.FullName} has an invalid amount of parameters."); - chunks.Add(chunk); + chunks.Add((Chunk)chunk); var posBefore = r.BaseStream.Position; GameBoxReaderWriter gbxrw = new GameBoxReaderWriter(r); - chunk.ReadWrite((dynamic)node, gbxrw); + chunk.ReadWrite(node, gbxrw); chunk.Progress = (int)(r.BaseStream.Position - posBefore); } From 332d4ea84106ab7bdd37e32434138137d61e0afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Tue, 15 Sep 2020 23:24:46 +0200 Subject: [PATCH 14/27] Update README.md links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ac046db5b..3d6bb7c5a 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ ![GBX.NET](logo.png) [![Nuget](https://img.shields.io/nuget/v/GBX.NET?style=for-the-badge)](https://www.nuget.org/packages/GBX.NET/) -[![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/BigBang1112/gbx-net?include_prereleases&style=for-the-badge)](https://github.com/BigBang1112/gbx-net/releases/latest) +[![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/BigBang1112/gbx-net?include_prereleases&style=for-the-badge)](https://github.com/BigBang1112/gbx-net/releases) [![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/BigBang1112/gbx-net?style=for-the-badge)](#) -[![GitHub](https://img.shields.io/github/license/BigBang1112/gbx-net?style=for-the-badge)](#) +[![GitHub](https://img.shields.io/github/license/BigBang1112/gbx-net?style=for-the-badge)](https://github.com/BigBang1112/gbx-net/blob/master/LICENSE) GBX.NET is a GameBox (.Gbx) file parser library written in C# for .NET software framework. This file type can be in many of the Nadeo games - TrackMania, ShootMania, Virtual Skipper... From d320ddca53da944176a7ce970c49f229fdfe060d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Wed, 16 Sep 2020 09:17:11 +0200 Subject: [PATCH 15/27] More to CGameCtnReplayRecord --- GBX.NET/Engines/Game/CGameCtnReplayRecord.cs | 23 ++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs index ab60aac3d..4e16b1cdb 100644 --- a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs +++ b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs @@ -1,4 +1,5 @@ using GBX.NET.Engines.TrackMania; +using GBX.NET.Engines.Plug; using System; using System.Collections.Generic; using System.IO; @@ -20,7 +21,8 @@ public class CGameCtnReplayRecord : Node public CGameCtnGhost[] Ghosts { get; set; } public long[] Extras { get; set; } - public CGameCtnMediaClip Clip { get; set; } + public CGameCtnMediaClip Clip { get; set; } + public CPlugEntRecordData RecordData { get; set; } public CGameCtnReplayRecord(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) { @@ -234,6 +236,20 @@ public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter #endregion + #region 0x010 chunk + + [Chunk(0x03093010)] + [IgnoreChunk] + public class Chunk03093010 : Chunk + { + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + { + + } + } + + #endregion + #region 0x011 chunk [Chunk(0x03093011)] @@ -284,17 +300,16 @@ public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter #region 0x024 chunk [Chunk(0x03093024)] - public class Chunk024 : Chunk + public class Chunk03093024 : Chunk { public int Unknown1 { get; set; } public int Unknown2 { get; set; } - public Node Unknown3 { get; set; } public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) { Unknown1 = r.ReadInt32(); Unknown2 = r.ReadInt32(); - Unknown3 = r.ReadNodeRef(); + n.RecordData = r.ReadNodeRef(); } } From 8ae9bbd51052707c92e91e8acc6e295eca940c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Wed, 16 Sep 2020 09:17:28 +0200 Subject: [PATCH 16/27] ReadToEnd --- GBX.NET/GameBoxReader.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/GBX.NET/GameBoxReader.cs b/GBX.NET/GameBoxReader.cs index c35144015..907be65a0 100644 --- a/GBX.NET/GameBoxReader.cs +++ b/GBX.NET/GameBoxReader.cs @@ -255,6 +255,11 @@ public byte[] ReadTillFacade() return ReadTill(0xFACADE01); } + public byte[] ReadToEnd() + { + return ReadBytes((int)(BaseStream.Length - BaseStream.Position)); + } + public uint PeekUInt32() { var result = ReadUInt32(); From 688a86b0d665748c33b3f1b4a0d7027bcbce1138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Wed, 16 Sep 2020 09:18:37 +0200 Subject: [PATCH 17/27] Rewrite of header parameter parsing --- GBX.NET/GameBox.cs | 364 +++++++++++++++-------------- GBX.NET/GameBoxBody.cs | 3 +- GBX.NET/GameBoxHeader.cs | 42 ++-- GBX.NET/GameBoxHeaderParameters.cs | 47 ++-- 4 files changed, 233 insertions(+), 223 deletions(-) diff --git a/GBX.NET/GameBox.cs b/GBX.NET/GameBox.cs index dcf6edfef..39f64e7ea 100644 --- a/GBX.NET/GameBox.cs +++ b/GBX.NET/GameBox.cs @@ -7,18 +7,9 @@ namespace GBX.NET { - public class GameBox : GameBox, IDisposable where T : Node + public class GameBox : GameBox where T : Node { - public override short Version => Header.Result.Parameters.Version; - public override char? ByteFormat => Header.Result.Parameters.ByteFormat; - public override char? RefTableCompression => Header.Result.Parameters.RefTableCompression; - public override char? BodyCompression => Header.Result.Parameters.BodyCompression; - public override char? UnknownByte => Header.Result.Parameters.UnknownByte; - public override uint? ClassID => Header.Result.Parameters.ClassID; - public override int? NumNodes => Header.Result.Parameters.NumNodes; - public new Task> Header { get; private set; } - public GameBoxRefTable RefTable { get; private set; } public GameBoxBody Body { get; private set; } public T MainNode { get; internal set; } @@ -30,7 +21,7 @@ public GameBox() public TChunk CreateHeaderChunk() where TChunk : HeaderChunk { - return (TChunk)Header.Result.Chunks.Create(); + return Header.Result.Chunks.Create(); } public void RemoveAllHeaderChunks() @@ -70,129 +61,66 @@ public void DiscoverAllChunks() foreach (var chunk in MainNode.Chunks) if(chunk is ISkippableChunk s) s.Discover(); + } + + public override bool ReadHeader(GameBoxReader reader) + { + var parameters = new GameBoxHeaderParameters(this); + if (!parameters.Read(reader)) return false; // Should already throw an exception + + Log.Write("Working out the header chunks in the background..."); + + Header = Task.Run(() => new GameBoxHeader(this, parameters.UserData)); + Header.ContinueWith(x => + { + if (x.Exception == null) + Log.Write("Header chunks parsed without any exceptions.", ConsoleColor.Green); + else + Log.Write("Header chunks parsed with exceptions.", ConsoleColor.Red); + }); + + return true; } - public override bool Read(Stream stream, bool withoutBody) + public override bool Read(GameBoxReader reader) { - using (var gbxr = new GameBoxReader(stream)) - { - - // Header - - Log.Write("Reading the header..."); - - var parameters = new GameBoxHeaderParameters(); - if (!parameters.Read(gbxr)) return false; - - Log.Write("Working out the header chunks in the background..."); - - Header = Task.Run(() => new GameBoxHeader(this, parameters)); - Header.ContinueWith(x => - { - if (x.Exception == null) - Log.Write("Header chunks parsed without any exceptions.", ConsoleColor.Green); - else - Log.Write("Header chunks parsed with exceptions.", ConsoleColor.Red); - }); - - // Reference table - - Log.Write("Reading the reference table..."); - - var numExternalNodes = gbxr.ReadInt32(); - - if (numExternalNodes > 0) - { - var ancestorLevel = gbxr.ReadInt32(); - - GameBoxRefTableFolder rootFolder = new GameBoxRefTableFolder("Root"); - - var numSubFolders = gbxr.ReadInt32(); - ReadRefTableFolders(numSubFolders, ref rootFolder); - - void ReadRefTableFolders(int n, ref GameBoxRefTableFolder folder) - { - for (var i = 0; i < n; i++) - { - var name = gbxr.ReadString(); - var numSubSubFolders = gbxr.ReadInt32(); - - var f = new GameBoxRefTableFolder(name, folder); - folder.Folders.Add(f); + // Header - ReadRefTableFolders(numSubSubFolders, ref f); - } - } - - var externalNodes = new ExternalNode[numExternalNodes]; - - for (var i = 0; i < numExternalNodes; i++) - { - string fileName = null; - int? resourceIndex = null; - bool? useFile = null; - int? folderIndex = null; - - var flags = gbxr.ReadInt32(); - - if ((flags & 4) == 0) - fileName = gbxr.ReadString(); - else - resourceIndex = gbxr.ReadInt32(); - - var nodeIndex = gbxr.ReadInt32(); - - if (parameters.Version >= 5) - useFile = gbxr.ReadBoolean(); - - if ((flags & 4) == 0) - folderIndex = gbxr.ReadInt32(); - - var extNode = new ExternalNode(flags, fileName, resourceIndex, nodeIndex, useFile, folderIndex); - externalNodes[i] = extNode; - } + Log.Write("Reading the header..."); - var refTable = new GameBoxRefTable(rootFolder, externalNodes); - RefTable = refTable; - } - else - { - Log.Write("No external nodes found, reference table completed.", ConsoleColor.Green); - } + if (!ReadHeader(reader)) + return false; - // Body + // Reference table + + Log.Write("Reading the reference table..."); - if (!withoutBody) - { - Log.Write("Reading the body..."); + ReadRefTable(reader); - switch (parameters.BodyCompression) - { - case 'C': - var uncompressedSize = gbxr.ReadInt32(); - var compressedSize = gbxr.ReadInt32(); - - var data = gbxr.ReadBytes(compressedSize); - - Body = GameBoxBody.DecompressAndConstruct(this, parameters.ClassID.GetValueOrDefault(), data, compressedSize, uncompressedSize); - break; - case 'U': - var uncompressedData = gbxr.ReadBytes((int)(stream.Length - stream.Position)); - Body = new GameBoxBody(this, parameters.ClassID.GetValueOrDefault(), uncompressedData, null, uncompressedData.Length); - break; - default: - Task.WaitAll(Header); - return false; - } + // Body - Log.Write("Body completed!"); + Log.Write("Reading the body..."); - Task.WaitAll(Header); - } - else - Task.WaitAll(Header); + switch (BodyCompression) + { + case 'C': + var uncompressedSize = reader.ReadInt32(); + var compressedSize = reader.ReadInt32(); + + var data = reader.ReadBytes(compressedSize); + + Body = GameBoxBody.DecompressAndConstruct(this, ClassID.GetValueOrDefault(), data, compressedSize, uncompressedSize); + break; + case 'U': + var uncompressedData = reader.ReadToEnd(); + Body = new GameBoxBody(this, ClassID.GetValueOrDefault(), uncompressedData, null, uncompressedData.Length); + break; + default: + return false; } + Log.Write("Body completed!"); + return true; } @@ -234,57 +162,117 @@ public void Save(string fileName) { Save(fileName, ClassIDRemap.Latest); } - - public void Dispose() - { - Header = null; - RefTable = null; - Body = null; - } } public class GameBox : IGameBox { - public ClassIDRemap Game { get; set; } - - public virtual short Version => Header.Result.Parameters.Version; - public virtual char? ByteFormat => Header.Result.Parameters.ByteFormat; - public virtual char? RefTableCompression => Header.Result.Parameters.RefTableCompression; - public virtual char? BodyCompression => Header.Result.Parameters.BodyCompression; - public virtual char? UnknownByte => Header.Result.Parameters.UnknownByte; - public virtual uint? ClassID => Header.Result.Parameters.ClassID; - public virtual int? NumNodes => Header.Result.Parameters.NumNodes; + public ClassIDRemap Game { get; set; } + + public short Version { get; set; } + public char? ByteFormat { get; set; } + public char? RefTableCompression { get; set; } + public char? BodyCompression { get; set; } + public char? UnknownByte { get; set; } + public uint? ClassID { get; internal set; } + public int? NumNodes { get; internal set; } public Task Header { get; private set; } + public GameBoxRefTable RefTable { get; private set; } public string FileName { get; set; } - public virtual bool Read(Stream stream, bool withoutBody) + public virtual bool ReadHeader(GameBoxReader reader) + { + var parameters = new GameBoxHeaderParameters(this); + if (!parameters.Read(reader)) return false; + + Log.Write("Working out the header chunks in the background..."); + + Header = Task.Run(() => new GameBoxHeader(this, parameters.UserData)); + Header.ContinueWith(x => + { + if (x.Exception == null) + Log.Write("Header chunks parsed without any exceptions."); + else + Log.Write("Header chunks parsed with exceptions."); + }); + + return true; + } + + public bool ReadRefTable(GameBoxReader reader) { - using (var gbxr = new GameBoxReader(stream)) + var numExternalNodes = reader.ReadInt32(); + + if (numExternalNodes > 0) { + var ancestorLevel = reader.ReadInt32(); + + GameBoxRefTableFolder rootFolder = new GameBoxRefTableFolder("Root"); + + var numSubFolders = reader.ReadInt32(); + ReadRefTableFolders(numSubFolders, ref rootFolder); - var parameters = new GameBoxHeaderParameters(); - if (!parameters.Read(gbxr)) return false; + void ReadRefTableFolders(int n, ref GameBoxRefTableFolder folder) + { + for (var i = 0; i < n; i++) + { + var name = reader.ReadString(); + var numSubSubFolders = reader.ReadInt32(); + + var f = new GameBoxRefTableFolder(name, folder); + folder.Folders.Add(f); + + ReadRefTableFolders(numSubSubFolders, ref f); + } + } - Log.Write("Working out the header chunks in the background..."); + var externalNodes = new ExternalNode[numExternalNodes]; - Header = Task.Run(() => new GameBoxHeader(this, parameters)); - Header.ContinueWith(x => + for (var i = 0; i < numExternalNodes; i++) { - if (x.Exception == null) - Log.Write("Header chunks parsed without any exceptions."); + string fileName = null; + int? resourceIndex = null; + bool? useFile = null; + int? folderIndex = null; + + var flags = reader.ReadInt32(); + + if ((flags & 4) == 0) + fileName = reader.ReadString(); else - Log.Write("Header chunks parsed with exceptions."); - }); + resourceIndex = reader.ReadInt32(); + + var nodeIndex = reader.ReadInt32(); + + if (Version >= 5) + useFile = reader.ReadBoolean(); + + if ((flags & 4) == 0) + folderIndex = reader.ReadInt32(); + + var extNode = new ExternalNode(flags, fileName, resourceIndex, nodeIndex, useFile, folderIndex); + externalNodes[i] = extNode; + } + + var refTable = new GameBoxRefTable(rootFolder, externalNodes); + RefTable = refTable; } + else + Log.Write("No external nodes found, reference table completed.", ConsoleColor.Green); + + return true; + } - return true; + public virtual bool Read(GameBoxReader reader) + { + return ReadHeader(reader) && ReadRefTable(reader); } public bool Read(Stream stream) { - return Read(stream, false); + using (GameBoxReader reader = new GameBoxReader(stream)) + return Read(reader); } [Obsolete] @@ -329,26 +317,57 @@ public static GameBox Parse(string fileName) where T : Node return gbx; } + public static uint? ReadClassID(GameBoxReader reader) + { + uint? classID = null; + + reader.ReadString("GBX".Length); + + var version = reader.ReadInt16(); // Version + + if (version >= 3) + { + reader.ReadByte(); + reader.ReadByte(); + reader.ReadByte(); + + if (version >= 4) + reader.ReadByte(); + + classID = reader.ReadUInt32(); + } + + return classID; + } + + public static uint? ReadClassID(Stream stream) + { + using (GameBoxReader r = new GameBoxReader(stream)) + return ReadClassID(r); + } + + public static uint? ReadClassID(string fileName) + { + using (var fs = File.OpenRead(fileName)) + return ReadClassID(fs); + } + public static GameBox Parse(string fileName) { using (var fs = File.OpenRead(fileName)) - { - var r = new GameBoxReader(fs); - - var parameters = new GameBoxHeaderParameters(); - parameters.Read(r); - - if (parameters.Version >= 3) + using (var r = new GameBoxReader(fs)) + { + var classID = ReadClassID(r); + + if (classID.HasValue) { - var modernID = parameters.ClassID.GetValueOrDefault(); - if (Node.Mappings.TryGetValue(parameters.ClassID.GetValueOrDefault(), out uint newerClassID)) + var modernID = classID.GetValueOrDefault(); + if (Node.Mappings.TryGetValue(classID.GetValueOrDefault(), out uint newerClassID)) modernID = newerClassID; Debug.WriteLine("Parse: " + modernID.ToString("x8")); - var availableClass = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass - && x.Namespace.StartsWith("GBX.NET.Engines") && GetBaseType(x) == typeof(Node) - && x.GetCustomAttribute().ID == modernID).FirstOrDefault(); + Node.AvailableClasses.TryGetValue(modernID, out Type availableClass); GameBox gbx; @@ -378,17 +397,20 @@ Type GetBaseType(Type t) return null; } - public static Type GetGameBoxType(Stream stream) - { - var gbxr = new GameBoxReader(stream); + public static Type GetGameBoxType(Stream stream) + { + using (var r = new GameBoxReader(stream)) + return GetGameBoxType(r); + } - var parameters = new GameBoxHeaderParameters(); - parameters.Read(gbxr); + public static Type GetGameBoxType(GameBoxReader reader) + { + var classID = ReadClassID(reader); - if (parameters.Version >= 3) + if (classID.HasValue) { - var modernID = parameters.ClassID.GetValueOrDefault(); - if (Node.Mappings.TryGetValue(parameters.ClassID.GetValueOrDefault(), out uint newerClassID)) + var modernID = classID.GetValueOrDefault(); + if (Node.Mappings.TryGetValue(classID.GetValueOrDefault(), out uint newerClassID)) modernID = newerClassID; Debug.WriteLine("GetGameBoxType: " + modernID.ToString("x8")); diff --git a/GBX.NET/GameBoxBody.cs b/GBX.NET/GameBoxBody.cs index cdf079612..ea79f88cb 100644 --- a/GBX.NET/GameBoxBody.cs +++ b/GBX.NET/GameBoxBody.cs @@ -53,12 +53,11 @@ public void Write(GameBoxWriter w) public void Write(GameBoxWriter w, ClassIDRemap remap) { - if(GBX.Header.Result.BodyCompression == 'C') + if(GBX.BodyCompression == 'C') { using (var msBody = new MemoryStream()) using (var gbxwBody = new GameBoxWriter(msBody, this)) { - GBX.MainNode.Write(gbxwBody, remap); MiniLZO.Compress(msBody.ToArray(), out byte[] output); diff --git a/GBX.NET/GameBoxHeader.cs b/GBX.NET/GameBoxHeader.cs index 91c84cbac..eb9596d2d 100644 --- a/GBX.NET/GameBoxHeader.cs +++ b/GBX.NET/GameBoxHeader.cs @@ -16,11 +16,11 @@ public class GameBoxHeader : GameBoxHeader, ILookbackable where T : Node public ChunkSet Chunks { get; set; } - public GameBoxHeader(GameBox gbx, GameBoxHeaderParameters parameters) : base(gbx, parameters) + public GameBoxHeader(GameBox gbx, byte[] userData) : base(gbx, userData) { - if (parameters.Version >= 3) + if (gbx.Version >= 3) { - var classID = parameters.ClassID.GetValueOrDefault(); + var classID = gbx.ClassID.GetValueOrDefault(); var modernID = classID; if (Node.Mappings.TryGetValue(classID, out uint newerClassID)) @@ -30,9 +30,9 @@ public GameBoxHeader(GameBox gbx, GameBoxHeaderParameters parameters) : base( && x.Namespace.StartsWith("GBX.NET.Engines") && GetBaseType(x) == typeof(Node) && x.GetCustomAttribute().ID == modernID).FirstOrDefault(); - if (parameters.Version == 6) + if (gbx.Version == 6) { - if (parameters.UserData != null && parameters.UserData.Length > 0) + if (userData != null && userData.Length > 0) { var headerChunkBaseType = typeof(HeaderChunk<>).MakeGenericType(availableClass); @@ -71,7 +71,7 @@ List GetInheritance(Type t) availableChunkClasses[chunkType.Key + cls] = chunkType.Value; } - using (var ms = new MemoryStream(parameters.UserData)) + using (var ms = new MemoryStream(userData)) using (var r = new GameBoxReader(ms, this)) { var numHeaderChunks = r.ReadInt32(); @@ -161,17 +161,17 @@ Type GetBaseType(Type t) public void Write(GameBoxWriter w, int numNodes, ClassIDRemap remap) { w.Write("GBX", StringLengthPrefix.None); - w.Write(Version); + w.Write(GBX.Version); - if (Version >= 3) + if (GBX.Version >= 3) { - w.Write((byte)ByteFormat.GetValueOrDefault()); - w.Write((byte)RefTableCompression.GetValueOrDefault()); - w.Write((byte)BodyCompression.GetValueOrDefault()); - if (Version >= 4) w.Write((byte)UnknownByte.GetValueOrDefault()); - w.Write(ClassID.GetValueOrDefault()); + w.Write((byte)GBX.ByteFormat.GetValueOrDefault()); + w.Write((byte)GBX.RefTableCompression.GetValueOrDefault()); + w.Write((byte)GBX.BodyCompression.GetValueOrDefault()); + if (GBX.Version >= 4) w.Write((byte)GBX.UnknownByte.GetValueOrDefault()); + w.Write(GBX.ClassID.GetValueOrDefault()); - if (Version >= 6) + if (GBX.Version >= 6) { using (var userData = new MemoryStream()) using (var gbxw = new GameBoxWriter(userData, this)) @@ -381,19 +381,9 @@ public class GameBoxHeader : GameBoxPart, ILookbackable List ILookbackable.LookbackStrings { get; set; } = new List(); bool ILookbackable.LookbackWritten { get; set; } - public GameBoxHeaderParameters Parameters { get; } - - public short Version => Parameters.Version; - public char? ByteFormat => Parameters.ByteFormat; - public char? RefTableCompression => Parameters.RefTableCompression; - public char? BodyCompression => Parameters.BodyCompression; - public char? UnknownByte => Parameters.UnknownByte; - public uint? ClassID => Parameters.ClassID; - public int? NumNodes => Parameters.NumNodes; - - public GameBoxHeader(GameBox gbx, GameBoxHeaderParameters parameters) : base(gbx) + public GameBoxHeader(GameBox gbx, byte[] userData) : base(gbx) { - Parameters = parameters; + } public override T CreateChunk(byte[] data) diff --git a/GBX.NET/GameBoxHeaderParameters.cs b/GBX.NET/GameBoxHeaderParameters.cs index 0d38c1aa4..9963b2fe5 100644 --- a/GBX.NET/GameBoxHeaderParameters.cs +++ b/GBX.NET/GameBoxHeaderParameters.cs @@ -7,14 +7,13 @@ namespace GBX.NET { public class GameBoxHeaderParameters { - public short Version { get; set; } - public char? ByteFormat { get; set; } - public char? RefTableCompression { get; set; } - public char? BodyCompression { get; set; } - public char? UnknownByte { get; set; } - public uint? ClassID { get; set; } + public GameBox GBX { get; } public byte[] UserData { get; set; } - public int? NumNodes { get; set; } + + public GameBoxHeaderParameters(GameBox gbx) + { + GBX = gbx; + } public bool Read(GameBoxReader r) { @@ -26,30 +25,30 @@ public bool Read(GameBoxReader r) return false; } - Version = r.ReadInt16(); - Log.Write($"- Version: {Version}"); + GBX.Version = r.ReadInt16(); + Log.Write($"- Version: {GBX.Version}"); - if (Version >= 3) + if (GBX.Version >= 3) { - ByteFormat = (char)r.ReadByte(); - Log.Write($"- Byte format: {ByteFormat}"); + GBX.ByteFormat = (char)r.ReadByte(); + Log.Write($"- Byte format: {GBX.ByteFormat}"); - RefTableCompression = (char)r.ReadByte(); - Log.Write($"- Ref. table compression: {RefTableCompression}"); + GBX.RefTableCompression = (char)r.ReadByte(); + Log.Write($"- Ref. table compression: {GBX.RefTableCompression}"); - BodyCompression = (char)r.ReadByte(); - Log.Write($"- Body compression: {RefTableCompression}"); + GBX.BodyCompression = (char)r.ReadByte(); + Log.Write($"- Body compression: {GBX.RefTableCompression}"); - if (Version >= 4) + if (GBX.Version >= 4) { - UnknownByte = (char)r.ReadByte(); - Log.Write($"- Unknown byte: {UnknownByte}"); + GBX.UnknownByte = (char)r.ReadByte(); + Log.Write($"- Unknown byte: {GBX.UnknownByte}"); } - ClassID = r.ReadUInt32(); - Log.Write($"- Class ID: 0x{ClassID:x8}"); + GBX.ClassID = r.ReadUInt32(); + Log.Write($"- Class ID: 0x{GBX.ClassID:x8}"); - if (Version >= 6) + if (GBX.Version >= 6) { var userDataSize = r.ReadInt32(); Log.Write($"- User data size: {userDataSize/1024f} kB"); @@ -58,8 +57,8 @@ public bool Read(GameBoxReader r) UserData = r.ReadBytes(userDataSize); } - NumNodes = r.ReadInt32(); - Log.Write($"- Number of nodes: {NumNodes}"); + GBX.NumNodes = r.ReadInt32(); + Log.Write($"- Number of nodes: {GBX.NumNodes}"); } Log.Write("Header completed!", ConsoleColor.Green); From 01a92c4a72396e79894003ac71ea8fbfbab49aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Thu, 17 Sep 2020 16:05:05 +0200 Subject: [PATCH 18/27] ReadArrayTillFacade, ReadStringTillFacade --- GBX.NET/GameBoxReader.cs | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/GBX.NET/GameBoxReader.cs b/GBX.NET/GameBoxReader.cs index 907be65a0..807532e6d 100644 --- a/GBX.NET/GameBoxReader.cs +++ b/GBX.NET/GameBoxReader.cs @@ -260,6 +260,50 @@ public byte[] ReadToEnd() return ReadBytes((int)(BaseStream.Length - BaseStream.Position)); } + public string ReadStringTillFacade() + { + return Encoding.UTF8.GetString(ReadTillFacade()); + } + + public T[] ReadArrayTillFacade() + { + var bytes = ReadTillFacade(); + + var array = new T[(int)Math.Ceiling(bytes.Length / (float)Marshal.SizeOf(default(T)))]; + Buffer.BlockCopy(bytes, 0, array, 0, bytes.Length); + + return array; + } + + public (T1[], T2[]) ReadArrayTillFacade() + { + var bytes = ReadTillFacade(); + + var array = new T1[(int)Math.Ceiling(bytes.Length / (float)Marshal.SizeOf(default(T1)))]; + Buffer.BlockCopy(bytes, 0, array, 0, bytes.Length); + + var array2 = new T2[(int)Math.Ceiling(bytes.Length / (float)Marshal.SizeOf(default(T2)))]; + Buffer.BlockCopy(bytes, 0, array2, 0, bytes.Length); + + return (array, array2); + } + + public (T1[], T2[], T3[]) ReadArrayTillFacade() + { + var bytes = ReadTillFacade(); + + var array = new T1[(int)Math.Ceiling(bytes.Length / (float)Marshal.SizeOf(default(T1)))]; + Buffer.BlockCopy(bytes, 0, array, 0, bytes.Length); + + var array2 = new T2[(int)Math.Ceiling(bytes.Length / (float)Marshal.SizeOf(default(T2)))]; + Buffer.BlockCopy(bytes, 0, array2, 0, bytes.Length); + + var array3 = new T3[(int)Math.Ceiling(bytes.Length / (float)Marshal.SizeOf(default(T3)))]; + Buffer.BlockCopy(bytes, 0, array3, 0, bytes.Length); + + return (array, array2, array3); + } + public uint PeekUInt32() { var result = ReadUInt32(); From f6220d5922d0c543135586ccb052b476b7e555c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Thu, 17 Sep 2020 16:05:43 +0200 Subject: [PATCH 19/27] CCtnMediaBlockEventTrackMania --- GBX.NET/Engines/Game/CGameCtnReplayRecord.cs | 635 +++++++++--------- .../CCtnMediaBlockEventTrackMania.cs | 105 ++- 2 files changed, 420 insertions(+), 320 deletions(-) diff --git a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs index 4e16b1cdb..7598e1d12 100644 --- a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs +++ b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs @@ -1,320 +1,321 @@ -using GBX.NET.Engines.TrackMania; -using GBX.NET.Engines.Plug; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading.Tasks; - -namespace GBX.NET.Engines.Game -{ - [Node(0x03093000)] - public class CGameCtnReplayRecord : Node - { - public Task> Track { get; set; } - - public int? AuthorVersion { get; set; } - public string AuthorLogin { get; set; } - public string AuthorNickname { get; set; } - public string AuthorZone { get; set; } - public string AuthorExtraInfo { get; set; } - - public CGameCtnGhost[] Ghosts { get; set; } - public long[] Extras { get; set; } +using GBX.NET.Engines.TrackMania; +using GBX.NET.Engines.Plug; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading.Tasks; + +namespace GBX.NET.Engines.Game +{ + [Node(0x03093000)] + public class CGameCtnReplayRecord : Node + { + public Task> Track { get; set; } + + public int? AuthorVersion { get; set; } + public string AuthorLogin { get; set; } + public string AuthorNickname { get; set; } + public string AuthorZone { get; set; } + public string AuthorExtraInfo { get; set; } + + public CGameCtnGhost[] Ghosts { get; set; } + public long[] Extras { get; set; } public CGameCtnMediaClip Clip { get; set; } - public CPlugEntRecordData RecordData { get; set; } - - public CGameCtnReplayRecord(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - - #region Chunks - - #region 0x000 chunk (basic) - - [Chunk(0x03093000, "basic")] - public class Chunk03093000 : HeaderChunk - { - public int Version { get; set; } - public Meta MapInfo { get; set; } - public TimeSpan Time { get; set; } - public string Nickname { get; set; } - public string DriverLogin { get; set; } - public byte Unknown1 { get; set; } - public string TitleUID { get; set; } - - public override void Read(GameBoxReader r, GameBoxWriter unknownW) - { - Version = r.ReadInt32(); - - if(Version >= 2) - { - MapInfo = r.ReadMeta(); - Time = TimeSpan.FromMilliseconds(r.ReadInt32()); - Nickname = r.ReadString(); - - if (Version >= 6) - { - DriverLogin = r.ReadString(); - - if (Version >= 8) - { - Unknown1 = r.ReadByte(); - TitleUID = r.ReadLookbackString(); - } - } - } - } - } - - #endregion - - #region 0x001 chunk (xml) - - [Chunk(0x03093001, "xml")] - public class Chunk03093001 : HeaderChunk - { - public string XML { get; set; } - - public override void Read(GameBoxReader r, GameBoxWriter unknownW) - { - XML = r.ReadString(); - } - } - - #endregion - - #region 0x002 chunk (author) - - [Chunk(0x03093002, "author")] - public class Chunk03093002H : HeaderChunk - { - public int Version { get; set; } - public int AuthorVersion { get; set; } - public string AuthorLogin { get; set; } - public string AuthorNickname { get; set; } - public string AuthorZone { get; set; } - public string AuthorExtraInfo { get; set; } - - public override void Read(GameBoxReader r, GameBoxWriter unknownW) - { - Version = r.ReadInt32(); - AuthorVersion = r.ReadInt32(); - AuthorLogin = r.ReadString(); - AuthorNickname = r.ReadString(); - AuthorZone = r.ReadString(); - AuthorExtraInfo = r.ReadString(); - } - } - - #endregion - - #region 0x002 chunk (track) - - [Chunk(0x03093002, "track")] - public class Chunk03093002B : Chunk - { - public int Version { get; set; } - - public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) - { - var size = r.ReadInt32(); - - if (size > 0) - { - var trackGbx = r.ReadBytes(size); - - n.Track = Task.Run(() => - { - using (var ms = new MemoryStream(trackGbx)) - { - var gbx = new GameBox(); - gbx.Read(ms); - return gbx; - } - }); - } - } - } - - #endregion - - #region 0x003 chunk - - [Chunk(0x03093003)] - public class Chunk03093003 : Chunk - { - public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) - { - var gsdgs = r.ReadArray(2); - var controlNames = r.ReadArray(i => - { - r.ReadInt32(); - r.ReadInt32(); - return r.ReadString(); - }); - - var numControlEntries = r.ReadInt32() - 1; - var controlEntries = new (int, int, int)[numControlEntries]; - - for (var i = 0; i < numControlEntries; i++) - controlEntries[i] = (r.ReadInt32(), r.ReadInt32(), r.ReadInt32()); - - r.ReadInt32(); - } - } - - #endregion - - #region 0x004 chunk - - [Chunk(0x03093004)] - public class Chunk03093004 : Chunk - { - public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) - { - r.ReadInt32(); - r.ReadInt32(); - - n.Ghosts = r.ReadArray(i => r.ReadNodeRef()); - - r.ReadInt32(); - r.ReadInt32(); - } - } - - #endregion - - #region 0x00C chunk - - [Chunk(0x0309300C)] - public class Chunk0309300C : Chunk - { - public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) - { - r.ReadNodeRef(); - } - } - - #endregion - - #region 0x00D chunk - - [Chunk(0x0309300D)] - public class Chunk0309300D : Chunk - { - public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) - { - r.ReadInt32(); - r.ReadInt32(); - - var controlNames = r.ReadArray(i => r.ReadLookbackString()); - - var num = r.ReadInt32(); - r.ReadInt32(); - - var array = new (int time, int index, byte enabled)[num]; - - for(var i = 0; i < num; i++) - array[i] = (r.ReadInt32(), r.ReadInt32(), r.ReadByte()); - } - } - - #endregion - - #region 0x00E chunk - - [Chunk(0x0309300E)] - public class Chunk0309300E : Chunk - { - public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) - { - var mediaBlockEvent = r.ReadNodeRef(); - } - } - - #endregion - - #region 0x010 chunk - - [Chunk(0x03093010)] - [IgnoreChunk] - public class Chunk03093010 : Chunk - { - public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + public CPlugEntRecordData RecordData { get; set; } + public CCtnMediaBlockEventTrackMania Events { get; set; } + + public CGameCtnReplayRecord(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) + { + + } + + #region Chunks + + #region 0x000 chunk (basic) + + [Chunk(0x03093000, "basic")] + public class Chunk03093000 : HeaderChunk + { + public int Version { get; set; } + public Meta MapInfo { get; set; } + public TimeSpan Time { get; set; } + public string Nickname { get; set; } + public string DriverLogin { get; set; } + public byte Unknown1 { get; set; } + public string TitleUID { get; set; } + + public override void Read(GameBoxReader r, GameBoxWriter unknownW) + { + Version = r.ReadInt32(); + + if(Version >= 2) + { + MapInfo = r.ReadMeta(); + Time = TimeSpan.FromMilliseconds(r.ReadInt32()); + Nickname = r.ReadString(); + + if (Version >= 6) + { + DriverLogin = r.ReadString(); + + if (Version >= 8) + { + Unknown1 = r.ReadByte(); + TitleUID = r.ReadLookbackString(); + } + } + } + } + } + + #endregion + + #region 0x001 chunk (xml) + + [Chunk(0x03093001, "xml")] + public class Chunk03093001 : HeaderChunk + { + public string XML { get; set; } + + public override void Read(GameBoxReader r, GameBoxWriter unknownW) + { + XML = r.ReadString(); + } + } + + #endregion + + #region 0x002 chunk (author) + + [Chunk(0x03093002, "author")] + public class Chunk03093002H : HeaderChunk + { + public int Version { get; set; } + public int AuthorVersion { get; set; } + public string AuthorLogin { get; set; } + public string AuthorNickname { get; set; } + public string AuthorZone { get; set; } + public string AuthorExtraInfo { get; set; } + + public override void Read(GameBoxReader r, GameBoxWriter unknownW) + { + Version = r.ReadInt32(); + AuthorVersion = r.ReadInt32(); + AuthorLogin = r.ReadString(); + AuthorNickname = r.ReadString(); + AuthorZone = r.ReadString(); + AuthorExtraInfo = r.ReadString(); + } + } + + #endregion + + #region 0x002 chunk (track) + + [Chunk(0x03093002, "track")] + public class Chunk03093002B : Chunk + { + public int Version { get; set; } + + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + { + var size = r.ReadInt32(); + + if (size > 0) + { + var trackGbx = r.ReadBytes(size); + + n.Track = Task.Run(() => + { + using (var ms = new MemoryStream(trackGbx)) + { + var gbx = new GameBox(); + gbx.Read(ms); + return gbx; + } + }); + } + } + } + + #endregion + + #region 0x003 chunk + + [Chunk(0x03093003)] + public class Chunk03093003 : Chunk + { + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + { + var gsdgs = r.ReadArray(2); + var controlNames = r.ReadArray(i => + { + r.ReadInt32(); + r.ReadInt32(); + return r.ReadString(); + }); + + var numControlEntries = r.ReadInt32() - 1; + var controlEntries = new (int, int, int)[numControlEntries]; + + for (var i = 0; i < numControlEntries; i++) + controlEntries[i] = (r.ReadInt32(), r.ReadInt32(), r.ReadInt32()); + + r.ReadInt32(); + } + } + + #endregion + + #region 0x004 chunk + + [Chunk(0x03093004)] + public class Chunk03093004 : Chunk + { + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + { + r.ReadInt32(); + r.ReadInt32(); + + n.Ghosts = r.ReadArray(i => r.ReadNodeRef()); + + r.ReadInt32(); + r.ReadInt32(); + } + } + + #endregion + + #region 0x00C chunk + + [Chunk(0x0309300C)] + public class Chunk0309300C : Chunk + { + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + { + r.ReadNodeRef(); + } + } + + #endregion + + #region 0x00D chunk + + [Chunk(0x0309300D)] + public class Chunk0309300D : Chunk + { + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + { + r.ReadInt32(); + r.ReadInt32(); + + var controlNames = r.ReadArray(i => r.ReadLookbackString()); + + var num = r.ReadInt32(); + r.ReadInt32(); + + var array = new (int time, int index, byte enabled)[num]; + + for(var i = 0; i < num; i++) + array[i] = (r.ReadInt32(), r.ReadInt32(), r.ReadByte()); + } + } + + #endregion + + #region 0x00E chunk + + [Chunk(0x0309300E)] + public class Chunk0309300E : Chunk + { + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + { + n.Events = r.ReadNodeRef(); + } + } + + #endregion + + #region 0x010 chunk + + [Chunk(0x03093010)] + [IgnoreChunk] + public class Chunk03093010 : Chunk + { + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + { + + } + } + + #endregion + + #region 0x011 chunk + + [Chunk(0x03093011)] + public class Chunk03093011 : Chunk + { + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) { - } - } - - #endregion - - #region 0x011 chunk - - [Chunk(0x03093011)] - public class Chunk03093011 : Chunk - { - public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) - { - - } - } - - #endregion - - // 0x013 skippable chunk - - #region 0x014 chunk - - [Chunk(0x03093014)] - public class Chunk03093014 : Chunk - { - public int Version { get; set; } - public int Unknown1 { get; set; } - - public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) - { - Version = r.ReadInt32(); - n.Ghosts = r.ReadArray(i => r.ReadNodeRef()); - Unknown1 = r.ReadInt32(); - n.Extras = r.ReadArray(i => r.ReadInt64()); - } - } - - #endregion - - #region 0x015 chunk - - [Chunk(0x03093015)] - public class Chunk03093015 : Chunk - { - public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) - { - n.Clip = r.ReadNodeRef(); - } - } - - #endregion - - #region 0x024 chunk - - [Chunk(0x03093024)] - public class Chunk03093024 : Chunk - { - public int Unknown1 { get; set; } - public int Unknown2 { get; set; } - - public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) - { - Unknown1 = r.ReadInt32(); - Unknown2 = r.ReadInt32(); - n.RecordData = r.ReadNodeRef(); - } - } - - #endregion - - #endregion - } -} + } + } + + #endregion + + // 0x013 skippable chunk + + #region 0x014 chunk + + [Chunk(0x03093014)] + public class Chunk03093014 : Chunk + { + public int Version { get; set; } + public int Unknown1 { get; set; } + + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + { + Version = r.ReadInt32(); + n.Ghosts = r.ReadArray(i => r.ReadNodeRef()); + Unknown1 = r.ReadInt32(); + n.Extras = r.ReadArray(i => r.ReadInt64()); + } + } + + #endregion + + #region 0x015 chunk + + [Chunk(0x03093015)] + public class Chunk03093015 : Chunk + { + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + { + n.Clip = r.ReadNodeRef(); + } + } + + #endregion + + #region 0x024 chunk + + [Chunk(0x03093024)] + public class Chunk03093024 : Chunk + { + public int Unknown1 { get; set; } + public int Unknown2 { get; set; } + + public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) + { + Unknown1 = r.ReadInt32(); + Unknown2 = r.ReadInt32(); + n.RecordData = r.ReadNodeRef(); + } + } + + #endregion + + #endregion + } +} diff --git a/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs b/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs index c6ad8b680..57edf7671 100644 --- a/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs +++ b/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs @@ -8,6 +8,52 @@ namespace GBX.NET.Engines.TrackMania [Node(0x2407F000)] public class CCtnMediaBlockEventTrackMania : CGameCtnMediaBlock { + public enum EStuntFigure + { + None, + StraightJump, + Flip, + BackFlip, + Spin, + Aerial, + AlleyOop, + Roll, + Corkscrew, + SpinOff, + Rodeo, + FlipFlap, + Twister, + FreeStyle, + SpinningMix, + FlippingChaos, + RollingMadness, + WreckNone, + WreckStraightJump, + WreckFlip, + WreckBackFlip, + WreckSpin, + WreckAerial, + WreckAlleyOop, + WreckRoll, + WreckCorkscrew, + WreckSpinOff, + WreckRodeo, + WreckFlipFlap, + WreckTwister, + WreckFreeStyle, + WreckSpinningMix, + WreckFlippingChaos, + WreckRollingMadness, + TimePenalty, + RespawnPenalty, + Grind, + Reset + } + + public float Start { get; set; } + public float End { get; set; } + public Stunt[] Stunts { get; set; } + public CCtnMediaBlockEventTrackMania(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) { @@ -16,9 +62,42 @@ public CCtnMediaBlockEventTrackMania(ILookbackable lookbackable, uint classID) : [Chunk(0x2407F000)] public class Chunk2407F000 : Chunk { - public override void Read(CCtnMediaBlockEventTrackMania n, GameBoxReader r, GameBoxWriter unknownW) - { - r.ReadTillFacade(); + public int U01 { get; set; } + + public override void ReadWrite(CCtnMediaBlockEventTrackMania n, GameBoxReaderWriter rw) + { + n.Start = rw.Single(n.Start); + n.End = rw.Single(n.End); + U01 = rw.Int32(U01); + + n.Stunts = rw.Array(n.Stunts, i => new Stunt() + { + Time = rw.Reader.ReadSingle(), + Figure = (EStuntFigure)rw.Reader.ReadInt32(), + Angle = rw.Reader.ReadInt32(), + Score = rw.Reader.ReadInt32(), + Factor = rw.Reader.ReadSingle(), + U01 = rw.Reader.ReadInt32(), + U02 = rw.Reader.ReadInt32(), + U03 = rw.Reader.ReadInt32(), + U04 = rw.Reader.ReadInt32(), + Combo = rw.Reader.ReadInt32(), + TotalScore = rw.Reader.ReadInt32() + }, + x => + { + rw.Writer.Write(x.Time); + rw.Writer.Write((int)x.Figure); + rw.Writer.Write(x.Angle); + rw.Writer.Write(x.Score); + rw.Writer.Write(x.Factor); + rw.Writer.Write(x.U01); + rw.Writer.Write(x.U02); + rw.Writer.Write(x.U03); + rw.Writer.Write(x.U04); + rw.Writer.Write(x.Combo); + rw.Writer.Write(x.TotalScore); + }); } } @@ -30,5 +109,25 @@ public override void Read(CCtnMediaBlockEventTrackMania n, GameBoxReader r, Game r.ReadTillFacade(); } } + + public class Stunt + { + public float Time { get; set; } + public EStuntFigure Figure { get; set; } + public int Angle { get; set; } + public int Score { get; set; } + public float Factor { get; set; } + public int U01 { get; set; } + public int U02 { get; set; } + public int U03 { get; set; } + public int U04 { get; set; } + public int Combo { get; set; } + public int TotalScore { get; set; } + + public override string ToString() + { + return $"[{Time}] {Figure} {Angle}° (+{Score} = {TotalScore})"; + } + } } } From e498fde4a097e9f2e23e4118dcf01c81d61542cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Thu, 17 Sep 2020 17:43:49 +0200 Subject: [PATCH 20/27] Straight stunt + fix unfinished TMS replays --- GBX.NET/Engines/Game/CGameCtnReplayRecord.cs | 19 ++-- .../CCtnMediaBlockEventTrackMania.cs | 91 ++++++++++--------- 2 files changed, 57 insertions(+), 53 deletions(-) diff --git a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs index 7598e1d12..a16e2b3aa 100644 --- a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs +++ b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs @@ -207,18 +207,21 @@ public class Chunk0309300D : Chunk { public override void Read(CGameCtnReplayRecord n, GameBoxReader r, GameBoxWriter unknownW) { - r.ReadInt32(); - r.ReadInt32(); + var unknown = r.ReadInt32(); + if (unknown != 0) + { + r.ReadInt32(); - var controlNames = r.ReadArray(i => r.ReadLookbackString()); + var controlNames = r.ReadArray(i => r.ReadLookbackString()); - var num = r.ReadInt32(); - r.ReadInt32(); + var num = r.ReadInt32(); + r.ReadInt32(); - var array = new (int time, int index, byte enabled)[num]; + var array = new (int time, int index, byte enabled)[num]; - for(var i = 0; i < num; i++) - array[i] = (r.ReadInt32(), r.ReadInt32(), r.ReadByte()); + for (var i = 0; i < num; i++) + array[i] = (r.ReadInt32(), r.ReadInt32(), r.ReadByte()); + } } } diff --git a/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs b/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs index 57edf7671..02619d2b9 100644 --- a/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs +++ b/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs @@ -1,13 +1,13 @@ -using GBX.NET.Engines.Game; -using System; -using System.Collections.Generic; -using System.Text; - -namespace GBX.NET.Engines.TrackMania -{ - [Node(0x2407F000)] - public class CCtnMediaBlockEventTrackMania : CGameCtnMediaBlock - { +using GBX.NET.Engines.Game; +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBX.NET.Engines.TrackMania +{ + [Node(0x2407F000)] + public class CCtnMediaBlockEventTrackMania : CGameCtnMediaBlock + { public enum EStuntFigure { None, @@ -48,22 +48,22 @@ public enum EStuntFigure RespawnPenalty, Grind, Reset - } - - public float Start { get; set; } - public float End { get; set; } - public Stunt[] Stunts { get; set; } - - public CCtnMediaBlockEventTrackMania(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - - [Chunk(0x2407F000)] - public class Chunk2407F000 : Chunk - { - public int U01 { get; set; } - + } + + public float Start { get; set; } + public float End { get; set; } + public Stunt[] Stunts { get; set; } + + public CCtnMediaBlockEventTrackMania(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) + { + + } + + [Chunk(0x2407F000)] + public class Chunk2407F000 : Chunk + { + public int U01 { get; set; } + public override void ReadWrite(CCtnMediaBlockEventTrackMania n, GameBoxReaderWriter rw) { n.Start = rw.Single(n.Start); @@ -77,7 +77,7 @@ public override void ReadWrite(CCtnMediaBlockEventTrackMania n, GameBoxReaderWri Angle = rw.Reader.ReadInt32(), Score = rw.Reader.ReadInt32(), Factor = rw.Reader.ReadSingle(), - U01 = rw.Reader.ReadInt32(), + Straight = rw.Reader.ReadBoolean(), U02 = rw.Reader.ReadInt32(), U03 = rw.Reader.ReadInt32(), U04 = rw.Reader.ReadInt32(), @@ -91,25 +91,25 @@ public override void ReadWrite(CCtnMediaBlockEventTrackMania n, GameBoxReaderWri rw.Writer.Write(x.Angle); rw.Writer.Write(x.Score); rw.Writer.Write(x.Factor); - rw.Writer.Write(x.U01); + rw.Writer.Write(x.Straight); rw.Writer.Write(x.U02); rw.Writer.Write(x.U03); rw.Writer.Write(x.U04); rw.Writer.Write(x.Combo); rw.Writer.Write(x.TotalScore); }); - } - } - - [Chunk(0x2407F003)] - public class Chunk2407F003 : Chunk - { - public override void Read(CCtnMediaBlockEventTrackMania n, GameBoxReader r, GameBoxWriter unknownW) - { - r.ReadTillFacade(); - } - } - + } + } + + [Chunk(0x2407F003)] + public class Chunk2407F003 : Chunk + { + public override void Read(CCtnMediaBlockEventTrackMania n, GameBoxReader r, GameBoxWriter unknownW) + { + r.ReadTillFacade(); + } + } + public class Stunt { public float Time { get; set; } @@ -117,7 +117,7 @@ public class Stunt public int Angle { get; set; } public int Score { get; set; } public float Factor { get; set; } - public int U01 { get; set; } + public bool Straight { get; set; } public int U02 { get; set; } public int U03 { get; set; } public int U04 { get; set; } @@ -126,8 +126,9 @@ public class Stunt public override string ToString() { - return $"[{Time}] {Figure} {Angle}° (+{Score} = {TotalScore})"; + return $"[{Time}] {(Combo > 1 ? Combo + "x " : "")}{(Combo > 0 ? "Chained " : "")}{Figure} " + + $"{(Angle > 0 ? Angle + "° " : "")}({(Figure == EStuntFigure.TimePenalty ? "-" : "+")}{Score} = {TotalScore})"; } - } - } -} + } + } +} From c94b539241a0317693c040b787d52fe9b6bb1ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sat, 19 Sep 2020 12:49:07 +0200 Subject: [PATCH 21/27] Make Node constructor parameterless --- GBX.NET/Engines/Control/CControlEffectSimi.cs | 5 - .../Engines/Game/CGameCtnAnchoredObject.cs | 15 - GBX.NET/Engines/Game/CGameCtnBlock.cs | 82 ++-- GBX.NET/Engines/Game/CGameCtnBlockSkin.cs | 15 - GBX.NET/Engines/Game/CGameCtnCampaign.cs | 287 ++++++------ GBX.NET/Engines/Game/CGameCtnChallenge.cs | 21 +- .../Engines/Game/CGameCtnChallengeGroup.cs | 149 +++--- .../Game/CGameCtnChallengeParameters.cs | 439 +++++++++--------- GBX.NET/Engines/Game/CGameCtnCollection.cs | 5 - GBX.NET/Engines/Game/CGameCtnCollectorList.cs | 93 ++-- GBX.NET/Engines/Game/CGameCtnDecoration.cs | 287 ++++++------ GBX.NET/Engines/Game/CGameCtnGhost.cs | 5 - .../Engines/Game/CGameCtnMacroBlockInfo.cs | 5 - GBX.NET/Engines/Game/CGameCtnMediaBlock.cs | 19 +- .../Game/CGameCtnMediaBlock3dStereo.cs | 85 ++-- .../Game/CGameCtnMediaBlockBloomHdr.cs | 91 ++-- .../Engines/Game/CGameCtnMediaBlockCamera.cs | 5 +- .../Game/CGameCtnMediaBlockCameraCustom.cs | 5 - .../Game/CGameCtnMediaBlockCameraEffect.cs | 19 +- .../CGameCtnMediaBlockCameraEffectShake.cs | 89 ++-- .../Game/CGameCtnMediaBlockCameraGame.cs | 5 - .../Game/CGameCtnMediaBlockCameraPath.cs | 5 - .../Game/CGameCtnMediaBlockColorGrading.cs | 101 ++-- .../Game/CGameCtnMediaBlockColoringBase.cs | 107 ++--- .../CGameCtnMediaBlockColoringCapturable.cs | 99 ++-- GBX.NET/Engines/Game/CGameCtnMediaBlockDOF.cs | 5 - .../Game/CGameCtnMediaBlockDirtyLens.cs | 5 - GBX.NET/Engines/Game/CGameCtnMediaBlockFog.cs | 5 - GBX.NET/Engines/Game/CGameCtnMediaBlockFx.cs | 5 +- .../Engines/Game/CGameCtnMediaBlockFxBlur.cs | 5 +- .../Game/CGameCtnMediaBlockFxBlurDepth.cs | 5 - .../Game/CGameCtnMediaBlockFxBlurMotion.cs | 5 - .../Game/CGameCtnMediaBlockFxCameraBlend.cs | 5 - .../Game/CGameCtnMediaBlockFxCameraMap.cs | 5 - .../Game/CGameCtnMediaBlockFxColors.cs | 5 - .../Engines/Game/CGameCtnMediaBlockGhost.cs | 5 - .../Engines/Game/CGameCtnMediaBlockImage.cs | 5 - .../Game/CGameCtnMediaBlockInterface.cs | 5 - .../Game/CGameCtnMediaBlockManialink.cs | 5 - .../Game/CGameCtnMediaBlockMusicEffect.cs | 5 - .../Engines/Game/CGameCtnMediaBlockShoot.cs | 5 - .../Engines/Game/CGameCtnMediaBlockSound.cs | 5 - .../Engines/Game/CGameCtnMediaBlockText.cs | 5 - .../Engines/Game/CGameCtnMediaBlockTime.cs | 5 - .../Game/CGameCtnMediaBlockToneMapping.cs | 5 - .../Engines/Game/CGameCtnMediaBlockTrails.cs | 5 - .../Game/CGameCtnMediaBlockTransitionFade.cs | 5 - .../Game/CGameCtnMediaBlockTriangles.cs | 5 +- .../Game/CGameCtnMediaBlockTriangles2D.cs | 5 +- .../Game/CGameCtnMediaBlockVehicleLight.cs | 5 - GBX.NET/Engines/Game/CGameCtnMediaClip.cs | 10 - .../Engines/Game/CGameCtnMediaClipGroup.cs | 5 - GBX.NET/Engines/Game/CGameCtnMediaTrack.cs | 10 - GBX.NET/Engines/Game/CGameCtnReplayRecord.cs | 5 - GBX.NET/Engines/Game/CGameCtnZoneGenealogy.cs | 5 - GBX.NET/Engines/Game/CGameGhost.cs | 5 - GBX.NET/Engines/Game/CGamePlayerProfile.cs | 5 - GBX.NET/Engines/GameData/CGameBlockItem.cs | 5 - .../Engines/GameData/CGameCtnAutoTerrain.cs | 5 - GBX.NET/Engines/GameData/CGameCtnCollector.cs | 5 - GBX.NET/Engines/GameData/CGameItemModel.cs | 5 - .../GameData/CGameItemPlacementParam.cs | 5 +- .../GameData/CGameWaypointSpecialProperty.cs | 5 - GBX.NET/Engines/Hms/CHmsLightMapCache.cs | 5 - GBX.NET/Engines/MwFoundations/CMwNod.cs | 5 - GBX.NET/Engines/Plug/CPlug.cs | 5 +- GBX.NET/Engines/Plug/CPlugCrystal.cs | 5 - GBX.NET/Engines/Plug/CPlugEntRecordData.cs | 5 - GBX.NET/Engines/Plug/CPlugMaterialUserInst.cs | 5 - GBX.NET/Engines/Plug/CPlugTreeGenerator.cs | 5 - .../CCtnMediaBlockEventTrackMania.cs | 5 - GBX.NET/GameBoxReader.cs | 2 + GBX.NET/Node.cs | 43 +- GBX.NET/SkippableChunk.cs | 2 + 74 files changed, 966 insertions(+), 1359 deletions(-) diff --git a/GBX.NET/Engines/Control/CControlEffectSimi.cs b/GBX.NET/Engines/Control/CControlEffectSimi.cs index 0a9e3ee5d..2724ead0d 100644 --- a/GBX.NET/Engines/Control/CControlEffectSimi.cs +++ b/GBX.NET/Engines/Control/CControlEffectSimi.cs @@ -5,11 +5,6 @@ public class CControlEffectSimi : Node { public Key[] Keys { get; set; } - public CControlEffectSimi(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x07010004)] public class Chunk004 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs b/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs index 6f37b9532..3762c4f4d 100644 --- a/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs +++ b/GBX.NET/Engines/Game/CGameCtnAnchoredObject.cs @@ -33,21 +33,6 @@ public int Variant set => Flags = (short)((Flags & 0xF0FF) | ((value & 15) << 8)); } - public CGameCtnAnchoredObject(ILookbackable lookbackable) : base(lookbackable) - { - - } - - public CGameCtnAnchoredObject(ILookbackable lookbackable, uint classId) : base(lookbackable, classId) - { - - } - - public CGameCtnAnchoredObject(Chunk chunk) : base(chunk) - { - - } - public override string ToString() { return ItemModel.ToString(); diff --git a/GBX.NET/Engines/Game/CGameCtnBlock.cs b/GBX.NET/Engines/Game/CGameCtnBlock.cs index 6b063258d..66ab894b4 100644 --- a/GBX.NET/Engines/Game/CGameCtnBlock.cs +++ b/GBX.NET/Engines/Game/CGameCtnBlock.cs @@ -1,60 +1,50 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// Block on a map (0x03057000) - /// - /// A block placed on a map. - [Node(0x03057000)] - public class CGameCtnBlock : Node - { - public Meta BlockInfo { get; set; } - - public Direction? Direction { get; set; } - - public Byte3? Coord { get; set; } - - public int? Flags { get; set; } - - public CGameCtnBlock(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - - public CGameCtnBlock(ILookbackable lookbackable) : base(lookbackable, 0x03057000) - { - - } - - public override string ToString() - { - return $"{BlockInfo?.ID} {Coord}"; + /// + /// A block placed on a map. + [Node(0x03057000)] + public class CGameCtnBlock : Node + { + public Meta BlockInfo { get; set; } + + public Direction? Direction { get; set; } + + public Byte3? Coord { get; set; } + + public int? Flags { get; set; } + + public override string ToString() + { + return $"{BlockInfo?.ID} {Coord}"; } - #region Chunks + #region Chunks #region 0x002 chunk /// /// CGameCtnBlock 0x002 chunk /// - [Chunk(0x03057002)] - public class Chunk03057002 : Chunk - { - public override void ReadWrite(CGameCtnBlock n, GameBoxReaderWriter rw) - { - n.BlockInfo = rw.Meta(n.BlockInfo); - n.Direction = (Direction)rw.Byte((byte)n.Direction.GetValueOrDefault()); - n.Coord = rw.Byte3(n.Coord.GetValueOrDefault()); - n.Flags = rw.Int32(n.Flags.GetValueOrDefault()); - } + [Chunk(0x03057002)] + public class Chunk03057002 : Chunk + { + public override void ReadWrite(CGameCtnBlock n, GameBoxReaderWriter rw) + { + n.BlockInfo = rw.Meta(n.BlockInfo); + n.Direction = (Direction)rw.Byte((byte)n.Direction.GetValueOrDefault()); + n.Coord = rw.Byte3(n.Coord.GetValueOrDefault()); + n.Flags = rw.Int32(n.Flags.GetValueOrDefault()); + } } #endregion - #endregion - } -} + #endregion + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnBlockSkin.cs b/GBX.NET/Engines/Game/CGameCtnBlockSkin.cs index 2f5790f22..bd7ef122a 100644 --- a/GBX.NET/Engines/Game/CGameCtnBlockSkin.cs +++ b/GBX.NET/Engines/Game/CGameCtnBlockSkin.cs @@ -19,21 +19,6 @@ public class CGameCtnBlockSkin : Node public FileRef SecondaryPackDesc { get; set; } - public CGameCtnBlockSkin(ILookbackable lookbackable) : this(lookbackable, 0x03059000) - { - - } - - public CGameCtnBlockSkin(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - - public CGameCtnBlockSkin(Chunk chunk) : base(chunk) - { - - } - #region Chunks #region 0x000 chunk diff --git a/GBX.NET/Engines/Game/CGameCtnCampaign.cs b/GBX.NET/Engines/Game/CGameCtnCampaign.cs index d9ef3f841..da692bff9 100644 --- a/GBX.NET/Engines/Game/CGameCtnCampaign.cs +++ b/GBX.NET/Engines/Game/CGameCtnCampaign.cs @@ -1,173 +1,168 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// Campaign info (0x03090000) - /// - /// Information about a campaign. - [Node(0x03090000)] - public class CGameCtnCampaign : Node - { - public CGameCtnChallengeGroup[] MapGroups { get; set; } - - public string CampaignID { get; set; } - - public int Index { get; set; } - - public string Name { get; set; } - public int Type { get; set; } - public int UnlockType { get; set; } - - public CGameCtnCampaign(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - - #region Chunks - - #region 0x000 chunk (map groups) - + /// + /// Information about a campaign. + [Node(0x03090000)] + public class CGameCtnCampaign : Node + { + public CGameCtnChallengeGroup[] MapGroups { get; set; } + + public string CampaignID { get; set; } + + public int Index { get; set; } + + public string Name { get; set; } + public int Type { get; set; } + public int UnlockType { get; set; } + + #region Chunks + + #region 0x000 chunk (map groups) + /// /// CGameCtnCampaign 0x000 chunk (map groups) - /// - [Chunk(0x03090000, "map groups")] - public class Chunk03090000 : Chunk - { - public int Version { get; set; } - - public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) - { - Version = rw.Int32(Version); - n.MapGroups = rw.Array(n.MapGroups, - i => rw.Reader.ReadNodeRef(), - x => rw.Writer.Write(x)); - } - } - - #endregion - - #region 0x006 chunk (campaign ID) - + /// + [Chunk(0x03090000, "map groups")] + public class Chunk03090000 : Chunk + { + public int Version { get; set; } + + public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) + { + Version = rw.Int32(Version); + n.MapGroups = rw.Array(n.MapGroups, + i => rw.Reader.ReadNodeRef(), + x => rw.Writer.Write(x)); + } + } + + #endregion + + #region 0x006 chunk (campaign ID) + /// /// CGameCtnCampaign 0x006 chunk (campaign ID) - /// - [Chunk(0x03090006, "campaign ID")] - public class Chunk03090006 : Chunk - { - public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) - { - n.CampaignID = rw.LookbackString(n.CampaignID); - } - } - - #endregion - - #region 0x009 skippable chunk - + /// + [Chunk(0x03090006, "campaign ID")] + public class Chunk03090006 : Chunk + { + public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) + { + n.CampaignID = rw.LookbackString(n.CampaignID); + } + } + + #endregion + + #region 0x009 skippable chunk + /// /// CGameCtnCampaign 0x009 skippable chunk - /// - [Chunk(0x03090009)] - public class Chunk03090009 : SkippableChunk - { - public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) - { - rw.Byte(Unknown); - rw.Int32(Unknown); - } - } - - #endregion - - #region 0x00A skippable chunk (index) - + /// + [Chunk(0x03090009)] + public class Chunk03090009 : SkippableChunk + { + public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) + { + rw.Byte(Unknown); + rw.Int32(Unknown); + } + } + + #endregion + + #region 0x00A skippable chunk (index) + /// /// CGameCtnCampaign 0x00A skippable chunk (index) - /// - [Chunk(0x0309000A, "index")] - public class Chunk0309000A : SkippableChunk - { - public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) - { - n.Index = rw.Int32(n.Index); - } - } - - #endregion - - #region 0x00D chunk - + /// + [Chunk(0x0309000A, "index")] + public class Chunk0309000A : SkippableChunk + { + public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) + { + n.Index = rw.Int32(n.Index); + } + } + + #endregion + + #region 0x00D chunk + /// /// CGameCtnCampaign 0x00D chunk - /// - [Chunk(0x0309000D)] - public class Chunk0309000D : Chunk - { - public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - } + /// + [Chunk(0x0309000D)] + public class Chunk0309000D : Chunk + { + public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + } } - #endregion + #endregion - #region 0x00E chunk + #region 0x00E chunk /// /// CGameCtnCampaign 0x00E chunk - /// - [Chunk(0x0309000E)] - public class Chunk0309000E : Chunk - { - public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - } + /// + [Chunk(0x0309000E)] + public class Chunk0309000E : Chunk + { + public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + } } - #endregion + #endregion - #region 0x00F skippable chunk (name) + #region 0x00F skippable chunk (name) /// /// CGameCtnCampaign 0x00F skippable chunk (name) - /// - [Chunk(0x0309000F, "name")] - public class Chunk0309000F : SkippableChunk - { - public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) - { - n.Name = rw.String(n.Name); - n.Type = rw.Int32(n.Type); - n.UnlockType = rw.Int32(n.UnlockType); - } - } - - #endregion - - #region 0x010 chunk - + /// + [Chunk(0x0309000F, "name")] + public class Chunk0309000F : SkippableChunk + { + public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) + { + n.Name = rw.String(n.Name); + n.Type = rw.Int32(n.Type); + n.UnlockType = rw.Int32(n.UnlockType); + } + } + + #endregion + + #region 0x010 chunk + /// /// CGameCtnCampaign 0x010 chunk - /// - [Chunk(0x03090010)] - public class Chunk03090010 : Chunk - { - public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - rw.Int32(Unknown); - } - } - - #endregion - - #endregion - } -} + /// + [Chunk(0x03090010)] + public class Chunk03090010 : Chunk + { + public override void ReadWrite(CGameCtnCampaign n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + rw.Int32(Unknown); + } + } + + #endregion + + #endregion + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnChallenge.cs b/GBX.NET/Engines/Game/CGameCtnChallenge.cs index ef06d37d8..3c268041c 100644 --- a/GBX.NET/Engines/Game/CGameCtnChallenge.cs +++ b/GBX.NET/Engines/Game/CGameCtnChallenge.cs @@ -537,25 +537,6 @@ public string ObjectiveTextBronze #endregion - /// - /// Creates a new instance with the latest node ID of 0x03043000. - /// - /// The parent of the node, usually or . - public CGameCtnChallenge(ILookbackable lookbackable) : this(lookbackable, 0x03043000) - { - - } - - /// - /// Creates a new instance with a specified node ID used for compatibility. - /// - /// The parent of the node, usually or . - /// Whole ID of the node. - public CGameCtnChallenge(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Methods /// @@ -584,7 +565,7 @@ public void PlaceItem(Meta itemModel, Vec3 absolutePosition, Vec3 pitchYawRoll, { var chunkItems = CreateChunk(); - var it = new CGameCtnAnchoredObject((Chunk)chunkItems) + var it = new CGameCtnAnchoredObject() { ItemModel = itemModel, AbsolutePositionInMap = absolutePosition, diff --git a/GBX.NET/Engines/Game/CGameCtnChallengeGroup.cs b/GBX.NET/Engines/Game/CGameCtnChallengeGroup.cs index 1ebc24337..4d30c9d4f 100644 --- a/GBX.NET/Engines/Game/CGameCtnChallengeGroup.cs +++ b/GBX.NET/Engines/Game/CGameCtnChallengeGroup.cs @@ -1,83 +1,78 @@ -using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// Group of maps (0x0308F000) - /// - [Node(0x0308F000)] - public class CGameCtnChallengeGroup : Node - { - public string Default { get; set; } - public MapInfo[] MapInfos { get; set; } - - public CGameCtnChallengeGroup(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - - #region Chunks - - #region 0x002 chunk (default) - + /// + [Node(0x0308F000)] + public class CGameCtnChallengeGroup : Node + { + public string Default { get; set; } + public MapInfo[] MapInfos { get; set; } + + #region Chunks + + #region 0x002 chunk (default) + /// /// CGameCtnChallengeGroup 0x002 chunk (default) - /// - [Chunk(0x0308F002, "default")] - public class Chunk0308F002 : Chunk - { - public override void ReadWrite(CGameCtnChallengeGroup n, GameBoxReaderWriter rw) - { - n.Default = rw.String(n.Default); - } - } - - #endregion - - #region 0x00B chunk (map infos) - + /// + [Chunk(0x0308F002, "default")] + public class Chunk0308F002 : Chunk + { + public override void ReadWrite(CGameCtnChallengeGroup n, GameBoxReaderWriter rw) + { + n.Default = rw.String(n.Default); + } + } + + #endregion + + #region 0x00B chunk (map infos) + /// /// CGameCtnChallengeGroup 0x00B chunk (map infos) - /// - [Chunk(0x0308F00B, "map infos")] - public class Chunk0308F00B : Chunk - { - public int Version { get; set; } - - public override void ReadWrite(CGameCtnChallengeGroup n, GameBoxReaderWriter rw) - { - Version = rw.Int32(Version); - - n.MapInfos = rw.Array(n.MapInfos, i => new MapInfo() - { - Metadata = rw.Reader.ReadMeta(), - FilePath = rw.Reader.ReadString() - }, - x => - { - rw.Writer.Write(x.Metadata); - rw.Writer.Write(x.FilePath); - }); - } - } - - #endregion - - #endregion - - public class MapInfo - { - public Meta Metadata { get; set; } - public string FilePath { get; set; } - - public override string ToString() - { - return Path.GetFileName(FilePath); - } - } - } -} + /// + [Chunk(0x0308F00B, "map infos")] + public class Chunk0308F00B : Chunk + { + public int Version { get; set; } + + public override void ReadWrite(CGameCtnChallengeGroup n, GameBoxReaderWriter rw) + { + Version = rw.Int32(Version); + + n.MapInfos = rw.Array(n.MapInfos, i => new MapInfo() + { + Metadata = rw.Reader.ReadMeta(), + FilePath = rw.Reader.ReadString() + }, + x => + { + rw.Writer.Write(x.Metadata); + rw.Writer.Write(x.FilePath); + }); + } + } + + #endregion + + #endregion + + public class MapInfo + { + public Meta Metadata { get; set; } + public string FilePath { get; set; } + + public override string ToString() + { + return Path.GetFileName(FilePath); + } + } + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnChallengeParameters.cs b/GBX.NET/Engines/Game/CGameCtnChallengeParameters.cs index fd14c6336..6b25ddc40 100644 --- a/GBX.NET/Engines/Game/CGameCtnChallengeParameters.cs +++ b/GBX.NET/Engines/Game/CGameCtnChallengeParameters.cs @@ -1,312 +1,307 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// Map parameters (0x0305B000) - /// - [Node(0x0305B000)] - public class CGameCtnChallengeParameters : Node + /// + [Node(0x0305B000)] + public class CGameCtnChallengeParameters : Node { - #region Properties - - /// - /// Time of the bronze medal. - /// - public TimeSpan? BronzeTime { get; set; } - - /// - /// Time of the silver medal. - /// - public TimeSpan? SilverTime { get; set; } - - /// - /// Time of the gold medal. - /// - public TimeSpan? GoldTime { get; set; } - - /// - /// Time of the author medal. - /// - public TimeSpan? AuthorTime { get; set; } - - /// - /// Usually author time or stunt score. - /// - public int? AuthorScore { get; set; } - - /// - /// Stunt time limit. - /// - public TimeSpan? TimeLimit { get; set; } - - public string MapType { get; set; } - - public string MapStyle { get; set; } - - public string[] Tips { get; } = new string[4]; + #region Properties - #endregion + /// + /// Time of the bronze medal. + /// + public TimeSpan? BronzeTime { get; set; } - public CGameCtnChallengeParameters(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + /// + /// Time of the silver medal. + /// + public TimeSpan? SilverTime { get; set; } - #region Chunks + /// + /// Time of the gold medal. + /// + public TimeSpan? GoldTime { get; set; } - #region 0x000 chunk + /// + /// Time of the author medal. + /// + public TimeSpan? AuthorTime { get; set; } + + /// + /// Usually author time or stunt score. + /// + public int? AuthorScore { get; set; } + + /// + /// Stunt time limit. + /// + public TimeSpan? TimeLimit { get; set; } + + public string MapType { get; set; } + + public string MapStyle { get; set; } + + public string[] Tips { get; } = new string[4]; + + #endregion + + #region Chunks + + #region 0x000 chunk /// /// CGameCtnChallengeParameters 0x000 chunk /// - [Chunk(0x0305B000)] - public class Chunk0305B000 : Chunk - { - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - - rw.Int32(Unknown); - } + [Chunk(0x0305B000)] + public class Chunk0305B000 : Chunk + { + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + + rw.Int32(Unknown); + } } - #endregion + #endregion - #region 0x001 chunk (tips) + #region 0x001 chunk (tips) /// /// CGameCtnChallengeParameters 0x001 chunk (tips) /// - [Chunk(0x0305B001, "tips")] - public class Chunk0305B001 : Chunk - { - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - for(var i = 0; i < 4; i++) - n.Tips[i] = rw.String(n.Tips[i]); - } + [Chunk(0x0305B001, "tips")] + public class Chunk0305B001 : Chunk + { + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + for(var i = 0; i < 4; i++) + n.Tips[i] = rw.String(n.Tips[i]); + } } #endregion - #region 0x002 chunk + #region 0x002 chunk /// /// CGameCtnChallengeParameters 0x002 chunk - /// - [Chunk(0x0305B002)] - public class Chunk0305B002 : Chunk - { - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - - rw.Single(Unknown); - rw.Single(Unknown); - rw.Single(Unknown); - - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - } + /// + [Chunk(0x0305B002)] + public class Chunk0305B002 : Chunk + { + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + + rw.Single(Unknown); + rw.Single(Unknown); + rw.Single(Unknown); + + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + } } - #endregion + #endregion - #region 0x003 chunk + #region 0x003 chunk /// /// CGameCtnChallengeParameters 0x003 chunk /// - [Chunk(0x0305B003)] - public class Chunk0305B003 : Chunk - { - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - rw.Single(Unknown); - - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - - rw.Int32(Unknown); - } + [Chunk(0x0305B003)] + public class Chunk0305B003 : Chunk + { + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + rw.Single(Unknown); + + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + + rw.Int32(Unknown); + } } - #endregion + #endregion - #region 0x004 chunk (medals) + #region 0x004 chunk (medals) /// /// CGameCtnChallengeParameters 0x004 chunk (medals) /// - [Chunk(0x0305B004, "medals")] - public class Chunk0305B004 : Chunk - { - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - n.BronzeTime = rw.TimeSpan32(n.BronzeTime); - n.SilverTime = rw.TimeSpan32(n.SilverTime); - n.GoldTime = rw.TimeSpan32(n.GoldTime); - n.AuthorTime = rw.TimeSpan32(n.AuthorTime); - - rw.UInt32(Unknown); - } + [Chunk(0x0305B004, "medals")] + public class Chunk0305B004 : Chunk + { + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + n.BronzeTime = rw.TimeSpan32(n.BronzeTime); + n.SilverTime = rw.TimeSpan32(n.SilverTime); + n.GoldTime = rw.TimeSpan32(n.GoldTime); + n.AuthorTime = rw.TimeSpan32(n.AuthorTime); + + rw.UInt32(Unknown); + } } #endregion - #region 0x005 chunk + #region 0x005 chunk /// /// CGameCtnChallengeParameters 0x005 chunk - /// - [Chunk(0x0305B005)] - public class Chunk0305B005 : Chunk - { - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - } + /// + [Chunk(0x0305B005)] + public class Chunk0305B005 : Chunk + { + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + } } - #endregion + #endregion - #region 0x006 chunk + #region 0x006 chunk /// /// CGameCtnChallengeParameters 0x006 chunk (items) /// - [Chunk(0x0305B006, "items")] - public class Chunk0305B006 : Chunk - { - public uint[] Items { get; set; } - - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - Items = rw.Array(Items, i => rw.Reader.ReadUInt32(), x => rw.Writer.Write(x)); - } + [Chunk(0x0305B006, "items")] + public class Chunk0305B006 : Chunk + { + public uint[] Items { get; set; } + + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + Items = rw.Array(Items, i => rw.Reader.ReadUInt32(), x => rw.Writer.Write(x)); + } } - #endregion + #endregion #region 0x007 chunk /// /// CGameCtnChallengeParameters 0x007 chunk /// - [Chunk(0x0305B007)] - public class Chunk0305B007 : Chunk - { - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - rw.UInt32(Unknown); - } + [Chunk(0x0305B007)] + public class Chunk0305B007 : Chunk + { + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + rw.UInt32(Unknown); + } } - #endregion - - #region 0x008 chunk (stunts) - - /// - /// CGameCtnChallengeParameters 0x008 chunk (stunts) - /// - [Chunk(0x0305B008, "stunts")] - public class Chunk0305B008 : Chunk - { - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - n.TimeLimit = TimeSpan.FromMilliseconds(rw.Int32(Convert.ToInt32(n.TimeLimit?.TotalMilliseconds ?? TimeSpan.FromMinutes(1).TotalMilliseconds))); - n.AuthorScore = rw.Int32(n.AuthorScore.GetValueOrDefault()); - } + #endregion + + #region 0x008 chunk (stunts) + + /// + /// CGameCtnChallengeParameters 0x008 chunk (stunts) + /// + [Chunk(0x0305B008, "stunts")] + public class Chunk0305B008 : Chunk + { + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + n.TimeLimit = TimeSpan.FromMilliseconds(rw.Int32(Convert.ToInt32(n.TimeLimit?.TotalMilliseconds ?? TimeSpan.FromMinutes(1).TotalMilliseconds))); + n.AuthorScore = rw.Int32(n.AuthorScore.GetValueOrDefault()); + } } - #endregion + #endregion #region 0x00A chunk (medals) /// /// CGameCtnChallengeParameters 0x00A chunk (medals) /// - [Chunk(0x0305B00A, "medals")] - public class Chunk0305B00A : SkippableChunk - { - public int Unknown1 { get; set; } - - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - Unknown1 = rw.Int32(Unknown1); - - n.BronzeTime = rw.TimeSpan32(n.BronzeTime); - n.SilverTime = rw.TimeSpan32(n.SilverTime); - n.GoldTime = rw.TimeSpan32(n.GoldTime); - n.AuthorTime = rw.TimeSpan32(n.AuthorTime); - n.TimeLimit = TimeSpan.FromMilliseconds(rw.Int32(Convert.ToInt32(n.TimeLimit?.TotalMilliseconds ?? TimeSpan.FromMinutes(1).TotalMilliseconds))); - n.AuthorScore = rw.Int32(n.AuthorScore.GetValueOrDefault()); - } + [Chunk(0x0305B00A, "medals")] + public class Chunk0305B00A : SkippableChunk + { + public int Unknown1 { get; set; } + + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + Unknown1 = rw.Int32(Unknown1); + + n.BronzeTime = rw.TimeSpan32(n.BronzeTime); + n.SilverTime = rw.TimeSpan32(n.SilverTime); + n.GoldTime = rw.TimeSpan32(n.GoldTime); + n.AuthorTime = rw.TimeSpan32(n.AuthorTime); + n.TimeLimit = TimeSpan.FromMilliseconds(rw.Int32(Convert.ToInt32(n.TimeLimit?.TotalMilliseconds ?? TimeSpan.FromMinutes(1).TotalMilliseconds))); + n.AuthorScore = rw.Int32(n.AuthorScore.GetValueOrDefault()); + } } - #endregion + #endregion - #region 0x00D chunk + #region 0x00D chunk /// /// CGameCtnChallengeParameters 0x00D chunk /// - [Chunk(0x0305B00D)] - public class Chunk0305B00D : Chunk - { - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - } + [Chunk(0x0305B00D)] + public class Chunk0305B00D : Chunk + { + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + } } - #endregion + #endregion #region 0x00E skippable chunk (map type) /// /// CGameCtnChallengeParameters 0x00E skippable chunk (map type) /// - [Chunk(0x0305B00E, "map type")] - public class Chunk0305B00E : SkippableChunk - { - public int Unknown1 { get; set; } - - public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) - { - n.MapType = rw.String(n.MapType); - n.MapStyle = rw.String(n.MapStyle); - Unknown1 = rw.Int32(Unknown1); - } + [Chunk(0x0305B00E, "map type")] + public class Chunk0305B00E : SkippableChunk + { + public int Unknown1 { get; set; } + + public override void ReadWrite(CGameCtnChallengeParameters n, GameBoxReaderWriter rw) + { + n.MapType = rw.String(n.MapType); + n.MapStyle = rw.String(n.MapStyle); + Unknown1 = rw.Int32(Unknown1); + } } #endregion - #endregion - } -} + #endregion + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnCollection.cs b/GBX.NET/Engines/Game/CGameCtnCollection.cs index 6e6392726..9ee59ac25 100644 --- a/GBX.NET/Engines/Game/CGameCtnCollection.cs +++ b/GBX.NET/Engines/Game/CGameCtnCollection.cs @@ -14,11 +14,6 @@ public class CGameCtnCollection : CMwNod public Meta Vehicle { get; set; } public string LoadingScreen { get; set; } - public CGameCtnCollection(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x001 chunk diff --git a/GBX.NET/Engines/Game/CGameCtnCollectorList.cs b/GBX.NET/Engines/Game/CGameCtnCollectorList.cs index 0e498a835..dccc20048 100644 --- a/GBX.NET/Engines/Game/CGameCtnCollectorList.cs +++ b/GBX.NET/Engines/Game/CGameCtnCollectorList.cs @@ -1,53 +1,48 @@ -namespace GBX.NET.Engines.Game -{ +namespace GBX.NET.Engines.Game +{ /// /// Puzzle piece list (0x0301B000) - /// - /// A list of puzzle pieces. - [Node(0x0301B000)] - public class CGameCtnCollectorList : Node - { - public Collector[] CollectorStock { get; set; } - - public CGameCtnCollectorList(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - - #region Chunks - - #region 0x000 chunk - + /// + /// A list of puzzle pieces. + [Node(0x0301B000)] + public class CGameCtnCollectorList : Node + { + public Collector[] CollectorStock { get; set; } + + #region Chunks + + #region 0x000 chunk + /// /// CGameCtnCollectorList 0x000 chunk - /// - [Chunk(0x0301B000)] - public class Chunk0301B000 : Chunk - { - public override void ReadWrite(CGameCtnCollectorList n, GameBoxReaderWriter rw) - { - n.CollectorStock = rw.Array(n.CollectorStock, - i => new Collector() - { - Meta = rw.Reader.ReadMeta(), - Count = rw.Reader.ReadInt32() - }, - x => - { - rw.Writer.Write(x.Meta); - rw.Writer.Write(x.Count); - }); - } - } - - #endregion - - #endregion - - public class Collector - { - public Meta Meta { get; set; } - public int Count { get; set; } - } - } -} + /// + [Chunk(0x0301B000)] + public class Chunk0301B000 : Chunk + { + public override void ReadWrite(CGameCtnCollectorList n, GameBoxReaderWriter rw) + { + n.CollectorStock = rw.Array(n.CollectorStock, + i => new Collector() + { + Meta = rw.Reader.ReadMeta(), + Count = rw.Reader.ReadInt32() + }, + x => + { + rw.Writer.Write(x.Meta); + rw.Writer.Write(x.Count); + }); + } + } + + #endregion + + #endregion + + public class Collector + { + public Meta Meta { get; set; } + public int Count { get; set; } + } + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnDecoration.cs b/GBX.NET/Engines/Game/CGameCtnDecoration.cs index 004f82542..94f55d2f0 100644 --- a/GBX.NET/Engines/Game/CGameCtnDecoration.cs +++ b/GBX.NET/Engines/Game/CGameCtnDecoration.cs @@ -1,148 +1,143 @@ -using GBX.NET.Engines.GameData; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using GBX.NET.Engines.GameData; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// Decoration of a map (0x03038000) - /// - [Node(0x03038000)] - public class CGameCtnDecoration : CGameCtnCollector - { - public CGameCtnDecoration(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - - #region Chunks - - #region 0x011 chunk - - [Chunk(0x03038011)] - public class Chunk03038011 : Chunk - { - public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - } - } - - #endregion - - #region 0x013 chunk - - [Chunk(0x03038013)] - public class Chunk03038013 : Chunk - { - public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - } - } - - #endregion - - #region 0x014 chunk - - [Chunk(0x03038014)] - public class Chunk03038014 : Chunk - { - public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - } - } - - #endregion - - #region 0x015 chunk - - [Chunk(0x03038015)] - public class Chunk03038015 : Chunk - { - public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - } - } - - #endregion - - #region 0x016 chunk - - [Chunk(0x03038016)] - public class Chunk03038016 : Chunk - { - public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - } - } - - #endregion - - #region 0x017 chunk - - [Chunk(0x03038017)] - public class Chunk03038017 : Chunk - { - public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - } - } - - #endregion - - #region 0x018 chunk - - [Chunk(0x03038018)] - public class Chunk03038018 : Chunk - { - public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - } - } - - #endregion - - #region 0x019 chunk - - [Chunk(0x03038019)] - public class Chunk03038019 : Chunk - { - public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - rw.Int32(Unknown); - rw.Int32(Unknown); - } - } - - #endregion - - #region 0x01A chunk - - [Chunk(0x0303801A)] - public class Chunk0303801A : Chunk - { - public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) - { - rw.Int32(Unknown); - rw.Int32(Unknown); - } - } - - #endregion - - #endregion - } -} + /// + [Node(0x03038000)] + public class CGameCtnDecoration : CGameCtnCollector + { + #region Chunks + + #region 0x011 chunk + + [Chunk(0x03038011)] + public class Chunk03038011 : Chunk + { + public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + } + } + + #endregion + + #region 0x013 chunk + + [Chunk(0x03038013)] + public class Chunk03038013 : Chunk + { + public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + } + } + + #endregion + + #region 0x014 chunk + + [Chunk(0x03038014)] + public class Chunk03038014 : Chunk + { + public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + } + } + + #endregion + + #region 0x015 chunk + + [Chunk(0x03038015)] + public class Chunk03038015 : Chunk + { + public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + } + } + + #endregion + + #region 0x016 chunk + + [Chunk(0x03038016)] + public class Chunk03038016 : Chunk + { + public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + } + } + + #endregion + + #region 0x017 chunk + + [Chunk(0x03038017)] + public class Chunk03038017 : Chunk + { + public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + } + } + + #endregion + + #region 0x018 chunk + + [Chunk(0x03038018)] + public class Chunk03038018 : Chunk + { + public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + } + } + + #endregion + + #region 0x019 chunk + + [Chunk(0x03038019)] + public class Chunk03038019 : Chunk + { + public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + rw.Int32(Unknown); + rw.Int32(Unknown); + } + } + + #endregion + + #region 0x01A chunk + + [Chunk(0x0303801A)] + public class Chunk0303801A : Chunk + { + public override void ReadWrite(CGameCtnDecoration n, GameBoxReaderWriter rw) + { + rw.Int32(Unknown); + rw.Int32(Unknown); + } + } + + #endregion + + #endregion + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnGhost.cs b/GBX.NET/Engines/Game/CGameCtnGhost.cs index 4d293be20..dae8e8d26 100644 --- a/GBX.NET/Engines/Game/CGameCtnGhost.cs +++ b/GBX.NET/Engines/Game/CGameCtnGhost.cs @@ -150,11 +150,6 @@ public TimeSpan[] Checkpoints #endregion - public CGameCtnGhost(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x000 skippable chunk (basic) diff --git a/GBX.NET/Engines/Game/CGameCtnMacroBlockInfo.cs b/GBX.NET/Engines/Game/CGameCtnMacroBlockInfo.cs index aa0d3c128..39c2d0aed 100644 --- a/GBX.NET/Engines/Game/CGameCtnMacroBlockInfo.cs +++ b/GBX.NET/Engines/Game/CGameCtnMacroBlockInfo.cs @@ -19,11 +19,6 @@ public class CGameCtnMacroBlockInfo : CGameCtnCollector public List FreeBlocks { get; set; } = new List(); - public CGameCtnMacroBlockInfo(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x000 chunk (blocks) diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlock.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlock.cs index 0d03c7dca..1d8680542 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlock.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlock.cs @@ -1,14 +1,11 @@ -namespace GBX.NET.Engines.Game -{ +namespace GBX.NET.Engines.Game +{ /// /// MediaTracker block (0x03077000) - /// - [Node(0x03077000)] - public class CGameCtnMediaBlock : Node - { - public CGameCtnMediaBlock(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - } + /// + [Node(0x03077000)] + public class CGameCtnMediaBlock : Node + { + + } } \ No newline at end of file diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlock3dStereo.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlock3dStereo.cs index 36779c14a..5d77b7898 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlock3dStereo.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlock3dStereo.cs @@ -1,57 +1,52 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// MediaTracker block - 3D stereo (0x03024000) - /// - [Node(0x03024000)] - public class CGameCtnMediaBlock3dStereo : CGameCtnMediaBlock - { - public Key[] Keys { get; set; } - - public CGameCtnMediaBlock3dStereo(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + /// + [Node(0x03024000)] + public class CGameCtnMediaBlock3dStereo : CGameCtnMediaBlock + { + public Key[] Keys { get; set; } - #region Chunks + #region Chunks - #region 0x000 chunk + #region 0x000 chunk /// /// CGameCtnMediaBlock3dStereo 0x000 chunk /// - [Chunk(0x03024000)] - public class Chunk03024000 : Chunk - { - public override void ReadWrite(CGameCtnMediaBlock3dStereo n, GameBoxReaderWriter rw) - { - n.Keys = rw.Array(n.Keys, i => new Key() - { - Time = rw.Reader.ReadSingle(), - UpToMax = rw.Reader.ReadSingle(), - ScreenDist = rw.Reader.ReadSingle() - }, - x => - { - rw.Writer.Write(x.Time); - rw.Writer.Write(x.UpToMax); - rw.Writer.Write(x.ScreenDist); - }); - } + [Chunk(0x03024000)] + public class Chunk03024000 : Chunk + { + public override void ReadWrite(CGameCtnMediaBlock3dStereo n, GameBoxReaderWriter rw) + { + n.Keys = rw.Array(n.Keys, i => new Key() + { + Time = rw.Reader.ReadSingle(), + UpToMax = rw.Reader.ReadSingle(), + ScreenDist = rw.Reader.ReadSingle() + }, + x => + { + rw.Writer.Write(x.Time); + rw.Writer.Write(x.UpToMax); + rw.Writer.Write(x.ScreenDist); + }); + } } - #endregion + #endregion - #endregion + #endregion - public class Key : MediaBlockKey - { - public float UpToMax { get; set; } - public float ScreenDist { get; set; } - } - } -} + public class Key : MediaBlockKey + { + public float UpToMax { get; set; } + public float ScreenDist { get; set; } + } + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockBloomHdr.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockBloomHdr.cs index b582b09de..1593da4bb 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockBloomHdr.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockBloomHdr.cs @@ -1,60 +1,55 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// MediaTracker block - Bloom HDR (0x03128000) - /// - [Node(0x03128000)] - public class CGameCtnMediaBlockBloomHdr : CGameCtnMediaBlock - { - public Key[] Keys { get; set; } - - public CGameCtnMediaBlockBloomHdr(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + /// + [Node(0x03128000)] + public class CGameCtnMediaBlockBloomHdr : CGameCtnMediaBlock + { + public Key[] Keys { get; set; } - #region Chunks + #region Chunks - #region 0x002 chunk + #region 0x002 chunk /// /// CGameCtnMediaBlockBloomHdr 0x002 chunk /// - [Chunk(0x03128002)] - public class Chunk03128002 : Chunk - { - public override void ReadWrite(CGameCtnMediaBlockBloomHdr n, GameBoxReaderWriter rw) - { - n.Keys = rw.Array(n.Keys, i => new Key() - { - Time = rw.Reader.ReadSingle(), - Intensity = rw.Reader.ReadSingle(), - StreaksIntensity = rw.Reader.ReadSingle(), - StreaksAttenuation = rw.Reader.ReadSingle() - }, - x => - { - rw.Writer.Write(x.Time); - rw.Writer.Write(x.Intensity); - rw.Writer.Write(x.StreaksIntensity); - rw.Writer.Write(x.StreaksAttenuation); - }); - } + [Chunk(0x03128002)] + public class Chunk03128002 : Chunk + { + public override void ReadWrite(CGameCtnMediaBlockBloomHdr n, GameBoxReaderWriter rw) + { + n.Keys = rw.Array(n.Keys, i => new Key() + { + Time = rw.Reader.ReadSingle(), + Intensity = rw.Reader.ReadSingle(), + StreaksIntensity = rw.Reader.ReadSingle(), + StreaksAttenuation = rw.Reader.ReadSingle() + }, + x => + { + rw.Writer.Write(x.Time); + rw.Writer.Write(x.Intensity); + rw.Writer.Write(x.StreaksIntensity); + rw.Writer.Write(x.StreaksAttenuation); + }); + } } - #endregion + #endregion - #endregion + #endregion - public class Key : MediaBlockKey - { - public float Intensity { get; set; } - public float StreaksIntensity { get; set; } - public float StreaksAttenuation { get; set; } - } - } -} + public class Key : MediaBlockKey + { + public float Intensity { get; set; } + public float StreaksIntensity { get; set; } + public float StreaksAttenuation { get; set; } + } + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockCamera.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockCamera.cs index de798bd02..736e7400c 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockCamera.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockCamera.cs @@ -11,9 +11,6 @@ namespace GBX.NET.Engines.Game [Node(0x0307C000)] public class CGameCtnMediaBlockCamera : CGameCtnMediaBlock { - public CGameCtnMediaBlockCamera(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + } } diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraCustom.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraCustom.cs index 6aeb45390..1de494925 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraCustom.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraCustom.cs @@ -15,11 +15,6 @@ public class CGameCtnMediaBlockCameraCustom : CGameCtnMediaBlockCamera { public List Keys { get; set; } = new List(); - public CGameCtnMediaBlockCameraCustom(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x002 chunk diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraEffect.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraEffect.cs index 59dba305a..010be3c02 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraEffect.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraEffect.cs @@ -1,14 +1,11 @@ -namespace GBX.NET.Engines.Game -{ +namespace GBX.NET.Engines.Game +{ /// /// MediaTracker block - Camera effect - /// - [Node(0x030A3000)] - public class CGameCtnMediaBlockCameraEffect : CGameCtnMediaBlock - { - public CGameCtnMediaBlockCameraEffect(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - } + /// + [Node(0x030A3000)] + public class CGameCtnMediaBlockCameraEffect : CGameCtnMediaBlock + { + + } } \ No newline at end of file diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraEffectShake.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraEffectShake.cs index edc3f2c86..5dbf93e47 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraEffectShake.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraEffectShake.cs @@ -1,59 +1,54 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Security.Cryptography; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// MediaTracker block - Camera shake - /// - [Node(0x030A4000)] - public class CGameCtnMediaBlockCameraEffectShake : CGameCtnMediaBlockCameraEffect - { - public Key[] Keys { get; set; } - - public CGameCtnMediaBlockCameraEffectShake(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + /// + [Node(0x030A4000)] + public class CGameCtnMediaBlockCameraEffectShake : CGameCtnMediaBlockCameraEffect + { + public Key[] Keys { get; set; } - #region Chunks + #region Chunks - #region 0x000 chunk + #region 0x000 chunk /// /// CGameCtnMediaBlockCameraEffectShake 0x000 chunk /// - [Chunk(0x030A4000)] - public class Chunk030A4000 : Chunk - { - public override void ReadWrite(CGameCtnMediaBlockCameraEffectShake n, GameBoxReaderWriter rw) - { - n.Keys = rw.Array(n.Keys, i => new Key() - { - Time = rw.Reader.ReadSingle(), - Intensity = rw.Reader.ReadSingle(), - Speed = rw.Reader.ReadSingle() - }, - x => - { - rw.Writer.Write(x.Time); - rw.Writer.Write(x.Intensity); - rw.Writer.Write(x.Speed); - }); - } + [Chunk(0x030A4000)] + public class Chunk030A4000 : Chunk + { + public override void ReadWrite(CGameCtnMediaBlockCameraEffectShake n, GameBoxReaderWriter rw) + { + n.Keys = rw.Array(n.Keys, i => new Key() + { + Time = rw.Reader.ReadSingle(), + Intensity = rw.Reader.ReadSingle(), + Speed = rw.Reader.ReadSingle() + }, + x => + { + rw.Writer.Write(x.Time); + rw.Writer.Write(x.Intensity); + rw.Writer.Write(x.Speed); + }); + } } - #endregion + #endregion - #endregion + #endregion - public class Key : MediaBlockKey - { - public float Intensity { get; set; } - public float Speed { get; set; } - } - } -} + public class Key : MediaBlockKey + { + public float Intensity { get; set; } + public float Speed { get; set; } + } + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraGame.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraGame.cs index 87d23fe10..9fdad5283 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraGame.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraGame.cs @@ -37,11 +37,6 @@ public enum EGameCam2 : int public int Target { get; set; } = -1; public string GameCam { get; set; } - public CGameCtnMediaBlockCameraGame(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x000 chunk diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraPath.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraPath.cs index 1aa46a574..8ae9cb8e4 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraPath.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockCameraPath.cs @@ -14,11 +14,6 @@ public class CGameCtnMediaBlockCameraPath : CGameCtnMediaBlockCamera { public Key[] Keys { get; set; } - public CGameCtnMediaBlockCameraPath(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x000 chunk diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockColorGrading.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockColorGrading.cs index a80027735..f389cb598 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockColorGrading.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockColorGrading.cs @@ -1,71 +1,66 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// MediaTracker block - Color grading - /// - [Node(0x03186000)] - public class CGameCtnMediaBlockColorGrading : CGameCtnMediaBlock - { - public FileRef Image { get; set; } - public Key[] Keys { get; set; } - - public CGameCtnMediaBlockColorGrading(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + /// + [Node(0x03186000)] + public class CGameCtnMediaBlockColorGrading : CGameCtnMediaBlock + { + public FileRef Image { get; set; } + public Key[] Keys { get; set; } - #region Chunks + #region Chunks - #region 0x000 chunk + #region 0x000 chunk /// /// CGameCtnMediaBlockColorGrading 0x000 chunk - /// - [Chunk(0x03186000)] - public class Chunk03186000 : Chunk - { - public override void ReadWrite(CGameCtnMediaBlockColorGrading n, GameBoxReaderWriter rw) - { - n.Image = rw.FileRef(n.Image); - } + /// + [Chunk(0x03186000)] + public class Chunk03186000 : Chunk + { + public override void ReadWrite(CGameCtnMediaBlockColorGrading n, GameBoxReaderWriter rw) + { + n.Image = rw.FileRef(n.Image); + } } - #endregion + #endregion - #region 0x001 chunk + #region 0x001 chunk /// /// CGameCtnMediaBlockColorGrading 0x001 chunk /// - [Chunk(0x03186001)] - public class Chunk03186001 : Chunk - { - public override void ReadWrite(CGameCtnMediaBlockColorGrading n, GameBoxReaderWriter rw) - { - n.Keys = rw.Array(n.Keys, i => new Key() - { - Time = rw.Reader.ReadSingle(), - Intensity = rw.Reader.ReadSingle() - }, - x => - { - rw.Writer.Write(x.Time); - rw.Writer.Write(x.Intensity); - }); - } + [Chunk(0x03186001)] + public class Chunk03186001 : Chunk + { + public override void ReadWrite(CGameCtnMediaBlockColorGrading n, GameBoxReaderWriter rw) + { + n.Keys = rw.Array(n.Keys, i => new Key() + { + Time = rw.Reader.ReadSingle(), + Intensity = rw.Reader.ReadSingle() + }, + x => + { + rw.Writer.Write(x.Time); + rw.Writer.Write(x.Intensity); + }); + } } - #endregion + #endregion - #endregion + #endregion - public class Key : MediaBlockKey - { - public float Intensity { get; set; } - } - } -} + public class Key : MediaBlockKey + { + public float Intensity { get; set; } + } + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockColoringBase.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockColoringBase.cs index 15aa81f80..c0f83e850 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockColoringBase.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockColoringBase.cs @@ -1,68 +1,63 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// MediaTracker block - Coloring base - /// - [Node(0x03172000)] - public class CGameCtnMediaBlockColoringBase : CGameCtnMediaBlock - { - public Key[] Keys { get; set; } - public int BaseIndex { get; set; } - - public CGameCtnMediaBlockColoringBase(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + /// + [Node(0x03172000)] + public class CGameCtnMediaBlockColoringBase : CGameCtnMediaBlock + { + public Key[] Keys { get; set; } + public int BaseIndex { get; set; } - #region Chunks + #region Chunks - #region 0x000 chunk + #region 0x000 chunk /// /// CGameCtnMediaBlockColoringBase 0x000 chunk /// - [Chunk(0x03172000)] - public class Chunk03172000 : Chunk - { - public int Version { get; set; } - - public override void ReadWrite(CGameCtnMediaBlockColoringBase n, GameBoxReaderWriter rw) - { - Version = rw.Int32(Version); - rw.Int32(Unknown); - - n.Keys = rw.Array(n.Keys, i => new Key() - { - Time = rw.Reader.ReadSingle(), - Hue = rw.Reader.ReadSingle(), - Intensity = rw.Reader.ReadSingle(), - Unknown = rw.Reader.ReadInt16() - }, - x => - { - rw.Writer.Write(x.Time); - rw.Writer.Write(x.Hue); - rw.Writer.Write(x.Intensity); - rw.Writer.Write(x.Unknown); - }); - - n.BaseIndex = rw.Int32(n.BaseIndex); - } + [Chunk(0x03172000)] + public class Chunk03172000 : Chunk + { + public int Version { get; set; } + + public override void ReadWrite(CGameCtnMediaBlockColoringBase n, GameBoxReaderWriter rw) + { + Version = rw.Int32(Version); + rw.Int32(Unknown); + + n.Keys = rw.Array(n.Keys, i => new Key() + { + Time = rw.Reader.ReadSingle(), + Hue = rw.Reader.ReadSingle(), + Intensity = rw.Reader.ReadSingle(), + Unknown = rw.Reader.ReadInt16() + }, + x => + { + rw.Writer.Write(x.Time); + rw.Writer.Write(x.Hue); + rw.Writer.Write(x.Intensity); + rw.Writer.Write(x.Unknown); + }); + + n.BaseIndex = rw.Int32(n.BaseIndex); + } } - #endregion + #endregion - #endregion + #endregion - public class Key : MediaBlockKey - { - public float Hue { get; set; } - public float Intensity { get; set; } - public short Unknown { get; set; } - } - } -} + public class Key : MediaBlockKey + { + public float Hue { get; set; } + public float Intensity { get; set; } + public short Unknown { get; set; } + } + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockColoringCapturable.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockColoringCapturable.cs index 951cb0dcb..8c5e698ab 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockColoringCapturable.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockColoringCapturable.cs @@ -1,65 +1,60 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace GBX.NET.Engines.Game -{ +using System; +using System.Collections.Generic; +using System.Text; + +namespace GBX.NET.Engines.Game +{ /// /// MediaTracker block - Coloring capturable - /// - [Node(0x0316C000)] - public class CGameCtnMediaBlockColoringCapturable : CGameCtnMediaBlock - { - public Key[] Keys { get; set; } - - public CGameCtnMediaBlockColoringCapturable(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + /// + [Node(0x0316C000)] + public class CGameCtnMediaBlockColoringCapturable : CGameCtnMediaBlock + { + public Key[] Keys { get; set; } #region Chunks - #region 0x000 chunk + #region 0x000 chunk /// /// CGameCtnMediaBlockColoringCapturable 0x000 chunk /// - [Chunk(0x0316C000)] - public class Chunk0316C000 : Chunk - { - public int Version { get; set; } - - public override void ReadWrite(CGameCtnMediaBlockColoringCapturable n, GameBoxReaderWriter rw) - { - Version = rw.Int32(Version); - rw.Int32(Unknown); - - n.Keys = rw.Array(n.Keys, i => new Key() - { - Time = rw.Reader.ReadSingle(), - Hue = rw.Reader.ReadSingle(), - Gauge = rw.Reader.ReadSingle(), - Emblem = rw.Reader.ReadInt32() - }, - x => - { - rw.Writer.Write(x.Time); - rw.Writer.Write(x.Hue); - rw.Writer.Write(x.Gauge); - rw.Writer.Write(x.Emblem); - }); - } + [Chunk(0x0316C000)] + public class Chunk0316C000 : Chunk + { + public int Version { get; set; } + + public override void ReadWrite(CGameCtnMediaBlockColoringCapturable n, GameBoxReaderWriter rw) + { + Version = rw.Int32(Version); + rw.Int32(Unknown); + + n.Keys = rw.Array(n.Keys, i => new Key() + { + Time = rw.Reader.ReadSingle(), + Hue = rw.Reader.ReadSingle(), + Gauge = rw.Reader.ReadSingle(), + Emblem = rw.Reader.ReadInt32() + }, + x => + { + rw.Writer.Write(x.Time); + rw.Writer.Write(x.Hue); + rw.Writer.Write(x.Gauge); + rw.Writer.Write(x.Emblem); + }); + } } - #endregion + #endregion - #endregion + #endregion - public class Key : MediaBlockKey - { - public float Hue { get; set; } - public float Gauge { get; set; } - public int Emblem { get; set; } - } - } -} + public class Key : MediaBlockKey + { + public float Hue { get; set; } + public float Gauge { get; set; } + public int Emblem { get; set; } + } + } +} diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockDOF.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockDOF.cs index b2b4c6939..99e24afd1 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockDOF.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockDOF.cs @@ -10,11 +10,6 @@ public class CGameCtnMediaBlockDOF : CGameCtnMediaBlock { public Key[] Keys { get; set; } - public CGameCtnMediaBlockDOF(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03126002)] public class Chunk03126002 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockDirtyLens.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockDirtyLens.cs index 10d2a8714..38c50ec9c 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockDirtyLens.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockDirtyLens.cs @@ -5,11 +5,6 @@ public class CGameCtnMediaBlockDirtyLens : CGameCtnMediaBlock { public Key[] Keys { get; set; } - public CGameCtnMediaBlockDirtyLens(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03165000)] public class Chunk03165000 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockFog.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockFog.cs index be5a23c65..b756f3bb3 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockFog.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockFog.cs @@ -10,11 +10,6 @@ public class CGameCtnMediaBlockFog : CGameCtnMediaBlock { public Key[] Keys { get; set; } - public CGameCtnMediaBlockFog(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03199000)] public class Chunk03199000 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockFx.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockFx.cs index 1c1f9b0bb..d2afffa3d 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockFx.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockFx.cs @@ -7,9 +7,6 @@ namespace GBX.NET.Engines.Game [Node(0x0307E000)] public class CGameCtnMediaBlockFx : CGameCtnMediaBlock { - public CGameCtnMediaBlockFx(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + } } diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlur.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlur.cs index 93930874e..08236d782 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlur.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlur.cs @@ -7,9 +7,6 @@ namespace GBX.NET.Engines.Game [Node(0x0307F000)] public class CGameCtnMediaBlockFxBlur : CGameCtnMediaBlockFx { - public CGameCtnMediaBlockFxBlur(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + } } diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlurDepth.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlurDepth.cs index 498d8f61d..1566a1ec7 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlurDepth.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlurDepth.cs @@ -10,11 +10,6 @@ public class CGameCtnMediaBlockFxBlurDepth : CGameCtnMediaBlockFx { public Key[] Keys { get; set; } - public CGameCtnMediaBlockFxBlurDepth(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03081001)] public class Chunk03081001 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlurMotion.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlurMotion.cs index f13ea99dc..b2587e8a0 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlurMotion.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxBlurMotion.cs @@ -12,11 +12,6 @@ public class CGameCtnMediaBlockFxBlurMotion : CGameCtnMediaBlockFxBlur public float? End { get; set; } - public CGameCtnMediaBlockFxBlurMotion(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x000 chunk diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxCameraBlend.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxCameraBlend.cs index b63522aa9..8db331e55 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxCameraBlend.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxCameraBlend.cs @@ -9,11 +9,6 @@ public class CGameCtnMediaBlockFxCameraBlend : CGameCtnMediaBlock { public Key[] Keys { get; set; } - public CGameCtnMediaBlockFxCameraBlend(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x0316D000)] public class Chunk0316D000 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxCameraMap.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxCameraMap.cs index 71dfd6bd0..05f136320 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxCameraMap.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxCameraMap.cs @@ -10,11 +10,6 @@ public class CGameCtnMediaBlockFxCameraMap : CGameCtnMediaBlock public float Start { get; set; } public float End { get; set; } - public CGameCtnMediaBlockFxCameraMap(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03139000)] public class Chunk03139000 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxColors.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxColors.cs index 61e313f62..100dda77c 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxColors.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxColors.cs @@ -7,11 +7,6 @@ namespace GBX.NET.Engines.Game [Node(0x03080000)] public class CGameCtnMediaBlockFxColors : CGameCtnMediaBlockFx { - public CGameCtnMediaBlockFxColors(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03080003)] public class Chunk03080003 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockGhost.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockGhost.cs index 51cf5daaf..31797d736 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockGhost.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockGhost.cs @@ -23,11 +23,6 @@ public class CGameCtnMediaBlockGhost : CGameCtnMediaBlock public bool ForceHue { get; set; } - public CGameCtnMediaBlockGhost(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x030E5001)] public class Chunk030E5001 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockImage.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockImage.cs index c00d0a34f..bbe66bdec 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockImage.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockImage.cs @@ -13,11 +13,6 @@ public class CGameCtnMediaBlockImage : CGameCtnMediaBlock public FileRef Image { get; set; } - public CGameCtnMediaBlockImage(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x030A5000)] public class Chunk030A5000 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockInterface.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockInterface.cs index 3bd8004b6..d4dc6883d 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockInterface.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockInterface.cs @@ -12,11 +12,6 @@ public class CGameCtnMediaBlockInterface : CGameCtnMediaBlock public bool ShowInterface { get; set; } public string Manialink { get; set; } - public CGameCtnMediaBlockInterface(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03195000)] public class Chunk03195000 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockManialink.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockManialink.cs index b224271cc..03c169cbc 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockManialink.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockManialink.cs @@ -11,11 +11,6 @@ public class CGameCtnMediaBlockManialink : CGameCtnMediaBlock public float End { get; set; } public string Manialink { get; set; } - public CGameCtnMediaBlockManialink(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x0312A001)] public class Chunk0312A001 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockMusicEffect.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockMusicEffect.cs index 0ed3408e2..118737c18 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockMusicEffect.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockMusicEffect.cs @@ -10,11 +10,6 @@ public class CGameCtnMediaBlockMusicEffect : CGameCtnMediaBlock { public Key[] Keys { get; set; } - public CGameCtnMediaBlockMusicEffect(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x030A6000)] public class Chunk030A6000 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockShoot.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockShoot.cs index 09a2db6dc..2360d4a81 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockShoot.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockShoot.cs @@ -10,11 +10,6 @@ public class CGameCtnMediaBlockShoot : CGameCtnMediaBlock public float Start { get; set; } public float End { get; set; } - public CGameCtnMediaBlockShoot(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03145000)] public class Chunk03145000 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockSound.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockSound.cs index 33fba3cf9..b3bcd3acc 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockSound.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockSound.cs @@ -12,11 +12,6 @@ public class CGameCtnMediaBlockSound : CGameCtnMediaBlock public Key[] Keys { get; set; } - public CGameCtnMediaBlockSound(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x001 chunk diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockText.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockText.cs index be8efea54..77f39b35c 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockText.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockText.cs @@ -12,11 +12,6 @@ public class CGameCtnMediaBlockText : CGameCtnMediaBlock public string Text { get; set; } public CControlEffectSimi Simi { get; set; } - public CGameCtnMediaBlockText(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x001 chunk diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockTime.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockTime.cs index c31aaa01b..9edc9d037 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockTime.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockTime.cs @@ -5,11 +5,6 @@ public class CGameCtnMediaBlockTime : CGameCtnMediaBlock { public Key[] Keys { get; set; } - public CGameCtnMediaBlockTime(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03085000)] public class Chunk03085000 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockToneMapping.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockToneMapping.cs index f06200bc3..bdf3de373 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockToneMapping.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockToneMapping.cs @@ -9,11 +9,6 @@ public class CGameCtnMediaBlockToneMapping : CGameCtnMediaBlock { public Key[] Keys { get; set; } - public CGameCtnMediaBlockToneMapping(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03127004)] public class Chunk03127004 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockTrails.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockTrails.cs index daebab41d..a0c1ae482 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockTrails.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockTrails.cs @@ -11,11 +11,6 @@ public class CGameCtnMediaBlockTrails : CGameCtnMediaBlock public float Start { get; set; } public float End { get; set; } - public CGameCtnMediaBlockTrails(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x000 chunk diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockTransitionFade.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockTransitionFade.cs index 50989f7cc..dd0a09bbd 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockTransitionFade.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockTransitionFade.cs @@ -13,11 +13,6 @@ public class CGameCtnMediaBlockTransitionFade : CGameCtnMediaBlock public Vec3 Color { get; set; } - public CGameCtnMediaBlockTransitionFade(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x030AB000)] public class Chunk030AB000 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles.cs index 4a9bbd81d..b1d26f51e 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles.cs @@ -7,9 +7,6 @@ namespace GBX.NET.Engines.Game [Node(0x03029000)] public class CGameCtnMediaBlockTriangles : CGameCtnMediaBlock { - public CGameCtnMediaBlockTriangles(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + } } diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles2D.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles2D.cs index 5601469f7..6a93eb075 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles2D.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles2D.cs @@ -7,9 +7,6 @@ namespace GBX.NET.Engines.Game [Node(0x0304B000)] public class CGameCtnMediaBlockTriangles2D : CGameCtnMediaBlockTriangles { - public CGameCtnMediaBlockTriangles2D(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + } } diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockVehicleLight.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockVehicleLight.cs index 5f44403a7..8b50dc6a4 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockVehicleLight.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockVehicleLight.cs @@ -11,11 +11,6 @@ public class CGameCtnMediaBlockVehicleLight : CGameCtnMediaBlock public float End { get; set; } public int Target { get; set; } - public CGameCtnMediaBlockVehicleLight(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03133000)] public class Chunk03133000 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaClip.cs b/GBX.NET/Engines/Game/CGameCtnMediaClip.cs index 843da7c83..0d115f12a 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaClip.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaClip.cs @@ -13,16 +13,6 @@ public class CGameCtnMediaClip : Node public List Tracks { get; set; } - public CGameCtnMediaClip(ILookbackable lookbackable) : base(lookbackable) - { - - } - - public CGameCtnMediaClip(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - public override string ToString() { return string.IsNullOrEmpty(Name) ? "Unnamed clip" : Name; diff --git a/GBX.NET/Engines/Game/CGameCtnMediaClipGroup.cs b/GBX.NET/Engines/Game/CGameCtnMediaClipGroup.cs index 4eabc5ced..760372795 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaClipGroup.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaClipGroup.cs @@ -14,11 +14,6 @@ public class CGameCtnMediaClipGroup : Node public Trigger[] Triggers { get; set; } - public CGameCtnMediaClipGroup(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x0307A002)] public class Chunk0307A002 : Chunk { diff --git a/GBX.NET/Engines/Game/CGameCtnMediaTrack.cs b/GBX.NET/Engines/Game/CGameCtnMediaTrack.cs index 3351e9e47..6f650c3f0 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaTrack.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaTrack.cs @@ -13,16 +13,6 @@ public class CGameCtnMediaTrack : Node public List Blocks { get; set; } - public CGameCtnMediaTrack(ILookbackable lookbackable) : base(lookbackable) - { - - } - - public CGameCtnMediaTrack(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - public override string ToString() { return Name; diff --git a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs index 7598e1d12..4b4a2d3c6 100644 --- a/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs +++ b/GBX.NET/Engines/Game/CGameCtnReplayRecord.cs @@ -25,11 +25,6 @@ public class CGameCtnReplayRecord : Node public CPlugEntRecordData RecordData { get; set; } public CCtnMediaBlockEventTrackMania Events { get; set; } - public CGameCtnReplayRecord(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x000 chunk (basic) diff --git a/GBX.NET/Engines/Game/CGameCtnZoneGenealogy.cs b/GBX.NET/Engines/Game/CGameCtnZoneGenealogy.cs index a013b39ba..40ece99c4 100644 --- a/GBX.NET/Engines/Game/CGameCtnZoneGenealogy.cs +++ b/GBX.NET/Engines/Game/CGameCtnZoneGenealogy.cs @@ -11,11 +11,6 @@ public class CGameCtnZoneGenealogy : Node public int BaseHeight { get; set; } public string CurrentZone { get; set; } - public CGameCtnZoneGenealogy(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - public override string ToString() { return string.Join(" ", Zones); diff --git a/GBX.NET/Engines/Game/CGameGhost.cs b/GBX.NET/Engines/Game/CGameGhost.cs index 0dc672a0c..035e2dd8f 100644 --- a/GBX.NET/Engines/Game/CGameGhost.cs +++ b/GBX.NET/Engines/Game/CGameGhost.cs @@ -11,11 +11,6 @@ public class CGameGhost : Node { public bool IsReplaying { get; set; } - public CGameGhost(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x003 chunk diff --git a/GBX.NET/Engines/Game/CGamePlayerProfile.cs b/GBX.NET/Engines/Game/CGamePlayerProfile.cs index d016241f8..70636d540 100644 --- a/GBX.NET/Engines/Game/CGamePlayerProfile.cs +++ b/GBX.NET/Engines/Game/CGamePlayerProfile.cs @@ -11,11 +11,6 @@ public class CGamePlayerProfile : Node public string OnlineLogin { get; set; } public string OnlineSupportKey { get; set; } - public CGamePlayerProfile(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x000 chunk diff --git a/GBX.NET/Engines/GameData/CGameBlockItem.cs b/GBX.NET/Engines/GameData/CGameBlockItem.cs index b0e74f55e..48bb017d5 100644 --- a/GBX.NET/Engines/GameData/CGameBlockItem.cs +++ b/GBX.NET/Engines/GameData/CGameBlockItem.cs @@ -11,11 +11,6 @@ public class CGameBlockItem : Node public string ArchetypeBlockInfoId { get; set; } public CPlugCrystal[] Crystals { get; set; } - public CGameBlockItem(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x2E025000)] public class Chunk2E025000 : Chunk { diff --git a/GBX.NET/Engines/GameData/CGameCtnAutoTerrain.cs b/GBX.NET/Engines/GameData/CGameCtnAutoTerrain.cs index 59f319545..c8d859af5 100644 --- a/GBX.NET/Engines/GameData/CGameCtnAutoTerrain.cs +++ b/GBX.NET/Engines/GameData/CGameCtnAutoTerrain.cs @@ -8,11 +8,6 @@ namespace GBX.NET.Engines.GameData [Node(0x03120000)] public class CGameCtnAutoTerrain : Node { - public CGameCtnAutoTerrain(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x03120001)] public class Chunk03120001 : Chunk { diff --git a/GBX.NET/Engines/GameData/CGameCtnCollector.cs b/GBX.NET/Engines/GameData/CGameCtnCollector.cs index b2fef4baf..0280af47e 100644 --- a/GBX.NET/Engines/GameData/CGameCtnCollector.cs +++ b/GBX.NET/Engines/GameData/CGameCtnCollector.cs @@ -22,11 +22,6 @@ public class CGameCtnCollector : Node public bool IconUseAutoRender { get; set; } public int IconQuarterRotationY { get; set; } - public CGameCtnCollector(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x003 chunk diff --git a/GBX.NET/Engines/GameData/CGameItemModel.cs b/GBX.NET/Engines/GameData/CGameItemModel.cs index 32c70585a..93a5bf794 100644 --- a/GBX.NET/Engines/GameData/CGameItemModel.cs +++ b/GBX.NET/Engines/GameData/CGameItemModel.cs @@ -48,11 +48,6 @@ public enum ItemType : int public Node Block { get; set; } public CGameItemPlacementParam ItemPlacement { get; set; } - public CGameItemModel(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x2E002000)] public class Chunk2E002000 : HeaderChunk { diff --git a/GBX.NET/Engines/GameData/CGameItemPlacementParam.cs b/GBX.NET/Engines/GameData/CGameItemPlacementParam.cs index d911dd482..cae7b10c4 100644 --- a/GBX.NET/Engines/GameData/CGameItemPlacementParam.cs +++ b/GBX.NET/Engines/GameData/CGameItemPlacementParam.cs @@ -8,9 +8,6 @@ namespace GBX.NET.Engines.GameData [Node(0x2E020000)] public class CGameItemPlacementParam : Node { - public CGameItemPlacementParam(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + } } \ No newline at end of file diff --git a/GBX.NET/Engines/GameData/CGameWaypointSpecialProperty.cs b/GBX.NET/Engines/GameData/CGameWaypointSpecialProperty.cs index 282079824..237c871cf 100644 --- a/GBX.NET/Engines/GameData/CGameWaypointSpecialProperty.cs +++ b/GBX.NET/Engines/GameData/CGameWaypointSpecialProperty.cs @@ -12,11 +12,6 @@ public class CGameWaypointSpecialProperty : Node public string Tag { get; set; } public int Order { get; set; } - public CGameWaypointSpecialProperty(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x000 chunk diff --git a/GBX.NET/Engines/Hms/CHmsLightMapCache.cs b/GBX.NET/Engines/Hms/CHmsLightMapCache.cs index 9005a02d2..9541fc089 100644 --- a/GBX.NET/Engines/Hms/CHmsLightMapCache.cs +++ b/GBX.NET/Engines/Hms/CHmsLightMapCache.cs @@ -8,11 +8,6 @@ namespace GBX.NET.Engines.Hms [Node(0x06022000)] public class CHmsLightMapCache : Node { - public CHmsLightMapCache(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x0602201A)] public class Chunk0602201A : SkippableChunk { diff --git a/GBX.NET/Engines/MwFoundations/CMwNod.cs b/GBX.NET/Engines/MwFoundations/CMwNod.cs index 14058708f..4dc448599 100644 --- a/GBX.NET/Engines/MwFoundations/CMwNod.cs +++ b/GBX.NET/Engines/MwFoundations/CMwNod.cs @@ -9,11 +9,6 @@ public class CMwNod : Node { public string[] Dependencies { get; set; } - public CMwNod(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - #region Chunks #region 0x000 chunk (FolderDep) diff --git a/GBX.NET/Engines/Plug/CPlug.cs b/GBX.NET/Engines/Plug/CPlug.cs index 3e0f1e0b5..755bd1da4 100644 --- a/GBX.NET/Engines/Plug/CPlug.cs +++ b/GBX.NET/Engines/Plug/CPlug.cs @@ -7,9 +7,6 @@ namespace GBX.NET.Engines.Plug [Node(0x0902B000)] public class CPlug : Node { - public CPlug(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } + } } diff --git a/GBX.NET/Engines/Plug/CPlugCrystal.cs b/GBX.NET/Engines/Plug/CPlugCrystal.cs index a234a885a..7e174ce4a 100644 --- a/GBX.NET/Engines/Plug/CPlugCrystal.cs +++ b/GBX.NET/Engines/Plug/CPlugCrystal.cs @@ -13,11 +13,6 @@ public class CPlugCrystal : CPlugTreeGenerator public CPlugMaterialUserInst[] Materials { get; set; } public Layer[] Layers { get; set; } - public CPlugCrystal(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x09003003)] public class Chunk09003003 : Chunk { diff --git a/GBX.NET/Engines/Plug/CPlugEntRecordData.cs b/GBX.NET/Engines/Plug/CPlugEntRecordData.cs index cb378d273..a47a805bb 100644 --- a/GBX.NET/Engines/Plug/CPlugEntRecordData.cs +++ b/GBX.NET/Engines/Plug/CPlugEntRecordData.cs @@ -10,11 +10,6 @@ namespace GBX.NET.Engines.Plug [Node(0x0911F000)] public class CPlugEntRecordData : Node { - public CPlugEntRecordData(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x0911F000)] public class Chunk000 : Chunk { diff --git a/GBX.NET/Engines/Plug/CPlugMaterialUserInst.cs b/GBX.NET/Engines/Plug/CPlugMaterialUserInst.cs index d2b20396e..15bd87bae 100644 --- a/GBX.NET/Engines/Plug/CPlugMaterialUserInst.cs +++ b/GBX.NET/Engines/Plug/CPlugMaterialUserInst.cs @@ -9,11 +9,6 @@ public class CPlugMaterialUserInst : Node { public string MaterialFile { get; set; } - public CPlugMaterialUserInst(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x090FD000)] public class Chunk090FD000 : Chunk { diff --git a/GBX.NET/Engines/Plug/CPlugTreeGenerator.cs b/GBX.NET/Engines/Plug/CPlugTreeGenerator.cs index 618f44024..41cbbab18 100644 --- a/GBX.NET/Engines/Plug/CPlugTreeGenerator.cs +++ b/GBX.NET/Engines/Plug/CPlugTreeGenerator.cs @@ -7,11 +7,6 @@ namespace GBX.NET.Engines.Plug [Node(0x09051000)] public class CPlugTreeGenerator : CPlug { - public CPlugTreeGenerator(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x09051000)] public class Chunk09051000 : Chunk { diff --git a/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs b/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs index 57edf7671..fb0eb6451 100644 --- a/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs +++ b/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs @@ -54,11 +54,6 @@ public enum EStuntFigure public float End { get; set; } public Stunt[] Stunts { get; set; } - public CCtnMediaBlockEventTrackMania(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x2407F000)] public class Chunk2407F000 : Chunk { diff --git a/GBX.NET/GameBoxReader.cs b/GBX.NET/GameBoxReader.cs index 807532e6d..0662b0897 100644 --- a/GBX.NET/GameBoxReader.cs +++ b/GBX.NET/GameBoxReader.cs @@ -12,6 +12,7 @@ namespace GBX.NET public class GameBoxReader : BinaryReader { public ILookbackable Lookbackable { get; } + public Chunk Chunk { get; internal set; } public GameBoxReader(Stream input) : base(input, Encoding.UTF8, true) { @@ -133,6 +134,7 @@ public T ReadNodeRef(GameBoxBody body) where T : Node if (index >= 0 && body.AuxilaryNodes.ElementAtOrDefault(index) == null) // If index is 0 or bigger and the node wasn't read yet { T node = Node.Parse(body, this); + node.ParentChunk = Chunk; if (index >= body.AuxilaryNodes.Count) body.AuxilaryNodes.Add(node); diff --git a/GBX.NET/Node.cs b/GBX.NET/Node.cs index 39fb721a7..4c5ac50a7 100644 --- a/GBX.NET/Node.cs +++ b/GBX.NET/Node.cs @@ -70,30 +70,16 @@ public uint[] ChunkIDs public static Dictionary AvailableClasses { get; } = new Dictionary(); public static Dictionary> AvailableInheritanceClasses { get; } = new Dictionary>(); - public static Dictionary> AvailableChunkClasses { get; } = new Dictionary>(); - - /// - /// - /// - /// Usually or - /// - public Node(ILookbackable lookbackable, uint classID) - { - Body = (GameBoxBody)lookbackable; - ID = classID; - } - - public Node(ILookbackable lookbackable) + public static Dictionary> AvailableChunkClasses { get; } = new Dictionary>(); + + public Node() { - Body = (GameBoxBody)lookbackable; ID = GetType().GetCustomAttribute().ID; } - public Node(Chunk chunk) + public Node(uint classID) { - ParentChunk = chunk; - Body = (GameBoxBody)chunk.Part; - ID = GetType().GetCustomAttribute().ID; + ID = classID; } static Type GetBaseType(Type t) @@ -131,7 +117,8 @@ public static T Parse(ILookbackable body, GameBoxReader r, uint? classID = nu var type = AvailableClasses[classID.Value]; - T node = (T)Activator.CreateInstance(type, body, type.GetCustomAttribute().ID); + T node = (T)Activator.CreateInstance(type); + node.Body = (GameBoxBody)r.Lookbackable; var chunks = new ChunkSet { @@ -256,24 +243,26 @@ public static T Parse(ILookbackable body, GameBoxReader r, uint? classID = nu { chunk = (IChunk)constructor.Invoke(new object[0]); chunk.Node = node; - chunk.Part = (GameBoxPart)body; - chunk.OnLoad(); } else if (constructorParams.Length == 1) - { chunk = (IChunk)constructor.Invoke(new object[] { node }); - chunk.Part = (GameBoxPart)body; - chunk.OnLoad(); - } - else throw new ArgumentException($"{type.FullName} has an invalid amount of parameters."); + else throw new ArgumentException($"{type.FullName} has an invalid amount of parameters."); + + chunk.Part = (GameBoxPart)body; + chunk.OnLoad(); + chunks.Add((Chunk)chunk); + r.Chunk = (Chunk)chunk; // Set chunk temporarily for reading + var posBefore = r.BaseStream.Position; GameBoxReaderWriter gbxrw = new GameBoxReaderWriter(r); chunk.ReadWrite(node, gbxrw); chunk.Progress = (int)(r.BaseStream.Position - posBefore); + + r.Chunk = null; } previousChunk = chunkID; diff --git a/GBX.NET/SkippableChunk.cs b/GBX.NET/SkippableChunk.cs index c85e8b7c5..49c572a8c 100644 --- a/GBX.NET/SkippableChunk.cs +++ b/GBX.NET/SkippableChunk.cs @@ -48,6 +48,8 @@ public void Discover() using (var gbxr = new GameBoxReader(Stream, Lookbackable)) { + gbxr.Chunk = this; + GameBoxReaderWriter gbxrw = new GameBoxReaderWriter(gbxr); try From aec9994db1b6946bcfb9e0e4e6cc85c6a5c03546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sat, 19 Sep 2020 15:07:35 +0200 Subject: [PATCH 22/27] Fix README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3d6bb7c5a..31353d394 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ [![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/BigBang1112/gbx-net?style=for-the-badge)](#) [![GitHub](https://img.shields.io/github/license/BigBang1112/gbx-net?style=for-the-badge)](https://github.com/BigBang1112/gbx-net/blob/master/LICENSE) -GBX.NET is a GameBox (.Gbx) file parser library written in C# for .NET software framework. This file type can be in many of the Nadeo games - TrackMania, ShootMania, Virtual Skipper... +GBX.NET is a GameBox (.Gbx) file parser library written in C# for .NET software framework. This file type can be seen in many of the Nadeo games like TrackMania, ShootMania or Virtual Skipper. -- Can recognize **entire GBX files**, however **can't read all possible files**. GBX file is basically a serialized class from the GameBox engine, and all of these classes must be known to read. This is where you can help contributing to the project, by exploring new chunks. How to do it will be documented soon. -- Can write GBX files which can be read by the parser, however this does not apply to all readable GBXs. +- GBX.NET can recognize **entire GBX files**, however **can't read all of the possible files**. GBX file is basically a serialized class from the GameBox engine, and all of these classes must be known to read. This is where you can help contributing to the project, by exploring new chunks. How to do it will be documented soon. +- GBX.NET can write GBX files which can be read by the parser, however this may not apply to all readable GBXs. - All versions of GBX are supported: ranging from TM1.0 to TM®. - Reading PAK file isn't currently supported. @@ -35,7 +35,8 @@ The library is also set to x86 assembly due to LZO compression problems in x64. To parse a GBX with a known type: ```cs -var gbx = GameBox.Parse("MyMap.Map.Gbx"); // Node data is available in gbx.MainNode +var gbx = GameBox.Parse("MyMap.Map.Gbx"); +// Node data is available in gbx.MainNode ``` To parse a GBX with an unknown type: From 57e23d91825ed18af7e90632d32de6a90c43146c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sat, 19 Sep 2020 15:43:44 +0200 Subject: [PATCH 23/27] Fix chunk writing of lookback --- GBX.NET/Engines/Game/CGameCtnChallenge.cs | 1 - GBX.NET/GameBox.cs | 716 ++++++------- GBX.NET/Node.cs | 1184 +++++++++++---------- 3 files changed, 953 insertions(+), 948 deletions(-) diff --git a/GBX.NET/Engines/Game/CGameCtnChallenge.cs b/GBX.NET/Engines/Game/CGameCtnChallenge.cs index 3c268041c..a1a1236f5 100644 --- a/GBX.NET/Engines/Game/CGameCtnChallenge.cs +++ b/GBX.NET/Engines/Game/CGameCtnChallenge.cs @@ -2121,7 +2121,6 @@ public override void Write(CGameCtnChallenge n, GameBoxWriter w, GameBoxReader u using (var itemMs = new MemoryStream()) using (var wr = new GameBoxWriter(itemMs, w.Lookbackable)) { - wr.Write(Unknown2); wr.Write(n.items.Count); diff --git a/GBX.NET/GameBox.cs b/GBX.NET/GameBox.cs index 39f64e7ea..a36d3cab4 100644 --- a/GBX.NET/GameBox.cs +++ b/GBX.NET/GameBox.cs @@ -1,66 +1,66 @@ -using System; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; - -namespace GBX.NET -{ - public class GameBox : GameBox where T : Node - { - public new Task> Header { get; private set; } - public GameBoxBody Body { get; private set; } - - public T MainNode { get; internal set; } - - public GameBox() - { - Game = ClassIDRemap.ManiaPlanet; - } - - public TChunk CreateHeaderChunk() where TChunk : HeaderChunk - { - return Header.Result.Chunks.Create(); - } - - public void RemoveAllHeaderChunks() - { - Header.Result.Chunks.Clear(); - } - - public bool RemoveHeaderChunk() where TChunk : HeaderChunk - { - return Header.Result.Chunks.RemoveWhere(x => x.ID == typeof(TChunk).GetCustomAttribute().ID) > 0; - } - - public TChunk CreateBodyChunk(byte[] data) where TChunk : Chunk - { - return MainNode.Chunks.Create(data); - } - - public TChunk CreateBodyChunk() where TChunk : Chunk - { - return CreateBodyChunk(new byte[0]); - } - - public void RemoveAllBodyChunks() - { - MainNode.Chunks.Clear(); - } - - public bool RemoveBodyChunk() where TChunk : Chunk - { - return MainNode.Chunks.Remove(); - } - - public void DiscoverAllChunks() - { - //foreach (var chunk in Header.Result.Chunks.Values) - // chunk.Discover(); - foreach (var chunk in MainNode.Chunks) - if(chunk is ISkippableChunk s) - s.Discover(); +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace GBX.NET +{ + public class GameBox : GameBox where T : Node + { + public new Task> Header { get; private set; } + public GameBoxBody Body { get; private set; } + + public T MainNode { get; internal set; } + + public GameBox() + { + Game = ClassIDRemap.ManiaPlanet; + } + + public TChunk CreateHeaderChunk() where TChunk : HeaderChunk + { + return Header.Result.Chunks.Create(); + } + + public void RemoveAllHeaderChunks() + { + Header.Result.Chunks.Clear(); + } + + public bool RemoveHeaderChunk() where TChunk : HeaderChunk + { + return Header.Result.Chunks.RemoveWhere(x => x.ID == typeof(TChunk).GetCustomAttribute().ID) > 0; + } + + public TChunk CreateBodyChunk(byte[] data) where TChunk : Chunk + { + return MainNode.Chunks.Create(data); + } + + public TChunk CreateBodyChunk() where TChunk : Chunk + { + return CreateBodyChunk(new byte[0]); + } + + public void RemoveAllBodyChunks() + { + MainNode.Chunks.Clear(); + } + + public bool RemoveBodyChunk() where TChunk : Chunk + { + return MainNode.Chunks.Remove(); + } + + public void DiscoverAllChunks() + { + //foreach (var chunk in Header.Result.Chunks.Values) + // chunk.Discover(); + foreach (var chunk in MainNode.Chunks) + if(chunk is ISkippableChunk s) + s.Discover(); } public override bool ReadHeader(GameBoxReader reader) @@ -80,107 +80,107 @@ public override bool ReadHeader(GameBoxReader reader) }); return true; - } - - public override bool Read(GameBoxReader reader) - { - // Header - - Log.Write("Reading the header..."); - - if (!ReadHeader(reader)) - return false; - + } + + public override bool Read(GameBoxReader reader) + { + // Header + + Log.Write("Reading the header..."); + + if (!ReadHeader(reader)) + return false; + // Reference table - Log.Write("Reading the reference table..."); - - ReadRefTable(reader); - - // Body - - Log.Write("Reading the body..."); - - switch (BodyCompression) - { - case 'C': - var uncompressedSize = reader.ReadInt32(); - var compressedSize = reader.ReadInt32(); - - var data = reader.ReadBytes(compressedSize); - - Body = GameBoxBody.DecompressAndConstruct(this, ClassID.GetValueOrDefault(), data, compressedSize, uncompressedSize); - break; - case 'U': - var uncompressedData = reader.ReadToEnd(); - Body = new GameBoxBody(this, ClassID.GetValueOrDefault(), uncompressedData, null, uncompressedData.Length); - break; - default: - return false; - } - - Log.Write("Body completed!"); - - return true; - } - - public void Write(GameBoxWriter w, ClassIDRemap remap) - { - (Header.Result as ILookbackable).LookbackWritten = false; - (Header.Result as ILookbackable).LookbackStrings.Clear(); - Header.Result.Write(w, Body.AuxilaryNodes.Count + 1, remap); - - if (RefTable == null) - w.Write(0); - else - RefTable.Write(w); - - (Body as ILookbackable).LookbackWritten = false; - (Body as ILookbackable).LookbackStrings.Clear(); - Body.AuxilaryNodes.Clear(); - - Body.Write(w, remap); - } - - public void Write(GameBoxWriter w) - { - Write(w, ClassIDRemap.Latest); - } - - public void Save(string fileName, ClassIDRemap remap) - { - using (var ms = new MemoryStream()) - using (var w = new GameBoxWriter(ms)) - { - Write(w, remap); - ms.Position = 0; - File.WriteAllBytes(fileName, ms.ToArray()); - } - } - - public void Save(string fileName) - { - Save(fileName, ClassIDRemap.Latest); - } - } - - public class GameBox : IGameBox - { + Log.Write("Reading the reference table..."); + + ReadRefTable(reader); + + // Body + + Log.Write("Reading the body..."); + + switch (BodyCompression) + { + case 'C': + var uncompressedSize = reader.ReadInt32(); + var compressedSize = reader.ReadInt32(); + + var data = reader.ReadBytes(compressedSize); + + Body = GameBoxBody.DecompressAndConstruct(this, ClassID.GetValueOrDefault(), data, compressedSize, uncompressedSize); + break; + case 'U': + var uncompressedData = reader.ReadToEnd(); + Body = new GameBoxBody(this, ClassID.GetValueOrDefault(), uncompressedData, null, uncompressedData.Length); + break; + default: + return false; + } + + Log.Write("Body completed!"); + + return true; + } + + public void Write(GameBoxWriter w, ClassIDRemap remap) + { + (Header.Result as ILookbackable).LookbackWritten = false; + (Header.Result as ILookbackable).LookbackStrings.Clear(); + Header.Result.Write(w, Body.AuxilaryNodes.Count + 1, remap); + + if (RefTable == null) + w.Write(0); + else + RefTable.Write(w); + + (Body as ILookbackable).LookbackWritten = false; + (Body as ILookbackable).LookbackStrings.Clear(); + Body.AuxilaryNodes.Clear(); + + Body.Write(w, remap); + } + + public void Write(GameBoxWriter w) + { + Write(w, ClassIDRemap.Latest); + } + + public void Save(string fileName, ClassIDRemap remap) + { + using (var ms = new MemoryStream()) + using (var w = new GameBoxWriter(ms)) + { + Write(w, remap); + ms.Position = 0; + File.WriteAllBytes(fileName, ms.ToArray()); + } + } + + public void Save(string fileName) + { + Save(fileName, ClassIDRemap.Latest); + } + } + + public class GameBox : IGameBox + { public ClassIDRemap Game { get; set; } - public short Version { get; set; } - public char? ByteFormat { get; set; } - public char? RefTableCompression { get; set; } - public char? BodyCompression { get; set; } - public char? UnknownByte { get; set; } - public uint? ClassID { get; internal set; } - public int? NumNodes { get; internal set; } - - public Task Header { get; private set; } - public GameBoxRefTable RefTable { get; private set; } - - public string FileName { get; set; } - + public short Version { get; set; } + public char? ByteFormat { get; set; } + public char? RefTableCompression { get; set; } + public char? BodyCompression { get; set; } + public char? UnknownByte { get; set; } + public uint? ClassID { get; internal set; } + public int? NumNodes { get; internal set; } + + public Task Header { get; private set; } + public GameBoxRefTable RefTable { get; private set; } + + public string FileName { get; set; } + public virtual bool ReadHeader(GameBoxReader reader) { var parameters = new GameBoxHeaderParameters(this); @@ -198,125 +198,125 @@ public virtual bool ReadHeader(GameBoxReader reader) }); return true; - } - + } + public bool ReadRefTable(GameBoxReader reader) - { - var numExternalNodes = reader.ReadInt32(); - - if (numExternalNodes > 0) - { - var ancestorLevel = reader.ReadInt32(); - - GameBoxRefTableFolder rootFolder = new GameBoxRefTableFolder("Root"); - - var numSubFolders = reader.ReadInt32(); - ReadRefTableFolders(numSubFolders, ref rootFolder); - - void ReadRefTableFolders(int n, ref GameBoxRefTableFolder folder) - { - for (var i = 0; i < n; i++) - { - var name = reader.ReadString(); - var numSubSubFolders = reader.ReadInt32(); - - var f = new GameBoxRefTableFolder(name, folder); - folder.Folders.Add(f); - - ReadRefTableFolders(numSubSubFolders, ref f); - } - } - - var externalNodes = new ExternalNode[numExternalNodes]; - - for (var i = 0; i < numExternalNodes; i++) - { - string fileName = null; - int? resourceIndex = null; - bool? useFile = null; - int? folderIndex = null; - - var flags = reader.ReadInt32(); - - if ((flags & 4) == 0) - fileName = reader.ReadString(); - else - resourceIndex = reader.ReadInt32(); - - var nodeIndex = reader.ReadInt32(); - - if (Version >= 5) - useFile = reader.ReadBoolean(); - - if ((flags & 4) == 0) - folderIndex = reader.ReadInt32(); - - var extNode = new ExternalNode(flags, fileName, resourceIndex, nodeIndex, useFile, folderIndex); - externalNodes[i] = extNode; - } - - var refTable = new GameBoxRefTable(rootFolder, externalNodes); - RefTable = refTable; - } - else + { + var numExternalNodes = reader.ReadInt32(); + + if (numExternalNodes > 0) + { + var ancestorLevel = reader.ReadInt32(); + + GameBoxRefTableFolder rootFolder = new GameBoxRefTableFolder("Root"); + + var numSubFolders = reader.ReadInt32(); + ReadRefTableFolders(numSubFolders, ref rootFolder); + + void ReadRefTableFolders(int n, ref GameBoxRefTableFolder folder) + { + for (var i = 0; i < n; i++) + { + var name = reader.ReadString(); + var numSubSubFolders = reader.ReadInt32(); + + var f = new GameBoxRefTableFolder(name, folder); + folder.Folders.Add(f); + + ReadRefTableFolders(numSubSubFolders, ref f); + } + } + + var externalNodes = new ExternalNode[numExternalNodes]; + + for (var i = 0; i < numExternalNodes; i++) + { + string fileName = null; + int? resourceIndex = null; + bool? useFile = null; + int? folderIndex = null; + + var flags = reader.ReadInt32(); + + if ((flags & 4) == 0) + fileName = reader.ReadString(); + else + resourceIndex = reader.ReadInt32(); + + var nodeIndex = reader.ReadInt32(); + + if (Version >= 5) + useFile = reader.ReadBoolean(); + + if ((flags & 4) == 0) + folderIndex = reader.ReadInt32(); + + var extNode = new ExternalNode(flags, fileName, resourceIndex, nodeIndex, useFile, folderIndex); + externalNodes[i] = extNode; + } + + var refTable = new GameBoxRefTable(rootFolder, externalNodes); + RefTable = refTable; + } + else Log.Write("No external nodes found, reference table completed.", ConsoleColor.Green); return true; - } - - public virtual bool Read(GameBoxReader reader) - { - return ReadHeader(reader) && ReadRefTable(reader); - } - - public bool Read(Stream stream) - { + } + + public virtual bool Read(GameBoxReader reader) + { + return ReadHeader(reader) && ReadRefTable(reader); + } + + public bool Read(Stream stream) + { using (GameBoxReader reader = new GameBoxReader(stream)) - return Read(reader); - } - - [Obsolete] - public bool Load(string fileName) - { - Log.Write($"Loading {fileName}..."); - - FileName = fileName; - - using (var fs = File.OpenRead(fileName)) - { - var success = Read(fs); - - if (success) Log.Write($"Loaded {fileName}!", ConsoleColor.Green); - else Log.Write($"File {fileName} has't loaded successfully.", ConsoleColor.Red); - - return success; - } - } - - [Obsolete] - public bool Load(string fileName, bool loadToMemory) - { - if (loadToMemory) - { - using (var ms = new MemoryStream(File.ReadAllBytes(fileName))) - return Read(ms); - } - - return Load(fileName); - } - - public static GameBox Parse(string fileName) where T : Node - { - GameBox gbx = new GameBox(); - using (var fs = File.OpenRead(fileName)) - { - gbx.FileName = fileName; - if (!gbx.Read(fs)) - return null; - } - return gbx; - } - + return Read(reader); + } + + [Obsolete] + public bool Load(string fileName) + { + Log.Write($"Loading {fileName}..."); + + FileName = fileName; + + using (var fs = File.OpenRead(fileName)) + { + var success = Read(fs); + + if (success) Log.Write($"Loaded {fileName}!", ConsoleColor.Green); + else Log.Write($"File {fileName} has't loaded successfully.", ConsoleColor.Red); + + return success; + } + } + + [Obsolete] + public bool Load(string fileName, bool loadToMemory) + { + if (loadToMemory) + { + using (var ms = new MemoryStream(File.ReadAllBytes(fileName))) + return Read(ms); + } + + return Load(fileName); + } + + public static GameBox Parse(string fileName) where T : Node + { + GameBox gbx = new GameBox(); + using (var fs = File.OpenRead(fileName)) + { + gbx.FileName = fileName; + if (!gbx.Read(fs)) + return null; + } + return gbx; + } + public static uint? ReadClassID(GameBoxReader reader) { uint? classID = null; @@ -338,102 +338,102 @@ public static GameBox Parse(string fileName) where T : Node } return classID; - } - + } + public static uint? ReadClassID(Stream stream) { using (GameBoxReader r = new GameBoxReader(stream)) return ReadClassID(r); - } - + } + public static uint? ReadClassID(string fileName) { using (var fs = File.OpenRead(fileName)) return ReadClassID(fs); - } - - public static GameBox Parse(string fileName) - { - using (var fs = File.OpenRead(fileName)) - using (var r = new GameBoxReader(fs)) + } + + public static GameBox Parse(string fileName) + { + using (var fs = File.OpenRead(fileName)) + using (var r = new GameBoxReader(fs)) { var classID = ReadClassID(r); - if (classID.HasValue) - { - var modernID = classID.GetValueOrDefault(); - if (Node.Mappings.TryGetValue(classID.GetValueOrDefault(), out uint newerClassID)) - modernID = newerClassID; - - Debug.WriteLine("Parse: " + modernID.ToString("x8")); - - Node.AvailableClasses.TryGetValue(modernID, out Type availableClass); - - GameBox gbx; - - if (availableClass == null) - gbx = new GameBox(); - else - gbx = (GameBox)Activator.CreateInstance(typeof(GameBox<>).MakeGenericType(availableClass)); - - fs.Seek(0, SeekOrigin.Begin); - - gbx.FileName = fileName; - - if (gbx.Read(fs)) - return gbx; - } - } - - Type GetBaseType(Type t) - { - if (t == null) - return null; - if (t.BaseType == typeof(Node)) - return t.BaseType; - return GetBaseType(t.BaseType); - } - - return null; - } - + if (classID.HasValue) + { + var modernID = classID.GetValueOrDefault(); + if (Node.Mappings.TryGetValue(classID.GetValueOrDefault(), out uint newerClassID)) + modernID = newerClassID; + + Debug.WriteLine("Parse: " + modernID.ToString("x8")); + + Node.AvailableClasses.TryGetValue(modernID, out Type availableClass); + + GameBox gbx; + + if (availableClass == null) + gbx = new GameBox(); + else + gbx = (GameBox)Activator.CreateInstance(typeof(GameBox<>).MakeGenericType(availableClass)); + + fs.Seek(0, SeekOrigin.Begin); + + gbx.FileName = fileName; + + if (gbx.Read(fs)) + return gbx; + } + } + + Type GetBaseType(Type t) + { + if (t == null) + return null; + if (t.BaseType == typeof(Node)) + return t.BaseType; + return GetBaseType(t.BaseType); + } + + return null; + } + public static Type GetGameBoxType(Stream stream) { using (var r = new GameBoxReader(stream)) return GetGameBoxType(r); - } - - public static Type GetGameBoxType(GameBoxReader reader) - { - var classID = ReadClassID(reader); - - if (classID.HasValue) - { - var modernID = classID.GetValueOrDefault(); - if (Node.Mappings.TryGetValue(classID.GetValueOrDefault(), out uint newerClassID)) - modernID = newerClassID; - - Debug.WriteLine("GetGameBoxType: " + modernID.ToString("x8")); - - var availableClass = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass - && x.Namespace.StartsWith("GBX.NET.Engines") && GetBaseType(x) == typeof(Node) - && x.GetCustomAttribute().ID == modernID).FirstOrDefault(); - - if (availableClass == null) return null; - - return typeof(GameBox<>).MakeGenericType(availableClass); - } - - Type GetBaseType(Type t) - { - if (t == null) - return null; - if (t.BaseType == typeof(Node)) - return t.BaseType; - return GetBaseType(t.BaseType); - } - - return null; - } - } -} + } + + public static Type GetGameBoxType(GameBoxReader reader) + { + var classID = ReadClassID(reader); + + if (classID.HasValue) + { + var modernID = classID.GetValueOrDefault(); + if (Node.Mappings.TryGetValue(classID.GetValueOrDefault(), out uint newerClassID)) + modernID = newerClassID; + + Debug.WriteLine("GetGameBoxType: " + modernID.ToString("x8")); + + var availableClass = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass + && x.Namespace.StartsWith("GBX.NET.Engines") && GetBaseType(x) == typeof(Node) + && x.GetCustomAttribute().ID == modernID).FirstOrDefault(); + + if (availableClass == null) return null; + + return typeof(GameBox<>).MakeGenericType(availableClass); + } + + Type GetBaseType(Type t) + { + if (t == null) + return null; + if (t.BaseType == typeof(Node)) + return t.BaseType; + return GetBaseType(t.BaseType); + } + + return null; + } + } +} diff --git a/GBX.NET/Node.cs b/GBX.NET/Node.cs index 4c5ac50a7..c476b6d0b 100644 --- a/GBX.NET/Node.cs +++ b/GBX.NET/Node.cs @@ -1,595 +1,601 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.Serialization; - -namespace GBX.NET -{ - public class Node - { - public static Dictionary Names { get; } - public static Dictionary Mappings { get; } // key: older, value: newer - - [IgnoreDataMember] - public GameBoxBody Body { get; set; } - [IgnoreDataMember] - public GameBox GBX => Body?.GBX; - - public ChunkSet Chunks { get; internal set; } - - /// - /// Chunk where the aux node appeared - /// - public Chunk ParentChunk { get; set; } - - public uint ID { get; } - public uint? FaultyChunk { get; private set; } - public byte[] Rest { get; private set; } - public bool Unknown { get; internal set; } - - public uint ModernID - { - get - { - if (Mappings.TryGetValue(ID, out uint newerClassID)) - return newerClassID; - return ID; - } - } - - public string ClassName - { - get - { - if (Names.TryGetValue(ModernID, out string name)) - return name; - return GetType().FullName.Substring("GBX.NET.Engines".Length+1).Replace(".", "::"); - } - } - - [IgnoreDataMember] - public uint[] ChunkIDs - { - get - { - var chunkTypes = GetType().GetNestedTypes().Where(x => x.BaseType == typeof(Chunk)).ToArray(); - var array = new uint[chunkTypes.Length]; - - for(var i = 0; i < array.Length; i++) - { - var att = chunkTypes[i].GetCustomAttribute(); - array[i] = att.ClassID + att.ChunkID; - } - - return array; - } - } - - public static Dictionary AvailableClasses { get; } = new Dictionary(); - public static Dictionary> AvailableInheritanceClasses { get; } = new Dictionary>(); +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization; + +namespace GBX.NET +{ + public class Node + { + public static Dictionary Names { get; } + public static Dictionary Mappings { get; } // key: older, value: newer + + [IgnoreDataMember] + public GameBoxBody Body { get; set; } + [IgnoreDataMember] + public GameBox GBX => Body?.GBX; + + public ChunkSet Chunks { get; internal set; } + + /// + /// Chunk where the aux node appeared + /// + public Chunk ParentChunk { get; set; } + + public uint ID { get; } + public uint? FaultyChunk { get; private set; } + public byte[] Rest { get; private set; } + public bool Unknown { get; internal set; } + + public uint ModernID + { + get + { + if (Mappings.TryGetValue(ID, out uint newerClassID)) + return newerClassID; + return ID; + } + } + + public string ClassName + { + get + { + if (Names.TryGetValue(ModernID, out string name)) + return name; + return GetType().FullName.Substring("GBX.NET.Engines".Length+1).Replace(".", "::"); + } + } + + [IgnoreDataMember] + public uint[] ChunkIDs + { + get + { + var chunkTypes = GetType().GetNestedTypes().Where(x => x.BaseType == typeof(Chunk)).ToArray(); + var array = new uint[chunkTypes.Length]; + + for(var i = 0; i < array.Length; i++) + { + var att = chunkTypes[i].GetCustomAttribute(); + array[i] = att.ClassID + att.ChunkID; + } + + return array; + } + } + + public static Dictionary AvailableClasses { get; } = new Dictionary(); + public static Dictionary> AvailableInheritanceClasses { get; } = new Dictionary>(); public static Dictionary> AvailableChunkClasses { get; } = new Dictionary>(); - public Node() - { - ID = GetType().GetCustomAttribute().ID; - } - - public Node(uint classID) - { - ID = classID; - } - - static Type GetBaseType(Type t) - { - if (t == null) - return null; - if (t.BaseType == typeof(Node)) - return t.BaseType; - return GetBaseType(t.BaseType); - } - - public static T[] ParseArray(ILookbackable body, GameBoxReader r) where T : Node - { - var count = r.ReadInt32(); - var array = new T[count]; - - for (var i = 0; i < count; i++) - { - _ = r.ReadUInt32(); - - array[i] = Parse(body, r); - } - - return array; - } - - public static T Parse(ILookbackable body, GameBoxReader r, uint? classID = null) where T : Node - { - var readNodeStart = DateTime.Now; - - if (classID == null) - classID = r.ReadUInt32(); - if (Mappings.TryGetValue(classID.Value, out uint newerClassID)) - classID = newerClassID; - - var type = AvailableClasses[classID.Value]; - + public Node() + { + ID = GetType().GetCustomAttribute().ID; + } + + public Node(uint classID) + { + ID = classID; + } + + static Type GetBaseType(Type t) + { + if (t == null) + return null; + if (t.BaseType == typeof(Node)) + return t.BaseType; + return GetBaseType(t.BaseType); + } + + public static T[] ParseArray(ILookbackable body, GameBoxReader r) where T : Node + { + var count = r.ReadInt32(); + var array = new T[count]; + + for (var i = 0; i < count; i++) + { + _ = r.ReadUInt32(); + + array[i] = Parse(body, r); + } + + return array; + } + + public static T Parse(ILookbackable body, GameBoxReader r, uint? classID = null) where T : Node + { + var readNodeStart = DateTime.Now; + + if (classID == null) + classID = r.ReadUInt32(); + if (Mappings.TryGetValue(classID.Value, out uint newerClassID)) + classID = newerClassID; + + var type = AvailableClasses[classID.Value]; + T node = (T)Activator.CreateInstance(type); - node.Body = (GameBoxBody)r.Lookbackable; - - var chunks = new ChunkSet - { - Node = node - }; - - uint? previousChunk = null; - - while (true) - { - var chunkID = r.ReadUInt32(); - - if (chunkID == 0xFACADE01) // no more chunks - { - break; - } - else if(chunkID == 0) - { - // weird case after ending node reference - } - else - { - if (node.Body != null && node.Body.GBX.ClassID.HasValue && Remap(node.Body.GBX.ClassID.Value) == node.ID) - Log.Write($"[{node.ClassName}] 0x{chunkID:x8} ({(float)r.BaseStream.Position / r.BaseStream.Length:0.00%})"); - else - Log.Write($"~ [{node.ClassName}] 0x{chunkID:x8} ({(float)r.BaseStream.Position / r.BaseStream.Length:0.00%})"); - } - - Type chunkClass = null; - - var reflected = ((Chunk.Remap(chunkID) & 0xFFFFF000) == node.ID || AvailableInheritanceClasses[type].Contains(Chunk.Remap(chunkID) & 0xFFFFF000)) - && (AvailableChunkClasses[type].TryGetValue(chunkID, out chunkClass) || AvailableChunkClasses[type].TryGetValue(chunkID & 0xFFF, out chunkClass)); - - var skippable = reflected && chunkClass.BaseType.GetGenericTypeDefinition() == typeof(SkippableChunk<>); - - if (!reflected || skippable) - { - var skip = r.ReadUInt32(); - - if (skip != 0x534B4950) - { - if (chunkID != 0 && !reflected) - { - Debug.WriteLine($"Wrong chunk format or unskippable chunk: {chunkID:x8} ({Names.Where(x => x.Key == Chunk.Remap(chunkID&0xFFFFF000)).Select(x => x.Value).FirstOrDefault() ?? "unknown class"})"); // Read till facade - node.FaultyChunk = chunkID; - - if (node.Body != null && node.Body.GBX.ClassID.HasValue && Remap(node.Body.GBX.ClassID.Value) == node.ID) - Log.Write($"[{node.ClassName}] 0x{chunkID:x8} ERROR (wrong chunk format or unknown unskippable chunk)", ConsoleColor.Red); - else - Log.Write($"~ [{node.ClassName}] 0x{chunkID:x8} ERROR (wrong chunk format or unknown unskippable chunk)", ConsoleColor.Red); - - var buffer = BitConverter.GetBytes(chunkID); - using (var restMs = new MemoryStream(ushort.MaxValue)) - { - restMs.Write(buffer, 0, buffer.Length); - - while (r.PeekUInt32() != 0xFACADE01) - restMs.WriteByte(r.ReadByte()); - - node.Rest = restMs.ToArray(); - } - Debug.WriteLine("FACADE found."); - } - break; - } - - Debug.WriteLine("Skippable chunk: " + chunkID.ToString("x")); - - var chunkDataSize = r.ReadInt32(); - Debug.WriteLine("Chunk size: " + chunkDataSize); - var chunkData = new byte[chunkDataSize]; - if (chunkDataSize > 0) - r.Read(chunkData, 0, chunkDataSize); - - if (reflected && chunkClass.GetCustomAttribute() == null) - { - ISkippableChunk c; - - var constructor = chunkClass.GetConstructors().First(); - var constructorParams = constructor.GetParameters(); - if (constructorParams.Length == 0) - { - c = (ISkippableChunk)constructor.Invoke(new object[0]); - c.Node = node; - c.Part = (GameBoxPart)body; - c.Stream = new MemoryStream(chunkData, 0, chunkData.Length, false); - if (chunkData == null || chunkData.Length == 0) - c.Discovered = true; - c.OnLoad(); - } - else if (constructorParams.Length == 2) - c = (ISkippableChunk)constructor.Invoke(new object[] { node, chunkData }); - else throw new ArgumentException($"{type.FullName} has an invalid amount of parameters."); - - chunks.Add((Chunk)c); - - if (chunkClass.GetCustomAttribute().ProcessSync) - c.Discover(); - } - else - { - Debug.WriteLine("Unknown skippable chunk: " + chunkID.ToString("x")); - chunks.Add((Chunk)Activator.CreateInstance(typeof(SkippableChunk<>).MakeGenericType(type), node, chunkID, chunkData)); - } - } - - if (reflected && !skippable) - { - Debug.WriteLine("Unskippable chunk: " + chunkID.ToString("x8")); - - if (skippable) // Does it ever happen? - { - var skip = r.ReadUInt32(); - var chunkDataSize = r.ReadInt32(); - } - - IChunk chunk; - - var constructor = chunkClass.GetConstructors().First(); - var constructorParams = constructor.GetParameters(); - if (constructorParams.Length == 0) - { - chunk = (IChunk)constructor.Invoke(new object[0]); - chunk.Node = node; - } - else if (constructorParams.Length == 1) - chunk = (IChunk)constructor.Invoke(new object[] { node }); + node.Body = (GameBoxBody)r.Lookbackable; + + var chunks = new ChunkSet + { + Node = node + }; + + uint? previousChunk = null; + + while (true) + { + var chunkID = r.ReadUInt32(); + + if (chunkID == 0xFACADE01) // no more chunks + { + break; + } + else if(chunkID == 0) + { + // weird case after ending node reference + } + else + { + if (node.Body != null && node.Body.GBX.ClassID.HasValue && Remap(node.Body.GBX.ClassID.Value) == node.ID) + Log.Write($"[{node.ClassName}] 0x{chunkID:x8} ({(float)r.BaseStream.Position / r.BaseStream.Length:0.00%})"); + else + Log.Write($"~ [{node.ClassName}] 0x{chunkID:x8} ({(float)r.BaseStream.Position / r.BaseStream.Length:0.00%})"); + } + + Type chunkClass = null; + + var reflected = ((Chunk.Remap(chunkID) & 0xFFFFF000) == node.ID || AvailableInheritanceClasses[type].Contains(Chunk.Remap(chunkID) & 0xFFFFF000)) + && (AvailableChunkClasses[type].TryGetValue(chunkID, out chunkClass) || AvailableChunkClasses[type].TryGetValue(chunkID & 0xFFF, out chunkClass)); + + var skippable = reflected && chunkClass.BaseType.GetGenericTypeDefinition() == typeof(SkippableChunk<>); + + if (!reflected || skippable) + { + var skip = r.ReadUInt32(); + + if (skip != 0x534B4950) + { + if (chunkID != 0 && !reflected) + { + Debug.WriteLine($"Wrong chunk format or unskippable chunk: {chunkID:x8} ({Names.Where(x => x.Key == Chunk.Remap(chunkID&0xFFFFF000)).Select(x => x.Value).FirstOrDefault() ?? "unknown class"})"); // Read till facade + node.FaultyChunk = chunkID; + + if (node.Body != null && node.Body.GBX.ClassID.HasValue && Remap(node.Body.GBX.ClassID.Value) == node.ID) + Log.Write($"[{node.ClassName}] 0x{chunkID:x8} ERROR (wrong chunk format or unknown unskippable chunk)", ConsoleColor.Red); + else + Log.Write($"~ [{node.ClassName}] 0x{chunkID:x8} ERROR (wrong chunk format or unknown unskippable chunk)", ConsoleColor.Red); + + var buffer = BitConverter.GetBytes(chunkID); + using (var restMs = new MemoryStream(ushort.MaxValue)) + { + restMs.Write(buffer, 0, buffer.Length); + + while (r.PeekUInt32() != 0xFACADE01) + restMs.WriteByte(r.ReadByte()); + + node.Rest = restMs.ToArray(); + } + Debug.WriteLine("FACADE found."); + } + break; + } + + Debug.WriteLine("Skippable chunk: " + chunkID.ToString("x")); + + var chunkDataSize = r.ReadInt32(); + Debug.WriteLine("Chunk size: " + chunkDataSize); + var chunkData = new byte[chunkDataSize]; + if (chunkDataSize > 0) + r.Read(chunkData, 0, chunkDataSize); + + if (reflected && chunkClass.GetCustomAttribute() == null) + { + ISkippableChunk c; + + var constructor = chunkClass.GetConstructors().First(); + var constructorParams = constructor.GetParameters(); + if (constructorParams.Length == 0) + { + c = (ISkippableChunk)constructor.Invoke(new object[0]); + c.Node = node; + c.Part = (GameBoxPart)body; + c.Stream = new MemoryStream(chunkData, 0, chunkData.Length, false); + if (chunkData == null || chunkData.Length == 0) + c.Discovered = true; + c.OnLoad(); + } + else if (constructorParams.Length == 2) + c = (ISkippableChunk)constructor.Invoke(new object[] { node, chunkData }); + else throw new ArgumentException($"{type.FullName} has an invalid amount of parameters."); + + chunks.Add((Chunk)c); + + if (chunkClass.GetCustomAttribute().ProcessSync) + c.Discover(); + } + else + { + Debug.WriteLine("Unknown skippable chunk: " + chunkID.ToString("x")); + chunks.Add((Chunk)Activator.CreateInstance(typeof(SkippableChunk<>).MakeGenericType(type), node, chunkID, chunkData)); + } + } + + if (reflected && !skippable) + { + Debug.WriteLine("Unskippable chunk: " + chunkID.ToString("x8")); + + if (skippable) // Does it ever happen? + { + var skip = r.ReadUInt32(); + var chunkDataSize = r.ReadInt32(); + } + + IChunk chunk; + + var constructor = chunkClass.GetConstructors().First(); + var constructorParams = constructor.GetParameters(); + if (constructorParams.Length == 0) + { + chunk = (IChunk)constructor.Invoke(new object[0]); + chunk.Node = node; + } + else if (constructorParams.Length == 1) + chunk = (IChunk)constructor.Invoke(new object[] { node }); else throw new ArgumentException($"{type.FullName} has an invalid amount of parameters."); chunk.Part = (GameBoxPart)body; - chunk.OnLoad(); - - chunks.Add((Chunk)chunk); - - r.Chunk = (Chunk)chunk; // Set chunk temporarily for reading - - var posBefore = r.BaseStream.Position; - - GameBoxReaderWriter gbxrw = new GameBoxReaderWriter(r); - chunk.ReadWrite(node, gbxrw); - - chunk.Progress = (int)(r.BaseStream.Position - posBefore); - - r.Chunk = null; - } - - previousChunk = chunkID; - } - - if (node.Body != null && node.Body.GBX.ClassID.HasValue && Remap(node.Body.GBX.ClassID.Value) == node.ID) - Log.Write($"[{node.ClassName}] DONE! ({(DateTime.Now - readNodeStart).TotalMilliseconds}ms)", ConsoleColor.Green); - else - Log.Write($"~ [{node.ClassName}] DONE! ({(DateTime.Now - readNodeStart).TotalMilliseconds}ms)", ConsoleColor.Green); - - node.Chunks = chunks; - - return node; - } - - public void Read(GameBoxReader r) - { - throw new NotImplementedException($"Node doesn't support Read."); - } - - public void Write(GameBoxWriter w) - { - Write(w, ClassIDRemap.Latest); - } - - public void Write(GameBoxWriter w, ClassIDRemap remap) - { - int counter = 0; - - foreach (dynamic chunk in Chunks) - { - counter += 1; - - chunk.Unknown.Position = 0; - - ILookbackable lb = chunk.Lookbackable; - - if (chunk is ILookbackable l) - { - l.LookbackWritten = false; - l.LookbackStrings.Clear(); - - lb = l; - } - - if (lb == null && ParentChunk is ILookbackable l2) - lb = l2; - - using (var ms = new MemoryStream()) - using (var msW = new GameBoxWriter(ms, lb)) - { - var rw = new GameBoxReaderWriter(msW); - - try - { - if (chunk is ISkippableChunk s && !s.Discovered) - s.Write(msW); - else - chunk.ReadWrite((dynamic)this, rw); - - w.Write(Chunk.Remap(chunk.ID, remap)); - - if (chunk is ISkippableChunk) - { - w.Write(0x534B4950); - w.Write((int)ms.Length); - } - - w.Write(ms.ToArray(), 0, (int)ms.Length); - } - catch (NotImplementedException e) - { - if (chunk is ISkippableChunk) - { - Debug.WriteLine(e.Message); - Debug.WriteLine("Ignoring the skippable chunk from writing."); - } - else throw e; // Unskippable chunk must have a Write implementation - } - } - } - - w.Write(0xFACADE01); - } - - static Node() - { - Names = new Dictionary(); - Mappings = new Dictionary(); - - var startTimestamp = DateTime.Now; - - using (StringReader reader = new StringReader(Resources.ClassID)) - { - var en = ""; - var engineName = ""; - - string line; - while ((line = reader.ReadLine()) != null) - { - var ch = "000"; - - var className = ""; - - if (line.StartsWith(" ")) - { - var cl = line.Substring(2, 3); - if (line.Length - 6 > 0) className = line.Substring(6); - - var classIDString = $"{en}{cl}{ch}"; - - if (uint.TryParse(classIDString, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out uint classID)) - { - Names[classID] = engineName + "::" + className; - } - else - { - Debug.WriteLine($"Invalid class ID {classIDString}, skipping"); - } - } - else - { - en = line.Substring(0, 2); - if (line.Length - 3 > 0) engineName = line.Substring(3); - } - } - } - - Debug.WriteLine("Classes named in " + (DateTime.Now - startTimestamp).TotalMilliseconds + "ms"); - - startTimestamp = DateTime.Now; - - using (StringReader reader = new StringReader(Resources.ClassIDMappings)) - { - string line; - while ((line = reader.ReadLine()) != null) - { - var valueKey = line.Split(new string[] { " -> " }, StringSplitOptions.None); - if (valueKey.Length == 2) - { - if (uint.TryParse(valueKey[0], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out uint key) - && uint.TryParse(valueKey[1], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out uint value)) - { - if (Mappings.ContainsValue(key)) // Virtual Skipper solution - Mappings[Mappings.FirstOrDefault(x => x.Value == key).Key] = value; - Mappings[key] = value; - } - } - } - } - - Debug.WriteLine("Mappings defined in " + (DateTime.Now - startTimestamp).TotalMilliseconds + "ms"); - - startTimestamp = DateTime.Now; - - foreach (var nodeType in Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass - && x.Namespace.StartsWith("GBX.NET.Engines") && GetBaseType(x) == typeof(Node))) - { - var nodeID = nodeType.GetCustomAttribute().ID; - - AvailableClasses.Add(nodeID, nodeType); - - var inheritanceClasses = GetInheritance(nodeType); - AvailableInheritanceClasses[nodeType] = inheritanceClasses; - - List GetInheritance(Type t) - { - List classes = new List(); - - Type cur = t.BaseType; - - while (cur != typeof(Node)) - { - classes.Add(cur.GetCustomAttribute().ID); - cur = cur.BaseType; - } - - return classes; - } - - var chunkType = typeof(Chunk<>).MakeGenericType(nodeType); - var skippableChunkType = typeof(SkippableChunk<>).MakeGenericType(nodeType); - - if (!AvailableChunkClasses.TryGetValue(nodeType, out Dictionary availableChunkClasses)) - { - availableChunkClasses = nodeType.GetNestedTypes().Where(x => - { - var isChunk = x.IsClass - && x.Namespace.StartsWith("GBX.NET.Engines") - && (x.BaseType == chunkType || x.BaseType == skippableChunkType); - if (!isChunk) return false; - - var chunkAttribute = x.GetCustomAttribute(); - if (chunkAttribute == null) throw new Exception($"Chunk {x.FullName} doesn't have a ChunkAttribute."); - - var attributesMet = chunkAttribute.ClassID == nodeID; - return isChunk && attributesMet; - }).ToDictionary(x => x.GetCustomAttribute().ChunkID); - - foreach (var cls in inheritanceClasses) - { - var availableInheritanceClass = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass - && x.Namespace.StartsWith("GBX.NET.Engines") && (GetBaseType(x) == typeof(Node)) - && (x.GetCustomAttribute().ID == cls)).FirstOrDefault(); - - var inheritChunkType = typeof(Chunk<>).MakeGenericType(availableInheritanceClass); - var inheritSkippableChunkType = typeof(SkippableChunk<>).MakeGenericType(availableInheritanceClass); - - foreach (var chunkT in availableInheritanceClass.GetNestedTypes().Where(x => x.IsClass - && x.Namespace.StartsWith("GBX.NET.Engines") && (x.BaseType == inheritChunkType || x.BaseType == inheritSkippableChunkType) - && (x.GetCustomAttribute().ClassID == cls)).ToDictionary(x => x.GetCustomAttribute().ChunkID)) - { - availableChunkClasses[chunkT.Key + cls] = chunkT.Value; - } - } - AvailableChunkClasses.Add(nodeType, availableChunkClasses); - } - } - - Debug.WriteLine("Types defined in " + (DateTime.Now - startTimestamp).TotalMilliseconds + "ms"); - } - - public T GetChunk() where T : Chunk - { - return Chunks.Get(); - } - - public T CreateChunk() where T : Chunk - { - return Chunks.Create(); - } - - public bool RemoveChunk() where T : Chunk - { - return Chunks.Remove(); - } - - public bool TryGetChunk(out T chunk) where T : Chunk - { - return Chunks.TryGet(out chunk); - } - - public void DiscoverChunk() where T : ISkippableChunk - { - Chunks.Discover(); - } - - public void DiscoverChunks() where T1 : ISkippableChunk where T2 : ISkippableChunk - { - Chunks.Discover(); - } - - public void DiscoverChunks() where T1 : ISkippableChunk where T2 : ISkippableChunk where T3 : ISkippableChunk - { - if (Chunks != null) - Chunks.Discover(); - else - ((dynamic)Body).DiscoverChunks(); - } - - public void DiscoverChunks() - where T1 : ISkippableChunk - where T2 : ISkippableChunk - where T3 : ISkippableChunk - where T4 : ISkippableChunk - { - Chunks.Discover(); - } - - public void DiscoverChunks() - where T1 : ISkippableChunk - where T2 : ISkippableChunk - where T3 : ISkippableChunk - where T4 : ISkippableChunk - where T5 : ISkippableChunk - { - Chunks.Discover(); - } - - public void DiscoverChunks() - where T1 : ISkippableChunk - where T2 : ISkippableChunk - where T3 : ISkippableChunk - where T4 : ISkippableChunk - where T5 : ISkippableChunk - where T6 : ISkippableChunk - { - Chunks.Discover(); - } - - public void DiscoverAllChunks() - { - if (Chunks != null) - Chunks.DiscoverAll(); - else - ((dynamic)Body).DiscoverAllChunks(); - } - - public static uint Remap(uint id) - { - if (Mappings.TryGetValue(id, out uint newerClassID)) - return newerClassID; - return id; - } - - public static T FromGBX(GameBox loadedGbx) where T : Node - { - return loadedGbx.MainNode; - } - - public static T FromGBX(string gbxFile) where T : Node - { - using (var fs = File.OpenRead(gbxFile)) - { - var type = GameBox.GetGameBoxType(fs); - fs.Seek(0, SeekOrigin.Begin); - - GameBox gbx; - if (type == null) - gbx = new GameBox(); - else - gbx = (GameBox)Activator.CreateInstance(type); - - if (gbx.Read(fs)) - return FromGBX((GameBox)gbx); - return default; - } - } - } -} + chunk.OnLoad(); + + chunks.Add((Chunk)chunk); + + r.Chunk = (Chunk)chunk; // Set chunk temporarily for reading + + var posBefore = r.BaseStream.Position; + + GameBoxReaderWriter gbxrw = new GameBoxReaderWriter(r); + chunk.ReadWrite(node, gbxrw); + + chunk.Progress = (int)(r.BaseStream.Position - posBefore); + + r.Chunk = null; + } + + previousChunk = chunkID; + } + + if (node.Body != null && node.Body.GBX.ClassID.HasValue && Remap(node.Body.GBX.ClassID.Value) == node.ID) + Log.Write($"[{node.ClassName}] DONE! ({(DateTime.Now - readNodeStart).TotalMilliseconds}ms)", ConsoleColor.Green); + else + Log.Write($"~ [{node.ClassName}] DONE! ({(DateTime.Now - readNodeStart).TotalMilliseconds}ms)", ConsoleColor.Green); + + node.Chunks = chunks; + + return node; + } + + public void Read(GameBoxReader r) + { + throw new NotImplementedException($"Node doesn't support Read."); + } + + public void Write(GameBoxWriter w) + { + Write(w, ClassIDRemap.Latest); + } + + public void Write(GameBoxWriter w, ClassIDRemap remap) + { + int counter = 0; + + foreach (dynamic chunk in Chunks) + { + counter += 1; + + ((IChunk)chunk).Node = this; + chunk.Unknown.Position = 0; + + ILookbackable lb = chunk.Lookbackable; + + if (chunk is ILookbackable l) + { + l.LookbackWritten = false; + l.LookbackStrings.Clear(); + + lb = l; + } + + if (lb == null) + { + if(ParentChunk is ILookbackable l2) + lb = l2; + else + lb = w.Lookbackable; + } + + using (var ms = new MemoryStream()) + using (var msW = new GameBoxWriter(ms, lb)) + { + var rw = new GameBoxReaderWriter(msW); + + try + { + if (chunk is ISkippableChunk s && !s.Discovered) + s.Write(msW); + else + chunk.ReadWrite((dynamic)this, rw); + + w.Write(Chunk.Remap(chunk.ID, remap)); + + if (chunk is ISkippableChunk) + { + w.Write(0x534B4950); + w.Write((int)ms.Length); + } + + w.Write(ms.ToArray(), 0, (int)ms.Length); + } + catch (NotImplementedException e) + { + if (chunk is ISkippableChunk) + { + Debug.WriteLine(e.Message); + Debug.WriteLine("Ignoring the skippable chunk from writing."); + } + else throw e; // Unskippable chunk must have a Write implementation + } + } + } + + w.Write(0xFACADE01); + } + + static Node() + { + Names = new Dictionary(); + Mappings = new Dictionary(); + + var startTimestamp = DateTime.Now; + + using (StringReader reader = new StringReader(Resources.ClassID)) + { + var en = ""; + var engineName = ""; + + string line; + while ((line = reader.ReadLine()) != null) + { + var ch = "000"; + + var className = ""; + + if (line.StartsWith(" ")) + { + var cl = line.Substring(2, 3); + if (line.Length - 6 > 0) className = line.Substring(6); + + var classIDString = $"{en}{cl}{ch}"; + + if (uint.TryParse(classIDString, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out uint classID)) + { + Names[classID] = engineName + "::" + className; + } + else + { + Debug.WriteLine($"Invalid class ID {classIDString}, skipping"); + } + } + else + { + en = line.Substring(0, 2); + if (line.Length - 3 > 0) engineName = line.Substring(3); + } + } + } + + Debug.WriteLine("Classes named in " + (DateTime.Now - startTimestamp).TotalMilliseconds + "ms"); + + startTimestamp = DateTime.Now; + + using (StringReader reader = new StringReader(Resources.ClassIDMappings)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + var valueKey = line.Split(new string[] { " -> " }, StringSplitOptions.None); + if (valueKey.Length == 2) + { + if (uint.TryParse(valueKey[0], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out uint key) + && uint.TryParse(valueKey[1], System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out uint value)) + { + if (Mappings.ContainsValue(key)) // Virtual Skipper solution + Mappings[Mappings.FirstOrDefault(x => x.Value == key).Key] = value; + Mappings[key] = value; + } + } + } + } + + Debug.WriteLine("Mappings defined in " + (DateTime.Now - startTimestamp).TotalMilliseconds + "ms"); + + startTimestamp = DateTime.Now; + + foreach (var nodeType in Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass + && x.Namespace.StartsWith("GBX.NET.Engines") && GetBaseType(x) == typeof(Node))) + { + var nodeID = nodeType.GetCustomAttribute().ID; + + AvailableClasses.Add(nodeID, nodeType); + + var inheritanceClasses = GetInheritance(nodeType); + AvailableInheritanceClasses[nodeType] = inheritanceClasses; + + List GetInheritance(Type t) + { + List classes = new List(); + + Type cur = t.BaseType; + + while (cur != typeof(Node)) + { + classes.Add(cur.GetCustomAttribute().ID); + cur = cur.BaseType; + } + + return classes; + } + + var chunkType = typeof(Chunk<>).MakeGenericType(nodeType); + var skippableChunkType = typeof(SkippableChunk<>).MakeGenericType(nodeType); + + if (!AvailableChunkClasses.TryGetValue(nodeType, out Dictionary availableChunkClasses)) + { + availableChunkClasses = nodeType.GetNestedTypes().Where(x => + { + var isChunk = x.IsClass + && x.Namespace.StartsWith("GBX.NET.Engines") + && (x.BaseType == chunkType || x.BaseType == skippableChunkType); + if (!isChunk) return false; + + var chunkAttribute = x.GetCustomAttribute(); + if (chunkAttribute == null) throw new Exception($"Chunk {x.FullName} doesn't have a ChunkAttribute."); + + var attributesMet = chunkAttribute.ClassID == nodeID; + return isChunk && attributesMet; + }).ToDictionary(x => x.GetCustomAttribute().ChunkID); + + foreach (var cls in inheritanceClasses) + { + var availableInheritanceClass = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.IsClass + && x.Namespace.StartsWith("GBX.NET.Engines") && (GetBaseType(x) == typeof(Node)) + && (x.GetCustomAttribute().ID == cls)).FirstOrDefault(); + + var inheritChunkType = typeof(Chunk<>).MakeGenericType(availableInheritanceClass); + var inheritSkippableChunkType = typeof(SkippableChunk<>).MakeGenericType(availableInheritanceClass); + + foreach (var chunkT in availableInheritanceClass.GetNestedTypes().Where(x => x.IsClass + && x.Namespace.StartsWith("GBX.NET.Engines") && (x.BaseType == inheritChunkType || x.BaseType == inheritSkippableChunkType) + && (x.GetCustomAttribute().ClassID == cls)).ToDictionary(x => x.GetCustomAttribute().ChunkID)) + { + availableChunkClasses[chunkT.Key + cls] = chunkT.Value; + } + } + AvailableChunkClasses.Add(nodeType, availableChunkClasses); + } + } + + Debug.WriteLine("Types defined in " + (DateTime.Now - startTimestamp).TotalMilliseconds + "ms"); + } + + public T GetChunk() where T : Chunk + { + return Chunks.Get(); + } + + public T CreateChunk() where T : Chunk + { + return Chunks.Create(); + } + + public bool RemoveChunk() where T : Chunk + { + return Chunks.Remove(); + } + + public bool TryGetChunk(out T chunk) where T : Chunk + { + return Chunks.TryGet(out chunk); + } + + public void DiscoverChunk() where T : ISkippableChunk + { + Chunks.Discover(); + } + + public void DiscoverChunks() where T1 : ISkippableChunk where T2 : ISkippableChunk + { + Chunks.Discover(); + } + + public void DiscoverChunks() where T1 : ISkippableChunk where T2 : ISkippableChunk where T3 : ISkippableChunk + { + if (Chunks != null) + Chunks.Discover(); + else + ((dynamic)Body).DiscoverChunks(); + } + + public void DiscoverChunks() + where T1 : ISkippableChunk + where T2 : ISkippableChunk + where T3 : ISkippableChunk + where T4 : ISkippableChunk + { + Chunks.Discover(); + } + + public void DiscoverChunks() + where T1 : ISkippableChunk + where T2 : ISkippableChunk + where T3 : ISkippableChunk + where T4 : ISkippableChunk + where T5 : ISkippableChunk + { + Chunks.Discover(); + } + + public void DiscoverChunks() + where T1 : ISkippableChunk + where T2 : ISkippableChunk + where T3 : ISkippableChunk + where T4 : ISkippableChunk + where T5 : ISkippableChunk + where T6 : ISkippableChunk + { + Chunks.Discover(); + } + + public void DiscoverAllChunks() + { + if (Chunks != null) + Chunks.DiscoverAll(); + else + ((dynamic)Body).DiscoverAllChunks(); + } + + public static uint Remap(uint id) + { + if (Mappings.TryGetValue(id, out uint newerClassID)) + return newerClassID; + return id; + } + + public static T FromGBX(GameBox loadedGbx) where T : Node + { + return loadedGbx.MainNode; + } + + public static T FromGBX(string gbxFile) where T : Node + { + using (var fs = File.OpenRead(gbxFile)) + { + var type = GameBox.GetGameBoxType(fs); + fs.Seek(0, SeekOrigin.Begin); + + GameBox gbx; + if (type == null) + gbx = new GameBox(); + else + gbx = (GameBox)Activator.CreateInstance(type); + + if (gbx.Read(fs)) + return FromGBX((GameBox)gbx); + return default; + } + } + } +} From 02cd8b279122aaf7413aac7f7db97ee9745de953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sat, 19 Sep 2020 16:32:57 +0200 Subject: [PATCH 24/27] Fixes --- .../CCtnMediaBlockEventTrackMania.cs | 19 ----------- IslandConverter/ConverterForm.Designer.cs | 33 +++++++++---------- 2 files changed, 16 insertions(+), 36 deletions(-) diff --git a/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs b/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs index 842e31f55..5a20956d5 100644 --- a/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs +++ b/GBX.NET/Engines/TrackMania/CCtnMediaBlockEventTrackMania.cs @@ -48,36 +48,17 @@ public enum EStuntFigure RespawnPenalty, Grind, Reset -<<<<<<< HEAD - } - - public float Start { get; set; } - public float End { get; set; } - public Stunt[] Stunts { get; set; } - - [Chunk(0x2407F000)] - public class Chunk2407F000 : Chunk - { - public int U01 { get; set; } - -======= } public float Start { get; set; } public float End { get; set; } public Stunt[] Stunts { get; set; } - public CCtnMediaBlockEventTrackMania(ILookbackable lookbackable, uint classID) : base(lookbackable, classID) - { - - } - [Chunk(0x2407F000)] public class Chunk2407F000 : Chunk { public int U01 { get; set; } ->>>>>>> e498fde4a097e9f2e23e4118dcf01c81d61542cb public override void ReadWrite(CCtnMediaBlockEventTrackMania n, GameBoxReaderWriter rw) { n.Start = rw.Single(n.Start); diff --git a/IslandConverter/ConverterForm.Designer.cs b/IslandConverter/ConverterForm.Designer.cs index 974b721bf..92c6d3215 100644 --- a/IslandConverter/ConverterForm.Designer.cs +++ b/IslandConverter/ConverterForm.Designer.cs @@ -97,7 +97,7 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.pbThumbnail.Location = new System.Drawing.Point(7, 221); this.pbThumbnail.Name = "pbThumbnail"; - this.pbThumbnail.Size = new System.Drawing.Size(210, 206); + this.pbThumbnail.Size = new System.Drawing.Size(209, 206); this.pbThumbnail.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage; this.pbThumbnail.TabIndex = 1; this.pbThumbnail.TabStop = false; @@ -109,7 +109,7 @@ private void InitializeComponent() this.bConvertAll.Enabled = false; this.bConvertAll.FlatStyle = System.Windows.Forms.FlatStyle.System; this.bConvertAll.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold); - this.bConvertAll.Location = new System.Drawing.Point(424, 264); + this.bConvertAll.Location = new System.Drawing.Point(523, 264); this.bConvertAll.Name = "bConvertAll"; this.bConvertAll.Size = new System.Drawing.Size(161, 34); this.bConvertAll.TabIndex = 2; @@ -137,9 +137,9 @@ private void InitializeComponent() this.groupBox1.Controls.Add(this.lMapName); this.groupBox1.Controls.Add(this.pbThumbnail); this.groupBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F); - this.groupBox1.Location = new System.Drawing.Point(0, 0); + this.groupBox1.Location = new System.Drawing.Point(3, 3); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(225, 434); + this.groupBox1.Size = new System.Drawing.Size(224, 434); this.groupBox1.TabIndex = 3; this.groupBox1.TabStop = false; this.groupBox1.Text = "Selected map"; @@ -276,7 +276,7 @@ private void InitializeComponent() this.panel1.ForeColor = System.Drawing.SystemColors.ControlLightLight; this.panel1.Location = new System.Drawing.Point(6, 19); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(574, 105); + this.panel1.Size = new System.Drawing.Size(673, 105); this.panel1.TabIndex = 4; // // lbLog @@ -287,7 +287,7 @@ private void InitializeComponent() this.lbLog.ItemHeight = 15; this.lbLog.Location = new System.Drawing.Point(0, 0); this.lbLog.Name = "lbLog"; - this.lbLog.Size = new System.Drawing.Size(572, 103); + this.lbLog.Size = new System.Drawing.Size(671, 103); this.lbLog.TabIndex = 0; // // groupBox2 @@ -299,7 +299,7 @@ private void InitializeComponent() this.groupBox2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F); this.groupBox2.Location = new System.Drawing.Point(6, 0); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(585, 130); + this.groupBox2.Size = new System.Drawing.Size(684, 130); this.groupBox2.TabIndex = 5; this.groupBox2.TabStop = false; this.groupBox2.Text = "Output"; @@ -315,7 +315,7 @@ private void InitializeComponent() this.ProgramMenuStrip.Location = new System.Drawing.Point(0, 0); this.ProgramMenuStrip.Name = "ProgramMenuStrip"; this.ProgramMenuStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; - this.ProgramMenuStrip.Size = new System.Drawing.Size(823, 24); + this.ProgramMenuStrip.Size = new System.Drawing.Size(924, 24); this.ProgramMenuStrip.TabIndex = 5; this.ProgramMenuStrip.Text = "File"; // @@ -414,7 +414,7 @@ private void InitializeComponent() this.groupBox3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F); this.groupBox3.Location = new System.Drawing.Point(6, 135); this.groupBox3.Name = "groupBox3"; - this.groupBox3.Size = new System.Drawing.Size(582, 99); + this.groupBox3.Size = new System.Drawing.Size(681, 99); this.groupBox3.TabIndex = 8; this.groupBox3.TabStop = false; this.groupBox3.Text = "Map base size"; @@ -465,7 +465,7 @@ private void InitializeComponent() this.bConvertSelected.Enabled = false; this.bConvertSelected.FlatStyle = System.Windows.Forms.FlatStyle.System; this.bConvertSelected.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F); - this.bConvertSelected.Location = new System.Drawing.Point(256, 264); + this.bConvertSelected.Location = new System.Drawing.Point(355, 264); this.bConvertSelected.Name = "bConvertSelected"; this.bConvertSelected.Size = new System.Drawing.Size(161, 34); this.bConvertSelected.TabIndex = 2; @@ -498,7 +498,7 @@ private void InitializeComponent() // this.splitContainer1.Panel2.Controls.Add(this.groupBox2); this.splitContainer1.Panel2MinSize = 100; - this.splitContainer1.Size = new System.Drawing.Size(591, 440); + this.splitContainer1.Size = new System.Drawing.Size(690, 437); this.splitContainer1.SplitterDistance = 300; this.splitContainer1.TabIndex = 9; // @@ -507,7 +507,7 @@ private void InitializeComponent() this.cbIgnoreMediaTracker.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.cbIgnoreMediaTracker.AutoSize = true; this.cbIgnoreMediaTracker.CheckAlign = System.Drawing.ContentAlignment.MiddleRight; - this.cbIgnoreMediaTracker.Location = new System.Drawing.Point(460, 241); + this.cbIgnoreMediaTracker.Location = new System.Drawing.Point(559, 241); this.cbIgnoreMediaTracker.Name = "cbIgnoreMediaTracker"; this.cbIgnoreMediaTracker.Size = new System.Drawing.Size(125, 17); this.cbIgnoreMediaTracker.TabIndex = 10; @@ -538,7 +538,7 @@ private void InitializeComponent() this.lvMaps.LargeImageList = this.ilThumbnails; this.lvMaps.Location = new System.Drawing.Point(6, 5); this.lvMaps.Name = "lvMaps"; - this.lvMaps.Size = new System.Drawing.Size(583, 125); + this.lvMaps.Size = new System.Drawing.Size(682, 125); this.lvMaps.TabIndex = 9; this.lvMaps.UseCompatibleStateImageBehavior = false; this.lvMaps.View = System.Windows.Forms.View.Tile; @@ -568,10 +568,8 @@ private void InitializeComponent() // splitContainer2.Panel2 // this.splitContainer2.Panel2.Controls.Add(this.groupBox1); - this.splitContainer2.Panel2MinSize = 260; - this.splitContainer2.Size = new System.Drawing.Size(823, 437); + this.splitContainer2.Size = new System.Drawing.Size(924, 437); this.splitContainer2.SplitterDistance = 690; - this.splitContainer2.SplitterWidth = 3; this.splitContainer2.TabIndex = 10; this.splitContainer2.Text = "splitContainer2"; // @@ -580,9 +578,10 @@ private void InitializeComponent() this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScroll = true; - this.ClientSize = new System.Drawing.Size(823, 461); + this.ClientSize = new System.Drawing.Size(924, 461); this.Controls.Add(this.splitContainer2); this.Controls.Add(this.ProgramMenuStrip); + this.DoubleBuffered = true; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MainMenuStrip = this.ProgramMenuStrip; this.MinimumSize = new System.Drawing.Size(839, 500); From 523f07050211633991f35b25bd739e365f059f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sat, 19 Sep 2020 18:47:32 +0200 Subject: [PATCH 25/27] Vec4 --- GBX.NET/GameBoxReader.cs | 6 ++++++ GBX.NET/GameBoxWriter.cs | 9 +++++++-- GBX.NET/Vec4.cs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 GBX.NET/Vec4.cs diff --git a/GBX.NET/GameBoxReader.cs b/GBX.NET/GameBoxReader.cs index 0662b0897..f529cd93b 100644 --- a/GBX.NET/GameBoxReader.cs +++ b/GBX.NET/GameBoxReader.cs @@ -226,6 +226,12 @@ public Vec3 ReadVec3() return new Vec3(floats[0], floats[1], floats[2]); } + public Vec4 ReadVec4() + { + var floats = ReadArray(4); + return new Vec4(floats[0], floats[1], floats[2], floats[3]); + } + public Int3 ReadInt3() { var ints = ReadArray(3); diff --git a/GBX.NET/GameBoxWriter.cs b/GBX.NET/GameBoxWriter.cs index 9571f1d20..7c80c8043 100644 --- a/GBX.NET/GameBoxWriter.cs +++ b/GBX.NET/GameBoxWriter.cs @@ -95,14 +95,19 @@ public void Write(T[] array, Action forLoop) } } + public void Write(Vec2 value) + { + Write(new float[] { value.X, value.Y }); + } + public void Write(Vec3 value) { Write(new float[] { value.X, value.Y, value.Z }); } - public void Write(Vec2 value) + public void Write(Vec4 value) { - Write(new float[] { value.X, value.Y }); + Write(new float[] { value.X, value.Y, value.Z, value.W }); } public void Write(Int3 value) diff --git a/GBX.NET/Vec4.cs b/GBX.NET/Vec4.cs new file mode 100644 index 000000000..d7df219b4 --- /dev/null +++ b/GBX.NET/Vec4.cs @@ -0,0 +1,34 @@ +namespace GBX.NET +{ + public struct Vec4 + { + public float X { get; } + public float Y { get; } + public float Z { get; } + public float W { get; } + + public Vec4(float x, float y, float z, float w) + { + X = x; + Y = y; + Z = z; + W = w; + } + + public override string ToString() => $"({X}, {Y}, {Z}, {W})"; + public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode(); + public override bool Equals(object obj) => obj is Vec4 a && a == this; + + public static bool operator ==(Vec4 a, Vec4 b) => a.X == b.X && a.Y == b.Y && a.Z == b.Z && a.W == b.W; + public static bool operator !=(Vec4 a, Vec4 b) => !(a.X == b.X && a.Y == b.Y && a.Z == b.Z && a.W == b.W); + + public static Vec4 operator +(Vec4 a, Vec4 b) => new Vec4(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W); + + public static Vec4 operator -(Vec4 a) => new Vec4(-a.X, -a.Y, -a.Z, -a.W); + + public static Vec4 operator *(Vec4 a, Vec4 b) => new Vec4(a.X * b.X, a.Y * b.Y, a.Z * b.Z, a.W * a.W); + + public static implicit operator Vec4((float X, float Y, float Z, float W) v) => new Vec4(v.X, v.Y, v.Z, v.W); + public static implicit operator (float X, float Y, float Z, float W)(Vec4 v) => (v.X, v.Y, v.Z, v.W); + } +} From dc7b236e67f469eef790623ff20c17a4df3ee10d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sat, 19 Sep 2020 18:48:44 +0200 Subject: [PATCH 26/27] Fix reading of TMUF tracks with some MT blocks --- GBX.NET/Engines/Game/CGameCtnChallenge.cs | 4 ++- .../Game/CGameCtnMediaBlockFxColors.cs | 20 +++++++++++++-- .../Game/CGameCtnMediaBlockTriangles.cs | 25 ++++++++++++++++++- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/GBX.NET/Engines/Game/CGameCtnChallenge.cs b/GBX.NET/Engines/Game/CGameCtnChallenge.cs index a1a1236f5..3c7dea11e 100644 --- a/GBX.NET/Engines/Game/CGameCtnChallenge.cs +++ b/GBX.NET/Engines/Game/CGameCtnChallenge.cs @@ -563,7 +563,7 @@ public void CrackPassword() public void PlaceItem(Meta itemModel, Vec3 absolutePosition, Vec3 pitchYawRoll, Byte3 blockUnitCoord, Vec3 offsetPivot, int variant = 0) { - var chunkItems = CreateChunk(); + CreateChunk(); var it = new CGameCtnAnchoredObject() { @@ -682,6 +682,8 @@ void ConvertMediaTrack(CGameCtnMediaTrack node) node.RemoveChunk(); node.Blocks.RemoveAll(x => x is CGameCtnMediaBlockGhost); // Some ghosts can crash the game + node.Blocks.RemoveAll(x => x is CGameCtnMediaBlockTriangles); // 2D triangles can't be written atm + node.Blocks.RemoveAll(x => x is CGameCtnMediaBlockFxColors); // FX colors can't be written atm } return true; diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxColors.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxColors.cs index 100dda77c..c97373cbf 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockFxColors.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockFxColors.cs @@ -8,9 +8,25 @@ namespace GBX.NET.Engines.Game public class CGameCtnMediaBlockFxColors : CGameCtnMediaBlockFx { [Chunk(0x03080003)] - public class Chunk03080003 : Chunk + public class Chunk03080003 : Chunk { - public Key[] Keys { get; set; } + public override void Read(CGameCtnMediaBlockFxColors n, GameBoxReader r, GameBoxWriter unknownW) + { + var numKeys = r.ReadInt32(); + r.ReadInt32(); + var intensity = r.ReadSingle(); + r.ReadInt32(); + var distance = r.ReadSingle(); + var farDistance = r.ReadSingle(); + var inverse = r.ReadSingle(); + var hue = r.ReadSingle(); + var saturation = r.ReadSingle(); // from center + var brightness = r.ReadSingle(); // from center + var contrast = r.ReadSingle(); // from center + var rgb = r.ReadVec3(); + + r.ReadTillFacade(); + } } } } diff --git a/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles.cs b/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles.cs index b1d26f51e..68bc1a3b7 100644 --- a/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles.cs +++ b/GBX.NET/Engines/Game/CGameCtnMediaBlockTriangles.cs @@ -7,6 +7,29 @@ namespace GBX.NET.Engines.Game [Node(0x03029000)] public class CGameCtnMediaBlockTriangles : CGameCtnMediaBlock { - + [Chunk(0x03029001)] + public class Chunk03029001 : Chunk + { + public override void Read(CGameCtnMediaBlockTriangles n, GameBoxReader r, GameBoxWriter unknownW) + { + var keys = r.ReadArray(i => new Key() { Time = r.ReadSingle() }); + + var numKeys = r.ReadInt32(); + var verticies = r.ReadArray(i => r.ReadVec3()); + + for (var i = 1; i < numKeys; i++) + for (var j = 0; j < verticies.Length; j++) + r.ReadVec3(); + + var colors = r.ReadArray(i => r.ReadVec4()); + + r.ReadTillFacade(); + } + } + + public class Key : MediaBlockKey + { + + } } } From ff10d6d0ab42b91152c1cfaec01efaea62cd32a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Pivo=C5=88ka?= Date: Sat, 19 Sep 2020 19:05:52 +0200 Subject: [PATCH 27/27] Simplified release notes --- GBX.NET/GBX.NET.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/GBX.NET/GBX.NET.csproj b/GBX.NET/GBX.NET.csproj index b2b4b4a88..f83433dc7 100644 --- a/GBX.NET/GBX.NET.csproj +++ b/GBX.NET/GBX.NET.csproj @@ -14,6 +14,7 @@ gbx, trackmania, maniaplanet, gamebox, net, chunk, x86 https://github.com/BigBang1112/gbx-net https://github.com/BigBang1112/gbx-net + Makes library compatible with .NET Standard 2.0, hugely improves reading speed.