diff --git a/ExploreForm.cs b/ExploreForm.cs index 397571e..9488756 100644 --- a/ExploreForm.cs +++ b/ExploreForm.cs @@ -189,21 +189,42 @@ namespace CodeWalker InitFileType(".awc", "Audio Wave Container", 22, FileTypeAction.ViewAwc); InitFileType(".rel", "Audio Data (REL)", 23, FileTypeAction.ViewRel); + InitSubFileType(".dat", "cache_y.dat", "Cache File", 6, FileTypeAction.ViewCacheDat); } private void InitFileType(string ext, string name, int imgidx, FileTypeAction defaultAction = FileTypeAction.ViewHex) { var ft = new FileTypeInfo(ext, name, imgidx, defaultAction); FileTypes[ext] = ft; } + private void InitSubFileType(string ext, string subext, string name, int imgidx, FileTypeAction defaultAction = FileTypeAction.ViewHex) + { + FileTypeInfo pti = null; + if (FileTypes.TryGetValue(ext, out pti)) + { + var ft = new FileTypeInfo(subext, name, imgidx, defaultAction); + pti.AddSubType(ft); + } + } public FileTypeInfo GetFileType(string fn) { var fi = new FileInfo(fn); - var ext = fi.Extension.ToLower(); + var ext = fi.Extension.ToLowerInvariant(); if (!string.IsNullOrEmpty(ext)) { FileTypeInfo ft; if (FileTypes.TryGetValue(ext, out ft)) { + if (ft.SubTypes != null) + { + var fnl = fn.ToLowerInvariant(); + foreach (var sft in ft.SubTypes) + { + if (fnl.EndsWith(sft.Extension)) + { + return sft; + } + } + } return ft; } else @@ -1062,6 +1083,7 @@ namespace CodeWalker case FileTypeAction.ViewYwr: case FileTypeAction.ViewYvr: case FileTypeAction.ViewYcd: + case FileTypeAction.ViewCacheDat: return true; case FileTypeAction.ViewHex: default: @@ -1168,6 +1190,9 @@ namespace CodeWalker case FileTypeAction.ViewYcd: ViewYcd(name, path, data, item.File); break; + case FileTypeAction.ViewCacheDat: + ViewCacheDat(name, path, data, item.File); + break; case FileTypeAction.ViewHex: default: ViewHex(name, path, data); @@ -1367,7 +1392,13 @@ namespace CodeWalker f.Show(); f.LoadYcd(ycd); } - + private void ViewCacheDat(string name, string path, byte[] data, RpfFileEntry e) + { + var cachedat = RpfFile.GetFile(e, data); + MetaForm f = new MetaForm(); + f.Show(); + f.LoadMeta(cachedat); + } private void ShowTreeContextMenu(TreeNode n, Point p) @@ -2740,6 +2771,7 @@ namespace CodeWalker public string Extension { get; set; } public int ImageIndex { get; set; } public FileTypeAction DefaultAction { get; set; } + public List SubTypes { get; set; } public FileTypeInfo(string extension, string name, int imageindex, FileTypeAction defaultAction) { @@ -2748,6 +2780,12 @@ namespace CodeWalker ImageIndex = imageindex; DefaultAction = defaultAction; } + + public void AddSubType(FileTypeInfo t) + { + if (SubTypes == null) SubTypes = new List(); + SubTypes.Add(t); + } } public enum FileTypeAction @@ -2770,6 +2808,7 @@ namespace CodeWalker ViewYwr = 15, ViewYvr = 16, ViewYcd = 17, + ViewCacheDat = 18, } } diff --git a/Forms/MetaForm.cs b/Forms/MetaForm.cs index dc2f773..9118e7c 100644 --- a/Forms/MetaForm.cs +++ b/Forms/MetaForm.cs @@ -223,7 +223,14 @@ namespace CodeWalker.Forms RawPropertyGrid.SelectedObject = cut; modified = false; } - + public void LoadMeta(CacheDatFile cachedat) + { + var fn = ((cachedat?.FileEntry?.Name) ?? "") + ".xml"; + Xml = cachedat.GetXml(); + FileName = fn; + RawPropertyGrid.SelectedObject = cachedat; + modified = false; + } diff --git a/GameFiles/FileTypes/CacheDatFile.cs b/GameFiles/FileTypes/CacheDatFile.cs index ebc6861..5d3e2c6 100644 --- a/GameFiles/FileTypes/CacheDatFile.cs +++ b/GameFiles/FileTypes/CacheDatFile.cs @@ -13,6 +13,7 @@ namespace CodeWalker.GameFiles { public RpfFileEntry FileEntry { get; set; } + public string Version { get; set; } public CacheFileDate[] FileDates { get; set; } public Dictionary MapNodeDict { get; set; } @@ -39,7 +40,7 @@ namespace CodeWalker.GameFiles if (b == 0) break; sb.Append((char)b); } - string versionstr = sb.ToString(); + Version = sb.ToString().Replace("[VERSION]", "").Replace("\r", "").Replace("\n", ""); sb.Clear(); int lastn = 0; int lspos = 0; @@ -201,6 +202,81 @@ namespace CodeWalker.GameFiles } + + public void LoadXml(string xml) + { + } + + public string GetXml() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine(MetaXmlBase.XmlHeader); + sb.AppendLine(string.Format("", Version)); + sb.AppendLine(" "); + if (FileDates != null) + { + foreach (var date in FileDates) + { + sb.AppendLine(string.Format(" {0}", date.ToCacheFileString())); + } + } + sb.AppendLine(" "); + sb.AppendLine(" "); + if (AllMapNodes != null) + { + foreach (var mapnode in AllMapNodes) + { + sb.AppendLine(" "); + sb.AppendLine(string.Format(" {0}", mapnode.Name.ToCleanString())); + sb.AppendLine(string.Format(" {0}", mapnode.ParentName.ToCleanString())); + sb.AppendLine(string.Format(" ", mapnode.ContentFlags.ToString())); + sb.AppendLine(string.Format(" ", FloatUtil.GetVector3XmlString(mapnode.streamingExtentsMin))); + sb.AppendLine(string.Format(" ", FloatUtil.GetVector3XmlString(mapnode.streamingExtentsMax))); + sb.AppendLine(string.Format(" ", FloatUtil.GetVector3XmlString(mapnode.entitiesExtentsMin))); + sb.AppendLine(string.Format(" ", FloatUtil.GetVector3XmlString(mapnode.entitiesExtentsMax))); + sb.AppendLine(string.Format(" ", mapnode.Unk1, mapnode.Unk2, mapnode.Unk3)); + sb.AppendLine(" "); + } + } + sb.AppendLine(" "); + sb.AppendLine(" "); + if (AllCInteriorProxies != null) + { + foreach (var intprox in AllCInteriorProxies) + { + sb.AppendLine(" "); + sb.AppendLine(string.Format(" {0}", intprox.Name.ToCleanString())); + sb.AppendLine(string.Format(" {0}", intprox.Parent.ToCleanString())); + sb.AppendLine(string.Format(" ", FloatUtil.GetVector3XmlString(intprox.Position))); + sb.AppendLine(string.Format(" ", FloatUtil.GetQuaternionXmlString(intprox.Orientation))); + sb.AppendLine(string.Format(" ", FloatUtil.GetVector3XmlString(intprox.BBMin))); + sb.AppendLine(string.Format(" ", FloatUtil.GetVector3XmlString(intprox.BBMax))); + sb.AppendLine(string.Format(" ", intprox.Unk01, intprox.Unk03)); + sb.AppendLine(string.Format(" ", intprox.Unk11, intprox.Unk12, intprox.Unk13, intprox.Unk14)); + sb.AppendLine(string.Format(" ", intprox.Unk15, intprox.Unk16, intprox.Unk17, intprox.Unk18)); + sb.AppendLine(" "); + } + } + sb.AppendLine(" "); + sb.AppendLine(" "); + if (AllBoundsStoreItems != null) + { + foreach (var bndstore in AllBoundsStoreItems) + { + sb.AppendLine(" "); + sb.AppendLine(string.Format(" {0}", bndstore.Name.ToCleanString())); + sb.AppendLine(string.Format(" ", FloatUtil.GetVector3XmlString(bndstore.Min))); + sb.AppendLine(string.Format(" ", FloatUtil.GetVector3XmlString(bndstore.Max))); + sb.AppendLine(string.Format(" ", bndstore.Layer)); + sb.AppendLine(" "); + } + } + sb.AppendLine(" "); + sb.AppendLine(""); + return sb.ToString(); + } + + public override string ToString() { if (FileEntry != null) @@ -213,7 +289,7 @@ namespace CodeWalker.GameFiles [TypeConverter(typeof(ExpandableObjectConverter))] public class CacheFileDate { - public MetaHash FileName { get; set; } + public MetaHash FileName { get; set; } //"resource_surrogate:/%s.rpf" public DateTime TimeStamp { get; set; } public uint FileID { get; set; } @@ -230,6 +306,11 @@ namespace CodeWalker.GameFiles { } //testing } + public string ToCacheFileString() + { + return FileName.Hash.ToString() + " " + TimeStamp.ToFileTimeUtc().ToString() + " " + FileID.ToString(); + } + public override string ToString() { return FileName.ToString() + ", " + TimeStamp.ToString() + ", " + FileID.ToString(); @@ -279,11 +360,11 @@ namespace CodeWalker.GameFiles public Quaternion Orientation { get; set; } public Vector3 BBMin { get; set; } public Vector3 BBMax { get; set; } - public float Unk11 { get; set; } + public uint Unk11 { get; set; } public uint Unk12 { get; set; } - public float Unk13 { get; set; } + public uint Unk13 { get; set; } public uint Unk14 { get; set; } - public float Unk15 { get; set; } + public uint Unk15 { get; set; } public uint Unk16 { get; set; } public uint Unk17 { get; set; } public uint Unk18 { get; set; } @@ -299,14 +380,131 @@ namespace CodeWalker.GameFiles Orientation = new Quaternion(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); BBMin = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); BBMax = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); - Unk11 = br.ReadSingle(); + Unk11 = br.ReadUInt32();//could be float Unk12 = br.ReadUInt32(); - Unk13 = br.ReadSingle(); + Unk13 = br.ReadUInt32();//could be float Unk14 = br.ReadUInt32(); - Unk15 = br.ReadSingle(); + Unk15 = br.ReadUInt32();//could be float Unk16 = br.ReadUInt32(); - Unk17 = br.ReadUInt32(); + Unk17 = br.ReadUInt32();//could be float Unk18 = br.ReadUInt32(); + + + + switch (Unk01) + { + case 0: //v_cashdepot + case 19: //dt1_02_carpark + case 20: //dt1_03_carpark + case 21: //dt1_05_carpark + case 4: //dt1_rd1_tun + case 14: //id1_11_tunnel1_int + case 24: //v_firedept + case 3: //id2_21_a_tun1 + case 22: //po1_08_warehouseint1 + case 11: //sc1_rd_inttun1 + case 10: //sc1_rd_inttun2b_end + case 18: //bt1_04_carpark + case 16: //v_hanger + case 1: //ap1_03_lisapark_subway + case 13: //kt1_03_carpark_int + case 5: //sm20_tun1 + case 2: //vbca_tunnel1 + case 15: //cs1_12_tunnel01_int + case 6: //cs1_14brailway1 + case 9: //cs2_roadsb_tunnel_01 + case 7: //cs3_03railtunnel_int1 + case 8: //cs4_rwayb_tunnelint + case 12: //ch1_roadsdint_tun1 + case 100: //hei_int_mph_carrierhang3 + case 47: //xm_x17dlc_int_base_ent + break; + default: + break; + } + + if (Unk02 != 0) + { } + + switch (Unk03) + { + case 6: //v_cashdepot + case 2: //dt1_02_carpark + case 8: //v_fib01 + case 4: //v_fib03 + case 0: //v_fib04 + case 7: //v_clotheslo + case 1: //v_gun + case 3: //v_genbank + case 11: //v_hospital + case 5: //v_shop_247 + case 32: //v_abattoir + case 13: //v_franklins + case 15: //v_michael + case 18: //v_faceoffice + case 29: //v_recycle + case 9: //v_stadium + case 54: //v_farmhouse + case 12: //v_ranch + case 26: //hei_gta_milo_bar + case 17: //hei_gta_milo_bedrm + case 14: //hei_gta_milo_bridge + case 48: //apa_mpapa_yacht + break; + default: + break; + } + + + if ((Unk12 == 0) || (Unk12 > 0xFFFFFF)) + { } + + switch (Unk14) + { + case 1: + case 0: + case 580: + case 355: //sm_smugdlc_int_01 + case 579: //xm_x17dlc_int_01 + break; + default: + break; + } + switch (Unk16) + { + case 1: + case 32758: //0x7FF6 + break; + default: + break; + } + switch (Unk17) //could be a float..! + { + case 9: + break; + case 0x415CBC04: //13.7959f + case 0x7B81AC94: + case 0x40FE3224: //7.94362f v_gun + case 0x41515774: //13.0839f v_gun + case 0x414E7B34: //12.9051f bkr_biker_dlc_int_03 + case 0x41389C14: //11.5381f imp_impexp_int_01 + case 0x4177B664: //15.482f gr_grdlc_int_01 + case 0xCE0404F4: // sm_smugdlc_int_01 + break; + default: + //string str = JenkIndex.GetString(Unk17); + break; + } + switch(Unk18) + { + case 0: + case 1: + case 32758: //0x7FF6 + break; + default: + break; + } + } public override string ToString() @@ -340,10 +538,10 @@ namespace CodeWalker.GameFiles public Vector3 streamingExtentsMax { get; set; } public Vector3 entitiesExtentsMin { get; set; } public Vector3 entitiesExtentsMax { get; set; } - public byte Unk02 { get; set; } - public byte Unk03 { get; set; } - public byte Unk04 { get; set; } - public byte Unk05 { get; set; } + public byte Unk1 { get; set; } + public byte Unk2 { get; set; } + public byte Unk3 { get; set; } + public byte Unk4 { get; set; } public MapDataStoreNodeExtra UnkExtra { get; set; } @@ -372,13 +570,23 @@ namespace CodeWalker.GameFiles streamingExtentsMax = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); entitiesExtentsMin = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); entitiesExtentsMax = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); - Unk02 = br.ReadByte(); - Unk03 = br.ReadByte(); - Unk04 = br.ReadByte(); - Unk05 = br.ReadByte(); + Unk1 = br.ReadByte(); //HD flag? (critical, long, strm) + Unk2 = br.ReadByte(); //lod flag? - primary map files + Unk3 = br.ReadByte(); //slod flag? + Unk4 = br.ReadByte(); - if (Unk05 == 0xFE) + if (Unk1 != 0) + { } + if (Unk2 != 0) + { } + if (Unk3 != 0) + { } + if (Unk4 != 0) + { } //no hits here now.. + + if (Unk4 == 0xFE) { + //this seems to never be hit anymore... UnkExtra = new MapDataStoreNodeExtra(br); } } @@ -417,6 +625,7 @@ namespace CodeWalker.GameFiles } } + public override string ToString() { return Name.ToString() + ", " + diff --git a/GameFiles/MetaTypes/Meta.cs b/GameFiles/MetaTypes/Meta.cs index 54cc321..43448e6 100644 --- a/GameFiles/MetaTypes/Meta.cs +++ b/GameFiles/MetaTypes/Meta.cs @@ -1012,6 +1012,11 @@ namespace CodeWalker.GameFiles return GlobalText.GetString(Hash); } + public string ToCleanString() + { + if (Hash == 0) return string.Empty; + return ToString(); + } public static implicit operator uint(MetaHash h) { diff --git a/Utils/Utils.cs b/Utils/Utils.cs index cfe41ec..2aed3c6 100644 --- a/Utils/Utils.cs +++ b/Utils/Utils.cs @@ -350,6 +350,21 @@ namespace CodeWalker var c = CultureInfo.InvariantCulture; return v.X.ToString(format, c) + ", " + v.Y.ToString(format, c) + ", " + v.Z.ToString(format, c); } + public static string GetVector3XmlString(Vector3 v) + { + var c = CultureInfo.InvariantCulture; + return string.Format("x=\"{0}\" y=\"{1}\" z=\"{2}\"", v.X.ToString(c), v.Y.ToString(c), v.Z.ToString(c)); + } + public static string GetVector4XmlString(Vector4 v) + { + var c = CultureInfo.InvariantCulture; + return string.Format("x=\"{0}\" y=\"{1}\" z=\"{2}\" w=\"{3}\"", v.X.ToString(c), v.Y.ToString(c), v.Z.ToString(c), v.W.ToString(c)); + } + public static string GetQuaternionXmlString(Quaternion q) + { + var c = CultureInfo.InvariantCulture; + return string.Format("x=\"{0}\" y=\"{1}\" z=\"{2}\" w=\"{3}\"", q.X.ToString(c), q.Y.ToString(c), q.Z.ToString(c), q.W.ToString(c)); + } public static Vector3 ParseVector3String(string s) {