Sloppy's Blog


  • Home

  • About

  • Archives
Sloppy's Blog

cocos2d-x调用摄像头进行拍照显示

Posted on 2017-04-22

cocos2d-x调用摄像头进行拍照显示

Sloppy's Blog

Servlet与Mina框架的Socket进行通信

Posted on 2017-03-28

背景

在游戏业务中,这种需求很常用,游戏大都是Socket通信。而且游戏外接的SDK,外接的平台都是HTTP Servlet供访问访问,或者GM工具都是HTTP协议的形式出现,这就需要Java web服务器的Servlet能跟socket进行游戏,目前我们的游戏中也用到了这种方式,

代码

下载最新的mina包,及相关的依赖包

  • log4j-1.2.17.jar
  • mina-core-2.0.16.jar
  • mina-http-2.0.16.jar
  • slf4j-api-1.7.25.jar
  • slf4j-log4j12-1.7.25.jar

新建java web项目,把上面相应的包,copy进:WebContent/WEB-INF/lib

编写类:ClientHandler,用于处理Mina Socket连接的IOHandler,代码如下:

package com.nikoer.mina;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

public class ClientHandler implements IoHandler {

    public static final Map results = new ConcurrentHashMap();
    @Override
    public void exceptionCaught(IoSession arg0, Throwable arg1)
            throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void inputClosed(IoSession arg0) throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        // TODO Auto-generated method stub
        String flag = (String)session.getAttribute("SendRequestFlag");
        results.put(flag, message);
        session.closeNow();
    }

    @Override
    public void messageSent(IoSession arg0, Object arg1) throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void sessionClosed(IoSession arg0) throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void sessionCreated(IoSession arg0) throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void sessionIdle(IoSession arg0, IdleStatus arg1) throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void sessionOpened(IoSession arg0) throws Exception {
        // TODO Auto-generated method stub

    }

}

新建 Servlet类:

package com.nikoer.mina;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

/**
 * Servlet implementation class HelloMinaServlet
 */
@WebServlet("/HelloMinaServlet")
public class HelloMinaServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public HelloMinaServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        this.doPost(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        String param1 = request.getParameter("param1");
        IoConnector connector = new NioSocketConnector();
        connector.setHandler(new ClientHandler());
        connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
        ConnectFuture future = connector.connect(new InetSocketAddress("127.0.0.1", 3456));
        future.awaitUninterruptibly();
        IoSession session = future.getSession();
        String flag = request.getLocalAddr() + UUID.randomUUID().toString();
        session.setAttribute("SendRequestFlag", flag);
        session.write(param1+"\n");
        session.getCloseFuture().awaitUninterruptibly();
        connector.dispose();
        Object result = ClientHandler.results.get(flag);
        ClientHandler.results.remove(flag);
        response.getWriter().write(result.toString());
    }

}

运行Servlet进行测试,当前这里的Socket服务器可以是任意的服务器。也可以用Mina来开发一个Socket服务器进行测试

Sloppy's Blog

Cocos2d-x脚本lua引擎与JS引擎共存

Posted on 2017-03-28

背景

公司里之前的平台项目有的是LUA开发的,有的是JS开发的。结果公司想把这些小项目整合到一个平台里来。打包形成一个总的APP项目。大家知道cocos2d-x 要么是LUA的,要么是JS的。同时存在,而且需要相互切换。是一件多么蛋疼的事情。多么蛋疼的技术选型开发。没办法。事已至此。就需要整合两个渲染引擎到一起。之前听外包团队好象很麻烦,自己这边测试了一下。发现只需要修改少些就可以了。

步骤

创建项目

  • 我们用命令行先创建cocos2d-x-js项目,cocos new -l js -d c:\cocos HelloCocosApp
  • 再创建cocos2d-x lua项目 cocos new -l -d c:\cocos HelloCocosLua

合并代码

  • 把lua项目下的frameworks\cocos2d-x\cocos\scripting\lua-bindings这些文件复制到js项目中的frameworks\cocos2d-x\cocos\scripting目录下,这样scripting目录下就会有两个目录:js-bindings,lua-bindings
  • 把lua项目下的frameworks\cocos2d-x\external\lua文件夹复制到js目录下的frameworks\cocos2d-x\external目录下

