Example #1
0
        public AllureLifecycle AddAttachment(string name, AttachFormat type, byte[] bytesArray,
                                             string fileExtension = "")
        {
            var asString = Encoding.Default.GetString(bytesArray);

            switch (type)
            {
            case AttachFormat.Xml:
                return(AddAttachment(name, type, asString));

            case AttachFormat.Json:
                return(AddAttachment(name, type, asString));

            case AttachFormat.ImagePng:
                return(AddAttachment(name, "image/png", bytesArray, ".png"));

            case AttachFormat.Txt:
                return(AddAttachment(name, type, asString));

            case AttachFormat.Html:
                return(AddAttachment(name, type, asString));

            case AttachFormat.Video:
                throw new ArgumentException(
                          $"You cant use \"{type}\" argument at this method. Try use method with FileInfo parameter.");

            default:
                throw new ArgumentOutOfRangeException(nameof(type), type, null);
            }
        }
Example #2
0
        public AllureLifecycle AddAttachment(string name, AttachFormat type, FileInfo file)
        {
            string inside;

            using (var u = new StreamReader(file.OpenRead()))
            {
                inside = u.ReadToEnd();
            }

            switch (type)
            {
            case AttachFormat.Xml:
                return(AddAttachment(name, AttachFormat.Xml, inside));

            case AttachFormat.Json:
                return(AddAttachment(name, AttachFormat.Json, inside));

            case AttachFormat.ImagePng:
                var bytes = Encoding.Default.GetBytes(inside);
                return(AddAttachment(name, "image/png", bytes, ".png"));

            case AttachFormat.Txt:
                return(AddAttachment(name, AttachFormat.Txt, inside));

            case AttachFormat.Video:
                return(AddAttachment(name, "video/mp4", file.FullName));

            case AttachFormat.Html:
                return(AddAttachment(name, AttachFormat.Html, inside));

            default:
                throw new ArgumentOutOfRangeException(nameof(type), type, null);
            }
        }
Example #3
0
        /// <summary>
        /// Writes a model hierarchy to stream and returns the contents
        /// </summary>
        /// <param name="format">Format of the file</param>
        /// <param name="NJFile">Whether to write an nj binary</param>
        /// <param name="model">The root model to write to the file</param>
        /// <param name="author">Author of the file</param>
        /// <param name="description">Description of the files contents</param>
        /// <param name="metadata">Other meta data</param>
        /// <param name="animFiles">Animation file paths</param>
        public static byte[] Write(AttachFormat format, bool NJFile, NJObject model, MetaData metaData)
        {
            using ExtendedMemoryStream stream = new();
            EndianWriter writer    = new(stream);
            uint         imageBase = 0;

            if (NJFile)
            {
                writer.WriteUInt16(NJ);
                switch (format)
                {
                case AttachFormat.BASIC:
                    writer.WriteUInt32(BM);
                    break;

                case AttachFormat.CHUNK:
                    writer.WriteUInt32(CM);
                    break;

                default:
                    throw new ArgumentException($"Attach format {format} not supported for NJ binaries");
                }
                writer.WriteUInt32(0); // file length placeholder
                imageBase = ~(8u);
            }
            else
            {
                ulong header = 0;
                header = format switch
                {
                    AttachFormat.BASIC => SA1MDLVer,
                    AttachFormat.CHUNK => SA2MDLVer,
                    AttachFormat.GC => SA2BMDLVer,
                    AttachFormat.Buffer => BFMDLVer,
                    _ => throw new ArgumentException($"Attach format {format} not supported for SAMDL files"),
                };
                writer.WriteUInt64(header);
                writer.WriteUInt32(0x10);
                writer.WriteUInt32(0); // labels placeholder
            }

            Dictionary <string, uint> labels = new();

            model.WriteHierarchy(writer, imageBase, false, format == AttachFormat.Buffer, labels);

            if (NJFile)
            {
                // replace size
                writer.Stream.Seek(4, SeekOrigin.Begin);
                writer.WriteUInt32((uint)writer.Stream.Length);
                writer.Stream.Seek(0, SeekOrigin.End);
            }
            else
            {
                metaData.Write(writer, labels);
            }

            return(stream.ToArray());
        }
Example #4
0
 private ModelFile(AttachFormat format, NJObject model, Motion[] animations, MetaData metaData, bool nj)
 {
     Format     = format;
     Model      = model;
     Animations = new ReadOnlyCollection <Motion>(animations);
     MetaData   = metaData;
     NJFile     = nj;
 }
