cocos2d-x引擎优化的一些建议,望引擎组重视

我不想每次更新都比较版本,所以分享出来: https://github.com/halx99/cocos2d-x-pc-port

在cocos2d-x中使用AES: https://github.com/halx99/cocos2d-x-pc-port/tree/master/crypto-support

用法:

// 复用内存方式:
std::string msg1 = “hello world, ok!”;
crypto::aes::overlapped::encrypt(msg1);
crypto::aes::overlapped::decrypt(msg2);
// 普通方式
std::string ciphertext = crypto::aes::encrypt(msg1);
std::string plaintext = crypto::aes::decrypt(ciphertext);

3赞

多谢建议。有些功能我和引擎组说了很多次,特别是文件存取hook回调,说了可能有一年吧,目前也不知道最新版本做进去没有。几乎每家公司都会修改文件存取的部分,加入自己的加解密,或者解析自己的数据封装格式。

至于把PC系统支持降低到兼容windows xp,我是觉得没太大必要了,现在国内基本都是win7了,加入winxp支持的话,引擎和编辑器发布的时候都还需要添加额外的测试工作量。

我关注github上的,应该是没加进去,而且我觉得c++11以后,引擎自己搞个Data数据结构,没太大必要

@minggo,在文件存取阶段增加hook回调,这个事情咱们说了得快有一年了吧

关于资源加密及回调的事情我想是两个方面的问题。

@halx99 建议的是所有的资源都放在一起打成一个包(类似Android现在的形式),然后都从这个包读取资源。引擎最初从cocos2d-iphone移植过来时没有这样的考虑。要做到这样的话,对引擎的改动比较大,必然带来兼容性的极大破坏。

@wangzhe 的意思是单个文件的读取、写入接口能有回调,这样可以做自己的操作,比如加密、解密等。这个对于开发者自己调用接口读取、写入文件是有效的。而引擎内部也会调用这些接口读取、写入信息,比如通过 Sprite::Create()创建sprite时,内部会调用文件读取接口读取图片数据生成纹理,这时这个回调接口从哪里获取呢?如果说在FileUtils里设置一个统一的回调接口,那么所有的文件读取都会走这个逻辑,显然也不符合需求。

所以文件的读取、写入增加回调的需求就变成了FileUtils可以被继承。开发者继承FileUtils就做自己想要的事情了。

@halx99
关于增加通用文件读取接口,以std::string作为返回值,那么如果是二进制数据呢?最近开发者提交了一个FileUitls::getContents()的接口,不知道这个是否能满足需求:https://github.com/cocos2d/cocos2d-x/pull/15479

ETC1的问题我看一下,是应该要有透明通道支持。
Data数据结构的说明能否给个具体的说明?

其实string处理二进制完全没任何问题(唯一的就是在申请分配内存是会+1个字节), 而且更加通用, 具体可以看我的实现, 很多标准库接口都会以string作为参数, 那么, 文件读取其实一个接口就够了,不需要那么多接口, 相比接口唯一的便利性,我认为+1字节是完全可以接受的

新接口,我看了下,个人拙见,除了增加接口复杂性,感觉意义不大, std::vector 和 std::string, 我更愿意选择std::string

恩,确实。这个和开发者提交的有异曲同工之妙。开发者的那个提交后,可以这样用

std::string bs;
auto serr = fs->getContents(_generatedFile, &bs);

std::vector<int> vbuf;
auto verr = fs->getContents(file, &vbuf);

Data dbuf;
auto derr = fs->getContents(file, &dbuf);

还可以扩展自己的数据类型,也就是你说的一个接口。我会把别的接口慢慢deperecated掉。现在别的接口内部也是用getContents()实现。

@minggo 关于解密hook, 我实现的方案中,默认hook是空的,如果开发者没有指定hook,则完全不影响原引擎Sprite::create读取纹理

嗯,我看到了。但是增加了hook后就意味着所有的资源都要走同一个逻辑。但是如果我只是想部分加密呢?

std::string也是支持的啊。

这样的话,只能有开发者对资源分表管理,加密的一个表,不加密的一个表, 目前我们游戏是全量加密,所以只有一个表

文件读取接口怎么知道这个分表用于区分哪些需要调用回调,哪些不需要?

嗯嗯,getContents这个接口比我说的更通用,只是增加一顶点复杂性,可以接受, 呵呵,我个人比较纠结,对于简易接口,喜欢one input, one output 原则。

这个我想,只能有开发者自己决定了,哪些需要加密,哪些不需要加密,分类的方法应该有很多,例如文件后缀什么的,引擎层面肯定无法控制的。这个表不应该在引擎层,而是由开发者自己管理,是否加密的逻辑也由开发者自行控制, 例如:


这里,hook需要在增加一个文件名参数, 让开发者来决定该文件是否需要解密

嗯,那我就加个接口用于设置这个hook函数吧,类似 FileUtils::setReadCallback(callback);

已经建立了issue

1赞

@halx99 不知道你是怎么支持ETC1 alpha通道的,从该文章 了解到,要支持alpha通道的话主要有两种:

  1. 把alpha数据和图片数据打在一个图片文件里
  2. alpha数据和图片分开位两个图片

对于方法2需要自己写shader,类似这个测试例子:https://github.com/cocos2d/cocos2d-x/blob/v3/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp#L665

方法1正如文章所说的,在scale时有性能下降,而且wrap时也只有一个方向是对的。

所以没太明白你说的支持指的是哪种。如果是方法2的话,那么其实是要自己写shader比较好控制。

OK,赞一个

我是用的方法二,直接在引擎层面支持,存储alpha通道的文件名和原文件名一致,仅仅多加一个Alpha后缀字符,引擎以此来判断纹理ETC1是否使用了有Alpha通道

但是这样也有问题:

1、你是在哪个阶段创建alpha后缀的纹理?Sprite初始化还是?那图集呢?
2、引擎应该尽量少对文件名、目录做限制,使用Alpha后缀区分比较过分,如果是完全工具化,那么没问题,工具和引擎配合不需要注意这种规则