Exemplo n.º 1
0
 public RootHandler()
 {
     GlobalRoot = new RootChunk()
     {
         ContentFlags = ContentFlags.None, LocaleFlags = LocaleFlags.All_WoW
     };
     encodingMap = new EncodingMap(EncodingType.ZLib, 9);
 }
Exemplo n.º 2
0
        public void SetArea(Vector3I start, Vector3I end, BlockVoxel voxel)
        {
            GetAreaFromPoints(start, end, out Vector3I areaStart,
                              out Vector3I areaScale);

            RootChunk.TraverseToChunk(areaStart, true, out var startChunk);
            RootChunk.TraverseToChunk(areaStart + areaScale, true,
                                      out var endChunk);
            int      chunkSideLength = RootChunk.SideLength;
            Vector3I wholeChunkArea  = Vector3I.One +
                                       ((endChunk.Offset - startChunk.Offset) / chunkSideLength);

            Chunk <BlockVoxel>[,,] chunkCache = new Chunk <BlockVoxel> [
                wholeChunkArea.X, wholeChunkArea.Y, wholeChunkArea.Z];
            chunkCache[0, 0, 0] = startChunk;
            chunkCache[chunkCache.GetLength(0) - 1,
                       chunkCache.GetLength(1) - 1,
                       chunkCache.GetLength(2) - 1] = endChunk;

            Chunk <BlockVoxel> currentChunk;

            for (int x = 0; x < areaScale.X; x++)
            {
                for (int y = 0; y < areaScale.Y; y++)
                {
                    for (int z = 0; z < areaScale.Z; z++)
                    {
                        Vector3I offset      = new Vector3I(x, y, z);
                        Vector3I cacheOffset =
                            ((areaStart - startChunk.Offset) + offset) /
                            chunkSideLength;

                        if (chunkCache[cacheOffset.X, cacheOffset.Y,
                                       cacheOffset.Z] == null)
                        {
                            RootChunk.TraverseToChunk(areaStart + offset,
                                                      true, out chunkCache[cacheOffset.X,
                                                                           cacheOffset.Y, cacheOffset.Z]);
                        }

                        currentChunk = chunkCache[cacheOffset.X,
                                                  cacheOffset.Y, cacheOffset.Z];

                        if (currentChunk.Availability !=
                            ChunkAvailability.None)
                        {
                            currentChunk.Unlock();
                            currentChunk.SetVoxel(areaStart + offset -
                                                  currentChunk.Offset, voxel);
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
 private bool IsBlockSolid(Vector3 position)
 {
     if (RootChunk.TraverseToChunk((Vector3I)position, false,
                                   out var chunk))
     {
         if (chunk.TryGetVoxel(position - chunk.Offset,
                               out var voxel, false))
         {
             var voxelBlock = Blocks.GetBlock(voxel.BlockKey);
             return(voxelBlock.Properties.Type ==
                    BlockColliderType.Solid);
         }
         else
         {
             return(false);
         }
     }
Exemplo n.º 4
0
        public RootHandler(Stream data, LocaleFlags locale, uint minimumid = 0)
        {
            this.minimumId = minimumid;
            this.locale    = locale;

            BinaryReader stream = new BinaryReader(data);

            long length = stream.BaseStream.Length;

            while (stream.BaseStream.Position < length)
            {
                RootChunk chunk = new RootChunk()
                {
                    Count        = stream.ReadUInt32(),
                    ContentFlags = (ContentFlags)stream.ReadUInt32(),
                    LocaleFlags  = (LocaleFlags)stream.ReadUInt32(),
                };

                // set the global root
                if (chunk.LocaleFlags == LocaleFlags.All_WoW && chunk.ContentFlags == ContentFlags.None)
                {
                    GlobalRoot = chunk;
                }

                uint fileDataIndex = 0;
                for (int i = 0; i < chunk.Count; i++)
                {
                    uint offset = stream.ReadUInt32();

                    RootEntry entry = new RootEntry()
                    {
                        FileDataIdOffset = offset,
                        FileDataId       = fileDataIndex + offset
                    };

                    fileDataIndex = entry.FileDataId + 1;
                    chunk.Entries.Add(entry);
                }

                foreach (var entry in chunk.Entries)
                {
                    entry.CEKey    = new MD5Hash(stream);
                    entry.NameHash = stream.ReadUInt64();
                    maxId          = Math.Max(maxId, entry.FileDataId);
                }

                Chunks.Add(chunk);
            }

            if (GlobalRoot == null)
            {
                CASContainer.Logger.LogCritical($"No Global root found. Root file is corrupt.");
                return;
            }

            // set maxid from cache
            maxId = Math.Max(Math.Max(maxId, minimumid), CASContainer.Settings.Cache?.MaxId ?? 0);

            // store encoding map
            encodingMap = (data as BLTEStream)?.EncodingMap.FirstOrDefault() ?? new EncodingMap(EncodingType.ZLib, 9);

            stream?.Dispose();
            data?.Dispose();
        }
Exemplo n.º 5
0
        private void SaveInternal(eSaveMode xiSaveMode, string xiFilename)
        {
            if (RootChunk == null)
            {
                MessageBox.Show("Can't save: no file is open");
                return;
            }

            string lExceptionWhen = "saving file";

            try
            {
                long lPreviousSize = -1;

                if (xiSaveMode == eSaveMode.Binary && File.Exists(xiFilename))
                {
                    lPreviousSize = new FileInfo(xiFilename).Length;
                }

                using (FileStream fs = File.Create(xiFilename))
                {
                    lExceptionWhen = "serialising the file";
                    if (xiSaveMode == eSaveMode.Binary)
                    {
                        if (RootChunk is VersionList)
                        {
                            CurrentLevel.Serialise(fs);
                        }
                        else
                        {
                            RootChunk.Serialise(fs);
                        }
                    }
                    else if (xiSaveMode == eSaveMode.Xml)
                    {
                        XmlSerializer xs = new XmlSerializer(typeof(Chunk));

                        if (RootChunk is VersionList)
                        {
                            xs.Serialize(fs, CurrentLevel);
                        }
                        else
                        {
                            xs.Serialize(fs, RootChunk);
                        }
                    }
                    else if (xiSaveMode == eSaveMode.Mmv)
                    {
                        if (RootChunk is VersionList)
                        {
                            VersionList lVersionList = (VersionList)RootChunk;
                            lVersionList.AddLevel(CurrentLevel);

                            RecursiveAddChunkNode(ChunkTreeView.Nodes[0].Nodes, 1, lVersionList.GetLastVersion());
                        }
                        else if (RootChunk is Level)
                        {
                            VersionList lVersionList = new VersionList(
                                (Level)RootChunk,
                                Path.GetFileNameWithoutExtension(xiFilename),
                                null);
                            RootChunk = lVersionList;
                        }
                        RootChunk.Serialise(fs);
                    }
                }

                if (lPreviousSize != -1 && lPreviousSize != new FileInfo(xiFilename).Length)
                {
                    MessageBox.Show("WARNING: The size of your level has changed. Please check it's not too large, and check MMEd for bugs that have allowed the size to change.",
                                    "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            catch (Exception err)
            {
                Trace.WriteLine(err);
                MessageBox.Show(string.Format("Exception occurred while {0}: {1}", lExceptionWhen, err.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            mLocalSettings.LastSavedFile = xiFilename;
            mLocalSettings.LastSavedMode = xiSaveMode;
            mCurrentFile     = xiFilename;
            mCurrentFileMode = xiSaveMode;
        }
Exemplo n.º 6
0
        public RootHandler(Stream data, LocaleFlags locale, uint minimumid = 0, bool onlineListfile = false)
        {
            this.minimumId = minimumid;
            this.locale    = locale;
            string cdnPath = Helper.GetCDNPath("listfile.csv");

            if (!(File.Exists(Path.Combine(CASContainer.Settings.OutputPath, cdnPath))) && onlineListfile)
            {
                CASContainer.Logger.LogInformation("Downloading listfile from WoW.Tools");
                ListFileClient.DownloadFile("https://wow.tools/casc/listfile/download/csv/unverified", cdnPath);
            }

            BinaryReader stream = new BinaryReader(data);

            // 8.2 root change
            int  magic     = stream.ReadInt32();
            bool newFormat = magic == headerMagic;

            if (newFormat)
            {
                allFiles   = stream.ReadInt32();
                namedFiles = stream.ReadInt32();
            }
            else
            {
                stream.BaseStream.Position = 0;
            }

            long length = stream.BaseStream.Length;

            while (stream.BaseStream.Position < length)
            {
                RootChunk chunk = new RootChunk()
                {
                    Count        = stream.ReadUInt32(),
                    ContentFlags = (ContentFlags)stream.ReadUInt32(),
                    LocaleFlags  = (LocaleFlags)stream.ReadUInt32(),
                };

                parsedFiles += (int)chunk.Count;

                // set the global root
                if (chunk.LocaleFlags == LocaleFlags.All_WoW && chunk.ContentFlags == ContentFlags.None)
                {
                    GlobalRoot = chunk;
                }

                uint fileDataIndex = 0;
                for (int i = 0; i < chunk.Count; i++)
                {
                    uint offset = stream.ReadUInt32();

                    RootEntry entry = new RootEntry()
                    {
                        FileDataIdOffset = offset,
                        FileDataId       = fileDataIndex + offset
                    };

                    fileDataIndex = entry.FileDataId + 1;
                    chunk.Entries.Add(entry);
                }

                if (newFormat)
                {
                    foreach (var entry in chunk.Entries)
                    {
                        entry.CEKey = new MD5Hash(stream);
                        maxId       = Math.Max(maxId, entry.FileDataId);
                    }

                    if (parsedFiles > allFiles - namedFiles)
                    {
                        foreach (var entry in chunk.Entries)
                        {
                            entry.NameHash = stream.ReadUInt64();
                        }
                    }
                    else // no namehash
                    {
                        foreach (var entry in chunk.Entries)
                        {
                            entry.NameHash = 0;
                        }
                    }
                }
                else
                {
                    foreach (var entry in chunk.Entries)
                    {
                        entry.CEKey    = new MD5Hash(stream);
                        entry.NameHash = stream.ReadUInt64();
                        maxId          = Math.Max(maxId, entry.FileDataId);
                    }
                }

                Chunks.Add(chunk);
            }

            if (GlobalRoot == null)
            {
                CASContainer.Logger.LogCritical($"No Global root found. Root file is corrupt.");
                return;
            }

            // use listfile to assign names
            var listFileLines = File.ReadAllLines(cdnPath);

            foreach (var listFileData in listFileLines)
            {
                var splitData = listFileData.Split(';');

                if (splitData.Length != 2)
                {
                    continue;
                }

                if (!uint.TryParse(splitData[0], out uint listFileDataID))
                {
                    continue;
                }

                ListFile[listFileDataID] = new Jenkins96().ComputeHash(splitData[1]);
            }

            foreach (var chunk in Chunks)
            {
                foreach (var entry in chunk.Entries)
                {
                    if (entry.NameHash == 0)
                    {
                        if (ListFile.ContainsKey(entry.FileDataId))
                        {
                            entry.NameHash = ListFile[entry.FileDataId];
                        }
                    }
                }
            }

            // set maxid from cache
            maxId = Math.Max(Math.Max(maxId, minimumid), CASContainer.Settings.Cache?.MaxId ?? 0);

            // store encoding map
            encodingMap = (data as BLTEStream)?.EncodingMap.FirstOrDefault() ?? new EncodingMap(EncodingType.ZLib, 9);

            stream?.Dispose();
            data?.Dispose();
        }
Exemplo n.º 7
0
 protected SRFile(string path, Stream stream) : base(stream)
 {
     Path      = path;
     RootChunk = new RootChunk(this);
 }