Example #1
0
 public GameBalance(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.Type = (BalanceType)stream.ReadValueS32();
     Gbi = stream.ReadString(256, true);
     Xls = stream.ReadString(256, true);
     this.I0 = stream.ReadValueS32();
     this.I1 = stream.ReadValueS32();
     this.ItemType = stream.ReadSerializedData<ItemTypeTable>(); //536
     stream.Position += 8;
     this.Item = stream.ReadSerializedData<ItemTable>(); //552
     stream.Position += 8;
     this.Experience = stream.ReadSerializedData<ExperienceTable>(); //568
     stream.Position += 8;
     this.HelpCodes = stream.ReadSerializedData<HelpCodesTable>(); //584
     stream.Position += 8;
     this.MonsterLevel = stream.ReadSerializedData<MonsterLevelTable>(); //600
     stream.Position += 8;
     this.Affixes = stream.ReadSerializedData<AffixTable>(); //616
     stream.Position += 8;
     this.Heros = stream.ReadSerializedData<HeroTable>(); //632
     stream.Position += 8;
     this.MovementStyles = stream.ReadSerializedData<MovementStyleTable>(); //648
     stream.Position += 8;
     this.Labels = stream.ReadSerializedData<LabelGBIDTable>(); //664
     stream.Position += 8;
     this.LootDistribution = stream.ReadSerializedData<LootDistTable>(); //680
     stream.Position += 8;
     this.RareItemNames = stream.ReadSerializedData<RareItemNamesTable>(); //696
     stream.Position += 8;
     this.MonsterAffixes = stream.ReadSerializedData<MonsterAffixesTable>(); //712
     stream.Position += 8;
     this.RareMonsterNames = stream.ReadSerializedData<MonsterNamesTable>(); //728
     stream.Position += 8;
     this.SocketedEffects = stream.ReadSerializedData<SocketedEffectTable>(); //744
     stream.Position += 8;
     this.ItemEnhancement = stream.ReadSerializedData<ItemEnhancementTable>(); //760
     stream.Position += 8;
     this.ItemDrop = stream.ReadSerializedData<ItemDropTable>(); //776
     stream.Position += 8;
     this.ItemLevelMod = stream.ReadSerializedData<ItemLevelModTable>(); //792
     stream.Position += 8;
     this.QualityClass = stream.ReadSerializedData<QualityClassTable>(); //808
     stream.Position += 8;
     this.Hirelings = stream.ReadSerializedData<HirelingTable>(); //824
     stream.Position += 8;
     this.SetItemBonus = stream.ReadSerializedData<SetItemBonusTable>(); //840
     stream.Position += 8;
     this.EliteModifiers = stream.ReadSerializedData<EliteModTable>(); //856
     stream.Position += 8;
     this.ItemTiers = stream.ReadSerializedData<ItemTierTable>(); //872
     stream.Position += 8;
     this.PowerFormula = stream.ReadSerializedData<PowerFormulaTable>(); //888
     stream.Position += 8;
     this.Recipes = stream.ReadSerializedData<RecipeTable>(); //904
     stream.Position += 8;
     this.ScriptedAchievementEvents = stream.ReadSerializedData<ScriptedAchievementEventsTable>(); //920
     stream.Close();
 }
Example #2
0
 public QuestRange(MpqFile file)
 {
     var stream = file.Open();
     this.Time0 = new QuestTime(stream);
     this.Time1 = new QuestTime(stream);
     stream.Close();
 }
Example #3
0
        public MarkerSet(MpqFile file)
        {
            var stream = file.Open();
            Header = new Header(stream);
            SNO = stream.ReadInt32();
            unknown0 = stream.ReadInt32();
            unknown1 = stream.ReadInt32();
            serMarkers = new SerializeData(stream);
            long x = stream.Position;
            Markers = new Marker[serMarkers.Size / 208];
            stream.Position = serMarkers.Offset + 16;
            for (int i = 0; i < serMarkers.Size / 208; i++)
            {
                Markers[i] = new Marker(stream);
            }
            stream.Position = x;
            stream.Position += (15 * 4); // pad 15
            serNoSpawns = new SerializeData(stream);
            stream.Position += (14 * 4);
            aabb = new AABB_(stream);
            i0 = stream.ReadInt32();
            byte[] buf = new byte[256];
            stream.Read(buf, 0, 256); filename = Encoding.ASCII.GetString(buf);
            nLabel = stream.ReadInt32();
            nSpecialIndexCount = stream.ReadInt32();
            serSpecialIndexList = new SerializeData(stream);

                stream.Close();
        }
Example #4
0
        public Power(MpqFile file)
        {
            var stream = file.Open();   
            this.Header = new Header(stream);
            LuaName = stream.ReadString(64, true);
            stream.Position += 4; // pad 1
            Powerdef = new PowerDef(stream);
            stream.Position = 440; // Seems like theres a bit of a gap - DarkLotus
            I0 = stream.ReadValueS32();
            I1 = stream.ReadValueS32();
            Chararray2 = stream.ReadString(256, true);
            ScriptFormulaCount = stream.ReadValueS32();
            ScriptFormulaDetails = stream.ReadSerializedData<ScriptFormulaDetails>();
            stream.Position += (3 * 4);
            i3 = stream.ReadValueS32();
            stream.Position += (3 * 4);

            // TODO: please fix this - use our serializable-data readers instead! /raist
            // TODO add a class for complied script so it can be deserialized properly. - DarkLotus
            // none of the .pow appear to have any data here, and stream position appears to be correct, unsure - DarkLotus
            var serCompliedScript = stream.GetSerializedDataPointer();
            if (serCompliedScript.Size > 0)
            {
                long x = stream.Position;
                stream.Position = serCompliedScript.Offset + 16;
                var buf = new byte[serCompliedScript.Size];
                stream.Read(buf, 0, serCompliedScript.Size);
                stream.Position = x;
                CompliedScript.AddRange(buf);
            }
            SNOQuestMetaData = stream.ReadValueS32();
            stream.Close();
        }
