Exemplo n.º 1
0
        public GameBoxReader(Stream input, ILookbackable lookbackable) : this(input)
        {
            Lookbackable = lookbackable;

            if (lookbackable is GameBoxBody b)
            {
                Body = b;
            }
        }
Exemplo n.º 2
0
        public Id ReadId(ILookbackable lookbackable)
        {
            if (!lookbackable.IdVersion.HasValue)
            {
                lookbackable.IdVersion = ReadInt32();

                if ((lookbackable.IdVersion & 0xC0000000) > 10) // Edge-case scenario where Id doesn't have a version for whatever reason (can be multiple)
                {
                    lookbackable.IdVersion = 3;

                    if (BaseStream.CanSeek)
                    {
                        BaseStream.Seek(-4, SeekOrigin.Current);
                    }
                    else
                    {
                        throw new NotSupportedException("GBX has the first Id presented without a version. Solution exists, but the stream does not support seeking.");
                    }
                }
            }

            var index = ReadUInt32();

            if ((index & 0x3FFF) == 0 && (index >> 30 == 1 || index >> 30 == 2))
            {
                var str = ReadString();
                lookbackable.IdStrings.Add(str);
                return(new Id(str, lookbackable));
            }
            else if ((index & 0x3FFF) == 0x3FFF)
            {
                switch (index >> 30)
                {
                case 2:
                    return(new Id("Unassigned", lookbackable));

                case 3:
                    return(new Id("", lookbackable));

                default:
                    throw new Exception();
                }
            }
            else if (index >> 30 == 0)
            {
                return(new Id(index.ToString(), lookbackable));
            }
            else if (lookbackable.IdStrings.Count > (index & 0x3FFF) - 1)
            {
                return(new Id(lookbackable.IdStrings[(int)(index & 0x3FFF) - 1], lookbackable));
            }
            else
            {
                return(new Id("", lookbackable));
            }
        }
Exemplo n.º 3
0
        public void Write(GameBoxWriter w, ClassIDRemap remap)
        {
            var stopwatch = Stopwatch.StartNew();

            int counter = 0;

            foreach (Chunk chunk in Chunks)
            {
                counter++;

                var logChunk = $"[{ClassName}] 0x{chunk.ID:X8} ({(float)counter / Chunks.Count:0.00%})";
                if (Body?.GBX.ClassID.HasValue == true && Remap(Body.GBX.ClassID.Value) == ID)
                {
                    Log.Write(logChunk);
                }
                else
                {
                    Log.Write($"~ {logChunk}");
                }

                ((IChunk)chunk).Node   = this;
                chunk.Unknown.Position = 0;

                ILookbackable lb = chunk.Lookbackable;

                if (chunk is ILookbackable l)
                {
                    l.IdWritten = false;
                    l.IdStrings.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);

                        msW.Chunk = chunk;

                        try
                        {
                            if (chunk is ISkippableChunk s && !s.Discovered)
                            {
                                s.Write(msW);
                            }
                            else if (chunk.GetType().GetCustomAttribute <AutoReadWriteChunkAttribute>() == null)
                            {
                                ((IChunk)chunk).ReadWrite(this, rw);
                            }
                            else
                            {
                                msW.Write(chunk.Unknown.ToArray(), 0, (int)chunk.Unknown.Length);
                            }

                            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);
                        }
Exemplo n.º 4
0
 public void Write(Ident ident, ILookbackable lookbackable)
 {
     Write(new Id(ident.ID, lookbackable));
     Write(ident.Collection.ToId(lookbackable));
     Write(new Id(ident.Author, lookbackable));
 }
Exemplo n.º 5
0
 /// <exception cref="IOException">An I/O error occurs.</exception>
 /// <exception cref="ObjectDisposedException">The stream is closed.</exception>
 public void Write(Ident?ident, ILookbackable lookbackable)
 {
     Write(new Id(ident?.ID, lookbackable));
     Write(ident?.Collection.ToId(lookbackable) ?? new Id(null, lookbackable));
     Write(new Id(ident?.Author, lookbackable));
 }
Exemplo n.º 6
0
 public GameBoxWriter(Stream input, ILookbackable lookbackable) : this(input)
 {
     Lookbackable = lookbackable;
 }