diff --git a/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs b/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs
index 6c211b4..66fa91a 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs
@@ -2,10 +2,12 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Xml;
namespace CodeWalker.GameFiles
{
@@ -202,12 +204,102 @@ namespace CodeWalker.GameFiles
}
-
- public void LoadXml(string xml)
+ public byte[] Save()
{
+ MemoryStream s = new MemoryStream();
+ DataWriter w = new DataWriter(s, Endianess.LittleEndian);
+
+ w.Write("[VERSION]\n" + Version + "\n");
+ while (w.Position < 100) w.Write((byte)0);
+
+ WriteString(w, "\n");
+ if (FileDates != null)
+ {
+ foreach (var d in FileDates)
+ {
+ WriteString(w, d.ToCacheFileString());
+ WriteString(w, "\n");
+ }
+ }
+ WriteString(w, "\n");
+ WriteString(w, "\nfwMapDataStore\n");
+ var modlen = (AllMapNodes?.Length ?? 0) * 64;
+ //if (AllMapNodes != null)
+ //{
+ // foreach (var n in AllMapNodes)
+ // {
+ // if (n.Unk4 == 0xFE)
+ // {
+ // modlen += 96;
+ // }
+ // }
+ //}
+ w.Write(modlen);
+ if (AllMapNodes != null)
+ {
+ foreach (var n in AllMapNodes)
+ {
+ n.Write(w);
+ }
+ }
+ WriteString(w, "\n");
+ WriteString(w, "\nCInteriorProxy\n");
+ w.Write((AllCInteriorProxies?.Length ?? 0) * 104);
+ if (AllCInteriorProxies != null)
+ {
+ foreach (var p in AllCInteriorProxies)
+ {
+ p.Write(w);
+ }
+ }
+ WriteString(w, "\n");
+ WriteString(w, "\nBoundsStore\n");
+ w.Write((AllBoundsStoreItems?.Length ?? 0) * 32);
+ if (AllBoundsStoreItems != null)
+ {
+ foreach (var b in AllBoundsStoreItems)
+ {
+ b.Write(w);
+ }
+ }
+ WriteString(w, "\n");
+
+
+ var buf = new byte[s.Length];
+ s.Position = 0;
+ s.Read(buf, 0, buf.Length);
+ return buf;
}
- public string GetXml()
+ private void WriteString(DataWriter w, string s)
+ {
+ for (int i = 0; i < s.Length; i++)
+ {
+ w.Write((byte)s[i]);
+ }
+ }
+
+
+ public void WriteXml(StringBuilder sb, int indent)
+ {
+ CacheDatXml.ValueTag(sb, indent, "Version", Version);
+ CacheDatXml.WriteItemArray(sb, FileDates, indent, "FileDates");
+ CacheDatXml.WriteItemArray(sb, AllMapNodes, indent, "MapDataStore");
+ CacheDatXml.WriteItemArray(sb, AllCInteriorProxies, indent, "InteriorProxies");
+ CacheDatXml.WriteItemArray(sb, AllBoundsStoreItems, indent, "BoundsStore");
+ }
+ public void ReadXml(XmlNode node)
+ {
+ Version = Xml.GetChildStringAttribute(node, "Version");
+ FileDates = XmlMeta.ReadItemArray(node, "FileDates");
+ AllMapNodes = XmlMeta.ReadItemArray(node, "MapDataStore");
+ AllCInteriorProxies = XmlMeta.ReadItemArray(node, "InteriorProxies");
+ AllBoundsStoreItems = XmlMeta.ReadItemArray(node, "BoundsStore");
+ }
+
+
+
+ public string GetXmlOLD()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(MetaXmlBase.XmlHeader);
@@ -252,8 +344,7 @@ namespace CodeWalker.GameFiles
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(string.Format(" ", intprox.Unk11, intprox.Unk12, intprox.Unk13, intprox.Unk14));
sb.AppendLine(" ");
}
}
@@ -287,12 +378,14 @@ namespace CodeWalker.GameFiles
}
}
- [TypeConverter(typeof(ExpandableObjectConverter))] public class CacheFileDate
+ [TypeConverter(typeof(ExpandableObjectConverter))] public class CacheFileDate : IMetaXmlItem
{
public MetaHash FileName { get; set; } //"resource_surrogate:/%s.rpf"
public DateTime TimeStamp { get; set; }
public uint FileID { get; set; }
+ public CacheFileDate()
+ { }
public CacheFileDate(string line)
{
string[] parts = line.Split(' ');
@@ -311,19 +404,34 @@ namespace CodeWalker.GameFiles
return FileName.Hash.ToString() + " " + TimeStamp.ToFileTimeUtc().ToString() + " " + FileID.ToString();
}
+ public void WriteXml(StringBuilder sb, int indent)
+ {
+ CacheDatXml.StringTag(sb, indent, "fileName", CacheDatXml.HashString(FileName));
+ CacheDatXml.ValueTag(sb, indent, "timeStamp", TimeStamp.ToFileTimeUtc().ToString());
+ CacheDatXml.ValueTag(sb, indent, "fileID", FileID.ToString());
+ }
+ public void ReadXml(XmlNode node)
+ {
+ FileName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "fileName"));
+ TimeStamp = DateTime.FromFileTimeUtc((long)Xml.GetChildULongAttribute(node, "timeStamp"));
+ FileID = Xml.GetChildUIntAttribute(node, "fileID");
+ }
+
public override string ToString()
{
return FileName.ToString() + ", " + TimeStamp.ToString() + ", " + FileID.ToString();
}
}
- [TypeConverter(typeof(ExpandableObjectConverter))] public class BoundsStoreItem
+ [TypeConverter(typeof(ExpandableObjectConverter))] public class BoundsStoreItem : IMetaXmlItem
{
public MetaHash Name { get; set; }
public Vector3 Min { get; set; }
public Vector3 Max { get; set; }
public uint Layer { get; set; }
+ public BoundsStoreItem()
+ { }
public BoundsStoreItem(Bounds b)
{
Name = 0;
@@ -339,6 +447,29 @@ namespace CodeWalker.GameFiles
Layer = br.ReadUInt32();
}
+ public void Write(DataWriter w)
+ {
+ w.Write(Name);
+ w.Write(Min);
+ w.Write(Max);
+ w.Write(Layer);
+ }
+
+ public void WriteXml(StringBuilder sb, int indent)
+ {
+ CacheDatXml.StringTag(sb, indent, "name", CacheDatXml.HashString(Name));
+ CacheDatXml.SelfClosingTag(sb, indent, "bbMin " + FloatUtil.GetVector3XmlString(Min));
+ CacheDatXml.SelfClosingTag(sb, indent, "bbMax " + FloatUtil.GetVector3XmlString(Max));
+ CacheDatXml.ValueTag(sb, indent, "layer", Layer.ToString());
+ }
+ public void ReadXml(XmlNode node)
+ {
+ Name = XmlMeta.GetHash(Xml.GetChildInnerText(node, "name"));
+ Min = Xml.GetChildVector3Attributes(node, "bbMin");
+ Max = Xml.GetChildVector3Attributes(node, "bbMax");
+ Layer = Xml.GetChildUIntAttribute(node, "layer");
+ }
+
public override string ToString()
{
return Name.ToString() + ", " +
@@ -346,10 +477,9 @@ namespace CodeWalker.GameFiles
Max.ToString() + ", " +
Layer.ToString();
}
-
}
- [TypeConverter(typeof(ExpandableObjectConverter))] public class CInteriorProxy
+ [TypeConverter(typeof(ExpandableObjectConverter))] public class CInteriorProxy : IMetaXmlItem
{
public uint Unk01 { get; set; }
public uint Unk02 { get; set; }
@@ -360,15 +490,13 @@ 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 Unk12 { get; set; }
- public float Unk13 { get; set; }
- public uint Unk14 { get; set; }
- public float Unk15 { get; set; }
- public uint Unk16 { get; set; }
- public uint Unk17 { get; set; }
- public uint Unk18 { get; set; }
+ public ulong Unk11 { get; set; }//possibly file offsets..?
+ public ulong Unk12 { get; set; }//possibly file offsets..?
+ public ulong Unk13 { get; set; }//possibly file offsets..?
+ public ulong Unk14 { get; set; }//possibly file offsets..?
+ public CInteriorProxy()
+ { }
public CInteriorProxy(BinaryReader br)
{
Unk01 = br.ReadUInt32();
@@ -380,15 +508,10 @@ 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();
- Unk12 = br.ReadUInt32();
- Unk13 = br.ReadSingle();
- Unk14 = br.ReadUInt32();
- Unk15 = br.ReadSingle();
- Unk16 = br.ReadUInt32();
- Unk17 = br.ReadUInt32();//could be float
- Unk18 = br.ReadUInt32();
-
+ Unk11 = br.ReadUInt64();
+ Unk12 = br.ReadUInt64();
+ Unk13 = br.ReadUInt64();
+ Unk14 = br.ReadUInt64(); //(unk14-unk13)=~ 5500000
switch (Unk01)
@@ -418,6 +541,8 @@ namespace CodeWalker.GameFiles
case 12: //ch1_roadsdint_tun1
case 100: //hei_int_mph_carrierhang3
case 47: //xm_x17dlc_int_base_ent
+ case 120:
+ case 119:
break;
default:
break;
@@ -450,56 +575,140 @@ namespace CodeWalker.GameFiles
case 17: //hei_gta_milo_bedrm
case 14: //hei_gta_milo_bridge
case 48: //apa_mpapa_yacht
+ case 43:
break;
default:
break;
}
-
- if ((Unk12 == 0) || (Unk12 > 0xFFFFFF))
- { }
-
+ switch (Unk11)
+ {
+ case 5390106048:
+ case 50578352072311817:
+ case 140699061757388:
+ case 738537932908210:
+ case 65651138218412653:
+ case 19678574933270533:
+ case 67944777457713148:
+ case 42661052301639680:
+ case 64551944402634707:
+ case 6851324394453320:
+ case 5376209604:
+ case 7160325822942775:
+ case 140695211737544:
+ case 5379565000:
+ case 12610731652297560:
+ case 0:
+ case 5836226042334228:
+ break;
+ default:
+ break;
+ }
+ switch (Unk12)
+ {
+ case 5394258664:
+ case 1788295895209:
+ case 2301144275160:
+ case 2301144295745:
+ case 2301144271926:
+ case 2293121037876:
+ case 2301144284982:
+ case 2301144280511:
+ case 2301144292239:
+ case 2301144276247:
+ case 2297948090320:
+ case 2301144281267:
+ case 2301144273909:
+ case 2301144274429:
+ case 2301144278131:
+ case 2301144276931:
+ case 2301144285912:
+ case 2301144279392:
+ case 2301144278900:
+ case 2301144280746:
+ case 2301144276750:
+ case 2301144279385:
+ case 794564824:
+ case 794585409:
+ case 3426812900:
+ case 3363906997:
+ case 2488666884898:
+ case 1551090123535:
+ case 3581544739:
+ case 2697016884:
+ case 2697019190:
+ case 2697014452:
+ case 2697013894:
+ case 2697026447:
+ case 2697010756:
+ case 2697012560:
+ case 2697010345:
+ case 2697015248:
+ case 2697009368:
+ case 2697014442:
+ case 2697008117:
+ case 2697008069:
+ case 2697018851:
+ case 2697012339:
+ case 2697010263:
+ case 2697019078:
+ case 2697013518:
+ case 2697013308:
+ case 2697013108:
+ case 2079647991056:
+ case 2333569996536:
+ case 3433367119:
+ case 2293344373240:
+ case 1527735255327:
+ case 1581974815172:
+ case 2067312412743:
+ case 2240565805648:
+ break;
+ default:
+ break;
+ }
+ switch (Unk13)
+ {
+ case 5416947112:
+ case 140699301996180:
+ case 140699066065044:
+ case 5381321844:
+ case 5385188756:
+ case 5385376164:
+ case 140696605328676:
+ case 140701349594068:
+ case 5387902360:
+ case 5380079992:
+ case 140695959352556:
+ case 140695215813968:
+ case 5383741744:
+ case 140697989613796:
+ case 140701810993260:
+ case 140701892506988:
+ case 140701188531008:
+ break;
+ default:
+ break;
+ }
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
+ case 140699307584676:
+ case 140699071655044:
+ case 5386712196:
+ case 5390629684:
+ case 5390817140:
+ case 140696610778260:
+ case 140701355067892:
+ case 5393331812:
+ case 5385368100:
+ case 140695964849172:
+ case 140695221335892:
+ case 5389196308:
+ case 140697995052276:
+ case 140701816510228:
+ case 140701898076100:
+ case 140701194017116:
break;
default:
break;
@@ -507,6 +716,57 @@ namespace CodeWalker.GameFiles
}
+ public void Write(DataWriter w)
+ {
+ w.Write(Unk01);
+ w.Write(Unk02);
+ w.Write(Unk03);
+ w.Write(Name);
+ w.Write(Parent);
+ w.Write(Position);
+ w.Write(Orientation.ToVector4());
+ w.Write(BBMin);
+ w.Write(BBMax);
+ w.Write(Unk11);
+ w.Write(Unk12);
+ w.Write(Unk13);
+ w.Write(Unk14);
+ }
+
+ public void WriteXml(StringBuilder sb, int indent)
+ {
+ CacheDatXml.StringTag(sb, indent, "name", CacheDatXml.HashString(Name));
+ CacheDatXml.StringTag(sb, indent, "parent", CacheDatXml.HashString(Parent));
+ CacheDatXml.SelfClosingTag(sb, indent, "position " + FloatUtil.GetVector3XmlString(Position));
+ CacheDatXml.SelfClosingTag(sb, indent, "rotation " + FloatUtil.GetVector4XmlString(Orientation.ToVector4()));
+ CacheDatXml.SelfClosingTag(sb, indent, "bbMin " + FloatUtil.GetVector3XmlString(BBMin));
+ CacheDatXml.SelfClosingTag(sb, indent, "bbMax " + FloatUtil.GetVector3XmlString(BBMax));
+ CacheDatXml.ValueTag(sb, indent, "unk01", Unk01.ToString());
+ CacheDatXml.ValueTag(sb, indent, "unk02", Unk02.ToString());
+ CacheDatXml.ValueTag(sb, indent, "unk03", Unk03.ToString());
+ CacheDatXml.ValueTag(sb, indent, "unk11", Unk11.ToString());
+ CacheDatXml.ValueTag(sb, indent, "unk12", Unk12.ToString());
+ CacheDatXml.ValueTag(sb, indent, "unk13", Unk13.ToString());
+ CacheDatXml.ValueTag(sb, indent, "unk14", Unk14.ToString());
+ }
+ public void ReadXml(XmlNode node)
+ {
+ Name = XmlMeta.GetHash(Xml.GetChildInnerText(node, "name"));
+ Parent = XmlMeta.GetHash(Xml.GetChildInnerText(node, "parent"));
+ Position = Xml.GetChildVector3Attributes(node, "position");
+ Orientation = Xml.GetChildVector4Attributes(node, "rotation").ToQuaternion();
+ BBMin = Xml.GetChildVector3Attributes(node, "bbMin");
+ BBMax = Xml.GetChildVector3Attributes(node, "bbMax");
+ Unk01 = Xml.GetChildUIntAttribute(node, "unk01");
+ Unk02 = Xml.GetChildUIntAttribute(node, "unk02");
+ Unk03 = Xml.GetChildUIntAttribute(node, "unk03");
+ Unk11 = Xml.GetChildULongAttribute(node, "unk11");
+ Unk12 = Xml.GetChildULongAttribute(node, "unk12");
+ Unk13 = Xml.GetChildULongAttribute(node, "unk13");
+ Unk14 = Xml.GetChildULongAttribute(node, "unk14");
+ }
+
+
public override string ToString()
{
return Unk01.ToString() + ", " +
@@ -521,15 +781,11 @@ namespace CodeWalker.GameFiles
Unk11.ToString() + ", " +
Unk12.ToString() + ", " +
Unk13.ToString() + ", " +
- Unk14.ToString() + ", " +
- Unk15.ToString() + ", " +
- Unk16.ToString() + ", " +
- Unk17.ToString() + ", " +
- Unk18.ToString();
+ Unk14.ToString();
}
}
- [TypeConverter(typeof(ExpandableObjectConverter))] public class MapDataStoreNode
+ [TypeConverter(typeof(ExpandableObjectConverter))] public class MapDataStoreNode : IMetaXmlItem
{
public MetaHash Name { get; set; }
public MetaHash ParentName { get; set; }
@@ -551,6 +807,8 @@ namespace CodeWalker.GameFiles
public CInteriorProxy[] InteriorProxies { get; set; }
private List InteriorProxyList;
+ public MapDataStoreNode()
+ { }
public MapDataStoreNode(YmapFile ymap)
{
Name = ymap._CMapData.name;
@@ -584,11 +842,65 @@ namespace CodeWalker.GameFiles
if (Unk4 != 0)
{ } //no hits here now..
- if (Unk4 == 0xFE)
- {
- //this seems to never be hit anymore...
- UnkExtra = new MapDataStoreNodeExtra(br);
- }
+ //if (Unk4 == 0xFE)
+ //{
+ // //this seems to never be hit anymore...
+ // UnkExtra = new MapDataStoreNodeExtra(br);
+ //}
+ }
+
+ public void Write(DataWriter w)
+ {
+ w.Write(Name);
+ w.Write(ParentName);
+ w.Write(ContentFlags);
+ w.Write(streamingExtentsMin);
+ w.Write(streamingExtentsMax);
+ w.Write(entitiesExtentsMin);
+ w.Write(entitiesExtentsMax);
+ w.Write(Unk1);
+ w.Write(Unk2);
+ w.Write(Unk3);
+ w.Write(Unk4);
+
+ //if (Unk4 == 0xFE)
+ //{
+ // if (UnkExtra == null)
+ // {
+ // UnkExtra = new MapDataStoreNodeExtra();
+ // }
+ // UnkExtra.Write(w);
+ //}
+ }
+
+
+ public void WriteXml(StringBuilder sb, int indent)
+ {
+ CacheDatXml.StringTag(sb, indent, "name", CacheDatXml.HashString(Name));
+ CacheDatXml.StringTag(sb, indent, "parent", CacheDatXml.HashString(ParentName));
+ CacheDatXml.ValueTag(sb, indent, "contentFlags", ContentFlags.ToString());
+ CacheDatXml.SelfClosingTag(sb, indent, "streamingExtentsMin " + FloatUtil.GetVector3XmlString(streamingExtentsMin));
+ CacheDatXml.SelfClosingTag(sb, indent, "streamingExtentsMax " + FloatUtil.GetVector3XmlString(streamingExtentsMax));
+ CacheDatXml.SelfClosingTag(sb, indent, "entitiesExtentsMin " + FloatUtil.GetVector3XmlString(entitiesExtentsMin));
+ CacheDatXml.SelfClosingTag(sb, indent, "entitiesExtentsMax " + FloatUtil.GetVector3XmlString(entitiesExtentsMax));
+ CacheDatXml.ValueTag(sb, indent, "unk1", Unk1.ToString());
+ CacheDatXml.ValueTag(sb, indent, "unk2", Unk2.ToString());
+ CacheDatXml.ValueTag(sb, indent, "unk3", Unk3.ToString());
+ CacheDatXml.ValueTag(sb, indent, "unk4", Unk4.ToString());
+ }
+ public void ReadXml(XmlNode node)
+ {
+ Name = XmlMeta.GetHash(Xml.GetChildInnerText(node, "name"));
+ ParentName = XmlMeta.GetHash(Xml.GetChildInnerText(node, "parent"));
+ ContentFlags = Xml.GetChildUIntAttribute(node, "contentFlags");
+ streamingExtentsMin = Xml.GetChildVector3Attributes(node, "streamingExtentsMin");
+ streamingExtentsMax = Xml.GetChildVector3Attributes(node, "streamingExtentsMax");
+ entitiesExtentsMin = Xml.GetChildVector3Attributes(node, "entitiesExtentsMin");
+ entitiesExtentsMax = Xml.GetChildVector3Attributes(node, "entitiesExtentsMax");
+ Unk1 = (byte)Xml.GetChildUIntAttribute(node, "unk1");
+ Unk2 = (byte)Xml.GetChildUIntAttribute(node, "unk2");
+ Unk3 = (byte)Xml.GetChildUIntAttribute(node, "unk3");
+ Unk4 = (byte)Xml.GetChildUIntAttribute(node, "unk4");
}
@@ -667,6 +979,8 @@ namespace CodeWalker.GameFiles
}
}
+ public MapDataStoreNodeExtra()
+ { }
public MapDataStoreNodeExtra(BinaryReader br)
{
Unk01 = br.ReadUInt32();
@@ -687,6 +1001,23 @@ namespace CodeWalker.GameFiles
}
+ public void Write(DataWriter w)
+ {
+ w.Write(Unk01);
+ var alen = Unk02?.Length ?? 0;
+ for (int i = 0; i < 60; i++)
+ {
+ w.Write((i < alen) ? Unk02[i] : (byte)0);
+ }
+ w.Write(Unk03);
+ w.Write(Unk04);
+ w.Write(Unk05);
+ w.Write(Unk06);
+ w.Write(Unk07);
+ w.Write(Unk08);
+ w.Write(Unk09);
+ w.Write(Unk10);
+ }
public override string ToString()
{
@@ -696,4 +1027,50 @@ namespace CodeWalker.GameFiles
+ public class CacheDatXml : MetaXmlBase
+ {
+
+ public static string GetXml(CacheDatFile cdf)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine(XmlHeader);
+
+ if (cdf != null)
+ {
+ var name = "CacheFile";
+
+ OpenTag(sb, 0, name);
+
+ cdf.WriteXml(sb, 1);
+
+ CloseTag(sb, 0, name);
+ }
+
+ return sb.ToString();
+ }
+
+
+ }
+
+
+ public class XmlCacheDat
+ {
+
+ public static CacheDatFile GetCacheDat(string xml)
+ {
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(xml);
+ return GetCacheDat(doc);
+ }
+
+ public static CacheDatFile GetCacheDat(XmlDocument doc)
+ {
+ CacheDatFile cdf = new CacheDatFile();
+ cdf.ReadXml(doc.DocumentElement);
+ return cdf;
+ }
+
+
+ }
+
}
diff --git a/CodeWalker.Core/GameFiles/GameFileCache.cs b/CodeWalker.Core/GameFiles/GameFileCache.cs
index 1d33e4c..75132b3 100644
--- a/CodeWalker.Core/GameFiles/GameFileCache.cs
+++ b/CodeWalker.Core/GameFiles/GameFileCache.cs
@@ -219,6 +219,7 @@ namespace CodeWalker.GameFiles
//TestMrfs();
//TestPlacements();
//TestDrawables();
+ //TestCacheFiles();
//TestHeightmaps();
//TestWatermaps();
//GetShadersXml();
@@ -4954,6 +4955,49 @@ namespace CodeWalker.GameFiles
UpdateStatus((DateTime.Now - starttime).ToString() + " elapsed, " + drawablecount.ToString() + " drawables, " + errs.Count.ToString() + " errors.");
}
+ public void TestCacheFiles()
+ {
+ foreach (RpfFile file in AllRpfs)
+ {
+ foreach (RpfEntry entry in file.AllEntries)
+ {
+ try
+ {
+ if (entry.NameLower.EndsWith("cache_y.dat"))// || entry.NameLower.EndsWith("cache_y_bank.dat"))
+ {
+ UpdateStatus(string.Format(entry.Path));
+ var cdfile = RpfMan.GetFile(entry);
+ if (cdfile != null)
+ {
+ var odata = entry.File.ExtractFile(entry as RpfFileEntry);
+ //var ndata = cdfile.Save();
+
+ var xml = CacheDatXml.GetXml(cdfile);
+ var cdf2 = XmlCacheDat.GetCacheDat(xml);
+ var ndata = cdf2.Save();
+
+ if (ndata.Length == odata.Length)
+ {
+ for (int i = 0; i < ndata.Length; i++)
+ {
+ if (ndata[i] != odata[i])
+ { break; }
+ }
+ }
+ else
+ { }
+ }
+ else
+ { }
+ }
+ }
+ catch (Exception ex)
+ {
+ UpdateStatus("Error! " + ex.ToString());
+ }
+ }
+ }
+ }
public void TestHeightmaps()
{
var errorfiles = new List();
diff --git a/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs b/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs
index a2ee470..47926c2 100644
--- a/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs
+++ b/CodeWalker.Core/GameFiles/MetaTypes/MetaXml.cs
@@ -284,7 +284,7 @@ namespace CodeWalker.GameFiles
{
var fn = (cdf?.FileEntry?.Name) ?? "";
filename = fn + ".xml";
- return cdf.GetXml();
+ return CacheDatXml.GetXml(cdf);
}
public static string GetXml(HeightmapFile hmf, out string filename, string outputfolder)
{
diff --git a/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs b/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs
index 8a86b80..ae4cfd4 100644
--- a/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs
+++ b/CodeWalker.Core/GameFiles/MetaTypes/XmlMeta.cs
@@ -168,7 +168,9 @@ namespace CodeWalker.GameFiles
}
public static byte[] GetCacheFileData(XmlDocument doc)
{
- return null; //TODO!!!
+ var cdf = XmlCacheDat.GetCacheDat(doc);
+ if (cdf == null) return null;
+ return cdf.Save();
}
public static byte[] GetHeightmapData(XmlDocument doc)
{
diff --git a/CodeWalker.Core/Utils/Xml.cs b/CodeWalker.Core/Utils/Xml.cs
index ca0dbc0..556e81a 100644
--- a/CodeWalker.Core/Utils/Xml.cs
+++ b/CodeWalker.Core/Utils/Xml.cs
@@ -144,6 +144,22 @@ namespace CodeWalker
}
return i;
}
+ public static ulong GetChildULongAttribute(XmlNode node, string name, string attribute = "value")
+ {
+ if (node == null) return 0;
+ string val = node.SelectSingleNode(name)?.Attributes[attribute]?.InnerText;
+ ulong i;
+ if (val?.StartsWith("0x") ?? false)
+ {
+ var subs = val.Substring(2);
+ i = Convert.ToUInt64(subs, 16);
+ }
+ else
+ {
+ ulong.TryParse(val, out i);
+ }
+ return i;
+ }
public static float GetChildFloatAttribute(XmlNode node, string name, string attribute = "value")
{
if (node == null) return 0;
diff --git a/CodeWalker/Forms/MetaForm.cs b/CodeWalker/Forms/MetaForm.cs
index 59e2b2a..2f6a059 100644
--- a/CodeWalker/Forms/MetaForm.cs
+++ b/CodeWalker/Forms/MetaForm.cs
@@ -349,7 +349,7 @@ namespace CodeWalker.Forms
public void LoadMeta(CacheDatFile cachedat)
{
var fn = ((cachedat?.FileEntry?.Name) ?? "") + ".xml";
- Xml = cachedat.GetXml();
+ Xml = MetaXml.GetXml(cachedat, out fn, "");
FileName = fn;
RawPropertyGrid.SelectedObject = cachedat;
rpfFileEntry = cachedat?.FileEntry;