コード例 #1
0
 public override void WriteTo(BinaryWriter w, Apk.Version v)
 {
     material.WriteTo(w);
     color.WriteTo(w, v);
     w.Write(raycastTarget);
     w.AlignStream();
     cullState.WriteTo(w);
     w.WriteAlignedString(text);
     w.Write(rightToLeft);
     w.AlignStream();
     fontAsset.WriteTo(w);
     w.Write(remainingData);
 }
コード例 #2
0
        public override void WriteTo(BinaryWriter w)
        {
            w.WriteAlignedString(name);
            w.Write(forcedFallbackFormat);
            w.Write(downscaleFallback);
            w.Write(width);
            w.Write(height);
            w.Write(completeImageSize);
            w.Write(textureFormat);
            w.Write(mipCount);
            w.Write(isReadable);
            w.Write(streamingMips);
            w.AlignStream();

            w.Write(streamingMipsPriority);
            w.Write(imageCount);
            w.Write(textureDimension);

            w.Write(filterMode);
            w.Write(anisotropic);
            w.Write(mipBias);
            w.Write(wrapU);
            w.Write(wrapV);
            w.Write(wrapW);

            w.Write(lightmapFormat);
            w.Write(colorSpace);
            w.WritePrefixedBytes(imageData);

            w.Write(offset);
            w.Write(size);
            w.WriteAlignedString(path);
        }
コード例 #3
0
 public override void WriteTo(BinaryWriter w)
 {
     text.WriteTo(w);
     w.Write(maintainTextAlignment);
     w.AlignStream();
     w.WriteAlignedString(key);
 }
コード例 #4
0
 public static void WriteAlignedString(this BinaryWriter write, string toWrite, int overrideAlignment = -1)
 {
     var result = Encoding.UTF8.GetBytes(toWrite);
     write.Write(result.Length);
     write.Write(result);
     write.AlignStream(overrideAlignment > 0 ? overrideAlignment : 4);
 }
コード例 #5
0
        public static void WriteAlignedString(this BinaryWriter writer, string str)
        {
            var bytes = Encoding.UTF8.GetBytes(str);

            writer.Write(bytes.Length);
            writer.Write(bytes);
            writer.AlignStream(4);
        }
コード例 #6
0
 public override void WriteTo(BinaryWriter w)
 {
     w.WriteAlignedString(packID);
     w.WriteAlignedString(packName);
     coverImage.WriteTo(w);
     w.Write(isPackAlwaysOwned);
     w.AlignStream();
     beatmapLevelCollection.WriteTo(w);
 }
コード例 #7
0
 public void WriteTo(BinaryWriter w)
 {
     w.WriteAlignedString(docsID);
     w.WriteAlignedString(sheetID);
     w.Write(format);
     textAsset.WriteTo(w);
     w.Write(downloadOnStart);
     w.AlignStream();
 }
コード例 #8
0
            // returns the location to patch the offsets
            public long WriteTo(BinaryWriter w)
            {
                w.AlignStream();
                w.Write(pathID);
                long patchPos = w.BaseStream.Position;

                w.Write(offset);
                w.Write(size);
                w.Write(typeID);
                return(patchPos);
            }
コード例 #9
0
 public override void WriteTo(BinaryWriter w, Apk.Version v)
 {
     w.WriteAlignedString(packID);
     w.WriteAlignedString(packName);
     coverImage.WriteTo(w);
     if (v < Apk.Version.V1_1_0)
     {
         w.Write(isPackAlwaysOwned);
         w.AlignStream();
     }
     beatmapLevelCollection.WriteTo(w);
 }
コード例 #10
0
        public override void WriteTo(BinaryWriter w, Apk.Version v)
        {
            w.WriteAlignedString(name);
            w.Write(loadType);
            w.Write(channels);
            w.Write(frequency);
            w.Write(bitsPerSample);
            w.Write(length);
            w.Write(isTracker);

            w.AlignStream();
            w.Write(subsoundIndex);
            w.Write(preloadAudio);
            w.Write(backgroundLoad);
            w.Write(legacy3D);

            w.AlignStream();
            w.WriteAlignedString(source);
            w.Write(offset);
            w.Write(size);
            w.Write(compressionFormat);
        }
