private static void Load()
        {
            liquidObjectToLVFDict = new Dictionary <uint, ushort>();

            var dbcd      = new DBCD.DBCD(new CASCDBCProvider(), new DBCD.Providers.GithubDBDProvider());
            var loStorage = dbcd.Load("LiquidObject", CASC.BuildName);
            var ltStorage = dbcd.Load("LiquidType", CASC.BuildName);
            var lmStorage = dbcd.Load("LiquidMaterial", CASC.BuildName);

            foreach (dynamic loEntry in loStorage.Values)
            {
                foreach (dynamic ltEntry in ltStorage.Values)
                {
                    if (loEntry.LiquidTypeID == ltEntry.ID)
                    {
                        foreach (dynamic lmEntry in lmStorage.Values)
                        {
                            if (ltEntry.MaterialID == lmEntry.ID)
                            {
                                liquidObjectToLVFDict.Add((uint)loEntry.ID, (ushort)lmEntry.LVF);
                            }
                        }
                    }
                }
            }

            loaded = true;
        }
示例#2
0
        static DBCD.IDBCDStorage LoadMaps()
        {
            var dbdProvider = new GithubDBDProvider();
            var dbcProvider = new MirrorDBCProvider(BuildConfig);
            var dbcd        = new DBCD.DBCD(dbcProvider, dbdProvider);

            var maps = dbcd.Load("Map");

            return(maps);
        }
示例#3
0
        static void Main(string[] args)
        {
            var dbcd       = new DBCD.DBCD(new ItemSparseProvider(), new GithubDBDProvider());
            var ItemSparse = dbcd.Load("ItemSparse", "8.2.5.31921");

            foreach (dynamic row in ItemSparse.Values)
            {
                Console.WriteLine(row.ID + " " + row.Display_lang);
            }
        }
示例#4
0
        static void Main(string[] args)
        {
            var dbcProvider = new DBCProvider();
            var dbdProvider = new DBDProvider();

            if (args.Length > 0)
            {
                foreach (var file in Directory.GetFiles(Path.Combine(SettingManager.dbcDir, args[0], "dbfilesclient"), "*.*", SearchOption.AllDirectories))
                {
                    var db = Path.GetFileNameWithoutExtension(file);
                    try
                    {
                        Console.WriteLine();
                        Console.WriteLine(file.Replace(SettingManager.dbcDir + "\\", ""));
                        DBCD.DBCD storage = new DBCD.DBCD(dbcProvider, dbdProvider);
                        storage.Load(db, args[0]);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message + " " + e.StackTrace);
                    }
                }
            }
            else
            {
                foreach (var dir in Directory.GetDirectories(SettingManager.dbcDir))
                {
                    var build = dir.Replace(SettingManager.dbcDir + "\\", "");
                    foreach (var file in Directory.GetFiles(Path.Combine(dir, "dbfilesclient"), "*.*", SearchOption.AllDirectories))
                    {
                        var db = Path.GetFileNameWithoutExtension(file);
                        try
                        {
                            Console.WriteLine();
                            Console.WriteLine(file.Replace(SettingManager.dbcDir + "\\", ""));
                            DBCD.DBCD storage = new DBCD.DBCD(dbcProvider, dbdProvider);
                            storage.Load(db, build);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message + " " + e.StackTrace);
                        }
                    }
                }
            }
        }
