XORでジャミング済みのPNGファイルを読み込む

XORでbitshiftさせたPNGをcocos2d-x側で読み込む際にデコードする。
PNGの処理については割愛

# cocos/platform/CCImage.h 
# 
# XOR_SEED と XOR_SEED_CNT は任意の値
#
	const char* XOR_SEED = "ABCDE12345";
	const int XOR_SEED_CNT = 10;


# cocos/platform/CCImage.cpp line 515
#
# 画像データを扱うImage関数 (cocos2d-x 3.13)
#
#
bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen)
{
    bool ret = false;
    
    do
    {
        CC_BREAK_IF(! data || dataLen <= 0);
        
        unsigned char* unpackedData = nullptr;
        ssize_t unpackedLen = 0;
        
        //detect and unzip the compress file
        if (ZipUtils::isCCZBuffer(data, dataLen))
        {
            unpackedLen = ZipUtils::inflateCCZBuffer(data, dataLen, &unpackedData);
        }
        else if (ZipUtils::isGZipBuffer(data, dataLen))
        {
            unpackedLen = ZipUtils::inflateMemory(const_cast<unsigned char*>(data), dataLen, &unpackedData);
        }
        else
        {
            unpackedData = const_cast<unsigned char*>(data);
            unpackedLen = dataLen;
        }

        _fileType = detectFormat(unpackedData, unpackedLen);

        switch (_fileType)
        {
        case Format::PNG:
            ret = initWithPngData(unpackedData, unpackedLen);
            break;
        case Format::JPG:
            ret = initWithJpgData(unpackedData, unpackedLen);
            break;
        case Format::TIFF:
            ret = initWithTiffData(unpackedData, unpackedLen);
            break;
        case Format::WEBP:
            ret = initWithWebpData(unpackedData, unpackedLen);
            break;
        case Format::PVR:
            ret = initWithPVRData(unpackedData, unpackedLen);
            break;
        case Format::ETC:
            ret = initWithETCData(unpackedData, unpackedLen);
            break;
        case Format::S3TC:
            ret = initWithS3TCData(unpackedData, unpackedLen);
            break;
        case Format::ATITC:
            ret = initWithATITCData(unpackedData, unpackedLen);
            break;
        default:
            {

            // ここから -------------------------------------------
                // XOR/PNG
                int ci = XOR_SEED_CNT; 
                unpackedData = const_cast<unsigned char*>(data);

                for (int i = 0; i < unpackedLen; i++) {
                    int idx = i % ci;
                    int key = XOR_SEED[idx] % 256;
                    unpackedData[i] = unpackedData[i] ^ key;
                }

                _fileType = detectFormat(unpackedData, unpackedLen);
                //
                if (_fileType == Format::PNG) {
                    ret = initWithPngData(unpackedData, unpackedLen);
                    break;
                }
           // ここまで ---------------------------------------------

                // load and detect image format
                tImageTGA* tgaData = tgaLoadBuffer(unpackedData, unpackedLen);
                
                if (tgaData != nullptr && tgaData->status == TGA_OK)
                {
                    ret = initWithTGAData(tgaData);
                }
                else
                {

                    CCLOG("cocos2d: unsupported image format!");
                }
                
                free(tgaData);
                break;
            }
        }
        
        if(unpackedData != data)
        {
            free(unpackedData);
        }
    } while (0);
    
    return ret;
}

cocos2d-x 3.13 テキストラベルが白くなる

8月末にバージョンアップされたcocos2d-xを早速使ってみると
いままで cocos studio で色を付けていたラベルの部分が全部白くなってしまう不具合があった。

# cocos/2d/CCLabel.cpp line 1894