コード例 #11
0
 public override void WriteTo(BinaryWriter w, Apk.Version v)
 {
     w.WriteAlignedString(name);
     foreach (float f in floats)
     {
         w.Write(f);
     }
     w.Write(extrude);
     w.Write(isPolygon);
     w.AlignStream();
     w.Write(guid);
     w.Write(second);
     w.WritePrefixedList(atlasTags, a => a.WriteTo(w));
     spriteAtlas.WriteTo(w);
     texture.WriteTo(w);
     w.Write(bytesAfterTexture);
 }
コード例 #12
0
        public void WriteTo(Stream outStream)
        {
            List <long> patchLocs = new List <long>(objects.Count);

            byte[] buf;
            int    length;
            int    dataOffset;
            int    metadataSize;

            using (MemoryStream stream = new MemoryStream()) {
                BinaryWriter w = new BinaryWriter(stream);

                // ===== Header
                w.Write((int)0);   // patch
                w.Write((int)0);   // patch
                w.WriteInt32BE(parsedGeneration);
                w.Write((int)0);   // patch
                w.WriteInt32BE(0); // not big endian

                // ===== Metadata
                w.WriteCString(version);
                w.Write(targetPlatform);
                w.Write(enableTypeTree);

                w.WritePrefixedList(types, x => x.WriteTo(w));
                w.WritePrefixedList(objects, x => patchLocs.Add(x.WriteTo(w)));
                w.WritePrefixedList(scripts, x => x.WriteTo(w));
                w.WritePrefixedList(externals, x => x.WriteTo(w));
                w.Write((byte)0);
                metadataSize = (int)w.BaseStream.Position - headerLen;

                w.WriteZeros(paddingLen);
                w.AlignStream();

                // ===== Data
                dataOffset = (int)w.BaseStream.Position;
                foreach (AssetObject obj in objects)
                {
                    obj.offset = (int)w.BaseStream.Position - dataOffset;
                    obj.data.WriteTo(w, apkVersion);
                    obj.size = ((int)w.BaseStream.Position - dataOffset) - obj.offset;
                    w.WriteZeros(obj.paddingLen);

                    // TODO do objects need to be aligned?
                    // All objects I can find are. If nothing is modified this shouldn't do anything.
                    // But if we change the size of an object it's probably more important to preserve
                    // alignment than the exact amount of padding.
                    w.AlignStream();
                }

                length = (int)stream.Length;
                stream.Close();
                buf = stream.GetBuffer();
            }

            // Patch header
            PatchInt(buf, 0 * 4, metadataSize, true);
            PatchInt(buf, 1 * 4, length, true);
            PatchInt(buf, 3 * 4, dataOffset, true);

            // Patch objects
            for (int i = 0; i < patchLocs.Count; i++)
            {
                PatchInt(buf, patchLocs[i] + 0 * 4, objects[i].offset, false);
                PatchInt(buf, patchLocs[i] + 1 * 4, objects[i].size, false);
            }

            outStream.Write(buf, 0, length);
        }