示例#5
0
        public static void ExportADT(uint wdtFileDataID, byte tileX, byte tileY, BackgroundWorker exportworker = null)
        {
            if (exportworker == null)
            {
                exportworker = new BackgroundWorker();
                exportworker.WorkerReportsProgress = true;
            }

            var outdir = ConfigurationManager.AppSettings["outdir"];

            var customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();

            customCulture.NumberFormat.NumberDecimalSeparator    = ".";
            System.Threading.Thread.CurrentThread.CurrentCulture = customCulture;

            var MaxSize      = 51200 / 3.0;
            var TileSize     = MaxSize / 32.0;
            var ChunkSize    = TileSize / 16.0;
            var UnitSize     = ChunkSize / 8.0;
            var UnitSizeHalf = UnitSize / 2.0;

            if (!Listfile.TryGetFilename(wdtFileDataID, out string wdtFilename))
            {
                Logger.WriteLine("ADT OBJ Exporter: WDT {0} has no known filename, skipping export!", wdtFileDataID);
                return;
            }

            var mapName = Path.GetFileNameWithoutExtension(wdtFilename);
            var file    = "world/maps/" + mapName + "/" + mapName + "_" + tileX.ToString() + "_" + tileY.ToString() + ".adt";

            var reader = new ADTReader();

            reader.LoadADT(wdtFileDataID, tileX, tileY, true, wdtFilename);

            var adt = reader.adtfile;

            if (adt.chunks == null)
            {
                Logger.WriteLine("ADT OBJ Exporter: File {0} has no chunks, skipping export!", file);
                return;
            }

            Logger.WriteLine("ADT OBJ Exporter: Starting export of {0}..", file);

            Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file)));

            exportworker.ReportProgress(0, "Loading ADT " + file);

            var renderBatches = new List <Structs.RenderBatch>();
            var verticelist   = new List <Structs.Vertex>();
            var indicelist    = new List <int>();
            var materials     = new Dictionary <int, string>();

            ConfigurationManager.RefreshSection("appSettings");
            var bakeQuality = ConfigurationManager.AppSettings["bakeQuality"];

            // Calculate ADT offset in world coordinates
            var adtStartX = ((adt.x - 32) * TileSize) * -1;
            var adtStartY = ((adt.y - 32) * TileSize) * -1;

            // Calculate first chunk offset in world coordinates
            var initialChunkX = adtStartY + (adt.chunks[0].header.indexX * ChunkSize) * -1;
            var initialChunkY = adtStartX + (adt.chunks[0].header.indexY * ChunkSize) * -1;

            uint ci = 0;

            for (var x = 0; x < 16; x++)
            {
                double xOfs = x / 16d;
                for (var y = 0; y < 16; y++)
                {
                    double yOfs = y / 16d;

                    var genx = (initialChunkX + (ChunkSize * x) * -1);
                    var geny = (initialChunkY + (ChunkSize * y) * -1);

                    var chunk = adt.chunks[ci];

                    var off = verticelist.Count();

                    var batch = new Structs.RenderBatch();

                    for (int i = 0, idx = 0; i < 17; i++)
                    {
                        bool isSmallRow = (i % 2) != 0;
                        int  rowLength  = isSmallRow ? 8 : 9;

                        for (var j = 0; j < rowLength; j++)
                        {
                            var v = new Structs.Vertex();

                            v.Normal = new Structs.Vector3D
                            {
                                X = (double)chunk.normals.normal_0[idx] / 127,
                                Y = (double)chunk.normals.normal_2[idx] / 127,
                                Z = (double)chunk.normals.normal_1[idx] / 127
                            };

                            var px = geny - (j * UnitSize);
                            var py = chunk.vertices.vertices[idx++] + chunk.header.position.Z;
                            var pz = genx - (i * UnitSizeHalf);

                            v.Position = new Structs.Vector3D
                            {
                                X = px,
                                Y = py,
                                Z = pz
                            };

                            if ((i % 2) != 0)
                            {
                                v.Position.X = (px - UnitSizeHalf);
                            }

                            double ofs = j;
                            if (isSmallRow)
                            {
                                ofs += 0.5;
                            }

                            if (bakeQuality == "none")
                            {
                                v.TexCoord = new Structs.Vector2D {
                                    X = (j + (((i % 2) != 0) ? 0.5f : 0f)) / 8f, Y = (i * 0.5f) / 8f
                                };
                            }
                            else if (bakeQuality == "high")
                            {
                                double tx = ofs / 8d;
                                double ty = 1 - (i / 16d);
                                v.TexCoord = new Structs.Vector2D {
                                    X = tx, Y = ty
                                };
                            }
                            else
                            {
                                double tx = -(v.Position.X - initialChunkY) / TileSize;
                                double ty = (v.Position.Z - initialChunkX) / TileSize;

                                v.TexCoord = new Structs.Vector2D {
                                    X = tx, Y = ty
                                };
                            }
                            verticelist.Add(v);
                        }
                    }

                    batch.firstFace = (uint)indicelist.Count();

                    // Stupid C# and its structs
                    var holesHighRes = new byte[8];
                    holesHighRes[0] = chunk.header.holesHighRes_0;
                    holesHighRes[1] = chunk.header.holesHighRes_1;
                    holesHighRes[2] = chunk.header.holesHighRes_2;
                    holesHighRes[3] = chunk.header.holesHighRes_3;
                    holesHighRes[4] = chunk.header.holesHighRes_4;
                    holesHighRes[5] = chunk.header.holesHighRes_5;
                    holesHighRes[6] = chunk.header.holesHighRes_6;
                    holesHighRes[7] = chunk.header.holesHighRes_7;

                    for (int j = 9, xx = 0, yy = 0; j < 145; j++, xx++)
                    {
                        if (xx >= 8)
                        {
                            xx = 0; ++yy;
                        }
                        var isHole = true;

                        // Check if chunk is using low-res holes
                        if ((chunk.header.flags & 0x10000) == 0)
                        {
                            // Calculate current hole number
                            var currentHole = (int)Math.Pow(2,
                                                            Math.Floor(xx / 2f) * 1f +
                                                            Math.Floor(yy / 2f) * 4f);

                            // Check if current hole number should be a hole
                            if ((chunk.header.holesLowRes & currentHole) == 0)
                            {
                                isHole = false;
                            }
                        }

                        else
                        {
                            // Check if current section is a hole
                            if (((holesHighRes[yy] >> xx) & 1) == 0)
                            {
                                isHole = false;
                            }
                        }

                        if (!isHole)
                        {
                            indicelist.AddRange(new int[] { off + j + 8, off + j - 9, off + j });
                            indicelist.AddRange(new int[] { off + j - 9, off + j - 8, off + j });
                            indicelist.AddRange(new int[] { off + j - 8, off + j + 9, off + j });
                            indicelist.AddRange(new int[] { off + j + 9, off + j + 8, off + j });

                            // Generates quads instead of 4x triangles
                            //indicelist.AddRange(new int[] { off + j + 8, off + j - 9, off + j - 8 });
                            //indicelist.AddRange(new int[] { off + j - 8, off + j + 9, off + j + 8 });
                        }

                        if ((j + 1) % (9 + 8) == 0)
                        {
                            j += 9;
                        }
                    }

                    if (bakeQuality == "high")
                    {
                        materials.Add((int)ci + 1, Path.GetFileNameWithoutExtension(file).Replace(" ", "") + "_" + ci);
                        batch.materialID = ci + 1;
                    }
                    else
                    {
                        if (!materials.ContainsKey(1))
                        {
                            materials.Add(1, Path.GetFileNameWithoutExtension(file).Replace(" ", ""));
                        }
                        batch.materialID = (uint)materials.Count();
                    }

                    batch.numFaces = (uint)(indicelist.Count()) - batch.firstFace;

                    if (bakeQuality == "none")
                    {
                        // Build alpha textures, export raw and height textures
                        var rawMaterials = new List <Renderer.Structs.Material>();

                        if (adt.textures.filenames == null)
                        {
                            for (var ti = 0; ti < adt.diffuseTextureFileDataIDs.Count(); ti++)
                            {
                                var material = new Renderer.Structs.Material();
                                material.filename  = adt.diffuseTextureFileDataIDs[ti].ToString();
                                material.textureID = (int)adt.diffuseTextureFileDataIDs[ti];

                                if (adt.texParams != null && adt.texParams.Count() >= ti)
                                {
                                    material.scale = (float)Math.Pow(2, (adt.texParams[ti].flags & 0xF0) >> 4);
                                    if (adt.texParams[ti].height != 0.0 || adt.texParams[ti].offset != 1.0)
                                    {
                                        material.heightScale  = adt.texParams[ti].height;
                                        material.heightOffset = adt.texParams[ti].offset;

                                        if (!WoWFormatLib.Utils.CASC.FileExists(adt.heightTextureFileDataIDs[ti]))
                                        {
                                            Console.WriteLine("Height texture: " + adt.heightTextureFileDataIDs[ti] + " does not exist! Falling back to original texture (hack)..");
                                            material.heightTexture = (int)adt.diffuseTextureFileDataIDs[ti];
                                        }
                                        else
                                        {
                                            material.heightTexture = (int)adt.heightTextureFileDataIDs[ti];
                                        }
                                    }
                                    else
                                    {
                                        material.heightScale  = 0.0f;
                                        material.heightOffset = 1.0f;
                                    }
                                }
                                else
                                {
                                    material.heightScale  = 0.0f;
                                    material.heightOffset = 1.0f;
                                    material.scale        = 1.0f;
                                }
                                rawMaterials.Add(material);
                            }
                        }
                        else
                        {
                            for (var ti = 0; ti < adt.textures.filenames.Count(); ti++)
                            {
                                var material = new Renderer.Structs.Material();
                                material.filename  = adt.textures.filenames[ti];
                                material.textureID = (int)WoWFormatLib.Utils.CASC.getFileDataIdByName(adt.textures.filenames[ti]);

                                if (adt.texParams != null && adt.texParams.Count() >= ti)
                                {
                                    material.scale = (float)Math.Pow(2, (adt.texParams[ti].flags & 0xF0) >> 4);
                                    if (adt.texParams[ti].height != 0.0 || adt.texParams[ti].offset != 1.0)
                                    {
                                        material.heightScale  = adt.texParams[ti].height;
                                        material.heightOffset = adt.texParams[ti].offset;

                                        var heightName = adt.textures.filenames[ti].Replace(".blp", "_h.blp");
                                        if (!WoWFormatLib.Utils.CASC.FileExists(heightName))
                                        {
                                            Console.WriteLine("Height texture: " + heightName + " does not exist! Falling back to original texture (hack)..");
                                            material.heightTexture = (int)WoWFormatLib.Utils.CASC.getFileDataIdByName(adt.textures.filenames[ti]);
                                        }
                                        else
                                        {
                                            material.heightTexture = (int)WoWFormatLib.Utils.CASC.getFileDataIdByName(heightName);
                                        }
                                    }
                                    else
                                    {
                                        material.heightScale  = 0.0f;
                                        material.heightOffset = 1.0f;
                                    }
                                }
                                else
                                {
                                    material.heightScale  = 0.0f;
                                    material.heightOffset = 1.0f;
                                    material.scale        = 1.0f;
                                }
                                rawMaterials.Add(material);
                            }
                        }

                        var layerMaterials = new List <uint>();
                        var alphalayermats = new List <int>();
                        var layerscales    = new List <float>();
                        var layerheights   = new List <int>();

                        //batch.heightScales = new Vector4();
                        //batch.heightOffsets = new Vector4();
                        exportworker.ReportProgress(10, "Exporting alpha layers " + file);

                        var baseTextureName      = Path.Combine(outdir, Path.GetDirectoryName(file), "terraindiffuse", Path.GetFileNameWithoutExtension(file).Replace(" ", ""));
                        var baseAlphaTextureName = Path.Combine(outdir, Path.GetDirectoryName(file), "terrainalpha", Path.GetFileNameWithoutExtension(file).Replace(" ", ""));
                        Directory.CreateDirectory(Path.GetDirectoryName(baseAlphaTextureName));

                        var pixels = new byte[4, 4096];

                        for (var li = 0; li < adt.texChunks[ci].layers.Count(); li++)
                        {
                            if (adt.texChunks[ci].alphaLayer != null)
                            {
                                var values = adt.texChunks[ci].alphaLayer[li].layer;
                                for (var tx = 0; tx < 64; tx++)
                                {
                                    for (var ty = 0; ty < 64; ty++)
                                    {
                                        pixels[li, tx * 64 + ty] = values[tx * 64 + ty];
                                    }
                                }
                            }

                            Renderer.Structs.Material curMat;

                            if (adt.diffuseTextureFileDataIDs == null)
                            {
                                if (adt.textures.filenames == null)
                                {
                                    throw new Exception("ADT has no textures?");
                                }

                                var texFileDataID = WoWFormatLib.Utils.CASC.getFileDataIdByName(adt.textures.filenames[adt.texChunks[ci].layers[li].textureId]);

                                //layerMaterials.Add((uint)BLPLoader.LoadTexture(texFileDataID));
                                curMat = rawMaterials.Where(material => material.filename == adt.textures.filenames[adt.texChunks[ci].layers[li].textureId]).Single();
                            }
                            else
                            {
                                //layerMaterials.Add((uint)BLPLoader.LoadTexture(adt.diffuseTextureFileDataIDs[adt.texChunks[ci].layers[li].textureId]));
                                curMat = rawMaterials.Where(material => material.filename == adt.diffuseTextureFileDataIDs[adt.texChunks[ci].layers[li].textureId].ToString()).Single();
                                //Console.WriteLine(ci + " " + li + " " + curMat.filename);
                            }

                            //layerscales.Add(curMat.scale);
                            //layerheights.Add(curMat.heightTexture);

                            //batch.heightScales[li] = curMat.heightScale;
                            //batch.heightOffsets[li] = curMat.heightOffset;
                        }

                        //batch.materialID = layerMaterials.ToArray();
                        //batch.alphaMaterialID = alphalayermats.ToArray();
                        //batch.scales = layerscales.ToArray();
                        //batch.heightMaterialIDs = layerheights.ToArray();

                        using (var bmp = new System.Drawing.Bitmap(64, 64))
                        {
                            for (var tx = 0; tx < 64; tx++)
                            {
                                for (var ty = 0; ty < 64; ty++)
                                {
                                    var color = System.Drawing.Color.FromArgb(pixels[0, tx * 64 + ty], pixels[1, tx * 64 + ty], pixels[2, tx * 64 + ty], pixels[3, tx * 64 + ty]);
                                    bmp.SetPixel(ty, tx, color);
                                }
                            }

                            bmp.Save(baseAlphaTextureName + "_" + ci + ".png", System.Drawing.Imaging.ImageFormat.Png);
                        }
                    }

                    renderBatches.Add(batch);
                    ci++;
                }
            }

            ConfigurationManager.RefreshSection("appSettings");

            bool exportWMO     = ConfigurationManager.AppSettings["exportWMO"] == "True";
            bool exportM2      = ConfigurationManager.AppSettings["exportM2"] == "True";
            bool exportFoliage = ConfigurationManager.AppSettings["exportFoliage"] == "True";

            if (exportFoliage)
            {
                exportworker.ReportProgress(65, "Exporting ADT foliage");

                try
                {
                    var build = WoWFormatLib.Utils.CASC.BuildName;
                    var dbcd  = new DBCD.DBCD(new DBC.CASCDBCProvider(), new GithubDBDProvider());
                    var groundEffectTextureDB = dbcd.Load("GroundEffectTexture");
                    var groundEffectDoodadDB  = dbcd.Load("GroundEffectDoodad");
                    for (var c = 0; c < reader.adtfile.texChunks.Length; c++)
                    {
                        for (var l = 0; l < reader.adtfile.texChunks[c].layers.Length; l++)
                        {
                            var effectID = reader.adtfile.texChunks[c].layers[l].effectId;
                            if (effectID == 0)
                            {
                                continue;
                            }

                            if (!groundEffectTextureDB.ContainsKey(effectID))
                            {
                                continue;
                            }

                            dynamic textureEntry = groundEffectTextureDB[effectID];
                            foreach (int doodad in textureEntry.DoodadID)
                            {
                                if (!groundEffectDoodadDB.ContainsKey(doodad))
                                {
                                    continue;
                                }

                                dynamic doodadEntry = groundEffectDoodadDB[doodad];

                                var filedataid = (uint)doodadEntry.ModelFileID;

                                if (!Listfile.TryGetFilename(filedataid, out var filename))
                                {
                                    Logger.WriteLine("Could not find filename for " + filedataid + ", setting filename to filedataid..");
                                    filename = filedataid.ToString();
                                }

                                if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file), "foliage")))
                                {
                                    Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file), "foliage"));
                                }

                                if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file), "foliage", Path.GetFileNameWithoutExtension(filename).ToLower() + ".obj")))
                                {
                                    M2Exporter.ExportM2(filedataid, null, Path.Combine(outdir, Path.GetDirectoryName(file), "foliage"), filename);
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Logger.WriteLine("Error exporting GroundEffects: " + e.Message);
                }
            }

            if (exportWMO || exportM2)
            {
                var doodadSW = new StreamWriter(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(file).Replace(" ", "") + "_ModelPlacementInformation.csv"));
                doodadSW.WriteLine("ModelFile;PositionX;PositionY;PositionZ;RotationX;RotationY;RotationZ;ScaleFactor;ModelId;Type");

                if (exportWMO)
                {
                    exportworker.ReportProgress(25, "Exporting ADT worldmodels");

                    for (var mi = 0; mi < reader.adtfile.objects.worldModels.entries.Count(); mi++)
                    {
                        var wmo = reader.adtfile.objects.worldModels.entries[mi];

                        var  filename   = "";
                        uint filedataid = 0;

                        if (reader.adtfile.objects.wmoNames.filenames == null)
                        {
                            filedataid = wmo.mwidEntry;
                            if (!Listfile.TryGetFilename(filedataid, out filename))
                            {
                                Logger.WriteLine("Warning! Could not find filename for " + filedataid + ", setting filename to filedataid..");
                                filename = filedataid.ToString() + ".wmo";
                            }
                        }
                        else
                        {
                            Logger.WriteLine("Warning!! File " + filename + " ID: " + filedataid + " still has filenames!");
                            filename = reader.adtfile.objects.wmoNames.filenames[wmo.mwidEntry];
                            if (!Listfile.TryGetFileDataID(filename, out filedataid))
                            {
                                Logger.WriteLine("Error! Could not find filedataid for " + filename + "!");
                                continue;
                            }
                        }

                        short doodadSet = -1;
                        if (ConfigurationManager.AppSettings["exportWMODoodads"] == "True")
                        {
                            doodadSet = (short)wmo.doodadSet;
                        }

                        if (string.IsNullOrEmpty(filename))
                        {
                            string wmoFile = Path.Combine(outdir, Path.GetDirectoryName(file), filedataid.ToString() + ".obj");
                            if (!File.Exists(wmoFile))
                            {
                                WMOExporter.ExportWMO(filedataid, exportworker, Path.Combine(outdir, Path.GetDirectoryName(file)), doodadSet);
                            }

                            if (File.Exists(wmoFile))
                            {
                                doodadSW.WriteLine(filedataid + ".obj;" + wmo.position.X + ";" + wmo.position.Y + ";" + wmo.position.Z + ";" + wmo.rotation.X + ";" + wmo.rotation.Y + ";" + wmo.rotation.Z + ";" + wmo.scale / 1024f + ";" + wmo.uniqueId + ";wmo");
                            }
                        }
                        else
                        {
                            string wmoFile = Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(filename).ToLower() + ".obj");
                            if (!File.Exists(wmoFile))
                            {
                                WMOExporter.ExportWMO(filedataid, exportworker, Path.Combine(outdir, Path.GetDirectoryName(file)), doodadSet, filename);
                            }

                            if (File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(filename).ToLower() + ".obj")))
                            {
                                doodadSW.WriteLine(Path.GetFileNameWithoutExtension(filename).ToLower() + ".obj;" + wmo.position.X + ";" + wmo.position.Y + ";" + wmo.position.Z + ";" + wmo.rotation.X + ";" + wmo.rotation.Y + ";" + wmo.rotation.Z + ";" + wmo.scale / 1024f + ";" + wmo.uniqueId + ";wmo");
                            }
                        }
                    }
                }

                if (exportM2)
                {
                    exportworker.ReportProgress(50, "Exporting ADT doodads");

                    for (var mi = 0; mi < reader.adtfile.objects.models.entries.Count(); mi++)
                    {
                        var doodad = reader.adtfile.objects.models.entries[mi];

                        string filename;
                        uint   filedataid;

                        if (reader.adtfile.objects.m2Names.filenames == null)
                        {
                            filedataid = doodad.mmidEntry;
                            if (!Listfile.TryGetFilename(filedataid, out filename))
                            {
                                Logger.WriteLine("Could not find filename for " + filedataid + ", setting filename to filedataid..");
                                filename = filedataid.ToString();
                            }
                        }
                        else
                        {
                            filename = reader.adtfile.objects.m2Names.filenames[doodad.mmidEntry].ToLower();
                            if (!Listfile.TryGetFileDataID(filename, out filedataid))
                            {
                                Logger.WriteLine("Error! Could not find filedataid for " + filename + "!");
                                continue;
                            }
                        }

                        if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(filename) + ".obj")))
                        {
                            M2Exporter.ExportM2(filedataid, null, Path.Combine(outdir, Path.GetDirectoryName(file)), filename);
                        }

                        if (File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(filename) + ".obj")))
                        {
                            doodadSW.WriteLine(Path.GetFileNameWithoutExtension(filename) + ".obj;" + doodad.position.X + ";" + doodad.position.Y + ";" + doodad.position.Z + ";" + doodad.rotation.X + ";" + doodad.rotation.Y + ";" + doodad.rotation.Z + ";" + doodad.scale / 1024f + ";" + doodad.uniqueId + ";m2");
                        }
                    }
                }

                doodadSW.Close();
            }

            exportworker.ReportProgress(75, "Exporting terrain textures..");

            if (bakeQuality != "none")
            {
                var mtlsw = new StreamWriter(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(file).Replace(" ", "") + ".mtl"));

                //No idea how MTL files really work yet. Needs more investigation.
                foreach (var material in materials)
                {
                    mtlsw.WriteLine("newmtl " + material.Value.Replace(" ", ""));
                    mtlsw.WriteLine("Ka 1.000000 1.000000 1.000000");
                    mtlsw.WriteLine("Kd 0.640000 0.640000 0.640000");
                    mtlsw.WriteLine("map_Ka " + material.Value.Replace(" ", "") + ".png");
                    mtlsw.WriteLine("map_Kd " + material.Value.Replace(" ", "") + ".png");
                }

                mtlsw.Close();
            }

            exportworker.ReportProgress(85, "Exporting terrain geometry..");

            var indices = indicelist.ToArray();

            var adtname = Path.GetFileNameWithoutExtension(file);

            var objsw = new StreamWriter(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(file).Replace(" ", "") + ".obj"));

            objsw.WriteLine("# Written by Marlamin's WoW OBJExporter. Original file: " + file);
            if (bakeQuality != "none")
            {
                objsw.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(file).Replace(" ", "") + ".mtl");
            }

            var verticeCounter = 1;
            var chunkCounter   = 1;

            foreach (var vertex in verticelist)
            {
                //objsw.WriteLine("# C" + chunkCounter + ".V" + verticeCounter);
                objsw.WriteLine("v " + vertex.Position.X.ToString("R") + " " + vertex.Position.Y.ToString("R") + " " + vertex.Position.Z.ToString("R"));
                objsw.WriteLine("vt " + vertex.TexCoord.X + " " + vertex.TexCoord.Y);
                objsw.WriteLine("vn " + vertex.Normal.X.ToString("R") + " " + vertex.Normal.Y.ToString("R") + " " + vertex.Normal.Z.ToString("R"));
                verticeCounter++;
                if (verticeCounter == 146)
                {
                    chunkCounter++;
                    verticeCounter = 1;
                }
            }

            if (bakeQuality == "minimap" || bakeQuality == "low" || bakeQuality == "medium")
            {
                objsw.WriteLine("g " + adtname.Replace(" ", ""));
                objsw.WriteLine("usemtl " + materials[1]);
                objsw.WriteLine("s 1");
            }

            for (int rbi = 0; rbi < renderBatches.Count(); rbi++)
            {
                var renderBatch = renderBatches[rbi];
                var i           = renderBatch.firstFace;
                if (bakeQuality == "high" || bakeQuality == "none")
                {
                    objsw.WriteLine("g " + adtname.Replace(" ", "") + "_" + rbi);
                }

                if (bakeQuality == "high" && materials.ContainsKey((int)renderBatch.materialID))
                {
                    objsw.WriteLine("usemtl " + materials[(int)renderBatch.materialID]);
                }

                while (i < (renderBatch.firstFace + renderBatch.numFaces))
                {
                    objsw.WriteLine("f " +
                                    (indices[i + 2] + 1) + "/" + (indices[i + 2] + 1) + "/" + (indices[i + 2] + 1) + " " +
                                    (indices[i + 1] + 1) + "/" + (indices[i + 1] + 1) + "/" + (indices[i + 1] + 1) + " " +
                                    (indices[i] + 1) + "/" + (indices[i] + 1) + "/" + (indices[i] + 1));
                    i = i + 3;
                }
            }

            objsw.Close();

            Logger.WriteLine("ADT OBJ Exporter: Finished with export of {0}..", file);
        }