Example #5
0
        public Quest(MpqFile file)
        {
            MpqFileStream stream = file.Open();

            Header = new Header(stream);
            QuestType = (QuestType)stream.ReadValueS32();
            NumberOfSteps = stream.ReadValueS32();
            NumberOfCompletionSteps = stream.ReadValueS32();
            I2 = stream.ReadValueS32();
            I3 = stream.ReadValueS32();
            I4 = stream.ReadValueS32();
            I5 = stream.ReadValueS32();

            QuestUnassignedStep = new QuestUnassignedStep(stream);
            stream.Position += 8;
            QuestSteps = stream.ReadSerializedData<QuestStep>();
            stream.Position += 8;
            QuestCompletionSteps = stream.ReadSerializedData<QuestCompletionStep>();

            LevelRange1 = new QuestLevelRange(stream);
            LevelRange2 = new QuestLevelRange(stream);
            LevelRange3 = new QuestLevelRange(stream);
            LevelRange4 = new QuestLevelRange(stream);


            stream.Close();
        }
Example #6
0
        public Conversation(MpqFile file)
        {
            MpqFileStream stream = file.Open();

            this.Header = new Header(stream);
            this.ConversationType = (ConversationTypes)stream.ReadValueS32();
            this.I0 = stream.ReadValueS32();
            this.I1 = stream.ReadValueS32();
            this.SNOQuest = stream.ReadValueS32();
            this.I2 = stream.ReadValueS32();
            this.I3 = stream.ReadValueS32();
            this.SNOConvPiggyback = stream.ReadValueS32();
            this.SNOConvUnlock = stream.ReadValueS32();
            this.I4 = stream.ReadValueS32();
            this.Unknown = stream.ReadString(128, true);
            this.SNOPrimaryNpc = stream.ReadValueS32();
            this.SNOAltNpc1 = stream.ReadValueS32();
            this.SNOAltNpc2 = stream.ReadValueS32();
            this.SNOAltNpc3 = stream.ReadValueS32();
            this.SNOAltNpc4 = stream.ReadValueS32();
            this.I5 = stream.ReadValueS32();

            stream.Position += (2 * 4);
            RootTreeNodes = stream.ReadSerializedData<ConversationTreeNode>();

            this.Unknown2 = stream.ReadString(256, true);
            this.I6 = stream.ReadValueS32();

            stream.Position += 12;
            CompiledScript = Encoding.ASCII.GetString(stream.ReadSerializedByteArray());
            stream.Position += 40;
            this.SNOBossEncounter = stream.ReadValueS32();
            stream.Close();
        }
Example #7
0
        public MarkerSet(MpqFile file)
        {
            var stream = file.Open();
            this.Header = new Header(stream);

            this.Markers = stream.ReadSerializedData<Marker>();

            stream.Position += (15 * 4);
            var pointerSpawns = stream.GetSerializedDataPointer();
            //TODO Load spawn locations

            stream.Position += (14 * 4);
            this.AABB = new AABB(stream);
            int i0 = stream.ReadValueS32();
            if (i0 != 0 && i0 != 1)
                throw new System.Exception("Farmy thought this field is a bool, but apparently its not");
            this.ContainsActorLocations = i0 == 1;

            this.FileName = stream.ReadString(256, true);

            this.NLabel = stream.ReadValueS32();
            SpecialIndexCount = stream.ReadValueS32();

            var pointerSpecialIndexList = stream.GetSerializedDataPointer();
            // TODO Load PointerSpecialIndexList

            stream.Close();
        }
Example #8
0
 public Recipe(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     ItemSpecifierData = new ItemSpecifierData(stream);
     stream.Close();
 }
Example #9
0
        public Scene(MpqFile file)
        {
            var stream = file.Open();
            this.Header = new Header(stream);

            Int0 = stream.ReadValueS32();
            this.AABBBounds = new AABB(stream);
            this.AABBMarketSetBounds = new AABB(stream);

            this.NavMesh = new NavMeshDef(stream);
            this.Exclusions = stream.ReadSerializedInts();

            stream.Position += (14 * 4);
            this.Inclusions = stream.ReadSerializedInts();

            stream.Position += (14 * 4);
            this.MarkerSets = stream.ReadSerializedInts();

            stream.Position += (14 * 4);
            this.LookLink = stream.ReadString(64, true);

            this.MsgTriggeredEvent = stream.ReadSerializedData<MsgTriggeredEvent>();
            this.Int1 = stream.ReadValueS32();

            stream.Position += (3 * 4);
            this.NavZone = new NavZoneDef(stream);
            this.SNOAppearance = stream.ReadValueS32();
            this.SNOPhysMesh = stream.ReadValueS32();
            stream.Close();
        }
Example #10
0
        public Scene(MpqFile file)
        {
            var stream = file.Open();
            this.Header = new Header(stream);

            Int0 = stream.ReadValueS32();
            this.AABBBounds = new AABB(stream);
            this.AABBMarketSetBounds = new AABB(stream);

            this.NavMesh = new NavMeshDef(stream); //load NavMeshDef
            var exclusions = stream.GetSerializedDataPointer();

            stream.Position += (14 * 4);
            var inclusions = stream.GetSerializedDataPointer();

            stream.Position += (14 * 4);
            this.MarkerSets = stream.ReadSerializedInts();

            stream.Position += (14 * 4);
            this.LookLink = stream.ReadString(64, true);

            // Maybe this is a list/array - DarkLotus
            this.MsgTriggeredEvent = stream.ReadSerializedItem<MsgTriggeredEvent>();
            this.Int1 = stream.ReadValueS32();

            stream.Position += (3 * 4);
            this.NavZone = new NavZoneDef(stream);

            stream.Close();
        }
