其他分享
首页 > 其他分享> > 在Android上将游戏资产下载到SD卡

在Android上将游戏资产下载到SD卡

作者:互联网

我正在开发一款Android游戏,该游戏必须将一些资产下载到SD卡上,以保持应用程序的尺寸尽可能小.我当时正在考虑使用未压缩的zip文件来捆绑所有资产.

客户的要求是尽可能保护这些资产.成为apk的一部分被认为是足够的保护,但是如果我这样做,则apk的大小将是巨大的.如果我只是在SD卡中放入一个zip捆绑包,那么任何人都可以将其解压缩并浏览其内容.

有没有简单的方法可以做到这一点而又不改写可怕的DRM?

显然,如果有人真的想检查Android游戏的资源,他们可以.我只是在寻找一种简单的解决方案,以免使其变得非常简单.

解决方法:

您可以使用encrypt the ZIP file with AES,但提取资产时会产生开销,这可能是个问题,因为编写游戏时性能通常非常重要.

但是,正如您所说的那样,使用安全加密并不真正值得,因为如果有人真的很感兴趣,他们可以在应用程序的源代码中找到密钥.因此,您可以自己编写一个InputStream和OutputStream来对ZIP文件的字节执行一些琐碎的转换.读取文件时,这将很快撤消,但会“损坏” ZIP文件,足以阻止有人浏览其SD卡.

使用它时,您可以将流放在File和ZIPInputStream之间,例如:

File assets = new File(Environment.getExternalStorageDirectory(),"assets");
ZipInputStream zip = new ZipInputStream(new TranslateInputStream(assets));

作为示例翻译,您可以对所有具有已知值的字节进行XOR:

private static final byte MAGIC_NUMBER = 13;

private void translateBuffer(byte[] buffer) {
    for (int i = 0;i < buffer.length;i++) {
        buffer[i] ^= MAGIC_NUMBER;
    }
}

private class TranslateOutputStream extends FileOutputStream {
    public TranslateOutputStream(File file) throws FileNotFoundException {
        super(file);
    }

    @Override
    public void write(int oneByte) throws IOException {
        oneByte ^= MAGIC_NUMBER;
        super.write(oneByte);
    }

    //In Android write(byte[]) calls this method so we don't need to override both        
    @Override
    public void write(byte[] buffer, int offset, int count)
            throws IOException {
        translateBuffer(buffer);
        super.write(buffer, offset, count);
    }
}

private class TranslateInputStream extends FileInputStream {

    public TranslateInputStream(File file) throws FileNotFoundException {
        super(file);
    }

    @Override
    public int read() throws IOException {
        return super.read() ^ MAGIC_NUMBER;
    }

    //In Android read(byte[]) calls this method so we don't need to override both        
    @Override
    public int read(byte[] buffer, int offset, int count)
            throws IOException {
        int bytesRead = super.read(buffer, offset, count);
        translateBuffer(buffer);
        return bytesRead;
    }
}

另外,由于您不关心压缩,因此无法使用ZIP.只需将所有资产串联在一起即可.创建Blob时,将每个资产的开始和结束位置写到索引文件中.然后,索引文件将包含在您的.apk文件中,从而可以从应用程序中的大文件中获取所需的数据.由于大blob不会采用标准格式,因此人们将无法轻松地从中提取文件.为了进一步确保您可以始终在文件的开头填充一些其他数据(也许只是一些纯文本),以使Blob看起来像其他东西.

标签:copy-protection,sd-card,android
来源: https://codeday.me/bug/20191106/2000279.html