Example #5
0
        /// <summary>
        /// Writes a model as an NJA file
        /// </summary>
        /// <param name="outputPath">Path to write the file to (extension will be forced to .NJA)</param>
        /// <param name="DX">Whether the file is for SADX</param>
        /// <param name="model">Top level object to write</param>
        /// <param name="textures">Texture list</param>
        public static void WriteNJA(string outputPath, bool DX, NJObject model, string[] textures = null)
        {
            NJObject[] objects  = model.GetObjects();
            Attach[]   attaches = objects.Select(x => x.Attach).Distinct().ToArray();

            AttachFormat fmt = AttachFormat.Buffer;

            if (attaches.Length > 0)
            {
                fmt = attaches[0].Format;
                foreach (Attach atc in attaches)
                {
                    if (fmt != atc.Format)
                    {
                        throw new InvalidCastException("Not all attaches are of the same type!");
                    }
                }
                if (fmt == AttachFormat.Buffer)
                {
                    throw new InvalidCastException("All attaches are of buffer format! Can't decide what format to write");
                }
            }

            outputPath = Path.ChangeExtension(outputPath, ".NJA");
            using TextWriter writer = File.CreateText(outputPath);
            List <string> labels = new();

            foreach (var atc in attaches)
            {
                atc.WriteNJA(writer, DX, labels, textures);
            }

            writer.WriteLine("OBJECT_START");
            writer.WriteLine();

            foreach (NJObject obj in objects.Reverse())
            {
                obj.WriteNJA(writer, labels);
            }

            writer.WriteLine("OBJECT_END");
            writer.WriteLine();

            writer.WriteLine();
            writer.WriteLine("DEFAULT_START");
            writer.WriteLine();

            writer.WriteLine("#ifndef DEFAULT_OBJECT_NAME");
            writer.Write("#define DEFAULT_OBJECT_NAME ");
            writer.WriteLine(model.Name);
            writer.WriteLine("#endif");

            writer.WriteLine();
            writer.WriteLine("DEFAULT_END");
            writer.WriteLine();
        }
Example #6
0
        private void Format_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox s = (ComboBox)sender;

            AttachFormat newFormat = (AttachFormat)s.SelectedIndex;

            if (_format == newFormat)
            {
                return;
            }

            _format = newFormat;
            RefreshFileExtension();
        }
Example #7
0
        public WndSave(Mode appMode, string lastFilePath, AttachFormat lastFormat, bool lastNJ, bool lastOptimized)
        {
            if (appMode is not Mode.Level and not Mode.Model)
            {
                throw new NotImplementedException("Only model and level files can be saved atm");
            }

            InitializeComponent();

            _sfd = new();
            _sfd.OverwritePrompt   = false;
            FilepathControl.Dialog = _sfd;

            if (!string.IsNullOrWhiteSpace(lastFilePath))
            {
                _sfd.InitialDirectory = Path.GetDirectoryName(lastFilePath);
                Filepath = lastFilePath;
                _format  = lastFormat;
                FormatControl.SelectedIndex = (int)lastFormat;
                NJFormatControl.IsChecked   = lastNJ;
                OptimizeControl.IsChecked   = lastOptimized;
            }
            else
            {
                _format = AttachFormat.Buffer;
            }
            _appMode = appMode;

            switch (appMode)
            {
            case Mode.Model:
                Title = "Save Model File";
                break;

            case Mode.Level:
                Title = "Save Level File";
                break;

            case Mode.ProjectSA1:
            case Mode.ProjectSA2:
            case Mode.None:
            default:
                break;
            }

            RefreshFileExtension();
        }
Example #8
0
        public AllureLifecycle AddAttachment(string name, AttachFormat type, string content, string fileExtension = "")
        {
            switch (type)
            {
            case AttachFormat.ImagePng:
            case AttachFormat.Video:
                throw new ArgumentException(
                          $"You cant use \"{type}\" argument at this method. Try use method with FileInfo or with bytes array parameter.");

            case AttachFormat.Xml:
                content = XDocument.Parse(content).ToString();
                if (string.IsNullOrEmpty(fileExtension))
                {
                    fileExtension = ".xml";
                }
                return(AddAttachment(name, "text/xml", Encoding.UTF8.GetBytes(content), fileExtension));

            case AttachFormat.Json:
                var obj = JsonConvert.DeserializeObject(content);
                content = JsonConvert.SerializeObject(obj, Formatting.Indented);
                if (string.IsNullOrEmpty(fileExtension))
                {
                    fileExtension = ".json";
                }
                return(AddAttachment(name, "application/json", Encoding.UTF8.GetBytes(content), fileExtension));

            case AttachFormat.Txt:
                if (string.IsNullOrEmpty(fileExtension))
                {
                    fileExtension = ".txt";
                }
                return(AddAttachment(name, "text/txt", Encoding.UTF8.GetBytes(content), fileExtension));

            case AttachFormat.Html:
                content = WebUtility.HtmlEncode(content);
                if (string.IsNullOrEmpty(fileExtension))
                {
                    fileExtension = ".html";
                }
                return(AddAttachment(name, "text/html", Encoding.UTF8.GetBytes(content), fileExtension));

            default:
                throw new ArgumentException($"You cant use \"{type}\" argument at this method.");
            }
        }