Example #11
0
 public QuestRange(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.Start = new QuestTime(stream);
     this.End = new QuestTime(stream);
     stream.Close();
 }
Example #12
0
 /// <summary>Resolves the data corresponding to the base file of a given patch <see cref="MpqFile"/>.</summary>
 /// <param name="file">The patch file.</param>
 /// <returns>A <see cref="Stream"/> containing the data for the base file if it was found; otherwise <c>null</c>.</returns>
 internal Stream ResolveBaseFileInternal(MpqFile file)
 {
     if (ResolveBaseFile != null)
         lock (resolveStreamEventArgs)
         {
             ResolveBaseFile(file, resolveStreamEventArgs);
             return(resolveStreamEventArgs.TransferStreamOwnership());
         } }
Example #13
0
 public ConversationList(MpqFile file)
 {
     MpqFileStream stream = file.Open();
     this.Header = new Header(stream);
     stream.Position += (12);
     ConversationListEntries = stream.ReadSerializedData<ConversationListEntry>();
     stream.Close();
 }
Example #14
0
 public Recipe(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.SNO = stream.ReadValueS32();
     stream.Position += (2 * 4);
     ItemSpecifierData = new ItemSpecifierData(stream);
     stream.Close();
 }
Example #15
0
 public Tutorial(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.I0 = stream.ReadValueS32();
     this.I1 = stream.ReadValueS32();
     this.Time = stream.ReadValueS32();
     stream.Close();
 }
Example #16
0
 public Encounter(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.SNOSpawn = stream.ReadValueS32();
     stream.Position += (2 * 4);// pad 2 int
     this.Spawnoptions = stream.ReadSerializedData<EncounterSpawnOptions>();
     stream.Close();
 }
Example #17
0
 public Actor(MpqFile file)
 {
     var stream = file.Open();
     stream.Seek(16, SeekOrigin.Begin);
     this.ActorSNO = stream.ReadInt32();
     stream.Position = 120;
     this.AnimSetSNO = stream.ReadInt32();
     stream.Close();
 }
Example #18
0
 public SkillKit(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     stream.Position += 12;
     this.TraitEntries = stream.ReadSerializedData<TraitEntry>();
     stream.Position += 8;
     this.ActiveSkillEntries = stream.ReadSerializedData<ActiveSkillEntry>();
     stream.Close();
 }
Example #19
0
 public SceneGroup(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.I0 = stream.ReadValueS32();
     this.Items = stream.ReadSerializedData<SceneGroupItem>();
     stream.Position += 8;
     this.I1 = stream.ReadValueS32();
     stream.Close();
 }
Example #20
0
        public int BitField1 { get; private set; }           // 25 bits - better this this would be an uint

        public Actor(MpqFile file)
        {
            var stream = file.Open();
            Header = new Header(stream);

            this.Int0 = stream.ReadValueS32();
            this.Type = (ActorType)stream.ReadValueS32();
            this.ApperanceSNO = stream.ReadValueS32();
            this.PhysMeshSNO = stream.ReadValueS32();
            this.Cylinder = new AxialCylinder(stream);
            this.Sphere = new Sphere(stream);
            this.AABBBounds = new AABB(stream);

            this.TagMap = stream.ReadSerializedItem<TagMap>();
            stream.Position += (2 * 4);

            this.AnimSetSNO = stream.ReadValueS32();
            this.MonsterSNO = stream.ReadValueS32();

            MsgTriggeredEvents = stream.ReadSerializedData<MsgTriggeredEvent>();

            this.Int1 = stream.ReadValueS32();
            stream.Position += (3 * 4);
            this.V0 = new Vector3D(stream.ReadValueF32(), stream.ReadValueF32(), stream.ReadValueF32());

            this.Looks = new WeightedLook[8];
            for (int i = 0; i < 8; i++)
            {
                this.Looks[i] = new WeightedLook(stream);
            }

            this.PhysicsSNO = stream.ReadValueS32();
            this.Int2 = stream.ReadValueS32();
            this.Int3 = stream.ReadValueS32();
            this.Float0 = stream.ReadValueF32();
            this.Float1 = stream.ReadValueF32();
            this.Float2 = stream.ReadValueF32();

            this.ActorCollisionData = new ActorCollisionData(stream);

            this.InventoryImages = new int[10]; //Was 5*8/4 - Darklotus
            for (int i = 0; i < 10; i++)
            {
                this.InventoryImages[i] = stream.ReadValueS32();
            }
            this.Int4 = stream.ReadValueS32();
            stream.Position += 4;
            BitField0 = stream.ReadValueS32();
            CastingNotes = stream.ReadSerializedString();
            VoiceOverRole = stream.ReadSerializedString();

            // Updated based on BoyC's 010 template and Moack's work. Think we just about read all data from actor now.- DarkLotus
            stream.Close();
        }
Example #21
0
 public TreasureClass(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.Percentage = stream.ReadValueF32();
     this.I0 = stream.ReadValueS32();
     this.I1 = stream.ReadValueS32();
     stream.Position += 8;
     this.ModifierList = stream.ReadSerializedData<LootDropModifier>();
     stream.Close();
 }
Example #22
0
File: Lore.cs Project: Naxp/mooege
 public Lore(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.I0 = stream.ReadValueS32();
     this.Category = (LoreCategory)stream.ReadValueS32();
     this.I1 = stream.ReadValueS32();
     this.I2 = stream.ReadValueS32();
     this.SNOConversation = stream.ReadValueS32();
     this.I3 = stream.ReadValueS32();
     stream.Close();
 }
