/// <summary> /// Gets the well-known MESG record's subrecord data containg the critical record info. /// </summary> /// <remarks> /// If the required record is not found, it is created. /// </remarks> /// <returns>The well-known MESG record's subrecord data containg the critical record info.</returns> protected SubRecord getCriticalRecordData() { GroupRecord grcGroup = null; Record recCriticalRecords = null; SubRecord srcCriticalData = null; foreach (var rec in Records) { grcGroup = rec as GroupRecord; if (grcGroup == null) { continue; } if (grcGroup.ContentsType == "MESG") { foreach (Record recRecord in grcGroup.Records) { foreach (var srcSubRecord in recRecord.SubRecords) { switch (srcSubRecord.Name) { case "EDID": if (srcSubRecord.GetStrData().Equals(CRITICAL_DATA_RECORD_EDID)) { recCriticalRecords = recRecord; } break; case "DESC": srcCriticalData = srcSubRecord; break; } } if (recCriticalRecords != null) { return srcCriticalData; } } } } //if there is no MESG group, create one if (grcGroup == null) { grcGroup = new GroupRecord("MESG"); AddRecord(grcGroup); } //if there is no fommCriticalRecords record, create one, we returned otherwise. recCriticalRecords = new Record(); recCriticalRecords.Name = "MESG"; var uintMastersCount = (UInt32) Masters.Count << 24; var uintFormId = uintMastersCount + 1; while (ContainsFormId(uintFormId)) { uintFormId++; } if ((uintFormId & 0xff000000) != uintMastersCount) { throw new PluginFullException("No available Form Id for new MESG record"); } recCriticalRecords.FormID = uintFormId; recCriticalRecords.Flags2 = 0x00044210; recCriticalRecords.Flags3 = 0x0002000f; var srcSub = new SubRecord(); srcSub.Name = "EDID"; srcSub.SetStrData(CRITICAL_DATA_RECORD_EDID, true); recCriticalRecords.SubRecords.Add(srcSub); srcCriticalData = new SubRecord(); srcCriticalData.Name = "DESC"; recCriticalRecords.SubRecords.Add(srcCriticalData); srcSub = new SubRecord(); srcSub.Name = "INAM"; srcSub.SetData(new byte[] { 0, 0, 0, 0 }); recCriticalRecords.SubRecords.Add(srcSub); srcSub = new SubRecord(); srcSub.Name = "DNAM"; srcSub.SetData(new byte[] { 0, 0, 0, 0 }); recCriticalRecords.SubRecords.Add(srcSub); srcSub = new SubRecord(); srcSub.Name = "TNAM"; srcSub.SetData(new byte[] { 0, 0, 0, 1 }); recCriticalRecords.SubRecords.Add(srcSub); grcGroup.AddRecord(recCriticalRecords); return srcCriticalData; }
public static bool Compile(Record r2, out string msg) { msg=null; r=new Record(); string script=null; int scptype=0; foreach(SubRecord sr2 in r2.SubRecords) { if(sr2.Name=="SCTX") script=sr2.GetStrData(); if(sr2.Name=="SCHR") { byte[] tmp=sr2.GetReadonlyData(); scptype=TypeConverter.h2si(tmp[16], tmp[17], tmp[18], tmp[19]); } } if(script==null) { msg="Script had no SCTX record to compile"; return false; } locals.Clear(); localList.Clear(); edidRefs.Clear(); refcount=0; errors.Clear(); ts=new TokenStream(script, errors); if(errors.Count>0) return OutputErrors( out msg); Token[] smt=ts.PopNextStatement(); if(smt.Length!=2||!smt[0].IsKeyword(Keywords.ScriptName)||smt[1].token==null) return ReturnError("Expected 'ScriptName <edid>'", out msg); SubRecord sr=new SubRecord(); sr.Name="EDID"; sr.SetStrData(smt[1].utoken, true); r.AddRecord(sr); r.descriptiveName=" ("+smt[1].token+")"; schr=new SubRecord(); schr.Name="SCHR"; r.AddRecord(schr); scda=new SubRecord(); scda.Name="SCDA"; r.AddRecord(scda); sr=new SubRecord(); sr.Name="SCTX"; sr.SetStrData(script, false); r.AddRecord(sr); bw=new BinaryWriter(new MemoryStream()); Emit(0x001d); Emit(0x0000); try { HandleVariables(); } catch(Exception ex) { return ReturnError(ex.Message, out msg); } for(int i=0;i<localList.Count;i++) { if(localList[i].type==VarType.Ref) { sr=new SubRecord(); sr.Name="SCRV"; sr.SetData(TypeConverter.si2h(i+1)); r.AddRecord(sr); refcount++; localList[i].refid=refcount; } } while(ts.PeekNextStatement().Length>0) { try { HandleBlock(); } catch(Exception ex) { return ReturnError(ex.Message, out msg); } } if(errors.Count>0) { return OutputErrors(out msg); } byte[] header=new byte[20]; TypeConverter.si2h(refcount, header, 4); TypeConverter.i2h((uint)bw.BaseStream.Length, header, 8); TypeConverter.si2h(localList.Count, header, 12); TypeConverter.si2h(scptype, header, 16); schr.SetData(header); byte[] compileddata=((MemoryStream)bw.BaseStream).GetBuffer(); if(compileddata.Length!=bw.BaseStream.Length) Array.Resize<byte>(ref compileddata, (int)bw.BaseStream.Length); scda.SetData(compileddata); r2.SubRecords.Clear(); r2.SubRecords.AddRange(r.SubRecords); bw.Close(); return true; }
private static void EmitRefLabel(Token t, RefType type) { if(t.type==TokenType.Global) { EmitByte(0x47); } else { switch(type) { case RefType.Standard: Emit(0x1c); break; case RefType.Expression: EmitByte(0x72); break; case RefType.Standalone: EmitByte(0x5a); break; } } if(t.type==TokenType.Local) { LocalVar var=locals[t.token]; if(var.refid==0) AddError("Variable was not of type ref"); else Emit((ushort)var.refid); } else if(t.type==TokenType.edid||t.type==TokenType.Global) { if(!edidRefs.ContainsKey(t.token)) { SubRecord sr=new SubRecord(); sr.Name="SCRO"; if(t.type==TokenType.edid) sr.SetData(TypeConverter.i2h(edidList[t.token].Key)); else sr.SetData(TypeConverter.i2h(globals[t.token])); r.AddRecord(sr); refcount++; edidRefs[t.token]=(ushort)refcount; } Emit(edidRefs[t.token]); } else { AddError("Expected ref variable or edid"); } }
public static bool CompileResultScript(SubRecord sr, out Record r2, out string msg) { msg=null; r2=null; r=new Record(); string script=sr.GetStrData(); locals.Clear(); localList.Clear(); edidRefs.Clear(); refcount=0; errors.Clear(); ts=new TokenStream(script, errors); if(errors.Count>0) return OutputErrors(out msg); schr=new SubRecord(); schr.Name="SCHR"; r.AddRecord(schr); scda=new SubRecord(); scda.Name="SCDA"; r.AddRecord(scda); sr=(SubRecord)sr.Clone(); r.AddRecord(sr); bw=new BinaryWriter(new MemoryStream()); while(ts.PeekNextStatement().Length>0) { try { HandleResultsBlock(); } catch(Exception ex) { return ReturnError(ex.Message, out msg); } } if(errors.Count>0) { return OutputErrors(out msg); } byte[] header=new byte[20]; TypeConverter.si2h(refcount, header, 4); TypeConverter.i2h((uint)bw.BaseStream.Length, header, 8); TypeConverter.si2h(localList.Count, header, 12); TypeConverter.si2h(0x10000, header, 16); schr.SetData(header); byte[] compileddata=((MemoryStream)bw.BaseStream).GetBuffer(); if(compileddata.Length!=bw.BaseStream.Length) Array.Resize<byte>(ref compileddata, (int)bw.BaseStream.Length); scda.SetData(compileddata); bw.Close(); r2=r; return true; }
private static void HandleVariables() { Token[] smt=ts.PeekNextStatement(); SubRecord slsd; SubRecord scvr; while(smt.Length>0&&smt[0].IsType()) { ts.PopNextStatement(); if(smt.Length!=2||smt[1].type!=TokenType.Unknown) { AddError("Expected <type> <variable name>"); smt=ts.PeekNextStatement(); continue; } slsd=new SubRecord(); slsd.Name="SLSD"; byte[] data=new byte[24]; TypeConverter.si2h(locals.Count+1, data, 0); if(smt[0].IsKeyword(Keywords.Int)) data[16]=1; slsd.SetData(data); r.AddRecord(slsd); scvr=new SubRecord(); scvr.Name="SCVR"; scvr.SetStrData(smt[1].utoken, true); r.AddRecord(scvr); LocalVar lv=new LocalVar(locals.Count+1, smt[0]); locals.Add(smt[1].token, lv); localList.Add(lv); ts.AddLocal(smt[1].token); smt=ts.PeekNextStatement(); } }
private void newToolStripMenuItem_Click(object sender, EventArgs e) { if (searchForm != null && searchForm.InSearch) { MessageBox.Show("Cannot modify contents while searching", "Error"); return; } var p = new Plugin(); var r = new Record(); r.Name = "TES4"; var sr = new SubRecord(); sr.Name = "HEDR"; sr.SetData(new byte[] { 0xD7, 0xA3, 0x70, 0x3F, 0xFA, 0x56, 0x0C, 0x00, 0x19, 0xEA, 0x07, 0xFF }); r.AddRecord(sr); sr = new SubRecord(); sr.Name = "CNAM"; sr.SetData(Encoding.ASCII.GetBytes("Default\0")); r.AddRecord(sr); p.AddRecord(r); var tn = new TreeNode(p.Name); tn.Tag = p; var tn2 = new TreeNode(r.DescriptiveName); tn2.Tag = r; tn.Nodes.Add(tn2); PluginTree.Nodes.Add(tn); }
private void addMasterToolStripMenuItem_Click(object sender, EventArgs e) { if (searchForm != null && searchForm.InSearch) { MessageBox.Show("Cannot modify contents while searching", "Error"); return; } var amfNewMaster = new AddMasterForm(); if (amfNewMaster.ShowDialog() == DialogResult.OK) { //find the root node for the current plugin var tndRoot = PluginTree.SelectedNode; if (tndRoot == null) { MessageBox.Show(this, "No plugin selected. Cannot continue.", "Missing Plugin", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } while (tndRoot.Parent != null) { tndRoot = tndRoot.Parent; } BaseRecord brcTES4 = null; foreach (TreeNode tndRecord in tndRoot.Nodes) { brcTES4 = (BaseRecord) tndRecord.Tag; if (brcTES4.Name.Equals("TES4")) { break; } brcTES4 = null; } if (brcTES4 == null) { MessageBox.Show(this, "Plugin lacks a vlid TES4 record. Cannot continue.", "Missing Record", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var sbrMaster = new SubRecord(); sbrMaster.Name = "MAST"; var intCount = Encoding.UTF8.GetByteCount(amfNewMaster.MasterName); var bteData = new byte[intCount + 1]; Array.Copy(Encoding.UTF8.GetBytes(amfNewMaster.MasterName), bteData, intCount); sbrMaster.SetData(bteData); brcTES4.AddRecord(sbrMaster); sbrMaster = new SubRecord(); sbrMaster.Name = "DATA"; sbrMaster.SetData(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }); brcTES4.AddRecord(sbrMaster); PluginTree_AfterSelect(null, null); } }
private void bSave_Click(object sender, EventArgs e) { var bytes = new List <byte>(); for (var j = 0; j < boxes.Count; j++) { if (!boxes[j].Enabled) { continue; } switch (valueTypes[j]) { case ElementValueType.Byte: { byte b; if (!byte.TryParse(boxes[j].Text, out b)) { MessageBox.Show("Invalid byte: " + boxes[j].Text, "Error"); return; } bytes.Add(b); break; } case ElementValueType.Short: { short s; if (!short.TryParse(boxes[j].Text, out s)) { MessageBox.Show("Invalid short: " + boxes[j].Text, "Error"); return; } var conv = TypeConverter.ss2h(s); bytes.Add(conv[0]); bytes.Add(conv[1]); break; } case ElementValueType.Int: { int i; if (!int.TryParse(boxes[j].Text, out i)) { MessageBox.Show("Invalid int: " + boxes[j].Text, "Error"); return; } var conv = TypeConverter.si2h(i); bytes.AddRange(conv); break; } case ElementValueType.Float: { float f; if (!float.TryParse(boxes[j].Text, out f)) { MessageBox.Show("Invalid float: " + boxes[j].Text, "Error"); return; } var conv = TypeConverter.f2h(f); bytes.AddRange(conv); break; } case ElementValueType.FormID: { uint i; if (!uint.TryParse(boxes[j].Text, NumberStyles.AllowHexSpecifier, null, out i)) { MessageBox.Show("Invalid formID: " + boxes[j].Text, "Error"); return; } var conv = TypeConverter.i2h(i); bytes.AddRange(conv); break; } case ElementValueType.String: { var conv = Encoding.Default.GetBytes(boxes[j].Text); bytes.AddRange(conv); bytes.Add(0); break; } case ElementValueType.fstring: { var conv = Encoding.Default.GetBytes(boxes[j].Text); bytes.AddRange(conv); break; } default: throw new ApplicationException(); } } sr.SetData(bytes.ToArray()); Close(); }