Example #9
0
File: Action.cs Project: X-Hax/SA3D
        /// <summary>
        /// Reads an action from a byte array
        /// </summary>
        /// <param name="source">Byte source</param>
        /// <param name="address">Address at which the action is located</param>
        /// <param name="imagebase">Image base for all addresses</param>
        /// <param name="format">Attach format</param>
        /// <param name="DX">Whether the file is for sadx</param>
        /// <param name="labels">C struct labels</param>
        /// <param name="attaches">Attaches that have already been read</param>
        /// <returns></returns>
        public static Action Read(byte[] source, uint address, uint imagebase, AttachFormat format, bool DX, Dictionary <uint, string> labels, Dictionary <uint, Attach> attaches)
        {
            uint mdlAddress = source.ToUInt32(address);

            if (mdlAddress == 0)
            {
                throw new FormatException($"Action at {address:X8} does not have a model!");
            }
            mdlAddress -= imagebase;
            NJObject mdl = NJObject.Read(source, mdlAddress, imagebase, format, DX, labels, attaches);

            uint aniAddress = source.ToUInt32(address + 4);

            if (aniAddress == 0)
            {
                throw new FormatException($"Action at {address:X8} does not have a model!");
            }
            aniAddress -= imagebase;
            Motion mtn = Motion.Read(source, ref aniAddress, imagebase, (uint)mdl.Count(), labels);

            return(new(mdl, mtn));
        }
Example #10
0
 /// <summary>
 /// Writes a model hierarchy (without meta data) to a stream and returns the contents
 /// </summary>
 /// <param name="format">Format of the file</param>
 /// <param name="NJFile">Whether to write an nj binary</param>
 /// <param name="model">The root model to write to the file</param>
 public static byte[] Write(AttachFormat format, bool NJFile, NJObject model)
 => Write(format, NJFile, model, new MetaData());
Example #11
0
 /// <summary>
 /// Writes a model hierarchy to a binary file
 /// </summary>
 /// <param name="format">Format of the file</param>
 /// <param name="outputPath">The path of the file</param>
 /// <param name="NJ">Whether to write an nj binary</param>
 /// <param name="model">The root model to write to the file</param>
 /// <param name="author">Author of the file</param>
 /// <param name="description">Description of the files contents</param>
 /// <param name="metadata">Other meta data</param>
 /// <param name="animFiles">Animation file paths</param>
 public static void WriteToFile(string outputPath, AttachFormat format, bool NJ, NJObject model, MetaData metaData)
 {
     File.WriteAllBytes(outputPath, Write(format, NJ, model, metaData));
 }
Example #12
0
 /// <summary>
 /// Writes a model hierarchy (without meta data) to a binary file
 /// </summary>
 /// <param name="format">Format of the file</param>
 /// <param name="outputPath">The path of the file</param>
 /// <param name="NJ">Whether to write an nj binary</param>
 /// <param name="model">The root model to write to the file</param>
 public static void WriteToFile(string outputPath, AttachFormat format, bool NJ, NJObject model)
 => WriteToFile(outputPath, format, NJ, model, new MetaData());
Example #13
0
        /// <summary>
        /// Reads a geometry animation from a byte array
        /// </summary>
        /// <param name="source">Byte source</param>
        /// <param name="address">Address at which the geometry animation is located</param>
        /// <param name="imageBase">Image base for all addresses</param>
        /// <param name="format">Attach format</param>
        /// <param name="DX">Whether the animation is for sadx</param>
        /// <param name="labels">C struct labels</param>
        /// <param name="models">Models that have already been read</param>
        /// <param name="attaches">Attaches that have already been read</param>
        /// <returns></returns>
        public static LandEntryMotion Read(byte[] source, uint address, uint imageBase, AttachFormat format, bool DX,
                                           Dictionary <uint, string> labels, Dictionary <uint, Attach> attaches)
        {
            float frame    = source.ToSingle(address);
            float step     = source.ToSingle(address + 4);
            float maxFrame = source.ToSingle(address + 8);

            uint     modelAddress = source.ToUInt32(address + 0xC) - imageBase;
            NJObject model        = NJObject.Read(source, modelAddress, imageBase, format, DX, labels, attaches);

            uint   motionAddress = source.ToUInt32(address + 0x10) - imageBase;
            Action action        = Action.Read(source, motionAddress, imageBase, format, DX, labels, attaches);

            uint texListPtr = source.ToUInt32(address + 0x14);

            return(new LandEntryMotion(frame, step, maxFrame, model, action, texListPtr));
        }