Example #23
0
 public Lore(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.SNO = stream.ReadValueS32();
     this.i0 = stream.ReadValueS32();
     this.i1 = stream.ReadValueS32();
     this.i2 = stream.ReadValueS32();
     this.snoConversation = stream.ReadValueS32();
     this.i3 = stream.ReadValueS32();
     stream.Close();
 }
Example #24
0
        public MpqFile[] FindFiles(string filename)
        {
            int[]     blocks = hashTable.FindMulti(filename);
            MpqFile[] files  = new MpqFile[blocks.Length];

            for (int i = 0; i < blocks.Length; i++)
            {
                blockTable.Entries[blocks[i]].OnNameDetected(filename);
                files[i] = files[blockTable.Entries[blocks[i]].FileIndex];
            }
            return(files);
        }
Example #25
0
 public Adventure(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.SNOSymbolActor = stream.ReadValueS32();
     this.F0 = stream.ReadValueF32();
     this.F1 = stream.ReadValueF32();
     this.F2 = stream.ReadValueF32();
     this.F3 = stream.ReadValueF32();
     this.SNOMarkerSet = stream.ReadValueS32();
     stream.Close();
 }
Example #26
0
        public Globals(MpqFile file)
        {
            var stream = file.Open();
            this.Header = new Header(stream);
            stream.Position += 8;
            this.ServerData = stream.ReadSerializedData<GlobalServerData>();

            stream.Position += 4;
            this.I0 = stream.ReadValueS32(); //32
            stream.Position += 12;
            this.StartLocationNames = new Dictionary<int, FileFormats.StartLocationName>();
            foreach (var startLocation in stream.ReadSerializedData<StartLocationName>())
                StartLocationNames.Add(startLocation.I0, startLocation);

            this.F0 = stream.ReadValueF32(); //56
            this.F1 = stream.ReadValueF32(); //60
            this.F2 = stream.ReadValueF32(); //64
            this.F3 = stream.ReadValueF32(); //68

            Colors = new RGBAColor[400]; //72
            for (int i = 0; i < 400; i++)
                Colors[i] = new RGBAColor(stream);

            this.I1 = stream.ReadValueS32(); //1672
            this.F4 = stream.ReadValueF32(); //1676
            this.I2 = stream.ReadValueS32(); //1680
            this.F5 = stream.ReadValueF32(); //1684
            this.F6 = stream.ReadValueF32(); //1688
            this.I3 = stream.ReadValueS32(); //1692
            this.I4 = stream.ReadValueS32(); //1696
            this.F7 = stream.ReadValueF32(); //1700
            this.F8 = stream.ReadValueF32(); //1704
            this.F9 = stream.ReadValueF32(); //1708
            this.I5 = stream.ReadValueS32(); //1712
            this.I6 = new int[4]; //1716
            for (int i = 0; i < 4; i++)
                this.I6[i] = stream.ReadValueS32();
            stream.Position += 4;
            this.BannerParams = new BannerParams(stream); //1736
            this.I7 = stream.ReadValueS32(); //1968
            this.I8 = stream.ReadValueS32(); //1972
            this.I9 = stream.ReadValueS32(); //1976
            this.I10 = stream.ReadValueS32(); //1980
            this.F10 = stream.ReadValueF32(); //1984
            this.F11 = stream.ReadValueF32(); //1988
            this.F12 = stream.ReadValueF32(); //1992
            this.F13 = stream.ReadValueF32(); //1996
            this.F14 = stream.ReadValueF32(); //2000
            this.F15 = stream.ReadValueF32(); //2004
            this.F16 = stream.ReadValueF32(); //2008
            this.F17 = stream.ReadValueF32(); //2012
            stream.Close();
        }
Example #27
0
        public Actor(MpqFile file)
        {
            var stream = file.Open();
            Header = new Header(stream);

            this.Int0 = stream.ReadValueS32();
            this.Type = (ActorType)stream.ReadValueS32();
            this.ApperanceSNO = stream.ReadValueS32();
            this.PhysMeshSNO = stream.ReadValueS32();
            this.Cylinder = new AxialCylinder(stream);
            this.Sphere = new Sphere(stream);
            this.AABBBounds = new AABB(stream);

            var tagmap = stream.GetSerializedDataPointer(); // we need to read tagmap. /raist.
            stream.Position += (2*4);

            this.AnimSetSNO = stream.ReadValueS32();
            this.MonsterSNO = stream.ReadValueS32();

            var msgTriggeredEvents = stream.GetSerializedDataPointer();

            this.Int1 = stream.ReadValueS32();
            stream.Position += (3*4);
            this.V0 = new Vector3D(stream.ReadValueF32(), stream.ReadValueF32(), stream.ReadValueF32());

            this.Looks = new WeightedLook[8];
            for (int i = 0; i < 8; i++)
            {
                this.Looks[i] = new WeightedLook(stream);
            }

            this.PhysicsSNO = stream.ReadValueS32();
            this.Int2 = stream.ReadValueS32();
            this.Int3 = stream.ReadValueS32();
            this.Float0 = stream.ReadValueF32();
            this.Float1 = stream.ReadValueF32();
            this.Float2 = stream.ReadValueF32();

            this.ActorCollisionData = new int[17]; // Was 68/4 - Darklotus 
            for (int i = 0; i < 17; i++)
            {
                this.ActorCollisionData[i] = stream.ReadValueS32();
            }

            this.InventoryImages = new int[10]; //Was 5*8/4 - Darklotus
            for (int i = 0; i < 10; i++)
            {
                this.InventoryImages[i] = stream.ReadValueS32();
            }

            // Updated based on BoyC's 010editoer template, looks like some data at the end still isnt parsed - Darklotus
            stream.Close();
        }
