前言
本文仅供学习探讨之用,如果侵犯了您的权益请联系我删除。
工具
需求背景
前两天翻网盘的时候看到了个叫”妖梦亚索.zip”的文件,依稀记得是以前某皮肤站上下载的自定义皮肤,还挺喜欢来着。
于是下载了下来打开看了一下,发现是上古的格式,东西都是裸的,而现在的数据都是wad封装起来的,所以已经不适用了。
然后我就萌生了移植到wad格式的想法,再体验一下妖梦亚索!
移植过程
解包原始文件
我们先从游戏目录下复制出Yasuo.wad.client
和Yasuo.zh_CN.wad.client
两个文件,因为我们要改的是中文的,所以到时候是直接改第二个,第一个是为了提取原来的一些资源。
然后我们用cslol-manager
自带的工具wad-extract.exe
来进行解包
- 执行
./wad-extract.exe ./Yasuo.wad.client yasuo
来解包基础资源 - 执行
./wad-extract.exe ./Yasuo.zh_CN.wad.client yasuozh
来解包中文资源
重命名为小写
解包后我们对比一下原始资源和”妖梦亚索”的资源,发现后者的都是大驼峰+snake_case的命名,前者已改为全snake_case,所以我们让GPT写个py脚本来全部重命名一下文件
import os
def rename_to_lowercase(root_dir):
for dirpath, dirnames, filenames in os.walk(root_dir, topdown=False):
# Rename files
for filename in filenames:
old_path = os.path.join(dirpath, filename)
new_path = os.path.join(dirpath, filename.lower())
if old_path != new_path:
os.rename(old_path, new_path)
print(f'Renamed file: {old_path} -> {new_path}')
# Rename directories
for dirname in dirnames:
old_path = os.path.join(dirpath, dirname)
new_path = os.path.join(dirpath, dirname.lower())
if old_path != new_path:
os.rename(old_path, new_path)
print(f'Renamed directory: {old_path} -> {new_path}')
if __name__ == "__main__":
target_directory = "/path/to/your/directory" # 将此处修改为你指定的目录路径
rename_to_lowercase(target_directory)
跑完之后全部文件名都变为了小写,不错。
替换资源
我们照着yasuo
里的资源路径在yasuozh
文件夹里建立相同的路径
assets\characters\yasuo\hud
游戏中界面显示的资源assets\characters\yasuo\skins\base
游戏人物基础特效与基础皮肤的资源
然后我们把妖梦亚索data\characters\yasuo
路径下的两个文件夹(hud, skins)复制进去。
然后把妖梦亚索data\particles
文件夹复制到assets
最后把妖梦亚索data\sounds\wwise\vo\zh_cn\characters\yasuo\skins\base\yasuo_base_vo_audio.wpk
文件复制到assets\sounds\wwise2016\vo\en_us\characters\yasuo\skins\base
覆盖掉原始文件就行了。
是不是很简单。
打包
最后我们用cslol-manager
自带的工具wad-make.exe
来进行打包
- 执行
./wad-make.exe yasuozh repack/WAD/Yasuo.zh_CN.wad.client
打包完成后我们进入repack
目录,然后新建一个META
目录,然后再META
目录下新建一个文件info.json
并输入下面的内容
{
"Author": "Bzi-Han",
"Description": "妖梦亚索RE",
"Heart": "",
"Home": "",
"Name": "妖梦亚索RE",
"Version": "1.0.0"
}
这是cslol-manager
导入MOD所需的格式,没有META/info.json
的话MOD会导入失败。
然后我们压缩为.zip
文件即可,文件的目录结构如下
repack.zip
├── META
│ └── info.json
└── WAD
└── Yasuo.zh_CN.wad.client
测试
导入MOD之后我们上游戏测试一下
看到这界面的时候还高兴了一下,以为要成功了,结果加载到80%的时候游戏就崩了。
又试了两次,还是一样的结果,那看来是哪里有问题。
在一番控制变量测试之后,发现是yasuo.skl
的问题,没猜错的话这个是模型的骨骼信息,我们把这个替换成原始的就能正常加载进入游戏
但是可以看到我们的模型变成了一个奇行种,剑也是不会动的。
修复模型格式
我猜测是现版本的skl和skn和老的在文件结构上有些不同,不过好在lol_maya
支持加载老版本的模型文件。
我们打开Maya导入一下妖梦亚索的模型文件(需要安装lol_maya插件)yasuo.skn
我们看到这里的两个节点和原始模型的节点顺序是不一样的,我们给它调整到最上面,这个其实应该是不影响的,我只是单纯的以防万一。
调整好后我们选择所有的对象,然后导出当前选择
我们直接替换掉之前的文件。
好了之后我们重复之前的步骤进行打包然后加载,然后上游戏试试看。
二次测试
可以看到我们的模型和动画都已经正常了,不过又发现人物的音效没有了,估计是yasuo_base_vo_audio.wpk
那边的音效ID和事件ID对不上,这个还得修复一下。
修复音效
我们先把原始资源
data\characters\yasuo\skins\skin0.bin
assets\sounds\wwise2016\vo\en_us\characters\yasuo\skins\base\yasuo_base_vo_audio.wpk
assets\sounds\wwise2016\vo\en_us\characters\yasuo\skins\base\yasuo_base_vo_events.bnk
都给复制出来
然后用bnk-gui.exe
依次打开上面的文件,然后Parse files就行了。
再用同样的步骤Parse妖梦亚索的yasuo_base_vo_audio.wpk
文件。
妖梦音效
原始音效
可以看到妖梦的音效ID和事件是对不上的,所以游戏里触发对应事件的时候就没有声音。
而正常的Parse之后会自动分类事件的音效,我们只需要将妖梦对应的音效替换掉原始音效包中对应的音效就行了。
不过蛋疼的是由于妖梦的音效包没有对应的事件分类,比如”刹”、”哈!”之类的对应的是哪个技能都傻傻分不清,只能说凭感觉来了。
先把妖梦的音效解包出来,然后去掉重复的再慢慢一个一个手动分类
我们让GPT写个脚本扫描解包出来的文件,然后把重复的音效都给删掉
import os
import hashlib
def calculate_hash(file_path, hash_function=hashlib.md5):
hash_obj = hash_function()
with open(file_path, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_obj.update(chunk)
return hash_obj.hexdigest()
def find_and_remove_duplicates(root_dir):
hashes = {}
for dirpath, _, filenames in os.walk(root_dir):
for filename in filenames:
file_path = os.path.join(dirpath, filename)
file_hash = calculate_hash(file_path)
if file_hash in hashes:
print(f"Duplicate found: {file_path} is a duplicate of {hashes[file_hash]}")
os.remove(file_path)
print(f"Deleted duplicate file: {file_path}")
else:
hashes[file_hash] = file_path
if __name__ == "__main__":
target_directory = "/path/to/your/directory" # 将此处修改为你指定的目录路径
find_and_remove_duplicates(target_directory)
跑完后88个文件只剩下19个了,重复率还是蛮高的。
毕竟音效有限,说话闲聊什么的基本都是同一个音效。
然后我们需要把这些wem
文件用ww2ogg.exe
全都转换为ogg
格式。
这里我的目录结构如下
├── All
│ ├── 1020530801.wem
│ └── ...
├── ww2ogg024
│ ├── ww2ogg.exe
│ └── ...
└── Convert
└── convert.bat
然后我们在convert.bat
里写入如下代码
@echo off
for %%f in (../All/*.wem) do "../ww2ogg024/ww2ogg.exe" ../All/%%f --pcb "../ww2ogg024/packed_codebooks_aoTuV_603.bin" -o %%f.ogg
运行convert.bat
之后我们就可以看到Convert
目录下多出了一堆ogg
文件,这些就是转换的对应的ogg
文件了。
虽然ww2ogg
这个转换的ogg
文件有问题,但是我们后续还会把它转换为wav
格式,所以这里可以先不管它。
@echo off
for %%f in (../Convert/1.4/*.ogg) do "ffmpeg" -i ../Convert/1.4/%%f -filter:a "volume=1.4" -y %%f.wav
for %%f in (../Convert/2.2/*.ogg) do "ffmpeg" -i ../Convert/2.2/%%f -filter:a "volume=2.2" -y %%f.wav
for %%f in (../Convert/2.8/*.ogg) do "ffmpeg" -i ../Convert/2.8/%%f -filter:a "volume=2.8" -y %%f.wav
这里我把原来的ogg音效根据声音大小分成了三个文件夹,然后用ffmpeg
把它们转换为wav
格式的同时放大它们对应倍率的声音,有些音效的声音实在是太小声了,所以这里我分别把它们放大到1.4
倍、2.2
倍和2.8
倍。
执行convert.bat
后我们得到了转换好的wav
文件,相应的声音也自动调整好了。
我们可以来听一下对比的效果
类型 | 音效 |
---|---|
原始音效 | |
妖梦调整前音效 | |
妖梦调整后音效 |
那些些微的失真就不用管了,重要的是能听的清楚,不然游戏里就会跟蚊子说话一样了。
然后我们就按自己的理解把音效进行分类
分类好了之后我这里再把R的音效做一些修改,剪掉”多余”的说辞,不然大招放完了还在念台词就太草了。
类似这样把前缀给剪掉,只留下招式名字。
然后我们先把对应的ID与音效重命名方便后面查找,现在就可以把这些音效给转换回wem
格式了。
我们在WWise
中设置格式为Vorbis
之后就可以导入音效然后全选右键Convet到WEM
格式了。
转换后的文件会在Project目录的.cache\Windows\SFX
目录下。
然后我们用bnk-gui.exe
打开原始文件开始进行音效替换,选择我们要替换的*.wem然后Replace wem data
选择要替换的音效文件就行了。
全部替换好后我们点Save as bnk/wpk
保存为yasuo_base_vo_audio.wpk
即可。
最后我们把yasuo_base_vo_audio.wpk
复制并替换掉yasuozh\assets\sounds\wwise2016\vo\en_us\characters\yasuo\skins\base\yasuo_base_vo_audio.wpk
文件即可,然后我们重复之前的步骤,打包加载并上游戏测试。
三次测试
现在动画音效啥的都没问题了,不错。
那到这里基本就结束了,这里顺便把RE的版本贴出来,感兴趣可以自己试试
结语
其实音效我只替换了一部分,有很多还是没有替换的,比如普通攻击和其他的BB部分,所以攻击的过程中可能会妖梦的声音夹杂着亚索的声音,很搞笑。
不过我也懒得去替换了,两个方案
- 找更多妖梦的音效然后替换掉亚索对应的音效,或者把一些无关紧要的对话都给替换成同一段音效。
- 搞个空的音效替换掉不想要的音效,这样就听不到那些奇怪的音效了233。
那就这样了,有缘再见~