public static CNS_File Read(byte[] rawBytes) { List <byte> bytes = rawBytes.ToList(); //Validation if (BitConverter.ToInt32(rawBytes, 0) != CNS_SIGNATURE) { throw new InvalidDataException("CNS_SIGNATURE not found at offset 0x0. Parse failed."); } int count = BitConverter.ToInt32(rawBytes, 8); int offset = BitConverter.ToInt32(rawBytes, 16); //Parse file CNS_File cnsFile = new CNS_File() { CnsEntries = new List <CNS_Entry>() }; cnsFile.Version = BitConverter.ToUInt16(rawBytes, 6); //Unknown values cnsFile.UnknownValues = BitConverter_Ex.ToUInt16Array(rawBytes, 20, 4); //Entries for (int i = 0; i < count; i++) { cnsFile.CnsEntries.Add(CNS_Entry.Read(rawBytes, bytes, offset)); offset += 180; } return(cnsFile); }
public static List <byte> Write(CNS_Entry cnsEntry) { List <byte> bytes = new List <byte>(); //Code if (cnsEntry.Str_00.Length > 8) { throw new Exception(String.Format("Dual_Code = {0} exceeds the maximum allowed length of 8. Load failed.", cnsEntry.Str_00)); } bytes.AddRange(Encoding.ASCII.GetBytes(cnsEntry.Str_00)); bytes.AddRange(new byte[8 - cnsEntry.Str_00.Length]); //Validate arrays Assertion.AssertArraySize(cnsEntry.I_10, 33, "CnsEntry", "I_10"); Assertion.AssertArraySize(cnsEntry.I_76, 33, "CnsEntry", "I_76"); Assertion.AssertArraySize(cnsEntry.I_146, 7, "CnsEntry", "I_146"); Assertion.AssertArraySize(cnsEntry.I_162, 7, "CnsEntry", "I_162"); //Remaining values bytes.AddRange(BitConverter.GetBytes(ushort.Parse(cnsEntry.Index))); bytes.AddRange(BitConverter_Ex.GetBytes(cnsEntry.I_10)); bytes.AddRange(BitConverter_Ex.GetBytes(cnsEntry.I_76)); bytes.AddRange(BitConverter.GetBytes(cnsEntry.I_142)); bytes.AddRange(BitConverter.GetBytes(cnsEntry.I_144)); bytes.AddRange(BitConverter_Ex.GetBytes(cnsEntry.I_146)); bytes.AddRange(BitConverter.GetBytes(cnsEntry.I_160)); bytes.AddRange(BitConverter_Ex.GetBytes(cnsEntry.I_162)); bytes.AddRange(BitConverter.GetBytes(cnsEntry.I_176)); bytes.AddRange(BitConverter.GetBytes(cnsEntry.I_178)); return(bytes); }
public byte[] SaveToBytes() { SortEntries(); List <byte> bytes = new List <byte>(); //Header bytes.AddRange(BitConverter.GetBytes(CNS_SIGNATURE)); //0 bytes.AddRange(BitConverter.GetBytes((UInt16)65534)); //4 bytes.AddRange(BitConverter.GetBytes(Version)); //6 bytes.AddRange(BitConverter.GetBytes(CnsEntries.Count)); //8 bytes.AddRange(BitConverter.GetBytes(20)); //12 bytes.AddRange(BitConverter.GetBytes(28)); //16 //Unknown values Assertion.AssertArraySize(UnknownValues, 4, "CNS", "UnknownValues"); bytes.AddRange(BitConverter_Ex.GetBytes(UnknownValues)); //Entries for (int i = 0; i < CnsEntries.Count; i++) { bytes.AddRange(CNS_Entry.Write(CnsEntries[i])); } return(bytes.ToArray()); }
/// <summary> /// Add a new CNS_Entry or replace an existing one with the same code. /// </summary> /// <param name="code">The 4-letter code for the Dual Skill. This should be the same as the one defined in the CUS.</param> /// <param name="id">ID of the Dual Skill. Use -1 to automatically assign the next unused ID.</param> public void AddEntry(CNS_Entry cnsEntry, string code, int id = -1) { for (int i = 0; i < CnsEntries.Count; i++) { if (CnsEntries[i].Str_00 == code) { //Entry already exists, so replace it and keep the same Dual ID. cnsEntry.Index = CnsEntries[i].Index; CnsEntries[i] = cnsEntry; return; } } //Entry didn't already exist, so add it as a new entry. if (id == -1) { cnsEntry.Index = NextId().ToString(); } else { cnsEntry.Index = id.ToString(); } CnsEntries.Add(cnsEntry); }