/// <summary> /// Reads Bioware Encapsulated Resource Files /// </summary> /// <param name="s">The Stream from which the File will be Read</param> protected ERF(Stream s) { using (BinaryReader br = new BinaryReader(s)) { //header FileType = new string(br.ReadChars(4)); Version = new string(br.ReadChars(4)); LanguageCount = br.ReadInt32(); LocalizedStringSize = br.ReadInt32(); EntryCount = br.ReadInt32(); OffsetToLocalizedStrings = br.ReadInt32(); OffsetToKeyList = br.ReadInt32(); OffsetToResourceList = br.ReadInt32(); BuildYear = br.ReadInt32(); BuildDay = br.ReadInt32(); DescriptionStrRef = br.ReadInt32(); Reserved_block = br.ReadBytes(116); br.BaseStream.Seek(OffsetToLocalizedStrings, SeekOrigin.Begin); //seek to local strings for (int i = 0; i < LanguageCount; i++) { String_List_Element SLE = new String_List_Element(); SLE.LanguageID = br.ReadInt32(); SLE.Language = Reference_Tables.Language_IDs[SLE.LanguageID]; SLE.StringSize = br.ReadInt32(); SLE.String = new string(br.ReadChars(SLE.StringSize)); Localized_String_List.Add(SLE); } br.BaseStream.Seek(OffsetToKeyList, SeekOrigin.Begin); //seek to key entries for (int i = 0; i < EntryCount; i++) { Key key = new Key(); key.ResRef = new string(br.ReadChars(16)).TrimEnd('\0'); key.ResID = br.ReadInt32(); key.ResType = br.ReadInt16(); key.Type_string = Reference_Tables.Res_Types[key.ResType]; key.Unused = br.ReadInt16(); Key_List.Add(key); } br.BaseStream.Seek(OffsetToResourceList, SeekOrigin.Begin); //seek to resource list for (int i = 0; i < EntryCount; i++) { Resource Res = new Resource(); Res.OffsetToResource = br.ReadInt32(); Res.ResourceSize = br.ReadInt32(); Resource_List.Add(Res); } foreach (Resource r in Resource_List) //populate resource_data for each resource in the list { br.BaseStream.Seek(r.OffsetToResource, SeekOrigin.Begin); //seek to raw resource data r.Resource_data = br.ReadBytes(r.ResourceSize); } } }
/// <summary> /// Adds another resource to the <see cref="ERF"/>. /// </summary> /// <param name="res_ref">The name of the resource/file. *Maximum of 16 Characters</param> /// <param name="file_data">A byte array containing the data for the resource</param> public void Append_File(string res_ref, byte[] file_data) { //header EntryCount++; OffsetToResourceList += 24; //key Key k = new Key(); k.ResRef = res_ref; k.ResID = Key_List.Last().ResID + 1; StringBuilder sb = new StringBuilder(4); sb.Append(new char[4] { (char)file_data[0], (char)file_data[1], (char)file_data[2], (char)file_data[3], }); k.ResType = (short)Reference_Tables.TypeCodes[sb.ToString()]; k.Type_string = k.Type_string = Reference_Tables.Res_Types[k.ResType]; k.Unused = 0; Key_List.Add(k); //Offset Correction int TotalOffset = OffsetToResourceList + EntryCount * 8; foreach (Resource res in Resource_List) { res.OffsetToResource = TotalOffset; TotalOffset += res.ResourceSize; } //resource Resource r = new Resource(); r.Resource_data = file_data; r.ResourceSize = file_data.Length; r.OffsetToResource = Resource_List.Last().OffsetToResource + Resource_List.Last().ResourceSize; Resource_List.Add(r); }