Example #28
0
 public PhysMesh(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.I0 = stream.ReadValueS32();
     this.CollisionMeshCount = stream.ReadValueS32();
     this.CollisionMeshes = stream.ReadSerializedData<CollisionMesh>();
     stream.Position += 12;
     this.S0 = stream.ReadString(256);
     this.S1 = stream.ReadString(256);
     this.I1 = stream.ReadValueS32();
     stream.Close();
 }
Example #29
0
File: Anim.cs Project: ralje/mooege
 public Anim(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.I0 = stream.ReadValueS32();
     this.I1 = stream.ReadValueS32();
     this.SNOAppearance = stream.ReadValueS32();
     this.Permutations = stream.ReadSerializedData<AnimPermutation>();
     this.I2 = stream.ReadValueS32();
     stream.Position += 12;
     this.I3 = stream.ReadValueS32();
     stream.Close();
 }
Example #30
0
 public LevelArea(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.I0 = stream.ReadValueS32();
     this.I1 = stream.ReadValueS32();
     this.SNOLevelAreaOverrideForGizmoLocs = stream.ReadValueS32();
     this.LocSet = new GizmoLocSet(stream);
     this.I2 = stream.ReadValueS32();
     stream.Position += 12;
     this.SpawnPopulation = stream.ReadSerializedData<LevelAreaSpawnPopulation>();
     stream.Close();
 }
Example #31
0
 public Condition(MpqFile file)
 {
     var stream = file.Open();
     this.Header = new Header(stream);
     this.I0 = stream.ReadValueS32();
     this.I1 = stream.ReadValueS32();
     this.Class = new int[5];
     for (int i = 0; i < 5; i++)
         this.Class[i] = stream.ReadValueS32();
     this.Difficulty = new int[4];
     for (int i = 0; i < 4; i++)
         this.Difficulty[i] = stream.ReadValueS32();
     this.LoreCondition = new LoreSubcondition[3];
     for (int i = 0; i < 3; i++)
         this.LoreCondition[i] = new LoreSubcondition(stream);
     this.QuestCondition = new QuestSubcondition[3];
     for (int i = 0; i < 3; i++)
         this.QuestCondition[i] = new QuestSubcondition(stream);
     this.ItemCondition = new ItemSubcondition[3];
     for (int i = 0; i < 3; i++)
         this.ItemCondition[i] = new ItemSubcondition(stream);
     this.I4 = stream.ReadValueS32(); //176
     this.I5 = stream.ReadValueS32();
     this.I6 = stream.ReadValueS32();
     this.I7 = stream.ReadValueS32();
     stream.Position += 4;
     this.I8 = stream.ReadValueS32();
     this.I9 = stream.ReadValueS32();
     this.I10 = stream.ReadValueS32();
     this.I11 = stream.ReadValueS32();
     this.SNOCurrentWorld = stream.ReadValueS32();
     this.SNOCurrentLevelArea = stream.ReadValueS32();
     this.SNOQuestRange = stream.ReadValueS32();
     this.FollowerCondition = new FollowerSubcondition(stream);
     this.LabelCondition = new LabelSubcondition[3];
     for (int i = 0; i < 3; i++)
         this.LabelCondition[i] = new LabelSubcondition(stream);
     this.SkillCondition = new SkillSubcondition[3];
     for (int i = 0; i < 3; i++)
         this.SkillCondition[i] = new SkillSubcondition(stream);
     this.MonsterCondition = new MonsterSubcondition[3];
     for (int i = 0; i < 3; i++)
         this.MonsterCondition[i] = new MonsterSubcondition(stream);
     this.GameFlagCondition = new GameFlagSubcondition[3];
     for (int i = 0; i < 3; i++)
         this.GameFlagCondition[i] = new GameFlagSubcondition(stream);
     this.PlayerFlagCondition = new PlayerFlagSubcondition[3];
     for (int i = 0; i < 3; i++)
         this.PlayerFlagCondition[i] = new PlayerFlagSubcondition(stream);
     stream.Close();
 }
Example #32
0
        public Scene(MpqFile file)
        {
            var stream = file.Open();

            long pos = 0; // x
            DEADBEEF = stream.ReadInt32();
            snoType = stream.ReadInt32();
            unknown1 = stream.ReadInt32();
            unknown2 = stream.ReadInt32();
            SceneSNO = stream.ReadInt32();
            unknown3 = stream.ReadInt32();
            unknown4 = stream.ReadInt32();
            i0 = stream.ReadInt32();
            aabbBounds = new AABB(stream);
            aabbMarkerSetBounds = new AABB(stream);

            //load NavMeshDef
            NavMesh = new NavMeshDef(stream);
            // end navmeshdef
            var serExclusions = new SerializeData(stream);
            stream.Position += 56;
            var serInclusions = new SerializeData(stream);
            stream.Position += 56;

            //MarkerSet Time
            var serMarkerSets = new SerializeData(stream);
            pos = stream.Position;
            stream.Position = serMarkerSets.Offset + 16;
            MarkerSets = new int[serMarkerSets.Size/4];
            for (int i = 0; i < serMarkerSets.Size/4; i++)
            {
                MarkerSets[i] = stream.ReadInt32();
            }
            stream.Position = pos + 56;

            //TODO - parse LookLink /dark
            LookLink = new char[64];
            for (int i = 0; i < 64; i++)
            {
                LookLink[i] = (char) stream.ReadByte();
            }

            var sermsgTriggeredEvents = new SerializeData(stream);
            int i1 = stream.ReadInt32();
            stream.Position += 12;

            //navzonedef
            NavZone = new NavZoneDef(stream);

            stream.Close();
        }
