private void GuessVersion() { _r.Seek(_fstart); short ver = _r.ReadInt16(); bool success; long offset = TryFindImageInDir(out success); if (success && GuessVersionWithImageOffsetAt(ver, offset)) { return; } for (ushort v = 0; v < ushort.MaxValue; v++) { uint vHash; if (!VersionHash(v, ver, out vHash)) { continue; } _r.VersionHash = vHash; if (DepthFirstImageSearch(out offset)) { break; } } if (!GuessVersionWithImageOffsetAt(ver, offset)) { WZUtil.Die("Unable to guess WZ version."); } }
private bool DepthFirstImageSearch(out long offset) { bool success = false; offset = -1; int count = _r.ReadWZInt(); for (int i = 0; i < count; i++) { byte type = _r.ReadByte(); switch (type) { case 1: _r.Skip(10); continue; case 2: int x = _r.ReadInt32(); type = _r.PeekFor(() => { _r.Seek(x + _fstart); return(_r.ReadByte()); }); break; case 3: case 4: _r.SkipWZString(); break; default: WZUtil.Die("Unknown object type in WzDirectory."); break; } _r.ReadWZInt(); _r.ReadWZInt(); offset = _r.Position; if (type == 4) { success = true; break; } if (type == 3) { try { offset = _r.PeekFor(() => { _r.Seek(_r.ReadWZOffset(_fstart)); long o; success = DepthFirstImageSearch(out o); return(o); }); break; } catch {} } _r.Skip(4); } return(success); }
private void Parse() { _r.Seek(0); if (_r.ReadInt32() != 0x31474B50) { WZUtil.Die("WZ file has invalid header; file does not have magic \"PKG1\"."); } _r.Skip(8); _fstart = _r.ReadUInt32(); GuessVersion(); MainDirectory = new WZDirectory("", null, this, _r, _fstart + 2); }
private long TryFindImageInDir(out bool success) { int count = _r.ReadWZInt(); if (count == 0) { WZUtil.Die("WZ file has no entries!"); } long offset = 0; offset = TryFindImageOffset(count, offset, out success); return(offset); }
internal string ReadWZStringBlock(bool encrypted) { switch (ReadByte()) { case 0: case 0x73: return(ReadWZString(encrypted)); case 1: case 0x1B: return(ReadWZStringAtOffset(ReadInt32(), encrypted)); default: return(WZUtil.Die <string>("Unknown string type in string block!")); } }
private long TryFindImageOffset(int count, long offset, out bool success) { success = false; for (int i = 0; i < count; i++) { byte type = _r.ReadByte(); switch (type) { case 1: _r.Skip(10); continue; case 2: int x = _r.ReadInt32(); type = _r.PeekFor(() => { _r.Seek(x + _fstart); return(_r.ReadByte()); }); break; case 3: case 4: _r.SkipWZString(); break; default: WZUtil.Die("Unknown object type in WzDirectory."); break; } _r.ReadWZInt(); _r.ReadWZInt(); offset = _r.Position; _r.Skip(4); if (type != 4) { continue; } success = true; break; } return(offset); }
internal void SkipWZStringBlock() { switch (ReadByte()) { case 0: case 0x73: SkipWZString(); return; case 1: case 0x1B: Skip(4); return; default: WZUtil.Die("Unknown string type in string block!"); return; } }