Example #14
0
        /// <summary>
        /// Reads a landtable from a byte array
        /// </summary>
        /// <param name="source"></param>
        /// <param name="address"></param>
        /// <param name="imageBase"></param>
        /// <param name="format"></param>
        /// <param name="labels"></param>
        /// <returns></returns>
        public static LandTable Read(byte[] source, uint address, uint imageBase, LandtableFormat format, Dictionary <uint, string> labels)
        {
            string name = labels.ContainsKey(address) ? labels[address] : "landtable_" + address.ToString("X8");
            float  radius;
            LandtableAttributes attribs = 0;

            string identifier = GenerateIdentifier();

            List <LandEntry>          geometry = new();
            string                    geomName;
            List <LandEntryMotion>    anim = new();
            string                    animName;
            Dictionary <uint, Attach> attaches = new();
            string                    texName  = "";
            uint texListPtr;

            uint   tmpaddr;
            ushort geoCount = source.ToUInt16(address);

            switch (format)
            {
            case LandtableFormat.SA1:
            case LandtableFormat.SADX:
                short anicnt = source.ToInt16(address + 2);
                attribs = (LandtableAttributes)source.ToUInt32(address + 4);
                radius  = source.ToSingle(address + 8);

                tmpaddr = source.ToUInt32(address + 0xC);
                if (tmpaddr != 0)
                {
                    tmpaddr -= imageBase;
                    geomName = labels.ContainsKey(tmpaddr) ? labels[tmpaddr] : "collist_" + tmpaddr.ToString("X8");

                    for (int i = 0; i < geoCount; i++)
                    {
                        geometry.Add(LandEntry.Read(source, tmpaddr, imageBase, AttachFormat.BASIC, format, labels, attaches));
                        tmpaddr += 0x24;
                    }
                }
                else
                {
                    geomName = "collist_" + identifier;
                }

                tmpaddr = source.ToUInt32(address + 0x10);
                if (tmpaddr != 0)
                {
                    tmpaddr -= imageBase;
                    animName = labels.ContainsKey(tmpaddr) ? labels[tmpaddr] : "animlist_" + tmpaddr.ToString("X8");

                    for (int i = 0; i < anicnt; i++)
                    {
                        anim.Add(LandEntryMotion.Read(source, tmpaddr, imageBase, AttachFormat.BASIC, format == LandtableFormat.SADX, labels, attaches));
                        tmpaddr += LandEntryMotion.Size;
                    }
                }
                else
                {
                    animName = "animlist_" + identifier;
                }

                tmpaddr = source.ToUInt32(address + 0x14);
                if (tmpaddr != 0)
                {
                    tmpaddr -= imageBase;
                    texName  = source.GetCString(tmpaddr, Encoding.ASCII);
                }
                texListPtr = source.ToUInt32(address + 0x18);

                break;

            case LandtableFormat.SA2:
            case LandtableFormat.SA2B:
                AttachFormat atcFmt = format == LandtableFormat.SA2 ? AttachFormat.CHUNK : AttachFormat.GC;

                ushort visualCount = source.ToUInt16(address + 2);
                radius = source.ToSingle(address + 0xC);

                tmpaddr = source.ToUInt32(address + 0x10);
                if (tmpaddr != 0)
                {
                    tmpaddr -= imageBase;
                    geomName = labels.ContainsKey(tmpaddr) ? labels[tmpaddr] : "collist_" + tmpaddr.ToString("X8");

                    for (int i = 0; i < geoCount; i++)
                    {
                        geometry.Add(LandEntry.Read(source, tmpaddr, imageBase, i >= visualCount ? AttachFormat.BASIC : atcFmt, format, labels, attaches));
                        tmpaddr += 0x20;
                    }
                }
                else
                {
                    geomName = "collist_" + identifier;
                }

                animName = "animlist_" + identifier;

                tmpaddr = source.ToUInt32(address + 0x18);
                if (tmpaddr != 0)
                {
                    tmpaddr -= imageBase;
                    texName  = source.GetCString(tmpaddr, Encoding.ASCII);
                }
                texListPtr = source.ToUInt32(address + 0x1C);

                break;

            default:
                throw new InvalidDataException("Landtable format not valid");
            }

            return(new(geometry, anim, format)
            {
                Name = name,
                DrawDistance = radius,
                Attributes = attribs,
                GeoName = geomName,
                GeoAnimName = animName,
                TexListPtr = texListPtr,
                TextureFileName = texName
            });
        }