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); }