void Label::updateDisplayedColor(const Color3B& parentColor)
{
    Node::updateDisplayedColor(parentColor);

    if (_currentLabelType == LabelType::TTF || _currentLabelType == LabelType::STRING_TEXTURE)
    // ここをコメントアウト    setTextColor(Color4B(_displayedColor));

とりあえず、上記をコメントアウトすることで対応。
ラベルのタイプで色を初期化するみたいなことしてると思うのだけれども
必要あると分かるまではコメントアウトでいいでしょう。

Lua5.1 用 metatable のマジックメソッド __next を実装する

Lua5.1には、metatableで利用できる、__next が無いらしいので独自に拡張する。


以下を参考
GeneralizedPairsAndIpairs

-- next関数の拡張
rawnext = next
function next(t,k)
  local m = getmetatable(t)
  local n = m and m.__next or rawnext
  return n(t,k)
end

-- nextの拡張だけで以下のようにできる
local priv = {a = 1, b = 2, c = 3}
local mt = {
  __next = function(t, k) 
    --
    -- ここに適当な処理を追加できる
    --
    return next(priv, k) 
  end
}
local t = setmetatable({}, mt)

for k,v in next, t do print(k,v) end

すばらしい。


cocos2d-x Lua メモリ改竄のチート対策でデータをジャミングしたい時などに、このmetatable使って処理するとやりやすいかも。

--
--
--
function encodeXXX()
  return -- デコード処理
end
--
--
--
function decodeXXX()
  return -- デコード処理
end
--
--
--
function createEncTable()
  local t1 = {}
  
  local t2 = setmetatable({},{
    __index = function(t, key)
      return decodeXXX(t1[key])
    end,
    __newindex = function(t, key, val)
      t1[key] = encodeXXX(val)
    end,
    __next = function(t, k)
      local t2 = {}
      for k,v in pairs(t1) do
        t2[k] = decodeXXX(v)
      end
      return next(t2,k)
    end
  })

  return t2
end

基本的な対策としてはジャミングが目的なので
エンコード部分は適当なXORとかの簡易なものでもいいと思う。

CocosCreator 以前のツールのダウンロード

Cocos CocosForWin CocosForMac CocosStudio CocosCodeIDE など公式からダウンロードできなくなったソフトは以下からまだダウンロードできるみたいです。


https://github.com/fusijie/Cocos-Resource#cocos-studio-%E4%B8%8B%E8%BD%BD

ccui.EditBox に、openKeyboard closeKeyboard がなかったので追加

なぜか、C++のファイルにキーボードをON/OFFする関数が定義されてなかったので追加した。
Implファイルにはあるのでプラットフォームごとの定義はある。
ただ、Lua-bindings を利用している場合は、UIEditBox.h UIEditBox.cpp から、
bindを自動生成しているのでこちらに記述がないとLuaから使えないので追加した。

cocos2d-x/cocos/ui/UIEditBox/UIEditBox.h

public: 

 virtual void openKeyboard();
 virtual void closeKeyboard();

cocos2d-x/cocos/ui/UIEditBox/UIEditBox.cpp

void EditBox::openKeyboard()
{
	if (_editBoxImpl != nullptr)
	{
		_editBoxImpl->openKeyboard();
	}
}

void EditBox::closeKeyboard()
{
	if (_editBoxImpl != nullptr)
	{
		_editBoxImpl->closeKeyboard();
	}
}

wxSqlite3で暗号化 sqlite3をセキュアに利用する

環境 Centos6


wsqlite3をダウンロードして解凍後コンパイルする。
https://sourceforge.net/projects/wxcode/files/Components/wxSQLite3/

cd [wxSqlite3 dir]/sqlite3/secure/src/

gcc -o sqlite3 -DSQLITE_HAS_CODEC=1 -DSQLITE_USER_AUTHENTICATION=0 shell.c sqlite3secure.c -ldl -lpthread

使い方

./sqlite3  test.db

>PRAGMA KEY='passcode';  # 最初にパスコードを指定する
>create table test(a,b);
>insert into test(a,b)values(1,2);
>select * from test;
>1|2
>.q # 終了

./sqlite3 test.db 
># パスコードを指定しない
>select * from test;
>Error: file is encrypted or is not a database
>.q #終了

./sqlite3 test.db
>PRAGMA KEY='passcode'; #  最初にパスコードを指定する
>select * from test;
>1|2
>.q #終了

これを利用するとcocos2d-xでwxsqlite3を利用するときに、外部でwxsqlite3を暗号化したデータベースを読み込ませることができる。

cocos2d-x Lua lua-binding に setOnJSCallback を追加した

cocos2d-x 3.12

WebViewクラスのsetOnJSCallback に相当するbind関数が
js-bindings の方には、追加されているが、lua-bindings には無かったので
適当に追加してみた。experimental なのであまり細かく調整されていないのかもしれないな。
Lua使ってる人少なそうだし。

# frameworks/cocos2d-x/cocos/scripting/lua-bindings/manula/ui/lua_cocos2dx_experimental_webview_manual.cpp


static int lua_cocos2dx_experimental_WebView_setOnJSCallback(lua_State* L)
{
    
    int argc = 0;
    cocos2d::experimental::ui::WebView* self = nullptr;
    
#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
    if (!tolua_isusertype(L,1,"ccexp.WebView",0,&tolua_err)) goto tolua_lerror;
#endif
    
    self = static_cast<cocos2d::experimental::ui::WebView*>(tolua_tousertype(L,1,0));
    
#if COCOS2D_DEBUG >= 1
    if (nullptr == self) {
        tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_experimental_WebView_setOnJSCallback'\n", nullptr);
        return 0;
    }
#endif
    
    argc = lua_gettop(L) - 1;
    
    if (argc == 1)
    {
#if COCOS2D_DEBUG >= 1
        if (!toluafix_isfunction(L,2,"LUA_FUNCTION",0,&tolua_err))
        {
            goto tolua_lerror;
        }
#endif
        
        LUA_FUNCTION handler = (  toluafix_ref_function(L,2,0));
        std::function<void(experimental::ui::WebView *sender, const std::string &url)> callback = [L,handler](experimental::ui::WebView *sender, const std::string &message){
            toluafix_pushusertype_ccobject(L, sender->_ID, &(sender->_luaID), (void*)sender,"ccexp.WebView");
            tolua_pushcppstring(L, message);
            LuaEngine::getInstance()->getLuaStack()->executeFunctionByHandler(handler, 2);
        };
        
        ScriptHandlerMgr::getInstance()->addCustomHandler((void*)self, handler);
        self->setOnJSCallback(callback);
        return 0;
    }
    luaL_error(L, "%s has wrong number of arguments: %d, was expecting %d\n ", "ccexp.WebView:setOnJSCallback",argc, 1);
    return 0;
#if COCOS2D_DEBUG >= 1
tolua_lerror:
    tolua_error(L, "#ferror in function 'lua_cocos2dx_experimental_WebView_setOnJSCallback'.", &tolua_err);
#endif
    return 0;
}


static void extendWebView(lua_State* L)
{
    lua_pushstring(L, "ccexp.WebView");
    lua_rawget(L, LUA_REGISTRYINDEX);
    if (lua_istable(L,-1))
    {
        tolua_function(L, "setOnShouldStartLoading", lua_cocos2dx_experimental_WebView_setOnShouldStartLoading);
        tolua_function(L, "setOnDidFinishLoading", lua_cocos2dx_experimental_WebView_setOnDidFinishLoading);
        tolua_function(L, "setOnDidFailLoading", lua_cocos2dx_experimental_WebView_setOnDidFailLoading);
        tolua_function(L, "setOnJSCallback", lua_cocos2dx_experimental_WebView_setOnJSCallback);
    }
    lua_pop(L, 1);
}

cocos2d-x Lua で開発してます。
C++も多少いじりますが、あくまでLuaにこだわってやってます。