// Reads bnd private IBinder ReadBnd(string path) { try { if (BND3.Is(path)) { return(BND3.Read(path)); } else if (BND4.Is(path)) { return(BND4.Read(path)); } else if (Spec.Game == FromGame.DS3 && path.EndsWith("Data0.bdt")) { return(SFUtil.DecryptDS3Regulation(path)); } else { throw new Exception($"Unrecognized bnd format for game {Spec.Game}: {path}"); } } catch (Exception ex) { throw new Exception($"Failed to load {path}: {ex}"); } }
public static void ReloadFMGs() { if (AssetLocator.Type == GameType.Undefined) { return; } if (AssetLocator.Type == GameType.DarkSoulsIISOTFS) { ReloadFMGsDS2(); IsLoaded = true; return; } IBinder fmgBinder; var desc = AssetLocator.GetEnglishItemMsgbnd(); if (AssetLocator.Type == GameType.DemonsSouls || AssetLocator.Type == GameType.DarkSoulsPTDE || AssetLocator.Type == GameType.DarkSoulsRemastered) { fmgBinder = BND3.Read(desc.AssetPath); } else { fmgBinder = BND4.Read(desc.AssetPath); } _fmgs = new Dictionary <ItemFMGTypes, FMG>(); foreach (var file in fmgBinder.Files) { _fmgs.Add((ItemFMGTypes)file.ID, FMG.Read(file.Bytes)); } IsLoaded = true; }
public TextHandler(byte[] itemMSGBNDData, byte[] menuMSGBNDData) { Item = BND3.Read(itemMSGBNDData); Menu = BND3.Read(menuMSGBNDData); NPCNames = new FMGHandler(this, Item, "NPC_name_"); EventText = new FMGHandler(this, Menu, "Event_text_"); WeaponNames = new FMGHandler(this, Item, "Weapon_name_"); WeaponSummaries = new FMGHandler(this, Item, "Weapon_description_"); WeaponDescriptions = new FMGHandler(this, Item, "Weapon_long_desc_"); ArmorNames = new FMGHandler(this, Item, "Armor_name_"); ArmorDescriptions = new FMGHandler(this, Item, "Armor_description_"); ArmorLongDescriptions = new FMGHandler(this, Item, "Armor_long_desc_"); GoodsNames = new FMGHandler(this, Item, "Item_name_"); GoodsDescriptions = new FMGHandler(this, Item, "Item_description_"); GoodsLongDescriptions = new FMGHandler(this, Item, "Item_long_desc_"); AccessoryNames = new FMGHandler(this, Item, "Accessory_name_"); AccessoryDescriptions = new FMGHandler(this, Item, "Accessory_description_"); AccessoryLongDescriptions = new FMGHandler(this, Item, "Accessory_long_desc_"); MagicNames = new FMGHandler(this, Item, "Magic_name_"); MagicDescriptions = new FMGHandler(this, Item, "Magic_description_"); MagicLongDescriptions = new FMGHandler(this, Item, "Magic_long_desc_"); MenuOther = new FMGHandler(this, Menu, "Menu_others_"); Conversations = new FMGHandler(this, Menu, "Conversation_"); }
public static Model LoadObject(string id) { Model obj = null; LoadingTaskMan.DoLoadingTaskSynchronous($"LOAD_OBJ_{id}", $"Loading object {id}...", progress => { if (GameType == GameTypes.DS3) { var chrbnd = BND4.Read($@"{InterrootPath}\obj\{id}.objbnd.dcx"); obj = new Model(progress, id, chrbnd, 0, null, null); } else if (GameType == GameTypes.DS1) { var chrbnd = BND3.Read($@"{InterrootPath}\obj\{id}.objbnd"); obj = new Model(progress, id, chrbnd, 0, null, null); } else if (GameType == GameTypes.DS1R) { var chrbnd = BND4.Read($@"{InterrootPath}\obj\{id}.objbnd.dcx"); obj = new Model(progress, id, chrbnd, 0, null, null); } else if (GameType == GameTypes.BB) { var chrbnd = BND4.Read($@"{InterrootPath}\obj\{id}.objbnd.dcx"); obj = new Model(progress, id, chrbnd, 0, null, null); } Scene.AddModel(obj); var texturesToLoad = obj.MainMesh.GetAllTexNamesToLoad(); LoadingTaskMan.DoLoadingTask($"LOAD_OBJ_{id}_TEX", "Loading additional object textures...", innerProgress => { if (GameType == GameTypes.DS1) { foreach (var tex in texturesToLoad) { TexturePool.AddTpfFromPath($@"{InterrootPath}\map\tx\{tex}.tpf"); } } else if (GameType == GameTypes.DS3) { int objGroup = int.Parse(id.Substring(1)) / 1_0000; var tpfBnds = System.IO.Directory.GetFiles($@"{InterrootPath}\map\m{objGroup:D2}", "*.tpfbhd"); foreach (var t in tpfBnds) { TexturePool.AddSpecificTexturesFromBinder(t, texturesToLoad, directEntryNameMatch: true); } } obj.MainMesh.TextureReloadQueued = true; }); }); return(obj); }
private static void SaveParamsDS1() { var dir = AssetLocator.GameRootDirectory; var mod = AssetLocator.GameModDirectory; if (!File.Exists($@"{dir}\\param\GameParam\GameParam.parambnd")) { MessageBox.Show("Could not find DS1 param file. Cannot save.", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Load params var param = $@"{mod}\param\GameParam\GameParam.parambnd"; if (!File.Exists(param)) { param = $@"{dir}\param\GameParam\GameParam.parambnd"; } BND3 paramBnd = BND3.Read(param); // Replace params with edited ones foreach (var p in paramBnd.Files) { if (_params.ContainsKey(Path.GetFileNameWithoutExtension(p.Name))) { p.Bytes = _params[Path.GetFileNameWithoutExtension(p.Name)].Write(); } } // Don't write to mod dir for now Utils.WriteWithBackup(dir, null, @"param\GameParam\GameParam.parambnd", paramBnd); }
public void LoadArmorPartsbnd(string partsbndPath, EquipSlot slot) { if (System.IO.File.Exists(partsbndPath)) { if (BND3.Is(partsbndPath)) { LoadArmorPartsbnd(BND3.Read(partsbndPath), slot); } else { LoadArmorPartsbnd(BND4.Read(partsbndPath), slot); } } else { if (slot == EquipSlot.Head) { HeadMesh?.Dispose(); } else if (slot == EquipSlot.Body) { BodyMesh?.Dispose(); } else if (slot == EquipSlot.Arms) { ArmsMesh?.Dispose(); } else if (slot == EquipSlot.Legs) { LegsMesh?.Dispose(); } } }
public static void LoadParams(SQLiteConnection con, string paramdefFilepath, IList <string> paramDirs) { // The metadata tables should be created ahead of time. CreateBndMetadataTables(con); CreateBndTableOfContentsTable(con); CreateParamMetadataTables(con); // Reading an original paramdefbnd var paramdefs = new Dictionary <string, PARAMDEF>(); var paramdefbnd = BND3.Read(paramdefFilepath); foreach (BinderFile file in paramdefbnd.Files) { var paramdef = PARAMDEF.Read(file.Bytes); paramdefs[paramdef.ParamType] = paramdef; } ReadParamdefsIntoDatabase(con, paramdefs.Values.ToList()); // Loading parambnd List <string> paramFilepaths = new List <string>(); foreach (var paramDir in paramDirs) { // DeS has both a gameparam.parambnd.dcx and a gameparamna.parambnd.dcx. // Only grab gameparamna.parambnd.dcx if we have it. string filterPattern = "*.parambnd.dcx"; if (Directory.GetFiles(paramDir, "*gameparamna.parambnd.dcx").Length > 0) { Console.WriteLine("Skipping gameparam.parambnd.dcx"); filterPattern = "*gameparamna.parambnd.dcx"; } paramFilepaths.AddRange(Directory.GetFiles(paramDir, filterPattern)); } foreach (var paramFilepath in paramFilepaths) { // Have to construct Table of Contents as we go through, since the info isn't all at BND level, but is needed when reconstructing var bndContents = new List <BndContentsEntry>(); Console.WriteLine("Loading file: " + paramFilepath); var parambnd = BND3.Read(paramFilepath); foreach (BinderFile file in parambnd.Files) { PARAM param = PARAM.Read(file.Bytes); // DSR doesn't seem to like applying carefully, specifically SP_EFFECT_PARAM_ST in Gameparam. At minimum. param.ApplyParamdef(paramdefs[param.ParamType]); var entry = new BndContentsEntry(paramFilepath, file.ID, file.Name, file.Flags, file.CompressionType, param.ParamType); bndContents.Add(entry); ReadParamIntoDatabase(con, Path.GetFileNameWithoutExtension(file.Name), param); } // Create the metadata tables ReadBndMetadataIntoDatabase(con, paramFilepath, parambnd); ReadBndTableOfContentsIntoDatabase(con, Path.GetFileName(paramFilepath), bndContents); } }
public static void WriteFile <TFormat>(TFormat file, string path, bool makeBackup = true) where TFormat : SoulsFile <TFormat>, new() { if (path.Contains("|")) { var splitPath = path.Split('|'); if (splitPath.Length != 2) { throw new Exception("Invalid internal BND path format. Expected 'C:\\Path\\To\\BND|Internal_File_Name.Extension'."); } var bndPath = splitPath[0]; var internalPath = splitPath[1]; if (BND3.Is(bndPath)) { var bnd3 = BND3.Read(bndPath); var internalFile = bnd3.Files.LastOrDefault(f => GetFileNameWithoutDirectoryOrExtension(f.Name) == internalPath); if (internalFile == null) { throw new Exception($"Internal BND file path '{internalPath}' not found in BND '{bndPath}'."); } internalFile.Bytes = file.Write(); if (makeBackup) { BackupFile(bndPath); } bnd3.Write(bndPath); } else if (BND4.Is(bndPath)) { var bnd4 = BND4.Read(bndPath); var internalFile = bnd4.Files.LastOrDefault(f => GetFileNameWithoutDirectoryOrExtension(f.Name) == internalPath); if (internalFile == null) { throw new Exception($"Internal BND file path '{internalPath}' not found in BND '{bndPath}'."); } internalFile.Bytes = file.Write(); if (makeBackup) { BackupFile(bndPath); } bnd4.Write(bndPath); } else { throw new Exception("Internal BND path specified but file is not a BND file!"); } } else { if (makeBackup) { BackupFile(path); } file.Write(path); } }
private static void PatchBND(string sourceLangDir, string refLangDir, string[] destFilePath) { foreach (var file in destFilePath)//Patch each file in files Array { if (BND3.IsRead(file, out BND3 destBND3)) { //Set source BND files string sourceLangFiles = $@"{ sourceLangDir }\{ Path.GetFileName(file) }"; BND3 sourceBND = BND3.Read(sourceLangFiles); string refLangFiles = $@"{refLangDir}\{Path.GetFileName(file)}"; //Make null ref BND, and make an actual BND read if it exists BND3 refBND = null; if (File.Exists(refLangFiles)) { refBND = BND3.Read(refLangFiles); } #region Debug Stuff //ConsoleLog(sourceBND.Files.Count); //Debug.WriteLine(Path.GetFileName(sourceBND.Files[0].Name)); //ConsoleLog(destFMG.Entries.Count + " & " + sourceFMG.Entries.Count); #endregion //Patch BND file PatchFMG(sourceBND, destBND3, refBND, file); //Write new BND destBND3.Write(file); } else if (BND4.IsRead(file, out BND4 destBND4)) { //Set source BND files string sourceLangFiles = $@"{sourceLangDir}\{Path.GetFileName(file)}"; BND4 sourceBND = BND4.Read(sourceLangFiles); string refLangFiles = $@"{refLangDir}\{Path.GetFileName(file)}"; //Make null ref BND, and make an actual BND read if it exists BND4 refBND = null; if (File.Exists(refLangFiles)) { refBND = BND4.Read(refLangFiles); } #region Debug Stuff //ConsoleLog(sourceBND.Files.Count); //Debug.WriteLine(Path.GetFileName(sourceBND.Files[0].Name)); //ConsoleLog(destFMG.Entries.Count + " & " + sourceFMG.Entries.Count); #endregion //Patch BND file PatchFMG(sourceBND, destBND4, refBND, file); //Write new BND destBND4.Write(file); } } }
static IBinder ReadIBinder(string name) { if (BND4.Is(name)) { return(BND4.Read(name)); } else { return(BND3.Read(name)); } }
public FMGHandler(TextHandler th, BND3 bnd, string name) { IEnumerable <BinderFile> list = bnd.Files.Where(f => Path.GetFileNameWithoutExtension(f.Name) == name); FileProper = list.ElementAt(0); Proper = FMG.Read(FileProper.Bytes); if (list.Count() > 1) { FilePatch = list.ElementAtOrDefault(1); Patch = FMG.Read(FilePatch.Bytes); } }
public void LoadFromPath(string file) { ReloadType = TaeFileContainerReloadType.None; containerBND3 = null; containerBND4 = null; taeInBND.Clear(); hkxInBND.Clear(); if (BND3.Is(file)) { ContainerType = TaeFileContainerType.BND3; containerBND3 = BND3.Read(file); foreach (var f in containerBND3.Files) { if (TAE.Is(f.Bytes)) { taeInBND.Add(f.Name, TAE.Read(f.Bytes)); } else if (f.Name.ToUpper().EndsWith(".HKX")) { hkxInBND.Add(f.Name, f.Bytes); } } } else if (BND4.Is(file)) { ContainerType = TaeFileContainerType.BND4; containerBND4 = BND4.Read(file); foreach (var f in containerBND4.Files) { if (TAE.Is(f.Bytes)) { taeInBND.Add(f.Name, TAE.Read(f.Bytes)); } else if (f.Name.ToUpper().EndsWith(".HKX")) { hkxInBND.Add(f.Name, f.Bytes); } } } else if (TAE.Is(file)) { ContainerType = TaeFileContainerType.TAE; taeInBND.Add(file, TAE.Read(file)); } filePath = file; //SFTODO ReloadType = TaeFileContainerReloadType.None; }
public static void AddSpecificTexturesFromBinder(string name, List <string> textures, bool directEntryNameMatch = false) { if (!File.Exists(name)) { return; } IBinder bnd = null; if (BXF4.IsBHD(name)) { bnd = BXF4.Read(name, name.Substring(0, name.Length - 7) + ".tpfbdt"); } else if (BXF4.IsBDT(name)) { bnd = BXF4.Read(name.Substring(0, name.Length - 7) + ".tpfbhd", name); } else if (BXF3.IsBHD(name)) { bnd = BXF3.Read(name, name.Substring(0, name.Length - 7) + ".tpfbdt"); } else if (BXF3.IsBDT(name)) { bnd = BXF3.Read(name.Substring(0, name.Length - 7) + ".tpfbhd", name); } else if (BND4.Is(name)) { bnd = BND4.Read(name); } else if (BND3.Is(name)) { bnd = BND3.Read(name); } foreach (var f in bnd.Files) { if (directEntryNameMatch ? textures.Contains(Utils.GetShortIngameFileName(f.Name).ToLower()) : TPF.Is(f.Bytes)) { var tpf = TPF.Read(f.Bytes); foreach (var tx in tpf.Textures) { var shortTexName = Utils.GetShortIngameFileName(tx.Name).ToLower(); if (textures.Contains(shortTexName)) { AddFetchTPF(tpf, tx.Name.ToLower()); textures.Remove(shortTexName); } } } } }
public static void Unpack(this BND3 bnd, string sourceName, string targetDir) { Directory.CreateDirectory(targetDir); XmlWriterSettings xws = new XmlWriterSettings(); xws.Indent = true; XmlWriter xw = XmlWriter.Create($"{targetDir}\\_yabber-bnd3.xml", xws); xw.WriteStartElement("bnd3"); xw.WriteElementString("filename", sourceName); xw.WriteElementString("compression", bnd.Compression.ToString()); xw.WriteElementString("timestamp", bnd.Timestamp); xw.WriteElementString("format", $"0x{(byte)bnd.Format:X2}"); xw.WriteElementString("bigendian", bnd.BigEndian.ToString()); xw.WriteElementString("unk1", bnd.Unk1.ToString()); xw.WriteElementString("unk2", $"0x{bnd.Unk2:X8}"); xw.WriteStartElement("files"); foreach (BND3.File file in bnd.Files) { string path, root; if (Binder.HasName(bnd.Format)) { path = YBUtil.UnrootBNDPath(file.Name, out root); } else { root = null; path = file.ID.ToString(); } xw.WriteStartElement("file"); xw.WriteElementString("id", file.ID.ToString()); if (Binder.HasName(bnd.Format)) { xw.WriteElementString("root", root); xw.WriteElementString("path", path); } xw.WriteElementString("flags", $"0x{(byte)file.Flags:X2}"); xw.WriteEndElement(); path = $"{targetDir}\\{path}"; Directory.CreateDirectory(Path.GetDirectoryName(path)); File.WriteAllBytes(path, file.Bytes); } xw.WriteEndElement(); xw.WriteEndElement(); xw.Close(); }
public GameParamHandler(Dictionary <string, PARAMDEF> paramdefs, TextHandler text, byte[] paramBNDData) { ParamDefs = paramdefs; ParamBnd = BND3.Read(paramBNDData); foreach (BinderFile file in ParamBnd.Files) { string name = Path.GetFileNameWithoutExtension(file.Name); PARAM param = PARAM.Read(file.Bytes); PARAMDEF p = ParamDefs[param.ParamType]; param.ApplyParamdef(p); Params[name] = param; } AI = new ParamDict <NPCThought>("NpcThinkParam", this, text); Armor = new ParamDict <Armor>("EquipParamProtector", this, text); ArmorUpgrades = new ParamDict <ArmorUpgrade>("ReinforceParamProtector", this, text); AttacksPC = new ParamDict <Attack>("AtkParam_Pc", this, text); AttacksNPC = new ParamDict <Attack>("AtkParam_Npc", this, text); BehaviorsPC = new ParamDict <Behavior>("BehaviorParam_PC", this, text); BehaviorsNPC = new ParamDict <Behavior>("BehaviorParam", this, text); Bullets = new ParamDict <Bullet>("Bullet", this, text); CalcCorrects = new ParamDict <CalcCorrect>("CalcCorrectGraph", this, text); ChrInits = new ParamDict <ChrInit>("CharaInitParam", this, text); CoolTimes = new ParamDict <CoolTime>("CoolTimeParam", this, text); UpgradeMaterials = new ParamDict <EquipMtrlSet>("EquipMtrlSetParam", this, text); FaceGens = new ParamDict <FaceGen>("FaceGenParam", this, text); GameAreas = new ParamDict <GameArea>("GameAreaParam", this, text); Goods = new ParamDict <Good>("EquipParamGoods", this, text); HitMtrls = new ParamDict <HitMtrl>("HitMtrlParam", this, text); ItemLots = new ParamDict <ItemLot>("ItemLotParam", this, text); Knockbacks = new ParamDict <Knockback>("KnockBackParam", this, text); LockCams = new ParamDict <LockCam>("LockCamParam", this, text); Magic = new ParamDict <Magic>("Magic", this, text); Movement = new ParamDict <Move>("MoveParam", this, text); MenuColorTables = new ParamDict <MenuColorTable>("MenuColorTableParam", this, text); NPCs = new ParamDict <NPC>("NpcParam", this, text); ObjActs = new ParamDict <ObjAct>("ObjActParam", this, text); Objects = new ParamDict <GameObject>("ObjectParam", this, text); Rings = new ParamDict <Accessory>("EquipParamAccessory", this, text); ShopLineups = new ParamDict <ShopLineup>("ShopLineupParam", this, text); Skeletons = new ParamDict <Skeleton>("SkeletonParam", this, text); SpEffects = new ParamDict <SpEffect>("SpEffectParam", this, text); SpEffectVFXs = new ParamDict <SpEffectVFX>("SpEffectVfxParam", this, text); Talks = new ParamDict <Talk>("TalkParam", this, text); Throws = new ParamDict <Throw>("ThrowParam", this, text); Weapons = new ParamDict <Weapon>("EquipParamWeapon", this, text); WeaponUpgrades = new ParamDict <WeaponUpgrade>("ReinforceParamWeapon", this, text); WhiteCoolTimes = new ParamDict <WhiteCoolTime>("WhiteCoolTimeParam", this, text); }
private void UnpackTPFs(ConcurrentQueue <string> filepaths) { string filepath; while (filepaths.TryDequeue(out filepath)) { Log.Enqueue("Unpacking texture file " + (fileCount - filepaths.Count) + " of " + fileCount); // These are already full paths, but trust no one, not even yourself string absolute = Path.GetFullPath(filepath); string relative = absolute.Substring(gameDir.Length + 1); byte[] bytes = File.ReadAllBytes(absolute); string extension = Path.GetExtension(absolute); string subpath = Path.GetDirectoryName(relative) + "\\" + Path.GetFileNameWithoutExtension(absolute); if (extension == ".dcx") { bytes = DCX.Decompress(bytes); extension = Path.GetExtension(Path.GetFileNameWithoutExtension(absolute)); subpath = subpath.Substring(0, subpath.Length - extension.Length); } switch (extension) { case ".tpf": TPF tpf = TPF.Read(bytes); UnpackTPF(tpf, looseDir, subpath); break; case ".chrbnd": case ".ffxbnd": case ".fgbnd": case ".objbnd": case ".partsbnd": BND3 bnd = BND3.Read(bytes); foreach (var entry in bnd.Files) { string entryExtension = Path.GetExtension(entry.Name); if (entryExtension == ".tpf") { TPF bndTPF = TPF.Read(entry.Bytes); UnpackTPF(bndTPF, looseDir, subpath); } } break; } } }
public static void AddTextureBnd(IBinder bnd, IProgress <double> prog) { var tpfs = bnd.Files.Where(file => file.Name != null && (file.Name.ToLower().EndsWith(".tpf") || file.Name.ToLower().EndsWith(".tpf.dcx"))).ToList(); var tbnds = bnd.Files.Where(file => file.Name != null && file.Name.ToLower().EndsWith(".tbnd")).ToList(); double total = tpfs.Count + tbnds.Count; double tpfFraction = 0; double tbndFraction = 0; if (total > 0) { tpfFraction = tpfs.Count / total; tbndFraction = tbnds.Count / total; } for (int i = 0; i < tpfs.Count; i++) { var file = tpfs[i]; if (file.Bytes.Length > 0) { TPF tpf = TPF.Read(file.Bytes); AddTpf(tpf); } prog?.Report(i / tpfFraction); } for (int i = 0; i < tbnds.Count; i++) { var file = tbnds[i]; if (file.Bytes.Length > 0) { IBinder tbnd = BND3.Read(file.Bytes); for (int j = 0; j < tbnd.Files.Count; j++) { TPF tpf = TPF.Read(tbnd.Files[j].Bytes); AddTpf(tpf); prog?.Report(tpfFraction + i / tbndFraction + j / tbnd.Files.Count * (tbndFraction / tbnds.Count)); } } prog?.Report(tpfFraction + i / tbndFraction); } prog?.Report(1); }
public static void SaveFMGs() { if (AssetLocator.Type == GameType.Undefined) { return; } if (AssetLocator.Type == GameType.DarkSoulsIISOTFS) { SaveFMGsDS2(); return; } // Load the fmg bnd, replace fmgs, and save IBinder fmgBinder; var desc = AssetLocator.GetEnglishItemMsgbnd(); if (AssetLocator.Type == GameType.DemonsSouls || AssetLocator.Type == GameType.DarkSoulsPTDE || AssetLocator.Type == GameType.DarkSoulsRemastered) { fmgBinder = BND3.Read(desc.AssetPath); } else { fmgBinder = BND4.Read(desc.AssetPath); } foreach (var file in fmgBinder.Files) { if (_fmgs.ContainsKey((ItemFMGTypes)file.ID)) { file.Bytes = _fmgs[(ItemFMGTypes)file.ID].Write(); } } var descw = AssetLocator.GetEnglishItemMsgbnd(true); if (fmgBinder is BND3 bnd3) { Utils.WriteWithBackup(AssetLocator.GameRootDirectory, AssetLocator.GameModDirectory, descw.AssetPath, bnd3); } else if (fmgBinder is BND4 bnd4) { Utils.WriteWithBackup(AssetLocator.GameRootDirectory, AssetLocator.GameModDirectory, descw.AssetPath, bnd4); } }
public static void Repack(string sourceDir, string targetDir) { BND3 bnd = new BND3(); XmlDocument xml = new XmlDocument(); xml.Load($"{sourceDir}\\_yabber-bnd3.xml"); string filename = xml.SelectSingleNode("bnd3/filename").InnerText; Enum.TryParse(xml.SelectSingleNode("bnd3/compression").InnerText, out bnd.Compression); bnd.Timestamp = xml.SelectSingleNode("bnd3/timestamp").InnerText; bnd.Format = (Binder.Format)Convert.ToByte(xml.SelectSingleNode("bnd3/format").InnerText, 16); bnd.BigEndian = bool.Parse(xml.SelectSingleNode("bnd3/bigendian").InnerText); bnd.Unk1 = bool.Parse(xml.SelectSingleNode("bnd3/unk1").InnerText); bnd.Unk2 = Convert.ToInt32(xml.SelectSingleNode("bnd3/unk2").InnerText, 16); foreach (XmlNode fileNode in xml.SelectNodes("bnd3/files/file")) { int id = int.Parse(fileNode.SelectSingleNode("id").InnerText); string name, path; if (Binder.HasName(bnd.Format)) { path = fileNode.SelectSingleNode("path").InnerText; name = fileNode.SelectSingleNode("root").InnerText + path; } else { path = id.ToString(); name = null; } byte flags = Convert.ToByte(fileNode.SelectSingleNode("flags").InnerText, 16); byte[] bytes = File.ReadAllBytes($"{sourceDir}\\{path}"); bnd.Files.Add(new BND3.File(id, name, (Binder.FileFlags)flags, bytes)); } string outPath = $"{targetDir}\\{filename}"; if (File.Exists(outPath) && !File.Exists(outPath + ".bak")) { File.Move(outPath, outPath + ".bak"); } bnd.Write(outPath); }
public static void LoadMessages(SQLiteConnection con, string messageDir) { List <string> messageFilepaths = new List <string>(); messageFilepaths.AddRange(Directory.GetFiles(messageDir, "*.msgbnd.dcx")); foreach (string messageFilepath in messageFilepaths) { var msgbnd = BND3.Read(messageFilepath); foreach (BinderFile file in msgbnd.Files) { string name = Path.GetFileNameWithoutExtension(file.Name); // Yes, .msgbnd file is FMG FMG msg = FMG.Read(file.Bytes); ReadMessagesIntoDatabase(con, name, msg); } } }
private Dictionary <string, Dictionary <string, T> > LoadBnd <T>(string relDir, Func <byte[], string, T> parser, string ext = "*esdbnd.dcx") { Console.WriteLine($"{dir} - {relDir}"); Dictionary <string, Dictionary <string, T> > ret = new Dictionary <string, Dictionary <string, T> >(); foreach (string path in Directory.GetFiles($@"{dir}\{relDir}", ext)) { string name = BaseName(path); Dictionary <string, T> bnds = new Dictionary <string, T>(); IBinder bnd; try { // :fatcat: bnd = dir.IndexOf("REMASTERED") != -1 ? (IBinder)BND3.Read(path) : BND4.Read(path); } catch (Exception ex) { throw new Exception($"Failed to load {path}: {ex}"); } foreach (BinderFile file in bnd.Files) { string bndName = BaseName(file.Name); try { T res = parser(file.Bytes, bndName); if (res != null) { bnds[bndName] = res; } } catch (Exception ex) { Console.WriteLine($"Failed to load {path}: {bndName}: {ex}"); } } if (bnds.Count > 0) { ret[name] = bnds; } } return(ret); }
public Dictionary <int, string> IndexAllFFX() { // Maps each FFX ID to the name of the (first) vanilla FFXBND that contains it (e.g. "10_01_00_00"). Dictionary <int, string> dict = new Dictionary <int, string>(); foreach (string bndFile in Directory.GetFiles(GameDir + @"\sfx")) { string bndFileName = Path.GetFileName(bndFile); if (bndFile.EndsWith(".ffxbnd.dcx")) { var bnd = BND3.Read(bndFile); foreach (var file in bnd.Files.Where(f => f.Name.EndsWith(".ffx"))) { string fileNumStr = Path.GetFileNameWithoutExtension(file.Name).Substring(1); int FFXID = int.Parse(fileNumStr); dict[FFXID] = bndFileName; } } } return(dict); }
void WriteMapFFXBND(int mapBlockID, HashSet <int> enemyModels) { HashSet <int> addedIDs = new HashSet <int>(); string ffxBNDName = $"FRPG_SfxBnd_m{mapBlockID:00}"; BND3 ffxBND = BND3.Read(GetGameDataResource(ffxBNDName + "_ffxbnd")); int bndIndex = ffxBND.Files.Where(file => file.ID < 100000).Max(file => file.ID) + 1; Dictionary <string, BND3> openBNDs = new Dictionary <string, BND3>(); foreach (int enemyModel in enemyModels) { foreach (var indexPath in EnemyGenerator.EnemyFFXSources[enemyModel]) { if (addedIDs.Contains(indexPath.Key)) { continue; // already added by another enemy } if (!indexPath.Value.Contains($"m{mapBlockID:00}")) // if enemy FFX is not already present in current block (or sub) FFXBND file... { string ffxFileName = $"f{indexPath.Key:0000000}.ffx"; if (!openBNDs.ContainsKey(indexPath.Value)) { openBNDs[indexPath.Value] = BND3.Read(GetGameDataResource(indexPath.Value + "_ffxbnd")); } // Lookup should never fail, by construction of FFXInfo. (But just in case it does, I'd rather print an error and have missing VFX.) var matches = openBNDs[indexPath.Value].Files.Where(f => f.Name.EndsWith(ffxFileName)); if (!matches.Any()) { Console.WriteLine($"ERROR: Could not find FFX {ffxFileName} in FFXBND {indexPath.Value}. VFX will be missing; please report to Grim!"); continue; } BinderFile ffxFile = matches.First(); ffxFile.ID = bndIndex; bndIndex++; ffxBND.Files.Add(ffxFile); addedIDs.Add(indexPath.Key); } } } ffxBND.Write(Mod.GameDir + $@"sfx\{ffxBNDName}.ffxbnd.dcx"); }
private static void LoadParamsDES() { var dir = AssetLocator.GameRootDirectory; var mod = AssetLocator.GameModDirectory; if (!File.Exists($@"{dir}\\param\gameparam\gameparam.parambnd.dcx")) { MessageBox.Show("Could not find DES regulation file. Functionality will be limited.", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // Load params var param = $@"{mod}\param\gameparam\gameparam.parambnd.dcx"; if (!File.Exists(param)) { param = $@"{dir}\param\gameparam\gameparam.parambnd.dcx"; } BND3 paramBnd = BND3.Read(param); LoadParamFromBinder(paramBnd); }
public static void Unpack(this BND3 bnd, string sourceName, string targetDir) { Directory.CreateDirectory(targetDir); var xws = new XmlWriterSettings(); xws.Indent = true; var xw = XmlWriter.Create($"{targetDir}\\_yabber-bnd3.xml", xws); xw.WriteStartElement("bnd3"); xw.WriteElementString("filename", sourceName); xw.WriteElementString("compression", bnd.Compression.ToString()); xw.WriteElementString("version", bnd.Version); xw.WriteElementString("format", bnd.Format.ToString()); xw.WriteElementString("bigendian", bnd.BigEndian.ToString()); xw.WriteElementString("bitbigendian", bnd.BitBigEndian.ToString()); xw.WriteElementString("unk18", $"0x{bnd.Unk18:X}"); YBinder.WriteBinderFiles(bnd, xw, targetDir); xw.WriteEndElement(); xw.Close(); }
void WriteMapLUABND(string luabndName, HashSet <int> battleGoalIDs, HashSet <int> logicGoalIDs = null) { // Reads from a folder full of unpacked binary AI Lua scripts and generates a LUABND for the given map ID name. // Note that in DSR, LUAINFO files are not needed (and LUAGNL was never needed). if (!battleGoalIDs.Any()) { throw new Exception("Empty list of battle goal IDs passed to Lua packer, which is not ever expected."); } BND3 mapLuaBND = new BND3 { Timestamp = "07D7R6" }; mapLuaBND.Compression = DCX.Type.DarkSouls1; int bndID = 1055; // first "safe" ID for loading order, according to vanilla use if (logicGoalIDs != null) { foreach (int goalID in logicGoalIDs) { string scriptPath = $"_{goalID:000000}_logic"; string bndPath = $@"N:\FRPG\data\INTERROOT_x64\script\ai\out\bin\{goalID:000000}_logic.lua"; BinderFile bndEntry = new BinderFile(Binder.FileFlags.x40, bndID, bndPath, GetGameDataResource(scriptPath)); mapLuaBND.Files.Add(bndEntry); bndID++; } } foreach (int goalID in battleGoalIDs) { string scriptPath = $"_{goalID:000000}_battle"; string bndPath = $@"N:\FRPG\data\INTERROOT_x64\script\ai\out\bin\{goalID:000000}_battle.lua"; BinderFile bndEntry = new BinderFile(Binder.FileFlags.x40, bndID, bndPath, GetGameDataResource(scriptPath)); mapLuaBND.Files.Add(bndEntry); bndID++; } mapLuaBND.Write(Mod.GameDir + $@"script\{luabndName}.luabnd.dcx"); }
private void UnpackGameBNDFile() { // Reading an original paramdefbnd paramDefs = new Dictionary <string, PARAMDEF>(); paramDefBnd = BND3.Read(pathToParamDef); foreach (BinderFile file in paramDefBnd.Files) { var paramdef = PARAMDEF.Read(file.Bytes); paramDefs[paramdef.ParamType] = paramdef; } parms = new Dictionary <string, PARAM>(); paramBnd = BND3.Read(pathToParamDataFile); foreach (BinderFile file in paramBnd.Files) { string name = Path.GetFileNameWithoutExtension(file.Name); var param = PARAM.Read(file.Bytes); param.ApplyParamdef(paramDefs[param.ParamType]); parms[name] = param; } }
public void DumpMessages(string dir) { foreach (string path in Directory.GetFiles(dir, "*.msgbnd*")) { string name = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(path)); try { IBinder bnd = BND3.Read(path); foreach (BinderFile file in bnd.Files) { string fileName = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file.Name)); string uname = System.Text.RegularExpressions.Regex.Replace(fileName, @"[^\x00-\x7F]", c => string.Format(@"u{0:x4}", (int)c.Value[0])); string fname = $"{name}_{uname}.txt"; // Console.WriteLine(fname); // string fileName = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file.Name)); FMG fmg = FMG.Read(file.Bytes); if (fmg.Entries != null) { File.WriteAllLines($@"{dir}\{fname}", fmg.Entries.Select(e => $"{e.ID} {(e.Text == null ? "" : e.Text.Replace("\r", "").Replace("\n", "\\n"))}")); } } } catch (Exception ex) { throw new Exception($"Failed to load file: {name}: {path}\r\n\r\n{ex}"); } } foreach (string path in Directory.GetFiles(dir, "*.fmg")) { FMG fmg = FMG.Read(path); string fname = Path.GetFileNameWithoutExtension(path); if (fmg.Entries != null) { File.WriteAllLines($@"{dir}\{fname}.txt", fmg.Entries.Select(e => $"{e.ID} {(e.Text == null ? "" : e.Text.Replace("\r", "").Replace("\n", "\\n"))}")); } } }
public static bool LoadParamBND(bool forceReload) { string interroot = GameDataManager.InterrootPath; bool justNowLoadedParamBND = false; if (forceReload || !ParamBNDs.ContainsKey(GameDataManager.GameType)) { ParamBNDs.Add(GameDataManager.GameType, null); if (GameDataManager.GameType == GameDataManager.GameTypes.DS1) { if (Directory.Exists($"{interroot}\\param\\GameParam\\") && File.Exists($"{interroot}\\param\\GameParam\\GameParam.parambnd")) { ParamBNDs[GameDataManager.GameType] = BND3.Read($"{interroot}\\param\\GameParam\\GameParam.parambnd"); } else { return(false); } } else if (GameDataManager.GameType == GameDataManager.GameTypes.BB) { if (Directory.Exists($"{interroot}\\param\\GameParam\\") && File.Exists($"{interroot}\\param\\GameParam\\GameParam.parambnd.dcx")) { ParamBNDs[GameDataManager.GameType] = BND4.Read($"{interroot}\\param\\GameParam\\GameParam.parambnd.dcx"); } else { return(false); } } else if (GameDataManager.GameType == GameDataManager.GameTypes.DS3) { if (Directory.Exists($"{interroot}\\param\\GameParam\\") && File.Exists($"{interroot}\\param\\GameParam\\GameParam_dlc2.parambnd.dcx")) { ParamBNDs[GameDataManager.GameType] = BND4.Read($"{interroot}\\param\\GameParam\\GameParam_dlc2.parambnd.dcx"); } else if (File.Exists($"{interroot}\\Data0.bdt")) { ParamBNDs[GameDataManager.GameType] = SFUtil.DecryptDS3Regulation($"{interroot}\\Data0.bdt"); } else { return(false); } } else { throw new NotImplementedException(); } justNowLoadedParamBND = true; } if (justNowLoadedParamBND || forceReload || GameTypeCurrentLoadedParamsAreFrom != GameDataManager.GameType) { LoadStuffFromParamBND(); } return(true); }
public SoulsMod(string gameDir, string backupExt = ".smbak", byte[] paramBNDData = null, byte[] paramdefBNDData = null, byte[] itemMSGBNDData = null, byte[] menuMSGBNDData = null) { if (!gameDir.EndsWith(@"\")) { gameDir += @"\"; } GameDir = gameDir; BackupExt = backupExt; // RestoreBackups(); // No need to restore backups automatically, as all files are loaded directly FROM the backups anyway. // Text is loaded first so it can be passed to `GameParamHandler`. #if DEBUG Console.Write("Loading Text... "); #endif if (itemMSGBNDData == null) { itemMSGBNDData = File.ReadAllBytes(GameDir + @"msg/ENGLISH/item.msgbnd.dcx"); } if (menuMSGBNDData == null) { menuMSGBNDData = File.ReadAllBytes(GameDir + @"msg/ENGLISH/menu.msgbnd.dcx"); } Text = new TextHandler(itemMSGBNDData, menuMSGBNDData); #if DEBUG Console.Write("Done.\n"); Console.Write("Loading Text (vanilla copy)... "); #endif VanillaText = new TextHandler(itemMSGBNDData, menuMSGBNDData); #if DEBUG Console.Write("Done.\n"); Console.Write("Loading ParamDefs... "); #endif if (paramdefBNDData == null) { paramdefBNDData = File.ReadAllBytes(GameDir + @"paramdef\paramdef.paramdefbnd.dcx"); } BND3 paramdefBnd = BND3.Read(paramdefBNDData); foreach (BinderFile file in paramdefBnd.Files) { PARAMDEF paramdef = PARAMDEF.Read(file.Bytes); ParamDefs[paramdef.ParamType] = paramdef; } #if DEBUG Console.Write("Done.\n"); Console.Write("Loading GameParams... "); #endif if (paramBNDData == null) { paramBNDData = File.ReadAllBytes(GameDir + @"param\GameParam\GameParam.parambnd.dcx"); } GPARAM = new GameParamHandler(ParamDefs, Text, paramBNDData); #if DEBUG Console.Write("Done.\n"); Console.Write("Loading GameParams (vanilla copy)... "); #endif if (paramBNDData != null) { VanillaGPARAM = new GameParamHandler(ParamDefs, VanillaText, paramBNDData); } else { VanillaGPARAM = new GameParamHandler(ParamDefs, VanillaText, GameDir + @"param\GameParam\GameParam.parambnd.dcx"); } #if DEBUG Console.Write("Done.\n"); #endif }