public override void OnRebuild(VoidPtr address, int length, bool force) { // Update base address for children. BaseAddress = (VoidPtr)address + sizeof(Common2TblHeader); // Initiate header struct Common2TblHeader *Header = (Common2TblHeader *)address; *Header = new Common2TblHeader(); Header->_OffCount = _offCount; Header->_DataTable = Children.Count; Header->_pad0 = Header->_pad1 = Header->_pad2 = Header->_pad3 = 0; Dictionary <ResourceNode, VoidPtr> dataLocations = new Dictionary <ResourceNode, VoidPtr>(); VoidPtr ptr = BaseAddress; foreach (var child in Children) { int size = child.CalculateSize(false); dataLocations.Add(child, ptr); child.Rebuild(ptr, size, false); ptr += size; } Header->_DataLength = (int)(ptr - BaseAddress); bint *dataPointers = (bint *)ptr; bint *stringPointers = dataPointers + 1; byte *strings = (byte *)(dataPointers + Children.Count + Children.Count); byte *currentString = strings; foreach (var child in Children) { *dataPointers = (int)(dataLocations[child] - BaseAddress); dataPointers += 2; *stringPointers = (int)(currentString - strings); stringPointers += 2; byte[] text = Encoding.UTF8.GetBytes(child.Name); fixed(byte *from = text) { Memory.Move(currentString, from, (uint)text.Length); currentString += text.Length; *currentString = 0; currentString++; } } Header->_Length = (int)(currentString - address); if (Header->_Length != length) { throw new Exception("Wrong amount of memory allocated for rebuild of common2 data"); } }
public override void OnRebuild(VoidPtr address, int length, bool force) { // Update base address for children. VoidPtr baseAddress = address + sizeof(Common2TblHeader); // Initiate header struct Common2TblHeader *Header = (Common2TblHeader *)address; *Header = new Common2TblHeader(); Header->_OffCount = _offCount; Header->_DataTable = Children.Count; Header->_pad0 = Header->_pad1 = Header->_pad2 = Header->_pad3 = 0; Dictionary <ResourceNode, VoidPtr> dataLocations = new Dictionary <ResourceNode, VoidPtr>(); VoidPtr ptr = baseAddress; foreach (ResourceNode child in Children) { int size = child.CalculateSize(false); dataLocations.Add(child, ptr); if (child is ClassicStageTblSizeTblNode && size == 48) { // Rebuild Dictionary <string, int> sizes = Children.ToDictionary(c => c.Name, c => { int fullSize = c.CalculateSize(false); int paddingInts = (c as ClassicStageTblNode)?.Padding?.Length ?? 0; return(fullSize - sizeof(bint) * paddingInts); }); bint[] newTbl = new bint[12]; fixed(bint *newTblPtr = newTbl) { foreach (string key in new[] { "simpleStageB1Tbl", "simpleStageB2Tbl", "simpleStage11Tbl" }) { if (!sizes.TryGetValue(key, out int s) || s != 0x104) { MessageBox.Show( $"Changing the size of {key} may not work properly (BrawlCrate doesn't know yet which size entry to update)"); } } bint *bptr = newTblPtr; foreach (string key in new[] { "simpleStage1Tbl", "simpleStage2Tbl", "simpleStage3Tbl", "simpleStage4Tbl", "simpleStageB1Tbl", "simpleStage5Tbl", "simpleStage6Tbl", "simpleStage7Tbl", "simpleStage8Tbl", "simpleStage9Tbl", "simpleStage10Tbl", "simpleStageB2Tbl" }) { if (sizes.TryGetValue(key, out int s)) { *bptr = s; } else { MessageBox.Show($"Cannot get size of {key}"); } bptr++; } child.ReplaceRaw(newTblPtr, 48); } } child.Rebuild(ptr, size, false); ptr += size; } Header->_DataLength = ptr - baseAddress; bint *dataPointers = (bint *)ptr; bint *stringPointers = dataPointers + 1; byte *strings = (byte *)(dataPointers + Children.Count + Children.Count); byte *currentString = strings; List <ResourceNode> childrenAlphabetical = Children.OrderBy(o => o.Name).ToList(); foreach (ResourceNode child in childrenAlphabetical) { *dataPointers = dataLocations[child] - baseAddress; dataPointers += 2; *stringPointers = (int)(currentString - strings); stringPointers += 2; byte[] text = Encoding.UTF8.GetBytes(child.Name); fixed(byte *from = text) { Memory.Move(currentString, from, (uint)text.Length); currentString += text.Length; *currentString = 0; currentString++; } } if (currentString - address > length) { throw new Exception($"Wrong amount of memory allocated for rebuild of common2 data (Expected: {currentString - address} | Actual: {length})"); } Header->_Length = length; }