예제 #1
0
        public static bool FileExists(MpqArchive archive, string path)
        {
            if (archive.FileExists(path))
            {
                return(true);
            }

            // Check if file is contained in an mpq archive.
            var subPath      = path;
            var ignoreLength = new FileInfo(subPath).FullName.Length - path.Length;

            while (!archive.FileExists(subPath))
            {
                var directoryName = new FileInfo(subPath).DirectoryName;
                if (directoryName.Length <= ignoreLength)
                {
                    return(false);
                }

                subPath = directoryName.Substring(ignoreLength);
            }

            var relativePath = path.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1));

            using var subArchiveStream = archive.OpenFile(subPath);
            using var subArchive       = MpqArchive.Open(subArchiveStream);
            return(FileExists(subArchive, relativePath));
        }
예제 #2
0
        /// <exception cref="FileNotFoundException"></exception>
        public static Stream GetFile(MpqArchive archive, string path)
        {
            if (archive.FileExists(path))
            {
                return(GetArchiveFileStream(archive, path));
            }

            // Assume file is contained in an mpq archive.
            var subPath      = path;
            var ignoreLength = new FileInfo(subPath).FullName.Length - path.Length;

            while (!archive.FileExists(subPath))
            {
                var directoryName = new FileInfo(subPath).DirectoryName;
                if (directoryName.Length <= ignoreLength)
                {
                    throw new FileNotFoundException($"File not found: {path}");
                }

                subPath = directoryName.Substring(ignoreLength);
            }

            var relativePath = path.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1));

            using var subArchiveStream = archive.OpenFile(subPath);
            using var subArchive       = MpqArchive.Open(subArchiveStream);
            return(GetArchiveFileStream(subArchive, relativePath));
        }
예제 #3
0
    static void TestStrings(MpqArchive mpq, string dot, int count, char[] test, int index)
    {
        if (index == count)
        {
            entry_count++;
            if (entry_count % 10000 == 0)
            {
                lock (consolelock) {
                    Console.Write(dot);
                    Console.Out.Flush();
                }
            }

            String entry = new String(test, 0, count);
            if (mpq.FileExists(entry))
            {
                lock (iolock) {
                    sw.WriteLine(entry);
                }
            }
            return;
        }
        for (int j = 0; j < allowable.Length; j++)
        {
            test[index] = allowable[j];
            TestStrings(mpq, dot, count, test, index + 1);
        }
    }
예제 #4
0
        public static Replay ParseRejoin(string fileName)
        {
            try {
                using (var archive = new MpqArchive(fileName)) {
                    archive.AddListfileFilenames();
                    var replay = new Replay();

                    // Replay Details
                    ReplayDetails.Parse(replay, DataParser.GetMpqFile(archive, "save.details"), true);

                    // Player level is stored there
                    // does not exist in brawl
                    if (archive.FileExists("replay.attributes.events"))
                    {
                        ReplayAttributeEvents.Parse(replay, DataParser.GetMpqFile(archive, "replay.attributes.events"));
                    }

                    return(replay);
                }
            }
            catch (Exception ex) {
                //TODO: WE REALLY DON't want to do this
                Debug.WriteLine(ex);
                return(null);
            }
        }
예제 #5
0
        public string Parse()
        {
            var s2MaPathNum = m_lobbyBytes[0];
            var s2MaPathLen = m_lobbyBytes[1];
            var dict        = new Dictionary <string, int>();

            foreach (var map in m_maps)
            {
                dict.Add(map, 0);
            }

            for (var i = 0; i < s2MaPathNum; i++)
            {
                var s2MaPath = Encoding.Default.GetString(m_lobbyBytes.Skip(2 + i * (s2MaPathLen + 2)).Take(s2MaPathLen).ToArray());
                try
                {
                    var tempPath = Path.GetTempFileName();
                    File.Copy(s2MaPath, tempPath, true);
                    s2MaPath = tempPath;
                    var mpq = new MpqArchive(s2MaPath);
                    if (mpq.FileExists("DocumentInfo"))
                    {
                        using (var ms = mpq.OpenFile("DocumentInfo"))
                        {
                            var buffer = new byte[ms.Length];
                            ms.Read(buffer, 0, (int)ms.Length);
                            var str = Encoding.Default.GetString(buffer);
                            foreach (var map in m_maps)
                            {
                                dict[map] += Regex.Matches(str, map.Substring(0, 8)).Count;
                            }
                        }
                    }
                    File.Delete(tempPath);
                }
                catch
                {
                }
            }

            var count   = 0;
            var mapName = "Unknown Map";

            foreach (var map in m_maps)
            {
                if (dict[map] > count)
                {
                    count   = dict[map];
                    mapName = map;
                }
            }
            return(mapName);
        }