添加项目引用

  • 接下来所有的项目在JS项目内完成,打开js项目的win32解决方案,添加项目引用,目录在:frameworks\cocos2d-x\cocos\scripting\lua-bindings\proj.win32\libluacocos2d.vcxproj
  • 在cocos项目属性上添加项目引用,
  • 添加c++附加包含目录,
    • $(EngineRoot)external\lua\tolua
    • $(EngineRoot)external\lua\lua

修改代码

  • 修改libjscocos2d里的ScriptingCore。修改单例,可以销毁。之前的单例是无法销毁的。代码如下:


    ScriptingCore ScriptingCore::getInstance()
    {
    //static ScriptingCore
    instance = nullptr;
    if (_defaultEngine == nullptr)

    _defaultEngine = new (std::nothrow) ScriptingCore();
    

    return _defaultEngine;
    }
    // 析构里增加至nullptr
    ScriptingCore::~ScriptingCore()
    {
    cleanup();
    JS_ShutDown();
    _defaultEngine = nullptr;
    }

  • 新建JSEngine类跟LuaEngine类,把原来初始化JS引擎的代码复制到JSEngine,把初始化Lua引擎的代码复制到LuaEngine里。分别提外部接口调用。这里我们可以做成单例使用。然后新建一个Scene自定义。在类里主要逻辑代码,监听从Lua跟JS发送过来的事件,切换引擎。
    bool CoolExpScene::init() {
      if (!Scene::init()) {
          return false;
      }
      Director::getInstance()->getEventDispatcher()->addCustomEventListener("SWITCH_LUA_ENGINE", [this](EventCustom* event) {
          CCLOG("CPP:SWITCH LUA ENGINE");
          Director::getInstance()->getScheduler()->performFunctionInCocosThread([]() {
              LuaEngine::getInstance()->initEngine();
          });
      });
      Director::getInstance()->getEventDispatcher()->addCustomEventListener("SWITCH_JS_ENGINE", [this](EventCustom* event) {
          CCLOG("CPP:SWITCH JS ENGINE");
          Director::getInstance()->getScheduler()->performFunctionInCocosThread([]() {
              JSEngine::getInstance()->initEngine();
          });
      });
      return true;
    }
    void CoolExpScene::onEnter() {
      Scene::onEnter();
      JSEngine::getInstance()->initEngine();
    }
    

AppDelegate.cpp初始化修改如下:
Director::getInstance()->runWithScene(CoolExpScene::create());

  • 修改脚本代码,关键性代码如下
    js

    var imageView = new ccui.ImageView(“res/strawberry.png”);
    imageView.attr({
    x: size.width / 2,
    y: size.height / 2
    
    });
    this.addChild(imageView);
    imageView.setTouchEnabled(true);
    imageView.addTouchEventListener(function(sender, type){
    if (type == ccui.Widget.TOUCH_ENDED) {
        cc.director.getRunningScene().removeAllChildren();
        cc.director.getEventDispatcher().dispatchCustomEvent("SWITCH_LUA_ENGINE");
    }
    
    });

    lua: cc.Director:getInstance():getEventDispatcher():dispatchCustomEvent(“SWITCH_JS_ENGINE”)

android编译修改

Android.mk文件关键修改如下:

..........代码
LOCAL_STATIC_LIBRARIES := cocos2d_js_static
LOCAL_STATIC_LIBRARIES += cocos2d_lua_static

..........代码

$(call import-module, scripting/js-bindings/proj.android)
$(call import-module,scripting/lua-bindings/proj.android)

IOS编译修改

添加libluacocos2dx项目引用,添加对应的head search path即可

Sloppy's Blog

Cocos2d-x-js集成Webpack进行开发

Posted on 2017-03-08

