290 lines
6.8 KiB
C#
290 lines
6.8 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Collections;
|
|
|
|
namespace BinLogReader
|
|
{
|
|
/// <summary>
|
|
/// binary log stuff yah
|
|
/// </summary>
|
|
public class BinLog
|
|
{
|
|
private static uint BINLOG_MAGIC = 0x414D424C;
|
|
private static short BINLOG_VERSION = 0x0300;
|
|
private static short BINLOG_MIN_VERSION = 0x0300;
|
|
|
|
private ArrayList oplist;
|
|
private PluginDb plugdb;
|
|
|
|
public ArrayList OpList
|
|
{
|
|
get
|
|
{
|
|
return oplist;
|
|
}
|
|
}
|
|
|
|
BinLog(int init_size)
|
|
{
|
|
oplist = new ArrayList(init_size);
|
|
}
|
|
|
|
public PluginDb GetPluginDB()
|
|
{
|
|
return plugdb;
|
|
}
|
|
|
|
public static BinLog FromFile(string filename)
|
|
{
|
|
if (!File.Exists(filename))
|
|
return null;
|
|
|
|
System.IO.FileStream stream = File.Open(filename, System.IO.FileMode.Open);
|
|
if (stream == null)
|
|
return null;
|
|
BinaryReader br = new BinaryReader(stream);
|
|
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 || version < BINLOG_MIN_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) );
|
|
|
|
bl.plugdb = PluginDb.FromFile(br);
|
|
PluginDb db = bl.plugdb;
|
|
|
|
if (db == null)
|
|
throw new Exception("Plugin database read failure");
|
|
|
|
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();
|
|
int file = br.ReadInt32();
|
|
BinLogSetLine bsl =
|
|
new BinLogSetLine(line, gametime, realtime, pl, file);
|
|
bl.OpList.Add(bsl);
|
|
break;
|
|
}
|
|
case BinLogOp.BinLog_CallPubFunc:
|
|
{
|
|
int pubidx = br.ReadInt32();
|
|
int fileid = br.ReadInt32();
|
|
BinLogPublic bp =
|
|
new BinLogPublic(pubidx,
|
|
gametime,
|
|
realtime,
|
|
pl,
|
|
fileid);
|
|
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();
|
|
int file = br.ReadInt32();
|
|
BinLogNativeCall bn =
|
|
new BinLogNativeCall(native,
|
|
parms,
|
|
gametime,
|
|
realtime,
|
|
pl,
|
|
file);
|
|
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 (Exception e)
|
|
{
|
|
if (bl != null && bl.plugdb != null)
|
|
{
|
|
BinLogSimple bs = new BinLogSimple(BinLogOp.BinLog_Invalid, gametime, realtime, pl);
|
|
bl.oplist.Add(bs);
|
|
}
|
|
else
|
|
{
|
|
throw new Exception(e.Message);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
br.Close();
|
|
stream.Close();
|
|
GC.Collect();
|
|
}
|
|
|
|
return bl;
|
|
}
|
|
}
|
|
}
|