Example #33
0
        private void CreateFiles(uint fileCount)
        {
            files = new MpqFile[fileCount];

            for (uint i = 0, blockIndex = 0; i < fileCount; i++)
            {
                while ((blockTable.Entries[blockIndex].Flags & MpqFileFlags.Exists) == 0)
                {
                    blockIndex++;
                }

                files[i] = new MpqFile(this, blockIndex++);
            }
        }
Example #34
0
        public MpqFile[] FindFiles(string filename)
        {
            foreach (var archive in archiveList)
            {
                var files = archive.FindFiles(filename);

                if (files.Length > 0)
                {
                    int deletedFileCount = 0;

                    foreach (var file in files)
                    {
                        if ((file.Flags & MpqFileFlags.Deleted) != 0)
                        {
                            deletedFileCount++;
                        }
                    }

                    if (deletedFileCount == 0)
                    {
                        return(files);
                    }
                    else if (deletedFileCount == files.Length)
                    {
                        break;
                    }

                    var existingFiles = new MpqFile[files.Length - deletedFileCount];

                    int i = 0;

                    foreach (var file in files)
                    {
                        if ((file.Flags & MpqFileFlags.Deleted) == 0)
                        {
                            existingFiles[i++] = file;
                        }
                    }

                    return(existingFiles);
                }
            }
            return(new MpqFile[0]);
        }
