Beispiel #1
0
        public static UndertaleChunk Unserialize(UndertaleReader reader)
        {
            string name = "(unknown)";

            try
            {
                name = reader.ReadChars(4);
                uint length = reader.ReadUInt32();

                // TODO: I can't think of a cleaner way to do this...
                Type type = Type.GetType(typeof(UndertaleChunk).FullName + name);
                if (type == null)
                {
                    throw new IOException("Unknown chunk " + name + "!!!");

                    /*Debug.WriteLine("Unknown chunk " + name + "!!!");
                     * reader.Position = reader.Position + length;
                     * return null;*/
                }

                UndertaleChunk chunk = (UndertaleChunk)Activator.CreateInstance(type);
                Debug.Assert(chunk.Name == name);
                chunk.Length = length;

                reader.SubmitMessage("Reading chunk " + chunk.Name);
                var lenReader = reader.EnsureLengthFromHere(chunk.Length);
                chunk.UnserializeChunk(reader);

                if (name != "FORM" && name != reader.LastChunkName)
                {
                    UndertaleGeneralInfo generalInfo = name == "GEN8" ? ((UndertaleChunkGEN8)chunk).Object : reader.undertaleData.GeneralInfo;
                    // These versions introduced new padding
                    // all chunks now start on 16-byte boundaries
                    // (but the padding is included with length of previous chunk)
                    if (generalInfo.Major >= 2 || (generalInfo.Major == 1 && generalInfo.Build >= 9999))
                    {
                        int  e   = reader.undertaleData.PaddingAlignException;
                        uint pad = (e == -1 ? 16 : (uint)e);
                        while (reader.Position % pad != 0)
                        {
                            if (reader.ReadByte() != 0)
                            {
                                reader.Position -= 1;
                                if (reader.Position % 4 == 0)
                                {
                                    reader.undertaleData.PaddingAlignException = 4;
                                }
                                else
                                {
                                    reader.undertaleData.PaddingAlignException = 1;
                                }
                                break;
                            }
                        }
                    }
                }

                lenReader.ToHere();

                return(chunk);
            }
            catch (UndertaleSerializationException e)
            {
                throw new UndertaleSerializationException(e.Message + " in chunk " + name, e);
            }
            catch (Exception e)
            {
                throw new UndertaleSerializationException(e.Message + "\nat " + reader.Position.ToString("X8") + " while reading chunk " + name, e);
            }
        }