/// <summary> /// Load GGPK /// </summary> /// <param name="path">Path to GGPK file</param> public GGPKContainer(string path, bool BundleMode = false) { // Open File fileStream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); Reader = new BinaryReader(fileStream); Writer = new BinaryWriter(fileStream); // Read ROOT Directory Record BaseRecord ggpk; while (!((ggpk = GetRecord()) is GGPKRecord)) { ; } ggpkRecord = ggpk as GGPKRecord; rootDirectory = GetRecord(ggpkRecord.RootDirectoryOffset) as DirectoryRecord; rootDirectory.Name = "ROOT"; // Build Linked FreeRecord List long NextFreeOffset = ggpkRecord.FirstFreeRecordOffset; while (NextFreeOffset > 0) { FreeRecord current = GetRecord(NextFreeOffset) as FreeRecord; LinkedFreeRecords.AddLast(current); NextFreeOffset = current.NextFreeOffset; } if (BundleMode) { return; } // Read Bundles var Bundles2DirectoryNameHash = MurmurHash2Unsafe.Hash("bundles2", 0); OriginalBundles2 = rootDirectory.Children.First(d => d.GetNameHash() == Bundles2DirectoryNameHash) as DirectoryRecord; if (OriginalBundles2.Children.FirstOrDefault(r => r.Name == "_.index.bin") is FileRecord _index) { IndexRecord = _index; fileStream.Seek(_index.DataBegin, SeekOrigin.Begin); Index = new IndexContainer(Reader); FakeBundles2 = new BundleDirectoryNode("Bundles2", "", MurmurHash2Unsafe.Hash("bundles2", 0), (int)OriginalBundles2.Offset, OriginalBundles2.Length, this); rootDirectory.Children.Remove(OriginalBundles2); rootDirectory.Children.Add(FakeBundles2); foreach (var f in Index.Files) { BuildBundleTree(f, FakeBundles2); } } foreach (var br in Index.Bundles) { RecordOfBundle[br] = (FileRecord)FindRecord(br.Name, OriginalBundles2); } }
/// <summary> /// Add a message /// </summary> /// <param name="message">The message type to add</param> /// <param name="IdentifyKey">The key to identify the sending and receiving message, the identify key must be unique</param> /// <param name="Seed">The seed to use</param> /// <returns>If false the message did already exist otherwise true</returns> public bool AddMessage(Type MessageType, string IdentifyKey, uint Seed) { lock (Messages) { uint messageId = hasher.Hash(ASCIIEncoding.Unicode.GetBytes(IdentifyKey), 0);//this.Seed); Todo: need to fix seed for plugins if (MessageType.BaseType == null) { throw new Exception("IMessage is not the base type"); } if (MessageType.GetConstructor(new Type[0]) == null) { throw new Exception("The type must contain a constructor with no arguments"); } if (Messages.ContainsKey(messageId)) { return(false); } Messages.Add(messageId, MessageType); return(true); } }
/// <summary> /// Load GGPK /// </summary> /// <param name="path">Path to GGPK file</param> public GGPKContainer(string path, bool BundleMode = false, bool SteamMode = false, bool BuildTree = true) { // Steam Mode (No GGPK) if (SteamMode) { if (BundleMode) { throw new NotSupportedException("BundleMode and SteamMode cannot be both true"); } Environment.CurrentDirectory = Directory.GetParent(path).FullName; Index = new IndexContainer(path); if (BuildTree) { rootDirectory = FakeBundles2 = new BundleDirectoryNode("Bundles2", "", MurmurHash2Unsafe.Hash("bundles2", 0), 0, 0, this); foreach (var f in Index.Files) { BuildBundleTree(f, rootDirectory); } } return; } // Open File fileStream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); Reader = new BinaryReader(fileStream); Writer = new BinaryWriter(fileStream); // Read ROOT Directory Record BaseRecord ggpk; while ((ggpk = GetRecord()) is not GGPKRecord) { ; } ggpkRecord = ggpk as GGPKRecord; rootDirectory = GetRecord(ggpkRecord.RootDirectoryOffset) as DirectoryRecord; rootDirectory.Name = "ROOT"; // Build Linked FreeRecord List LinkedFreeRecords = new LinkedList <FreeRecord>(); var NextFreeOffset = ggpkRecord.FirstFreeRecordOffset; while (NextFreeOffset > 0) { FreeRecord current = GetRecord(NextFreeOffset) as FreeRecord; LinkedFreeRecords.AddLast(current); NextFreeOffset = current.NextFreeOffset; } // Read Bundles OriginalBundles2 = rootDirectory.Children.FirstOrDefault(d => d.GetNameHash() == MurmurHash2Unsafe.Hash("bundles2", 0)) as DirectoryRecord; if (OriginalBundles2?.Children.FirstOrDefault(r => r.Name == "_.index.bin") is FileRecord _index) { IndexRecord = _index; if (BundleMode) { return; } fileStream.Seek(_index.DataBegin, SeekOrigin.Begin); Index = new IndexContainer(Reader); if (BuildTree) { FakeBundles2 = new BundleDirectoryNode("Bundles2", "", MurmurHash2Unsafe.Hash("bundles2", 0), (int)OriginalBundles2.Offset, OriginalBundles2.Length, this); rootDirectory.Children.Remove(OriginalBundles2); rootDirectory.Children.Add(FakeBundles2); foreach (var f in Index.Files) { BuildBundleTree(f, FakeBundles2); } } _RecordOfBundle = new Dictionary <LibBundle.Records.BundleRecord, FileRecord>(Index.Bundles.Length); } // else BundleMode = true; }
public virtual uint GetNameHash() { return(MurmurHash2Unsafe.Hash(Name.ToLower(), 0)); }