diff --git a/plugins/BinLogReader/BinLog.cs b/plugins/BinLogReader/BinLog.cs index f51cc891..e97bd83f 100644 --- a/plugins/BinLogReader/BinLog.cs +++ b/plugins/BinLogReader/BinLog.cs @@ -1,5 +1,7 @@ using System; using System.IO; +using System.Text; +using System.Collections; namespace BinLogReader { @@ -8,10 +10,25 @@ namespace BinLogReader /// public class BinLog { - private static uint BINLOG_MAGIC = 0x414D424C + private static uint BINLOG_MAGIC = 0x414D424C; private static short BINLOG_VERSION = 0x0100; - public static BinLog FromFile(string filename) + private ArrayList oplist; + + public ArrayList OpList + { + get + { + return oplist; + } + } + + BinLog(int init_size) + { + oplist = new ArrayList(init_size); + } + + public static BinLog FromFile(string filename, PluginDb db) { if (!File.Exists(filename)) return null; @@ -23,11 +40,219 @@ public static BinLog FromFile(string filename) if (br == null) return null; + BinLog bl = null; + BinLogOp opcode = BinLogOp.BinLog_Invalid; + long realtime = 0; + float gametime = 0.0f; + int plug_id = -1; + Plugin pl = null; + try { + uint magic = br.ReadUInt32(); + if (magic != BINLOG_MAGIC) + throw new Exception("Invalid magic log number"); + + ushort version = br.ReadUInt16(); + if (version > BINLOG_VERSION) + throw new Exception("Unknown log version number"); + + byte timesize = br.ReadByte(); + + bool bits64 = (timesize == 8) ? true : false; + + FileInfo fi = new FileInfo(filename); + //guestimate required size + if (fi.Length > 500) + bl = new BinLog( (int)((fi.Length - 500) / 6) ); + else + bl = new BinLog( (int)(fi.Length / 6) ); + + do + { + opcode = (BinLogOp)br.ReadByte(); + gametime = br.ReadSingle(); + if (bits64) + realtime = br.ReadInt64(); + else + realtime = (long)br.ReadInt32(); + plug_id = br.ReadInt32(); + pl = db.GetPluginById(plug_id); + switch (opcode) + { + case BinLogOp.BinLog_SetString: + { + long addr; + if (bits64) + addr = br.ReadInt64(); + else + addr = (long)br.ReadInt32(); + int maxlen = br.ReadInt32(); + ushort len = br.ReadUInt16(); + byte [] str = br.ReadBytes(len+1); + string text = Encoding.ASCII.GetString(str, 0, len); + BinLogSetString bgs = + new BinLogSetString(addr, maxlen, text, gametime, realtime, pl); + bl.OpList.Add(bgs); + break; + } + case BinLogOp.BinLog_GetString: + { + long addr; + if (bits64) + addr = br.ReadInt64(); + else + addr = (long)br.ReadInt32(); + ushort len = br.ReadUInt16(); + byte [] str = br.ReadBytes(len+1); + string text = Encoding.ASCII.GetString(str, 0, len); + BinLogGetString bgs = + new BinLogGetString(addr, text, gametime, realtime, pl); + bl.OpList.Add(bgs); + break; + } + case BinLogOp.BinLog_NativeParams: + { + ArrayList parms; + if (bits64) + { + long num = br.ReadInt64(); + long p; + Int64 i64; + parms = new ArrayList((int)num); + for (int i=0; i<(int)num; i++) + { + p = br.ReadInt64(); + i64 = new Int64(); + i64 = p; + parms.Add(i64); + } + } + else + { + int num = br.ReadInt32(); + int p; + Int32 i32; + parms = new ArrayList(num); + for (int i=0; i + BinLog_NativeError, + BinLog_NativeRet, + BinLog_CallPubFunc, // + BinLog_SetLine, // + BinLog_Registered, // + BinLog_FormatString, + BinLog_NativeParams, + BinLog_GetString, + BinLog_SetString, + }; + + public enum BinLogFlags + { + Show_RealTime = (1<<0), + Show_GameTime = (1<<1), + Show_PlugId = (1<<2), + Show_PlugFile = (1<<3), + }; + + public abstract class BinLogEntry + { + protected float GameTime; + protected long RealTime; + protected Plugin pl; + + protected BinLogEntry(float gt, long rt, Plugin _pl) + { + GameTime = gt; + RealTime = rt; + pl = _pl; + } + + public static bool HasFlag(BinLogFlags a, BinLogFlags b) + { + return ( (a & b) == b ); + } + + public static string PluginText(Plugin pl, BinLogFlags flags) + { + string plugintext = ""; + if (HasFlag(flags, BinLogFlags.Show_PlugId) + && HasFlag(flags, BinLogFlags.Show_PlugFile)) + { + plugintext = "\"" + pl.File + "\"" + " (" + pl.Index + ")"; + } + else if (HasFlag(flags, BinLogFlags.Show_PlugId)) + { + plugintext = pl.Index.ToString(); + } + else if (HasFlag(flags, BinLogFlags.Show_PlugFile)) + { + plugintext = "\"" + pl.File + "\""; + } + return plugintext; + } + + public static string BinLogString(BinLogEntry ble, BinLogFlags flags) + { + string logtext = ""; + if (HasFlag(flags, BinLogFlags.Show_RealTime)) + logtext += ble.realtime.ToString(); + if (HasFlag(flags, BinLogFlags.Show_GameTime)) + { + if (logtext.Length > 0) + { + logtext += ", " + ble.gametime.ToString(); + } + else + { + logtext += ble.gametime.ToString(); + } + } + logtext += ": "; + logtext += ble.ToLogString(flags); + + return logtext; + } + + public float gametime + { + [DebuggerStepThrough] + get + { + return GameTime; + } + } + + public Plugin plugin + { + [DebuggerStepThrough] + get + { + return pl; + } + } + + public long realtime + { + [DebuggerStepThrough] + get + { + return RealTime; + } + } + + public abstract BinLogOp Op(); + public abstract string ToLogString(BinLogFlags flags); + }; + + public class BinLogSetLine : BinLogEntry + { + private int line; + + public int Line + { + get + { + return line; + } + } + + public BinLogSetLine(int _line, float gt, long rt, Plugin _pl) + : base(gt, rt, _pl) + { + line = _line; + } + + public override string ToLogString(BinLogFlags flags) + { + string plugtext = BinLogEntry.PluginText(plugin, flags); + string logtext = "Plugin hit line " + Line + "."; + + return logtext; + } + + public override BinLogOp Op() + { + return BinLogOp.BinLog_SetLine; + } + } + + public class BinLogPublic : BinLogEntry + { + private int pubidx; + + public string Public + { + get + { + return plugin.FindPublic(pubidx); + } + } + + public BinLogPublic(int pi, float gt, long rt, Plugin _pl) + : base(gt, rt, _pl) + { + pubidx = pi; + } + + public override string ToLogString(BinLogFlags flags) + { + string plugtext = BinLogEntry.PluginText(plugin, flags); + string logtext = "Plugin " + plugtext + " had public function "; + logtext += "\"" + Public + "\" (" + pubidx + ") called."; + + return logtext; + } + + public override BinLogOp Op() + { + return BinLogOp.BinLog_CallPubFunc; + } + } + + public class BinLogSetString : BinLogEntry + { + private long address; + private int maxlen; + private string text; + + public BinLogSetString(long addr, int _maxlen, string fmt, float gt, long rt, Plugin _pl) + : base(gt, rt, _pl) + { + address = addr; + maxlen = _maxlen; + text = fmt; + } + + public override string ToLogString(BinLogFlags flags) + { + string plugtext = BinLogEntry.PluginText(plugin, flags); + string logtext = "Setting string (addr " + address + ") (maxlen " + maxlen + ") from Plugin " + plugtext + ". String:"; + logtext += "\n\t " + text; + + return logtext; + } + + public override BinLogOp Op() + { + return BinLogOp.BinLog_GetString; + } + } + + public class BinLogGetString : BinLogEntry + { + private long address; + private string text; + + public BinLogGetString(long addr, string fmt, float gt, long rt, Plugin _pl) + : base(gt, rt, _pl) + { + address = addr; + text = fmt; + } + + public override string ToLogString(BinLogFlags flags) + { + string plugtext = BinLogEntry.PluginText(plugin, flags); + string logtext = "Retrieving string (addr " + address + ") from Plugin " + plugtext + ". String:"; + logtext += "\n\t " + text; + + return logtext; + } + + public override BinLogOp Op() + { + return BinLogOp.BinLog_GetString; + } + } + + public class BinLogNativeRet : BinLogEntry + { + private long returnval; + + public BinLogNativeRet(long ret, float gt, long rt, Plugin _pl) + : base(gt, rt, _pl) + { + returnval = ret; + } + + public override string ToLogString(BinLogFlags flags) + { + return "Native returned: " + returnval; + } + + public override BinLogOp Op() + { + return BinLogOp.BinLog_NativeRet; + } + } + + public class BinLogNativeCall : BinLogEntry + { + private int nativeidx; + private int numparams; + + public string Native + { + get + { + return plugin.FindNative(nativeidx); + } + } + + public BinLogNativeCall(int na, int nu, float gt, long rt, Plugin _pl) + : base(gt, rt, _pl) + { + nativeidx = na; + numparams = nu; + } + + public override string ToLogString(BinLogFlags flags) + { + string plugtext = BinLogEntry.PluginText(plugin, flags); + string logtext = "Plugin " + plugtext + " called native "; + logtext += "\"" + Native + "\" (" + nativeidx + ")"; + logtext += " with " + numparams + " parameters."; + + return logtext; + } + + public override BinLogOp Op() + { + return BinLogOp.BinLog_NativeCall; + } + } + + public class BinLogSimple : BinLogEntry + { + private BinLogOp my_op; + public BinLogSimple(BinLogOp op, float gt, long rt, Plugin _pl) : + base(gt, rt, _pl) + { + my_op = op; + } + + public override string ToLogString(BinLogFlags flags) + { + switch (my_op) + { + case BinLogOp.BinLog_Start: + { + return "Binary log started."; + } + case BinLogOp.BinLog_End: + { + return "Binary log ended."; + } + case BinLogOp.BinLog_Invalid: + { + return "Binary log corrupt past this point."; + } + } + + return ""; + } + + public override BinLogOp Op() + { + return my_op; + } + } + + public class BinLogNativeParams : BinLogEntry + { + private ArrayList plist; + + public ArrayList ParamList + { + get + { + return plist; + } + set + { + plist = value; + } + } + + public override BinLogOp Op() + { + return BinLogOp.BinLog_NativeParams; + } + + public BinLogNativeParams(float gt, long rt, Plugin _pl) + : base(gt, rt, _pl) + { + } + + public override string ToLogString(BinLogFlags flags) + { + string logtext = "Native parameters: ("; + if (plist != null) + { + for (int i=0; i @@ -99,6 +99,7 @@ /> + /// Required designer variable. /// @@ -51,6 +60,9 @@ protected override void Dispose( bool disposing ) base.Dispose( disposing ); } + private PluginDb plugdb; + private BinLog binlog; + #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify @@ -60,11 +72,23 @@ private void InitializeComponent() { this.mainMenu1 = new System.Windows.Forms.MainMenu(); this.menuItem1 = new System.Windows.Forms.MenuItem(); - this.menuItem2 = new System.Windows.Forms.MenuItem(); + this.MenuFileOpen = new System.Windows.Forms.MenuItem(); this.menuItem3 = new System.Windows.Forms.MenuItem(); this.menuItem4 = new System.Windows.Forms.MenuItem(); this.menuItem5 = new System.Windows.Forms.MenuItem(); this.menuItem6 = new System.Windows.Forms.MenuItem(); + this.ofd = new System.Windows.Forms.OpenFileDialog(); + this.MainTab = new System.Windows.Forms.TabControl(); + this.PluginsTab = new System.Windows.Forms.TabPage(); + this.PluginList = new System.Windows.Forms.ListView(); + this.LogTextTab = new System.Windows.Forms.TabPage(); + this.TextLog = new System.Windows.Forms.RichTextBox(); + this.LogListTab = new System.Windows.Forms.TabPage(); + this.ViewTab = new System.Windows.Forms.TabPage(); + this.MainTab.SuspendLayout(); + this.PluginsTab.SuspendLayout(); + this.LogTextTab.SuspendLayout(); + this.SuspendLayout(); // // mainMenu1 // @@ -76,15 +100,16 @@ private void InitializeComponent() // this.menuItem1.Index = 0; this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { - this.menuItem2, + this.MenuFileOpen, this.menuItem3, this.menuItem4}); this.menuItem1.Text = "&File"; // - // menuItem2 + // MenuFileOpen // - this.menuItem2.Index = 0; - this.menuItem2.Text = "&Open"; + this.MenuFileOpen.Index = 0; + this.MenuFileOpen.Text = "&Open"; + this.MenuFileOpen.Click += new System.EventHandler(this.MenuFileOpen_Click); // // menuItem3 // @@ -109,18 +134,110 @@ private void InitializeComponent() this.menuItem6.Index = 0; this.menuItem6.Text = "&About"; // + // ofd + // + this.ofd.Filter = "Binary Log Files|*.blg"; + // + // MainTab + // + this.MainTab.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.MainTab.Controls.Add(this.PluginsTab); + this.MainTab.Controls.Add(this.LogTextTab); + this.MainTab.Controls.Add(this.LogListTab); + this.MainTab.Controls.Add(this.ViewTab); + this.MainTab.Location = new System.Drawing.Point(8, 12); + this.MainTab.Name = "MainTab"; + this.MainTab.SelectedIndex = 0; + this.MainTab.Size = new System.Drawing.Size(656, 372); + this.MainTab.TabIndex = 0; + this.MainTab.SelectedIndexChanged += new System.EventHandler(this.MainTab_SelectedIndexChanged); + // + // PluginsTab + // + this.PluginsTab.Controls.Add(this.PluginList); + this.PluginsTab.Location = new System.Drawing.Point(4, 22); + this.PluginsTab.Name = "PluginsTab"; + this.PluginsTab.Size = new System.Drawing.Size(648, 346); + this.PluginsTab.TabIndex = 0; + this.PluginsTab.Text = "Plugins"; + // + // PluginList + // + this.PluginList.AllowColumnReorder = true; + this.PluginList.AutoArrange = false; + this.PluginList.Dock = System.Windows.Forms.DockStyle.Fill; + this.PluginList.FullRowSelect = true; + this.PluginList.Location = new System.Drawing.Point(0, 0); + this.PluginList.MultiSelect = false; + this.PluginList.Name = "PluginList"; + this.PluginList.Size = new System.Drawing.Size(648, 346); + this.PluginList.TabIndex = 0; + this.PluginList.View = System.Windows.Forms.View.Details; + // + // LogTextTab + // + this.LogTextTab.Controls.Add(this.TextLog); + this.LogTextTab.Location = new System.Drawing.Point(4, 22); + this.LogTextTab.Name = "LogTextTab"; + this.LogTextTab.Size = new System.Drawing.Size(648, 346); + this.LogTextTab.TabIndex = 1; + this.LogTextTab.Text = "Event Log (Text)"; + // + // TextLog + // + this.TextLog.Dock = System.Windows.Forms.DockStyle.Fill; + this.TextLog.Font = new System.Drawing.Font("Lucida Sans Typewriter", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); + this.TextLog.Location = new System.Drawing.Point(0, 0); + this.TextLog.Name = "TextLog"; + this.TextLog.Size = new System.Drawing.Size(648, 346); + this.TextLog.TabIndex = 0; + this.TextLog.Text = ""; + // + // LogListTab + // + this.LogListTab.Location = new System.Drawing.Point(4, 22); + this.LogListTab.Name = "LogListTab"; + this.LogListTab.Size = new System.Drawing.Size(648, 346); + this.LogListTab.TabIndex = 3; + this.LogListTab.Text = "Event Log (List)"; + // + // ViewTab + // + this.ViewTab.Location = new System.Drawing.Point(4, 22); + this.ViewTab.Name = "ViewTab"; + this.ViewTab.Size = new System.Drawing.Size(648, 346); + this.ViewTab.TabIndex = 2; + this.ViewTab.Text = "View Configuration"; + // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); - this.ClientSize = new System.Drawing.Size(772, 437); + this.ClientSize = new System.Drawing.Size(676, 393); + this.Controls.Add(this.MainTab); this.Menu = this.mainMenu1; this.Name = "Form1"; this.Text = "AMX Mod X BinLogReader"; this.Load += new System.EventHandler(this.Form1_Load); + this.MainTab.ResumeLayout(false); + this.PluginsTab.ResumeLayout(false); + this.LogTextTab.ResumeLayout(false); + this.ResumeLayout(false); } #endregion + + public enum ViewAreas + { + Update_All=0, + Update_Plugins=1, + Update_Text=2, + } + + private ViewAreas g_UpdateViews; + /// /// The main entry point for the application. /// @@ -132,12 +249,138 @@ static void Main() private void Form1_Load(object sender, System.EventArgs e) { - PluginDb db = PluginDb.FromFile("c:\\hlserver\\cstrike\\addons\\amxmodx\\data\\binlogs\\bindb0001.bdb"); + plugdb = null; + binlog = null; + g_UpdateViews = ViewAreas.Update_All; } private void menuItem4_Click(object sender, System.EventArgs e) { Application.Exit(); } + + private void ClearViews(ViewAreas v) + { + if (v == ViewAreas.Update_All || + ((v & ViewAreas.Update_Plugins) == ViewAreas.Update_Plugins)) + { + PluginList.Clear(); + PluginList.Columns.Clear(); + } + if (v == ViewAreas.Update_Text || + ((v & ViewAreas.Update_Text) == ViewAreas.Update_Text)) + { + TextLog.Clear(); + } + } + + private void UpdateViews(ViewAreas v, BinLogFlags b) + { + ClearViews(v); + + if (v == ViewAreas.Update_All || + ((v & ViewAreas.Update_Plugins) == ViewAreas.Update_Plugins) + && (plugdb != null)) + { + PluginList.View = View.Details; + PluginList.Columns.Add("Number", 60, HorizontalAlignment.Left); + PluginList.Columns.Add("File", 100, HorizontalAlignment.Left); + PluginList.Columns.Add("Title", 120, HorizontalAlignment.Left); + PluginList.Columns.Add("Version", 60, HorizontalAlignment.Left); + PluginList.Columns.Add("Status", 60, HorizontalAlignment.Left); + + int num = plugdb.Count; + ListViewItem[] items = new ListViewItem[num]; + for (int i=0; i Private - + Private - + Private @@ -142,6 +142,123 @@ Private + + Private + + + Private + + + 126, 17 + + + True + + + False + + + True + + + Private + + + Private + + + 4, 4 + + + False + + + True + + + True + + + Private + + + Private + + + 8, 8 + + + False + + + Private + + + Private + + + False + + + True + + + True + + + Private + + + Private + + + 8, 8 + + + False + + + Private + + + Private + + + False + + + True + + + True + + + Private + + + Private + + + 8, 8 + + + False + + + True + + + True + + + Private + + + Private + + + 8, 8 + False @@ -157,18 +274,18 @@ 4, 4 - - Form1 - True - 80 + 49 True + + Form1 + Private diff --git a/plugins/BinLogReader/Plugin.cs b/plugins/BinLogReader/Plugin.cs index fce17c27..58a0ae96 100644 --- a/plugins/BinLogReader/Plugin.cs +++ b/plugins/BinLogReader/Plugin.cs @@ -12,13 +12,71 @@ public class Plugin private string Filename; private ArrayList Natives; private ArrayList Publics; + private string title; + private string version; + private int index; - public Plugin(string name, int natives, int publics, byte _status) + public string File + { + get + { + return Filename; + } + } + + public string Title + { + get + { + return title; + } + set + { + title = value; + } + } + + public string Version + { + get + { + return version; + } + set + { + version = value; + } + } + + public string Status + { + get + { + if (status == 0) + return "Failed"; + else if (status == 1) + return "Running"; + else if (status == 2) + return "Debug"; + return ""; + } + } + + public int Index + { + get + { + return index; + } + } + + public Plugin(string name, int natives, int publics, byte _status, int _index) { Filename = name; Natives = new ArrayList(natives); Publics = new ArrayList(publics); status = _status; + index = _index; } public void AddNative(string name) diff --git a/plugins/BinLogReader/PluginDb.cs b/plugins/BinLogReader/PluginDb.cs index 593966e2..9c464a26 100644 --- a/plugins/BinLogReader/PluginDb.cs +++ b/plugins/BinLogReader/PluginDb.cs @@ -14,6 +14,14 @@ public class PluginDb private static short BINDB_VERSION = 0x0100; private ArrayList PluginList; + public int Count + { + get + { + return PluginList.Count; + } + } + public PluginDb(uint plugins) { PluginList = new ArrayList((int)plugins); @@ -51,11 +59,11 @@ public static PluginDb FromFile(string filename) //check header uint magic = br.ReadUInt32(); if (magic != BINDB_MAGIC) - throw new Exception("Invalid magic number"); + throw new Exception("Invalid magic DB number"); //check version ushort vers = br.ReadUInt16(); if (vers > BINDB_VERSION) - throw new Exception("Unknown version"); + throw new Exception("Unknown DB version"); //read plugins uint plugins = br.ReadUInt32(); db = new PluginDb(plugins); @@ -70,7 +78,8 @@ public static PluginDb FromFile(string filename) Encoding.ASCII.GetString(name, 0, length), (int)natives, (int)publics, - status); + status, + (int)i); Plugin pl = db.GetPluginById(id); for (uint j=0; j