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; }
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); }