Page 27 of 35

Posted: Sat Dec 29, 2007 6:28 am
by Fiel
I'm back at it again!

This next version has all of the features in my previous post with the following enhancements:

- Can now extract MP3 files from Sound.wz
- Can extract all files from Map.wz without error

http://r a p i dshare.com/files/79779987/MapleStory.zip

Interestingly enough, in the Sound.wz all of the extractors jump over those 87 hex numbers to get to the actual sound file. I figured out what it was - IDv3 tags. It wasn't worth it to extract them, though. >_>

Posted: Sat Dec 29, 2007 8:50 am
by themoviefund
Thanks so much for finding a fix to that extremely annoying bug ;)

.. With only two lines of code xD

Posted: Sat Dec 29, 2007 11:17 pm
by kornto
Hi Fiel, It is koolk.
I promised to send you fixes to all the bugs but i forgot, sorry.

I see that you fixed two bugs already, nice!
So here is more fixes:
-In other versions(MSEA for example) there is another problem with Map.WZ.
In subBlock, the flag is 0x73. So add this in subBlock before: check(flag, 0x1b, f, "flag")

Code: Select all

if(flag == 0x73):
 val = extract73type(f, name, baseOffset, endOfBlock)
 result.append(val)
 i+=1
 flag = rS8(f)
Maybe there is more correct way to fix it, but this is working.(I did fast converting to python, can you check if it works with maplesea?)
-Some of the images(in Map.WZ) are already in 32 bits, so you only need to change the order of the RGBA.
So here is the fixed 16to32:

Code: Select all

def image16to32(width, height, data):
  datalen = len(data)
  buf = ""
  for i in range(width*height):
    # Not all images decompress correectly. This makes up for it.
    if(i > datalen/2 - 1):
      p = [0,0]
    elif(width*height*2 == len(data)/2):
     p = struct.unpack("BBBB", data[i*4:i*4+4])
    else:
     p = struct.unpack("BB", data[i*2:i*2+2])
    if(width*height*2 == len(data)/2):
      a = p[3]
      r = p[2]
      g = p[1]
      b = p[0]
    else:
      a = p[1] / 16 ; a = a*16 + a
      r = p[1] % 16 ; r = r*16 + r
      g = p[0] / 16 ; g = g*16 + g
      b = p[0] % 16 ; b = b*16 + b

    if(a >  255): a = 255
    if(r >  255): r = 255
    if(g >  255): g = 255
    if(b >  255): b = 255

    buf += struct.pack("BBBB", r, g, b, a)
  return buf
-extract73type doesn't return all the values.
Here is the fix:

Code: Select all

  if(iname == "Canvas"):
    space = rU16(f)  ; checkA(space, [0, 256], f)
    if(space == 256):
      nil = rU16(f)
      count = rU8(f)
      for i in range(count):
        qname = dumpBlock(f, name, baseOffset)
        val = dumpEntryValue(f, name + "/" + str(qname), baseOffset)
        vals.append([qname, val])
    imgname = name.replace('/', '.') + ".png"
    dumpImage(f, imgname)
    vals.append(['image', imgname])
    return vals
-subBlock return x,y
so why not?

Code: Select all

result.append([["x", val1], ["y", val2]])
Did i miss any bug?

Posted: Sat Dec 29, 2007 11:49 pm
by themoviefund
kornto wrote: -extract73type doesn't return all the values.
Here is the fix:

Code: Select all

  if(iname == "Canvas"):
    space = rU16(f)  ; checkA(space, [0, 256], f)
    if(space == 256):
      nil = rU16(f)
      count = rU8(f)
      for i in range(count):
        qname = dumpBlock(f, name, baseOffset)
        val = dumpEntryValue(f, name + "/" + str(qname), baseOffset)
        vals.append([qname, val])
    imgname = name.replace('/', '.') + ".png"
    dumpImage(f, imgname)
    vals.append(['image', imgname])
    return vals
What exactly does this do? I see it adds some extra values, but are you sure they are valid? Do you know what these are?
-subBlock return x,y
so why not?

Code: Select all

