├── .gitignore ├── LICENSE ├── README.md ├── assets ├── New Scene.fire ├── New Scene.fire.meta ├── NewScript.js └── NewScript.js.meta ├── creator.d.ts ├── doc ├── icon.png └── scene.png ├── jsconfig.json ├── local ├── assets.json ├── console.json ├── hierarchy.json ├── local.json ├── node-library.json └── scene.json ├── packages └── plugin-bugly │ ├── bugly │ └── 1.4.3 │ │ ├── bugly │ │ ├── .DS_Store │ │ ├── Android.mk │ │ ├── CrashReport.h │ │ ├── CrashReport.mm │ │ ├── js │ │ │ ├── Android.mk │ │ │ ├── BuglyJSAgent.cpp │ │ │ └── BuglyJSAgent.h │ │ └── lua │ │ │ ├── Android.mk │ │ │ ├── BuglyLuaAgent.cpp │ │ │ └── BuglyLuaAgent.h │ │ ├── libs │ │ ├── bugly_agent.jar │ │ └── bugly_crash_release.jar │ │ └── prebuilt │ │ └── armeabi-v7a │ │ └── libBugly.so │ ├── buglySymbolAndroid │ ├── buglySymbolAndroid.bat │ ├── buglySymbolAndroid.jar │ ├── buglySymbolAndroid.sh │ ├── settings.txt │ └── 符号表工具Android版-使用指南.pdf │ ├── core │ └── CfgUtil.js │ ├── i18n │ ├── en.js │ └── zh.js │ ├── main.js │ ├── package.json │ └── panel │ ├── index.css │ ├── index.html │ └── index.js ├── project.json ├── settings └── project.json ├── template-banner.png └── template.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | library/ 3 | build/ 4 | temp/ 5 | settings/ 6 | local/ 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 xu_yanfeng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 注意 2 | - 仓库已经迁徙到https://github.com/tidys/CocosCreatorPlugins/tree/master/packages/plugin-bugly, 方便统一管理插件 3 | ## 腾讯bugly接入插件 4 | - 插件开源地址: https://github.com/tidys/cocos-cretor-bugly-plugin 5 | - bugly官方文档: https://bugly.qq.com/docs/user-guide/instruction-manual-plugin-cocos/?v=20170912151050 6 | 7 | 8 | ## 功能 9 | - 修改android工程配置 10 | - 符号表自动上传功能 11 | 12 | ## 参数 13 | - App Id: 腾讯bugly后台提供 14 | - App Key: 腾讯bugly后台提供 15 | - App Package: 游戏包名,插件会自动读取项目的配置 16 | - App Version: 游戏版本 17 | - App Channal: 游戏渠道 18 | - 自动上传符号表: 是否自动上传生成的符号表文件 19 | 20 | 21 | ## 注意 22 | - 插件中使用的是bugly1.4.3 23 | - creator建议1.7.x以上 24 | - **添加Bugly** 操作只需要App Id 25 | - **生成符号表** 操作需要所有参数 26 | - **生成符号表** 需要java环境,请确保已经安装java,并且**JRE或JDK版本需要 >= 1.6** 27 | 28 | 有啥好的意见可以提议,后期会不断优化 29 | -------------------------------------------------------------------------------- /assets/New Scene.fire: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "__type__": "cc.SceneAsset", 4 | "_name": "", 5 | "_objFlags": 0, 6 | "_rawFiles": null, 7 | "scene": { 8 | "__id__": 1 9 | } 10 | }, 11 | { 12 | "__type__": "cc.Scene", 13 | "_objFlags": 0, 14 | "_parent": null, 15 | "_children": [ 16 | { 17 | "__id__": 2 18 | } 19 | ], 20 | "_tag": -1, 21 | "_active": true, 22 | "_components": [], 23 | "_prefab": null, 24 | "_id": "2d3c7aea-38d7-4b6d-a34b-c0f6691bde13", 25 | "_opacity": 255, 26 | "_color": { 27 | "__type__": "cc.Color", 28 | "r": 255, 29 | "g": 255, 30 | "b": 255, 31 | "a": 255 32 | }, 33 | "_cascadeOpacityEnabled": true, 34 | "_anchorPoint": { 35 | "__type__": "cc.Vec2", 36 | "x": 0, 37 | "y": 0 38 | }, 39 | "_contentSize": { 40 | "__type__": "cc.Size", 41 | "width": 0, 42 | "height": 0 43 | }, 44 | "_localZOrder": 0, 45 | "_globalZOrder": 0, 46 | "_opacityModifyRGB": false, 47 | "groupIndex": 0, 48 | "autoReleaseAssets": null 49 | }, 50 | { 51 | "__type__": "cc.Node", 52 | "_name": "Canvas", 53 | "_objFlags": 0, 54 | "_parent": { 55 | "__id__": 1 56 | }, 57 | "_children": [ 58 | { 59 | "__id__": 3 60 | } 61 | ], 62 | "_tag": -1, 63 | "_active": true, 64 | "_components": [ 65 | { 66 | "__id__": 5 67 | }, 68 | { 69 | "__id__": 6 70 | } 71 | ], 72 | "_prefab": null, 73 | "_id": "87fx18rYJJLKqyepGjwlOC", 74 | "_opacity": 255, 75 | "_color": { 76 | "__type__": "cc.Color", 77 | "r": 255, 78 | "g": 255, 79 | "b": 255, 80 | "a": 255 81 | }, 82 | "_cascadeOpacityEnabled": true, 83 | "_anchorPoint": { 84 | "__type__": "cc.Vec2", 85 | "x": 0.5, 86 | "y": 0.5 87 | }, 88 | "_contentSize": { 89 | "__type__": "cc.Size", 90 | "width": 960, 91 | "height": 640 92 | }, 93 | "_rotationX": 0, 94 | "_rotationY": 0, 95 | "_scaleX": 1, 96 | "_scaleY": 1, 97 | "_position": { 98 | "__type__": "cc.Vec2", 99 | "x": 480, 100 | "y": 320 101 | }, 102 | "_skewX": 0, 103 | "_skewY": 0, 104 | "_localZOrder": 0, 105 | "_globalZOrder": 0, 106 | "_opacityModifyRGB": false, 107 | "groupIndex": 0 108 | }, 109 | { 110 | "__type__": "cc.Node", 111 | "_name": "New Label", 112 | "_objFlags": 0, 113 | "_parent": { 114 | "__id__": 2 115 | }, 116 | "_children": [], 117 | "_tag": -1, 118 | "_active": true, 119 | "_components": [ 120 | { 121 | "__id__": 4 122 | } 123 | ], 124 | "_prefab": null, 125 | "_id": "51PEkBOpJAPZoehMEKmSTz", 126 | "_opacity": 255, 127 | "_color": { 128 | "__type__": "cc.Color", 129 | "r": 255, 130 | "g": 255, 131 | "b": 255, 132 | "a": 255 133 | }, 134 | "_cascadeOpacityEnabled": true, 135 | "_anchorPoint": { 136 | "__type__": "cc.Vec2", 137 | "x": 0.5, 138 | "y": 0.5 139 | }, 140 | "_contentSize": { 141 | "__type__": "cc.Size", 142 | "width": 351.27, 143 | "height": 40 144 | }, 145 | "_rotationX": 0, 146 | "_rotationY": 0, 147 | "_scaleX": 1, 148 | "_scaleY": 1, 149 | "_position": { 150 | "__type__": "cc.Vec2", 151 | "x": 0, 152 | "y": 0 153 | }, 154 | "_skewX": 0, 155 | "_skewY": 0, 156 | "_localZOrder": 0, 157 | "_globalZOrder": 0, 158 | "_opacityModifyRGB": false, 159 | "groupIndex": 0 160 | }, 161 | { 162 | "__type__": "cc.Label", 163 | "_name": "", 164 | "_objFlags": 0, 165 | "node": { 166 | "__id__": 3 167 | }, 168 | "_enabled": true, 169 | "_useOriginalSize": false, 170 | "_actualFontSize": 40, 171 | "_fontSize": 40, 172 | "_lineHeight": 40, 173 | "_enableWrapText": true, 174 | "_N$file": null, 175 | "_isSystemFontUsed": true, 176 | "_spacingX": 0, 177 | "_N$string": "Cocos-Bugly-Plugin", 178 | "_N$horizontalAlign": 1, 179 | "_N$verticalAlign": 1, 180 | "_N$fontFamily": "Arial", 181 | "_N$overflow": 0 182 | }, 183 | { 184 | "__type__": "cc.Canvas", 185 | "_name": "", 186 | "_objFlags": 0, 187 | "node": { 188 | "__id__": 2 189 | }, 190 | "_enabled": true, 191 | "_designResolution": { 192 | "__type__": "cc.Size", 193 | "width": 960, 194 | "height": 640 195 | }, 196 | "_fitWidth": false, 197 | "_fitHeight": true 198 | }, 199 | { 200 | "__type__": "bfc94MeRoNMdYCIViT1Qrvx", 201 | "_name": "", 202 | "_objFlags": 0, 203 | "node": { 204 | "__id__": 2 205 | }, 206 | "_enabled": true 207 | } 208 | ] -------------------------------------------------------------------------------- /assets/New Scene.fire.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.0", 3 | "uuid": "2d3c7aea-38d7-4b6d-a34b-c0f6691bde13", 4 | "asyncLoadAssets": false, 5 | "autoReleaseAssets": false, 6 | "subMetas": {} 7 | } -------------------------------------------------------------------------------- /assets/NewScript.js: -------------------------------------------------------------------------------- 1 | cc.Class({ 2 | extends: cc.Component, 3 | 4 | properties: { 5 | 6 | }, 7 | 8 | 9 | onLoad () { 10 | 11 | }, 12 | 13 | start () { 14 | 15 | }, 16 | 17 | // update (dt) {}, 18 | }); 19 | -------------------------------------------------------------------------------- /assets/NewScript.js.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.0.5", 3 | "uuid": "bfc9431e-4683-4c75-8088-5624f542bbf1", 4 | "isPlugin": false, 5 | "loadPluginInWeb": true, 6 | "loadPluginInNative": true, 7 | "loadPluginInEditor": false, 8 | "subMetas": {} 9 | } -------------------------------------------------------------------------------- /doc/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tidys/cocos-cretor-bugly-plugin/21435bf3c2b9be45b55d5596bbd8d39f06bf201a/doc/icon.png -------------------------------------------------------------------------------- /doc/scene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tidys/cocos-cretor-bugly-plugin/21435bf3c2b9be45b55d5596bbd8d39f06bf201a/doc/scene.png -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "experimentalDecorators": true 6 | }, 7 | "exclude": [ 8 | "node_modules", 9 | ".vscode", 10 | "library", 11 | "local", 12 | "settings", 13 | "temp" 14 | ] 15 | } -------------------------------------------------------------------------------- /local/assets.json: -------------------------------------------------------------------------------- 1 | { 2 | "item-states": [ 3 | { 4 | "folded": false, 5 | "id": "mount-assets" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /local/console.json: -------------------------------------------------------------------------------- 1 | { 2 | "fontsize": 14, 3 | "lineheight": 30 4 | } -------------------------------------------------------------------------------- /local/hierarchy.json: -------------------------------------------------------------------------------- 1 | { 2 | "item-states": [ 3 | { 4 | "folded": true, 5 | "id": "87fx18rYJJLKqyepGjwlOC" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /local/local.json: -------------------------------------------------------------------------------- 1 | { 2 | "last-edit": "2d3c7aea-38d7-4b6d-a34b-c0f6691bde13" 3 | } -------------------------------------------------------------------------------- /local/node-library.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": null 3 | } -------------------------------------------------------------------------------- /local/scene.json: -------------------------------------------------------------------------------- 1 | { 2 | "designWidth": 640, 3 | "designHeight": 480 4 | } -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/bugly/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tidys/cocos-cretor-bugly-plugin/21435bf3c2b9be45b55d5596bbd8d39f06bf201a/packages/plugin-bugly/bugly/1.4.3/bugly/.DS_Store -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/bugly/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := bugly_crashreport_cocos_static 6 | 7 | LOCAL_MODULE_FILENAME := libcrashreport 8 | 9 | LOCAL_CPP_EXTENSION := .mm .cpp .cc 10 | LOCAL_CFLAGS += -x c++ 11 | 12 | LOCAL_SRC_FILES := CrashReport.mm 13 | 14 | LOCAL_C_INCLUDES := $(LOCAL_PATH)\ 15 | $(LOCAL_PATH)/../ \ 16 | $(LOCAL_PATH)/../../ \ 17 | $(LOCAL_PATH)/../../cocos/base \ 18 | $(LOCAL_PATH)/../../cocos \ 19 | $(LOCAL_PATH)/../../cocos/2d \ 20 | $(LOCAL_PATH)/../../cocos/2d/platform/android \ 21 | $(LOCAL_PATH)/../../cocos/platform/android \ 22 | $(LOCAL_PATH)/../../cocos/math/kazmath \ 23 | $(LOCAL_PATH)/../../cocos/physics \ 24 | $(LOCAL_PATH)/../../cocos2dx \ 25 | $(LOCAL_PATH)/../../cocos2dx/include \ 26 | $(LOCAL_PATH)/../../cocos2dx/platform/android \ 27 | $(LOCAL_PATH)/../../cocos2dx/kazmath/include \ 28 | $(LOCAL_PATH)/../../external 29 | 30 | include $(BUILD_STATIC_LIBRARY) -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/bugly/CrashReport.h: -------------------------------------------------------------------------------- 1 | /****************************************************** 2 | Copyright (C) 2016 Tencent Bugly, Inc. 3 | 4 | https://bugly.qq.com/v2 5 | 6 | 7 | Version: 1.3.3 8 | 9 | ******************************************************/ 10 | 11 | #ifndef CRASHREPORT_H 12 | #define CRASHREPORT_H 13 | 14 | #ifndef CATEGORY_LUA_EXCEPTION 15 | #define CATEGORY_LUA_EXCEPTION 6 16 | #endif 17 | 18 | #ifndef CATEGORY_JS_EXCEPTION 19 | #define CATEGORY_JS_EXCEPTION 5 20 | #endif 21 | 22 | #include "cocos2d.h" 23 | 24 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 25 | #include 26 | #endif 27 | 28 | class CrashReport 29 | { 30 | public: 31 | 32 | /** 33 | * @brief 初始化 34 | * 35 | * @param appId 注册应用时,Bugly分配的AppID 36 | */ 37 | static void initCrashReport(const char* appId); 38 | 39 | /** 40 | * @brief 初始化 41 | * 42 | * @param appId 注册应用时,Bugly分配的AppID 43 | * @param debug 是否开启Debug信息打印,默认关闭,开启则会打印SDK的调试信息 44 | */ 45 | static void initCrashReport(const char* appId, bool debug); 46 | 47 | /** 48 | * @brief 设置应用的用户唯一标识 49 | * 50 | * @param userId 51 | */ 52 | static void setUserId(const char* userId); 53 | 54 | /** 55 | * @brief 上报自定义错误 56 | * 57 | * @param category 错误的分类,5表示Lua错误,6表示JS错误 58 | * @param type 错误类型的名称 59 | * @param msg 错误原因 60 | * @param traceback 错误堆栈 61 | */ 62 | static void reportException(int category, const char* type, const char* msg, const char* traceback); 63 | 64 | static void reportException(int category, const char* type, const char* msg, const char* traceback, bool quit); 65 | 66 | /** 67 | * @brief 设置自定义标签,标签需预先在Bugly平台定义 68 | * 69 | * @param tag 70 | */ 71 | static void setTag(int tag); 72 | 73 | /** 74 | * @brief 设置自定义Key-Value 75 | * 76 | * @param key 77 | * @param value 78 | */ 79 | static void addUserValue(const char* key, const char* value); 80 | 81 | /** 82 | * @brief 删除指定的Key-Value 83 | * 84 | * @param key 85 | */ 86 | static void removeUserValue(const char* key); 87 | 88 | /** 89 | * 日志级别 90 | */ 91 | enum CRLogLevel{ Off=0, Error=1,Warning=2,Info=3,Debug=4,Verbose=5 }; 92 | 93 | /** 94 | * @brief 自定义日志 95 | * 96 | * @param level 日志级别 {@link CRLogLevel} 97 | * @param tag 日志标签 98 | * @param fmt 日志内容 99 | * @param ... 动态参数 100 | */ 101 | static void log(CrashReport::CRLogLevel level, const char* tag, const char* fmt, ...); 102 | 103 | /** 104 | * @brief 初始化 105 | * 106 | * @param appId 注册应用时,Bugly分配的AppID 107 | * @param debug 是否开启Debug信息打印,默认关闭,开启则会打印SDK的调试信息 108 | * @param level 是否开启崩溃时自定义日志的上报,默认值为 {@link CRLogLevel:Off},即关闭。设置为其他的值,即会在崩溃时上报自定义日志。如设置为CRLogLevel:Warning,则会上报CRLogLevel:Warning、CRLogLevel:Error的日志 109 | */ 110 | static void initCrashReport(const char* appId, bool debug, CrashReport::CRLogLevel level); 111 | 112 | /** 113 | * @brief 设置渠道 114 | * 115 | * @param channel 渠道标识 116 | */ 117 | static void setAppChannel(const char* channel); 118 | 119 | /** 120 | * @brief 设置应用版本 121 | * 122 | * @param version 应用版本信息 123 | */ 124 | static void setAppVersion(const char* version); 125 | 126 | /** 127 | * @brief 设置CrashReporter的渠道类别,默认值为0,表示官方版本,2表示MSDK内置版本,3表示IM SDK内置版本 128 | * 129 | * @param type 130 | */ 131 | static void setCrashReporterType(int type); 132 | 133 | /** 134 | * @brief 设置游戏类型,Cocos为1 135 | */ 136 | static void setGameType(); 137 | 138 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 139 | /** 140 | * @brief 检查JNI调用是否存在Pending exception 141 | * 142 | * @param env 143 | */ 144 | static bool checkPendingException(JNIEnv* env); 145 | 146 | static JNIEnv* getJniEnv(); 147 | 148 | static jstring getJniString(JNIEnv* env, const char* str); 149 | 150 | static void releaseJniString(JNIEnv* env, jstring jniString); 151 | 152 | static bool callJniStaticVoidMethod(JNIEnv* env, const char* className, const char* methodName, const char* paramType, ...); 153 | #endif 154 | 155 | CrashReport(); 156 | private: 157 | static bool initialized; 158 | static bool hasSetGameType; 159 | static int crashReporterType; 160 | }; 161 | 162 | #endif 163 | -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/bugly/CrashReport.mm: -------------------------------------------------------------------------------- 1 | 2 | #include "CrashReport.h" 3 | 4 | #include "cocos2d.h" 5 | #include 6 | 7 | #define LOG_TAG "CrashReport" 8 | #define LOG_BUFFER_SIZE 1024 9 | 10 | #ifndef GAME_TYPE_COCOS 11 | #define GAME_TYPE_COCOS 1 12 | #endif 13 | 14 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 15 | 16 | #include 17 | #include 18 | #include "platform/android/jni/JniHelper.h" 19 | 20 | #define LOGD(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##args) 21 | #define LOGI(fmt, args...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, fmt, ##args) 22 | #define LOGW(fmt, args...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, fmt, ##args) 23 | #define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, fmt, ##args) 24 | 25 | #define CRASHREPORT_CLASS "com/tencent/bugly/agent/GameAgent" 26 | #define METHOD_INIT "initCrashReport" 27 | #define METHOD_INIT_PARAMETER "(Ljava/lang/String;Z)V" 28 | #define METHOD_POST_EXCEPTION "postException" 29 | #define METHOD_POST_EXCEPTION_PARAMETER "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V" 30 | #define METHOD_SET_USER_ID "setUserId" 31 | #define METHOD_SET_USER_ID_PARAMETER "(Ljava/lang/String;)V" 32 | #define METHOD_SET_CHANNEL "setAppChannel" 33 | #define METHOD_SET_CHANNEL_PARAMETER "(Ljava/lang/String;)V" 34 | #define METHOD_SET_VERSION "setAppVersion" 35 | #define METHOD_SET_VERSION_PARAMETER "(Ljava/lang/String;)V" 36 | #define METHOD_SET_GAME_TYPE "setGameType" 37 | #define METHOD_SET_GAME_TYPE_PARAMETER "(I)V" 38 | #define METHOD_SET_LOG "setLog" 39 | #define METHOD_SET_LOG_PARAMETER "(ILjava/lang/String;Ljava/lang/String;)V" 40 | #define METHOD_SET_USER_SCENE_TAG "setUserSceneTag" 41 | #define METHOD_SET_USER_SCENE_TAG_PARAMETER "(I)V" 42 | #define METHOD_PUT_USER_DATA "putUserData" 43 | #define METHOD_PUT_USER_DATA_PARAMETER "(Ljava/lang/String;Ljava/lang/String;)V" 44 | #define METHOD_REMOVE_USER_DATA "removeUserData" 45 | #define METHOD_REMOVE_USER_DATA_PARAMETER "(Ljava/lang/String;)V" 46 | #define METHOD_SET_SDK_CHANNEL "setSdkPackageName" 47 | #define METHOD_SET_SDK_CHANNEL_PARAMETER "(Ljava/lang/String;)V" 48 | 49 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 50 | #import 51 | 52 | #define NSStringMake(const_char_pointer) (const_char_pointer == NULL ? nil : @(const_char_pointer)) 53 | #define NSStringMakeNonnull(const_char_pointer) (const_char_pointer == NULL ? @"" : @(const_char_pointer)) 54 | 55 | #define LOGD(fmt, args...) CCLOG("[Debug] %s: " fmt, LOG_TAG, ##args) 56 | #define LOGI(fmt, args...) CCLOG("[Info] %s: " fmt, LOG_TAG, ##args) 57 | #define LOGW(fmt, args...) CCLOGERROR("[Warn] %s: " fmt, LOG_TAG, ##args) 58 | #define LOGE(fmt, args...) CCLOGERROR("[Error] %s: " fmt, LOG_TAG, ##args) 59 | 60 | #define BUGLY_AGENT_CLASS @"BuglyAgent" 61 | #define BUGLY_AGENT_METHOD_INIT @"initWithAppId:debugMode:" 62 | #define BUGLY_AGENT_METHOD_INIT_LOG @"initWithAppId:debugMode:logger:" 63 | #define BUGLY_AGENT_METHOD_USER @"setUserIdentifier:" 64 | #define BUGLY_AGENT_METHOD_CHANNEL @"setAppChannel:" 65 | #define BUGLY_AGENT_METHOD_VERSION @"setAppVersion:" 66 | #define BUGLY_AGENT_METHOD_EXCEPTION @"reportException:name:message:stackTrace:userInfo:terminateApp:" 67 | #define BUGLY_AGENT_METHOD_SCENE @"setSceneTag:" 68 | #define BUGLY_AGENT_METHOD_SCENE_VALUE @"setSceneValue:forKey:" 69 | #define BUGLY_AGENT_METHOD_SCENE_CLEAN @"removeSceneValueForKey:" 70 | #define BUGLY_AGENT_METHOD_LOG @"level:tag:log:" 71 | #define BUGLY_AGENT_METHOD_CONFIG_REPORTER_TYPE @"configCrashReporterType:" 72 | #endif 73 | 74 | CrashReport::CrashReport(){ 75 | LOGD("%s", __FUNCTION__); 76 | } 77 | 78 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 79 | 80 | bool CrashReport::checkPendingException(JNIEnv* env) { 81 | if (env == NULL) { 82 | return false; 83 | } 84 | 85 | if (env->ExceptionOccurred() != 0) { 86 | LOGE("[cocos2d-x] check jni error"); 87 | env->ExceptionDescribe(); 88 | env->ExceptionClear(); 89 | return true; 90 | } 91 | return false; 92 | } 93 | 94 | JNIEnv* CrashReport::getJniEnv() { 95 | JavaVM* jvm = cocos2d::JniHelper::getJavaVM(); 96 | if (jvm == NULL) { 97 | LOGE("[cocos2d-x] JavaVM is null."); 98 | return NULL; 99 | } 100 | JNIEnv* env = NULL; 101 | jvm->GetEnv((void**)&env, JNI_VERSION_1_6); 102 | if (env == NULL) { 103 | LOGE("[cocos2d-x] failed to get env."); 104 | return NULL; 105 | } 106 | return env; 107 | } 108 | 109 | jstring CrashReport::getJniString(JNIEnv* jniEnv, const char* str) { 110 | if (str == NULL) { 111 | return NULL; 112 | } 113 | 114 | JNIEnv *env = jniEnv; 115 | if (env == NULL) { 116 | env = getJniEnv(); 117 | } 118 | if (env == NULL) { 119 | return NULL; 120 | } 121 | jstring jniString = env->NewStringUTF(str); 122 | if (checkPendingException(env)) { 123 | LOGE("[cocos2d-x] failed to new Java UTF string: %s", str); 124 | return NULL; 125 | } 126 | return jniString; 127 | } 128 | 129 | void CrashReport::releaseJniString(JNIEnv* jniEnv, jstring jniString) { 130 | if (jniString == NULL) { 131 | return; 132 | } 133 | 134 | JNIEnv *env = jniEnv; 135 | if (env == NULL) { 136 | env = getJniEnv(); 137 | } 138 | if (env == NULL) { 139 | return; 140 | } 141 | env->DeleteLocalRef(jniString); 142 | } 143 | 144 | bool CrashReport::callJniStaticVoidMethod(JNIEnv* jniEnv, const char* className, const char* methodName, const char* paramType, ...) { 145 | if (className == NULL || methodName == NULL || paramType == NULL) { 146 | LOGE("[cocos2d-x] parameters input to callJniStaticVoidMethod is not enough."); 147 | return false; 148 | } 149 | 150 | JNIEnv *env = jniEnv; 151 | if (env == NULL) { 152 | env = getJniEnv(); 153 | } 154 | if (env == NULL) { 155 | LOGE("[cocos2d-x] can not get JNIEnv."); 156 | return false; 157 | } 158 | jclass jniClass = env->FindClass(className); 159 | if (checkPendingException(env)) { 160 | LOGE("[cocos2d-x] failed to find class: %s", className); 161 | return false; 162 | } 163 | jmethodID method = env->GetStaticMethodID(jniClass, methodName, paramType); 164 | if (checkPendingException(env)) { 165 | LOGE("[cocos2d-x] failed to find method '%s' with param type '%s'.", methodName, paramType); 166 | return false; 167 | } 168 | 169 | va_list args; 170 | va_start(args, paramType); 171 | LOGI("[cocos2d-x] trying to call method: %s", methodName); 172 | env->CallStaticVoidMethodV(jniClass, method, args); 173 | va_end(args); 174 | 175 | if (checkPendingException(env)) { 176 | LOGE("[cocos2d-x] failed to call method: %s", methodName); 177 | return false; 178 | } 179 | return true; 180 | } 181 | 182 | #endif 183 | 184 | void CrashReport::initCrashReport(const char* appId) { 185 | CrashReport::initCrashReport(appId, false); 186 | } 187 | 188 | void CrashReport::initCrashReport(const char* appId, bool isDebug) { 189 | CrashReport::initCrashReport(appId, isDebug, CrashReport::CRLogLevel::Off); 190 | } 191 | 192 | bool CrashReport::initialized = false; 193 | bool CrashReport::hasSetGameType = false; 194 | int CrashReport::crashReporterType = 0; 195 | 196 | void CrashReport::initCrashReport(const char* appId, bool isDebug, CrashReport::CRLogLevel level) { 197 | if (!initialized) { 198 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 199 | LOGI("[cocos2d-x] start init."); 200 | initialized = true; 201 | JavaVM* jvm = cocos2d::JniHelper::getJavaVM(); 202 | if (jvm == NULL) { 203 | LOGE("[cocos2d-x] JavaVM is null."); 204 | return; 205 | } 206 | JNIEnv* env = NULL; 207 | jvm->GetEnv((void**)&env, JNI_VERSION_1_6); 208 | if (env == NULL) { 209 | LOGE("[cocos2d-x] JNIEnv is null."); 210 | return; 211 | } 212 | jvm->AttachCurrentThread(&env, 0); 213 | //call channel set package name 214 | if (crashReporterType != 0) { 215 | 216 | LOGI("[cocos2d-x] set channel: %d", crashReporterType); 217 | const char* packageName = ""; 218 | switch(crashReporterType) { 219 | case 0: 220 | case 1: 221 | break; 222 | case 2: 223 | packageName = "com.tencent.bugly.msdk"; 224 | break; 225 | case 3: 226 | packageName = "com.tencent.bugly.imsdk"; 227 | break; 228 | default: 229 | break; 230 | } 231 | LOGI("set packagename: %s", packageName); 232 | jstring jPackageName = getJniString(env, packageName); 233 | callJniStaticVoidMethod(env, CRASHREPORT_CLASS, METHOD_SET_SDK_CHANNEL, METHOD_SET_SDK_CHANNEL_PARAMETER, jPackageName); 234 | releaseJniString(env, jPackageName); 235 | } 236 | 237 | // set game type 238 | setGameType(); 239 | 240 | // call init 241 | LOGI("[cocos2d-x] init Bugly by game agent."); 242 | jstring jAppId = getJniString(env, appId); 243 | callJniStaticVoidMethod(env, CRASHREPORT_CLASS, METHOD_INIT, METHOD_INIT_PARAMETER, jAppId, isDebug); 244 | releaseJniString(env, jAppId); 245 | // iOS 246 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 247 | NSString* pAppId = NSStringMake(appId); 248 | BOOL pDebug = isDebug ? YES : NO; 249 | 250 | Class clazz = NSClassFromString(BUGLY_AGENT_CLASS); 251 | if (clazz) { 252 | BOOL initLog = true; 253 | SEL selector = NSSelectorFromString(BUGLY_AGENT_METHOD_INIT_LOG); 254 | 255 | NSMethodSignature* signature = [clazz methodSignatureForSelector:selector]; 256 | if (signature == nil) { 257 | selector = NSSelectorFromString(BUGLY_AGENT_METHOD_INIT); 258 | signature = [clazz methodSignatureForSelector:selector]; 259 | 260 | initLog = false; 261 | } 262 | if (signature) { 263 | 264 | LOGI("Init the sdk with App ID: %s", appId); 265 | 266 | NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; 267 | if (invocation) { 268 | [invocation setTarget:clazz]; 269 | [invocation setSelector:selector]; 270 | 271 | [invocation setArgument:&pAppId atIndex:2]; 272 | [invocation setArgument:&pDebug atIndex:3]; 273 | 274 | if (initLog) { 275 | //Error=4,Warn=3,Info=2,Debug=1,Verbose=0,Off=-1 276 | //LogError=1<<0,Warn=1<<1,Info=1<<2,Debug=1<<3,Verbose=1<<4 277 | NSInteger pLevel = level; 278 | 279 | [invocation setArgument:&pLevel atIndex:4]; 280 | } 281 | 282 | [invocation invoke]; 283 | } 284 | } 285 | } else { 286 | LOGE("Fail to get class by NSClassFromString(%s)", BUGLY_AGENT_CLASS.UTF8String); 287 | } 288 | #endif /* iOS */ 289 | initialized = true; 290 | } 291 | 292 | } 293 | 294 | void CrashReport::setTag(int tag) { 295 | setGameType(); 296 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 297 | LOGI("[cocos2d-x] set user scene tag: %d", tag); 298 | 299 | callJniStaticVoidMethod(NULL, CRASHREPORT_CLASS, METHOD_SET_USER_SCENE_TAG, METHOD_SET_USER_SCENE_TAG_PARAMETER, tag); 300 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 301 | if (tag < 0) { 302 | return; 303 | } 304 | NSUInteger pTag = tag; 305 | 306 | Class clazz = NSClassFromString(BUGLY_AGENT_CLASS); 307 | if (clazz) { 308 | SEL selector = NSSelectorFromString(BUGLY_AGENT_METHOD_SCENE); 309 | NSMethodSignature* signature = [clazz methodSignatureForSelector:selector]; 310 | if (signature) { 311 | 312 | LOGI("Set user scene tag id: %d", tag); 313 | 314 | NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; 315 | if (invocation) { 316 | [invocation setTarget:clazz]; 317 | [invocation setSelector:selector]; 318 | 319 | [invocation setArgument:&pTag atIndex:2]; 320 | 321 | [invocation invoke]; 322 | } 323 | } 324 | } else { 325 | LOGE("Fail to get class by NSClassFromString(%s)", BUGLY_AGENT_CLASS.UTF8String); 326 | } 327 | #endif 328 | } 329 | 330 | void CrashReport::addUserValue(const char* key, const char* value) { 331 | setGameType(); 332 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 333 | LOGI("[cocos2d-x] put user data: %s:%s", key, value); 334 | JNIEnv* env = getJniEnv(); 335 | 336 | jstring jKey = getJniString(env, key); 337 | jstring jValue = getJniString(env, value); 338 | callJniStaticVoidMethod(env, CRASHREPORT_CLASS, METHOD_PUT_USER_DATA, METHOD_PUT_USER_DATA_PARAMETER, jKey, jValue); 339 | releaseJniString(env, jKey); 340 | releaseJniString(env, jValue); 341 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 342 | NSString * pKey = NSStringMakeNonnull(key); 343 | NSString * pValue = NSStringMakeNonnull(value); 344 | 345 | Class clazz = NSClassFromString(BUGLY_AGENT_CLASS); 346 | if (clazz) { 347 | SEL selector = NSSelectorFromString(BUGLY_AGENT_METHOD_SCENE_VALUE); 348 | 349 | NSMethodSignature* signature = [clazz methodSignatureForSelector:selector]; 350 | 351 | if (signature) { 352 | LOGI("Set user Key-Value: [%s, %s]", key, value); 353 | 354 | NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; 355 | if (invocation) { 356 | [invocation setTarget:clazz]; 357 | [invocation setSelector:selector]; 358 | 359 | [invocation setArgument:&pValue atIndex:2]; 360 | [invocation setArgument:&pKey atIndex:3]; 361 | 362 | [invocation invoke]; 363 | } 364 | } 365 | } else { 366 | LOGE("Fail to get class by NSClassFromString(%s)", BUGLY_AGENT_CLASS.UTF8String); 367 | } 368 | #endif 369 | } 370 | 371 | void CrashReport::removeUserValue(const char* key) { 372 | setGameType(); 373 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 374 | LOGI("[cocos2d-x] remove user data: %s", key); 375 | 376 | JNIEnv* env = getJniEnv(); 377 | 378 | jstring jKey = getJniString(env, key); 379 | callJniStaticVoidMethod(env, CRASHREPORT_CLASS, METHOD_REMOVE_USER_DATA, METHOD_REMOVE_USER_DATA_PARAMETER, jKey); 380 | releaseJniString(env, jKey); 381 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 382 | NSString * pKey = NSStringMakeNonnull(key); 383 | 384 | Class clazz = NSClassFromString(BUGLY_AGENT_CLASS); 385 | 386 | if (clazz) { 387 | SEL selector = NSSelectorFromString(BUGLY_AGENT_METHOD_SCENE_CLEAN); 388 | 389 | NSMethodSignature* signature = [clazz methodSignatureForSelector:selector]; 390 | if (signature) { 391 | NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; 392 | if (invocation) { 393 | [invocation setTarget:clazz]; 394 | [invocation setSelector:selector]; 395 | 396 | [invocation setArgument:&pKey atIndex:2]; 397 | 398 | [invocation invoke]; 399 | } 400 | } 401 | } else { 402 | LOGE("Fail to get class by NSClassFromString(%s)", BUGLY_AGENT_CLASS.UTF8String); 403 | } 404 | #endif 405 | } 406 | 407 | void CrashReport::setUserId(const char* userId) { 408 | setGameType(); 409 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 410 | LOGI("[cocos2d-x] set user ID: %s", userId); 411 | 412 | JNIEnv* env = getJniEnv(); 413 | 414 | jstring jUserId = getJniString(env, userId); 415 | callJniStaticVoidMethod(env, CRASHREPORT_CLASS, METHOD_SET_USER_ID, METHOD_SET_USER_ID_PARAMETER, jUserId); 416 | releaseJniString(env, jUserId); 417 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 418 | NSString * pUserId = NSStringMake(userId); 419 | 420 | Class clazz = NSClassFromString(BUGLY_AGENT_CLASS); 421 | 422 | if (clazz) { 423 | SEL selector = NSSelectorFromString(BUGLY_AGENT_METHOD_USER); 424 | NSMethodSignature* signature = [clazz methodSignatureForSelector:selector]; 425 | if (signature) { 426 | LOGI("Set user id: %s", userId); 427 | 428 | NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; 429 | if (invocation) { 430 | [invocation setTarget:clazz]; 431 | [invocation setSelector:selector]; 432 | 433 | [invocation setArgument:&pUserId atIndex:2]; 434 | 435 | [invocation invoke]; 436 | } 437 | } 438 | } else { 439 | LOGE("Fail to get class by NSClassFromString(%s)", BUGLY_AGENT_CLASS.UTF8String); 440 | } 441 | #endif 442 | } 443 | 444 | void CrashReport::reportException(int category, const char* type, const char* msg, const char* traceback) { 445 | reportException(category, type, msg, traceback, false); 446 | } 447 | 448 | void CrashReport::reportException(int category, const char* type, const char* msg, const char* traceback, bool quit) { 449 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 450 | LOGI("[cocos2d-x] post a exception."); 451 | JNIEnv* env = getJniEnv(); 452 | 453 | jstring typeStr = getJniString(env, type); 454 | jstring msgStr = getJniString(env, msg); 455 | jstring traceStr = getJniString(env, traceback); 456 | callJniStaticVoidMethod(env, CRASHREPORT_CLASS, METHOD_POST_EXCEPTION, METHOD_POST_EXCEPTION_PARAMETER, category, typeStr, msgStr, traceStr, quit); 457 | releaseJniString(env, typeStr); 458 | releaseJniString(env, msgStr); 459 | releaseJniString(env, traceStr); 460 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 461 | NSUInteger pCategory = category; 462 | NSString * pType = NSStringMake(type); 463 | NSString * pMsg = NSStringMake(msg); 464 | NSString * pTraceStack = NSStringMake(traceback); 465 | NSDictionary * nullObject = nil; 466 | BOOL terminateApp = quit ? YES : NO; 467 | 468 | Class clazz = NSClassFromString(BUGLY_AGENT_CLASS); 469 | 470 | if (clazz) { 471 | SEL selector = NSSelectorFromString(BUGLY_AGENT_METHOD_EXCEPTION); 472 | NSMethodSignature* signature = [clazz methodSignatureForSelector:selector]; 473 | 474 | if (signature) { 475 | LOGI("Report exception: %s\n%s", msg, traceback); 476 | 477 | NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; 478 | if (invocation) { 479 | [invocation setTarget:clazz]; 480 | [invocation setSelector:selector]; 481 | 482 | [invocation setArgument:&pCategory atIndex:2]; 483 | [invocation setArgument:&pType atIndex:3]; 484 | [invocation setArgument:&pMsg atIndex:4]; 485 | [invocation setArgument:&pTraceStack atIndex:5]; 486 | [invocation setArgument:&nullObject atIndex:6]; 487 | [invocation setArgument:&terminateApp atIndex:7]; 488 | 489 | [invocation invoke]; 490 | } 491 | } 492 | } else { 493 | LOGE("Fail to get class by NSClassFromString(%s)", BUGLY_AGENT_CLASS.UTF8String); 494 | } 495 | #endif 496 | } 497 | 498 | void CrashReport::setAppChannel(const char * channel){ 499 | setGameType(); 500 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 501 | LOGI("[cocos2d-x] set App channel: %s", channel); 502 | 503 | JNIEnv* env = getJniEnv(); 504 | 505 | jstring jChannel = getJniString(env, channel); 506 | callJniStaticVoidMethod(env, CRASHREPORT_CLASS, METHOD_SET_CHANNEL, METHOD_SET_CHANNEL_PARAMETER, jChannel); 507 | releaseJniString(env, jChannel); 508 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 509 | NSString * pUserId = NSStringMake(channel); 510 | 511 | Class clazz = NSClassFromString(BUGLY_AGENT_CLASS); 512 | 513 | if (clazz) { 514 | SEL selector = NSSelectorFromString(BUGLY_AGENT_METHOD_CHANNEL); 515 | NSMethodSignature* signature = [clazz methodSignatureForSelector:selector]; 516 | if (signature) { 517 | LOGI("Set channel: %s", channel); 518 | 519 | NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; 520 | if (invocation) { 521 | [invocation setTarget:clazz]; 522 | [invocation setSelector:selector]; 523 | 524 | [invocation setArgument:&pUserId atIndex:2]; 525 | 526 | [invocation invoke]; 527 | } 528 | } 529 | } else { 530 | LOGE("Fail to get class by NSClassFromString(%s)", BUGLY_AGENT_CLASS.UTF8String); 531 | } 532 | #endif 533 | } 534 | 535 | void CrashReport::setAppVersion(const char * version){ 536 | setGameType(); 537 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 538 | LOGI("[cocos2d-x] set App version: %s", version); 539 | JNIEnv* env = getJniEnv(); 540 | 541 | jstring jVersion = getJniString(env, version); 542 | callJniStaticVoidMethod(env, CRASHREPORT_CLASS, METHOD_SET_VERSION, METHOD_SET_VERSION_PARAMETER, jVersion); 543 | releaseJniString(env, jVersion); 544 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 545 | NSString * pUserId = NSStringMake(version); 546 | 547 | Class clazz = NSClassFromString(BUGLY_AGENT_CLASS); 548 | 549 | if (clazz) { 550 | SEL selector = NSSelectorFromString(BUGLY_AGENT_METHOD_VERSION); 551 | NSMethodSignature* signature = [clazz methodSignatureForSelector:selector]; 552 | if (signature) { 553 | LOGI("Set version: %s", version); 554 | 555 | NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; 556 | if (invocation) { 557 | [invocation setTarget:clazz]; 558 | [invocation setSelector:selector]; 559 | 560 | [invocation setArgument:&pUserId atIndex:2]; 561 | 562 | [invocation invoke]; 563 | } 564 | } 565 | } else { 566 | LOGE("Fail to get class by NSClassFromString(%s)", BUGLY_AGENT_CLASS.UTF8String); 567 | } 568 | #endif 569 | } 570 | 571 | void CrashReport::log(CrashReport::CRLogLevel level, const char * tag, const char * fmts, ...) { 572 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 573 | static char msg[LOG_BUFFER_SIZE]; 574 | va_list args; 575 | va_start(args, fmts); 576 | int size = vsnprintf(msg, LOG_BUFFER_SIZE, fmts, args); 577 | va_end(args); 578 | if (size > LOG_BUFFER_SIZE) { 579 | LOGW("The length[%d] of string is out of the buffer size[%d]", size, LOG_BUFFER_SIZE); 580 | } 581 | // CCLOG("[LOG] %s: %s", tag, msg); 582 | 583 | JNIEnv* env = getJniEnv(); 584 | jstring jTag = getJniString(env, tag); 585 | jstring jMsg = getJniString(env, msg); 586 | callJniStaticVoidMethod(env, CRASHREPORT_CLASS, METHOD_SET_LOG, METHOD_SET_LOG_PARAMETER, (int)level, jTag, jMsg); 587 | releaseJniString(env, jTag); 588 | releaseJniString(env, jMsg); 589 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 590 | if (NULL == fmts) { 591 | return; 592 | } 593 | 594 | static char msg[LOG_BUFFER_SIZE]; 595 | va_list args; 596 | 597 | va_start(args, fmts); 598 | int size = vsnprintf(msg, LOG_BUFFER_SIZE, fmts, args); 599 | va_end(args); 600 | 601 | if (size > LOG_BUFFER_SIZE) { 602 | LOGW("The length[%d] of string is out of the buffer size[%d]", size, LOG_BUFFER_SIZE); 603 | } 604 | 605 | // CCLOG("[LOG] %s: %s", tag, msg); 606 | 607 | NSString * pMsg = NSStringMake(msg); 608 | NSString * pTag = NSStringMake(tag); 609 | 610 | //Error=4,Warn=3,Info=2,Debug=1,Verbose=0,Off=-1 611 | //LogError=1<<0,Warn=1<<1,Info=1<<2,Debug=1<<3,Verbose=1<<4 612 | NSInteger pLevel = (level >= 4 ? 1 : (level == 3 ? 2 : (level == 2 ? 4 : (level == 1 ? 8 : (level == 0 ? 16 : 0))))); 613 | 614 | Class clazz = NSClassFromString(BUGLY_AGENT_CLASS); 615 | if (clazz) { 616 | SEL selector = NSSelectorFromString(BUGLY_AGENT_METHOD_LOG); 617 | NSMethodSignature* signature = [clazz methodSignatureForSelector:selector]; 618 | 619 | if (signature) { 620 | NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; 621 | 622 | if (invocation) { 623 | [invocation setTarget:clazz]; 624 | [invocation setSelector:selector]; 625 | 626 | [invocation setArgument:&pLevel atIndex:2]; 627 | [invocation setArgument:&pTag atIndex:3]; 628 | [invocation setArgument:&pMsg atIndex:4]; 629 | 630 | [invocation invoke]; 631 | } 632 | } else { 633 | LOGE("Fail to methodSignatureForSelector %s", BUGLY_AGENT_METHOD_LOG.UTF8String); 634 | } 635 | } else { 636 | LOGE("Fail to get class by NSClassFromString(%s)", BUGLY_AGENT_CLASS.UTF8String); 637 | } 638 | #endif 639 | } 640 | 641 | void CrashReport::setGameType(){ 642 | if (hasSetGameType) { 643 | return; 644 | } 645 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 646 | if (callJniStaticVoidMethod(NULL, CRASHREPORT_CLASS, METHOD_SET_GAME_TYPE, METHOD_SET_GAME_TYPE_PARAMETER, GAME_TYPE_COCOS)) { 647 | hasSetGameType = true; 648 | } 649 | 650 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 651 | 652 | #endif 653 | } 654 | 655 | void CrashReport::setCrashReporterType(int type) { 656 | crashReporterType = type; 657 | #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) 658 | // Android 659 | LOGD("Set the crash reporter type: %d", type); 660 | #elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) 661 | // iOS 662 | NSInteger pType = type; 663 | 664 | Class clazz = NSClassFromString(BUGLY_AGENT_CLASS); 665 | if (clazz) { 666 | SEL selector = NSSelectorFromString(BUGLY_AGENT_METHOD_CONFIG_REPORTER_TYPE); 667 | 668 | NSMethodSignature* signature = [clazz methodSignatureForSelector:selector]; 669 | 670 | if (signature) { 671 | LOGI("Config crash reporter type: %d", type); 672 | 673 | NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature]; 674 | if (invocation) { 675 | [invocation setTarget:clazz]; 676 | [invocation setSelector:selector]; 677 | 678 | [invocation setArgument:&pType atIndex:2]; 679 | 680 | [invocation invoke]; 681 | } else { 682 | LOGE("Fail to invocationWithMethodSignature for selector %s", BUGLY_AGENT_METHOD_CONFIG_REPORTER_TYPE.UTF8String); 683 | } 684 | } else { 685 | LOGE("Fail to methodSignatureForSelector %s", BUGLY_AGENT_METHOD_CONFIG_REPORTER_TYPE.UTF8String); 686 | } 687 | } else { 688 | LOGE("Fail to get class by NSClassFromString(%s)", BUGLY_AGENT_CLASS.UTF8String); 689 | } 690 | 691 | #endif 692 | } 693 | -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/bugly/js/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := bugly_agent_cocos_static_js 6 | 7 | LOCAL_MODULE_FILENAME := libbuglyagentjs 8 | 9 | LOCAL_SRC_FILES := BuglyJSAgent.cpp 10 | 11 | LOCAL_CPPFLAGS := -D__STDC_LIMIT_MACROS=1 -Wno-invalid-offsetof 12 | 13 | LOCAL_C_INCLUDES := $(LOCAL_PATH)\ 14 | $(LOCAL_PATH)/../ \ 15 | $(LOCAL_PATH)/../../ \ 16 | $(LOCAL_PATH)/../../../ \ 17 | $(LOCAL_PATH)/../../../cocos \ 18 | $(LOCAL_PATH)/../../../cocos/2d \ 19 | $(LOCAL_PATH)/../../../cocos/base \ 20 | $(LOCAL_PATH)/../../../cocos/2d/platform/android \ 21 | $(LOCAL_PATH)/../../../cocos/platform/android \ 22 | $(LOCAL_PATH)/../../../cocos/scripting/js-bindings/manual \ 23 | $(LOCAL_PATH)/../../../external/spidermonkey/include/android \ 24 | $(LOCAL_PATH)/../../../cocos/math/kazmath \ 25 | $(LOCAL_PATH)/../../../cocos/physics \ 26 | $(LOCAL_PATH)/../../../cocos2dx \ 27 | $(LOCAL_PATH)/../../../cocos2dx/include \ 28 | $(LOCAL_PATH)/../../../cocos2dx/platform/android \ 29 | $(LOCAL_PATH)/../../../cocos2dx/kazmath/include \ 30 | $(LOCAL_PATH)/../../../scripting/javascript/binding \ 31 | $(LOCAL_PATH)/../../../scripting/javascript/spidermonkey-android/include \ 32 | 33 | 34 | include $(BUILD_STATIC_LIBRARY) -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/bugly/js/BuglyJSAgent.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // BuglyJSAgent.cpp 3 | // Bugly 4 | // 5 | // Created by Yeelik on 16/4/25. 6 | // 7 | // 8 | 9 | #include "BuglyJSAgent.h" 10 | 11 | #include "cocos2d.h" 12 | #include "ScriptingCore.h" 13 | 14 | #include "jsb_helper.h" 15 | #include "jsapi.h" 16 | #include "jsfriendapi.h" 17 | #include "cocos2d_specifics.hpp" 18 | 19 | #include 20 | 21 | #include "CrashReport.h" 22 | 23 | #ifndef CATEGORY_JS_EXCEPTION 24 | #define CATEGORY_JS_EXCEPTION 5 25 | #endif 26 | 27 | void BuglyJSAgent::registerJSFunctions(JSContext *cx, BLYJSObject global){ 28 | CCLOG("-> %s", __PRETTY_FUNCTION__); 29 | 30 | // register js function with c++ function 31 | JS_DefineFunction(cx, global, "buglySetUserId", BuglyJSAgent::setUserId,1, JSPROP_READONLY | JSPROP_PERMANENT); 32 | JS_DefineFunction(cx, global, "buglySetTag", BuglyJSAgent::setTag,1, JSPROP_READONLY | JSPROP_PERMANENT); 33 | JS_DefineFunction(cx, global, "buglyAddUserValue", BuglyJSAgent::addUserValue,2, JSPROP_READONLY | JSPROP_PERMANENT); 34 | JS_DefineFunction(cx, global, "buglyLog", BuglyJSAgent::printLog, 3, JSPROP_READONLY | JSPROP_PERMANENT); 35 | } 36 | 37 | void BuglyJSAgent::registerJSExceptionHandler(JSContext *cx){ 38 | CCLOG("-> %s", __PRETTY_FUNCTION__); 39 | 40 | JS_SetErrorReporter(cx, BuglyJSAgent::reportJSError); 41 | } 42 | 43 | void BuglyJSAgent::reportJSError(JSContext *cx, const char *message, JSErrorReport *report){ 44 | CCLOG("-> %s", __PRETTY_FUNCTION__); 45 | 46 | const char* format = "%s:%u:%s\n"; 47 | const char* filename = report != nullptr && report->filename ? report->filename : ""; 48 | 49 | size_t bufLen = strlen(format) + strlen(filename) + strlen(message) + 32; 50 | char* traceback = (char*)malloc(bufLen); 51 | memset(traceback, 0, bufLen); 52 | sprintf(traceback, format, filename, (unsigned int)report->lineno, message); 53 | 54 | const char *reason = strstr(message, ":"); 55 | const char *name = message; 56 | 57 | if (reason == nullptr) { 58 | reason = message; 59 | } else { 60 | size_t len = strlen(message) - strlen(reason); 61 | if (len > 0) { 62 | name = strndup(message, len); 63 | reason ++; 64 | } 65 | } 66 | 67 | CrashReport::reportException(CATEGORY_JS_EXCEPTION, (name != message) ? name : "JSError", message, traceback); 68 | free(traceback); 69 | 70 | if (name != message) { 71 | free((void*)name); 72 | } 73 | } 74 | 75 | bool BuglyJSAgent::setUserId(JSContext *cx, unsigned argc, JS::Value *vp){ 76 | CCLOG("-> %s", __PRETTY_FUNCTION__); 77 | 78 | if (argc > 0) { 79 | #if COCOS2D_VERSION >= 0x00030500 80 | JS::CallArgs args = JS::CallArgsFromVp(argc, vp); 81 | 82 | const char *userId; 83 | jsval_to_charptr(cx, args.get(0), &userId); 84 | CrashReport::setUserId(userId); 85 | 86 | args.rval().setUndefined(); 87 | #else 88 | jsval *argvp = JS_ARGV(cx, vp); 89 | 90 | const char *userId; 91 | jsval_to_charptr(cx, *argvp++, &userId); 92 | CrashReport::setUserId(userId); 93 | #endif 94 | } 95 | 96 | return true; 97 | } 98 | 99 | bool BuglyJSAgent::setTag(JSContext *cx, unsigned argc, JS::Value *vp){ 100 | CCLOG("-> %s", __PRETTY_FUNCTION__); 101 | 102 | if (argc > 0) { 103 | #if COCOS2D_VERSION >= 0x00030500 104 | JS::CallArgs args = JS::CallArgsFromVp(argc, vp); 105 | 106 | int tag = 0; 107 | jsval_to_int(cx, args.get(0), &tag); 108 | CrashReport::setTag(tag); 109 | 110 | args.rval().setUndefined(); 111 | #else 112 | jsval *argvp = JS_ARGV(cx, vp); 113 | 114 | int tag = 0; 115 | jsval_to_int(cx, *argvp++, &tag); 116 | CrashReport::setTag(tag); 117 | #endif 118 | } 119 | return true; 120 | } 121 | 122 | bool BuglyJSAgent::addUserValue(JSContext *cx, unsigned argc, JS::Value *vp) { 123 | CCLOG("-> %s", __PRETTY_FUNCTION__); 124 | 125 | if (argc > 1) { 126 | #if COCOS2D_VERSION >= 0x00030500 127 | JS::CallArgs args = JS::CallArgsFromVp(argc, vp); 128 | 129 | const char *key, *value; 130 | jsval_to_charptr(cx, args.get(0), &key); 131 | jsval_to_charptr(cx, args.get(1), &value); 132 | CrashReport::addUserValue(key, value); 133 | 134 | args.rval().setUndefined(); 135 | 136 | #else 137 | jsval *argvp = JS_ARGV(cx, vp); 138 | 139 | const char *key, *value; 140 | jsval_to_charptr(cx, *argvp++, &key); 141 | jsval_to_charptr(cx, *argvp++, &value); 142 | 143 | CrashReport::addUserValue(key, value); 144 | #endif 145 | } 146 | 147 | return true; 148 | } 149 | 150 | bool BuglyJSAgent::printLog(JSContext *cx, unsigned argc, JS::Value *vp){ 151 | CCLOG("-> %s", __PRETTY_FUNCTION__); 152 | 153 | if (argc > 2) { 154 | #if COCOS2D_VERSION >= 0x00030500 155 | JS::CallArgs args = JS::CallArgsFromVp(argc, vp); 156 | 157 | int level = 0; 158 | const char *tag, *msg; 159 | jsval_to_int(cx, args.get(0), &level); 160 | jsval_to_charptr(cx, args.get(1), &tag); 161 | jsval_to_charptr(cx, args.get(2), &msg); 162 | 163 | CrashReport::CRLogLevel pLevel = CrashReport::CRLogLevel::Off; 164 | switch (level) { 165 | case -1: 166 | pLevel = CrashReport::CRLogLevel::Off; 167 | break; 168 | case 0: 169 | pLevel = CrashReport::CRLogLevel::Verbose; 170 | break; 171 | case 1: 172 | pLevel = CrashReport::CRLogLevel::Debug; 173 | break; 174 | case 2: 175 | pLevel = CrashReport::CRLogLevel::Info; 176 | break; 177 | case 3: 178 | pLevel = CrashReport::CRLogLevel::Warning; 179 | break; 180 | case 4: 181 | pLevel = CrashReport::CRLogLevel::Error; 182 | break; 183 | 184 | default: 185 | break; 186 | } 187 | CrashReport::log(pLevel, tag, msg); 188 | 189 | args.rval().setUndefined(); 190 | #else 191 | jsval *argvp = JS_ARGV(cx, vp); 192 | 193 | int level = 0; 194 | const char *tag, *msg; 195 | jsval_to_int(cx, *argvp++, &level); 196 | jsval_to_charptr(cx, *argvp++, &tag); 197 | jsval_to_charptr(cx, *argvp++, &msg); 198 | 199 | CrashReport::CRLogLevel pLevel = CrashReport::CRLogLevel::Off; 200 | switch (level) { 201 | case -1: 202 | pLevel = CrashReport::CRLogLevel::Off; 203 | break; 204 | case 0: 205 | pLevel = CrashReport::CRLogLevel::Verbose; 206 | break; 207 | case 1: 208 | pLevel = CrashReport::CRLogLevel::Debug; 209 | break; 210 | case 2: 211 | pLevel = CrashReport::CRLogLevel::Info; 212 | break; 213 | case 3: 214 | pLevel = CrashReport::CRLogLevel::Warning; 215 | break; 216 | case 4: 217 | pLevel = CrashReport::CRLogLevel::Error; 218 | break; 219 | 220 | default: 221 | break; 222 | } 223 | CrashReport::log(pLevel, tag, msg); 224 | #endif 225 | } 226 | 227 | return true; 228 | } 229 | -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/bugly/js/BuglyJSAgent.h: -------------------------------------------------------------------------------- 1 | // 2 | // BuglyJSAgent.h 3 | // Bugly 4 | // 5 | // Copyright © 2016年 Bugly. All rights reserved. 6 | // 7 | // 8 | 9 | #ifndef __BUGLY_JS_AGENT_H__ 10 | #define __BUGLY_JS_AGENT_H__ 11 | 12 | #include "cocos2d.h" 13 | #include "ScriptingCore.h" 14 | 15 | #if COCOS2D_VERSION >= 0x00030500 16 | #define BLYJSObject JS::HandleObject 17 | #else 18 | #define BLYJSObject JSObject* 19 | #endif 20 | 21 | class BuglyJSAgent { 22 | public: 23 | 24 | static void registerJSFunctions(JSContext *cx, BLYJSObject object); 25 | 26 | static void registerJSExceptionHandler(JSContext * cx); 27 | static void reportJSError(JSContext *cx, const char *message, JSErrorReport *report); 28 | 29 | /* define js function 'buglySetUserId' */ 30 | static bool setUserId(JSContext *cx, unsigned argc, JS::Value *vp); 31 | 32 | /* define js function 'buglySetTag' */ 33 | static bool setTag(JSContext *cx, unsigned argc, JS::Value *vp); 34 | 35 | /* define js function 'buglyAddUserValue' */ 36 | static bool addUserValue(JSContext *cx, unsigned argc, JS::Value *vp); 37 | 38 | /* define js function 'buglyLog' */ 39 | static bool printLog(JSContext *cx, unsigned argc, JS::Value *vp); 40 | }; 41 | 42 | #endif /* __BUGLY_JS_AGENT_H__ */ 43 | -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/bugly/lua/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_MODULE := bugly_agent_cocos_static_lua 6 | 7 | LOCAL_MODULE_FILENAME := libbuglyagentlua 8 | 9 | LOCAL_SRC_FILES := BuglyLuaAgent.cpp 10 | 11 | # Maybe you need modify the head files according to the version of cocos engine be used 12 | # This head files Cocos/frameworks/cocos2d-x-3.6 13 | # 14 | LOCAL_C_INCLUDES := $(LOCAL_PATH)\ 15 | $(LOCAL_PATH)/../ \ 16 | $(LOCAL_PATH)/../../ \ 17 | $(LOCAL_PATH)/../../../ \ 18 | $(LOCAL_PATH)/../../../cocos \ 19 | $(LOCAL_PATH)/../../../cocos/base \ 20 | $(LOCAL_PATH)/../../../cocos/platform/android \ 21 | $(LOCAL_PATH)/../../../cocos/scripting/lua-bindings/manual \ 22 | $(LOCAL_PATH)/../../../cocos/math/kazmath \ 23 | $(LOCAL_PATH)/../../../cocos/physics \ 24 | $(LOCAL_PATH)/../../../external \ 25 | $(LOCAL_PATH)/../../../external/lua/luajit/include\ 26 | $(LOCAL_PATH)/../../../external/lua/tolua\ 27 | $(LOCAL_PATH)/../../../cocos2dx \ 28 | $(LOCAL_PATH)/../../../cocos2dx/include \ 29 | $(LOCAL_PATH)/../../../cocos2dx/platform/android \ 30 | $(LOCAL_PATH)/../../../cocos2dx/kazmath/include \ 31 | $(LOCAL_PATH)/../../../cocos/2d \ 32 | $(LOCAL_PATH)/../../../cocos/2d/platform/android \ 33 | $(LOCAL_PATH)/../../../scripting/lua/cocos2dx_support \ 34 | $(LOCAL_PATH)/../../../scripting/lua/lua \ 35 | $(LOCAL_PATH)/../../../scripting/lua/tolua \ 36 | 37 | 38 | include $(BUILD_STATIC_LIBRARY) -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/bugly/lua/BuglyLuaAgent.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // BuglyLuaAgent.cpp 3 | // Bugly 4 | // 5 | // Created by Yeelik on 16/4/25. 6 | // 7 | // 8 | 9 | #include "BuglyLuaAgent.h" 10 | 11 | #include "cocos2d.h" 12 | #include "CCLuaEngine.h" 13 | 14 | #include "CrashReport.h" 15 | 16 | #ifndef CATEGORY_LUA_EXCEPTION 17 | #define CATEGORY_LUA_EXCEPTION 6 18 | #endif 19 | 20 | #pragma mark - BuglyLuaAgent 21 | 22 | /* 23 | cocos2d::LuaEngine * BuglyLuaAgent::getLuaEngine() { 24 | #if COCOS2D_VERSION >= 0x00030000 25 | return cocos2d::LuaEngine::getInstance(); 26 | #else 27 | return cocos2d::CCLuaEngine::defaultEngine(); 28 | #endif 29 | } 30 | 31 | lua_State *BuglyLuaAgent::getLuaState() { 32 | return BuglyLuaAgent::getLuaEngine()->getLuaStack()->getLuaState(); 33 | } 34 | */ 35 | 36 | void BuglyLuaAgent::registerLuaExceptionHandler(cocos2d::LuaEngine * engine) { 37 | lua_State *L = engine->getLuaStack()->getLuaState(); 38 | 39 | lua_register(L, "buglyReportLuaException", BuglyLuaAgent::reportLuaException); 40 | lua_register(L, "buglySetUserId", BuglyLuaAgent::setUserId); 41 | lua_register(L, "buglySetTag", BuglyLuaAgent::setTag); 42 | lua_register(L, "buglyAddUserValue", BuglyLuaAgent::addUserValue); 43 | lua_register(L, "buglyRemoveUserValue", BuglyLuaAgent::removeUserValue); 44 | lua_register(L, "buglyLog", BuglyLuaAgent::printLog); 45 | 46 | } 47 | 48 | int BuglyLuaAgent::reportLuaException(lua_State *L) { 49 | const char* type = ""; 50 | const char* msg = lua_tostring(L, 1); 51 | const char* traceback = lua_tostring(L, 2); 52 | bool quit = lua_toboolean(L, 3); 53 | 54 | CrashReport::reportException(CATEGORY_LUA_EXCEPTION, type, msg, traceback, quit); 55 | 56 | return 0; 57 | } 58 | 59 | int BuglyLuaAgent::setUserId(lua_State *L) { 60 | const char* userId = lua_tostring(L, 1); 61 | 62 | CrashReport::setUserId(userId); 63 | 64 | return 0; 65 | } 66 | 67 | int BuglyLuaAgent::setTag(lua_State *L) { 68 | int tag = lua_tonumber(L, 1); 69 | CrashReport::setTag(tag); 70 | 71 | return 0; 72 | } 73 | 74 | int BuglyLuaAgent::addUserValue(lua_State *L) { 75 | const char* key = lua_tostring(L, 1); 76 | const char* value = lua_tostring(L, 2); 77 | 78 | CrashReport::addUserValue(key, value); 79 | 80 | return 0; 81 | } 82 | 83 | int BuglyLuaAgent::removeUserValue(lua_State *L) { 84 | const char* key = lua_tostring(L, 1); 85 | 86 | CrashReport::removeUserValue(key); 87 | return 0; 88 | } 89 | 90 | int BuglyLuaAgent::printLog(lua_State *L) { 91 | int level = lua_tonumber(L, 1); 92 | const char* tag = lua_tostring(L, 2); 93 | const char* log = lua_tostring(L, 3); 94 | 95 | CrashReport::CRLogLevel crLevel = CrashReport::CRLogLevel::Off; 96 | switch (level) { 97 | case -1: 98 | crLevel = CrashReport::CRLogLevel::Off; 99 | break; 100 | case 0: 101 | crLevel = CrashReport::CRLogLevel::Verbose; 102 | break; 103 | case 1: 104 | crLevel = CrashReport::CRLogLevel::Debug; 105 | break; 106 | case 2: 107 | crLevel = CrashReport::CRLogLevel::Info; 108 | break; 109 | case 3: 110 | crLevel = CrashReport::CRLogLevel::Warning; 111 | break; 112 | case 4: 113 | crLevel = CrashReport::CRLogLevel::Error; 114 | break; 115 | } 116 | 117 | CrashReport::log(crLevel, tag, log); 118 | 119 | return 0; 120 | } -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/bugly/lua/BuglyLuaAgent.h: -------------------------------------------------------------------------------- 1 | // 2 | // BuglyLuaAgent.hpp 3 | // Bugly 4 | // 5 | // Copyright © 2016年 Bugly. All rights reserved. 6 | // 7 | // 8 | 9 | #ifndef __BUGLY_LUA_AGENT_H__ 10 | #define __BUGLY_LUA_AGENT_H__ 11 | 12 | #include "CCLuaEngine.h" 13 | #include "cocos2d.h" 14 | 15 | class BuglyLuaAgent { 16 | public: 17 | /* 18 | static cocos2d::LuaEngine *getLuaEngine(); 19 | 20 | static lua_State *getLuaState(); 21 | */ 22 | 23 | /** 24 | * @brief register lua exception handler 25 | * 26 | * @param engine the lua engine 27 | */ 28 | static void registerLuaExceptionHandler(cocos2d::LuaEngine * engine); 29 | 30 | /** 31 | * @brief binding lua function 'buglyReportLuaException 32 | * 33 | * @param L lua_State which contains 3 arguments: {msg, traceback, quit} 34 | * L[1] - string, msg 35 | * L[2] - string, traceback 36 | * L[3] - bool, quit 37 | */ 38 | static int reportLuaException(lua_State *L); 39 | 40 | /** 41 | * @brief binding lua function 'buglySetUserId' 42 | * 43 | * @param L lua_State which contains 1 arguments: {userId} 44 | * 45 | */ 46 | static int setUserId(lua_State *L); 47 | 48 | /** 49 | * @brief register lua function 'buglySetTag' 50 | * 51 | * @param L lua_State which contains 1 arguments: {tag} 52 | * 53 | */ 54 | static int setTag(lua_State *L); 55 | 56 | /** 57 | * @brief register lua function 'buglyAddUserValue' 58 | * 59 | * @param L lua_State which contains 2 arguments: {key, value} 60 | * 61 | */ 62 | static int addUserValue(lua_State *L); 63 | 64 | /** 65 | * @brief register lua function 'buglyRemoveUserValue' 66 | * 67 | * @param L lua_State which contains 1 arguments: {key} 68 | * 69 | */ 70 | static int removeUserValue(lua_State *L); 71 | 72 | /** 73 | * @brief register lua function 'buglyLog' 74 | * 75 | * @param L lua_State which contains 3 arguments: {level, tag, log} 76 | * L[1] - int, level - which value is 0=Verbose, 1=Debug, 2=Info, 3=Warn, 4=Error 77 | * L[2] - string, tag - the tag name of the log 78 | * L[3] - string, log - the message of the log, NOT support format string, you should use it with string.format(...) 79 | * 80 | * @code 81 | * 82 | * buglyLog(2, "Login", string.format("Login user name: %s", user)) 83 | */ 84 | static int printLog(lua_State *L); 85 | }; 86 | 87 | #endif /* __BUGLY_LUA_AGENT_H__ */ 88 | -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/libs/bugly_agent.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tidys/cocos-cretor-bugly-plugin/21435bf3c2b9be45b55d5596bbd8d39f06bf201a/packages/plugin-bugly/bugly/1.4.3/libs/bugly_agent.jar -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/libs/bugly_crash_release.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tidys/cocos-cretor-bugly-plugin/21435bf3c2b9be45b55d5596bbd8d39f06bf201a/packages/plugin-bugly/bugly/1.4.3/libs/bugly_crash_release.jar -------------------------------------------------------------------------------- /packages/plugin-bugly/bugly/1.4.3/prebuilt/armeabi-v7a/libBugly.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tidys/cocos-cretor-bugly-plugin/21435bf3c2b9be45b55d5596bbd8d39f06bf201a/packages/plugin-bugly/bugly/1.4.3/prebuilt/armeabi-v7a/libBugly.so -------------------------------------------------------------------------------- /packages/plugin-bugly/buglySymbolAndroid/buglySymbolAndroid.bat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tidys/cocos-cretor-bugly-plugin/21435bf3c2b9be45b55d5596bbd8d39f06bf201a/packages/plugin-bugly/buglySymbolAndroid/buglySymbolAndroid.bat -------------------------------------------------------------------------------- /packages/plugin-bugly/buglySymbolAndroid/buglySymbolAndroid.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tidys/cocos-cretor-bugly-plugin/21435bf3c2b9be45b55d5596bbd8d39f06bf201a/packages/plugin-bugly/buglySymbolAndroid/buglySymbolAndroid.jar -------------------------------------------------------------------------------- /packages/plugin-bugly/buglySymbolAndroid/buglySymbolAndroid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2015-2016 Bugly, Tencent Inc. All rights reserved. 4 | # 5 | # Usage: 6 | # buglySymbolAndroid.sh [out.zip] 7 | # 8 | # Extract symbols from so file. 9 | # It call 'buglySymbolAndroid.jar', make sure there is Java environment on the system. 10 | # 11 | # 12 | 13 | function printIndroduction { 14 | echo "Bugly符号表工具Android版 -- Bugly Symtab Tool for Android" 15 | echo "适用平台 -- Applicable platform: Linux" 16 | echo "Copyright 2015-2016 Bugly, Tencent Inc. All rights reserved." 17 | echo "" 18 | } 19 | 20 | # function - usage 21 | function printUsage(){ 22 | echo "----" 23 | echo "$1" 24 | echo "----" 25 | echo "用法 -- Usage: buglySymbolAndroid.sh [out.zip]" 26 | echo "" 27 | echo "参数说明 -- Introduction for arguments" 28 | echo ":" 29 | echo " SO文件路径名 -- Path where so file exist" 30 | echo "" 31 | echo "[out.zip] (可选 -- Optional):" 32 | echo " 输出文件名 -- Zip file name for output" 33 | echo " 如果[out.zip]不是绝对路径名,[out.zip]将生成在脚本所在目录" 34 | echo " -- If it's not an absolute path, the [out.zip] will be generated into the directory of the script." 35 | exit 3 36 | } 37 | 38 | # function - extract 39 | function extractSymbol() { 40 | java -Xms512m -Xmx1024m -Dfile.encoding=UTF8 -jar "$JarPath" $* 41 | } 42 | 43 | # main 44 | printIndroduction 45 | 46 | # Check the Java Environment 47 | CheckJavaVersion=$(java -version 2>&1) 48 | echo "$CheckJavaVersion" | grep -q "Java(TM)" 49 | if [ $? -ne 0 ] 50 | then 51 | echo "----" 52 | echo "系统中未安装Java或者未配置Java环境,请检查!-- Please check if your system has installed Java or configured environment for Java!" 53 | echo "Java官网 -- Java Web Site:www.java.com" 54 | exit 1 55 | fi 56 | 57 | # Check the jar 58 | #ShellDir=$(cd `dirname $0`; pwd) 59 | pathName=$(cd `dirname $0`; pwd) 60 | JarName="buglySymbolAndroid.jar" 61 | JarPath="$pathName/$JarName" 62 | if [ ! -f "$JarPath" ]; then 63 | echo " ----" 64 | echo " 未找到\"$JarName\"!-- Can not find \"$JarName\"!" 65 | echo " 请将\"$JarName\"复制到\"$pathName\"中!" 66 | echo " -- Please copy \"$JarName\" to \"$pathName\"!" 67 | exit 2 68 | fi 69 | 70 | # call the function to extract symbols 71 | extractSymbol $* -------------------------------------------------------------------------------- /packages/plugin-bugly/buglySymbolAndroid/settings.txt: -------------------------------------------------------------------------------- 1 | ****************************************** 2 | * Bugly 符号表工具配置文件 * 3 | * * 4 | * Debug 调试模式开关(打印更多Log) * 5 | * Upload 上传开关 * 6 | * ID Bugly平台的APP ID * 7 | * Key Bugly平台的APP key * 8 | * * 9 | ****************************************** 10 | Debug=false 11 | Upload=false 12 | ID= 13 | Key= 14 | -------------------------------------------------------------------------------- /packages/plugin-bugly/buglySymbolAndroid/符号表工具Android版-使用指南.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tidys/cocos-cretor-bugly-plugin/21435bf3c2b9be45b55d5596bbd8d39f06bf201a/packages/plugin-bugly/buglySymbolAndroid/符号表工具Android版-使用指南.pdf -------------------------------------------------------------------------------- /packages/plugin-bugly/core/CfgUtil.js: -------------------------------------------------------------------------------- 1 | var FS = require('fire-fs'); 2 | var path = require('path'); 3 | const {remote} = require('electron'); 4 | 5 | let self = module.exports = { 6 | cfgData: { 7 | channal: "", 8 | gameID: "", 9 | gameVersion: null, 10 | gameKey: null, 11 | isAutoUpload: false 12 | }, 13 | setIsAutoUpload(b) { 14 | this.cfgData.isAutoUpload = b; 15 | this.saveConfig(); 16 | }, 17 | 18 | getGameID() { 19 | return this.cfgData.gameID; 20 | }, 21 | setGameID(id) { 22 | this.cfgData.gameID = id; 23 | this.saveConfig(); 24 | }, 25 | 26 | setGameKeyAndVersion(key, version, channal) { 27 | this.cfgData.gameKey = key; 28 | this.cfgData.gameVersion = version; 29 | this.cfgData.channal = channal; 30 | 31 | this.saveConfig(); 32 | }, 33 | 34 | saveConfig() { 35 | let configFilePath = self._getAppCfgPath(); 36 | 37 | FS.writeFile(configFilePath, JSON.stringify(this.cfgData), function (error) { 38 | if (!error) { 39 | console.log("保存配置成功!"); 40 | } 41 | }.bind(this)); 42 | }, 43 | cleanConfig() { 44 | FS.unlink(this._getAppCfgPath()); 45 | }, 46 | _getAppCfgPath() { 47 | let userDataPath = remote.app.getPath('userData'); 48 | let tar = Editor.libraryPath; 49 | tar = tar.replace(/\\/g, '-'); 50 | tar = tar.replace(/:/g, '-'); 51 | return path.join(userDataPath, "plugin-bugly-cfg-" + tar + ".json"); 52 | // return Editor.url('packages://hot-update-tools/save/cfg.json'); 53 | }, 54 | initCfg(cb) { 55 | let configFilePath = this._getAppCfgPath(); 56 | if (FS.existsSync(configFilePath)) { 57 | console.log("cfg path: " + configFilePath); 58 | FS.readFile(configFilePath, 'utf-8', function (err, data) { 59 | if (!err) { 60 | let saveData = JSON.parse(data.toString()); 61 | self.cfgData = saveData; 62 | if (cb) { 63 | cb(saveData); 64 | } 65 | } 66 | }.bind(self)); 67 | } else { 68 | if (cb) { 69 | cb(null); 70 | } 71 | } 72 | } 73 | }; -------------------------------------------------------------------------------- /packages/plugin-bugly/i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports={ 2 | title:'Bugly Tools', 3 | }; -------------------------------------------------------------------------------- /packages/plugin-bugly/i18n/zh.js: -------------------------------------------------------------------------------- 1 | module.exports={ 2 | title:'Bugly 工具', 3 | } -------------------------------------------------------------------------------- /packages/plugin-bugly/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | load() { 5 | // execute when package loaded 6 | }, 7 | 8 | unload() { 9 | // execute when package unloaded 10 | }, 11 | 12 | // register your ipc messages here 13 | messages: { 14 | 'open'() { 15 | // open entry panel registered in package.json 16 | Editor.Panel.open('plugin-bugly'); 17 | }, 18 | 'say-hello'() { 19 | Editor.log('Hello World!'); 20 | // send ipc message to panel 21 | Editor.Ipc.sendToPanel('plugin-bugly', 'plugin-bugly:hello'); 22 | }, 23 | 'clicked'() { 24 | Editor.log('Button clicked!'); 25 | }, 26 | 'popup-create-menu'(event, x, y, data) { 27 | let electron = require('electron'); 28 | let BrowserWindow = electron.BrowserWindow; 29 | let template = [ 30 | { 31 | label: '清空日志', click() { 32 | Editor.Ipc.sendToPanel('plugin-bugly', 'plugin-bugly:cleanLog', data); 33 | } 34 | }, 35 | // {type: 'separator'}, 36 | ]; 37 | let editorMenu = new Editor.Menu(template, event.sender); 38 | 39 | x = Math.floor(x); 40 | y = Math.floor(y); 41 | editorMenu.nativeMenu.popup(BrowserWindow.fromWebContents(event.sender), x, y); 42 | editorMenu.dispose(); 43 | }, 44 | 'builder:query-build-options'(event){ 45 | Editor.Ipc.sendToPanel('plugin-bugly', 'plugin-bugly:queryBuildOptions', event); 46 | }, 47 | }, 48 | }; -------------------------------------------------------------------------------- /packages/plugin-bugly/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plugin-bugly", 3 | "version": "0.0.1", 4 | "description": "The package template for getting started.", 5 | "author": "Cocos Creator", 6 | "main": "main.js", 7 | "main-menu": { 8 | "i18n:MAIN_MENU.package.title/i18n:plugin-bugly.title": { 9 | "message": "plugin-bugly:open" 10 | } 11 | }, 12 | "panel": { 13 | "main": "panel/index.js", 14 | "type": "dockable", 15 | "title": "plugin-bugly", 16 | "width": 400, 17 | "height": 780, 18 | "min-height": 780 19 | } 20 | } -------------------------------------------------------------------------------- /packages/plugin-bugly/panel/index.css: -------------------------------------------------------------------------------- 1 | :host { margin: 5px; } 2 | h2 { color: #f90; } -------------------------------------------------------------------------------- /packages/plugin-bugly/panel/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 6 |
7 | 8 |
9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 |
21 | 22 |
23 | 24 | 刷新 25 |
26 |
27 | 28 |
29 | 30 |
31 |
32 | 33 |
34 | 35 |
36 |
37 | 38 |
39 | 40 | 打开 41 |
42 |
43 | 44 |
45 | 46 | 47 |
48 |
49 |
50 | 添加Bugly 51 | 生成符号表 52 |
53 | 54 |

