//public int InsertAndCombine(int StartingValue, int AddingValue, out uint Mask, out byte ShiftVal) //{ // Mask = 0; // ShiftVal = 0; // BitArray StartingBits = new BitArray(new int[] { StartingValue }); // BitArray AddingBits = new BitArray(new int[] { AddingValue }); // int MinAddBitSize = GetMinLength(AddingValue); // bool success = false; // for (int i = 0; i < StartingBits.Count - MinAddBitSize; i++) // { // if (StartingBits[i] == AddingBits[0]) // { // bool CanFit = true; // for (int j = 0; j < MinAddBitSize; j++) // { // if (StartingBits[i + j] != AddingBits[j]) // { // CanFit = false; // break; // } // } // if (CanFit) // { // success = true; // BitArray BitMask = new BitArray(new int[1]); // for (int j = 0; j < MinAddBitSize; j++) // { // BitMask[i + j] = true; // } // Mask = (uint)BitMask.ToInt32(); // ShiftVal = (byte)i; // break; // } // } // } // if (!success) // { // int NumberInsertLocation = GetMinLength(StartingValue); // int BackwardsOffset = 0; // bool HasFoundFit = false; // int BestFitOffset = 0; // while (NumberInsertLocation - BackwardsOffset > 0) // { // if (StartingBits[NumberInsertLocation - BackwardsOffset] == AddingBits[0]) // { // bool CanFit = true; // for (int i = 0; i < MinAddBitSize; i++) // { // if (AddingBits[i] && StartingBits[(NumberInsertLocation - BackwardsOffset) + i] != AddingBits[i]) // { // if ((NumberInsertLocation - BackwardsOffset) + i < NumberInsertLocation) // { // CanFit = false; // break; // } // } // } // if (CanFit) // { // HasFoundFit = true; // BestFitOffset = NumberInsertLocation - BackwardsOffset; // break; // } // } // BackwardsOffset++; // } // for (int j = 0; j < MinAddBitSize; j++) // { // StartingBits[HasFoundFit ? BestFitOffset + j : NumberInsertLocation] = AddingBits[j]; // } // BitArray BitMask = new BitArray(new int[1]); // for (int j = 0; j < MinAddBitSize; j++) // { // BitMask[HasFoundFit ? BestFitOffset + j : NumberInsertLocation] = true; // } // Mask = (uint)BitMask.ToInt32(); // ShiftVal = (byte)(HasFoundFit ? BestFitOffset : NumberInsertLocation); // } // return StartingBits.ToInt32(); //} //private int GetMinLength(int val) //{ // for (int i = 28; i >= 0; i -= 4) // if ((val >> i) > 0) // return i + 4; // return 0; //} internal void Read(Stream BCSV) { Fields = new Dictionary <uint, BCSVField>(); Entries = new List <BCSVEntry>(); int entrycount = BitConverter.ToInt32(BCSV.ReadReverse(0, 4), 0); //Console.Write($"{entrycount} Entries "); int fieldcount = BitConverter.ToInt32(BCSV.ReadReverse(0, 4), 0); //Console.WriteLine($"done with {fieldcount} fields"); uint dataoffset = BitConverter.ToUInt32(BCSV.ReadReverse(0, 4), 0); uint entrysize = BitConverter.ToUInt32(BCSV.ReadReverse(0, 4), 0); //Console.WriteLine("Loading Fields:"); for (int i = 0; i < fieldcount; i++) { BCSVField currentfield = new BCSVField(BCSV); Fields.Add(currentfield.HashName, currentfield); //Console.Write($"\r{Math.Min(((float)(i + 1) / (float)fieldcount) * 100.0f, 100.0f)}% "); } //Console.WriteLine("Complete!"); //Console.WriteLine("Loading Entries:"); for (int i = 0; i < entrycount; i++) { BCSVEntry currententry = new BCSVEntry(BCSV, Fields, dataoffset + (entrycount * entrysize)); Entries.Add(currententry); BCSV.Position += entrysize; //Console.Write($"\r{Math.Min(((float)(i + 1) / (float)entrycount) * 100.0f, 100.0f)}% "); } //Console.WriteLine("Complete!"); }
/// <summary> /// Add a BCSVField to the Field Dictionary /// </summary> /// <param name="field">Field to add</param> public void Add(BCSVField field) => Fields.Add(field.HashName, field);
/// <summary> /// Save the BCSV using a Stream /// </summary> /// <param name="BCSV"></param> public void Save(Stream BCSV) { BCSV.WriteReverse(BitConverter.GetBytes(EntryCount), 0, 4); ushort offset = 0; List <KeyValuePair <uint, BCSVField> > FieldList = Fields.ToList(); for (int i = 0; i < FieldList.Count; i++) { BCSVField currentfield = FieldList[i].Value; if (currentfield.AutoRecalc) { currentfield.Bitmask = currentfield.DataType == DataTypes.BYTE ? 0x000000FF : (currentfield.DataType == DataTypes.INT16 ? 0x0000FFFF : 0xFFFFFFFF); currentfield.ShiftAmount = 0; } currentfield.EntryOffset = offset; offset += (ushort)(currentfield.DataType == DataTypes.BYTE ? 1 : (currentfield.DataType == DataTypes.INT16 ? 2 : 4)); } while (offset % 4 != 0) { offset++; } #region Fill the Entries for (int i = 0; i < EntryCount; i++) { Entries[i].FillMissingFields(Fields); } #endregion #region Collect the strings List <string> Strings = new List <string>();// { "5324" }; for (int i = 0; i < EntryCount; i++) { for (int j = 0; j < Entries[i].Data.Count; j++) { if (Fields.ContainsKey(Entries[i].Data.ElementAt(j).Key) && Fields[Entries[i].Data.ElementAt(j).Key].DataType == DataTypes.STRING) { if (!Strings.Any(O => O.Equals((string)Entries[i].Data.ElementAt(j).Value))) { Strings.Add((string)Entries[i].Data.ElementAt(j).Value); } } } } #endregion BCSV.WriteReverse(BitConverter.GetBytes(Fields.Count), 0, 4); BCSV.Write(new byte[4], 0, 4); BCSV.WriteReverse(BitConverter.GetBytes((int)offset), 0, 4); Console.WriteLine("Writing the Fields:"); for (int i = 0; i < Fields.Count; i++) { Fields.ElementAt(i).Value.Write(BCSV); Console.Write($"\r{Math.Min(((float)(i + 1) / (float)Fields.Count) * 100.0f, 100.0f)}% "); } Console.WriteLine("Complete!"); while (BCSV.Position % 4 != 0) { BCSV.WriteByte(0x00); } uint DataPos = (uint)BCSV.Position; BCSV.Position = 0x08; BCSV.WriteReverse(BitConverter.GetBytes(DataPos), 0, 4); BCSV.Position = DataPos; Console.WriteLine("Writing the Entries:"); for (int i = 0; i < EntryCount; i++) { Entries[i].Save(BCSV, Fields, offset, Strings); while (BCSV.Position % 4 != 0) { BCSV.WriteByte(0x00); } Console.Write($"\r{Math.Min(((float)(i + 1) / (float)Entries.Count) * 100.0f, 100.0f)}% "); } Console.WriteLine("Complete!"); for (int i = 0; i < Strings.Count; i++) { BCSV.WriteString(Strings[i], 0x00); } uint numPadding = 16 - (uint)(BCSV.Position % 16); byte[] padding = new byte[numPadding]; for (int i = 0; i < numPadding; i++) { padding[i] = 64; } BCSV.Write(padding, 0, (int)numPadding); }