Fleshed out log and database readers, began basics of GUI
This commit is contained in:
parent
e067a980be
commit
82fe1e10d9
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace BinLogReader
|
namespace BinLogReader
|
||||||
{
|
{
|
||||||
|
@ -8,10 +10,25 @@ namespace BinLogReader
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BinLog
|
public class BinLog
|
||||||
{
|
{
|
||||||
private static uint BINLOG_MAGIC = 0x414D424C
|
private static uint BINLOG_MAGIC = 0x414D424C;
|
||||||
private static short BINLOG_VERSION = 0x0100;
|
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))
|
if (!File.Exists(filename))
|
||||||
return null;
|
return null;
|
||||||
|
@ -23,11 +40,219 @@ public static BinLog FromFile(string filename)
|
||||||
if (br == null)
|
if (br == null)
|
||||||
return 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
|
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<num; i++)
|
||||||
|
{
|
||||||
|
p = br.ReadInt32();
|
||||||
|
i32 = new Int32();
|
||||||
|
i32 = p;
|
||||||
|
parms.Add(i32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BinLogNativeParams bnp =
|
||||||
|
new BinLogNativeParams(gametime, realtime, pl);
|
||||||
|
bnp.ParamList = parms;
|
||||||
|
bl.OpList.Add(bnp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinLogOp.BinLog_FormatString:
|
||||||
|
{
|
||||||
|
int parm = br.ReadInt32();
|
||||||
|
int max = br.ReadInt32();
|
||||||
|
ushort len = br.ReadUInt16();
|
||||||
|
byte [] str = br.ReadBytes(len + 1);
|
||||||
|
string text = Encoding.ASCII.GetString(str, 0, len);
|
||||||
|
BinLogFmtString bfs =
|
||||||
|
new BinLogFmtString(parm, max, text, gametime, realtime, pl);
|
||||||
|
bl.OpList.Add(bfs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinLogOp.BinLog_End:
|
||||||
|
{
|
||||||
|
BinLogSimple bs =
|
||||||
|
new BinLogSimple(BinLogOp.BinLog_End, gametime, realtime, pl);
|
||||||
|
bl.OpList.Add(bs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinLogOp.BinLog_SetLine:
|
||||||
|
{
|
||||||
|
int line = br.ReadInt32();
|
||||||
|
BinLogSetLine bsl =
|
||||||
|
new BinLogSetLine(line, gametime, realtime, pl);
|
||||||
|
bl.OpList.Add(bsl);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinLogOp.BinLog_CallPubFunc:
|
||||||
|
{
|
||||||
|
int pubidx = br.ReadInt32();
|
||||||
|
BinLogPublic bp =
|
||||||
|
new BinLogPublic(pubidx,
|
||||||
|
gametime,
|
||||||
|
realtime,
|
||||||
|
pl);
|
||||||
|
bl.OpList.Add(bp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinLogOp.BinLog_NativeRet:
|
||||||
|
{
|
||||||
|
long ret;
|
||||||
|
if (bits64)
|
||||||
|
ret = br.ReadInt64();
|
||||||
|
else
|
||||||
|
ret = (long)br.ReadUInt32();
|
||||||
|
BinLogNativeRet bnr =
|
||||||
|
new BinLogNativeRet(ret, gametime, realtime, pl);
|
||||||
|
bl.OpList.Add(bnr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinLogOp.BinLog_NativeCall:
|
||||||
|
{
|
||||||
|
int native = br.ReadInt32();
|
||||||
|
int parms = br.ReadInt32();
|
||||||
|
BinLogNativeCall bn =
|
||||||
|
new BinLogNativeCall(native,
|
||||||
|
parms,
|
||||||
|
gametime,
|
||||||
|
realtime,
|
||||||
|
pl);
|
||||||
|
bl.OpList.Add(bn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinLogOp.BinLog_Start:
|
||||||
|
{
|
||||||
|
BinLogSimple bs =
|
||||||
|
new BinLogSimple(opcode, gametime, realtime, null);
|
||||||
|
bl.oplist.Add(bs);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinLogOp.BinLog_Registered:
|
||||||
|
{
|
||||||
|
byte length1 = br.ReadByte();
|
||||||
|
byte [] title = br.ReadBytes(length1 + 1);
|
||||||
|
byte length2 = br.ReadByte();
|
||||||
|
byte [] vers = br.ReadBytes(length2 + 1);
|
||||||
|
BinLogRegister be =
|
||||||
|
new BinLogRegister(gametime, realtime, pl);
|
||||||
|
be.title = Encoding.ASCII.GetString(title, 0, length1);
|
||||||
|
be.version = Encoding.ASCII.GetString(vers, 0, length2);
|
||||||
|
bl.oplist.Add(be);
|
||||||
|
pl.Title = be.title;
|
||||||
|
pl.Version = be.version;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
BinLogSimple bs = new BinLogSimple(BinLogOp.BinLog_Invalid, gametime, realtime, pl);
|
||||||
|
bl.oplist.Add(bs);
|
||||||
|
opcode = BinLogOp.BinLog_End;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (opcode != BinLogOp.BinLog_End);
|
||||||
|
opcode =BinLogOp.BinLog_End;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
if (bl != null)
|
||||||
|
{
|
||||||
|
BinLogSimple bs = new BinLogSimple(BinLogOp.BinLog_Invalid, gametime, realtime, pl);
|
||||||
|
bl.oplist.Add(bs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -35,6 +260,8 @@ public static BinLog FromFile(string filename)
|
||||||
stream.Close();
|
stream.Close();
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return bl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
462
plugins/BinLogReader/BinLogOps.cs
Normal file
462
plugins/BinLogReader/BinLogOps.cs
Normal file
|
@ -0,0 +1,462 @@
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace BinLogReader
|
||||||
|
{
|
||||||
|
public enum BinLogOp
|
||||||
|
{
|
||||||
|
BinLog_Invalid=0,
|
||||||
|
BinLog_Start=1,
|
||||||
|
BinLog_End,
|
||||||
|
BinLog_NativeCall, //<int16_t native id>
|
||||||
|
BinLog_NativeError,
|
||||||
|
BinLog_NativeRet,
|
||||||
|
BinLog_CallPubFunc, //<int16_t public id>
|
||||||
|
BinLog_SetLine, //<int16_t line no#>
|
||||||
|
BinLog_Registered, //<string title> <string version>
|
||||||
|
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<plist.Count; i++)
|
||||||
|
{
|
||||||
|
logtext += plist[i].ToString();
|
||||||
|
if (i < plist.Count - 1)
|
||||||
|
logtext += ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logtext += ")";
|
||||||
|
|
||||||
|
return logtext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BinLogFmtString : BinLogEntry
|
||||||
|
{
|
||||||
|
private int parm;
|
||||||
|
private int maxlen;
|
||||||
|
private string text;
|
||||||
|
|
||||||
|
public override BinLogOp Op()
|
||||||
|
{
|
||||||
|
return BinLogOp.BinLog_FormatString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BinLogFmtString(int pa, int ma, string str, float gt, long rt, Plugin _pl)
|
||||||
|
: base(gt, rt, _pl)
|
||||||
|
{
|
||||||
|
parm = pa;
|
||||||
|
maxlen = ma;
|
||||||
|
text = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToLogString(BinLogFlags flags)
|
||||||
|
{
|
||||||
|
string plugintext = BinLogEntry.PluginText(pl, flags);
|
||||||
|
string logtext = "Plugin " + plugintext + " formatted parameter " + parm;
|
||||||
|
logtext += " (maxlen " + maxlen + "), result: \n\t" + text;
|
||||||
|
|
||||||
|
return logtext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BinLogRegister : BinLogEntry
|
||||||
|
{
|
||||||
|
private string _title;
|
||||||
|
private string _version;
|
||||||
|
|
||||||
|
public string title
|
||||||
|
{
|
||||||
|
[DebuggerStepThrough]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _title;
|
||||||
|
}
|
||||||
|
[DebuggerStepThrough]
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_title = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string version
|
||||||
|
{
|
||||||
|
[DebuggerStepThrough]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _version;
|
||||||
|
}
|
||||||
|
[DebuggerStepThrough]
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_version = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToLogString(BinLogFlags flags)
|
||||||
|
{
|
||||||
|
string plugintext = BinLogEntry.PluginText(pl, flags);
|
||||||
|
string logtext = "Plugin " + plugintext + " registered as ";
|
||||||
|
logtext += "(\"" + _title + "\", \"" + _version + "\")";
|
||||||
|
|
||||||
|
return logtext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BinLogRegister(float gt, long rt, Plugin _pl) :
|
||||||
|
base(gt, rt, _pl)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override BinLogOp Op()
|
||||||
|
{
|
||||||
|
return BinLogOp.BinLog_Registered;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -86,7 +86,7 @@
|
||||||
/>
|
/>
|
||||||
<Reference
|
<Reference
|
||||||
Name = "System.XML"
|
Name = "System.XML"
|
||||||
AssemblyName = "System.XML"
|
AssemblyName = "System.Xml"
|
||||||
HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
|
HintPath = "..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
|
||||||
/>
|
/>
|
||||||
</References>
|
</References>
|
||||||
|
@ -99,6 +99,7 @@
|
||||||
/>
|
/>
|
||||||
<File
|
<File
|
||||||
RelPath = "AssemblyInfo.cs"
|
RelPath = "AssemblyInfo.cs"
|
||||||
|
SubType = "Code"
|
||||||
BuildAction = "Compile"
|
BuildAction = "Compile"
|
||||||
/>
|
/>
|
||||||
<File
|
<File
|
||||||
|
@ -106,6 +107,11 @@
|
||||||
SubType = "Code"
|
SubType = "Code"
|
||||||
BuildAction = "Compile"
|
BuildAction = "Compile"
|
||||||
/>
|
/>
|
||||||
|
<File
|
||||||
|
RelPath = "BinLogOps.cs"
|
||||||
|
SubType = "Code"
|
||||||
|
BuildAction = "Compile"
|
||||||
|
/>
|
||||||
<File
|
<File
|
||||||
RelPath = "Form1.cs"
|
RelPath = "Form1.cs"
|
||||||
SubType = "Form"
|
SubType = "Form"
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace BinLogReader
|
namespace BinLogReader
|
||||||
{
|
{
|
||||||
|
@ -14,11 +15,19 @@ public class Form1 : System.Windows.Forms.Form
|
||||||
{
|
{
|
||||||
private System.Windows.Forms.MainMenu mainMenu1;
|
private System.Windows.Forms.MainMenu mainMenu1;
|
||||||
private System.Windows.Forms.MenuItem menuItem1;
|
private System.Windows.Forms.MenuItem menuItem1;
|
||||||
private System.Windows.Forms.MenuItem menuItem2;
|
|
||||||
private System.Windows.Forms.MenuItem menuItem3;
|
private System.Windows.Forms.MenuItem menuItem3;
|
||||||
private System.Windows.Forms.MenuItem menuItem4;
|
private System.Windows.Forms.MenuItem menuItem4;
|
||||||
private System.Windows.Forms.MenuItem menuItem5;
|
private System.Windows.Forms.MenuItem menuItem5;
|
||||||
private System.Windows.Forms.MenuItem menuItem6;
|
private System.Windows.Forms.MenuItem menuItem6;
|
||||||
|
private System.Windows.Forms.OpenFileDialog ofd;
|
||||||
|
private System.Windows.Forms.MenuItem MenuFileOpen;
|
||||||
|
private System.Windows.Forms.TabPage PluginsTab;
|
||||||
|
private System.Windows.Forms.TabPage LogTextTab;
|
||||||
|
private System.Windows.Forms.TabPage ViewTab;
|
||||||
|
private System.Windows.Forms.TabPage LogListTab;
|
||||||
|
private System.Windows.Forms.ListView PluginList;
|
||||||
|
private System.Windows.Forms.RichTextBox TextLog;
|
||||||
|
private System.Windows.Forms.TabControl MainTab;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required designer variable.
|
/// Required designer variable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -51,6 +60,9 @@ protected override void Dispose( bool disposing )
|
||||||
base.Dispose( disposing );
|
base.Dispose( disposing );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PluginDb plugdb;
|
||||||
|
private BinLog binlog;
|
||||||
|
|
||||||
#region Windows Form Designer generated code
|
#region Windows Form Designer generated code
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Required method for Designer support - do not modify
|
/// Required method for Designer support - do not modify
|
||||||
|
@ -60,11 +72,23 @@ private void InitializeComponent()
|
||||||
{
|
{
|
||||||
this.mainMenu1 = new System.Windows.Forms.MainMenu();
|
this.mainMenu1 = new System.Windows.Forms.MainMenu();
|
||||||
this.menuItem1 = new System.Windows.Forms.MenuItem();
|
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.menuItem3 = new System.Windows.Forms.MenuItem();
|
||||||
this.menuItem4 = new System.Windows.Forms.MenuItem();
|
this.menuItem4 = new System.Windows.Forms.MenuItem();
|
||||||
this.menuItem5 = new System.Windows.Forms.MenuItem();
|
this.menuItem5 = new System.Windows.Forms.MenuItem();
|
||||||
this.menuItem6 = 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
|
// mainMenu1
|
||||||
//
|
//
|
||||||
|
@ -76,15 +100,16 @@ private void InitializeComponent()
|
||||||
//
|
//
|
||||||
this.menuItem1.Index = 0;
|
this.menuItem1.Index = 0;
|
||||||
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
|
||||||
this.menuItem2,
|
this.MenuFileOpen,
|
||||||
this.menuItem3,
|
this.menuItem3,
|
||||||
this.menuItem4});
|
this.menuItem4});
|
||||||
this.menuItem1.Text = "&File";
|
this.menuItem1.Text = "&File";
|
||||||
//
|
//
|
||||||
// menuItem2
|
// MenuFileOpen
|
||||||
//
|
//
|
||||||
this.menuItem2.Index = 0;
|
this.MenuFileOpen.Index = 0;
|
||||||
this.menuItem2.Text = "&Open";
|
this.MenuFileOpen.Text = "&Open";
|
||||||
|
this.MenuFileOpen.Click += new System.EventHandler(this.MenuFileOpen_Click);
|
||||||
//
|
//
|
||||||
// menuItem3
|
// menuItem3
|
||||||
//
|
//
|
||||||
|
@ -109,18 +134,110 @@ private void InitializeComponent()
|
||||||
this.menuItem6.Index = 0;
|
this.menuItem6.Index = 0;
|
||||||
this.menuItem6.Text = "&About";
|
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
|
// Form1
|
||||||
//
|
//
|
||||||
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
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.Menu = this.mainMenu1;
|
||||||
this.Name = "Form1";
|
this.Name = "Form1";
|
||||||
this.Text = "AMX Mod X BinLogReader";
|
this.Text = "AMX Mod X BinLogReader";
|
||||||
this.Load += new System.EventHandler(this.Form1_Load);
|
this.Load += new System.EventHandler(this.Form1_Load);
|
||||||
|
this.MainTab.ResumeLayout(false);
|
||||||
|
this.PluginsTab.ResumeLayout(false);
|
||||||
|
this.LogTextTab.ResumeLayout(false);
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public enum ViewAreas
|
||||||
|
{
|
||||||
|
Update_All=0,
|
||||||
|
Update_Plugins=1,
|
||||||
|
Update_Text=2,
|
||||||
|
}
|
||||||
|
|
||||||
|
private ViewAreas g_UpdateViews;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The main entry point for the application.
|
/// The main entry point for the application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -132,12 +249,138 @@ static void Main()
|
||||||
|
|
||||||
private void Form1_Load(object sender, System.EventArgs e)
|
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)
|
private void menuItem4_Click(object sender, System.EventArgs e)
|
||||||
{
|
{
|
||||||
Application.Exit();
|
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<num; i++)
|
||||||
|
{
|
||||||
|
Plugin pl = plugdb.GetPluginById(i);
|
||||||
|
ListViewItem item = new ListViewItem(i.ToString());
|
||||||
|
item.SubItems.Add(pl.File);
|
||||||
|
item.SubItems.Add(pl.Title);
|
||||||
|
item.SubItems.Add(pl.Version);
|
||||||
|
item.SubItems.Add(pl.Status);
|
||||||
|
items[i] = item;
|
||||||
|
}
|
||||||
|
PluginList.Items.AddRange(items);
|
||||||
|
}
|
||||||
|
if (v == ViewAreas.Update_Text ||
|
||||||
|
((v & ViewAreas.Update_Text) == ViewAreas.Update_Text)
|
||||||
|
&& (binlog != null))
|
||||||
|
{
|
||||||
|
ArrayList al = binlog.OpList;
|
||||||
|
BinLogEntry ble;
|
||||||
|
string fulltext = "";
|
||||||
|
for (int i=0; i<al.Count; i++)
|
||||||
|
{
|
||||||
|
ble = (BinLogEntry)al[i];
|
||||||
|
fulltext += BinLogEntry.BinLogString(ble,
|
||||||
|
(BinLogFlags.Show_GameTime | BinLogFlags.Show_PlugFile | BinLogFlags.Show_PlugId));
|
||||||
|
fulltext += "\n";
|
||||||
|
}
|
||||||
|
TextLog.Text = fulltext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MenuFileOpen_Click(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
DialogResult res = ofd.ShowDialog(this);
|
||||||
|
|
||||||
|
if (res != DialogResult.OK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
/* try to open the accompanying database file */
|
||||||
|
Regex r = new Regex(@"binlog(\d+)\.blg");
|
||||||
|
Match m = r.Match(ofd.FileName);
|
||||||
|
if (!m.Success)
|
||||||
|
{
|
||||||
|
throw new Exception("Failed to find binary database, filename unrecognized!");
|
||||||
|
}
|
||||||
|
Group g = m.Groups[1];
|
||||||
|
CaptureCollection cc = g.Captures;
|
||||||
|
Capture c = cc[0];
|
||||||
|
string dbfile = r.Replace(ofd.FileName, "bindb" + c.ToString() + ".bdb", 1);
|
||||||
|
|
||||||
|
plugdb = PluginDb.FromFile(dbfile);
|
||||||
|
if (plugdb == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Stream failure in database file");
|
||||||
|
}
|
||||||
|
|
||||||
|
binlog = BinLog.FromFile(ofd.FileName, plugdb);
|
||||||
|
if (binlog == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Stream failure in log file");
|
||||||
|
}
|
||||||
|
|
||||||
|
MainTab.SelectedTab = MainTab.TabPages[0];
|
||||||
|
ClearViews(ViewAreas.Update_All);
|
||||||
|
UpdateViews(ViewAreas.Update_Plugins, BinLogFlags.Show_PlugFile | BinLogFlags.Show_GameTime);
|
||||||
|
g_UpdateViews = ViewAreas.Update_Text;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
string msg = "Failed to open binary log";
|
||||||
|
if (ex.Message != null)
|
||||||
|
msg += ": " + ex.Message;
|
||||||
|
MessageBox.Show(this,
|
||||||
|
msg,
|
||||||
|
"AMX Mod X Binary Log Reader",
|
||||||
|
MessageBoxButtons.OK,
|
||||||
|
MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainTab_SelectedIndexChanged(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
if ((g_UpdateViews & ViewAreas.Update_Text) == ViewAreas.Update_Text)
|
||||||
|
{
|
||||||
|
UpdateViews(ViewAreas.Update_Text, BinLogFlags.Show_PlugFile|BinLogFlags.Show_GameTime);
|
||||||
|
g_UpdateViews &= ~(ViewAreas.Update_Text);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,10 +112,10 @@
|
||||||
<data name="menuItem1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<data name="menuItem1.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>Private</value>
|
<value>Private</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuItem2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<data name="MenuFileOpen.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>Private</value>
|
<value>Private</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuItem2.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<data name="MenuFileOpen.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>Private</value>
|
<value>Private</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="menuItem3.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<data name="menuItem3.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
@ -142,6 +142,123 @@
|
||||||
<data name="menuItem6.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<data name="menuItem6.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>Private</value>
|
<value>Private</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ofd.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="ofd.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="ofd.Location" type="System.Drawing.Point, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>126, 17</value>
|
||||||
|
</data>
|
||||||
|
<data name="MainTab.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</data>
|
||||||
|
<data name="MainTab.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</data>
|
||||||
|
<data name="MainTab.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</data>
|
||||||
|
<data name="MainTab.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="MainTab.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="MainTab.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>4, 4</value>
|
||||||
|
</data>
|
||||||
|
<data name="PluginsTab.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</data>
|
||||||
|
<data name="PluginsTab.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</data>
|
||||||
|
<data name="PluginsTab.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</data>
|
||||||
|
<data name="PluginsTab.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="PluginsTab.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="PluginsTab.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>8, 8</value>
|
||||||
|
</data>
|
||||||
|
<data name="PluginList.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</data>
|
||||||
|
<data name="PluginList.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="PluginList.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogTextTab.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogTextTab.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogTextTab.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogTextTab.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogTextTab.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogTextTab.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>8, 8</value>
|
||||||
|
</data>
|
||||||
|
<data name="TextLog.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</data>
|
||||||
|
<data name="TextLog.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="TextLog.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogListTab.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogListTab.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogListTab.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogListTab.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogListTab.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="LogListTab.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>8, 8</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewTab.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>False</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewTab.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewTab.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>True</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewTab.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewTab.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewTab.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>8, 8</value>
|
||||||
|
</data>
|
||||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>False</value>
|
<value>False</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -157,18 +274,18 @@
|
||||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>4, 4</value>
|
<value>4, 4</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="$this.Name">
|
|
||||||
<value>Form1</value>
|
|
||||||
</data>
|
|
||||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>True</value>
|
<value>True</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>80</value>
|
<value>49</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>True</value>
|
<value>True</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="$this.Name">
|
||||||
|
<value>Form1</value>
|
||||||
|
</data>
|
||||||
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<data name="$this.DefaultModifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>Private</value>
|
<value>Private</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
@ -12,13 +12,71 @@ public class Plugin
|
||||||
private string Filename;
|
private string Filename;
|
||||||
private ArrayList Natives;
|
private ArrayList Natives;
|
||||||
private ArrayList Publics;
|
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;
|
Filename = name;
|
||||||
Natives = new ArrayList(natives);
|
Natives = new ArrayList(natives);
|
||||||
Publics = new ArrayList(publics);
|
Publics = new ArrayList(publics);
|
||||||
status = _status;
|
status = _status;
|
||||||
|
index = _index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddNative(string name)
|
public void AddNative(string name)
|
||||||
|
|
|
@ -14,6 +14,14 @@ public class PluginDb
|
||||||
private static short BINDB_VERSION = 0x0100;
|
private static short BINDB_VERSION = 0x0100;
|
||||||
private ArrayList PluginList;
|
private ArrayList PluginList;
|
||||||
|
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return PluginList.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public PluginDb(uint plugins)
|
public PluginDb(uint plugins)
|
||||||
{
|
{
|
||||||
PluginList = new ArrayList((int)plugins);
|
PluginList = new ArrayList((int)plugins);
|
||||||
|
@ -51,11 +59,11 @@ public static PluginDb FromFile(string filename)
|
||||||
//check header
|
//check header
|
||||||
uint magic = br.ReadUInt32();
|
uint magic = br.ReadUInt32();
|
||||||
if (magic != BINDB_MAGIC)
|
if (magic != BINDB_MAGIC)
|
||||||
throw new Exception("Invalid magic number");
|
throw new Exception("Invalid magic DB number");
|
||||||
//check version
|
//check version
|
||||||
ushort vers = br.ReadUInt16();
|
ushort vers = br.ReadUInt16();
|
||||||
if (vers > BINDB_VERSION)
|
if (vers > BINDB_VERSION)
|
||||||
throw new Exception("Unknown version");
|
throw new Exception("Unknown DB version");
|
||||||
//read plugins
|
//read plugins
|
||||||
uint plugins = br.ReadUInt32();
|
uint plugins = br.ReadUInt32();
|
||||||
db = new PluginDb(plugins);
|
db = new PluginDb(plugins);
|
||||||
|
@ -70,7 +78,8 @@ public static PluginDb FromFile(string filename)
|
||||||
Encoding.ASCII.GetString(name, 0, length),
|
Encoding.ASCII.GetString(name, 0, length),
|
||||||
(int)natives,
|
(int)natives,
|
||||||
(int)publics,
|
(int)publics,
|
||||||
status);
|
status,
|
||||||
|
(int)i);
|
||||||
Plugin pl = db.GetPluginById(id);
|
Plugin pl = db.GetPluginById(id);
|
||||||
for (uint j=0; j<natives; j++)
|
for (uint j=0; j<natives; j++)
|
||||||
{
|
{
|
||||||
|
@ -88,7 +97,8 @@ public static PluginDb FromFile(string filename)
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
throw new Exception("File is corrupt");
|
db = null;
|
||||||
|
throw new Exception("DB file is corrupt");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -100,9 +110,9 @@ public static PluginDb FromFile(string filename)
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int CreatePlugin(string file, int natives, int publics, byte status)
|
private int CreatePlugin(string file, int natives, int publics, byte status, int index)
|
||||||
{
|
{
|
||||||
Plugin pl = new Plugin(file, natives, publics, status);
|
Plugin pl = new Plugin(file, natives, publics, status, index);
|
||||||
PluginList.Add(pl);
|
PluginList.Add(pl);
|
||||||
return PluginList.Count - 1;
|
return PluginList.Count - 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user