Example #35
0
        private void OpenInternal(Stream stream, bool shouldParseListFile)
        {
            // MPQ offsets can be 32 bits, 48 bits or 64 bits depending on the MPQ version used…
            long hashTableOffset, hashTableCompressedSize, hashTableSize;
            long blockTableOffset, blockTableCompressedSize, blockTableSize;
            long highBlockTableOffset, highBlockTableCompressedSize, highBlockTableSize;
            long enhancedHashTableOffset, enhancedHashTableCompressedSize;
            long enhancedBlockTableOffset, enhancedBlockTableCompressedSize;
            uint hashTableLength, blockTableLength;
            uint rawChunkSize;
            uint signature;

            byte[] hashes;

            if (!stream.CanSeek)
            {
                throw new InvalidOperationException(ErrorMessages.GetString("SeekableStreamRequired"));
            }
            if (checked (stream.Position + stream.Length) < 0x20)
            {
                throw new InvalidDataException(ErrorMessages.GetString("NotEnoughData"));
            }

            // We use a lot of "long" and "int" variables here, but data is likely stored as ulong and uint…
            // So better test for overflow… Who knows what might happen in the future… ;)
            // The "safe" pattern is to read as unsigned and cast to signed where oferflow is possible.
            checked
            {
                this.stream       = stream;
                archiveDataOffset = stream.Position;                 // We don't handle searching for MPQ data. The stream must already be positionned at the beginning of the MPQ data.
                signature         = stream.ReadUInt32();
                // The first part of the file may be MPQ user data. The next part should be regular MPQ archive data.
                if (signature == MpqUserDataSignature)
                {
                    userDataOffset = archiveDataOffset;
                    userDataLength = stream.ReadUInt32();
                    stream.Seek(stream.ReadUInt32() - 3 * sizeof(uint), SeekOrigin.Current);
                    archiveDataOffset = stream.Position;
                    signature         = stream.ReadUInt32();
                }
                // Checking for MPQ archive signature
                if (signature != MpqArchiveSignature)
                {
                    throw new InvalidDataException(ErrorMessages.GetString("InvalidData"));
                }
                headerSize        = stream.ReadUInt32();
                archiveDataLength = stream.ReadUInt32();
                // MPQ format detection
                // Unknown MPQ version will raise an error… This seems like a safe idea.
                ushort mpqVersion = stream.ReadUInt16();
                switch (mpqVersion)             // Read MPQ format
                {
                case 0:                         // Original MPQ format
                    archiveFormat = MpqFormat.Original;
                    if (headerSize < 0x20)
                    {
                        throw new InvalidDataException(ErrorMessages.GetString("InvalidArchiveHeader"));
                    }
                    break;

                case 1:                         // Extended MPQ format (WoW Burning Crusade)
                    archiveFormat = MpqFormat.BurningCrusade;
                    if (headerSize < 0x2C)
                    {
                        throw new InvalidDataException(ErrorMessages.GetString("InvalidArchiveHeader"));
                    }
                    break;

                case 2:                         // Enhanced MPQ format (Take 1)
                    archiveFormat = MpqFormat.CataclysmFirst;
                    // Header may not contain any additional field than BC extended MPQ format.
                    // However, if additional fields are present, the header should be at least 68 bytes long.
                    if (headerSize < 0x2C || (headerSize > 0x2C && headerSize < 0x44))
                    {
                        throw new InvalidDataException(ErrorMessages.GetString("InvalidArchiveHeader"));
                    }
                    break;

                case 3:                         // Enhanced MPQ format (Take 2)
                    archiveFormat = MpqFormat.CataclysmSecond;
                    if (headerSize < 0xD0)
                    {
                        throw new InvalidDataException(ErrorMessages.GetString("InvalidArchiveHeader"));
                    }
                    break;

                default:
                    throw new MpqVersionNotSupportedException(mpqVersion); // Newer MPQ versions can probably be read just as well by the existing code… But can't know for sure…
                }
                blockSize        = 0x200 << stream.ReadUInt16();           // Calculate block size
                hashTableOffset  = stream.ReadUInt32();                    // Get Hash Table Offset
                blockTableOffset = stream.ReadUInt32();                    // Get Block Table Offset
                hashTableLength  = stream.ReadUInt32();                    // Get Hash Table Size
                blockTableLength = stream.ReadUInt32();                    // Get Block Table Size

                // Assign the compressed size for the various tables.
                // Since compression was non-existant with V1 & V2, we know the compressed size is the uncompressed size.
                // If the compressed size is different as specified in V4, this will be overwritten later.
                hashTableCompressedSize = 4 * sizeof(uint) * hashTableLength;
                if (blockTableOffset > hashTableOffset && blockTableOffset - hashTableOffset < hashTableCompressedSize)                 // Compute compressed hash table length if needed
                {
                    hashTableCompressedSize = blockTableOffset - hashTableOffset;
                }
                blockTableCompressedSize = 4 * sizeof(uint) * blockTableLength;

                // Process additional values for "Burning Crusade" MPQ format
                if (archiveFormat >= MpqFormat.BurningCrusade)
                {
                    ushort hashTableOffsetHigh, blockTableOffsetHigh;

                    // Read extended information
                    highBlockTableOffset         = (long)stream.ReadUInt64();
                    highBlockTableCompressedSize = highBlockTableOffset != 0 ? sizeof(uint) * blockTableLength : 0;
                    hashTableOffsetHigh          = stream.ReadUInt16();
                    blockTableOffsetHigh         = stream.ReadUInt16();
                    // Modify offsets accordingly
                    hashTableOffset  |= (long)hashTableOffsetHigh << 32;
                    blockTableOffset |= (long)blockTableOffsetHigh << 32;

                    // Handle MPQ version 3 (Cataclysm First) and newer
                    if (archiveFormat >= MpqFormat.CataclysmFirst && headerSize >= 0x44)
                    {
                        archiveDataLength        = (long)stream.ReadUInt64();
                        enhancedBlockTableOffset = (long)stream.ReadUInt64();
                        enhancedHashTableOffset  = (long)stream.ReadUInt64();

                        // Handle MPQ version 4 (Cataclysm Second)
                        if (archiveFormat >= MpqFormat.CataclysmSecond)
                        {
                            hashTableCompressedSize          = (long)stream.ReadUInt64();
                            blockTableCompressedSize         = (long)stream.ReadUInt64();
                            highBlockTableCompressedSize     = (long)stream.ReadUInt64();
                            enhancedHashTableCompressedSize  = (long)stream.ReadUInt64();
                            enhancedBlockTableCompressedSize = (long)stream.ReadUInt64();

                            rawChunkSize = stream.ReadUInt32();

                            hashes = new byte[6 * 16];

                            if (stream.Read(hashes, 0, hashes.Length) != hashes.Length)
                            {
                                throw new EndOfStreamException();
                            }
                        }
                        else
                        {
                            // TODO: Compute the uncompresed size for the new enhanced tables of version 3… (Will have to check how to do that…)
                            highBlockTableCompressedSize = highBlockTableOffset > 0 ? sizeof(ushort) * blockTableLength : 0;
                        }
                    }
                    else
                    {
#if DEBUG
                        long oldArchiveSize = archiveDataLength;
#endif
                        // Compute 64 bit archive size (We don't really need it for MPQ reading, but for integrity checks, we do…)
                        if (highBlockTableOffset > hashTableOffset && highBlockTableOffset > blockTableOffset)
                        {
                            archiveDataLength = highBlockTableOffset + sizeof(ushort) * blockTableLength;
                        }
                        else if (blockTableOffset > hashTableOffset)
                        {
                            archiveDataLength = blockTableOffset + 4 * sizeof(uint) * blockTableLength;
                        }
                        else
                        {
                            archiveDataLength = hashTableOffset + 4 * sizeof(uint) * hashTableLength;
                        }
#if DEBUG
                        Debug.Assert(oldArchiveSize >= archiveDataLength);
#endif
                    }
                }
                else
                {
                    highBlockTableOffset         = 0;
                    highBlockTableCompressedSize = 0;
                }

                if (!CheckOffset((uint)headerSize) ||
                    !CheckOffset(hashTableOffset) || !CheckOffset(blockTableOffset) ||
                    hashTableLength < blockTableLength)
                {
                    throw new InvalidDataException(ErrorMessages.GetString("InvalidArchiveHeader"));
                }

                hashTableSize      = 4 * sizeof(uint) * hashTableLength;
                blockTableSize     = 4 * sizeof(uint) * blockTableLength;
                highBlockTableSize = highBlockTableOffset != 0 ? sizeof(ushort) * blockTableLength : 0;

                // Check for strong signature presence
                if (stream.Length >= archiveDataOffset + archiveDataLength + 2052)
                {
                    stream.Seek(archiveDataOffset + archiveDataLength, SeekOrigin.Begin);

                    hasStrongSignature = stream.ReadUInt32() == MpqStrongSignatureSignature;
                }
            }

            // Create buffers for table reading
            var tableReadBuffer = hashTableSize < hashTableCompressedSize || blockTableSize < blockTableCompressedSize || highBlockTableCompressedSize < highBlockTableSize ?
                                  new byte[Math.Max(Math.Max(hashTableCompressedSize, blockTableCompressedSize), highBlockTableCompressedSize)] :
                                  null;

            var tableBuffer = new byte[Math.Max(hashTableSize, blockTableSize)];

            // Read Hash Table
            ReadHashTable(tableBuffer, hashTableLength, hashTableOffset, hashTableCompressedSize, tableReadBuffer);

            // Read Block Table
            ReadBlockTable(tableBuffer, blockTableLength, blockTableOffset, blockTableCompressedSize, highBlockTableOffset, highBlockTableCompressedSize, tableReadBuffer);

            // When possible, find and parse the listfile…
            listFile = FindFile(ListFileName);
            if (listFile == null)
            {
                return;
            }
            if (shouldParseListFile)
            {
                ParseListFile();
            }
        }