예제 #6
0
        public Map(string filename)
        {
            MapPath = filename;
            using (FileStream fs = new FileStream(filename, FileMode.Open)) {
                byte[] d = new byte[fs.Length];
                fs.Read(d, 0, d.Length);
                fs.Seek(0, SeekOrigin.Begin);

                this.MapSize = BitConverter.GetBytes((int)fs.Length);
                this.MapInfo = new CRC32().ComputeHash(d, 0, d.Length);

                using (MpqArchive a = new MpqArchive(fs, true))
                {
                    uint CRCVal = 0;

                    SHA1Managed sha = new SHA1Managed();

                    byte[] commonJData, blizzardJData;
                    if (a.FileExists("Scripts\\common.j"))
                    {
                        using (var commonOverload = a.OpenFile("Scripts\\common.j")){
                            var ms = new MemoryStream();
                            commonOverload.CopyTo(ms);
                            commonJData = ms.ToArray();
                            ms.Dispose();
                        }
                    }
                    else
                    {
                        commonJData = File.ReadAllBytes("dep/common.j");
                    }
                    if (a.FileExists("Scripts\\blizzard.j"))
                    {
                        using (var blizzardOverload = a.OpenFile("Scripts\\blizzard.j")){
                            var ms = new MemoryStream();
                            blizzardOverload.CopyTo(ms);
                            blizzardJData = ms.ToArray();
                            ms.Dispose();
                        }
                    }
                    else
                    {
                        blizzardJData = File.ReadAllBytes("dep/blizzard.j");
                    }

                    CRCVal = CRCVal ^ XORRotateLeft(commonJData);
                    CRCVal = CRCVal ^ XORRotateLeft(blizzardJData);

                    sha.TransformBlock(commonJData, 0, commonJData.Length, commonJData, 0);
                    sha.TransformBlock(blizzardJData, 0, blizzardJData.Length, blizzardJData, 0);

                    var  magicBytes = new byte[] { 0x9e, 0x37, 0xf1, 0x03 };
                    uint magicInt   = 0x03F1379E;

                    CRCVal = ROTL(CRCVal, 3);
                    CRCVal = ROTL(CRCVal ^ magicInt, 3);

                    sha.TransformBlock(magicBytes, 0, magicBytes.Length, magicBytes, 0);

                    string[] filenames   = { "war3map.j", "scripts\\war3map.j", "war3map.w3e", "war3map.wpm", "war3map.doo", "war3map.w3u", "war3map.w3b", "war3map.w3d", "war3map.w3a", "war3map.w3q" };
                    var      foundScript = false;

                    foreach (string fn in filenames)
                    {
                        if (foundScript && fn == filenames[2])
                        {
                            continue;
                        }

                        if (!a.FileExists(fn))
                        {
                            continue;
                        }

                        using (MpqStream s = a.OpenFile(fn)){
                            var ms = new MemoryStream();
                            s.CopyTo(ms);
                            var fdata = ms.ToArray();
                            ms.Dispose();

                            CRCVal = ROTL(CRCVal ^ XORRotateLeft(fdata), 3);
                            sha.TransformBlock(fdata, 0, fdata.Length, fdata, 0);
                        }
                    }

                    MapCRC = BitConverter.GetBytes(CRCVal);

                    sha.TransformFinalBlock(new byte[] {}, 0, 0);
                    MapSha = sha.Hash;
                    //loading actual map shit now

                    int MapFlags;

                    using (MpqStream m = a.OpenFile("war3map.w3i")){
                        BinaryReader br         = new BinaryReader(m);
                        var          FileFormat = br.ReadInt32();
                        if (FileFormat != 18 && FileFormat != 25)
                        {
                            throw new Exception("Unknown w3i file format " + FileFormat);
                        }

                        //most of these are practically garbage, but still fun to have :)
                        int    g_NumSaves              = br.ReadInt32();
                        int    g_EditorVer             = br.ReadInt32();
                        string g_MapName               = ConvertUtils.parseStringZ(br);
                        string g_MapAuthor             = ConvertUtils.parseStringZ(br);
                        string g_MapDesc               = ConvertUtils.parseStringZ(br);
                        string g_MapReccomendedPlayers = ConvertUtils.parseStringZ(br);
                        byte[] g_CameraBounds          = br.ReadBytes(32);
                        byte[] g_CameraBoundsExt       = br.ReadBytes(16);
                        int    g_MapWidth              = MapWidth = br.ReadInt32();
                        int    g_MapHeight             = MapHeight = br.ReadInt32();
                        int    g_MapFlags              = MapFlags = br.ReadInt32();
                        byte   g_MapGroundType         = br.ReadByte();

                        bool   g_TFTLoading = FileFormat == 25;
                        int    g_LoadingScreenId;
                        string g_LoadingScreenPath = "";
                        if (!g_TFTLoading)
                        {
                            g_LoadingScreenId = br.ReadInt32();
                        }
                        else
                        {
                            g_LoadingScreenId   = br.ReadInt32();
                            g_LoadingScreenPath = ConvertUtils.parseStringZ(br);
                        }

                        string g_LoadingText     = ConvertUtils.parseStringZ(br);
                        string g_LoadingTitle    = ConvertUtils.parseStringZ(br);
                        string g_LoadingSubTitle = ConvertUtils.parseStringZ(br);

                        int    g_PrologueScreenId;
                        string g_PrologueScreenPath = "";
                        if (!g_TFTLoading)
                        {
                            g_PrologueScreenId = br.ReadInt32();
                        }
                        else
                        {
                            g_PrologueScreenId   = br.ReadInt32();
                            g_PrologueScreenPath = ConvertUtils.parseStringZ(br);
                        }

                        string g_PrologueText     = ConvertUtils.parseStringZ(br);
                        string g_PrologueTitle    = ConvertUtils.parseStringZ(br);
                        string g_PrologueSubTitle = ConvertUtils.parseStringZ(br);

                        if (FileFormat == 25)
                        {
                            br.ReadBytes(4 + 4 + 4 + 4 + 1 + 1 + 1 + 1 + 4); // int fog, int fog startz, int fog endz, int fogdensity, byte fogRED, byte ffogGREEN, byte fogBLUE, byte fogALPHA, int globalWeatherId

                            ConvertUtils.parseStringZ(br);                   // custom sound environment

                            br.ReadBytes(5);                                 // bytes[5] {tilesetid, waterTintRED, waterTintGREEN, waterTintBLUE, waterTintALPHA}
                        }

                        int g_NumPlayers = MapNumPlayers = br.ReadInt32();
                        int ClosedSlots  = 0;

                        for (int i = 0; i < MapNumPlayers; i++)
                        {
                            Slot s = new Slot();

                            s.color = (byte)br.ReadInt32();
                            int status = br.ReadInt32();

                            if (status == 1)
                            {
                                s.slotStatus = (byte)SlotStatus.OPEN;
                            }
                            else if (status == 2)
                            {
                                s.slotStatus   = (byte)SlotStatus.OCCUPIED;
                                s.computer     = 1;
                                s.computertype = (byte)SlotCompType.NORMAL;
                            }
                            else
                            {
                                s.slotStatus = (byte)SlotStatus.CLOSED;
                                ClosedSlots++;
                            }

                            switch (br.ReadInt32())
                            {
                            case 1: s.race = (byte)SlotRace.HUMAN; break;

                            case 2: s.race = (byte)SlotRace.ORC; break;

                            case 3: s.race = (byte)SlotRace.UNDEAD; break;

                            case 4: s.race = (byte)SlotRace.NIGHTELF; break;

                            default: s.race = (byte)SlotRace.RANDOM; break;
                            }

                            br.ReadBytes(4);               // fixedstart
                            ConvertUtils.parseStringZ(br); //playername (could be interesting)
                            br.ReadBytes(16);              // startx, starty, allylow, allyhigh

                            if (s.slotStatus != (byte)SlotStatus.CLOSED)
                            {
                                Slots.Add(s);
                            }
                        }
                        MapNumPlayers -= ClosedSlots;

                        int g_NumTeams = MapNumTeams = br.ReadInt32();

                        for (int i = 0; i < MapNumTeams; i++)
                        {
                            int Flags      = br.ReadInt32();
                            int PlayerMask = br.ReadInt32();

                            for (int si = 0; si < MAX_SLOTS; si++)
                            {
                                if ((PlayerMask & 1) == 1)
                                {
                                    foreach (Slot s in Slots)
                                    {
                                        if (s.color == si)
                                        {
                                            s.team = (byte)i;
                                        }
                                    }
                                }

                                PlayerMask >>= 1;
                            }

                            ConvertUtils.parseStringZ(br); //Team Name
                        }
                    }

                    MapOptions    = MapFlags & ((int)MAPOPTIONS.MELEE | (int)MAPOPTIONS.FIXEDPLAYERSETTINGS | (int)MAPOPTIONS.CUSTOMFORCES);
                    MapFilterType = (int)MAPFILTERTYPE.SCENARIO;

                    if ((MapOptions & (int)MAPOPTIONS.MELEE) == (int)MAPOPTIONS.MELEE)
                    {
                        byte team = 0;
                        foreach (Slot s in Slots)
                        {
                            s.team = team++;
                            s.race = (byte)SlotRace.RANDOM;
                        }
                        MapFilterType = (int)MAPFILTERTYPE.MELEE;
                    }

                    if ((MapOptions & (int)MAPOPTIONS.FIXEDPLAYERSETTINGS) != (int)MAPOPTIONS.FIXEDPLAYERSETTINGS)
                    {
                        foreach (Slot s in Slots)
                        {
                            s.race = (byte)(s.race | (byte)SlotRace.SELECTABLE);
                        }
                    }
                }
            }

            LoadGameVariables();

            if ((MapFlags & (int)MAPFLAGS.RANDOMRACES) == (int)MAPFLAGS.RANDOMRACES)
            {
                foreach (Slot s in Slots)
                {
                    s.race = (byte)SlotRace.RANDOM;
                }
            }

            if ((MapObservers & (int)MAPOBSERVERS.ALLOWED) == (int)MAPOBSERVERS.ALLOWED || (MapObservers & (int)MAPOBSERVERS.REFEREES) == (int)MAPOBSERVERS.REFEREES)
            {
                var observercount = MAX_SLOTS;
                if ((MapOptions & (int)MAPOPTIONS.MELEE) == (int)MAPOPTIONS.MELEE)
                {
                    observercount = 12;
                }
                while (Slots.Count < observercount)
                {
                    Slots.Add(new Slot(0, 255, (byte)SlotStatus.OPEN, 0, MAX_SLOTS, MAX_SLOTS, (byte)SlotRace.RANDOM | (byte)SlotRace.SELECTABLE));
                }
            }

            // System.Console.WriteLine(BitConverter.ToString(MapInfo).Replace("-",""));
            // System.Console.WriteLine(BitConverter.ToString(MapCRC).Replace("-",""));
            // System.Console.WriteLine(BitConverter.ToString(MapSha).Replace("-",""));
        }
예제 #7
0
 public bool Exists(string file)
 {
     return(mpqArchive.FileExists(file));
 }