public override void Write(Vault vault, BinaryWriter bw) { bw.Write(VLT64Hasher.Hash(Collection.Name)); bw.Write(VLT64Hasher.Hash(Collection.Class.Name)); bw.Write(Collection.Parent != null ? VLT64Hasher.Hash(Collection.Parent.Name) : 0L); bw.Write(_entries.Count); bw.Write(0); bw.Write(_entries.Count); ushort numTypes = (ushort)_types.Length; ushort typesLen = (ushort)(numTypes % 2 == 0 ? numTypes : numTypes + 1); bw.Write(numTypes); bw.Write(typesLen); _srcLayoutPtr = bw.BaseStream.Position; bw.Write(0); bw.Write(0); // align foreach (var type in _types) { bw.Write(type); } if (typesLen != numTypes) { bw.Write(0L); } foreach (var attribEntry in _entries) { attribEntry.Write(vault, bw); } }
public override void Write(Vault vault, BinaryWriter bw) { int collectionReserve = (from collection in vault.SaveContext.Collections where collection.Class.Name == Class.Name select collection).Count(); bw.Write(VLT64Hasher.Hash(Class.Name)); bw.Write(collectionReserve); bw.Write(Class.Fields.Count); _srcDefinitionsPtr = bw.BaseStream.Position; bw.Write(0); int staticSize = ComputeStaticSize(); bw.Write(staticSize); if (staticSize > 0) { _srcStaticPtr = bw.BaseStream.Position; } bw.Write(0); bw.Write(ComputeBaseSize()); bw.Write((ushort)0); bw.Write((ushort)Class.BaseFields.Count()); bw.Write(0); // align }
public override void Write(Vault vault, BinaryWriter bw) { _text = new Text(Class, Field, Collection); _text.Value = Value; bw.Write(string.IsNullOrEmpty(Value) ? 0L : VLT64Hasher.Hash(Value)); bw.Write(string.IsNullOrEmpty(Value) ? 0 : VLT32Hasher.Hash(Value)); _text.Write(vault, bw); }
public override void Write(Vault vault, BinaryWriter bw) { if (vault.Database.Options.Type == DatabaseType.X86Database) { bw.Write(VLT32Hasher.Hash(CollectionKey)); } else { bw.Write(VLT64Hasher.Hash(CollectionKey)); } }
public override void Prepare(Vault vault) { List <KeyValuePair <string, VLTBaseType> > optionalDataColumns = (from pair in Collection.GetData() let field = Collection.Class[pair.Key] where !field.IsInLayout orderby field.Name select pair).ToList(); _entries = new List <AttribEntry64>(); _types = Collection.Class.BaseFields.Select(f => f.TypeName) .Concat(optionalDataColumns.Select(c => Collection.Class[c.Key].TypeName)) .Select(s => VLT64Hasher.Hash(s)).Distinct().ToArray(); for (var index = 0; index < optionalDataColumns.Count; index++) { var optionalDataColumn = optionalDataColumns[index]; var entry = new AttribEntry64(Collection); var vltClassField = Collection.Class[optionalDataColumn.Key]; entry.Key = VLT64Hasher.Hash(optionalDataColumn.Key); entry.TypeIndex = (ushort)Array.IndexOf(_types, VLT64Hasher.Hash(vltClassField.TypeName)); entry.EntryFlags = 0; entry.NodeFlags = NodeFlagsEnum.Default; if (entry.IsInline()) { entry.InlineData = optionalDataColumn.Value; entry.NodeFlags |= NodeFlagsEnum.IsInline; } else { entry.InlineData = new VLTAttribType(Collection.Class, vltClassField, Collection) { Data = optionalDataColumn.Value }; } if (vltClassField.IsArray) { entry.NodeFlags |= NodeFlagsEnum.IsArray; } if ((vltClassField.Flags & DefinitionFlags.HasHandler) != 0) { entry.NodeFlags |= NodeFlagsEnum.HasHandler; } _entries.Add(entry); } }
public override void WritePointerData(Vault vault, BinaryWriter bw) { _dstDefinitionsPtr = bw.BaseStream.Position; foreach (var field in Class.Fields.Values) { AttribDefinition64 definition = new AttribDefinition64(); definition.Key = VLT64Hasher.Hash(field.Name); definition.Type = VLT64Hasher.Hash(field.TypeName); definition.Flags = field.Flags; definition.Size = field.Size; definition.MaxCount = field.MaxCount; definition.Offset = field.Offset; definition.Alignment = field.Alignment; definition.Write(vault, bw); } }
public override void Write(Vault vault, BinaryWriter bw) { bw.Write(VLT64Hasher.Hash(Class.Name)); int collReserve = (from collection in vault.Database.RowManager.GetFlattenedCollections(Class.Name) select collection).Count(); if (collReserve == 0) { throw new InvalidDataException("Cannot serialize legacy ClassLoadData when mCollectionReserve is 0."); } bw.Write(collReserve); bw.Write(Class.Fields.Count); _srcDefinitionsPtr = bw.BaseStream.Position; bw.Write(0); bw.Write(ComputeBaseSize()); bw.Write(0); bw.Write((ushort)Class.BaseFields.Count()); bw.Write((ushort)0); }
public override void WritePointerData(Vault vault, BinaryWriter bw) { _dstDefinitionsPtr = bw.BaseStream.Position; foreach (var field in Class.Fields.Values) { AttribDefinition64 definition = new AttribDefinition64(); definition.Key = VLT64Hasher.Hash(field.Name); definition.Alignment = field.Alignment; definition.Flags = field.Flags; definition.MaxCount = field.MaxCount; definition.Offset = field.Offset; definition.Size = field.Size; definition.Type = VLT64Hasher.Hash(field.TypeName); definition.Write(vault, bw); } if (_srcStaticPtr != 0) { bw.AlignWriter(0x10); _dstStaticPtr = bw.BaseStream.Position; foreach (var staticField in Class.StaticFields) { bw.AlignWriter(staticField.Alignment); staticField.StaticValue.Write(vault, bw); } foreach (var staticField in Class.StaticFields) { if (staticField.StaticValue is IPointerObject pointerObject) { pointerObject.WritePointerData(vault, bw); } } } }
public override void Write(Vault vault, BinaryWriter bw) { bw.Write(VLT64Hasher.Hash(Collection.Name)); bw.Write(VLT64Hasher.Hash(Collection.Class.Name)); //bw.Write((uint) (Collection.Parent?.Key ?? 0)); bw.Write(Collection.Parent != null ? VLT64Hasher.Hash(Collection.Parent.Name) : 0u); bw.Write((uint)_entries.Length); bw.Write(0); bw.Write((uint)_entries.Length); bw.Write((uint)_types.Length); _srcLayoutPtr = bw.BaseStream.Position; bw.Write(0); foreach (var type in _types) { bw.Write(type); } foreach (var entry in _entries) { entry.Write(vault, bw); } }
/// <summary> /// Deserializes the files. /// </summary> public LoadedDatabase Deserialize() { var deserializer = new DeserializerBuilder().Build(); using var dbs = new StreamReader(Path.Combine(_inputDirectory, "info.yml")); var loadedDatabase = deserializer.Deserialize <LoadedDatabase>(dbs); var isX86 = _database.Options.Type == DatabaseType.X86Database; foreach (var loadedDatabaseClass in loadedDatabase.Classes) { var vltClass = new VltClass(loadedDatabaseClass.Name); foreach (var loadedDatabaseClassField in loadedDatabaseClass.Fields) { var field = new VltClassField( isX86 ? VLT32Hasher.Hash(loadedDatabaseClassField.Name) : VLT64Hasher.Hash(loadedDatabaseClassField.Name), loadedDatabaseClassField.Name, loadedDatabaseClassField.TypeName, loadedDatabaseClassField.Flags, loadedDatabaseClassField.Alignment, loadedDatabaseClassField.Size, loadedDatabaseClassField.MaxCount, loadedDatabaseClassField.Offset); // Handle static value if (loadedDatabaseClassField.StaticValue != null) { field.StaticValue = ConvertSerializedValueToDataValue(_database.Options.GameId, _inputDirectory, vltClass, field, null, loadedDatabaseClassField.StaticValue); } vltClass.Fields.Add(field.Key, field); } _database.AddClass(vltClass); } foreach (var loadedDatabaseType in loadedDatabase.Types) { _database.Types.Add(new DatabaseTypeInfo { Name = loadedDatabaseType.Name, Size = loadedDatabaseType.Size }); } var collectionParentDictionary = new Dictionary <string, string>(); var collectionDictionary = new Dictionary <string, VltCollection>(); var vaultsToSaveDictionary = new Dictionary <string, List <Vault> >(); var collectionsToBeAdded = new List <VltCollection>(); foreach (var file in loadedDatabase.Files) { file.LoadedVaults = new List <Vault>(); var baseDirectory = Path.Combine(_inputDirectory, file.Group, file.Name); vaultsToSaveDictionary[file.Name] = new List <Vault>(); foreach (var vault in file.Vaults) { var vaultDirectory = Path.Combine(baseDirectory, vault).Trim(); var newVault = new Vault(vault) { Database = _database, IsPrimaryVault = vault == "db" }; if (Directory.Exists(vaultDirectory)) { HashSet <string> trackedCollections = new HashSet <string>(); foreach (var dataFile in Directory.GetFiles(vaultDirectory, "*.yml")) { var className = Path.GetFileNameWithoutExtension(dataFile); var vltClass = _database.FindClass(className); if (vltClass == null) { throw new InvalidDataException($"Unknown class: {className} ({dataFile})"); } //#if DEBUG // Debug.WriteLine("Processing class '{0}' in vault '{1}' (file: {2})", className, vault, dataFile); //#else // Console.WriteLine("Processing class '{0}' in vault '{1}' (file: {2})", className, vault, dataFile); //#endif using var vr = new StreamReader(dataFile); var collections = deserializer.Deserialize <List <LoadedCollection> >(vr); foreach (var loadedCollection in collections) { // BUG 16.02.2020: we have to do this to get around a YamlDotNet bug if (loadedCollection.Name == null) { loadedCollection.Name = "null"; } foreach (var k in loadedCollection.Data.Keys.ToList().Where(k => loadedCollection.Data[k] == null)) { loadedCollection.Data[k] = "null"; } } var newCollections = new List <VltCollection>(); void AddCollectionsToList(ICollection <VltCollection> collectionList, IEnumerable <LoadedCollection> collectionsToAdd) { if (collectionList == null) { throw new Exception("collectionList should not be null!"); } collectionsToAdd ??= new List <LoadedCollection>(); foreach (var loadedCollection in collectionsToAdd) { var newVltCollection = new VltCollection(newVault, vltClass, loadedCollection.Name); foreach (var(key, value) in loadedCollection.Data) { newVltCollection.SetRawValue(key, ConvertSerializedValueToDataValue(_database.Options.GameId, vaultDirectory, vltClass, vltClass[key], newVltCollection, value)); } collectionParentDictionary[newVltCollection.ShortPath] = loadedCollection.ParentName; collectionList.Add(newVltCollection); collectionDictionary[newVltCollection.ShortPath] = newVltCollection; } } AddCollectionsToList(newCollections, collections); foreach (var newCollection in newCollections) { if (!trackedCollections.Add(newCollection.ShortPath)) { throw new SerializedDatabaseLoaderException($"Duplicate collection found! Multiple collections at '{newCollection.ShortPath}' have been defined in your YML files."); } collectionsToBeAdded.Add(newCollection); } } } else { Console.WriteLine("WARN: vault {0} has no folder; looked for {1}", vault, vaultDirectory); } vaultsToSaveDictionary[file.Name].Add(newVault); _database.Vaults.Add(newVault); file.LoadedVaults.Add(newVault); } } // dependency resolution var resolved = new List <VaultDependencyNode>(); var unresolved = new List <VaultDependencyNode>(); foreach (var vault in _database.Vaults) { var vaultCollections = collectionsToBeAdded.Where(c => c.Vault.Name == vault.Name).ToList(); VaultDependencyNode node = new VaultDependencyNode(vault); foreach (var vaultCollection in vaultCollections) { string parentKey = collectionParentDictionary[vaultCollection.ShortPath]; if (!string.IsNullOrEmpty(parentKey)) { var parentCollection = collectionDictionary[$"{vaultCollection.Class.Name}/{parentKey}"]; if (parentCollection.Vault.Name != vault.Name) { node.AddEdge(new VaultDependencyNode(parentCollection.Vault)); } } } ResolveDependencies(node, resolved, unresolved); Debug.WriteLine("Vault {0}: {1} collections", vault.Name, vaultCollections.Count); } resolved = resolved.Distinct(VaultDependencyNode.VaultComparer).ToList(); unresolved = unresolved.Distinct(VaultDependencyNode.VaultComparer).ToList(); if (unresolved.Count != 0) { throw new SerializedDatabaseLoaderException("Cannot continue loading - unresolved vault dependencies"); } foreach (var node in resolved) { var vault = node.Vault; var vaultCollections = collectionsToBeAdded.Where(c => c.Vault.Name == vault.Name).ToList(); Debug.WriteLine("Loading collections for vault {0} ({1})", vault.Name, vaultCollections.Count); foreach (var collection in vaultCollections) { string parentKey = collectionParentDictionary[collection.ShortPath]; if (string.IsNullOrEmpty(parentKey)) { // Add collection directly _database.RowManager.AddCollection(collection); } else { var parentCollection = collectionDictionary[$"{collection.Class.Name}/{parentKey}"]; parentCollection.AddChild(collection); } } } _loadedDatabase = loadedDatabase; return(loadedDatabase); }
public override ulong GetExportID() { return(VLT64Hasher.Hash(Class.Name)); }
public override ulong GetExportID() { return(VLT64Hasher.Hash($"{Collection.Class.Name}/{Collection.Name}")); }