示例#6
0
        static void Main(string[] args)
        {
            if (args.Length < 4)
            {
                throw new ArgumentException("Required arguments: cdndir, buildconfig, cdnconfig, outdir");
            }

            var cdndir = args[0];
            var bc     = args[1];
            var cdnc   = args[2];
            var outdir = args[3];

            var mapFilter = "";

            if (args.Length == 5)
            {
                mapFilter = args[4];
            }

            // Open storage for specific build
            TACTRepo tactRepo = new TACTRepo(cdndir)
            {
                ConfigContainer = new ConfigContainer()
            };

            Console.WriteLine("Loading configs..");
            tactRepo.ConfigContainer.OpenLocal(tactRepo.BaseDirectory, bc, cdnc);

            Console.WriteLine("Loading indices..");
            tactRepo.IndexContainer = new TACT.Net.Indices.IndexContainer();
            tactRepo.IndexContainer.Open(tactRepo.BaseDirectory, tactRepo.ConfigContainer);

            Console.WriteLine("Loading encoding..");
            tactRepo.EncodingFile = new TACT.Net.Encoding.EncodingFile(tactRepo.BaseDirectory, tactRepo.ConfigContainer.EncodingEKey);

            Console.WriteLine("Looking up root..");
            tactRepo.EncodingFile.TryGetCKeyEntry(tactRepo.ConfigContainer.RootCKey, out var rootCEntry);

            Console.WriteLine("Loading root..");
            tactRepo.RootFile = new TACT.Net.Root.RootFile(tactRepo.BaseDirectory, rootCEntry.EKey);

            Console.WriteLine("Loading TACT keys..");
            try
            {
                using (var client = new HttpClient())
                {
                    var result = client.GetAsync("https://wow.tools/api.php?type=tactkeys").Result;
                    var keys   = result.Content.ReadAsStringAsync().Result.Split('\n');
                    foreach (var key in keys)
                    {
                        var split = key.Split(' ');
                        if (split.Length < 2)
                        {
                            continue;
                        }

                        var keyname  = Convert.ToUInt64(split[0], 16);
                        var keybytes = split[1];
                        if (TACT.Net.Cryptography.KeyService.TryAddKey(keyname, keybytes))
                        {
                            Console.WriteLine("Added TACT key " + split[0]);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred retrieving/loading TACT keys: " + e.Message);
            }

            // Set up DBCD
            var dbdProvider = new GithubDBDProvider();
            var dbcProvider = new TACTDBCProvider(tactRepo);
            var dbcd        = new DBCD.DBCD(dbcProvider, dbdProvider);

            // Open Map DBC with local defs
            Console.WriteLine("Opening Map.db2..");

            // This will currently crash on partially encrypted DBs with unknown keys due to https://github.com/wowdev/TACT.Net/issues/12
            var mapdb = dbcd.Load("Map");

            // Run through map db
            Console.WriteLine("Extracting tiles..");

            foreach (dynamic map in mapdb.Values)
            {
                if (!string.IsNullOrEmpty(mapFilter) && map.Directory != mapFilter)
                {
                    continue;
                }

                Console.WriteLine(map.Directory);

                // Load WDT
                Stream wdtStream;

                try
                {
                    if (map.WdtFileDataID == 0)
                    {
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Console.WriteLine("Skipping map " + map.Directory + " with no WDT!");
                        Console.ResetColor();
                        continue;
                    }

                    wdtStream = tactRepo.RootFile.OpenFile((uint)map.WdtFileDataID, tactRepo);
                }
                catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException e)
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("Older build detected: map record has no wdtFileDataID property");
                    Console.ResetColor();
                    wdtStream = tactRepo.RootFile.OpenFile("world/maps/" + map.Directory + "/" + map.Directory + ".wdt", tactRepo);
                }

                if (wdtStream == null)
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("Skipping map " + map.Directory + " with unshipped WDT!");
                    Console.ResetColor();
                    continue;
                }

                var minimapFDIDs = WDT.FileDataIdsFromWDT(wdtStream);
                if (minimapFDIDs.Count() == 0)
                {
                    // Pre-MAID build, extract by filename
                    for (var x = 0; x < 64; x++)
                    {
                        for (var y = 0; y < 64; y++)
                        {
                            string tileName      = "world/minimaps/" + map.Directory + "/map" + x.ToString().PadLeft(2, '0') + "_" + y.ToString().PadLeft(2, '0') + ".blp";
                            var    minimapStream = tactRepo.RootFile.OpenFile(tileName, tactRepo);
                            if (minimapStream == null)
                            {
                                continue;
                            }

                            var minimapName = "map" + x.ToString().PadLeft(2, '0') + "_" + y.ToString().PadLeft(2, '0') + ".blp";
                            var minimapPath = Path.Combine(outdir, "world", "minimaps", map.Directory, minimapName);

                            Directory.CreateDirectory(Path.GetDirectoryName(minimapPath));

                            using (var fileStream = File.Create(minimapPath))
                            {
                                minimapStream.CopyTo(fileStream);
                            }
                        }
                    }
                }
                else
                {
                    // Extract tiles by FDID
                    minimapFDIDs = minimapFDIDs.Where(chunk => chunk.fileDataId != 0).ToArray();
                    foreach (var minimap in minimapFDIDs)
                    {
                        var minimapStream = tactRepo.RootFile.OpenFile(minimap.fileDataId, tactRepo);
                        if (minimapStream == null)
                        {
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.WriteLine("Unable to extract minimap " + minimap.fileDataId + " for tile " + minimap.x + "_" + minimap.y);
                            Console.ResetColor();
                            continue;
                        }

                        var minimapName = "map" + minimap.x.ToString().PadLeft(2, '0') + "_" + minimap.y.ToString().PadLeft(2, '0') + ".blp";
                        var minimapPath = Path.Combine(outdir, "world", "minimaps", map.Directory, minimapName);

                        Directory.CreateDirectory(Path.GetDirectoryName(minimapPath));

                        using (var fileStream = File.Create(minimapPath))
                        {
                            minimapStream.CopyTo(fileStream);
                        }
                    }
                }
            }

            // Append any filenames from listfile for additional non-WDT referenced minimaps?
        }
