internal GroupRecord(uint Size, BinaryReader br, bool Oblivion, string[] recFilter, bool filterAll) { Name = "GRUP"; data = br.ReadBytes(4); groupType = br.ReadUInt32(); dateStamp = br.ReadUInt32(); string contentType = groupType == 0 ? Encoding.CP1252.GetString(data) : ""; if (!Oblivion) { flags = br.ReadUInt32(); } uint amountRead = 0; while (amountRead < Size - (Oblivion ? 20 : 24)) { string s = ReadRecName(br); uint recsize = br.ReadUInt32(); if (s == "GRUP") { bool skip = filterAll || (recFilter != null && Array.IndexOf(recFilter, contentType) >= 0); var gr = new GroupRecord(recsize, br, Oblivion, recFilter, skip); amountRead += recsize; if (!filterAll) { AddRecord(gr); } } else { bool skip = filterAll || (recFilter != null && Array.IndexOf(recFilter, s) >= 0); if (skip) { long size = (recsize + (Oblivion ? 12 : 16)); //if ((br.ReadUInt32() & 0x00040000) > 0) size += 4; br.BaseStream.Position += size; // just read past the data amountRead += (uint)(recsize + (Oblivion ? 20 : 24)); } else { var r = new Record(s, recsize, br, Oblivion); amountRead += (uint)(recsize + (Oblivion ? 20 : 24)); AddRecord(r); } } } if (amountRead > (Size - (Oblivion ? 20 : 24))) { throw new TESParserException("Record block did not match the size specified in the group header"); } UpdateShortDescription(); }
public GroupEditor(GroupRecord gr) { this.gr = gr; InitializeComponent(); Icon = Resources.tesv_ico; cmbGroupType.ContextMenu = new ContextMenu(); cmbGroupType.SelectedIndex = (int) gr.groupType; tbRecType.Text = gr.ContentsType; byte[] data = gr.GetData(); tbX.Text = TypeConverter.h2ss(data[2], data[3]).ToString(); tbY.Text = TypeConverter.h2ss(data[0], data[1]).ToString(); tbBlock.Text = TypeConverter.h2i(data[0], data[1], data[2], data[3]).ToString(); tbParent.Text = TypeConverter.h2i(data[0], data[1], data[2], data[3]).ToString("X8"); tbDateStamp.Text = gr.dateStamp.ToString("X8"); tbFlags.Text = gr.flags.ToString("X8"); }
public GroupEditor(GroupRecord gr) { this.gr = gr; InitializeComponent(); Icon = Resources.tesv_ico; cmbGroupType.ContextMenu = new ContextMenu(); cmbGroupType.SelectedIndex = (int)gr.groupType; tbRecType.Text = gr.ContentsType; byte[] data = gr.GetData(); tbX.Text = TypeConverter.h2ss(data[2], data[3]).ToString(); tbY.Text = TypeConverter.h2ss(data[0], data[1]).ToString(); tbBlock.Text = TypeConverter.h2i(data[0], data[1], data[2], data[3]).ToString(); tbParent.Text = TypeConverter.h2i(data[0], data[1], data[2], data[3]).ToString("X8"); tbDateStamp.Text = gr.dateStamp.ToString("X8"); tbFlags.Text = gr.flags.ToString("X8"); }
private GroupRecord(GroupRecord gr, bool recursive) { Name = "GRUP"; data = (byte[])gr.data.Clone(); groupType = gr.groupType; dateStamp = gr.dateStamp; flags = gr.flags; if (recursive) { records = new List <Rec>(gr.records.Count); for (int i = 0; i < gr.records.Count; i++) { AddRecord(gr.records[i].Clone()); } } Name = gr.Name; UpdateShortDescription(); }
public bool IsEquivalent(GroupRecord other) { return(this.GroupType == other.GroupType && ByteArrayCompare(this.GetReadonlyData(), other.GetReadonlyData())); }
public bool IsEquivalent(GroupRecord other) { return this.GroupType == other.GroupType && ByteArrayCompare(this.GetReadonlyData(), other.GetReadonlyData()); }
private GroupRecord(GroupRecord gr, bool recursive) { Name = "GRUP"; data = (byte[]) gr.data.Clone(); groupType = gr.groupType; dateStamp = gr.dateStamp; flags = gr.flags; if (recursive) { records = new List<Rec>(gr.records.Count); for (int i = 0; i < gr.records.Count; i++) AddRecord(gr.records[i].Clone()); } Name = gr.Name; UpdateShortDescription(); }
internal GroupRecord(uint Size, BinaryReader br, bool Oblivion, string[] recFilter, bool filterAll) { Name = "GRUP"; data = br.ReadBytes(4); groupType = br.ReadUInt32(); dateStamp = br.ReadUInt32(); string contentType = groupType == 0 ? Encoding.CP1252.GetString(data) : ""; if (!Oblivion) flags = br.ReadUInt32(); uint amountRead = 0; while (amountRead < Size - (Oblivion ? 20 : 24)) { string s = ReadRecName(br); uint recsize = br.ReadUInt32(); if (s == "GRUP") { try { bool skip = filterAll || (recFilter != null && Array.IndexOf(recFilter, contentType) >= 0); var gr = new GroupRecord(recsize, br, Oblivion, recFilter, skip); if (!filterAll) AddRecord(gr); } catch (Exception e) { System.Windows.Forms.MessageBox.Show(e.Message); } finally { amountRead += recsize; } } else { bool skip = filterAll || (recFilter != null && Array.IndexOf(recFilter, s) >= 0); if (skip) { long size = (recsize + (Oblivion ? 12 : 16)); //if ((br.ReadUInt32() & 0x00040000) > 0) size += 4; br.BaseStream.Position += size; // just read past the data amountRead += (uint) (recsize + (Oblivion ? 20 : 24)); } else { try { var r = new Record(s, recsize, br, Oblivion); AddRecord(r); } catch (Exception e) { System.Windows.Forms.MessageBox.Show(e.Message); } finally { amountRead += (uint)(recsize + (Oblivion ? 20 : 24)); } } } } UpdateShortDescription(); if (amountRead != (Size - (Oblivion ? 20 : 24))) { throw new TESParserException(String.Format("Record block did not match the size specified in the group header! Header Size={0:D} Group Size={1:D}", Size - (Oblivion ? 20 : 24), amountRead)); } }
public static void SanitizePlugin(Plugin plugin) { // performance update to prevent lists from updating currently selected record bool oldHoldUpdates = BaseRecord.HoldUpdates; try { BaseRecord.HoldUpdates = true; if (plugin == null) { throw new ApplicationException("Cannot select plugin"); } var hdr = plugin.Records.OfType <Rec>().FirstOrDefault(x => x.Name == "TES4"); if (hdr == null) { throw new ApplicationException(Resources.PluginLacksAValidTes4RecordCannotContinue); } var toParse = new Queue <BaseRecord>(plugin.Records.OfType <BaseRecord>().Where(x => !x.Equals(hdr))); plugin.Clear(); plugin.AddRecord(hdr); var groups = new Dictionary <string, GroupRecord>(); foreach (string s in SanitizeOrder) { var gr = new GroupRecord(s); plugin.AddRecord(gr); groups[s] = gr; } bool looseGroupsWarning = false; bool unknownRecordsWarning = false; while (toParse.Count > 0) { var r = toParse.Dequeue(); if (r is GroupRecord) { var gr = (GroupRecord)r; if (gr.ContentsType == "CELL" || gr.ContentsType == "WRLD" || gr.ContentsType == "DIAL") { var gr2 = groups[gr.ContentsType]; foreach (BaseRecord r2 in gr.Records) { gr2.AddRecord(r2); } gr.Clear(); } else { foreach (BaseRecord r2 in gr.Records) { toParse.Enqueue(r2); } gr.Clear(); } } else if (r is Record) { var r2 = (Record)r; if (LooseGroups.Contains(r2.Name)) { looseGroupsWarning = true; plugin.AddRecord(r2); } else { if (groups.ContainsKey(r2.Name)) { groups[r2.Name].AddRecord(r2); } else { unknownRecordsWarning = true; plugin.AddRecord(r2); } } } } foreach (GroupRecord gr2 in groups.Values) { if (gr2.Records.Count == 0) { plugin.DeleteRecord(gr2); } } if (looseGroupsWarning) { MessageBox.Show(Resources.CannotSanitizeLooseGroups, Resources.WarningText); } if (unknownRecordsWarning) { MessageBox.Show(Resources.CannotSanitizeUnknownRecords, Resources.WarningText); } plugin.InvalidateCache(); int reccount = -1 + plugin.Records.Cast <Rec>().Sum(r => sanitizeCountRecords(r)); var tes4 = plugin.Records.OfType <Record>().FirstOrDefault(x => x.Name == "TES4"); if (tes4 != null) { if (tes4.SubRecords.Count > 0 && tes4.SubRecords[0].Name == "HEDR" && tes4.SubRecords[0].Size >= 8) { byte[] data = tes4.SubRecords[0].GetData(); byte[] reccountbytes = TypeConverter.si2h(reccount); for (int i = 0; i < 4; i++) { data[4 + i] = reccountbytes[i]; } tes4.SubRecords[0].SetData(data); } } } finally { BaseRecord.HoldUpdates = oldHoldUpdates; } }
public static int CopyRecordsTo(BaseRecord[] src, IGroupRecord dst) { int count = 0; if (src != null && dst != null) { if (dst is Plugin) { var dstRec = src.Where(x => !LooseGroups.Contains(x.Name)).Select(x => x.Clone()).ToArray(); if (dstRec.All(x => x is Record)) { // put records into appropriate groups var groups = dst.Records.OfType <GroupRecord>(); var lookup = dstRec.GroupBy(r => r.Name).Select(g => new { key = g.Key, value = g.ToArray() }) .ToLookup(k => k.key, v => v.value); foreach (var kvp in lookup) { if (LooseGroups.Contains(kvp.Key)) { dst.AddRecords(dstRec); } else { var gr = groups.FirstOrDefault(x => x.ContentsType == kvp.Key); if (gr == null) { gr = new GroupRecord(kvp.Key); dst.AddRecord(gr); } foreach (var list in kvp) { gr.AddRecords(list); } } } } else { dst.AddRecords(dstRec); } // handle loose groups by creating copy of parent groups foreach (var srcRec in src.Where(x => LooseGroups.Contains(x.Name))) { var dstnodes = new Stack <BaseRecord>(); dstnodes.Push(srcRec.Clone(recursive: true)); for (var n = srcRec.Parent; n is GroupRecord; n = n.Parent) { dstnodes.Push(n.Clone(recursive: false)); } var par = dst as IGroupRecord; foreach (var baseRecord in dstnodes) { if (par == null) { break; } if (baseRecord is GroupRecord) { var gr = baseRecord as GroupRecord; var pargr = par.Records.OfType <GroupRecord>().FirstOrDefault(x => x.IsEquivalent(gr)); if (pargr != null) { par = pargr; continue; } } par.AddRecord(baseRecord); par = baseRecord as IGroupRecord; } count += dstnodes.Count; } } else { var dstRec = src.Select(x => x.Clone()).ToArray(); dst.AddRecords(dstRec); count += dstRec.Count(); } } return(count); }
public static DialogResult Display(GroupRecord gr) { var ge = new GroupEditor(gr); return ge.ShowDialog(); }
public static DialogResult Display(GroupRecord gr) { var ge = new GroupEditor(gr); return(ge.ShowDialog()); }
public static void SanitizePlugin(Plugin plugin) { // performance update to prevent lists from updating currently selected record bool oldHoldUpdates = BaseRecord.HoldUpdates; try { BaseRecord.HoldUpdates = true; if (plugin == null) throw new ApplicationException("Cannot select plugin"); var hdr = plugin.Records.OfType<Rec>().FirstOrDefault(x => x.Name == "TES4"); if (hdr == null) { throw new ApplicationException(Resources.PluginLacksAValidTes4RecordCannotContinue); } var toParse = new Queue<BaseRecord>(plugin.Records.OfType<BaseRecord>().Where(x => !x.Equals(hdr))); plugin.Clear(); plugin.AddRecord(hdr); var groups = new Dictionary<string, GroupRecord>(); foreach (string s in SanitizeOrder) { var gr = new GroupRecord(s); plugin.AddRecord(gr); groups[s] = gr; } bool looseGroupsWarning = false; bool unknownRecordsWarning = false; while (toParse.Count > 0) { var r = toParse.Dequeue(); if (r is GroupRecord) { var gr = (GroupRecord)r; if (gr.ContentsType == "CELL" || gr.ContentsType == "WRLD" || gr.ContentsType == "DIAL") { var gr2 = groups[gr.ContentsType]; foreach (BaseRecord r2 in gr.Records) gr2.AddRecord(r2); gr.Clear(); } else { foreach (BaseRecord r2 in gr.Records) toParse.Enqueue(r2); gr.Clear(); } } else if (r is Record) { var r2 = (Record)r; if (LooseGroups.Contains(r2.Name)) { looseGroupsWarning = true; plugin.AddRecord(r2); } else { if (groups.ContainsKey(r2.Name)) groups[r2.Name].AddRecord(r2); else { unknownRecordsWarning = true; plugin.AddRecord(r2); } } } } foreach (GroupRecord gr2 in groups.Values) { if (gr2.Records.Count == 0) plugin.DeleteRecord(gr2); } if (looseGroupsWarning) { MessageBox.Show(Resources.CannotSanitizeLooseGroups, Resources.WarningText); } if (unknownRecordsWarning) { MessageBox.Show(Resources.CannotSanitizeUnknownRecords, Resources.WarningText); } plugin.InvalidateCache(); UpdateRecordCount(plugin); /* int reccount = -1 + plugin.Records.Cast<Rec>().Sum(r => sanitizeCountRecords(r)); var tes4 = plugin.Records.OfType<Record>().FirstOrDefault(x => x.Name == "TES4"); if (tes4 != null) { if (tes4.SubRecords.Count > 0 && tes4.SubRecords[0].Name == "HEDR" && tes4.SubRecords[0].Size >= 8) { byte[] data = tes4.SubRecords[0].GetData(); byte[] reccountbytes = TypeConverter.si2h(reccount); for (int i = 0; i < 4; i++) data[4 + i] = reccountbytes[i]; tes4.SubRecords[0].SetData(data); } } */ } finally { BaseRecord.HoldUpdates = oldHoldUpdates; } }
public static int CopyRecordsTo(BaseRecord[] src, IGroupRecord dst) { int count = 0; if (src != null && dst != null) { if (dst is Plugin) { var dstRec = src.Where(x => !LooseGroups.Contains(x.Name)).Select(x => x.Clone()).ToArray(); if (dstRec.All(x => x is Record)) { // put records into appropriate groups var groups = dst.Records.OfType<GroupRecord>(); var lookup = dstRec.GroupBy(r => r.Name).Select(g => new {key = g.Key, value = g.ToArray()}) .ToLookup(k => k.key, v => v.value); foreach (var kvp in lookup) { if (LooseGroups.Contains(kvp.Key)) { dst.AddRecords(dstRec); } else { var gr = groups.FirstOrDefault(x => x.ContentsType == kvp.Key); if (gr == null) { gr = new GroupRecord(kvp.Key); dst.AddRecord(gr); } foreach (var list in kvp) gr.AddRecords(list); } } } else { dst.AddRecords(dstRec); } // handle loose groups by creating copy of parent groups foreach (var srcRec in src.Where(x => LooseGroups.Contains(x.Name))) { var dstnodes = new Stack<BaseRecord>(); dstnodes.Push(srcRec.Clone(recursive: true)); for (var n = srcRec.Parent; n is GroupRecord; n = n.Parent) dstnodes.Push(n.Clone(recursive: false)); var par = dst as IGroupRecord; foreach (var baseRecord in dstnodes) { if (par == null) break; if (baseRecord is GroupRecord) { var gr = baseRecord as GroupRecord; var pargr = par.Records.OfType<GroupRecord>().FirstOrDefault(x => x.IsEquivalent(gr)); if (pargr != null) { par = pargr; continue; } } par.AddRecord(baseRecord); par = baseRecord as IGroupRecord; } count += dstnodes.Count; } } else { var dstRec = src.Select(x => x.Clone()).ToArray(); dst.AddRecords(dstRec); count += dstRec.Count(); } } return count; }