result.append([["x", val1], ["y", val2]])
I can't find this. I think I'm using a different version of code, which function is this in? (can't find it in "subBlock")

Thanks.

Posted: Sun Dec 30, 2007 7:04 am
by Fiel
Yeah, there are still more problems... *test post*

Posted: Sun Dec 30, 2007 7:15 am
by Fiel
.............

Posted: Sun Dec 30, 2007 7:30 am
by themoviefund
As far as I can tell, I see no changes in my extraction o_o

Code: Select all

def extract73type(f, name, baseOffset, endOfBlock):
  iname = rStr(f)
  if(iname == "Shape2D#Convex2D"):
    count = rPackNum(f)
    return subBlock(f, count, endOfBlock,0, name)
  if(iname == "Shape2D#Vector2D"):
    val1 = rPackNum(f)
    val2 = rPackNum(f)
    return [["x", val1], ["y", val2]]
  if(iname == "Canvas"):
    space = rU16(f)  ; checkA(space, [0, 256], f)
    if(space == 256):
      nil = rU16(f)
      count = rU8(f)
      for i in range(count):
        qname = dumpBlock(f, name, baseOffset)
        val = dumpEntryValue(f, name + "/" + str(qname), baseOffset)
        vals.append([name.replace('/','.') + '.' + qname, val])
    imgname = name.replace('/', '.') + ".png"
    dumpImage(f, imgname)
    return ['image', imgname]
  if(iname == "UOL"):
    nil = rU8(f)
    image = dumpBlock(f, name, baseOffset)
    cName = computeName(image, name)
    return ['image*', cName]
  if(iname == "Sound_DX8"):
    nil = rU8(f)
    size = rPackNum(f)
    dumpMp3(f, size, endOfBlock, name.replace('/','.'))
    return ["mp3", name]
What does the addition of this line do:
vals.append([name.replace('/','.') + '.' + qname, val])
vals is not a global in this function, so it doesn't actually affect anything. It's not returned either.

Posted: Sun Dec 30, 2007 10:36 am
by kornto
Fiel wrote:
kornto wrote:-extract73type doesn't return all the values.
Here is the fix:

Code: Select all

  if(iname == "Canvas"):
    space = rU16(f)  ; checkA(space, [0, 256], f)
    if(space == 256):
      nil = rU16(f)
      count = rU8(f)
      for i in range(count):
        qname = dumpBlock(f, name, baseOffset)
        val = dumpEntryValue(f, name + "/" + str(qname), baseOffset)
        vals.append([qname, val])
    imgname = name.replace('/', '.') + ".png"
    dumpImage(f, imgname)
    vals.append(['image', imgname])
    return vals
This half-worked. The "return vals" at the end actually appends itself to vals, so this would cause things to be double-added. I had to take that out. Also, I changed the "vals.append([qname,val])" so that it would fit a little better with the rest of the extraction.
I don't know, when i extracted it always some of the values of the first image in ".img" were missing(for example delay and origin x/y), becuase it didn't do anything with the val. Are you sure that it works now?
Fiel wrote:
As of this moment, I can only think of one other problem with this python extractor. In UI//UIWindow.img, a file is extracted with the name "Memo.FontTime...png". This causes Windows to not recognize the filename. The actual filename should be "Memo.FontTime.10.png". I looked at the area in the code where this happens and it turns out that the WZ data does have it coming out as a '.' instead of a '10'. This also happens with another file in the WZ, "coconut.fontTime" (prefix). I can't locate the error for this one, but I'm guessing it's a logical error somewhere!

Link: http://r a p i dshare.com/files/80008923/dump.py.html
Oh yea, this is very annoying.
For me it creates file with the name: "Memo.FontTime." and it is impossible to delete it! because there isn't really such a file but I see it. (i found a trick how to delete it).
The problem is that the filename should be Memo.FontTime.:.png(not 10)
But : is an invalid character for a filename.
You can try to replace the ":" to a valid character, I didn't try it yet.

And in subblock, you don't need the check for the 0x73 and 0x1b.
Just add it before the if:

Code: Select all

flag = rS8(f) ; checkA(flag, [0x1b, 0x73], f)

Posted: Sun Dec 30, 2007 7:42 pm
by themoviefund
kornto wrote:
Fiel wrote:
As of this moment, I can only think of one other problem with this python extractor. In UI//UIWindow.img, a file is extracted with the name "Memo.FontTime...png". This causes Windows to not recognize the filename. The actual filename should be "Memo.FontTime.10.png". I looked at the area in the code where this happens and it turns out that the WZ data does have it coming out as a '.' instead of a '10'. This also happens with another file in the WZ, "coconut.fontTime" (prefix). I can't locate the error for this one, but I'm guessing it's a logical error somewhere!
Oh yea, this is very annoying.
For me it creates file with the name: "Memo.FontTime." and it is impossible to delete it! because there isn't really such a file but I see it. (i found a trick how to delete it).
The problem is that the filename should be Memo.FontTime.:.png(not 10)
But : is an invalid character for a filename.
You can try to replace the ":" to a valid character, I didn't try it yet.
I'm not sure where to fix it, but I know how.

Code: Select all

def fix(number):
    return ord(number) - 48;
   
fix('0') #0
fix('5') #5
fix(':') #10

Posted: Sun Dec 30, 2007 7:48 pm
by kornto
themoviefund wrote:
kornto wrote:
Fiel wrote:
As of this moment, I can only think of one other problem with this python extractor. In UI//UIWindow.img, a file is extracted with the name "Memo.FontTime...png". This causes Windows to not recognize the filename. The actual filename should be "Memo.FontTime.10.png". I looked at the area in the code where this happens and it turns out that the WZ data does have it coming out as a '.' instead of a '10'. This also happens with another file in the WZ, "coconut.fontTime" (prefix). I can't locate the error for this one, but I'm guessing it's a logical error somewhere!
Oh yea, this is very annoying.
For me it creates file with the name: "Memo.FontTime." and it is impossible to delete it! because there isn't really such a file but I see it. (i found a trick how to delete it).
The problem is that the filename should be Memo.FontTime.:.png(not 10)
But : is an invalid character for a filename.
You can try to replace the ":" to a valid character, I didn't try it yet.
I'm not sure where to fix it, but I know how.

Code: Select all

def fix(number):
    return ord(number) - 48;
   
fix('0') #0
fix('5') #5
fix(':') #10
Why not just use replace(":", something else)?
It should be ':'(in the clock), but you can't name a file with :.

Posted: Sun Dec 30, 2007 7:51 pm
by themoviefund
If ':' == 10, then ';' could equal 11. That would get to be x.replace(':', '10').replace(etc.)...

For now, it would work, since there are no 11's, but it might fail in the future.

Posted: Sun Dec 30, 2007 9:14 pm
by kornto
themoviefund wrote:If ':' == 10, then ';' could equal 11. That would get to be x.replace(':', '10').replace(etc.)...

For now, it would work, since there are no 11's, but it might fail in the future.
It isn't 10!
It is ':'.
the font thing is for the clock.
And there are 11 characters in the clock:
0,1,2,3,4,5,6,7,8,9,:
It is only coincidental thing that ':' come after '9' in ASCII.

Posted: Sun Dec 30, 2007 9:18 pm
by themoviefund
...The clock? I don't know what your talking about now xD

Posted: Sun Dec 30, 2007 9:59 pm
by Fiel
You can't do string.replace(':','10') because doing the xor screws up the ASCII table. It's a quick hack fix, and I think it might be too risky to do it.

I'm also glad I'm not the only one with the memo/coconut problem.

Also, using the time function, I did some quick benchmarks:

String.wz: 0 minutes 4 seconds
Base.wz: 0 minutes 0 seconds
Character.wz: 4 minutes 7 seconds
Effect.wz: 0 minutes 0 seconds
Etc.wz: 0 minutes 2 seconds
Item.wz: 0 minutes 5 seconds
Map.wz: 3 minutes 2 seconds
Mob.wz: 0 minutes 9 seconds
Morph.wz: 0 minutes 0 seconds
NPC.wz: 0 minutes 7 seconds
Quest.wz: 0 minutes 4 seconds
Reactor.wz: 0 minutes 0 seconds
Skill.wz: 0 minutes 4 seconds
Sound.wz: 0 minutes 0 seconds
TamingMob.wz: 0 minutes 0 seconds
UI.wz: 0 minutes 1 seconds

Try to beat that on a subsequent extraction! :)
koolk wrote: I don't know, when i extracted it always some of the values of the first image in ".img" were missing(for example delay and origin x/y), becuase it didn't do anything with the val. Are you sure that it works now?
Yeah, go ahead and extract the first directory from accessory. It's there, now.

Posted: Sun Dec 30, 2007 10:02 pm
by themoviefund
I ported Lambda's code to another language a couple weeks ago, but now I'm interested in your cache technique which clearly yields faster extract times. What exactly do you cache?