mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2026-05-14 17:05:10 +08:00
HD textures (WIP), vehicles.meta gtxd loading
This commit is contained in:
@@ -15,7 +15,7 @@ namespace CodeWalker.GameFiles
|
||||
public RbfFile Rbf { get; set; }
|
||||
|
||||
|
||||
public Dictionary<string, string> CMapParentTxds { get; set; }
|
||||
public Dictionary<string, string> TxdRelationships { get; set; }
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace CodeWalker.GameFiles
|
||||
|
||||
if (rbfstruct.Name == "CMapParentTxds")
|
||||
{
|
||||
LoadMapParentTxds(rbfstruct);
|
||||
LoadTxdRelationships(rbfstruct);
|
||||
}
|
||||
|
||||
Loaded = true;
|
||||
@@ -68,7 +68,7 @@ namespace CodeWalker.GameFiles
|
||||
xml = xml.Remove(0, bom.Length);
|
||||
}
|
||||
|
||||
LoadMapParentTxds(xml);
|
||||
LoadTxdRelationships(xml);
|
||||
Loaded = true;
|
||||
}
|
||||
|
||||
@@ -76,10 +76,10 @@ namespace CodeWalker.GameFiles
|
||||
}
|
||||
|
||||
|
||||
private void LoadMapParentTxds(RbfStructure rbfstruct)
|
||||
private void LoadTxdRelationships(RbfStructure rbfstruct)
|
||||
{
|
||||
|
||||
CMapParentTxds = new Dictionary<string, string>();
|
||||
TxdRelationships = new Dictionary<string, string>();
|
||||
//StringBuilder sblist = new StringBuilder();
|
||||
foreach (var child in rbfstruct.Children)
|
||||
{
|
||||
@@ -118,9 +118,9 @@ namespace CodeWalker.GameFiles
|
||||
}
|
||||
if ((!string.IsNullOrEmpty(parentstr)) && (!string.IsNullOrEmpty(childstr)))
|
||||
{
|
||||
if (!CMapParentTxds.ContainsKey(childstr))
|
||||
if (!TxdRelationships.ContainsKey(childstr))
|
||||
{
|
||||
CMapParentTxds.Add(childstr, parentstr);
|
||||
TxdRelationships.Add(childstr, parentstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -140,13 +140,13 @@ namespace CodeWalker.GameFiles
|
||||
|
||||
|
||||
|
||||
private void LoadMapParentTxds(string xml)
|
||||
private void LoadTxdRelationships(string xml)
|
||||
{
|
||||
XmlDocument xmldoc = new XmlDocument();
|
||||
xmldoc.LoadXml(xml); //maybe better load xml.ToLower() and use "cmapparenttxds/txdrelationships/item" as xpath?
|
||||
XmlNodeList items = xmldoc.SelectNodes("CMapParentTxds/txdRelationships/Item | CMapParentTxds/txdRelationships/item");
|
||||
|
||||
CMapParentTxds = new Dictionary<string, string>();
|
||||
TxdRelationships = new Dictionary<string, string>();
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
string parentstr = Xml.GetChildInnerText(items[i], "parent");
|
||||
@@ -154,9 +154,9 @@ namespace CodeWalker.GameFiles
|
||||
|
||||
if ((!string.IsNullOrEmpty(parentstr)) && (!string.IsNullOrEmpty(childstr)))
|
||||
{
|
||||
if (!CMapParentTxds.ContainsKey(childstr))
|
||||
if (!TxdRelationships.ContainsKey(childstr))
|
||||
{
|
||||
CMapParentTxds.Add(childstr, parentstr);
|
||||
TxdRelationships.Add(childstr, parentstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace CodeWalker.GameFiles
|
||||
{
|
||||
public class VehiclesFile : GameFile, PackedFile
|
||||
{
|
||||
|
||||
public RbfFile Rbf { get; set; }
|
||||
|
||||
|
||||
public Dictionary<string, string> TxdRelationships { get; set; }
|
||||
|
||||
|
||||
|
||||
|
||||
public VehiclesFile() : base(null, GameFileType.Vehicles)
|
||||
{
|
||||
}
|
||||
public VehiclesFile(RpfFileEntry entry) : base(entry, GameFileType.Vehicles)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Load(byte[] data, RpfFileEntry entry)
|
||||
{
|
||||
RpfFileEntry = entry;
|
||||
Name = entry.Name;
|
||||
FilePath = Name;
|
||||
|
||||
|
||||
if (entry.NameLower.EndsWith(".meta"))
|
||||
{
|
||||
//required for update\x64\dlcpacks\mpheist\dlc.rpf\common\data\gtxd.meta and update\x64\dlcpacks\mpluxe\dlc.rpf\common\data\gtxd.meta
|
||||
string bom = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
|
||||
string xml = Encoding.UTF8.GetString(data);
|
||||
|
||||
if (xml.StartsWith(bom, StringComparison.Ordinal))
|
||||
{
|
||||
xml = xml.Remove(0, bom.Length);
|
||||
}
|
||||
|
||||
XmlDocument xmldoc = new XmlDocument();
|
||||
xmldoc.LoadXml(xml);
|
||||
|
||||
LoadVehicles(xmldoc);
|
||||
|
||||
LoadTxdRelationships(xmldoc);
|
||||
|
||||
Loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void LoadVehicles(XmlDocument xmldoc)
|
||||
{
|
||||
XmlNodeList items = xmldoc.SelectNodes("CVehicleModelInfo__InitDataList/InitDatas/Item | CVehicleModelInfo__InitDataList/InitDatas/item");
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
//TODO...
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadTxdRelationships(XmlDocument xmldoc)
|
||||
{
|
||||
XmlNodeList items = xmldoc.SelectNodes("CVehicleModelInfo__InitDataList/txdRelationships/Item | CVehicleModelInfo__InitDataList/txdRelationships/item");
|
||||
|
||||
TxdRelationships = new Dictionary<string, string>();
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
string parentstr = Xml.GetChildInnerText(items[i], "parent");
|
||||
string childstr = Xml.GetChildInnerText(items[i], "child");
|
||||
|
||||
if ((!string.IsNullOrEmpty(parentstr)) && (!string.IsNullOrEmpty(childstr)))
|
||||
{
|
||||
if (!TxdRelationships.ContainsKey(childstr))
|
||||
{
|
||||
TxdRelationships.Add(childstr, parentstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -70,6 +70,7 @@ namespace CodeWalker.GameFiles
|
||||
Ywr = 14,
|
||||
Yvr = 15,
|
||||
Gtxd = 16,
|
||||
Vehicles = 17,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ namespace CodeWalker.GameFiles
|
||||
private volatile bool archetypesLoaded = false;
|
||||
private Dictionary<uint, Archetype> archetypeDict = new Dictionary<uint, Archetype>();
|
||||
private Dictionary<uint, RpfFileEntry> textureLookup = new Dictionary<uint, RpfFileEntry>();
|
||||
private Dictionary<uint, uint> textureParents;
|
||||
private Dictionary<MetaHash, MetaHash> textureParents;
|
||||
private Dictionary<MetaHash, MetaHash> hdtexturelookup;
|
||||
|
||||
private object updateSyncRoot = new object();
|
||||
private object requestSyncRoot = new object();
|
||||
@@ -132,6 +133,7 @@ namespace CodeWalker.GameFiles
|
||||
mainCache.Clear();
|
||||
|
||||
textureLookup.Clear();
|
||||
|
||||
GameFile queueclear;
|
||||
while (requestQueue.TryPop(out queueclear))
|
||||
{ } //empty the old queue out...
|
||||
@@ -958,6 +960,7 @@ namespace CodeWalker.GameFiles
|
||||
private void InitManifestDicts()
|
||||
{
|
||||
AllManifests = new List<YmfFile>();
|
||||
hdtexturelookup = new Dictionary<MetaHash, MetaHash>();
|
||||
foreach (RpfFile file in ActiveMapRpfFiles.Values) //RpfMan.BaseRpfs)
|
||||
{
|
||||
if (file.AllEntries == null) continue;
|
||||
@@ -985,6 +988,19 @@ namespace CodeWalker.GameFiles
|
||||
{ }
|
||||
else
|
||||
{ }
|
||||
|
||||
|
||||
if (ymffile.HDTxdAssetBindings != null)
|
||||
{
|
||||
for (int i = 0; i < ymffile.HDTxdAssetBindings.Length; i++)
|
||||
{
|
||||
var b = ymffile.HDTxdAssetBindings[i];
|
||||
var targetasset = JenkHash.GenHash(b.targetAsset.ToString().ToLowerInvariant());
|
||||
var hdtxd = JenkHash.GenHash(b.HDTxd.ToString().ToLowerInvariant());
|
||||
hdtexturelookup[targetasset] = hdtxd;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -996,70 +1012,49 @@ namespace CodeWalker.GameFiles
|
||||
private void InitGtxds()
|
||||
{
|
||||
|
||||
Dictionary<uint, uint> parentTxds = new Dictionary<uint, uint>();
|
||||
var parentTxds = new Dictionary<MetaHash, MetaHash>();
|
||||
|
||||
IEnumerable<RpfFile> rpfs = PreloadedMode ? AllRpfs : (IEnumerable<RpfFile>)ActiveMapRpfFiles.Values;
|
||||
|
||||
foreach (RpfFile file in rpfs)
|
||||
var addTxdRelationships = new Action<Dictionary<string, string>>((from) =>
|
||||
{
|
||||
if (file.AllEntries == null) continue;
|
||||
foreach (RpfEntry entry in file.AllEntries)
|
||||
foreach (var kvp in from)
|
||||
{
|
||||
try
|
||||
uint chash = JenkHash.GenHash(kvp.Key.ToLowerInvariant());
|
||||
uint phash = JenkHash.GenHash(kvp.Value.ToLowerInvariant());
|
||||
if (!parentTxds.ContainsKey(chash))
|
||||
{
|
||||
if ((entry.NameLower == "gtxd.ymt") || (entry.NameLower == "gtxd.meta"))
|
||||
{
|
||||
GtxdFile ymt = RpfMan.GetFile<GtxdFile>(entry);
|
||||
if (ymt.CMapParentTxds != null)
|
||||
{
|
||||
foreach (var kvp in ymt.CMapParentTxds)
|
||||
{
|
||||
uint chash = JenkHash.GenHash(kvp.Key.ToLowerInvariant());
|
||||
uint phash = JenkHash.GenHash(kvp.Value.ToLowerInvariant());
|
||||
if (!parentTxds.ContainsKey(chash))
|
||||
{
|
||||
parentTxds.Add(chash, phash);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
parentTxds.Add(chash, phash);
|
||||
}
|
||||
catch (Exception ex)
|
||||
else
|
||||
{
|
||||
string errstr = entry.Path + "\n" + ex.ToString();
|
||||
ErrorLog(errstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (EnableDlc)
|
||||
var addRpfTxdRelationships = new Action<IEnumerable<RpfFile>>((from) =>
|
||||
{
|
||||
foreach (var dlcfile in DlcActiveRpfs)
|
||||
foreach (RpfFile file in from)
|
||||
{
|
||||
foreach (RpfEntry entry in dlcfile.AllEntries)
|
||||
if (file.AllEntries == null) continue;
|
||||
foreach (RpfEntry entry in file.AllEntries)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (entry.NameLower == "gtxd.meta")
|
||||
if ((entry.NameLower == "gtxd.ymt") || (entry.NameLower == "gtxd.meta"))
|
||||
{
|
||||
GtxdFile ymt = RpfMan.GetFile<GtxdFile>(entry);
|
||||
if (ymt.CMapParentTxds != null)
|
||||
if (ymt.TxdRelationships != null)
|
||||
{
|
||||
foreach (var kvp in ymt.CMapParentTxds)
|
||||
{
|
||||
uint chash = JenkHash.GenHash(kvp.Key.ToLowerInvariant());
|
||||
uint phash = JenkHash.GenHash(kvp.Value.ToLowerInvariant());
|
||||
if (!parentTxds.ContainsKey(chash))
|
||||
{
|
||||
parentTxds.Add(chash, phash);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
addTxdRelationships(ymt.TxdRelationships);
|
||||
}
|
||||
}
|
||||
else if (entry.NameLower == "vehicles.meta")
|
||||
{
|
||||
VehiclesFile vf = RpfMan.GetFile<VehiclesFile>(entry);
|
||||
if (vf.TxdRelationships != null)
|
||||
{
|
||||
addTxdRelationships(vf.TxdRelationships);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1070,6 +1065,16 @@ namespace CodeWalker.GameFiles
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
addRpfTxdRelationships(rpfs);
|
||||
|
||||
|
||||
if (EnableDlc)
|
||||
{
|
||||
addRpfTxdRelationships(DlcActiveRpfs);
|
||||
}
|
||||
|
||||
|
||||
@@ -1078,7 +1083,7 @@ namespace CodeWalker.GameFiles
|
||||
|
||||
|
||||
|
||||
//ensure global texture dicts:
|
||||
//ensure resident global texture dicts:
|
||||
YtdFile ytd1 = new YtdFile(GetYtdEntry(JenkHash.GenHash("mapdetail")));
|
||||
LoadFile(ytd1);
|
||||
AddTextureLookups(ytd1);
|
||||
@@ -1087,17 +1092,6 @@ namespace CodeWalker.GameFiles
|
||||
LoadFile(ytd2);
|
||||
AddTextureLookups(ytd2);
|
||||
|
||||
YtdFile ytd3 = new YtdFile(GetYtdEntry(JenkHash.GenHash("vehshare_worn")));
|
||||
LoadFile(ytd3);
|
||||
AddTextureLookups(ytd3);
|
||||
|
||||
YtdFile ytd4 = new YtdFile(GetYtdEntry(JenkHash.GenHash("vehshare_army")));
|
||||
LoadFile(ytd4);
|
||||
AddTextureLookups(ytd4);
|
||||
|
||||
YtdFile ytd5 = new YtdFile(GetYtdEntry(JenkHash.GenHash("vehshare_truck")));
|
||||
LoadFile(ytd5);
|
||||
AddTextureLookups(ytd5);
|
||||
|
||||
|
||||
}
|
||||
@@ -1435,7 +1429,7 @@ namespace CodeWalker.GameFiles
|
||||
{
|
||||
lock (updateSyncRoot)
|
||||
{
|
||||
lock (textureSyncRoot)
|
||||
//lock (textureSyncRoot)
|
||||
{
|
||||
SelectedDlc = dlc;
|
||||
EnableDlc = enable;
|
||||
@@ -1459,7 +1453,7 @@ namespace CodeWalker.GameFiles
|
||||
{
|
||||
lock (updateSyncRoot)
|
||||
{
|
||||
lock (textureSyncRoot)
|
||||
//lock (textureSyncRoot)
|
||||
{
|
||||
EnableMods = enable;
|
||||
RpfMan.EnableMods = enable;
|
||||
@@ -1901,7 +1895,7 @@ namespace CodeWalker.GameFiles
|
||||
break;
|
||||
case GameFileType.Ytd:
|
||||
req.Loaded = LoadFile(req as YtdFile);
|
||||
if (req.Loaded) AddTextureLookups(req as YtdFile);
|
||||
//if (req.Loaded) AddTextureLookups(req as YtdFile);
|
||||
break;
|
||||
case GameFileType.Ymap:
|
||||
YmapFile y = req as YmapFile;
|
||||
@@ -1983,7 +1977,7 @@ namespace CodeWalker.GameFiles
|
||||
}
|
||||
public YtdFile TryGetParentYtd(uint hash)
|
||||
{
|
||||
uint phash;
|
||||
MetaHash phash;
|
||||
if(textureParents.TryGetValue(hash, out phash))
|
||||
{
|
||||
return GetYtd(phash);
|
||||
@@ -1992,19 +1986,31 @@ namespace CodeWalker.GameFiles
|
||||
}
|
||||
public uint TryGetParentYtdHash(uint hash)
|
||||
{
|
||||
uint phash = 0;
|
||||
MetaHash phash = 0;
|
||||
textureParents.TryGetValue(hash, out phash);
|
||||
return phash;
|
||||
}
|
||||
public uint TryGetHDTextureHash(uint txdhash)
|
||||
{
|
||||
MetaHash hdhash = 0;
|
||||
if (hdtexturelookup?.TryGetValue(txdhash, out hdhash) ?? false)
|
||||
{
|
||||
return hdhash;
|
||||
}
|
||||
return txdhash;
|
||||
}
|
||||
|
||||
public Texture TryFindTextureInParent(uint texhash, uint txdhash)
|
||||
{
|
||||
Texture tex = null;
|
||||
|
||||
var ytd = TryGetParentYtd(txdhash);
|
||||
while ((ytd != null) && (ytd.Loaded) && (ytd.TextureDict != null) && (tex == null))
|
||||
while ((ytd != null) && (tex == null))
|
||||
{
|
||||
tex = ytd.TextureDict.Lookup(texhash);
|
||||
if (ytd.Loaded && (ytd.TextureDict != null))
|
||||
{
|
||||
tex = ytd.TextureDict.Lookup(texhash);
|
||||
}
|
||||
if (tex == null)
|
||||
{
|
||||
ytd = TryGetParentYtd(ytd.Key.Hash);
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace CodeWalker.GameFiles
|
||||
public ResourcePointerList64<Texture> Textures { get; set; }
|
||||
|
||||
public Dictionary<uint, Texture> Dict { get; set; }
|
||||
|
||||
public long MemoryUsage
|
||||
{
|
||||
get
|
||||
@@ -81,7 +82,7 @@ namespace CodeWalker.GameFiles
|
||||
dict[hash] = tex;
|
||||
}
|
||||
}
|
||||
Dict = new Dictionary<uint, Texture>(dict);
|
||||
Dict = dict;// new Dictionary<uint, Texture>(dict);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -108,21 +109,6 @@ namespace CodeWalker.GameFiles
|
||||
};
|
||||
}
|
||||
|
||||
public Dictionary<uint, Texture> GetDictionary()
|
||||
{
|
||||
Dictionary<uint, Texture> td = new Dictionary<uint, Texture>();
|
||||
if ((Textures != null) && (Textures.data_items != null))
|
||||
{
|
||||
var texs = Textures.data_items;
|
||||
var hashes = TextureNameHashes;
|
||||
for (int i = 0; (i < texs.Length) && (i < hashes.Length); i++)
|
||||
{
|
||||
td.Add(hashes[i], texs[i]);
|
||||
}
|
||||
}
|
||||
return td;
|
||||
}
|
||||
|
||||
public Texture Lookup(uint hash)
|
||||
{
|
||||
Texture tex = null;
|
||||
@@ -132,6 +118,21 @@ namespace CodeWalker.GameFiles
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
|
||||
//public Dictionary<uint, Texture> GetDictionary()
|
||||
//{
|
||||
// Dictionary<uint, Texture> td = new Dictionary<uint, Texture>();
|
||||
// if ((Textures != null) && (Textures.data_items != null))
|
||||
// {
|
||||
// var texs = Textures.data_items;
|
||||
// var hashes = TextureNameHashes;
|
||||
// for (int i = 0; (i < texs.Length) && (i < hashes.Length); i++)
|
||||
// {
|
||||
// td.Add(hashes[i], texs[i]);
|
||||
// }
|
||||
// }
|
||||
// return td;
|
||||
//}
|
||||
}
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))] public class TextureBase : ResourceSystemBlock
|
||||
|
||||
Reference in New Issue
Block a user