public async Task TestRecompression(int file) { var name = (AmxNames)file; var amxGarc = await Game.GetGarc(GarcNames.AmxFiles); if (file >= amxGarc.Garc.FileCount) { Assert.Inconclusive($"Nonexistent file: {file}"); } if (!Directory.Exists("Recompression")) { Directory.CreateDirectory("Recompression"); } var amxFile = await amxGarc.GetFile(file); var amx = new pkNX.Structures.Amx(amxFile); var origData = amx.Data; var decompressed = amx.DecompressedInstructions; var recompressed = PawnUtil.CompressScript(decompressed); var newData = amx.Data .Take(amx.Header.COD) .Concat(recompressed) .ToArray(); await File.WriteAllBytesAsync($"Recompression\\{name}_old.bin", origData); await File.WriteAllBytesAsync($"Recompression\\{name}_new.bin", newData); Assert.AreEqual(origData, newData, $"File {file} failed"); }
public async Task TestItemRandomizer() { var random = this.GetNewTaskRandom(); var itemNames = await Game.GetTextFile(TextNames.ItemNames); var amxGarc = await Game.GetGarc(GarcNames.AmxFiles, true); var fldItemFile = await amxGarc.GetFile((int)AmxNames.FldItem); var fldItemAmx = new pkNX.Structures.Amx(fldItemFile); var itemDataPayload = fldItemAmx.DataPayload.Skip(9).ToArray(); Assert.AreEqual(0, itemDataPayload.Length % 3, "Item data payload length incorrect"); var legalItems = Legal.Pouch_Items_XY .Concat(Legal.Pouch_Medicine_XY) .Concat(Legal.Pouch_TMHM_XY) .Concat(Legal.Pouch_Berry_XY) .ToList(); for (var i = 0; i < 206; i++) { var itemId = itemDataPayload[i * 3]; var quantity = itemDataPayload[i * 3 + 1]; var scriptId = itemDataPayload[i * 3 + 2]; var itemName = itemNames.Lines[(int)itemId]; var newItemId = legalItems.GetRandom(random); var newItemName = itemNames.Lines[newItemId]; TestContext.Progress.WriteLine($"Script {scriptId:X4} has item {itemName} x{quantity}, changing to {newItemName}"); itemDataPayload[i * 3] = newItemId; } var dataStart = fldItemAmx.CodeLength / sizeof(uint); var instructions = fldItemAmx.DecompressedInstructions // Original code .Take(dataStart) // Original data header .Concat(fldItemAmx.DataPayload.Take(9)) // Our own data payload .Concat(itemDataPayload) .ToArray(); var newCompressedBytes = PawnUtil.CompressScript(instructions); var newData = fldItemAmx.Data.Take(fldItemAmx.Header.COD).Concat(newCompressedBytes).ToArray(); // Write new size BitConverter.GetBytes(newData.Length).CopyTo(newData, 0); File.WriteAllBytes("old.bin", fldItemAmx.Data); File.WriteAllBytes("new.bin", newData); await amxGarc.SetFile((int)AmxNames.FldItem, newData); await Game.SaveFile(amxGarc); }
public void TestAlgorithm() { //var bytes = new byte[] { 0x8E, 0xA5, 0xA0, 0x81, 0x45 }; //var bytes = new byte[] { 0xF4, 0x40 }; var bytes = new byte[] { 0x8F, 0xA2, 0xA0, 0x81, 0x45 }; var value = PawnUtil.QuickDecompress2(bytes, 1)[0]; var bytes2 = PawnUtil.CompressScript(new[] { value }); TestContext.Progress.WriteLine(string.Join(" ", bytes.Select(b => $"{b:X2}"))); TestContext.Progress.WriteLine(value.ToString("X8")); TestContext.Progress.WriteLine(string.Join(" ", bytes2.Select(b => $"{b:X2}"))); Assert.AreEqual(bytes, bytes2); }
public byte[] Write() { var dataStart = this.amx.CodeLength / sizeof(uint); var newItemData = this.Items.SelectMany(item => new[] { item.ItemId, item.Unused1, item.ScriptIdOffset, }).ToArray(); var originalItemData = this.ItemData; var newDataPayload = this.amx.DataPayload // Original 9 data values before item data .Take(DataPayloadOffsets[this.gameVersion]) // Plus our new item data .Concat(newItemData) // Plus the "unused slots" from the original file .Concat(originalItemData.Skip(newItemData.Length)); var newInstructions = this.amx.DecompressedInstructions // Original instructions before the data payload .Take(dataStart) // Our new data payload from above .Concat(newDataPayload) .ToArray(); var newInstructionData = PawnUtil.CompressScript(newInstructions); var newData = this.amx.Data // Original file contents before Code section .Take(this.amx.Header.COD) // New compressed code/data from above .Concat(newInstructionData) .ToArray(); // Write new size to the header BitConverter.GetBytes(newData.Length).CopyTo(newData, 0); return(newData); }