相信大家在开发cocos2d-x-js项目时,经常会碰到一个让人头痛的问题就是需要不停在的project.json添加文件,模块化不合理,引用第三方的NodeJs库,等一系统的需求,那这里我们采用WebPack集成成Cocos2d-x-js项目,一举解决了上述问题:

  • 第一步新建一个空项目,cocos new -l js -d c:\cocos HelloCocosJS
  • 在项目的根目录下添加webpack.config.js文件,内容如下:


var webpack = require('webpack');
var _ = require('lodash');
var npmModules = require('./package.json').dependencies;
var vendorLibs = [];
if(npmModules) {
    _.each(npmModules,function (item,key) {
        vendorLibs.push(key);
    });
}


module.exports = {
    entry: {
        app: "./source/init.js",
        vendor: vendorLibs,
    },
    output: {
        path: __dirname+"/src",
        filename: "bundle.js"
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin(/* chunkName= */"vendor", /* filename= */"vendor.js")
    ]
};

* 创建package.json文件,内容如下:
{
  "name": "HelloCocos2d-xJS",
  "version": "1.0.0",
  "description": "HelloCocos2d-xJS",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "lodash": "^3.10.1",
    "webpack": "^1.12.2",
    "webpack-dev-server": "^1.12.0"
  },
  "dependencies": {
    "lodash": "^3.10.1"
  }
}

  • 修改project.json把里面的jsList内容换成下面的:
"jsList" : [
        "src/vendor.js",
        "src/bundle.js"
 ]
  • 安装nodejs,然后安装webpack:npm install -g webpack
  • 修改main.js,内容如下:

    cc.game.onStart = function(){
        app.start();
    };
    cc.game.run();  

  • 新建文件夹resource,添加文件init.js,内容如下:
var res = require('./main/resources.js');
var MainScene = require('./main/mainscene.js');

var _ = require('lodash');

var g_resources = [];
_.each(res,function(item) {
    g_resources.push(item);
});

window.app = {}; // need a better way to expose a global game objecta

window.app.start = function() {
    if(!cc.sys.isNative && document.getElementById("cocosLoading")) //If referenced loading.js, please remove it
        document.body.removeChild(document.getElementById("cocosLoading"));

    // Pass true to enable retina display, on Android disabled by default to improve performance
    cc.view.enableRetina(cc.sys.os === cc.sys.OS_IOS ? true : false);

    // Adjust viewport meta
    cc.view.adjustViewPort(true);

    // Uncomment the following line to set a fixed orientation for your game
    // cc.view.setOrientation(cc.ORIENTATION_PORTRAIT);

    // Setup the resolution policy and design resolution size
    cc.view.setDesignResolutionSize(960, 640, cc.ResolutionPolicy.SHOW_ALL);

    // The game will be resized when browser size change
    cc.view.resizeWithBrowserSize(true);

    //load resources
    cc.LoaderScene.preload(g_resources, function () {
        cc.director.runScene(new MainScene());
        //cc.director.runScene(new ChipmunkScene());
    }, this);
};
  • 在resource目录下新建main文件夹,在main文件夹下,新建resources.js文件,内容如下:
var res = {
    HelloWorld_png : "res/HelloWorld.png"
};

module.exports = res;
  • 在main目录下,新建mainscene.js文件,内容如下:
var res = require("./resources.js");
var MainLayer = cc.Layer.extend({
    cocosNode:null,
    ctor:function () {

        this._super();
        var size = cc.winSize;

        var sprite = new Sprite(res.HelloWorld_png);
        addChild(sprite);
        return true;
    }
});


var MainScene = cc.Scene.extend({
    onEnter:function () {
        this._super();
        var layer = new MainLayer();
        this.addChild(layer);
    }
});
module.exports = MainScene;
  • 回到根目录,运行命令webpack,然后用VS运行项目。结果收工。
Sloppy's Blog

ES6中的Promise

Posted on 2017-03-08

相信大家见过这种代码,有种想死的冲动,代码如下:

$.ajax({
        url: '......',
        success: function (data) {
        $.ajax({
            // 要在第一个请求成功后才可以执行下一步
            url: '......',
            success: function (data) {
                 // ......
                 $.ajax({
                    // 要在第二个请求成功后才可以执行下一步
                    url: '......',
                    success: function (data) {
                         // ......
                    }
                });
            }
        });
    }
});
如果出现多个需要执行的加调。是不是根本无法理解,想死了。下面看看ES6中的promise魅力:
function printHello (ready) {
    return new Promise(function (resolve, reject) {
        if (ready) {
            resolve("Hello");
        } else {
            reject("Good bye!");
        }
    });
}