示例#7
0
        public static void exportADT(string file, string outdir, string bakeQuality, BackgroundWorker exportworker = null)
        {
            if (exportworker == null)
            {
                exportworker = new BackgroundWorker
                {
                    WorkerReportsProgress = true
                };
            }

            var customCulture = (System.Globalization.CultureInfo)System.Threading.Thread.CurrentThread.CurrentCulture.Clone();

            customCulture.NumberFormat.NumberDecimalSeparator    = ".";
            System.Threading.Thread.CurrentThread.CurrentCulture = customCulture;

            var MaxSize      = 51200 / 3.0;
            var TileSize     = MaxSize / 32.0;
            var ChunkSize    = TileSize / 16.0;
            var UnitSize     = ChunkSize / 8.0;
            var UnitSizeHalf = UnitSize / 2.0;

            string mapname = file;

            mapname = mapname.Substring(mapname.LastIndexOf("\\", mapname.Length - 2) + 1);
            mapname = mapname.Substring(0, mapname.Length - 4);

            var reader = new ADTReader();

            var ADTfile = file;

            exportworker.ReportProgress(0, "Loading ADT " + file);

            if (Managers.ConfigurationManager.Profile <= 3) //WoTLK and below
            {
                reader.Load335ADT(ADTfile);
            }
            else
            {
                reader.LoadADT(ADTfile);
            }

            if (reader.adtfile.chunks == null)
            {
                throw new Exception("ADT OBJ Exporter: File has no chunks, skipping export!");
            }

            if (!Directory.Exists(Path.Combine(outdir, Path.GetDirectoryName(file))))
            {
                Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file)));
            }

            var renderBatches = new List <Structs.RenderBatch>();
            var verticelist   = new List <Structs.Vertex>();
            var indicelist    = new List <int>();
            var materials     = new Dictionary <int, string>();

            // Calculate ADT offset in world coordinates
            var adtStartX = reader.adtfile.chunks[0].header.position.X;
            var adtStartY = reader.adtfile.chunks[0].header.position.Y;

            // Calculate first chunk offset in world coordinates
            var initialChunkX = adtStartX + (reader.adtfile.chunks[0].header.indexX * ChunkSize) * -1;
            var initialChunkY = adtStartY + (reader.adtfile.chunks[0].header.indexY * ChunkSize) * -1;

            uint ci = 0;

            for (var x = 0; x < 16; x++)
            {
                for (var y = 0; y < 16; y++)
                {
                    var genx = (initialChunkX + (ChunkSize * x) * -1);
                    var geny = (initialChunkY + (ChunkSize * y) * -1);

                    var chunk = reader.adtfile.chunks[ci];

                    var off = verticelist.Count();

                    var batch = new Structs.RenderBatch();

                    for (int row = 0, idx = 0; row < 17; row++)
                    {
                        bool isSmallRow = (row % 2) != 0;
                        int  rowLength  = isSmallRow ? 8 : 9;

                        for (var col = 0; col < rowLength; col++)
                        {
                            var v = new Structs.Vertex();

                            v.Normal = new Structs.Vector3D
                            {
                                X = (double)chunk.normals.normal_0[idx] / 127,
                                Y = (double)chunk.normals.normal_2[idx] / 127,
                                Z = (double)chunk.normals.normal_1[idx] / 127
                            };

                            var px = geny - (col * UnitSize);
                            var py = chunk.vertices.vertices[idx++] + chunk.header.position.Z;
                            var pz = genx - (row * UnitSizeHalf);

                            v.Position = new Structs.Vector3D
                            {
                                X = px,
                                Y = py,
                                Z = pz
                            };

                            if ((row % 2) != 0)
                            {
                                v.Position.X = (px - UnitSizeHalf);
                            }

                            double ofs = col;
                            if (isSmallRow)
                            {
                                ofs += 0.5;
                            }

                            if (bakeQuality == "high")
                            {
                                double tx = ofs / 8d;
                                double ty = 1 - (row / 16d);
                                v.TexCoord = new Structs.Vector2D {
                                    X = tx, Y = ty
                                };
                            }
                            else
                            {
                                double tx = -(v.Position.X - initialChunkY) / TileSize;
                                double ty = (v.Position.Z - initialChunkX) / TileSize;

                                v.TexCoord = new Structs.Vector2D {
                                    X = tx, Y = ty
                                };
                            }
                            verticelist.Add(v);
                        }
                    }

                    batch.firstFace = (uint)indicelist.Count();

                    // Stupid C# and its structs
                    var holesHighRes = new byte[8];
                    holesHighRes[0] = chunk.header.holesHighRes_0;
                    holesHighRes[1] = chunk.header.holesHighRes_1;
                    holesHighRes[2] = chunk.header.holesHighRes_2;
                    holesHighRes[3] = chunk.header.holesHighRes_3;
                    holesHighRes[4] = chunk.header.holesHighRes_4;
                    holesHighRes[5] = chunk.header.holesHighRes_5;
                    holesHighRes[6] = chunk.header.holesHighRes_6;
                    holesHighRes[7] = chunk.header.holesHighRes_7;

                    for (int j = 9, xx = 0, yy = 0; j < 145; j++, xx++)
                    {
                        if (xx >= 8)
                        {
                            xx = 0; ++yy;
                        }
                        var isHole = true;

                        // Check if chunk is using low-res holes
                        if ((chunk.header.flags & 0x10000) == 0)
                        {
                            // Calculate current hole number
                            var currentHole = (int)Math.Pow(2,
                                                            Math.Floor(xx / 2f) * 1f +
                                                            Math.Floor(yy / 2f) * 4f);

                            // Check if current hole number should be a hole
                            if ((chunk.header.holesLowRes & currentHole) == 0)
                            {
                                isHole = false;
                            }
                        }

                        //Sloppy ignore holes:
                        if (Managers.ConfigurationManager.ADTIgnoreHoles)
                        {
                            isHole = false;
                        }
                        else
                        {
                            // Check if current section is a hole
                            if (((holesHighRes[yy] >> xx) & 1) == 0)
                            {
                                isHole = false;
                            }
                        }

                        if (!isHole)
                        {
                            indicelist.AddRange(new int[] { off + j + 8, off + j - 9, off + j });
                            indicelist.AddRange(new int[] { off + j - 9, off + j - 8, off + j });
                            indicelist.AddRange(new int[] { off + j - 8, off + j + 9, off + j });
                            indicelist.AddRange(new int[] { off + j + 9, off + j + 8, off + j });

                            // Generates quads instead of 4x triangles
                            //indicelist.AddRange(new int[] { off + j + 8, off + j - 9, off + j - 8 });
                            //indicelist.AddRange(new int[] { off + j - 8, off + j + 9, off + j + 8 });
                        }
                        if ((j + 1) % (9 + 8) == 0)
                        {
                            j += 9;
                        }
                    }

                    if (bakeQuality == "high")
                    {
                        materials.Add((int)ci + 1, Path.GetFileNameWithoutExtension(file) + "_" + ci);
                        batch.materialID = ci + 1;
                    }
                    else
                    {
                        if (!materials.ContainsKey(1))
                        {
                            materials.Add(1, Path.GetFileNameWithoutExtension(file));
                        }
                        batch.materialID = (uint)materials.Count();
                    }
                    batch.numFaces = (uint)(indicelist.Count()) - batch.firstFace;

                    renderBatches.Add(batch);
                    ci++;
                }
            }

            bool exportWMO       = Managers.ConfigurationManager.ADTExportWMO;
            bool exportM2        = Managers.ConfigurationManager.ADTExportM2;
            bool exportTextures  = Managers.ConfigurationManager.ADTexportTextures;
            bool exportAlphaMaps = Managers.ConfigurationManager.ADTexportAlphaMaps;
            bool exportHeightmap = Managers.ConfigurationManager.ADTExportHeightmap;
            bool exportFoliage   = Managers.ConfigurationManager.ADTExportFoliage;

            //FOLIAGE
            if (exportFoliage && Managers.ArchiveManager.usingCasc) //ONLY EXPROT IF CASC; PRE CASC NEEDS TO BE IMPLEMEMNTED
            {
                exportworker.ReportProgress(65, "Exporting foliage");

                try
                {
                    var build = Managers.ArchiveManager.cascHandler.Config.VersionName; //TODO: IMPLEMENT PRE CASC BUILDS
                    var dbcd  = new DBCD.DBCD(new WoWExport.DBC.ArchiveDBCProvider(), new WoWExport.DBC.LocalDBCDProvider());
                    var groundEffectTextureDB = dbcd.Load("GroundEffectTexture", build);
                    var groundEffectDoodadDB  = dbcd.Load("GroundEffectDoodad", build);

                    for (var c = 0; c < reader.adtfile.texChunks.Length; c++)
                    {
                        for (var l = 0; l < reader.adtfile.texChunks[c].layers.Length; l++)
                        {
                            var effectID = reader.adtfile.texChunks[c].layers[l].effectId;
                            if (effectID == 0)
                            {
                                continue;
                            }

                            if (!groundEffectTextureDB.ContainsKey(effectID))
                            {
                                continue;
                            }

                            dynamic textureEntry = groundEffectTextureDB[effectID];
                            foreach (int doodad in textureEntry.DoodadID)
                            {
                                if (!groundEffectDoodadDB.ContainsKey(doodad))
                                {
                                    continue;
                                }

                                dynamic doodadEntry = groundEffectDoodadDB[doodad];

                                var filedataid = (uint)doodadEntry.ModelFileID;

                                if (!WoWExport.Listfile.TryGetFilename(filedataid, out var filename))
                                {
                                    Console.WriteLine("Could not find filename for " + filedataid + ", setting filename to filedataid..");
                                    filename = filedataid.ToString();
                                }

                                if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file), "foliage")))
                                {
                                    Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file), "foliage"));
                                }

                                if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file), "foliage", Path.GetFileNameWithoutExtension(filename).ToLower() + ".obj")))
                                {
                                    M2Exporter.ExportM2(filename, Path.Combine(outdir, Path.GetDirectoryName(file), "foliage"));
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error exporting GroundEffects: " + e.Message);
                }
            }

            if (exportWMO || exportM2)
            {
                var doodadSW = new StreamWriter(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(file).Replace(" ", "") + "_ModelPlacementInformation.csv"));
                doodadSW.WriteLine("ModelFile;PositionX;PositionY;PositionZ;RotationX;RotationY;RotationZ;ScaleFactor;ModelId;Type");

                if (exportWMO)
                {
                    exportworker.ReportProgress(25, "Exporting WMOs");

                    for (var mi = 0; mi < reader.adtfile.objects.worldModels.entries.Count(); mi++)
                    {
                        var wmo = reader.adtfile.objects.worldModels.entries[mi];

                        float wmoScale;
                        if (wmo.scale != 0)
                        {
                            wmoScale = wmo.scale / 1024f;
                        }
                        else
                        {
                            wmoScale = 1;
                        }

                        var filename = reader.adtfile.objects.wmoNames.filenames[wmo.mwidEntry];

                        if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(filename).ToLower() + ".obj")))
                        {
                            WMOExporter.ExportWMO(filename, Path.Combine(outdir, Path.GetDirectoryName(file)), exportworker, null, wmo.doodadSet);
                        }

                        if (Managers.ConfigurationManager.ADTModelsPlacementGlobalPath)
                        {
                            doodadSW.WriteLine(Path.Combine(Path.GetDirectoryName(filename).ToLower(), Path.GetFileNameWithoutExtension(filename).ToLower() + ".obj") + ";" + wmo.position.X + ";" + wmo.position.Y + ";" + wmo.position.Z + ";" + wmo.rotation.X + ";" + wmo.rotation.Y + ";" + wmo.rotation.Z + ";" + wmoScale + ";" + wmo.uniqueId + ";wmo");
                        }
                        else
                        {
                            doodadSW.WriteLine(Path.GetFileNameWithoutExtension(filename).ToLower() + ".obj;" + wmo.position.X + ";" + wmo.position.Y + ";" + wmo.position.Z + ";" + wmo.rotation.X + ";" + wmo.rotation.Y + ";" + wmo.rotation.Z + ";" + wmoScale + ";" + wmo.uniqueId + ";wmo");
                        }
                    }
                }

                if (exportM2)
                {
                    exportworker.ReportProgress(50, "Exporting M2s");

                    for (var mi = 0; mi < reader.adtfile.objects.models.entries.Count(); mi++)
                    {
                        var doodad = reader.adtfile.objects.models.entries[mi];

                        string filename;
                        filename = reader.adtfile.objects.m2Names.filenames[doodad.mmidEntry];
                        if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(filename).ToLower() + ".obj")))
                        {
                            M2Exporter.ExportM2(filename, Path.Combine(outdir, Path.GetDirectoryName(file)), exportworker);
                        }
                        if (Managers.ConfigurationManager.ADTModelsPlacementGlobalPath)
                        {
                            doodadSW.WriteLine(Path.Combine(Path.GetDirectoryName(filename).ToLower(), Path.GetFileNameWithoutExtension(filename).ToLower() + ".obj") + ";" + doodad.position.X + ";" + doodad.position.Y + ";" + doodad.position.Z + ";" + doodad.rotation.X + ";" + doodad.rotation.Y + ";" + doodad.rotation.Z + ";" + doodad.scale / 1024f + ";" + doodad.uniqueId + ";m2");
                        }
                        else
                        {
                            doodadSW.WriteLine(Path.GetFileNameWithoutExtension(filename).ToLower() + ".obj;" + doodad.position.X + ";" + doodad.position.Y + ";" + doodad.position.Z + ";" + doodad.rotation.X + ";" + doodad.rotation.Y + ";" + doodad.rotation.Z + ";" + doodad.scale / 1024f + ";" + doodad.uniqueId + ";m2");
                        }
                    }
                }
                doodadSW.Close();
            }
            #region Alpha&Tex
            //----------------------------------------------------------------------------------------------------------
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////
            ///TEXTURE & ALPHA & HEIGHTMAP RELATED START
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //----------------------------------------------------------------------------------------------------------
            if (exportTextures) //Export ground textures
            {
                {
                    if (!Directory.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures")))
                    {
                        Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures"));
                    }
                }

                List <String> GroundTextures = reader.adtfile.textures.filenames.ToList();

                var blpreader = new BLPReader();
                foreach (string texture in GroundTextures)
                {
                    if (Managers.ConfigurationManager.ADTPreserveTextureStruct)
                    {
                        if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures", Path.GetDirectoryName(texture) + Path.GetFileNameWithoutExtension(texture) + ".png")))
                        {
                            if (!Directory.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures", Path.GetDirectoryName(texture))))
                            {
                                Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures", Path.GetDirectoryName(texture)));
                            }

                            if (Managers.ArchiveManager.FileExists(texture))
                            {
                                try
                                {
                                    blpreader.LoadBLP(Managers.ArchiveManager.ReadThisFile(texture));
                                    blpreader.bmp.Save(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures", Path.GetDirectoryName(texture), Path.GetFileNameWithoutExtension(texture) + ".png"));
                                    if (Managers.ConfigurationManager.ADTExportSpecularTextures)
                                    {
                                        if (Managers.ArchiveManager.FileExists(Path.Combine(Path.GetDirectoryName(texture), Path.GetFileNameWithoutExtension(texture) + "_s.blp")))
                                        {
                                            if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures", Path.GetDirectoryName(texture), Path.GetFileNameWithoutExtension(texture) + "_s.png")))
                                            {
                                                blpreader.LoadBLP(Managers.ArchiveManager.ReadThisFile(Path.Combine(Path.GetDirectoryName(texture), Path.GetFileNameWithoutExtension(texture) + "_s.blp")));
                                                blpreader.bmp.Save(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures", Path.GetDirectoryName(texture), Path.GetFileNameWithoutExtension(texture) + "_s.png"));
                                            }
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    //Error on file save
                                    throw new Exception(e.Message);
                                }
                            }
                            else
                            {
                                //Missing file
                            }
                        }
                    }
                    else
                    {
                        if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures\\", Path.GetFileNameWithoutExtension(texture) + ".png")))
                        {
                            if (Managers.ArchiveManager.FileExists(texture))
                            {
                                try
                                {
                                    blpreader.LoadBLP(Managers.ArchiveManager.ReadThisFile(texture));
                                    blpreader.bmp.Save(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures\\", Path.GetFileNameWithoutExtension(texture) + ".png"));
                                    if (Managers.ConfigurationManager.ADTExportSpecularTextures)
                                    {
                                        if (Managers.ArchiveManager.FileExists(Path.Combine(Path.GetDirectoryName(texture), Path.GetFileNameWithoutExtension(texture) + "_s.blp")))
                                        {
                                            if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures\\", Path.GetFileNameWithoutExtension(texture) + "_s.png")))
                                            {
                                                blpreader.LoadBLP(Managers.ArchiveManager.ReadThisFile(Path.Combine(Path.GetDirectoryName(texture), Path.GetFileNameWithoutExtension(texture) + "_s.blp")));
                                                blpreader.bmp.Save(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\GroundTextures\\", Path.GetFileNameWithoutExtension(texture) + "_s.png"));
                                            }
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    //Error on file save
                                    throw new Exception(e.Message);
                                }
                            }
                            else
                            {
                                //Missing file
                            }
                        }
                    }
                }
            }

            if (exportAlphaMaps)
            {
                Generators.ADT_Alpha.ADT_Alpha AlphaMapsGenerator = new Generators.ADT_Alpha.ADT_Alpha();
                AlphaMapsGenerator.GenerateAlphaMaps(reader.adtfile, Managers.ConfigurationManager.ADTAlphaMode);

                List <System.Drawing.Bitmap> AlphaLayers = new List <System.Drawing.Bitmap>();
                AlphaLayers = AlphaMapsGenerator.AlphaLayers;

                if (!Directory.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\AlphaMaps")))
                {
                    Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\AlphaMaps"));
                }

                if (AlphaLayers != null)
                {
                    if (Managers.ConfigurationManager.ADTAlphaMode == 0 || Managers.ConfigurationManager.ADTAlphaMode == 1)
                    {
                        for (int m = 0; m < AlphaLayers.ToArray().Length; m++)
                        {
                            if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\AlphaMaps\\", mapname + "_" + m + ".png")))
                            {
                                try
                                {
                                    AlphaLayers[m].Save(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\AlphaMaps\\", mapname + "_" + m + ".png"));
                                }
                                catch
                                {
                                    //Error on file save
                                }
                            }
                        }
                    }
                    if (Managers.ConfigurationManager.ADTAlphaMode == 2 || Managers.ConfigurationManager.ADTAlphaMode == 3)
                    {
                        List <String> AlphaLayersNames = new List <String>(AlphaMapsGenerator.AlphaLayersNames);
                        for (int m = 0; m < AlphaLayers.ToArray().Length; m++)
                        {
                            if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\AlphaMaps\\", mapname + "_" + AlphaLayersNames[m].Replace(";", "_") + ".png")))
                            {
                                try
                                {
                                    AlphaLayers[m].Save(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\AlphaMaps\\", mapname + "_" + AlphaLayersNames[m].Replace(";", "_") + ".png"));
                                }
                                catch
                                {
                                    //Error on file save
                                }
                            }
                        }
                    }
                    if (Managers.ConfigurationManager.ADTAlphaMode == 4) //Splatmaps
                    {
                        //Save the splatmaps
                        for (int m = 0; m < AlphaLayers.ToArray().Length; m++)
                        {
                            if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\AlphaMaps\\", mapname + "_splatmap_" + m + ".png")))
                            {
                                try
                                {
                                    AlphaLayers[m].Save(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\AlphaMaps\\", mapname + "_splatmap_" + m + ".png"));
                                }
                                catch
                                {
                                    //Error on file save
                                }
                            }
                        }
                        //Save the material info JSON
                        if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\AlphaMaps\\", mapname + "_MaterialData.json")))
                        {
                            try
                            {
                                File.WriteAllText(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\AlphaMaps\\", mapname + "_MaterialData.json"), AlphaMapsGenerator.SplatmapJSON);
                            }
                            catch
                            {
                                //Error on file save
                            }
                        }
                    }
                }

                //Check if the CSV already exists, if not, create it
                if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\" + mapname + "_" + "layers.csv")))
                {
                    //Generate layer information CSV
                    StreamWriter layerCsvSR = new StreamWriter(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\" + mapname + "_" + "layers.csv"));
                    //Insert CSV scheme
                    layerCsvSR.WriteLine("chunk;tex0;tex1;tex2;tex3");
                    for (uint c = 0; c < reader.adtfile.chunks.Count(); c++)
                    {
                        string csvLine = c.ToString();
                        for (int li = 0; li < reader.adtfile.texChunks[c].layers.Count(); li++)
                        {
                            var AlphaLayerName = reader.adtfile.textures.filenames[reader.adtfile.texChunks[c].layers[li].textureId].ToLower();
                            if (Managers.ConfigurationManager.ADTPreserveTextureStruct)
                            {
                                csvLine = csvLine + ";" + Path.Combine(Path.GetDirectoryName(AlphaLayerName), Path.GetFileNameWithoutExtension(AlphaLayerName));
                            }
                            else
                            {
                                csvLine = csvLine + ";" + Path.GetFileNameWithoutExtension(AlphaLayerName);
                            }
                        }
                        layerCsvSR.WriteLine(csvLine);
                    }
                    layerCsvSR.Close();
                }
            }

            if (exportHeightmap)
            {
                Generators.ADT_Height.ADT_Height heightmapGenerator = new Generators.ADT_Height.ADT_Height();
                heightmapGenerator.GenerateHeightmap(reader.adtfile);

                if (!Directory.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\HeightMaps")))
                {
                    Directory.CreateDirectory(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\HeightMaps"));
                }

                try
                {
                    File.WriteAllText(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\HeightMaps\\", mapname + "_HeightData.json"), Newtonsoft.Json.JsonConvert.SerializeObject(heightmapGenerator.heightArray2d));
                    heightmapGenerator.heightMap.Save(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\HeightMaps\\", mapname + "_heightmap.png"));
                }
                catch
                {
                    //Error on save
                }
            }
            //----------------------------------------------------------------------------------------------------------
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////
            ///TEXTURE & ALPHA & HEIGHTMAP RELATED END
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //----------------------------------------------------------------------------------------------------------
            #endregion

            //VERTEX COLORS -- not implemented

            /*
             * //Vertex color data
             * if (!File.Exists(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\" + mapname + "_" + "vertex_colors.csv")))
             * {
             *  StreamWriter vertesColorCSV = new StreamWriter(Path.Combine(outdir, Path.GetDirectoryName(file) + "\\" + mapname + "_" + "vertex_colors.csv"));
             *  vertesColorCSV.WriteLine("chunk;vert;a;r;g;b"); //header
             *  for (uint c = 0; c < reader.adtfile.chunks.Count(); c++)
             *  {
             *      if (reader.adtfile.chunks[c].vertexShading.red != null)
             *      {
             *          for (int i = 0; i < 145; i++)
             *          {
             *              //Console.WriteLine(c + "_" + i + "-" + reader.adtfile.chunks[c].vertexShading.alpha[i] + " " + reader.adtfile.chunks[c].vertexShading.red[i] + " " + reader.adtfile.chunks[c].vertexShading.green[i] + " " + reader.adtfile.chunks[c].vertexShading.blue[i]);
             *              vertesColorCSV.WriteLine(c + ";" + i + ";" + reader.adtfile.chunks[c].vertexShading.alpha[i] + ";" + reader.adtfile.chunks[c].vertexShading.red[i] + ";" + reader.adtfile.chunks[c].vertexShading.green[i] + ";" + reader.adtfile.chunks[c].vertexShading.blue[i]);
             *          }
             *      }
             *      else
             *      {
             *          //Console.WriteLine(c + "- null");
             *          vertesColorCSV.WriteLine(c + ";0;0;0;0;0");
             *      }
             *  }
             *  vertesColorCSV.Close();
             * }
             */

            exportworker.ReportProgress(75, "Exporting terrain textures..");

            if (bakeQuality != "none")
            {
                var mtlsw = new StreamWriter(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(file).Replace(" ", "") + ".mtl"));

                //No idea how MTL files really work yet. Needs more investigation.
                foreach (var material in materials)
                {
                    mtlsw.WriteLine("newmtl " + material.Value.Replace(" ", ""));
                    mtlsw.WriteLine("Ka 1.000000 1.000000 1.000000");
                    mtlsw.WriteLine("Kd 0.640000 0.640000 0.640000");
                    mtlsw.WriteLine("map_Ka " + material.Value.Replace(" ", "") + ".png");
                    mtlsw.WriteLine("map_Kd " + material.Value.Replace(" ", "") + ".png");
                }

                mtlsw.Close();
            }

            exportworker.ReportProgress(85, "Exporting terrain geometry..");

            var indices = indicelist.ToArray();

            var adtname = Path.GetFileNameWithoutExtension(file);

            var objsw = new StreamWriter(Path.Combine(outdir, Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(file).Replace(" ", "") + ".obj"));

            objsw.WriteLine("# Written by Marlamin's WoW OBJExporter. Original file: " + file);
            if (bakeQuality != "none")
            {
                objsw.WriteLine("mtllib " + Path.GetFileNameWithoutExtension(file).Replace(" ", "") + ".mtl");
            }

            objsw.WriteLine("g " + adtname.Replace(" ", ""));
            var verticeCounter = 1;
            var chunkCounter   = 1;
            foreach (var vertex in verticelist)
            {
                objsw.WriteLine("# C" + chunkCounter + ".V" + verticeCounter);
                objsw.WriteLine("v " + vertex.Position.X.ToString("R") + " " + vertex.Position.Y.ToString("R") + " " + vertex.Position.Z.ToString("R"));
                objsw.WriteLine("vt " + vertex.TexCoord.X + " " + vertex.TexCoord.Y);
                objsw.WriteLine("vn " + vertex.Normal.X.ToString("R") + " " + vertex.Normal.Y.ToString("R") + " " + vertex.Normal.Z.ToString("R"));
                verticeCounter++;
                if (verticeCounter == 146)
                {
                    chunkCounter++;
                    verticeCounter = 1;
                }
            }

            if (bakeQuality != "high")
            {
                objsw.WriteLine("usemtl " + materials[1]);
                objsw.WriteLine("s 1");
            }
            int currentChunk = 0;
            foreach (var renderBatch in renderBatches)
            {
                var i = renderBatch.firstFace;
                if (bakeQuality == "high" && materials.ContainsKey((int)renderBatch.materialID))
                {
                    if (Managers.ConfigurationManager.ADTSplitChunks)
                    {
                        objsw.WriteLine("g " + materials[(int)renderBatch.materialID]);
                        objsw.WriteLine("usemtl " + materials[(int)renderBatch.materialID]);
                        objsw.WriteLine("s 1");
                    }
                    else
                    {
                        objsw.WriteLine("usemtl " + materials[(int)renderBatch.materialID]);
                    }
                }
                while (i < (renderBatch.firstFace + renderBatch.numFaces))
                {
                    objsw.WriteLine("f " +
                                    (indices[i + 2] + 1) + "/" + (indices[i + 2] + 1) + "/" + (indices[i + 2] + 1) + " " +
                                    (indices[i + 1] + 1) + "/" + (indices[i + 1] + 1) + "/" + (indices[i + 1] + 1) + " " +
                                    (indices[i] + 1) + "/" + (indices[i] + 1) + "/" + (indices[i] + 1));
                    i += 3;
                }
                currentChunk++;
            }

            objsw.Close();
        }
示例#8
0
        private static void Main(string[] args)
        {
            var config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("settings.json", true, true).Build();

            var saveExplored   = bool.Parse(config["saveExploredMaps"]);
            var saveUnexplored = bool.Parse(config["saveUnexploredMaps"]);
            var saveLayers     = bool.Parse(config["saveMapLayers"]);
            var saveExploredMapsWithoutUnexplored = bool.Parse(config["saveExploredMapsWithoutUnexplored"]);

            if (saveExplored && !Directory.Exists("explored"))
            {
                Directory.CreateDirectory("explored");
            }

            if (saveUnexplored && !Directory.Exists("unexplored"))
            {
                Directory.CreateDirectory("unexplored");
            }

            if (saveLayers && !Directory.Exists("layers"))
            {
                Directory.CreateDirectory("layers");
            }

            if (saveExploredMapsWithoutUnexplored && !Directory.Exists("exploredNoUnexplored"))
            {
                Directory.CreateDirectory("exploredNoUnexplored");
            }

            var locale = CASCLib.LocaleFlags.enUS;

            if (config["locale"] != string.Empty)
            {
                switch (config["locale"])
                {
                case "deDE":
                    locale = CASCLib.LocaleFlags.deDE;
                    break;

                case "enUS":
                    locale = CASCLib.LocaleFlags.enUS;
                    break;

                case "ruRU":
                    locale = CASCLib.LocaleFlags.ruRU;
                    break;

                case "zhCN":
                    locale = CASCLib.LocaleFlags.zhCN;
                    break;

                case "zhTW":
                    locale = CASCLib.LocaleFlags.zhTW;
                    break;
                }
            }

            if (config["installDir"] != string.Empty && Directory.Exists(config["installDir"]))
            {
                CASC.InitCasc(null, config["installDir"], config["program"], locale);
            }
            else
            {
                CASC.InitCasc(null, null, config["program"], locale);
            }

            var dbcd = new DBCD.DBCD(new CASCDBCProvider(), new DBCD.Providers.GithubDBDProvider());

            var UIMap               = dbcd.Load("UiMap", CASC.BuildName);
            var UIMapXArt           = dbcd.Load("UiMapXMapArt", CASC.BuildName);
            var UIMapArtTile        = dbcd.Load("UiMapArtTile", CASC.BuildName);
            var UIMapArt            = dbcd.Load("UiMapArt", CASC.BuildName);
            var UIMapArtStyleLayer  = dbcd.Load("UiMapArtStyleLayer", CASC.BuildName);
            var WorldMapOverlay     = dbcd.Load("WorldMapOverlay", CASC.BuildName);
            var WorldMapOverlayTile = dbcd.Load("WorldMapOverlayTile", CASC.BuildName);

            Console.WriteLine(); // new line after wdc2 debug output

            foreach (dynamic mapRow in UIMap.Values)
            {
                var mapName = mapRow.Name_lang;

                Console.WriteLine(mapRow.ID + " = " + mapName);

                foreach (dynamic mxaRow in UIMapXArt.Values)
                {
                    var uiMapArtID = mxaRow.UiMapArtID;
                    var uiMapID    = mxaRow.UiMapID;

                    if (mxaRow.PhaseID != 0)
                    {
                        continue; // Skip phase stuff for now
                    }
                    if (uiMapID == mapRow.ID)
                    {
                        var maxRows  = uint.MinValue;
                        var maxCols  = uint.MinValue;
                        var tileDict = new Dictionary <string, int>();

                        foreach (dynamic matRow in UIMapArtTile.Values)
                        {
                            var matUiMapArtID = matRow.UiMapArtID;
                            if (matUiMapArtID == uiMapArtID)
                            {
                                var fdid       = matRow.FileDataID;
                                var rowIndex   = matRow.RowIndex;
                                var colIndex   = matRow.ColIndex;
                                var layerIndex = matRow.LayerIndex;

                                // Skip other layers for now
                                if (layerIndex != 0)
                                {
                                    continue;
                                }

                                if (rowIndex > maxRows)
                                {
                                    maxRows = rowIndex;
                                }

                                if (colIndex > maxCols)
                                {
                                    maxCols = colIndex;
                                }

                                tileDict.Add(rowIndex + "," + colIndex, fdid);
                            }
                        }

                        uint res_x = 0;
                        uint res_y = 0;

                        foreach (dynamic maRow in UIMapArt.Values)
                        {
                            if (maRow.ID == uiMapArtID)
                            {
                                foreach (dynamic mastRow in UIMapArtStyleLayer.Values)
                                {
                                    if (mastRow.ID == maRow.UiMapArtStyleID)
                                    {
                                        res_x = mastRow.LayerHeight;
                                        res_y = mastRow.LayerWidth;
                                        continue;
                                    }
                                }
                                continue;
                            }
                        }

                        if (res_x == 0)
                        {
                            res_x = (maxRows + 1) * 256;
                        }

                        if (res_y == 0)
                        {
                            res_y = (maxCols + 1) * 256;
                        }

                        var bmp = new Bitmap((int)res_y, (int)res_x);
                        var g   = Graphics.FromImage(bmp);

                        var bmp2 = new Bitmap((int)res_y, (int)res_x);
                        var g2   = Graphics.FromImage(bmp2);

                        for (var cur_x = 0; cur_x < maxRows + 1; cur_x++)
                        {
                            for (var cur_y = 0; cur_y < maxCols + 1; cur_y++)
                            {
                                var fdid = tileDict[cur_x + "," + cur_y];

                                if (CASC.FileExists((uint)fdid))
                                {
                                    using (var stream = CASC.OpenFile((uint)fdid))
                                    {
                                        try
                                        {
                                            var blp = new BlpFile(stream);
                                            g.DrawImage(blp.GetBitmap(0), cur_y * 256, cur_x * 256, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);
                                        }
                                        catch (Exception e)
                                        {
                                            Console.WriteLine("An error occured opening BLP with filedataid " + fdid);
                                        }
                                    }
                                }
                            }
                        }

                        if (saveUnexplored)
                        {
                            bmp.Save("unexplored/ " + CleanFileName(mapRow.ID + " - " + mapName + ".png"));
                        }

                        if (!saveLayers && !saveExplored)
                        {
                            continue;
                        }

                        foreach (dynamic wmorow in WorldMapOverlay.Values)
                        {
                            var WMOUIMapArtID = wmorow.UiMapArtID;
                            var offsetX       = wmorow.OffsetX;
                            var offsetY       = wmorow.OffsetY;

                            uint maxWMORows  = 0;
                            uint maxWMOCols  = 0;
                            var  wmoTileDict = new Dictionary <string, int>();

                            if (WMOUIMapArtID == uiMapArtID)
                            {
                                foreach (dynamic wmotrow in WorldMapOverlayTile.Values)
                                {
                                    var worldMapOverlayID = wmotrow.WorldMapOverlayID;

                                    // something wrong in/around this check
                                    if (worldMapOverlayID == wmorow.ID)
                                    {
                                        var fdid       = wmotrow.FileDataID;
                                        var rowIndex   = wmotrow.RowIndex;
                                        var colIndex   = wmotrow.ColIndex;
                                        var layerIndex = wmotrow.LayerIndex;

                                        // Skip other layers for now
                                        if (layerIndex != 0)
                                        {
                                            continue;
                                        }

                                        if (rowIndex > maxWMORows)
                                        {
                                            maxWMORows = rowIndex;
                                        }

                                        if (colIndex > maxWMOCols)
                                        {
                                            maxWMOCols = colIndex;
                                        }

                                        wmoTileDict.Add(rowIndex + "," + colIndex, fdid);
                                    }
                                }
                            }

                            if (wmoTileDict.Count == 0)
                            {
                                continue;
                            }

                            var layerResX = (maxWMORows + 1) * 256;
                            var layerResY = (maxWMOCols + 1) * 256;

                            var layerBitmap   = new Bitmap((int)layerResY, (int)layerResX);
                            var layerGraphics = Graphics.FromImage(layerBitmap);

                            for (var cur_x = 0; cur_x < maxWMORows + 1; cur_x++)
                            {
                                for (var cur_y = 0; cur_y < maxWMOCols + 1; cur_y++)
                                {
                                    var fdid = wmoTileDict[cur_x + "," + cur_y];

                                    if (CASC.FileExists((uint)fdid))
                                    {
                                        using (var stream = CASC.OpenFile((uint)fdid))
                                        {
                                            try
                                            {
                                                var blp  = new BlpFile(stream);
                                                var posY = cur_y * 256 + offsetX;
                                                var posX = cur_x * 256 + offsetY;

                                                if (saveLayers)
                                                {
                                                    layerGraphics.DrawImage(blp.GetBitmap(0), cur_y * 256, cur_x * 256, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);
                                                }

                                                var blpBMP = blp.GetBitmap(0);
                                                g.DrawImage(blpBMP, posY, posX, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);

                                                if (saveExploredMapsWithoutUnexplored)
                                                {
                                                    g2.DrawImage(blpBMP, posY, posX, new Rectangle(0, 0, 256, 256), GraphicsUnit.Pixel);
                                                }
                                            }
                                            catch (Exception e)
                                            {
                                                Console.WriteLine("An error occured opening BLP with filedataid " + fdid);
                                            }
                                        }
                                    }
                                }
                            }

                            if (saveLayers)
                            {
                                if (!Directory.Exists("layers/" + CleanFileName(mapRow
                                                                                + " - " + mapName) + "/"))
                                {
                                    Directory.CreateDirectory("layers/" + CleanFileName(mapRow.ID + " - " + mapName) + "/");
                                }
                                layerBitmap.Save("layers/" + CleanFileName(mapRow.ID + " - " + mapName) + "/" + wmorow.ID + ".png");
                            }
                        }

                        if (saveExplored)
                        {
                            bmp.Save("explored/ " + CleanFileName(mapRow.ID + " - " + mapName + ".png"));
                        }

                        if (saveExploredMapsWithoutUnexplored)
                        {
                            bmp2.Save("exploredNoUnexplored/ " + CleanFileName(mapRow.ID + " - " + mapName + ".png"));
                        }
                    }
                }
            }
        }
示例#9
0
        public static void Execute(string filter = null)
        {
            var dbcd = new DBCD.DBCD(new DBCProvider(dbPath), new DBDProvider(definitionsPath));

            var build = "8.3.0.34220";

            var connectionString = new SqlConnectionStringBuilder
            {
                InitialCatalog     = "wow",
                DataSource         = "(local)",
                IntegratedSecurity = true
            }.ToString();

            using var connection = new SqlConnection(connectionString);
            connection.Open();
            var server   = new Server();
            var database = server.Databases["wow"];

            // The DBCache which stores downloaded / patched database records from the server side
            Console.WriteLine("Loading in hotfix cache...");
            var hotfix = new HotfixReader(Path.Combine(cachePath, "DBCache.bin"));
            var caches = Directory.EnumerateFiles(cachePath, "DBCache.bin*.tmp").ToList();

            hotfix.CombineCaches(caches.ToArray());

            Console.WriteLine("Loading tables..");
            foreach (var databaseFile in Directory.EnumerateFiles(dbPath, "*.db?", SearchOption.TopDirectoryOnly))
            {
                Console.WriteLine();

                var name = Path.GetFileNameWithoutExtension(databaseFile);

                if (name.StartsWith("UnitTest", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                if (!string.IsNullOrWhiteSpace(filter) && !filter.Contains(name, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                var storage = dbcd.Load(name, build, Locale.EnUS).ApplyingHotfixes(hotfix);

                DBCDRow item = storage.Values.FirstOrDefault();
                if (item == null)
                {
                    Console.WriteLine(name + ": **EMPTY**");
                    continue;
                }

                Console.WriteLine(name);
                Console.WriteLine(string.Join("", Enumerable.Repeat("=", name.Length)));

                using var table = new DataTable(name);

                for (var j = 0; j < storage.AvailableColumns.Length; ++j)
                {
                    string fieldname = storage.AvailableColumns[j];
                    var    field     = item[fieldname];

                    var isEndOfRecord = j == storage.AvailableColumns.Length - 1;

                    if (field is Array a)
                    {
                        for (var i = 0; i < a.Length; i++)
                        {
                            var isEndOfArray = a.Length - 1 == i;
                            Console.Write($"{fieldname}[{i}]");
                            if (!isEndOfArray)
                            {
                                Console.Write(",");
                            }

                            table.Columns.Add(new DataColumn(fieldname + "_" + i)
                            {
                                DataType = a.GetType().GetElementType()
                            });
                        }
                    }
                    else
                    {
                        var column = new DataColumn(fieldname)
                        {
                            DataType = field.GetType()
                        };

                        table.Columns.Add(column);

                        if (fieldname.Equals("id", StringComparison.OrdinalIgnoreCase))
                        {
                            table.PrimaryKey = new[] { column };
                        }

                        Console.Write(fieldname);
                    }

                    if (!isEndOfRecord)
                    {
                        Console.Write(",");
                    }
                }

                database.CreateTableSchema(table);

                // Process rows
                foreach (var row in storage.Values)
                {
                    var dataRow = table.NewRow();

                    foreach (var fieldName in storage.AvailableColumns)
                    {
                        var value = row[fieldName];

                        if (value is Array a)
                        {
                            for (var j = 0; j < a.Length; j++)
                            {
                                var arrayValue = a.GetValue(j).ToString();

                                // if (searchValues.Contains(arrayValue))
                                // {
                                //     Console.ForegroundColor = ConsoleColor.Yellow;
                                //     Console.WriteLine($"Found matching record: {table.TableName}#{row.ID}");
                                //     Console.ResetColor();
                                // }

                                dataRow[fieldName + "_" + j] = arrayValue;
                            }
                        }
                        else
                        {
                            dataRow[fieldName] = value;
                        }
                    }

                    table.Rows.Add(dataRow);
                }

                // Bulk import the data
                var bulk = new SqlBulkCopy(connection);
                bulk.DestinationTableName = table.TableName;
                bulk.WriteToServer(table);

                Console.WriteLine();
            }
        }