Example #36
0
        internal MpqFileStream(MpqFile file, Stream baseStream = null)
        {
            try
            {
                PatchInfoHeader?patchInfoHeader;                  // Used to differentiate between regulat files and patch files. Also contains the patch header :p

                // Store bits of information as local variables, in order to adjust them later.
                bool singleUnit     = (file.Flags & MpqFileFlags.SingleBlock) != 0;
                bool compressed     = file.IsCompressed;
                uint compressedSize = (uint)file.CompressedSize;

                this.file   = file;
                this.offset = file.Offset;

                // Process the patch information header first

                if (file.IsPatch)
                {
                    // Resolving the base file this early may be a waste if the patch ever happens to be a COPY patch… Anyway, it allows for checking the base file's integrity.
                    // But seriously, what's the point in COPY patches anyway ? Aren't those just like regular MPQ files, only with added (useless) weight ?
                    if ((baseStream = baseStream ?? file.Archive.ResolveBaseFileInternal(file)) == null)
                    {
                        throw new FileNotFoundException(string.Format(ErrorMessages.GetString("PatchBaseFileNotFound"), file.Name));
                    }

                    patchInfoHeader = ReadPatchInfoHeader(file.Archive, file.Offset);

                    offset += patchInfoHeader.Value.HeaderLength;
                    length  = patchInfoHeader.Value.PatchLength;                    // No matter what crap may be written in the block table, it seems that this field is always right (I had to update the decompression method just for that…)

                    if (patchInfoHeader.Value.PatchLength <= file.CompressedSize)
                    {
                        // As it seems, there are some bogus entries in the block table of mpq patch archives. (Only for patch files though)
                        // If you browse the list of DBC files, i'd say there are about 10% of them which have a bogus block table entry.
                        // So, for detecting them, we'll use the same method as in stormlib. We'll try to read the patch header to know is the patch is compressed or not.

                        // By the way, we cannot detect whether the patch is compressed or not if it is encrypted.
                        if (file.IsEncrypted)
                        {
                            throw new InvalidDataException(ErrorMessages.GetString("PatchInfoHeaderInvalidData"));
                        }

                        // Try to read the patch header in the data following the information header and adjust the compressed size dependign on the result:
                        // Since we are “sure” of the uncompressed size (given in the patch header), there is no point in compression if the compressed data isn't even one byte less.
                        // Thus, we can mostly safely decrease the compressed size by 1, which, by the way, is necessary to make decompression work in UpdateBuffer()…
                        compressedSize = patchInfoHeader.Value.PatchLength - ((compressed = !TestPatchHeader(file.Archive, offset)) ? (uint)1 : 0);

                        // It appears that the single unit flag is also lying on some patch entries. Files reported as blocky (such as some of the cataclysm mp3) are in fact single unit…
                        // Forcing this single unit flag to true when the file is compressed seems to be a good solution. Also, we may (or not :p) save a bit of memory by using blocks for uncompressed files.
                        singleUnit = compressed;
                    }
                }
                else
                {
                    patchInfoHeader = null;
                    length          = checked ((uint)file.Size);
                }

                // Set up the stream the same way for both patches and regular files…

                if (file.IsEncrypted)
                {
                    if (file.Seed == 0)
                    {
                        throw new SeedNotFoundException(file.BlockIndex);
                    }
                    else
                    {
                        this.seed = file.Seed;
                    }

                    if ((file.Flags & MpqFileFlags.PositionEncrypted) != 0)
                    {
                        this.seed = (this.seed + (uint)file.Offset) ^ (uint)this.length;
                    }
                }

                if (singleUnit)
                {
                    this.fileHeader = new uint[] { 0, compressedSize }
                }
                ;
                else if (compressed)
                {
                    this.fileHeader = ReadBlockOffsets(file.Archive, this.seed, this.offset, (int)((length + file.Archive.BlockSize - 1) / file.Archive.BlockSize + 1));
                }
                else
                {
                    this.fileHeader    = new uint[(int)(length + file.Archive.BlockSize - 1) / file.Archive.BlockSize + 1];
                    this.fileHeader[0] = 0;
                    for (int i = 1; i < this.fileHeader.Length; i++)
                    {
                        this.fileHeader[i] = this.fileHeader[i - 1] + (uint)file.Archive.BlockSize;
                        if (this.fileHeader[i] > length)
                        {
                            this.fileHeader[i] = (uint)this.length;
                        }
                    }
                }

                // Treat the files smaller than the block size as single unit. (But only now that we've read the file header)
                singleUnit |= length <= file.Archive.BlockSize;

                this.blockBuffer = new byte[singleUnit ? length : (uint)file.Archive.BlockSize];
                if (compressed)
                {
                    this.compressedBuffer = new byte[singleUnit ? compressedSize : (uint)file.Archive.BlockSize];
                }
                this.lastBlockLength = this.length > 0 ? this.length % (uint)this.blockBuffer.Length : 0;
                if (this.lastBlockLength == 0)
                {
                    this.lastBlockLength = (uint)this.blockBuffer.Length;
                }
                this.currentBlock = -1;

                UpdateBuffer();

                // If we finished initializing a stream to patch data, all there is left is to apply the patch
                if (patchInfoHeader != null)
                {
                    // The patching methods will read from this stream instance (whose constructor has yet to finish… !) and return the patched data.
                    this.blockBuffer = ApplyPatch(patchInfoHeader.Value, baseStream);
                    // Once the patch has been applied, transform this stream into a mere memory stream. (The same as with single unit files, in fact)
                    this.compressedBuffer = null;
                    this.fileHeader       = new uint[] { 0, (uint)this.blockBuffer.Length };
                    this.position         = 0;
                    this.currentBlock     = 0;
                    this.readBufferOffset = 0;
                    this.length           = (uint)this.blockBuffer.Length;
                }
            }
            finally { if (baseStream != null)
                      {
                          baseStream.Dispose();
                      }
            }
        }