原作者是:B0redom
帖子地址:Wakfu OST (1.31)
原作者 用D语言写的源码如下 - extractor.d
1 import std.stdio; 2 import std.file; 3 import std.conv; 4 import std.stream; 5 import std.bitmanip; 6 7 void main(string args[]){ 8 Stream pkfile = new BufferedFile(args[1],FileMode.In); 9 10 int headersize; 11 int counter = 0; 12 int filecount; 13 int throwaway; 14 int offset; 15 16 pkfile.read(headersize); 17 pkfile.read(filecount); 18 writefln("Count is : " ~ to!string(filecount)); 19 int[] files = new int[filecount]; 20 for(int x = 0; x < filecount; x++){ 21 pkfile.read(throwaway); 22 pkfile.read(offset); 23 files[x] = offset + (headersize + 4); 24 } 25 26 files = files.sort; 27 for(int x =0; x < filecount; x++){ 28 pkfile.seekSet(cast(long)files[x]); 29 long len; 30 pkfile.read(len); 31 int newlen = cast(int)len; 32 ubyte[] ogg = new ubyte[newlen]; 33 pkfile.read(ogg); 34 string outname = getcwd() ~"/"~ to!string(counter) ~ ".ogg"; 35 Stream oggout = new BufferedFile(outname,FileMode.OutNew); 36 oggout.write(shiftL(ogg,newlen)); 37 oggout.close(); 38 writefln("Creating file " ~ to!string(counter) ~".ogg"); 39 counter++; 40 } 41 } 42 43 ubyte[] shiftL(ubyte[] ogg,int ogglength){ 44 ubyte[] temp = new ubyte[ogglength]; 45 for(int x = 0;x < ogglength;x++){ 46 temp[x] = cast(byte)(ogg[x]-1); 47 } 48 return temp; 49 }
新增:默认导出文件位置为对应PK文件名相同的文件夹下!
1 /* 2 原作者:B0redom / https://www.reddit.com/user/B0redom/ 3 帖子地址:Wakfu OST (1.31) / https://www.reddit.com/r/wakfu/comments/1xu64i/wakfu_ost_131/ 4 修改者: iblackly / https://www.cnblogs.com/iblackly/ 5 修改记录: 6 增加导出文件名称。 7 默认导出文件位置为对应PK文件名相同的文件夹下! 8 */ 9 10 import std.stdio; 11 import std.file; 12 import std.conv; 13 import std.stream; 14 import std.bitmanip; 15 import std.regex; 16 17 // Main函数 18 void main(string args[]) 19 { 20 // 读取PK文件 21 Stream pkfile = new BufferedFile(args[1], FileMode.In); 22 // Header大小 23 int headersize; 24 // 计数 25 int counter = 0; 26 // 包内文件数量 27 int filecount; 28 int throwaway; 29 // 偏移 30 int offset; 31 // PK文件名称 32 auto pkFileNmae = matchAll(args[1], regex(`(w+)(?=.pk)`)); 33 // 打印文件名称 34 writefln("File Name: " ~ pkFileNmae.front.hit); 35 // PK文件对应的文件夹 36 auto pkDir = pkFileNmae.front.hit; 37 // 创建文件夹 38 pkDir.mkdir; 39 // 进入文件夹 40 pkDir.chdir; 41 // 获取Header大小 42 pkfile.read(headersize); 43 // 获取包内文件数量 44 pkfile.read(filecount); 45 // 打印包内有多少文件 46 writefln("文件数量:" ~ to!string(filecount)); 47 48 int[] files = new int[filecount]; 49 50 for (int x = 0; x < filecount; x++) 51 { 52 pkfile.read(throwaway); 53 pkfile.read(offset); 54 files[x] = offset + (headersize + 4); 55 } 56 57 files = files.sort; 58 for (int x = 0; x < filecount; x++) 59 { 60 pkfile.seekSet(cast(long) files[x]); 61 long len; 62 pkfile.read(len); 63 int newlen = cast(int) len; 64 ubyte[] ogg = new ubyte[newlen]; 65 pkfile.read(ogg); 66 string outname = pkFileNmae.front.hit ~ to!string(counter) ~ ".ogg"; 67 Stream oggout = new BufferedFile(outname, FileMode.OutNew); 68 oggout.write(shiftL(ogg, newlen)); 69 oggout.close(); 70 writefln("Creating file " ~ pkFileNmae.front.hit ~ to!string(counter) ~ ".ogg"); 71 counter++; 72 } 73 writefln("Done!!!"); 74 } 75 76 ubyte[] shiftL(ubyte[] ogg, int ogglength) 77 { 78 ubyte[] temp = new ubyte[ogglength]; 79 for (int x = 0; x < ogglength; x++) 80 { 81 temp[x] = cast(byte)(ogg[x] - 1); 82 } 83 return temp; 84 }
下载D语言编译器
编译
dmd wakfupk.d -release
在 dmd2windowsin 目录下会生成 wakfupk.exe
使用
进入 Wakfu 游戏目录
WAKFUcontentssoundsmusics
将 wakfupk.exe 放置目录内
将 musics.pk 文件 拖动到 wakfupk.exe 即可提取成功
其它PK文件同理
下载地址:
https://iblackly.lanzous.com/b05m7imje