public static void JsonToBin(string filename) { byte[] data = File.ReadAllBytes(filename); Dictionary <string, int> stringAddresses = new Dictionary <string, int>(); UnitxtFile unitxt = Json.Deserialize <UnitxtFile>(data, 0, data.Length); int pr3_pointers = 0; // Add all the strings as well as the group pointer for (int i1 = 0; i1 < stringGroupCount; i1++) { pr3_pointers += 1; pr3_pointers += unitxt.StringGroups[i1].entries.Count; } // Whatever, this should be enough, every time ByteArray baPR2 = new ByteArray(1024 * 1024); ByteArray baPR3 = new ByteArray((pr3_pointers + 5) * 2 + 32); for (int i1 = 0; i1 < stringGroupCount; i1++) { for (int i2 = 0; i2 < unitxt.StringGroups[i1].entries.Count; i2++) { // Only add this string if we don't have it yet, // Gotta save the bytes if (!stringAddresses.ContainsKey(unitxt.StringGroups[i1].entries[i2])) { // Save it's address stringAddresses[unitxt.StringGroups[i1].entries[i2]] = baPR2.Position; // Write it out baPR2.WriteStringA(unitxt.StringGroups[i1].entries[i2], 0, unitxt.StringGroups[i1].entries[i2].Length, true); // Some padding? baPR2.Pad(4); } } } // Write the tables // We'll need the first one List <int> tablePointers = new List <int>(); baPR2.Endianess = Endianess.BigEndian; for (int i1 = 0; i1 < unitxt.SomeTables.Count; i1++) { // Save the table offset tablePointers.Add(baPR2.Position); for (int i2 = 0; i2 < unitxt.SomeTables[i1].Count; i2++) { baPR2.Write(unitxt.SomeTables[i1][i2]); } } // We'll need this offset, it's the beginning of the short table pointer in pr3 int tablePointer = baPR2.Position; for (int i1 = 0; i1 < unitxt.SomeTables.Count; i1++) { // Save the table offset baPR2.Write(tablePointers[i1]); } // Table count offset, needed at the end int tableCountOffset = baPR2.Position; baPR2.Endianess = Endianess.LittleEndian; baPR2.Write(unitxt.tableValue); baPR2.Endianess = Endianess.BigEndian; baPR2.Write(tablePointer); for (int i1 = 0; i1 < stringGroupCount; i1++) { unitxt.StringGroups[i1].groupOffset = baPR2.Position; for (int i2 = 0; i2 < unitxt.StringGroups[i1].entries.Count; i2++) { // Instead of getting the addresses from the strings themselves // Just use the dict, no duplicates :) baPR2.Write(stringAddresses[unitxt.StringGroups[i1].entries[i2]]); } } int stringGroupOffset = baPR2.Position; for (int i1 = 0; i1 < stringGroupCount; i1++) { baPR2.Write(unitxt.StringGroups[i1].groupOffset); } int tableCountOffsetOffset = baPR2.Position; baPR2.Write(tableCountOffset); baPR2.Write(stringGroupOffset); baPR2.Resize(baPR2.Position); // Write Pr3 data baPR3.Write(0x20); baPR3.Endianess = Endianess.BigEndian; baPR3.Write(pr3_pointers + 5); baPR3.Write(1); baPR3.Write(0); baPR3.Write(tableCountOffsetOffset); baPR3.Write(0); baPR3.Write(0); baPR3.Write(0); // Just fill this stuff baPR3.Write((short)(tablePointer / 4)); baPR3.Write((short)1); baPR3.Write((short)2); for (int i1 = 0; i1 < pr3_pointers; i1++) { baPR3.Write((short)1); } baPR3.Write((short)1); baPR3.Write((short)1); uint prc_key = (uint)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; byte[] dataPR2 = PSOCT.CompressPRC(baPR2.Buffer, prc_key, true); byte[] dataPR3 = PSOCT.CompressPRC(baPR3.Buffer, prc_key, true); File.WriteAllBytes(Path.ChangeExtension(filename, ".pr2"), dataPR2); File.WriteAllBytes(Path.ChangeExtension(filename, ".pr3"), dataPR3); }
public static void JsonToBin(string filename) { byte[] data = File.ReadAllBytes(filename); Dictionary <string, int> stringAddresses = new Dictionary <string, int>(); UnitxtFile unitxt = Json.Deserialize <UnitxtFile>(data, 0, data.Length); int pr3_pointersCount = 0; // Add all the strings as well as the group pointer for (int i1 = 0; i1 < stringGroupCount - 2; i1++) { pr3_pointersCount += 1; pr3_pointersCount += unitxt.StringGroups[i1].entries.Count; } pr3_pointersCount += 7; // Whatever, this should be enough, every time ByteArray baPR2 = new ByteArray(1024 * 1024); ByteArray baPR3 = new ByteArray(pr3_pointersCount * 2 + 32); for (int i1 = 0; i1 < stringGroupCount - 2; i1++) { for (int i2 = 0; i2 < unitxt.StringGroups[i1].entries.Count; i2++) { // Only add this string if we don't have it yet, // Gotta save the bytes if (!stringAddresses.ContainsKey(unitxt.StringGroups[i1].entries[i2])) { // Save it's address stringAddresses[unitxt.StringGroups[i1].entries[i2]] = baPR2.Position; // Write it out baPR2.WriteStringA(unitxt.StringGroups[i1].entries[i2], 0, unitxt.StringGroups[i1].entries[i2].Length, true); // Some padding? baPR2.Pad(4); } } } int firstPointer = baPR2.Position; // Write the first 10 groups for (int i1 = 0; i1 < 10; i1++) { unitxt.StringGroups[i1].groupOffset = baPR2.Position; for (int i2 = 0; i2 < unitxt.StringGroups[i1].entries.Count; i2++) { baPR2.Write(stringAddresses[unitxt.StringGroups[i1].entries[i2]]); } } int pointerTable11 = baPR2.Position; for (int i1 = 0; i1 < unitxt.SomeTables[0].Count; i1++) { baPR2.Write(unitxt.SomeTables[0][i1]); } int pointerTable12 = baPR2.Position; for (int i1 = 0; i1 < unitxt.SomeTables[1].Count; i1++) { baPR2.Write(unitxt.SomeTables[1][i1]); } int pointerTable1 = baPR2.Position; baPR2.Write(pointerTable11); baPR2.Write(pointerTable12); int pointerTable21 = baPR2.Position; for (int i1 = 0; i1 < unitxt.SomeTables2[0].Count; i1++) { baPR2.Write(unitxt.SomeTables2[0][i1]); } int pointerTable22 = baPR2.Position; for (int i1 = 0; i1 < unitxt.SomeTables2[1].Count; i1++) { baPR2.Write(unitxt.SomeTables2[1][i1]); } int tableValuePointer = baPR2.Position; baPR2.Write(unitxt.tableValue); baPR2.Write(pointerTable21); baPR2.Write(pointerTable1); baPR2.Write(pointerTable22); // The rest int shipSelectPointer = 0; for (int i1 = 10; i1 < stringGroupCount - 2; i1++) { unitxt.StringGroups[i1].groupOffset = baPR2.Position; for (int i2 = 0; i2 < unitxt.StringGroups[i1].entries.Count; i2++) { if (i1 == 11 && i2 == 347) { shipSelectPointer = baPR2.Position; } baPR2.Write(stringAddresses[unitxt.StringGroups[i1].entries[i2]]); } } int groupsOffset = baPR2.Position; for (int i1 = 0; i1 < stringGroupCount - 2; i1++) { if (i1 == 12) { baPR2.Write(tableValuePointer); } baPR2.Write(unitxt.StringGroups[i1].groupOffset); } baPR2.Write(shipSelectPointer); baPR2.Resize(baPR2.Position); // Write Pr3 data baPR3.Write(0x20); baPR3.Write(pr3_pointersCount); baPR3.Write(1); baPR3.Write(0); baPR3.Write(groupsOffset); baPR3.Write(0); baPR3.Write(0); baPR3.Write(0); // Just fill this stuff for (int i1 = 0; i1 < 10; i1++) { for (int i2 = 0; i2 < unitxt.StringGroups[i1].entries.Count; i2++) { baPR3.Write((short)1); } } baPR3.Write((short)0x71); baPR3.Write((short)1); baPR3.Write((short)0x2A); baPR3.Write((short)1); baPR3.Write((short)1); for (int i1 = 10; i1 < stringGroupCount - 2; i1++) { for (int i2 = 0; i2 < unitxt.StringGroups[i1].entries.Count; i2++) { baPR3.Write((short)1); } } // Write this at the end because I am too lazy to do it properly baPR3.Write((short)(firstPointer / 4), 0x20); for (int i1 = 10; i1 < stringGroupCount; i1++) { baPR3.Write((short)1); } uint prc_key = (uint)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; byte[] dataPR2 = PSOCT.CompressPRC(baPR2.Buffer, prc_key, false); byte[] dataPR3 = PSOCT.CompressPRC(baPR3.Buffer, prc_key, false); File.WriteAllBytes(Path.ChangeExtension(filename, ".pr2"), dataPR2); File.WriteAllBytes(Path.ChangeExtension(filename, ".pr3"), dataPR3); }