Cocos抖音小游戏“同质化提醒”解决方案
阅读本文前默认你有一定的Cocos引擎基础
原因
因项目需求,我们拿了一个已经在抖音上上架过的产品进行二次开发,改完后打包上传,结果后台准备提审时发现无法提审,且出现了如下提示:
同质化提醒:系统检测到当前提交的小游戏与平台小游戏高度相似,不符合平台要求,请修改小游戏内容重新提审
因为没提审就出现这个警告,且警告是立刻出现的,所以我们判断是上传后机审的。
因为有较多的资产复用,所以我们怀疑过是抖音后台用md5撞库来判断的,所以尝试过图片加噪点、代码混淆这种比较简单的方法来避免md5重复,但是上传后依旧是“同质化提醒”。
最后,我们是通过批量替换资产UUID后消除了警告。
原理很简单:我们使用的是Cocos引擎,Cocos引擎会在资产文件的同目录下,生成一个.meta文件来存放资产的UUID。
在构建时,Cocos会按照资产的UUID生成目录结构和资产文件名(尤其是图片文件)
然后又因为我们这个项目复用了大量的已经上架的产品的资产,UUID没变化,这导致最后构建出来的抖音小游戏项目结构与线上已有产品的项目结构高度相似。
所以,只需要为每个资产重新生成UUID,替换掉旧的UUID后即可。最后我们也是成功提审了。
替换思路
手动编写批处理程序,对资产文件和UUID进行批处理替换。
事先注意:
- 我这不提供具体替换UUID的批处理程序代码,但是我会提供整体思路和部分细节,读者按自己的需求实现;
- 在替换前,先对项目进行备份,一定要备份!避免批处理程序出错导致不可逆的项目损坏,只需要对项目目录下的
assets文件夹备份即可; - 在进行批处理替换前,自己要对项目结构有一个明确的了解,以便在批处理程序导致项目部分损坏后有手动修复能力;
- 在开始替换前,先确保原项目没有出现资产丢失的警告,如果有将不利于后续手动修复;
以下是技术实现:
1. 生成UUID映射表
遍历资产目录下的所有meta文件,并读取文件中的UUID。meta文件是纯文本的json格式,可以使用正则表达式直接匹配或读取json格式,但考虑到meta文件结构的复杂性,建议直接使用正则匹配,例如:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}。
在读取到所有UUID后,建立一个映射表,为每个旧UUID生成一个新UUID,在后续的操作中会将项目中的所有旧UUID映射替换为新UUID。
UUID的生成方案有很多种,可以自己查资料编写或是使用一些第三方库,比如在C#中可以使用Guid.NewGuid().ToString("D")来生成。
2. 压缩UUID
在Cocos的资产文件中,对于资产的引用不会直接使用原格式的UUID,而是使用一种经过压缩编码的UUID格式,例如:
- 原UUID:
a4a73587-54d3-4aae-9ab9-22997e7a7086 - 压缩后(23格式):
a4a73WHVNNKrpq5Ipl+enCG - 压缩后(22格式):
a4pzWHVNNKrpq5Ipl+enCG
具体的压缩算法参考这篇博客:cocos-uuid解密脚本。
在Cocos引擎中,原UUID、23压缩格式和22压缩格式会混合使用,所以在映射表中,你需要为每一个UUID保留6份UUID,其中旧UUID的3种格式,和新UUID的3种格式。
3. 替换UUID
遍历资产目录下的指定资产文件,并将文件中的旧UUID替换为映射后的新UUID。
对于需要遍历哪些资产文件,可以参考如下表格:
.meta资产的元数据文件,其中会包含资产本身的UUID和部分其他资产的UUID;.scene场景文件,引用其他资产时会包含资产的UUID;.prefab预制体文件,和场景文件一样;.anim动画文件,可能会包含其他资产的UUID;.mtl材质文件,可能会包含着色器、纹理资源的UUID;.jsonJSON文本文件,可能会包含资产的UUID;
需要注意的是:如果在你的脚本代码中包含了使用UUID加载资产文件的代码,则需要把.ts文件也考虑进去。
替换时需要遍历整个映射表,将文件中的所有UUID替换为对应的UUID(注意格式对应)。伪代码如下:
defreplace(filename):text=read_file(filename)# 读取文件forcombineinuuid_map:# 遍历映射表text=text.replace(combine.old_uuid32,combine.new_uuid32)# 替换原始格式UUIDtext=text.replace(combine.old_uuid23,combine.new_uuid23)# 替换23格式UUIDtext=text.replace(combine.old_uuid22,combine.new_uuid22)# 替换22格式UUIDsave_file(filename,text)# 保存文件4. 收尾修复
批处理程序替换完后,打开Cocos引擎,等待资产的重新导入,在此期间控制台可能会疯狂报出错误,先暂时忽略,等待导入完成后,无视错误直接运行一遍。
如果运行后出现黑屏、或者大面积资产丢失,说明资产导入异常,替换UUID失败了,请还原备份,重新自主检查批处理程序看看哪里出现了问题。
如果画面亮了,点开各种游戏界面、场景,能够基本“正常运行”,或者只有零零散散几个丢失的资源,说明导入成功了,此时先无视控制台,重启引擎,重新打开项目,这一步是让引擎重新导入游戏资产。
然后再次查看控制台,是否还有“missing”警告,看看有没有资产导入失败。点开游戏的各个界面、场景、预制体,手动修复这些导入失败的问题。
最后再经过反复的测试,确保游戏正常运行没有问题后,就能构建打包上传抖音了,如果一切顺利,就能看到警告消失了。
补充细节
- 以上是一个替换UUID的基本思路,不涉及具体代码,可以使用任意主流编程语言来编写;
- 使用批处理程序的过程中,先关闭引擎,避免引擎的重导入功能和替换同时进行导致的资产错乱;
- 在确保完全替换完UUID前,不要删除项目目录下的
temp文件夹,该文件夹中缓存了部分meta文件,在部分资产替换失败时,引擎会尝试用缓存自动修复这些错; - 不需要替换所有
- 因为我们也只是第一次尝试这种方法并成功了,没有特别多的成功案例,所以本方案也只能是作为参考。