日志:

55 | 57 |
58 |
59 | -------------------------------------------------------------------------------- /packages/plugin-bugly/panel/index.js: -------------------------------------------------------------------------------- 1 | var FS = require("fire-fs"); 2 | var PATH = require('fire-path'); 3 | var CfgUtil = Editor.require("packages://plugin-bugly/core/CfgUtil"); 4 | var fse = require('fs-extra'); 5 | var rimraf = require('rimraf'); 6 | var Electron = require('electron'); 7 | 8 | Editor.Panel.extend({ 9 | style: FS.readFileSync(Editor.url('packages://plugin-bugly/panel/index.html', 'utf8')) + "", 10 | template: FS.readFileSync(Editor.url('packages://plugin-bugly/panel/index.html', 'utf8')) + "", 11 | 12 | $: { 13 | logTextArea: '#logTextArea', 14 | uploadBtn: '#uploadBtn', 15 | }, 16 | 17 | ready() { 18 | let logCtrl = this.$logTextArea; 19 | let logListScrollToBottom = function () { 20 | setTimeout(function () { 21 | logCtrl.scrollTop = logCtrl.scrollHeight; 22 | }, 10); 23 | }; 24 | let uploadBtn = this.$uploadBtn; 25 | let setUploadBtnDisabled = function (b) { 26 | uploadBtn.disabled = b; 27 | }; 28 | 29 | 30 | window.plugin = new window.Vue({ 31 | el: this.shadowRoot, 32 | created() { 33 | console.log("created"); 34 | this.initPlugin(); 35 | }, 36 | data: { 37 | preGameID: "", 38 | gameID: "", 39 | gameKey: "", 40 | gamePackage: "com.game.test", 41 | gameVersion: "1.0", 42 | channal: "", 43 | logView: [], 44 | isShowFreshAppPackage: true, 45 | isShowOutPutFileFilePath: false, 46 | outPutFilePath: "",// 符号保存位置 47 | isAutoUpload: true, 48 | }, 49 | methods: { 50 | _addLog(str) { 51 | let time = new Date(); 52 | // this.logView = "[" + time.toLocaleString() + "]: " + str + "\n" + this.logView; 53 | this.logView += "[" + time.toLocaleString() + "]: " + str + "\n"; 54 | logListScrollToBottom(); 55 | }, 56 | _addLogNoTime(data) { 57 | this.logView += data; 58 | logListScrollToBottom(); 59 | }, 60 | initPlugin() { 61 | CfgUtil.initCfg(function (data) { 62 | if (data) { 63 | // console.log(data); 64 | this.gameID = data.gameID; 65 | this.gameKey = data.gameKey; 66 | this.gameVersion = data.gameVersion; 67 | this.channal = data.channal; 68 | this.isAutoUpload = data.isAutoUpload; 69 | } 70 | }.bind(this)); 71 | // 包名 72 | this.updateGamePackageName(); 73 | }, 74 | // 更新游戏包名 75 | updateGamePackageName() { 76 | let projectPath = Editor.projectInfo.path; 77 | let buildCfg = PATH.join(projectPath, "settings/builder.json"); 78 | if (!FS.existsSync(buildCfg)) { 79 | this.gamePackage = null; 80 | } else { 81 | function setGamePackage() { 82 | let data = FS.readFileSync(buildCfg, 'utf-8'); 83 | let buildData = null; 84 | try { 85 | buildData = JSON.parse(data); 86 | } catch (e) { 87 | console.log(e); 88 | buildData = null; 89 | } 90 | if (buildData) { 91 | if (buildData.packageName) { 92 | this.gamePackage = buildData.packageName; 93 | } else { 94 | this.gamePackage = null; 95 | } 96 | } 97 | } 98 | 99 | FS.unwatchFile(buildCfg); 100 | this.isShowFreshAppPackage = false; 101 | FS.watch(buildCfg, function (event, fileName) { 102 | console.log("event:%s, file:%s ", event, fileName); 103 | setGamePackage.apply(this); 104 | }.bind(this)); 105 | setGamePackage.apply(this); 106 | } 107 | }, 108 | onLogViewMenu(event) { 109 | console.log("onLogViewMenu"); 110 | Editor.Ipc.sendToMain('plugin-bugly:popup-create-menu', event.x, event.y, null); 111 | }, 112 | onChangeGameID() { 113 | let oldGameID = CfgUtil.getGameID(); 114 | CfgUtil.setGameID(this.gameID); 115 | if (oldGameID === this.gameID) { 116 | return; 117 | } 118 | 119 | // 替换code值 120 | let projectPath = Editor.projectInfo.path; 121 | let buildCfg = PATH.join(projectPath, "local/builder.json"); 122 | if (!FS.existsSync(buildCfg)) { 123 | this._addLog("发现没有构建项目, 使用前请先构建项目!"); 124 | return; 125 | } 126 | 127 | 128 | let data = FS.readFileSync(buildCfg, 'utf-8'); 129 | let buildData = JSON.parse(data); 130 | let buildFullDir = PATH.join(projectPath, buildData.buildPath); 131 | let AppDelegateCppFilePath = PATH.join(buildFullDir, 132 | "jsb-" + buildData.template + "/frameworks/runtime-src/Classes/AppDelegate.cpp"); 133 | 134 | if (FS.existsSync(AppDelegateCppFilePath)) { 135 | let fileData = FS.readFileSync(AppDelegateCppFilePath, 'utf-8'); 136 | let gameIDFlag = "CrashReport::initCrashReport(\"" + oldGameID + "\", false);"; 137 | let newGameIDString = "CrashReport::initCrashReport(\"" + this.gameID + "\", false);"; 138 | if (fileData.indexOf(gameIDFlag) >= 0) { 139 | fileData = fileData.replace(gameIDFlag, newGameIDString); 140 | FS.writeFileSync(AppDelegateCppFilePath, fileData); 141 | this._addLog("文件成功更新GameID: " + AppDelegateCppFilePath); 142 | } 143 | } 144 | }, 145 | onAutoUpload() { 146 | this.isAutoUpload = !this.isAutoUpload; 147 | CfgUtil.setIsAutoUpload(this.isAutoUpload); 148 | }, 149 | onSaveCfg() { 150 | CfgUtil.setGameKeyAndVersion(this.gameKey, this.gameVersion, this.channal); 151 | }, 152 | //打开符号表文件 153 | onOpenBuglySymbol() { 154 | if (!FS.existsSync(this.outPutFilePath)) { 155 | return; 156 | } 157 | Electron.shell.showItemInFolder(this.outPutFilePath); 158 | Electron.shell.beep(); 159 | }, 160 | // 上传符号表文件 161 | onUploadBuglySymbol() { 162 | console.log("onUploadBuglySymbol"); 163 | 164 | if (!(this.gameID && this.gameID.length > 0)) { 165 | this._addLog("请填写AppId"); 166 | return; 167 | } 168 | 169 | if (!(this.gameKey && this.gameKey.length > 0)) { 170 | this._addLog("请填写App Key"); 171 | return; 172 | } 173 | if (!(this.gamePackage && this.gamePackage.length > 0)) { 174 | this._addLog("未发现包名, 请先构建安卓项目"); 175 | return; 176 | } 177 | 178 | if (!(this.gameVersion && this.gameVersion.length > 0)) { 179 | this._addLog("请填写版本号"); 180 | return; 181 | } 182 | if (!(this.channal && this.channal.length > 0)) { 183 | this._addLog("请填写channal"); 184 | return; 185 | } 186 | 187 | 188 | let projectPath = Editor.projectInfo.path; 189 | 190 | // 检测so文件 191 | let buildCfg = PATH.join(projectPath, "local/builder.json"); 192 | if (!FS.existsSync(buildCfg)) { 193 | this._addLog("发现没有构建项目, 使用前请先构建项目!"); 194 | return; 195 | } 196 | let data = FS.readFileSync(buildCfg, 'utf-8'); 197 | let buildData = JSON.parse(data); 198 | let buildFullDir = PATH.join(projectPath, buildData.buildPath); 199 | let soPath = PATH.join(buildFullDir, 200 | "jsb-" + buildData.template + "/frameworks/runtime-src/proj.android-studio/app/libs/armeabi-v7a/libcocos2djs.so"); 201 | 202 | if (!FS.existsSync(soPath)) { 203 | this._addLog("请编译项目, 没有发现so文件:" + soPath); 204 | return; 205 | } 206 | 207 | // 符号文件保存地址 208 | const {remote} = require('electron'); 209 | let outPutDirPath = PATH.join(remote.app.getPath('userData'), "buglySymbolAndroid"); 210 | if (!FS.existsSync(outPutDirPath)) { 211 | FS.mkdirSync(outPutDirPath); 212 | } 213 | let outPutFilePath = PATH.join(outPutDirPath, "buglySymbol.zip"); 214 | if (FS.existsSync(outPutFilePath)) { 215 | FS.unlinkSync(outPutFilePath); 216 | } 217 | this.outPutFilePath = ""; 218 | this.isShowOutPutFileFilePath = false; 219 | 220 | let jarPath = PATH.join(projectPath, "packages/plugin-bugly/buglySymbolAndroid/buglySymbolAndroid.jar"); 221 | if (FS.existsSync(jarPath)) { 222 | setUploadBtnDisabled(true); 223 | 224 | let buglyCmd = 225 | "java -Xms512m -Xmx1024m -Dfile.encoding=UTF8 " + 226 | " -jar " + jarPath + 227 | " -i " + soPath + 228 | " -o " + "\"" + outPutFilePath + "\"" + 229 | " -id " + this.gameID + 230 | " -key " + this.gameKey + 231 | " -package " + this.gamePackage + 232 | " -version " + this.gameVersion + 233 | " -channel " + this.channal; 234 | 235 | if (this.isAutoUpload) { 236 | buglyCmd += " -u "; 237 | } 238 | this._addLog("\n[Jar Cmd] " + buglyCmd + "\n"); 239 | // console.log(buglyCmd); 240 | let callFile = require('child_process'); 241 | let ret = callFile.exec(buglyCmd, function (err, stdOut) { 242 | if (err) { 243 | this._addLog("[生成失败:] " + err); 244 | setUploadBtnDisabled(false); 245 | } else { 246 | // this._addLog(stdOut); 247 | } 248 | }.bind(this)); 249 | 250 | ret.stdout.on('data', function (data) { 251 | this._addLogNoTime(data); 252 | 253 | 254 | if (data.indexOf("Successfully zipped symtab file!") >= 0) { 255 | this._addLog("生成成功!"); 256 | this.outPutFilePath = outPutFilePath; 257 | this.isShowOutPutFileFilePath = true; 258 | if (this.isAutoUpload) { 259 | this._addLog("开始上传!"); 260 | } else { 261 | setUploadBtnDisabled(false); 262 | } 263 | } 264 | 265 | if (data.indexOf('Failed to upload symtab file') >= 0) { 266 | this._addLog("上传失败!"); 267 | setUploadBtnDisabled(false); 268 | this.outPutFilePath = outPutFilePath; 269 | this.isShowOutPutFileFilePath = true; 270 | } 271 | if (data.indexOf('Successfully uploaded') >= 0) { 272 | this._addLog("上传成功!"); 273 | setUploadBtnDisabled(false); 274 | this.outPutFilePath = outPutFilePath; 275 | this.isShowOutPutFileFilePath = true; 276 | } 277 | }.bind(this)); 278 | } 279 | 280 | }, 281 | _checkIsBuildProject() { 282 | let projectDir = path.join(Editor.assetdb.library, "../"); 283 | let buildCfg = path.join(projectDir, "local/builder.json"); 284 | if (FileUtil.isFileExit(buildCfg)) { 285 | fs.readFile(buildCfg, 'utf-8', function (err, data) { 286 | if (!err) { 287 | let buildData = JSON.parse(data); 288 | let buildDir = buildData.buildPath; 289 | let buildFullDir = path.join(projectDir, buildDir); 290 | let jsbDir = path.join(buildFullDir, "jsb-default"); 291 | this._checkResourceRootDir(jsbDir); 292 | } 293 | }.bind(this)) 294 | } else { 295 | } 296 | }, 297 | queryBuildOptions(a) { 298 | this.updateGamePackageName(); 299 | }, 300 | onAddBuglySdk() { 301 | if (!(this.gameID && this.gameID.length > 0)) { 302 | this._addLog("请填写App Id"); 303 | return; 304 | } 305 | 306 | let projectPath = Editor.projectInfo.path; 307 | let buildCfg = PATH.join(projectPath, "local/builder.json"); 308 | if (!FS.existsSync(buildCfg)) { 309 | this._addLog("发现没有构建项目, 使用前请先构建项目!"); 310 | return; 311 | } 312 | 313 | 314 | let data = FS.readFileSync(buildCfg, 'utf-8'); 315 | let buildData = JSON.parse(data); 316 | let buildFullDir = PATH.join(projectPath, buildData.buildPath); 317 | 318 | 319 | let version = '1.4.3'; 320 | let buglyResPath = PATH.join(projectPath, 'packages/plugin-bugly/bugly/' + version); 321 | 322 | 323 | // 1.拷贝jar包 324 | /* 将 325 | CocosPlugin\agent\Android\bugly_agent.jar 326 | BuglySDK\Android\bugly_crash_release.jar 327 | 拷贝到 328 | Android工程的frameworks\runtime-src\proj.android-studio\app\libs\ 329 | */ 330 | 331 | function step1() { 332 | window.plugin._addLog("copy jar .."); 333 | // 拷贝的源目录 334 | let agentJar = PATH.join(buglyResPath, "libs/bugly_agent.jar"); 335 | let crashJar = PATH.join(buglyResPath, "libs/bugly_crash_release.jar"); 336 | let jarPath = PATH.join(buglyResPath, "libs"); 337 | if (!FS.existsSync(jarPath)) { 338 | window.plugin._addLog("没有发现插件bugly的jar文件"); 339 | return; 340 | } 341 | 342 | // 拷贝的目标目录 343 | let projAndroidStudio = PATH.join(buildFullDir, "jsb-" + buildData.template + "/frameworks/runtime-src/proj.android-studio/"); 344 | 345 | if (!FS.existsSync(projAndroidStudio)) { 346 | window.plugin._addLog("请构建项目,项目目录不存在:" + projAndroidStudio); 347 | return; 348 | } 349 | 350 | let desJarDir = PATH.join(projAndroidStudio, "app/libs/"); 351 | if (!FS.existsSync(desJarDir)) { 352 | window.plugin._addLog("android studio工程未编译,请编译as项目"); 353 | return; 354 | } 355 | 356 | fse.copy(jarPath, desJarDir, function (err) { 357 | if (err) { 358 | window.plugin._addLog("copy jar failed!"); 359 | console.log(err); 360 | } else { 361 | window.plugin._addLog("copy jar success!"); 362 | step2(); 363 | } 364 | }); 365 | }; 366 | 367 | 368 | // 2.拷贝so库 369 | /* 将 370 | BuglySDK\Android\libs\armeabi-v7a文件夹 371 | 拷贝到 372 | jsb-default\frameworks\runtime-src\proj.android-studio\app\jni\prebuilt, 373 | * 如果prebuilt文件夹不存在就创建一下,如果还需要其他ABI就拷贝相应的,比如常用于模拟器的x86。 374 | * */ 375 | 376 | function step2() { 377 | window.plugin._addLog("copy so .."); 378 | let prebuilt = PATH.join(buildFullDir, 379 | "jsb-" + buildData.template + 380 | "/frameworks/runtime-src/proj.android-studio/app/jni/prebuilt"); 381 | 382 | if (!FS.existsSync(prebuilt)) { 383 | FS.mkdirSync(prebuilt); 384 | window.plugin._addLog("创建 prebuilt 文件夹"); 385 | } 386 | 387 | let prebuiltPath = PATH.join(buglyResPath, "prebuilt"); 388 | if (!FS.existsSync(prebuiltPath)) { 389 | window.plugin._addLog("没有发现插件的prebuilt文件"); 390 | return; 391 | } 392 | fse.copy(prebuiltPath, prebuilt, function (err) { 393 | if (err) { 394 | window.plugin._addLog("copy so failed!"); 395 | console.log(err); 396 | } else { 397 | window.plugin._addLog("copy so success!"); 398 | step3(); 399 | } 400 | }); 401 | } 402 | 403 | // 3.拷贝代码 404 | /* 将 405 | CocosPlugin\bugly文件夹 406 | 拷贝到 407 | frameworks\runtime-src\Classes里面 408 | 其实只需要用到CrashReport.h和CrashReport.mm, 409 | */ 410 | function step3() { 411 | window.plugin._addLog("copy code .."); 412 | 413 | let buglyPath = PATH.join(buglyResPath, "bugly"); 414 | if (!FS.existsSync(buglyPath)) { 415 | window.plugin._addLog("没有发现插件的bugly代码文件"); 416 | return; 417 | } 418 | 419 | let classPath = PATH.join(buildFullDir, 420 | "jsb-" + buildData.template + "/frameworks/runtime-src/Classes/bugly"); 421 | if (!FS.existsSync(classPath)) { 422 | FS.mkdirSync(classPath); 423 | } 424 | 425 | fse.copy(buglyPath, classPath, function (err) { 426 | if (err) { 427 | window.plugin._addLog("copy code failed!"); 428 | console.log(err); 429 | } else { 430 | window.plugin._addLog("copy code success!"); 431 | step4(); 432 | } 433 | }) 434 | 435 | } 436 | 437 | // 4.修改Android.mk 438 | function step4() { 439 | 440 | let mkFile = PATH.join(buildFullDir, 441 | "jsb-" + buildData.template + "/frameworks/runtime-src/proj.android-studio/app/jni/Android.mk"); 442 | 443 | if (!FS.existsSync(mkFile)) { 444 | window.plugin._addLog("不存在mk文件: " + mkFile); 445 | doFailed(); 446 | return; 447 | } 448 | 449 | let data = FS.readFileSync(mkFile, 'utf-8'); 450 | // 增加bugly.so模块 451 | let buglySoFlag = 452 | "LOCAL_PATH := $(call my-dir)\n" + 453 | "# --- bugly: 引用 libBugly.so ---\n" + 454 | "include $(CLEAR_VARS)\n" + 455 | "LOCAL_MODULE := bugly_native_prebuilt\n" + 456 | "LOCAL_SRC_FILES := prebuilt/$(TARGET_ARCH_ABI)/libBugly.so\n" + 457 | "include $(PREBUILT_SHARED_LIBRARY)\n" + 458 | "# --- bugly: end ---"; 459 | if (data.indexOf(buglySoFlag) === -1) { 460 | data = data.replace("LOCAL_PATH := $(call my-dir)", buglySoFlag); 461 | window.plugin._addLog("[Android.mk] 增加libBugly.so引用"); 462 | } else { 463 | window.plugin._addLog("[Android.mk] 已经增加libBugly.so引用"); 464 | } 465 | 466 | // 增加CrashReport.mm编译文件 467 | let AppDelegateFlag = 468 | "\t\t\t\t ../../../Classes/AppDelegate.cpp \\\n" + 469 | "\t\t\t\t ../../../Classes/bugly/CrashReport.mm \\\n"; 470 | if (data.indexOf(AppDelegateFlag) === -1) { 471 | data = data.replace("\t\t\t\t ../../../Classes/AppDelegate.cpp \\\n", AppDelegateFlag); 472 | window.plugin._addLog("[Android.mk] 增加CrashReport.mm引用"); 473 | } else { 474 | window.plugin._addLog("[Android.mk] 已经增加CrashReport.mm引用"); 475 | } 476 | 477 | // 导入bugly 478 | let extFlag = 479 | "# --- bugly: 增加cpp扩展名mm\n" + 480 | "LOCAL_CPP_EXTENSION := .mm .cpp .cc\n" + 481 | "LOCAL_CFLAGS += -x c++\n" + 482 | "LOCAL_SRC_FILES := hellojavascript/main.cpp"; 483 | if (data.indexOf(extFlag) === -1) { 484 | data = data.replace("LOCAL_SRC_FILES := hellojavascript/main.cpp", extFlag); 485 | window.plugin._addLog("[Android.mk] 增加cpp扩展名mm"); 486 | } else { 487 | window.plugin._addLog("[Android.mk] 已经增加cpp扩展名mm"); 488 | } 489 | 490 | FS.writeFileSync(mkFile, data); 491 | step5(); 492 | } 493 | 494 | // 5.修改AppDelegate.cpp 495 | function step5() { 496 | let AppDelegateCppFilePath = PATH.join(buildFullDir, 497 | "jsb-" + buildData.template + "/frameworks/runtime-src/Classes/AppDelegate.cpp"); 498 | if (!FS.existsSync(AppDelegateCppFilePath)) { 499 | window.plugin._addLog("没有发现文件: " + AppDelegateCppFilePath); 500 | doFailed(); 501 | return; 502 | } 503 | let data = FS.readFileSync(AppDelegateCppFilePath, 'utf-8'); 504 | let newData = data; 505 | // 添加头文件引入 506 | let buglyHeadFlag = 507 | "// bugly\n" + 508 | "#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)\n" + 509 | "#include \"bugly/CrashReport.h\"\n" + 510 | "#endif\n" + 511 | "USING_NS_CC;"; 512 | if (data.indexOf(buglyHeadFlag) === -1) { 513 | data = data.replace("USING_NS_CC;", buglyHeadFlag); 514 | window.plugin._addLog("[AppDelegate.cpp] 添加bugly头文件引用"); 515 | } else { 516 | window.plugin._addLog("[AppDelegate.cpp] 已经添加bugly头文件引用"); 517 | } 518 | // 添加bugly初始化 519 | let initFlag = 520 | "bool AppDelegate::applicationDidFinishLaunching()\n" + 521 | "{\n" + 522 | " // 初始化bugly\n" + 523 | "#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)\n" + 524 | " CrashReport::initCrashReport(\"" + window.plugin.gameID + "\", false);\n" + 525 | "#endif"; 526 | 527 | if (data.indexOf(initFlag) === -1) { 528 | data = data.replace( 529 | "bool AppDelegate::applicationDidFinishLaunching()\n" + 530 | "{", initFlag); 531 | window.plugin._addLog("[AppDelegate.cpp] 添加bugly init code"); 532 | } else { 533 | window.plugin._addLog("[AppDelegate.cpp] 已经添加bugly init code"); 534 | } 535 | 536 | // js异常上报 537 | let jsReportFlag = "setExceptionCallback([](const char* location, const char* message, const char* stack){\n" + 538 | " // Send exception information to server like Tencent Bugly.\n" + 539 | " #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)\n" + 540 | " CrashReport::reportException(CATEGORY_JS_EXCEPTION, \"JSException\", message, stack);\n" + 541 | " #endif\n"; 542 | 543 | if (data.indexOf(jsReportFlag) === -1) { 544 | data = data.replace("setExceptionCallback([](const char* location, const char* message, const char* stack){\n" + 545 | " // Send exception information to server like Tencent Bugly.\n", jsReportFlag); 546 | window.plugin._addLog("[AppDelegate.cpp] 添加bugly ExceptionCallback code"); 547 | } else { 548 | window.plugin._addLog("[AppDelegate.cpp] 已经添加bugly ExceptionCallback code"); 549 | } 550 | 551 | 552 | FS.writeFileSync(AppDelegateCppFilePath, data); 553 | 554 | doSuccess(); 555 | } 556 | 557 | function doSuccess() { 558 | window.plugin._addLog("成功添加bugly,请重新编译项目!"); 559 | } 560 | 561 | function doFailed() { 562 | window.plugin._addLog("添加bugly失败!"); 563 | } 564 | 565 | step1(); 566 | } 567 | } 568 | }) 569 | }, 570 | 571 | // register your ipc messages here 572 | messages: { 573 | 'plugin-bugly:cleanLog'(event) { 574 | window.plugin.logView = []; 575 | }, 576 | 'plugin-bugly:queryBuildOptions'(event) { 577 | window.plugin.queryBuildOptions(a); 578 | }, 579 | 580 | } 581 | }); -------------------------------------------------------------------------------- /project.json: -------------------------------------------------------------------------------- 1 | { 2 | "engine": "cocos2d-html5", 3 | "packages": "packages" 4 | } -------------------------------------------------------------------------------- /settings/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "start-scene": "current", 3 | "group-list": [ 4 | "default" 5 | ], 6 | "collision-matrix": [ 7 | [ 8 | true 9 | ] 10 | ], 11 | "excluded-modules": [], 12 | "design-resolution-width": 960, 13 | "design-resolution-height": 640, 14 | "fit-width": false, 15 | "fit-height": true, 16 | "use-project-simulator-setting": false, 17 | "simulator-orientation": false, 18 | "use-customize-simulator": false, 19 | "simulator-resolution": { 20 | "width": 960, 21 | "height": 640 22 | }, 23 | "cocos-analytics": { 24 | "enable": false, 25 | "appID": "", 26 | "appSecret": "" 27 | } 28 | } -------------------------------------------------------------------------------- /template-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tidys/cocos-cretor-bugly-plugin/21435bf3c2b9be45b55d5596bbd8d39f06bf201a/template-banner.png -------------------------------------------------------------------------------- /template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "TEMPLATES.helloworld.name", 3 | "desc": "TEMPLATES.helloworld.desc", 4 | "banner": "template-banner.png" 5 | } --------------------------------------------------------------------------------