function printWorld () {
    alert("World");
}

function printExclamation () {
    alert("!");
}

printHello(true)
    .then(function(message){
        alert(message);
    })
    .then(printWorld)
    .then(printExclamation);

还可以这样写:

function printHello (ready) {
    return new Promise(function (resolve, reject) {
        if (ready) {
            resolve("Hello");
        } else {
            reject("Good bye!");
        }
    });
}

printHello(false).then(function (message) {
    return message;
}).then(function (message) {
    return message  + ' World';
}).then(function (message) {
    return message + '!';
}).then(function (message) {
    console.log(message);
},function (error) {
    console.log(error);
});

当然还可以多个Promise:

var p1 = new Promise(function (resolve) {
    setTimeout(function () {
        resolve("Hello");
    }, 3000);
});

var p2 = new Promise(function (resolve) {
    setTimeout(function () {
        resolve("World");
    }, 1000);
});

Promise.all([p1, p2]).then(function (result) {
    console.log(result); // ["Hello", "World"]
});
Sloppy's Blog

Cocos2d-x集成高德地图

Posted on 2017-02-14

在某些项目里,或者游戏项目里。偶尔要显示一下地图,怎么办,这里稍微研究了一下Cocos2d-x集成高德地图,目前只实现了。接入2D的,3D的还没有试过,目前只测试了Android项目。

申请开发KEY

请自行打开网站,申请http://developer.amap.com/,创建好项目。拿到KEY后。开始创建Cocos2d项目

接入项目

如果创建Cocos2d-x项目。就不详细说了。需要把下面的几个Jar包放入Android Lib包:
cryptopp_1

配置Java Build Path

编译代码

重载AppActivity的onCreate方法,内容如下:

    private   MapView mMapView = null;
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        mMapView = new MapView(this.getBaseContext());
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(800, 1200);
        mMapView.setLayoutParams(layoutParams);

        //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
        mMapView.onCreate(savedInstanceState);
        this.mFrameLayout.addView(mMapView);

    }
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        mMapView.onDestroy();
    }

    protected void onResume(){
        super.onResume();
        mMapView.onResume();
    }
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
        mMapView.onPause();
    }
     protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
        mMapView.onSaveInstanceState(outState);
     }

配置AndroidManifest.xml文件,添加权限:

1
2
3
4
5
6
7
8
9
10
11
12
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="com.android.vending.CHECK_LICENSE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.BLUETOOTH" />

在XML Application节点中间添加:

1
2
<meta-data android:name="com.amap.api.v2.apikey" android:value="5c47b0c32d838f2ad503da355e175ba5"></meta-data>

修改你的包名为申请APP时的包名即可。打包,Run到手机。

Sloppy's Blog

Lambda的妙用

Posted on 2017-02-04

有时候,我们需要根据各种不同的条件去查找某个对象里是否含有特定条件的数据。然后返回给业务使用,譬如,我们有一个名字库,我们需要查找是否含有.cao 结尾的。.test结尾的名字,那传统的可能就是一个类提供两个接口,那如果条件越多。是不是接口越来越多。太麻烦了。我们可以用lambda来解决问题,代码如下(代码中的中括号,用间括号代替):

class UserList
{
public:
    template[typename Func]
    std::vector[std::string] findMatchingUsers(Func func)
    {
        std::vector[std::string] results;
        for (auto it : _users) {
            if (func(it))
            {
                results.push_back(it);
            }
        }
        return results;
    }

private:
    std::vector[std::string] _users;
};

使用:

UserList global_user_list;
return global_user_list.findMatchingUsers(
    [](const string& user) { return user.find(".cao") != string::npos; }
);
Sloppy's Blog

std::string的一些用法

Posted on 2017-02-04

收集一些字符串的用法

反转字符串