コード例 #13
0
        public static void write(string fileName, ref yarnDictionary rootz)
        {
            yarnFile f;

            if (!rootz.yarnFiles.TryGetValue(fileName, out f))
            {
                //yarn file not found
                Form1.Log("ERROR yarn file not found: " + fileName, true);
                return;
            }

            string assetFileName = Path.GetFileName(f.assetsFilePath);

            Form1.Log("Writing " + f.yarnFileName + " to " + assetFileName + "...");

            if (File.Exists(f.assetsFilePath))
            {
                if (IsFileLocked(f.assetsFilePath))
                {
                    MessageBox.Show("The file " + assetFileName + " is locked." + Environment.NewLine + Environment.NewLine +
                                    "Try closing any programs that could use it and if that fails try restarting your computer.",
                                    "File Locked", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    Form1.Log("Failed to write " + assetFileName + " (locked)", true);
                    return;
                }

                //calculate new yarn object length
                string yarnFilePath = AppDomain.CurrentDomain.BaseDirectory + @"\yarn files\" + f.yarnFileName + ".txt";

                if (IsFileLocked(yarnFilePath))
                {
                    MessageBox.Show("The file " + f.yarnFileName + " is locked." + Environment.NewLine + Environment.NewLine +
                                    "Sublime is known to cause this problem, try editing with another text editor. Also close any programs that could use " + f.yarnFileName +
                                    " and if that fails try restarting your computer.",
                                    "File Locked", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    Form1.Log("Failed to write " + assetFileName + " (" + f.yarnFileName + " locked)", true);
                    return;
                }
                string newContent = File.ReadAllText(yarnFilePath);

                byte[] newContentBytes = Encoding.UTF8.GetBytes(newContent);
                byte[] pathBytes       = Encoding.UTF8.GetBytes(f.yarnPath);

                uint newLength                = 0;
                uint newLength_name           = 0;
                uint newLength_namePadding    = 0;
                uint newLength_content        = 0;
                uint newLength_contentPadding = 0;
                uint newLength_path           = 0;
                uint newLength_pathPadding    = 0;

                newLength_name = 4 + (uint)f.yarnFileName.Length;
                if (newLength_name % 4 > 0)
                {
                    newLength_namePadding = 4 - (newLength_name % 4);
                }

                newLength_content = 4 + (uint)newContentBytes.Length;
                if (newLength_content % 4 > 0)
                {
                    newLength_contentPadding = 4 - (newLength_content % 4);
                }

                newLength_path = 4 + (uint)f.yarnPath.Length;
                if (newLength_path % 4 > 0)
                {
                    newLength_pathPadding = 4 - (newLength_path % 4);
                }

                newLength  = newLength_name + newLength_namePadding;
                newLength += newLength_content + newLength_contentPadding;
                newLength += newLength_path + newLength_pathPadding;

                //calculate offset delta
                int offsetDelta = (int)newLength - (int)f.length;

                //change file length
                long nextObjectOriginalPosition = f.objectDataOffset + f.offset + f.length;
                long nextObjectNewPosition      = nextObjectOriginalPosition + offsetDelta;
                long assetfileSize        = new FileInfo(f.assetsFilePath).Length;
                long followingObjectsSize = assetfileSize - nextObjectOriginalPosition;
                long newAssetFileSize     = assetfileSize + offsetDelta;

                if (offsetDelta < 0)
                {
                    //yarn object is smaller now -> transpose yarn object following bytes and truncate file
                    FileOps.FileHelper.Transpose(f.assetsFilePath, nextObjectOriginalPosition, nextObjectNewPosition, followingObjectsSize);
                    FileOps.FileHelper.SetFileLen(f.assetsFilePath, newAssetFileSize);
                }
                else if (offsetDelta > 0)
                {
                    //yarn object is bigger now -> transpose yarn object following bytes
                    FileOps.FileHelper.Transpose(f.assetsFilePath, nextObjectOriginalPosition, nextObjectNewPosition, followingObjectsSize);
                }

                //update object table with new length and new offsets for following objects
                List <uint> offsets = new List <uint>();

                // SB: Dodgy to leave this hardcoded but at least it's a constant by one name rather than magic numbers, right?
                // Use my newly added "f.objectEntrySize" for the size of the entry object as a whole...
                const int offsetToIndex  = 0;                  // SB: 8 bytes long (in file versions >= 14)    Won't work for file version < 14 (where this is Int32), but that doesn't apply to NITW
                const int offsetToOffset = offsetToIndex + 8;  // SB: 4 bytes long
                const int offsetToLength = offsetToOffset + 4; // SB: 4 bytes long
                uint      m_Version;

                //put all object offsets in a list
                using (BinaryReader reader = new BinaryReader(File.Open(f.assetsFilePath, FileMode.Open)))
                {
                    reader.ReadUInt32BE();
                    reader.ReadUInt32BE();
                    m_Version = reader.ReadUInt32BE();

                    reader.BaseStream.Seek(f.objectInfoPosition, SeekOrigin.Begin);
                    for (int i = 0; i < f.objectInfoCount; i++)
                    {
                        if (m_Version >= 14)
                        {
                            reader.AlignStream();
                        }

                        //skip uint64 index
                        reader.BaseStream.Seek(offsetToOffset, SeekOrigin.Current);

                        //save offsets for later
                        uint offset = reader.ReadUInt32();
                        offsets.Add(offset);

                        //skip rest of entry
                        var remainingBytes = f.objectEntrySize - offsetToLength;   // SB: still a little dodgy
                        reader.BaseStream.Seek(remainingBytes, SeekOrigin.Current);
                    }
                }



                //write new length and new offsets and new file size
                using (BinaryWriter writer = new BinaryWriter(File.Open(f.assetsFilePath, FileMode.Open)))
                {
                    //update filesize
                    writer.BaseStream.Seek(4, SeekOrigin.Begin);
                    byte[] newAssetFileSizeBytes = BitConverter.GetBytes((uint)newAssetFileSize);
                    Array.Reverse(newAssetFileSizeBytes);
                    writer.Write(newAssetFileSizeBytes);

                    long indexPosition = (f.index - 1) * f.objectEntrySize;     // SB: removed hardcoded value
                    writer.BaseStream.Seek(f.objectInfoPosition + indexPosition, SeekOrigin.Begin);

                    if (m_Version >= 14)
                    {
                        writer.AlignStream();
                    }

                    //update yarn length
                    {
                        writer.BaseStream.Seek(offsetToLength, SeekOrigin.Current);
                        writer.Write(newLength);

                        var remainingBytes = f.objectEntrySize - offsetToLength - 4;   // SB: still a little dodgy, additional -4 since we just wrote the length so we're passed the length
                        writer.BaseStream.Seek(remainingBytes, SeekOrigin.Current);
                    }

                    //update all offsets behind f.index
                    for (int i = (int)(f.index); i < f.objectInfoCount; i++)
                    {
                        if (m_Version >= 14)
                        {
                            writer.AlignStream();
                        }

                        uint newOffset = (uint)(offsets[i] + offsetDelta);

                        writer.BaseStream.Seek(offsetToOffset, SeekOrigin.Current);
                        writer.Write(newOffset);

                        var remainingBytes = f.objectEntrySize - offsetToLength;   // SB: still a little dodgy
                        writer.BaseStream.Seek(remainingBytes, SeekOrigin.Current);
                    }

                    //update yarn content
                    writer.BaseStream.Seek(f.objectDataOffset + f.offset + 4 + f.yarnFileName.Length + newLength_namePadding, SeekOrigin.Begin);
                    writer.Write((uint)(newContentBytes.Length));


                    writer.Write(newContentBytes);
                    if (newContentBytes.Length > 0)
                    {
                        int paddingTemp = 0;
                        if (newContentBytes.Length % 4 > 0)
                        {
                            paddingTemp = 4 - (newContentBytes.Length % 4);
                        }

                        for (int i = 0; i < paddingTemp; i++)
                        {
                            writer.Write((byte)0);
                        }
                    }

                    writer.BaseStream.Position = writer.BaseStream.Position;

                    writer.Write((uint)f.yarnPath.Length);
                    writer.Write(pathBytes);
                    if (pathBytes.Length > 0)
                    {
                        int paddingTemp = 0;
                        if (pathBytes.Length % 4 > 0)
                        {
                            paddingTemp = 4 - (pathBytes.Length % 4);
                        }

                        for (int i = 0; i < paddingTemp; i++)
                        {
                            writer.Write((byte)0);
                        }
                    }
                }

                Form1.Log("Writing " + f.yarnFileName + " to " + assetFileName + " done", true);

                //update yarn dictionary
                f.lastModified = File.GetLastWriteTime(yarnFilePath);
                f.length       = newLength;
                f.edited       = true;
                rootz.yarnFiles[f.yarnFileName] = f;
                JsonUtil.saveYarnDictionary(rootz);
            }
            else
            {
                Form1.Log("Failed to write " + assetFileName + " (not found)", true);
                return;
            }
        }
コード例 #14
0
 public static void WritePrefixedBytes(this BinaryWriter w, byte[] l)
 {
     w.Write((int)l.Length);
     w.Write(l);
     w.AlignStream();
 }
コード例 #15
0
 public static void AlignStream(this BinaryWriter writer)
 {
     writer.AlignStream(4);
 }
コード例 #16
0
        private static void WriteValue(object value, List <TypeTree> members, BinaryWriter write, ref int i)
        {
            var member     = members[i];
            var level      = member.m_Depth;
            var varTypeStr = member.m_Type;
            var align      = (member.m_MetaFlag & 0x4000) != 0;

            switch (varTypeStr)
            {
            case "SInt8":
                write.Write((sbyte)value);
                break;

            case "UInt8":
                write.Write((byte)value);
                break;

            case "short":
            case "SInt16":
                write.Write((short)value);
                break;

            case "UInt16":
            case "unsigned short":
                write.Write((ushort)value);
                break;

            case "int":
            case "SInt32":
                write.Write((int)value);
                break;

            case "UInt32":
            case "unsigned int":
            case "Type*":
                write.Write((uint)value);
                break;

            case "long long":
            case "SInt64":
                write.Write((long)value);
                break;

            case "UInt64":
            case "unsigned long long":
                write.Write((ulong)value);
                break;

            case "float":
                write.Write((float)value);
                break;

            case "double":
                write.Write((double)value);
                break;

            case "bool":
                write.Write((bool)value);
                break;

            case "string":
                write.WriteAlignedString((string)value);
                i += 3;
                break;

            case "vector":
            {
                if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
                {
                    align = true;
                }
                var list = (List <object>)value;
                var size = list.Count;
                write.Write(size);
                var vector = GetMembers(members, level, i);
                i += vector.Count - 1;
                vector.RemoveRange(0, 3);
                for (int j = 0; j < size; j++)
                {
                    int tmp = 0;
                    WriteValue(list[j], vector, write, ref tmp);
                }
                break;
            }

            case "map":
            {
                if ((members[i + 1].m_MetaFlag & 0x4000) != 0)
                {
                    align = true;
                }
                var dic  = (List <KeyValuePair <object, object> >)value;
                var size = dic.Count;
                write.Write(size);
                var map = GetMembers(members, level, i);
                i += map.Count - 1;
                map.RemoveRange(0, 4);
                var first = GetMembers(map, map[0].m_Depth, 0);
                map.RemoveRange(0, first.Count);
                var second = map;
                for (int j = 0; j < size; j++)
                {
                    int tmp1 = 0;
                    int tmp2 = 0;
                    WriteValue(dic[j].Key, first, write, ref tmp1);
                    WriteValue(dic[j].Value, second, write, ref tmp2);
                }
                break;
            }

            case "TypelessData":
            {
                var bytes = ((object[])value).Cast <byte>().ToArray();
                var size  = bytes.Length;
                write.Write(size);
                write.Write(bytes);
                i += 2;
                break;
            }

            default:
            {
                if (i != members.Count && members[i + 1].m_Type == "Array")
                {
                    goto case "vector";
                }
                var @class = GetMembers(members, level, i);
                @class.RemoveAt(0);
                i += @class.Count;
                var obj    = (ExpandoObject)value;
                var objdic = (IDictionary <string, object>)obj;
                for (int j = 0; j < @class.Count; j++)
                {
                    var classmember = @class[j];
                    var name        = classmember.m_Name;
                    WriteValue(objdic[name], @class, write, ref j);
                }
                break;
            }
            }
            if (align)
            {
                write.AlignStream(4);
            }
        }
コード例 #17
0
 public void WriteTo(BinaryWriter w)
 {
     w.Write(fileIndex);
     w.AlignStream();
     w.Write(inFileID);
 }