void get_DirTree(TreeNode parent, wz_file f, string fPath, byte enc_type, bool all_on_list_child) { List<string> dirs = new List<string>(); string name = ""; int size = 0; int cs32 = 0; int offs = 0; int count = packed_int(f); bool on_list = false; bool use_enc = !WZ.encryption.listwz ? true : false; bool all_lst = (all_on_list_child || WZ.encryption.list.Contains(parent.Text.ToLower() + '/')) ? true : false; for(int i = 0; i < count; i++) { switch(f.bStream.ReadByte()) { case 0x02: name = readStrAt(f.header.head_size + 1 + f.bStream.ReadInt32(), f, use_enc); size = packed_int(f); cs32 = packed_int(f); offs = calc_offset(f); on_list = (all_lst || ((parent.Text == "Base.wz" || parent.Text == "base.wz") && WZ.encryption.list_contains(name.ToLower())) || WZ.encryption.list_contains(parent.Text.ToLower().Replace(".wz", "") + '/' + name.ToLower())) ? true : false ; parent.Nodes.Add(name).Tag = new image(name, size, cs32, offs, false, false, on_list, WZ.wz_files.IndexOf(f)); f.img_count++; break; case 0x03: name = readStr(f, use_enc); size = packed_int(f); cs32 = packed_int(f); f.stream.Position += 4; dirs.Add(name); break; case 0x04: name = readStr(f, use_enc); size = packed_int(f); cs32 = packed_int(f); offs = calc_offset(f); on_list = (all_lst || ( (parent.Text == "Base.wz" || parent.Text == "base.wz") && WZ.encryption.list_contains(name.ToLower()) ) || WZ.encryption.list_contains(parent.Text.ToLower().Replace(".wz", "") + '/' + name.ToLower())) ? true : false ; parent.Nodes.Add(name).Tag = new image(name, size, cs32, offs, false, false, on_list, WZ.wz_files.IndexOf(f)); f.img_count++; break; } } foreach(string dir in dirs) { TreeNode t = parent.Nodes.Add(dir); t.Tag = ""; if(f.header.file_name == "Base.wz" || f.header.file_name == "base.wz") { WZ.has_basewz = true; get_DirTree(t, f, fPath, enc_type, false); load_file(fPath + "\\" + dir + ".wz", t); } else { get_DirTree(t, f, fPath, enc_type, all_lst); } } }
Bitmap extract_png(PNG png, wz_file f) { DeflateStream zlib; int size_png = 0; int x = 0, y = 0, b = 0, g = 0; Bitmap png_decoded = null; BitmapData bmp_data; byte[] plain_data; f.stream.Position = png.offs; if(f.bStream.ReadUInt16() == 0x9C78) { zlib = new DeflateStream(f.stream, CompressionMode.Decompress); } else { f.stream.Position -= 2; MemoryStream data_stream = new MemoryStream(); int blocksize = 0; int end_of_png = (int)(png.data_length + f.stream.Position); while(f.stream.Position < end_of_png){ blocksize = f.bStream.ReadInt32(); for(int i = 0; i < blocksize; i++) { data_stream.WriteByte((byte)(f.bStream.ReadByte() ^ WZ.encryption.keys[i])); } } data_stream.Position = 2; zlib = new DeflateStream(data_stream, CompressionMode.Decompress); } switch (png.form) { case 1: png_decoded = new Bitmap(png.w, png.h, PixelFormat.Format32bppArgb); bmp_data = png_decoded.LockBits(new Rectangle(0, 0, png.w, png.h), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); size_png = png.w * png.h * 2; plain_data = new byte[size_png]; zlib.Read(plain_data, 0, size_png); byte[] argb = new Byte[size_png * 2]; for (int i = 0; i < size_png; i++) { b = plain_data[i] & 0x0F; b |= (b << 4); argb[i * 2] = (byte)b; g = plain_data[i] & 0xF0; g |= (g >> 4); argb[i * 2 + 1] = (byte)g; } Marshal.Copy(argb, 0, bmp_data.Scan0, argb.Length); png_decoded.UnlockBits(bmp_data); break; case 2: png_decoded = new Bitmap(png.w, png.h, PixelFormat.Format32bppArgb); bmp_data = png_decoded.LockBits(new Rectangle(0, 0, png.w, png.h), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); size_png = png.w * png.h * 4; plain_data = new byte[size_png]; zlib.Read(plain_data, 0, size_png); Marshal.Copy(plain_data, 0, bmp_data.Scan0, plain_data.Length); png_decoded.UnlockBits(bmp_data); break; case 513: png_decoded = new Bitmap(png.w, png.h, PixelFormat.Format16bppRgb565); bmp_data = png_decoded.LockBits(new Rectangle(0, 0, png.w, png.h), ImageLockMode.WriteOnly, PixelFormat.Format16bppRgb565); size_png = png.w * png.h * 2; plain_data = new byte[size_png]; zlib.Read(plain_data, 0, size_png); Marshal.Copy(plain_data, 0, bmp_data.Scan0, plain_data.Length); png_decoded.UnlockBits(bmp_data); break; case 517: png_decoded = new Bitmap(png.w, png.h); size_png = png.w * png.h / 128; plain_data = new byte[size_png]; zlib.Read(plain_data, 0, size_png); byte iB = 0; for (int i = 0; i < size_png; i++) { for (byte j = 0; j < 8; j++) { iB = Convert.ToByte(((plain_data[i] & (0x01 << (7 - j))) >> (7 - j)) * 0xFF); for (int k = 0; k < 16; k++) { if (x == png.w) { x = 0; y++; } png_decoded.SetPixel(x, y, Color.FromArgb(0xFF, iB, iB, iB)); x++; } } } break; } return png_decoded; }
/************* EXTRACTING *************/ void extract_value(int offset, TreeNode parent, wz_file f, bool use_enc) { parent = parent.Nodes.Add(get_string(offset, f, use_enc)); switch(f.bStream.ReadByte()){ case 0x00: parent.Tag = null; break; case 0x02: parent.Tag = f.bStream.ReadInt16(); break; case 0x03: parent.Tag = packed_int(f); break; case 0x04: parent.Tag = packed_float(f); break; case 0x05: parent.Tag = f.bStream.ReadDouble(); break; case 0x08: parent.Tag = get_string(offset, f, use_enc); break; case 0x09: extract_img(offset, parent, f.bStream.ReadInt32() + (int)f.stream.Position, f, use_enc); break; case 0x0B: parent.Tag = f.bStream.ReadInt16(); break; default: MessageBox.Show("Error in get_value. Offset: " + Convert.ToString(f.stream.Position, CultureInfo.InvariantCulture), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0); break; } }
/******************* BASIC FILE READING *******************/ static int packed_int(wz_file f) { int s = f.bStream.ReadSByte(); return (s == -128) ? f.bStream.ReadInt32() : s; }
void extract_img(int offset, TreeNode parent, int eob, wz_file f, bool is_on_list) { int entries = 0; switch(get_string(offset, f, is_on_list)) { case "Property": f.stream.Position += 2; entries = packed_int(f); for(int i = 0; i < entries; i++) { extract_value(offset, parent, f, is_on_list); } break; case "Shape2D#Vector2D": parent.Tag = new vector(packed_int(f), packed_int(f)); break; case "Canvas": f.stream.Position++; if(f.bStream.ReadByte() == 0x01) { f.stream.Position += 2; entries = packed_int(f); for(int i = 0; i < entries; i++) { extract_value(offset, parent, f, is_on_list); } } int w = packed_int(f); int h = packed_int(f); int form = packed_int(f) + f.bStream.ReadByte(); f.stream.Position += 4; int bufsize = f.bStream.ReadInt32(); //parent.Tag = new PNG(w, h, bufsize-1, form, (int)f.stream.Position+1, f.header.file_name); parent.Tag = new PNG(w, h, bufsize-1, form, (int)f.stream.Position+1, WZ.wz_files.IndexOf(f)); f.stream.Position += bufsize; break; case "Shape2D#Convex2D": entries = packed_int(f); for(int i = 0; i < entries; i++) { extract_img(offset, parent, 0, f, is_on_list); } break; case "Sound_DX8": f.stream.Position++; int len = packed_int(f); int ms = packed_int(f); parent.Tag = new MP3(eob - len, len, ms); f.stream.Position = eob; break; case "UOL": f.stream.Position++; parent.Tag = new UOL(get_string(offset, f, is_on_list)); break; default: break; } }
public void detect_encryption(wz_file f) { int old_off = (int)f.stream.Position; f.stream.Position = 62; packed_int(f); f.stream.Position++; int len = (int)(-f.bStream.ReadSByte()); byte[] bytes = f.bStream.ReadBytes(len); StringBuilder sb = new StringBuilder(); for(int i = 0; i < len; i++) { bytes[i] ^= (byte)(0xAA + i); sb.Append((char)bytes[i]); } if(sb.ToString().Contains(".img") || sb.ToString().Contains("Cash")) { this.all_strings_encrypted = false; } else { sb.Remove(0, sb.Length); if(this.enc_type != WZ_crypto.enc_unknown) { for(int i = 0; i < len; i++) { bytes[i] ^= this.keys[i]; sb.Append((char)bytes[i]); } if(sb.ToString().Contains(".img") || sb.ToString().Contains("Cash")) { this.all_strings_encrypted = true; this.encryption_detected = true; } } else { for(int i = 0; i < len; i++) { sb.Append((char)(bytes[i] ^ keys_kms[i])); } if(sb.ToString().Contains(".img") || sb.ToString().Contains("Cash")) { this.enc_type = WZ_crypto.enc_KMS; this.keys = this.keys_kms; this.all_strings_encrypted = true; this.all_pngs_encrypted = true; this.encryption_detected = true; } else { sb.Remove(0, sb.Length); for(int i = 0; i < len; i++) { sb.Append((char)(bytes[i] ^ keys_gms[i])); } if(sb.ToString().Contains(".img") || sb.ToString().Contains("Cash")){ this.enc_type = WZ_crypto.enc_GMS; this.keys = this.keys_gms; this.all_strings_encrypted = true; this.all_pngs_encrypted = true; this.encryption_detected = true; } } } } f.stream.Position = old_off; }
static float packed_float(wz_file f) { float fl = f.bStream.ReadSByte(); return (fl == -128) ? f.bStream.ReadSingle() : fl; }
void saveMP3(MP3 mp3, string filename, wz_file f) { FileStream save = new FileStream(filename, FileMode.OpenOrCreate); f.stream.Position = mp3.offset; save.Write(f.bStream.ReadBytes(mp3.length), 0, mp3.length); save.Close(); }
int calc_offset(wz_file f) { uint offset = (uint)(f.stream.Position - 0x3C) ^ 0xFFFFFFFF; uint bytes = f.bStream.ReadUInt32(); int distance = 0; long pos = f.stream.Position; uint[] test_offset = new uint[5]; if (!f.header.checked_version) { for (int i = 0; i < 5; i++) { test_offset[i] = offset * System.Convert.ToUInt32(f.header.hash_version_test[i]); test_offset[i] -= 0x581C3F6D; distance = (int)test_offset[i] & 0x1F; test_offset[i] = (test_offset[i] << distance) | (test_offset[i] >> (32 - distance)); test_offset[i] ^= bytes; test_offset[i] += 0x78; if (test_offset[i] < f.header.file_size) { f.stream.Position = test_offset[i]; if (f.stream.ReadByte() == 0x73) { f.stream.Position = pos; f.header.c_version = f.header.c_version_test[i]; f.header.hash_version = f.header.hash_version_test[i]; f.header.checked_version = true; offset = test_offset[i]; i = 5; } } } } else { offset *= f.header.hash_version; offset -= 0x581C3F6D; distance = (int)offset & 0x1F; offset = (offset << distance) | (offset >> (32 - distance)); offset ^= bytes; offset += 0x78; } return (int)offset; }
Bitmap render_layer(TreeNode layer_node, int height, int width, int centerX, int centerY, wz_file f, image map_img) { TreeNode t_node, t_node2; int x = 0, y = 0, z = 0, i = 0; vector v = new vector(0, 0); bool flipped = false; SortedList<int, List<tile>> z_layer_objects = new SortedList<int, List<tile>>(); SortedList<int, List<tile>> z_layer_tiles = new SortedList<int, List<tile>>(); Bitmap bMap = new Bitmap(width, height); Graphics gMap = Graphics.FromImage(bMap); image tile_img, obj_img; string tS_tile = ""; TreeNode found_node; toolStripStatusLabel1.Text = "Getting Objects..."; t_node = FindNode(layer_node, "obj"); for (i = 0; i < t_node.Nodes.Count; i++) { t_node2 = FindNode(t_node, i.ToString()); if (t_node2 != null) { found_node = FindNode(t_node2, "x"); if (found_node != null) { x = (int)found_node.Tag; } found_node = FindNode(t_node2, "y"); if (found_node != null) { y = (int)found_node.Tag; } found_node = FindNode(t_node2, "z"); if (found_node != null) { z = (int)found_node.Tag; } found_node = FindNode(t_node2, "f"); if (found_node != null) { flipped = System.Convert.ToBoolean(found_node.Tag); } string oS_obj = (string)(FindNode(t_node2, "oS").Tag); string l0_obj = (string)(FindNode(t_node2, "l0").Tag); string l1_obj = (string)(FindNode(t_node2, "l1").Tag); string l2_obj = (string)(FindNode(t_node2, "l2").Tag); obj_img = FindImage("Map\\Obj\\" + oS_obj + ".img",treeView1.Nodes[0]); object png_uol = get_value(l0_obj + "\\" + l1_obj + "\\" + l2_obj + "\\0", obj_img); PNG png; if (png_uol.GetType().Name == "UOL") { MessageBox.Show("UOL obj"); TreeNode uol_node = FindNode(FindNode(FindNode(FindNode(obj_img.node, l0_obj), l1_obj), l2_obj), "0"); png = (PNG)resolve_UOL((UOL)png_uol, uol_node).Tag; } else { png = (PNG)png_uol; } found_node = FindByFullPath(l0_obj + "\\" + l1_obj + "\\" + l2_obj + "\\0", obj_img.node); found_node = FindNode(found_node, "origin"); if (found_node != null) { v = (vector)found_node.Tag; } if (z_layer_objects.ContainsKey(z)) { z_layer_objects[z].Add(new tile(extract_png(png, f), x, y, v.x, v.y, flipped)); } else { z_layer_objects.Add(z, new List<tile>()); z_layer_objects[z].Add(new tile(extract_png(png, f), x, y, v.x, v.y, flipped)); } } } toolStripStatusLabel1.Text = "Getting Tiles..."; t_node = FindNode(layer_node, "info"); if (t_node.Nodes.Count > 0) { tS_tile = (string)(FindNode(t_node, "tS").Tag); } t_node = FindNode(layer_node, "tile"); if ((t_node.Nodes.Count > 0)) { for (i = 0; i < t_node.Nodes.Count; i++) { t_node2 = FindNode(t_node, i.ToString()); if (t_node2 != null) { found_node = FindNode(t_node2, "x"); if (found_node != null) { x = (int)found_node.Tag; } found_node = FindNode(t_node2, "y"); if (found_node != null) { y = (int)found_node.Tag; } found_node = FindNode(t_node2, "zM"); if (found_node != null) { z = (int)found_node.Tag; } string u_tile = "", no_tile = ""; found_node = FindNode(t_node2, "u"); if (found_node != null) { u_tile = (string)(found_node.Tag); } found_node = FindNode(t_node2, "no"); if (found_node != null) { no_tile = found_node.Tag.ToString();} tile_img = FindImage("Map\\Tile\\" + tS_tile + ".img", treeView1.Nodes[0]); PNG png = (PNG)get_value(u_tile + "\\" + no_tile, tile_img); found_node = FindByFullPath(u_tile + "\\" + no_tile , tile_img.node); found_node = FindNode(found_node, "origin"); if (found_node != null) { v = (vector)found_node.Tag; } found_node = FindByFullPath(u_tile + "\\" + no_tile, tile_img.node); found_node = FindNode(found_node, "z"); if (found_node != null) { z += (int)found_node.Tag; } if (z_layer_tiles.ContainsKey(z)) { z_layer_tiles[z].Add(new tile(extract_png(png, f), x, y, v.x, v.y, flipped)); } else { z_layer_tiles.Add(z, new List<tile>()); z_layer_tiles[z].Add(new tile(extract_png(png, f), x, y, v.x, v.y, flipped)); } } } } toolStripStatusLabel1.Text = "Adding Objects"; foreach (KeyValuePair<int, List<tile>> z_layer in z_layer_objects) { foreach (tile t in z_layer.Value) { if (!t.flip) { gMap.DrawImage(t.pic, t.x + centerX - t.ox, t.y + centerY - t.oy); } else { Bitmap flippedBmp = t.pic; flippedBmp.RotateFlip(RotateFlipType.RotateNoneFlipX); gMap.DrawImage(flippedBmp, t.x + centerX + t.ox - flippedBmp.Width, t.y + centerY - t.oy); } } } toolStripStatusLabel1.Text = "Adding Tiles..."; foreach (KeyValuePair<int, List<tile>> z_layer in z_layer_tiles) { foreach (tile t in z_layer.Value) { if (!t.flip) { gMap.DrawImage(t.pic, t.x + centerX - t.ox, t.y + centerY - t.oy); Console.WriteLine(String.Format("set position X {0} {1}",t.x,t.ox)); Console.WriteLine(String.Format("set position Y {0} {1}", t.y, t.oy)); Console.WriteLine(String.Format("set map {0} {1}", centerX, centerY)); } else { Bitmap flippedBmp = t.pic; flippedBmp.RotateFlip(RotateFlipType.RotateNoneFlipX); gMap.DrawImage(flippedBmp, t.x + centerX + t.ox - flippedBmp.Width, t.y + centerY - t.oy); } } } return bMap; }
/************* MAP RENDERER *************/ bool render_map(image map_img, wz_file f) { Application.DoEvents(); int map_width = 0, map_height = 0, map_centerX = 0, map_centerY = 0; List<Bitmap> layers = new List<Bitmap>(); TreeNode found_node; image t_img; toolStripStatusLabel1.Text = "Getting map size..."; try { map_width = (int)get_value("miniMap\\width", map_img); map_height = (int)get_value("miniMap\\height", map_img); map_centerX = (int)get_value("miniMap\\centerX", map_img); map_centerY = (int)get_value("miniMap\\centerY", map_img); } catch { int map_top = 0, map_bottom = 0, map_left = 0, map_right = 0; try { map_top = (int)get_value("info\\VRTop", map_img); map_bottom = (int)get_value("info\\VRBottom", map_img); map_left = (int)get_value("info\\VRLeft", map_img); map_right = (int)get_value("info\\VRRight", map_img); map_width = map_right - map_left; map_height = map_bottom - map_top; map_centerX = -map_left; map_centerY = -map_top; } catch { MessageBox.Show("Sorry, but this map cannot be rendered due to size information lacking. Maybe this map might be rendered in the future.", "Impossible to render this map", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return false; } } foreach (TreeNode n in map_img.node.Nodes) { if ("0123456789".IndexOf(n.Text.Substring(0), 0) != -1) { layers.Add(render_layer(n, map_height, map_width, map_centerX, map_centerY, f, map_img)); Application.DoEvents(); } } Bitmap finalMap = new Bitmap(map_width, map_height); Graphics fMap = Graphics.FromImage(finalMap); toolStripStatusLabel1.Text = "Creating picture..."; switch (lstRenders.SelectedIndex) { case 0: fMap.FillRectangle(Brushes.Transparent, 0, 0, map_width, map_height); break; case 1: fMap.FillRectangle(Brushes.Black, 0, 0, map_width, map_height); break; case 2: fMap.FillRectangle(Brushes.White, 0, 0, map_width, map_height); break; } foreach (Bitmap bmp in layers) { fMap.DrawImage(bmp, 0, 0); } //Portals if (chkPortalr.Checked == true) { toolStripStatusLabel1.Text = "Adding portals"; TreeNode portals = FindNode(map_img.node, "portal"); if (portals != null) { image MapHelper = FindImage("Map\\MapHelper.img", treeView1.Nodes[0]); Bitmap portal_picture = extract_png((PNG)get_value("portal\\game\\pv\\0", MapHelper), f); foreach (TreeNode node in portals.Nodes) { if ((int)FindNode(node, "pt").Tag == 2 && Convert.ToString(FindNode(node, "pn").Tag).Substring(0, 2) != "in") { fMap.DrawImage(portal_picture, (int)FindNode(node, "x").Tag + map_centerX - 43, (int)FindNode(node, "y").Tag + map_centerY - 173); } Application.DoEvents(); } } } //Reactors if (chkReactorr.Checked == true) { toolStripStatusLabel1.Text = "Adding reactors"; TreeNode reactors = FindNode(map_img.node, "reactor"); if (reactors != null) { if (reactors.Nodes.Count > 0){ foreach (TreeNode reactor in reactors.Nodes){ found_node = FindNode(reactor, "id"); if (found_node != null){ t_img = FindImage("Reactor\\" + (string)found_node.Tag + ".img", treeView1.Nodes[0]); if (t_img != null){ string link = (string)get_value("info\\link", t_img); if (link != null){ t_img = FindImage("Reactor\\" + link + ".img", treeView1.Nodes[0]); } vector v = (vector)get_value("0\\0\\origin", t_img); bool flip = Convert.ToBoolean(FindNode(reactor, "f").Tag); if (!flip){ fMap.DrawImage(extract_png((PNG)get_value("0\\0", t_img), WZ.wz_files[t_img.wz_f]), (int)FindNode(reactor, "x").Tag + map_centerX - v.x, (int)FindNode(reactor, "y").Tag + map_centerY - v.y); }else{ Bitmap flippedBmp = extract_png((PNG)get_value("0\\0", t_img), WZ.wz_files[t_img.wz_f]); flippedBmp.RotateFlip(RotateFlipType.RotateNoneFlipX); fMap.DrawImage(flippedBmp, (int)FindNode(reactor, "x").Tag + map_centerX + v.x - flippedBmp.Width, (int)FindNode(reactor, "y").Tag + map_centerY - v.y); } Application.DoEvents(); } } } } } } //Monsters if (chkMobr.Checked == true) { toolStripStatusLabel1.Text = "Adding monsters..."; TreeNode monsters = FindNode(map_img.node, "life"); if (monsters != null) { if (monsters.Nodes.Count > 0) { string stand_fly = "stand"; foreach (TreeNode life in monsters.Nodes) { if ((string)FindNode(life, "type").Tag == "m") { t_img = FindImage("Mob\\" + (string)FindNode(life, "id").Tag + ".img", treeView1.Nodes[0]); string link = (string)get_value("info\\link", t_img); while(link != null) { t_img = FindImage("Mob\\" + link + ".img", treeView1.Nodes[0]); link = (string)get_value("info\\link", t_img); } if (FindNode(t_img.node, "stand") == null){ stand_fly = "fly"; } vector v = (vector)get_value(stand_fly + "\\0\\origin", t_img); bool flip = Convert.ToBoolean(FindNode(life, "f").Tag); if (!flip) { object mob_picture = get_value(stand_fly + "\\0", t_img); if (mob_picture != null) { PNG png_mob; if (mob_picture.GetType().Name == "UOL") { TreeNode uol_node = FindNode(FindNode(t_img.node, stand_fly), "0"); png_mob = (PNG)(resolve_UOL((UOL)mob_picture, uol_node).Tag); TreeNode resolved_node = resolve_UOL((UOL)mob_picture, uol_node); resolved_node = FindNode(resolved_node, "origin"); v = (vector)resolved_node.Tag; } else { png_mob = (PNG)mob_picture; } Bitmap bitmap_mob = extract_png(png_mob, WZ.wz_files[t_img.wz_f]); int x_mob = (int)FindNode(life, "x").Tag + map_centerX - v.x; int y_mob = (int)FindNode(life, "cy").Tag + map_centerY - v.y; fMap.DrawImage(bitmap_mob, x_mob, y_mob); } } else { object mob_picture = get_value(stand_fly + "\\0", t_img); if (mob_picture != null) { PNG png_mob; if (mob_picture.GetType().Name == "UOL") { TreeNode uol_node = FindNode(FindNode(t_img.node, stand_fly), "0"); png_mob = (PNG)(resolve_UOL((UOL)mob_picture, uol_node).Tag); TreeNode resolved_node = resolve_UOL((UOL)mob_picture, uol_node); resolved_node = FindNode(resolved_node, "origin"); v = (vector)resolved_node.Tag; } else { png_mob = (PNG)mob_picture; } Bitmap flippedBmp = extract_png(png_mob, WZ.wz_files[t_img.wz_f]); flippedBmp.RotateFlip(RotateFlipType.RotateNoneFlipX); fMap.DrawImage(flippedBmp, (int)FindNode(life, "x").Tag + map_centerX + v.x - flippedBmp.Width, (int)FindNode(life, "cy").Tag + map_centerY - v.y); } } } else { continue; } Application.DoEvents(); } } } } //NPC if (chkNPCr.Checked == true) { toolStripStatusLabel1.Text = "Adding NPCs..."; TreeNode npcs = FindNode(map_img.node, "life"); if (npcs != null) { if (npcs.Nodes.Count > 0) { foreach (TreeNode life in npcs.Nodes) { if ((string)FindNode(life, "type").Tag == "n") { t_img = FindImage("Npc\\" + (string)FindNode(life, "id").Tag + ".img", treeView1.Nodes[0]); vector v = (vector)get_value("stand\\0\\origin", t_img); found_node = FindNode(life, "f"); if (found_node != null) { bool flip = Convert.ToBoolean(FindNode(life, "f").Tag); if (!flip) { object npc_picture = get_value("stand\\0", t_img); if (npc_picture != null) { PNG png_npc; if (npc_picture.GetType().Name == "UOL") { TreeNode uol_node = FindNode(FindNode(t_img.node, "stand"), "0"); png_npc = (PNG)(resolve_UOL((UOL)npc_picture, uol_node).Tag); TreeNode resolved_node = resolve_UOL((UOL)npc_picture, uol_node); resolved_node = FindNode(resolved_node, "origin"); v = (vector)resolved_node.Tag; } else { png_npc = (PNG)npc_picture; } fMap.DrawImage(extract_png(png_npc, WZ.wz_files[t_img.wz_f]), (int)FindNode(life, "x").Tag + map_centerX - v.x, (int)FindNode(life, "cy").Tag + map_centerY - v.y); } } else { object npc_picture = get_value("stand\\0", t_img); if (npc_picture != null) { PNG png_npc; if (npc_picture.GetType().Name == "UOL") { TreeNode uol_node = FindNode(FindNode(t_img.node, "stand"), "0"); png_npc = (PNG)(resolve_UOL((UOL)npc_picture, uol_node).Tag); TreeNode resolved_node = resolve_UOL((UOL)npc_picture, uol_node); resolved_node = FindNode(resolved_node, "origin"); v = (vector)resolved_node.Tag; } else { png_npc = (PNG)npc_picture; } Bitmap flippedBmp = extract_png(png_npc, WZ.wz_files[t_img.wz_f]); flippedBmp.RotateFlip(RotateFlipType.RotateNoneFlipX); fMap.DrawImage(flippedBmp, (int)FindNode(life, "x").Tag + map_centerX + v.x - flippedBmp.Width, (int)FindNode(life, "cy").Tag + map_centerY - v.y); } } } else { fMap.DrawImage(extract_png((PNG)get_value("stand\\0", t_img), WZ.wz_files[t_img.wz_f]), (int)FindNode(life, "x").Tag + map_centerX - v.x, (int)FindNode(life, "cy").Tag + map_centerY - v.y); } } else { continue; } Application.DoEvents(); } } } } toolStripStatusLabel1.Text = "Ending process..."; picRender.Image = finalMap; picRender.Size = finalMap.Size; return true; }
string readStrAt(int offset, wz_file f, bool use_enc) { int oldoffset = (int)f.stream.Position; f.stream.Position = offset; string ret = readStr(f, use_enc); f.stream.Position = oldoffset; return ret; }
string readStr(wz_file f, bool use_enc) { StringBuilder retStr = new StringBuilder(); int size = f.bStream.ReadSByte(); if(size < 0) { byte mask = 0xAA; size = (size == -128) ? f.bStream.ReadInt32() : -size; for(int i = 0; i < size; i++) { retStr.Append((char)(f.bStream.ReadByte() ^ (use_enc || WZ.encryption.all_strings_encrypted ? mask ^ WZ.encryption.keys[i] : mask))); unchecked { mask++; } } return retStr.ToString(); } if(size > 0) { int mask = 0xAAAA; if (size == 127) { size = f.bStream.ReadInt32(); } for(int i = 0; i < size; i++) { retStr.Append((char) (f.bStream.ReadByte() + f.bStream.ReadByte()*0x100 ^ (use_enc || WZ.encryption.all_strings_encrypted ? mask ^ WZ.encryption.keys[2*i] ^ (WZ.encryption.keys[2*i+1]*0x100) : mask))); unchecked { mask++; } } return retStr.ToString(); } return ""; }
void load_file(string filename, TreeNode parent) { string fName = Path.GetFileName(filename); string fPath = Path.GetDirectoryName(filename); wz_file f; try { f = new wz_file(filename); if(!WZ.encryption.encryption_detected){ WZ.encryption.detect_encryption(f); } } catch { Cursor = Cursors.Default; toolStripStatusLabel1.Text = "Error!"; treeView1.Enabled = true; menuStrip1.Enabled = true; MessageBox.Show("Error: " + fName + " could not be opened! Maybe it's used by another program already.", "Error while opening " + fName, MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0); mnuHeaderInfo.Enabled = false; return; } f.header = get_header(fName, f); if (f.header == null) { treeView1.Enabled = true; menuStrip1.Enabled = true; toolStripStatusLabel1.Text = "Error!"; Cursor = Cursors.Default; MessageBox.Show("Wrong file signature in " + fName + "!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0); mnuHeaderInfo.Enabled = false; return; } WZ.wz_files.Add(f); if(fName.ToLower() == "map.wz") { WZ.index_map = WZ.wz_files.IndexOf(f);; } get_DirTree(parent, f, fPath, WZ.encryption.enc_type, false); }
string get_string(int offset, wz_file f, bool use_enc) { switch(f.bStream.ReadByte()) { case 0x00: return readStr(f, use_enc); case 0x01: return readStrAt(offset + f.bStream.ReadInt32(), f, use_enc); case 0x04: f.stream.Position += 8; return ""; case 0x73: goto case 0x00; case 0x1B: goto case 0x01; default: MessageBox.Show("Unknown string type at offset: " + Convert.ToString(f.stream.Position, CultureInfo.InvariantCulture), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0); break; } return ""; }
wz_header get_header(string filename, wz_file f) { string signature = new string(f.bStream.ReadChars(4)); if(signature != "PKG1"){ return null; } int filesize = (int)f.stream.Length; int datasize = (int)f.bStream.ReadInt64(); int headersize = f.bStream.ReadInt32(); string copyright = new string(f.bStream.ReadChars(headersize - (int)f.stream.Position)); int encver = f.bStream.ReadUInt16(); int[] ver = new int[5]; uint[] h_ver = new uint[5]; int start_ver = -1; for (int i = 0; i < 5; i++) { ver[i] = get_version(encver, start_ver); h_ver[i] = get_version_hash(encver, ver[i]); start_ver = ver[i]; } wz_header header = new wz_header(signature, copyright, filename, headersize, datasize, filesize, ver, h_ver, false); return header; }