// 反转
std::string s="HelloWorld";
std::string sr;
std::reverse(s.begin(), s.end());  
// 反转字符串到另外一字符
sr.assign(s.rbegin(), s.rend());

判断字符串是字符是某个字符串开始或者结尾

std::string s("hello, world");
std::string head("hello");
std::string tail("ld");
bool startwith = s.compare(0, head.size(), head) == 0;
bool endwith = s.compare(s.size() - tail.size(), tail.size(), tail) == 0;  

转换类型(toint, todouble)

std::string s("123");  
int i = atoi(s.c_str());  

std::string sd("12.3");  
double d = atof(sd.c_str());  

替换字符串

std::string str("hello, world");  
std::string sub("ello, ");  
str.replace(str.find(sub), sub.size(), "appy ");  

删除字符

std::string str = "  heLLo  ";  
str.erase(0, str.find_first_not_of(" "));    

str.erase(str.find_last_not_of(" ")+1);  

删除特定字符

std::string str = "   hello, world. say bye   ";  
str.erase(remove_if(str.begin(),str.end(),   
    bind2nd(equal_to(), ' ')),   
    str.end());   

大小写

std::string str = "heLLo";  

std::transform(str.begin(), str.end(), str.begin(), toupper);   

std::transform(str.begin(), str.end(), str.begin(), tolower);  
Sloppy's Blog

Cocos2d-x集成cryptopp类库(Android,Win32)

Posted on 2017-01-24

背景

前两天用Cocos2d-x IOS集成了cryptopp类库进行了一些加密解密的测试,回想,如果项目中,需要用到这个类库,是不是所有平台都需要呢。今天就Windows,Android平台,进行了一下集成测试,中间还是出现了一些小细节的问题,IOS这里就不介绍了,请参考上一篇博文(IOS使用cryptopp-Cocos2d-x项目)。我这里是一个Cocos2d-x CPP的项目,我们这里项目名叫:HelloCocos,可以用如下命令创建:

cocos new cpp -d c:/cocos -l cpp HelloCocos

准备工作

我们先下载最新cryptopp类库(565),然后在我们的游戏源码目录下,新建一个文件夹叫:external,跟Classes同级目录,把下载好的类库放进去,修改改文件夹名为cryptopp.

Android平台

在该目录下,新建一个Android.mk文件。用来编译Android版本,这里面需要注意的是,需要一些含有main入口的文件CPP文件不添加进Android.mk文件内(fipstest.cpp,regtest.cpp,test.cpp,validat1.cpp,validat2.cpp,validat3.cpp,bench.cpp,bench2.cpp),具体参考如下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := cryptopp_static
LOCAL_ARM_MODE := arm
LOCAL_MODULE_FILENAME := libcryptopp

