public static IEnumerable <WZProperty> ImageChildren(WZProperty self) { using (WZReader reader = self.FileContainer.GetContentReader(null, self)) { if (self.Offset >= reader.BaseStream.Length) { yield break; } reader.BaseStream.Seek(self.Offset, SeekOrigin.Begin); if (reader.ReadByte() != 0x73) { throw new InvalidOperationException("Image should have header of 0x73"); } long oldPosition = reader.BaseStream.Position; if (!reader.ReadWZString(false, self.Encrypted).Equals("Property")) { reader.BaseStream.Position = oldPosition; if (!reader.ReadWZStringExpecting(out self.Encrypted, "Property", false)) { throw new InvalidOperationException("Unknown encryption method"); } } if (reader.ReadInt16() != 0) { throw new InvalidOperationException("Image needs to have 0 as part of header"); } foreach (WZProperty prop in PropertyList(reader, self).ToArray()) { yield return(prop); } } }
public static WZProperty Image(WZReader reader, WZProperty self) { if (self.Offset >= reader.BaseStream.Length) { return(self); } self.ContainerStartLocation = self.Offset; reader.Container = self; byte imgType = reader.ReadByte(); if (imgType == 1) { return(new WZPropertyWeak <string>(() => { using (reader = self.FileContainer.GetContentReader(null, self)) { reader.BaseStream.Seek(self.Offset, SeekOrigin.Begin); reader.ReadByte(); return reader.ReadLuaScript(); } }, self.NameWithoutExtension, self.Path, self.FileContainer, PropertyType.Lua, self.Parent, self.Size, self.Checksum, self.Offset)); } if (imgType != 0x73) { throw new InvalidOperationException("Unknown image type, not supported!"); } long oldPosition = reader.BaseStream.Position; if (!reader.ReadWZString(false, self.Encrypted).Equals("Property")) { reader.BaseStream.Position = oldPosition; if (!reader.ReadWZStringExpecting(out self.Encrypted, "Property", false)) { throw new InvalidOperationException("Unknown encryption method"); } } if (reader.ReadInt16() != 0) { throw new InvalidOperationException("Image needs to have 0 as part of header"); } return(self); }
private bool GuessVersionWithImageOffsetAt(short ver, long offset) { bool success = false; for (ushort v = 0; v < ushort.MaxValue; v++) { uint vHash = v.ToString() .Aggregate <char, uint>(0, (current, t) => (32 * current) + t + 1); if ((0xFF ^ (vHash >> 24) ^ (vHash << 8 >> 24) ^ (vHash << 16 >> 24) ^ (vHash << 24 >> 24)) != ver) { continue; } _r.BaseStream.Seek(offset, SeekOrigin.Begin); _r.VersionKey = vHash; VersionKey = vHash; VersionId = v; try { long currentOffset = _r.BaseStream.Position; _r.BaseStream.Seek(_r.ReadWZOffset(), SeekOrigin.Begin); byte childType = _r.ReadByte(); if (childType == 0x73) { long oldPosition = _r.BaseStream.Position; if (!_r.ReadWZStringExpecting(out IsEncrypted, "Property", false)) { _r.BaseStream.Position = oldPosition; continue; } success = true; _r.BaseStream.Position = oldPosition; break; } else if (childType == 0x01) { // Lua script, impossible to guarantee found valid version string luaScript = _r.ReadLuaScript(); if (luaScript.StartsWith("!version")) { EncryptionType encTesting = EncryptionType.None; bool wrongEncryption = false; do { PackageCollection col = new PackageCollection(); using (Package p = new Package(col, PackagePath, v)) { p.MainDirectory.Encrypted = encTesting; IEnumerable <WZProperty> children = p.MainDirectory.Children; WZProperty firstImg; do { firstImg = children.FirstOrDefault(c => c.Type == PropertyType.Image); wrongEncryption = children.Any(c => c.Name.Contains("?")); if (firstImg == null && !wrongEncryption) { children = children.Where(c => c != null).SelectMany(c => c.Children ?? new WZProperty[0]).Where(c => c != null).ToArray(); } } while (firstImg == null && children.Count() > 0 && !wrongEncryption); if (firstImg != null) {// No imgs??? if (encTesting == EncryptionType.None) { encTesting = IsEncrypted = firstImg.Encrypted; } else { IsEncrypted = encTesting; } success = true; break; } else if (wrongEncryption) { encTesting = (EncryptionType)(((int)encTesting) + 1); } else { break; } if ((int)encTesting == 3) { break; } } } while (wrongEncryption); if (!wrongEncryption && !success) { IsEncrypted = encTesting; success = true; } break; } } } catch { success = false; } } return(success); }