LOCAL_SRC_FILES := \
        3way.cpp \
        adler32.cpp \
        algebra.cpp \
        algparam.cpp \
        arc4.cpp \
        asn.cpp \
        authenc.cpp \
        base32.cpp \
        base64.cpp \
        basecode.cpp \
        bfinit.cpp \
        blake2.cpp \
        blowfish.cpp \
        blumshub.cpp \
        camellia.cpp \
        cast.cpp \
        casts.cpp \
        cbcmac.cpp \
        ccm.cpp \
        chacha.cpp \
        channels.cpp \
        cmac.cpp \
        cpu.cpp \
        crc.cpp \
        cryptlib.cpp \
        default.cpp \
        des.cpp \
        dessp.cpp \
        dh.cpp \
        dh2.cpp \
        dll.cpp \
        dsa.cpp \
        eax.cpp \
        ec2n.cpp \
        eccrypto.cpp \
        ecp.cpp \
        elgamal.cpp \
        emsa2.cpp \
        eprecomp.cpp \
        esign.cpp \
        files.cpp \
        filters.cpp \
        fips140.cpp \
        gcm.cpp \
        gf256.cpp \
        gf2n.cpp \
        gf2_32.cpp \
        gfpcrypt.cpp \
        gost.cpp \
        gzip.cpp \
        hex.cpp \
        hmac.cpp \
        hrtimer.cpp \
        ida.cpp \
        idea.cpp \
        integer.cpp \
        iterhash.cpp \
        keccak.cpp \
        luc.cpp \
        mars.cpp \
        marss.cpp \
        md2.cpp \
        md4.cpp \
        md5.cpp \
        misc.cpp \
        modes.cpp \
        mqueue.cpp \
        mqv.cpp \
        nbtheory.cpp \
        network.cpp \
        oaep.cpp \
        osrng.cpp \
        panama.cpp \
        pch.cpp \
        pkcspad.cpp \
        polynomi.cpp \
        pssr.cpp \
        pubkey.cpp \
        queue.cpp \
        rabin.cpp \
        randpool.cpp \
        rc2.cpp \
        rc5.cpp \
        rc6.cpp \
        rdrand.cpp \
        rdtables.cpp \
        rijndael.cpp \
        ripemd.cpp \
        rng.cpp \
        rsa.cpp \
        rw.cpp \
        safer.cpp \
        salsa.cpp \
        seal.cpp \
        seed.cpp \
        serpent.cpp \
        sha.cpp \
        sha3.cpp \
        shacal2.cpp \
        shark.cpp \
        sharkbox.cpp \
        simple.cpp \
        skipjack.cpp \
        socketft.cpp \
        sosemanuk.cpp \
        square.cpp \
        squaretb.cpp \
        strciphr.cpp \
        tea.cpp \
        tftables.cpp \
        tiger.cpp \
        tigertab.cpp \
        trdlocal.cpp \
        ttmac.cpp \
        twofish.cpp \
        vmac.cpp \
        wait.cpp \
        wake.cpp \
        whrlpool.cpp \
        winpipes.cpp \
        xtr.cpp \
        xtrcrypt.cpp \
        zdeflate.cpp \
        zinflate.cpp \
        zlib.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)

include $(BUILD_STATIC_LIBRARY)
另外,修改proj.android/jni/Application.mk文件内的CPPFLAGS为如下内容(主要添加了-fexceptions):
APP_CPPFLAGS := -frtti -fexceptions -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -std=c++11 -fsigned-char

修改添加proj.android/build-cfg.json文件如下(添加ndk_module_path里的external):

{
    "ndk_module_path" :[
        "../cocos2d",
        "../cocos2d/cocos",
        "../cocos2d/external",
        "../external"
    ],
    "copy_resources": [
        {
            "from": "../Resources",
            "to": ""
        }
    ]
}

修改proj.android/jni/Android.mk文件,主要修改(LOCAL_C_INCLUDES,添加external,增加引用cryptopp_static,增加import-module):

.......code
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \
            $(LOCAL_PATH)/../../external

..... code

LOCAL_STATIC_LIBRARIES := cocos2dx_static
LOCAL_STATIC_LIBRARIES += cryptopp_static
.... code
$(call import-module,.)
$(call import-module,cryptopp)

.....

Windows平台

我们用VS2015打开HelloCocos.sln,添加已经存在的项目:cryptlib,这里面我们需要修改该项目的几个编译属性:如下图

cryptopp_1

cryptopp_2

修改HelloCocos项目配置,添加引用路径../external:

cryptopp_4

修改Lib输出目录:
cryptopp_4

添加链接库:
cryptopp_4

编译测试代码

VS打开HelloWorldScene.cpp文件,添加头文件引用:#include “cryptopp/md5.h” #include “cryptopp/hex.h”,在HelloWorld::init最后添加如下代码:


byte digest[CryptoPP::MD5::DIGESTSIZE];
std::string message = “HelloWorld”;
CryptoPP::MD5 hash;
hash.CalculateDigest(digest, (const byte*)message.c_str(), message.size());
CryptoPP::HexEncoder encoder;
std::string output;
encoder.Attach(new CryptoPP::StringSink(output));
encoder.Put(digest, sizeof(digest));
encoder.MessageEnd();

CCLOG(“HelloWorld MD5:%s”, output.c_str());

运行项目,是不是打印里出现了:HelloWorld MD5:68E109F0F40CA72A15E05CC22786F8E6,命令行编译Android项目:


cocos compile -m debug -p android

安装到手机上连接测试。用Eclipse看LOGCAT打印,也出现了HelloWorld MD5:68E109F0F40CA72A15E05CC22786F8E6

最后的项目结构如下:
cryptopp_3

Cryptopp的Android编译配置文件:Android.mk文件下载

Sloppy's Blog

IOS使用cryptopp(Cocos2d-x项目)

Posted on 2017-01-22

相信很多的项目中经常要用到各种不同的加密解密的问题,加密主要分为:

  • 对称加解密,就是需要密钥才能加密解密.加解密双方都需要密钥
  • 非对称加密,一般是使用公私钥的方式,公钥加密,私钥解密
  • 不可逆加密,广泛用于常用的MD5,用户密码加密,字符串比较小,当然现在计算机性能好.可以加密很大的字符串.性能也没有问题

准备工作

我们使用的c++ 库,cryptopp,包含了各种加密方式,我们先下载:https://www.cryptopp.com/#download,这里我用的是5.6.2版本。解压Zip,我们先在Windows是打开:cryptest.sln。编译结束后,进入cryptopp562\Win32\Output\Debug目录,打开命令行。运行如下命令:

cryptest.exe r
输入:私钥文件名,公钥文件名,Seed字符串,输入要加密的字符串,这里我输入的是:HelloWorld,好了。我们把当前目录下的。私钥文件(PrivateKey),以及加密后的密文Copy到r.txt文本文件中(新建一个r.txt文件)。 ### IOS平台 打开我们事先建的Cocos2d-x项目,新建一个目录cryptopp,并添加进Xcode项目,把cryptopp562目录下的所有的源文件(h文件,CPP文件),复制到文件目录,这里我们删除一些不需要的文件,我这里删除的是(validat1.cpp,validat2.cpp,validat3.cpp,bench.cpp,bench2.cpp,test.cpp),把上面产生的私钥文件跟文本文件,放到项目的Resources/res目录下 修改HelloWorldScene.cpp代码。 添加如下头文件引用:
include "cryptopp/rsa.h"
include "cryptopp/files.h"
include "cryptopp/hex.h"
include "cryptopp/filters.h"
include "cryptopp/modes.h"
include "cryptopp/aes.h"

// 引用命名空间
using namespace CryptoPP;
using namespace std;

定义几个对象
typedef CryptoPP::RSAES >::Decryptor RSAES_OAEP_SHA_Decryptor;
static OFB_Mode::Encryption s_globalRNG;

定义解密方法:
std::string RSADecryptString(const char *privFilename, const char *ciphertext)
{
    CryptoPP::FileSource privFile(privFilename, true, new HexDecoder);
    RSAES_OAEP_SHA_Decryptor priv(privFile);
    string result;
    StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(s_globalRNG, priv, new StringSink(result))));
    return result;
}

在HelloWorld::init方法最后面添加如下代码:

std::string seed = IntToString(time(NULL));
seed.resize(16);
s_globalRNG.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data());

std::string cipherTxt=FileUtils::getInstance()->getStringFromFile("res/r.txt");
std::string privateKeyFile = FileUtils::getInstance()->fullPathForFilename("res/PrivateKey");
std::string txt = RSADecryptString(privateKeyFile.c_str(),cipherTxt.c_str());
CCLOG("originaleTxt:%s",txt.c_str());

是不是在控制台输出了:HelloWorld字符串?这里面我们演示的是加密的第二种方法,通常这种方式,私钥是解密者所有,公钥是加密者所有。

计算字符串的MD5值:

byte digest[CryptoPP::MD5::DIGESTSIZE];
std::string message = "HelloWorld";
CryptoPP::MD5 hash;
hash.CalculateDigest(digest, (const byte*)message.c_str(), message.size());
CryptoPP::HexEncoder encoder;
std::string output;
encoder.Attach(new CryptoPP::StringSink(output));
encoder.Put(digest,sizeof(digest));
encoder.MessageEnd();

12…6
Sloppy

Sloppy

54 posts
7 tags
© 2017 Sloppy
Powered by Hexo
Theme - NexT.Muse