diff --git a/Assets/TEngine/Runtime/GameFramework/Bugly.meta b/Assets/TEngine/Runtime/GameFramework/Bugly.meta
new file mode 100644
index 00000000..e037a9a5
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Bugly.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: a2e8f0a34b8444829a115ceca00610ee
+timeCreated: 1681895814
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyConfig.cs b/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyConfig.cs
new file mode 100644
index 00000000..db30a69e
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyConfig.cs
@@ -0,0 +1,14 @@
+using UnityEngine;
+
+namespace TEngine
+{
+ [CreateAssetMenu]
+ public class BuglyConfig : ScriptableObject
+ {
+ public string channelId;
+ public string androidId;
+ public string androidKey;
+ public string iosId;
+ public string iosKey;
+ }
+}
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyConfig.cs.meta b/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyConfig.cs.meta
new file mode 100644
index 00000000..08a3f2ec
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyConfig.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: acf9017ac21e41dc97f7c328c0d6017f
+timeCreated: 1681895834
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyManager.cs b/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyManager.cs
new file mode 100644
index 00000000..ea243c36
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyManager.cs
@@ -0,0 +1,88 @@
+namespace TEngine
+{
+ public class BuglyManager
+ {
+ private static BuglyManager _buglyManager;
+
+ public static BuglyManager Instance => _buglyManager ??= new BuglyManager();
+
+ public void Init(BuglyConfig config,string version = "")
+ {
+ if (config!= null)
+ {
+ ConfigDefault(config.channelId, string.IsNullOrEmpty(version) ? Version.GameVersion : version);
+ BuglyAgent.ConfigDebugMode (false);
+#if UNITY_IPHONE || UNITY_IOS
+ BuglyAgent.InitWithAppId (config.iosId);
+#elif UNITY_ANDROID
+ BuglyAgent.InitWithAppId (config.androidId);
+#endif
+ BuglyAgent.EnableExceptionHandler();
+ Log.Info($"Init Bugly Successes");
+ }
+ else
+ {
+ Log.Fatal("Init Bugly Fatal buglyConfig.asset is null!");
+ }
+ }
+
+ ///
+ /// 启动C#异常捕获上报,默认自动上报级别为LogError,那么LogError、LogException的异常日志都会自动捕获上报。
+ ///
+ public void EnableExceptionHandle()
+ {
+ BuglyAgent.EnableExceptionHandler();
+ }
+
+ ///
+ /// 设置自动上报日志信息的级别,默认LogError,则>=LogError的日志都会自动捕获上报。
+ ///
+ /// 日志级别
+ public void SetReportLogLevel(LogSeverity logLevel)
+ {
+ BuglyAgent.ConfigAutoReportLogLevel(logLevel);
+ }
+
+ ///
+ /// 设置上报的用户唯一标识,项目组可在收到服务器登录回调后调用。
+ ///
+ /// 用户唯一标识。
+ public void SetUserId(string userId)
+ {
+ BuglyAgent.SetUserId(userId);
+ }
+
+ ///
+ /// 上报已捕获C#异常
+ ///
+ /// 异常。
+ /// 描述。
+ public void ReportException(System.Exception e, string description)
+ {
+ BuglyAgent.ReportException(e, description);
+ }
+
+ ///
+ /// 上报自定义错误信息
+ ///
+ /// 错误名称
+ /// 错误原因
+ /// 错误堆栈
+ public void ReportError(string name, string reason, string traceback)
+ {
+ BuglyAgent.ReportException(name, reason, traceback);
+ }
+
+ ///
+ /// 修改默认配置
+ ///
+ /// 渠道号
+ /// 版本号
+ /// 用户唯一标识
+ /// 初始化延时
+ public void ConfigDefault(string channel, string version, string userID = "Unknow", long time = 0)
+ {
+ BuglyAgent.ConfigDefault(channel = null, version, userID = "Unknow", time = 0);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyManager.cs.meta b/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyManager.cs.meta
new file mode 100644
index 00000000..891c70ea
--- /dev/null
+++ b/Assets/TEngine/Runtime/GameFramework/Bugly/BuglyManager.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 94102b3b00fd4c9293073236adec064c
+timeCreated: 1681895834
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/Plugins.meta b/Assets/TEngine/Runtime/Plugins.meta
new file mode 100644
index 00000000..17a3548f
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e8eaf3c7fb019ec4393fe8d9fb91c484
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android.meta b/Assets/TEngine/Runtime/Plugins/Android.meta
new file mode 100644
index 00000000..dcc4d161
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e270de18454c9d34bb5de575c0970bcf
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins.meta
new file mode 100644
index 00000000..18181e3b
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 8958f050e22651e4eb88468e84e82067
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android.meta
new file mode 100644
index 00000000..45b586c7
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android.meta
@@ -0,0 +1,5 @@
+fileFormatVersion: 2
+guid: 694411f45e4e64facb88eebfc2e1df1c
+folderAsset: yes
+DefaultImporter:
+ userData:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs.meta
new file mode 100644
index 00000000..d1c607d7
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 644a9f5710e62403c94066ef9b61e775
+folderAsset: yes
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/arm64-v8a.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/arm64-v8a.meta
new file mode 100644
index 00000000..12c4d1a1
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/arm64-v8a.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: dbe6ceb596d63f5418beb7a12d34993b
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/arm64-v8a/libBugly.so b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/arm64-v8a/libBugly.so
new file mode 100644
index 00000000..3163ec82
Binary files /dev/null and b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/arm64-v8a/libBugly.so differ
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/arm64-v8a/libBugly.so.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/arm64-v8a/libBugly.so.meta
new file mode 100644
index 00000000..aa028557
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/arm64-v8a/libBugly.so.meta
@@ -0,0 +1,80 @@
+fileFormatVersion: 2
+guid: 6f1342562738e5d4dae6ca9bd5a4d02e
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 0
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ : Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 0
+ Exclude Editor: 1
+ Exclude Linux64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 1
+ settings:
+ CPU: ARM64
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ AddToEmbeddedBinaries: false
+ CPU: AnyCPU
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/armeabi-v7a.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/armeabi-v7a.meta
new file mode 100644
index 00000000..3d60b3f7
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/armeabi-v7a.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: fb7b442d8e32443e5856838741007f70
+folderAsset: yes
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/armeabi-v7a/libBugly.so b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/armeabi-v7a/libBugly.so
new file mode 100644
index 00000000..3a902d0e
Binary files /dev/null and b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/armeabi-v7a/libBugly.so differ
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/armeabi-v7a/libBugly.so.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/armeabi-v7a/libBugly.so.meta
new file mode 100644
index 00000000..7193d3b1
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/armeabi-v7a/libBugly.so.meta
@@ -0,0 +1,80 @@
+fileFormatVersion: 2
+guid: 432060a129574479db0cfd441cdf3d69
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 0
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ : Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 0
+ Exclude Editor: 1
+ Exclude Linux64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 1
+ settings:
+ CPU: ARMv7
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ AddToEmbeddedBinaries: false
+ CPU: AnyCPU
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/bugly_crash_release.jar b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/bugly_crash_release.jar
new file mode 100644
index 00000000..e2d94ca9
Binary files /dev/null and b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/bugly_crash_release.jar differ
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/bugly_crash_release.jar.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/bugly_crash_release.jar.meta
new file mode 100644
index 00000000..8ca3164a
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/bugly_crash_release.jar.meta
@@ -0,0 +1,32 @@
+fileFormatVersion: 2
+guid: 74c10c94ce6f83b44998e0ad9de920bc
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 0
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ Android: Android
+ second:
+ enabled: 1
+ settings: {}
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/buglyagent.jar b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/buglyagent.jar
new file mode 100644
index 00000000..b3d5fcf9
Binary files /dev/null and b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/buglyagent.jar differ
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/buglyagent.jar.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/buglyagent.jar.meta
new file mode 100644
index 00000000..43ee2e71
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/buglyagent.jar.meta
@@ -0,0 +1,32 @@
+fileFormatVersion: 2
+guid: 1db231dca0f72420cb880590f799d7d5
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 0
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ Android: Android
+ second:
+ enabled: 1
+ settings: {}
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/x86.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/x86.meta
new file mode 100644
index 00000000..86f270f5
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/x86.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 79531ba82725e4071861c982307805c3
+folderAsset: yes
+timeCreated: 1443426231
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/x86/libBugly.so b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/x86/libBugly.so
new file mode 100644
index 00000000..bddb714f
Binary files /dev/null and b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/x86/libBugly.so differ
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/x86/libBugly.so.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/x86/libBugly.so.meta
new file mode 100644
index 00000000..4106179b
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/Android/libs/x86/libBugly.so.meta
@@ -0,0 +1,80 @@
+fileFormatVersion: 2
+guid: 16eaf0ec67588418783d6f5311aa71ce
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 0
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ : Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 0
+ Exclude Editor: 1
+ Exclude Linux64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 1
+ settings:
+ CPU: x86
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ AddToEmbeddedBinaries: false
+ CPU: AnyCPU
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyAgent.cs b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyAgent.cs
new file mode 100644
index 00000000..cb3e89db
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyAgent.cs
@@ -0,0 +1,1084 @@
+// ----------------------------------------
+//
+// BuglyAgent.cs
+//
+// Author:
+// Yeelik,
+//
+// Copyright (c) 2015 Bugly, Tencent. All rights reserved.
+//
+// ----------------------------------------
+//
+using UnityEngine;
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+
+using System.Runtime.InteropServices;
+
+// We dont use the LogType enum in Unity as the numerical order doesnt suit our purposes
+///
+/// Log severity.
+/// { Log, LogDebug, LogInfo, LogWarning, LogAssert, LogError, LogException }
+///
+public enum LogSeverity
+{
+ Log,
+ LogDebug,
+ LogInfo,
+ LogWarning,
+ LogAssert,
+ LogError,
+ LogException
+}
+
+///
+/// Bugly agent.
+///
+public sealed class BuglyAgent
+{
+
+ // Define delegate support multicasting to replace the 'Application.LogCallback'
+ public delegate void LogCallbackDelegate (string condition,string stackTrace,LogType type);
+
+ ///
+ /// Configs the type of the crash reporter and customized log level to upload
+ ///
+ /// Type. Default=0, 1=Bugly v2.x MSDK=2
+ /// Log level. Off=0,Error=1,Warn=2,Info=3,Debug=4
+ public static void ConfigCrashReporter(int type, int logLevel){
+ _SetCrashReporterType (type);
+ _SetCrashReporterLogLevel (logLevel);
+ }
+
+ ///
+ /// Init sdk with the specified appId.
+ /// This will initialize sdk to report native exception such as obj-c, c/c++, java exceptions, and also enable c# exception handler to report c# exception logs
+ ///
+ /// App identifier.
+ public static void InitWithAppId (string appId)
+ {
+ if (IsInitialized) {
+ DebugLog (null, "BuglyAgent has already been initialized.");
+
+ return;
+ }
+
+ if (string.IsNullOrEmpty (appId)) {
+ return;
+ }
+
+ // init the sdk with app id
+ InitBuglyAgent (appId);
+ DebugLog (null, "Initialized with app id: {0}", appId);
+
+ // Register the LogCallbackHandler by Application.RegisterLogCallback(Application.LogCallback)
+ _RegisterExceptionHandler ();
+ }
+
+ ///
+ /// Only Enable the C# exception handler.
+ ///
+ ///
+ /// You can call it when you do not call the 'InitWithAppId(string)', but you must make sure initialized the sdk in elsewhere,
+ /// such as the native code in associated Android or iOS project.
+ ///
+ ///
+ ///
+ /// Default Level is LogError, so the LogError, LogException will auto report.
+ ///
+ ///
+ ///
+ /// You can call the method BuglyAgent.ConfigAutoReportLogLevel(LogSeverity)
+ /// to change the level to auto report if you known what are you doing.
+ ///
+ ///
+ ///
+ public static void EnableExceptionHandler ()
+ {
+ if (IsInitialized) {
+ DebugLog (null, "BuglyAgent has already been initialized.");
+ return;
+ }
+
+ DebugLog (null, "Only enable the exception handler, please make sure you has initialized the sdk in the native code in associated Android or iOS project.");
+
+ // Register the LogCallbackHandler by Application.RegisterLogCallback(Application.LogCallback)
+ _RegisterExceptionHandler ();
+ }
+
+ ///
+ /// Registers the log callback handler.
+ ///
+ /// If you need register logcallback using Application.RegisterLogCallback(LogCallback),
+ /// you can call this method to replace it.
+ ///
+ ///
+ ///
+ /// Handler.
+ public static void RegisterLogCallback (LogCallbackDelegate handler)
+ {
+ if (handler != null) {
+ DebugLog (null, "Add log callback handler: {0}", handler);
+
+ _LogCallbackEventHandler += handler;
+ }
+ }
+
+ ///
+ /// Sets the log callback extras handler.
+ ///
+ /// Handler.
+ public static void SetLogCallbackExtrasHandler(Func> handler){
+ if (handler != null) {
+ _LogCallbackExtrasHandler = handler;
+
+ DebugLog(null, "Add log callback extra data handler : {0}", handler);
+ }
+ }
+
+ ///
+ /// Reports the exception.
+ ///
+ /// E.
+ /// Message.
+ public static void ReportException (System.Exception e, string message)
+ {
+ if (!IsInitialized) {
+ return;
+ }
+
+ DebugLog (null, "Report exception: {0}\n------------\n{1}\n------------", message, e);
+
+ _HandleException (e, message, false);
+ }
+
+ ///
+ /// Reports the exception.
+ ///
+ /// Name.
+ /// Message.
+ /// Stack trace.
+ public static void ReportException (string name, string message, string stackTrace)
+ {
+ if (!IsInitialized) {
+ return;
+ }
+
+ DebugLog (null, "Report exception: {0} {1} \n{2}", name, message, stackTrace);
+
+ _HandleException (LogSeverity.LogException, name, message, stackTrace, false);
+ }
+
+ ///
+ /// Unregisters the log callback.
+ ///
+ /// Handler.
+ public static void UnregisterLogCallback (LogCallbackDelegate handler)
+ {
+ if (handler != null) {
+ DebugLog (null, "Remove log callback handler");
+
+ _LogCallbackEventHandler -= handler;
+ }
+ }
+
+ ///
+ /// Sets the user identifier.
+ ///
+ /// User identifier.
+ public static void SetUserId (string userId)
+ {
+ if (!IsInitialized) {
+ return;
+ }
+ DebugLog (null, "Set user id: {0}", userId);
+
+ SetUserInfo (userId);
+ }
+
+ ///
+ /// Sets the scene.
+ ///
+ /// Scene identifier.
+ public static void SetScene (int sceneId)
+ {
+ if (!IsInitialized) {
+ return;
+ }
+ DebugLog (null, "Set scene: {0}", sceneId);
+
+ SetCurrentScene (sceneId);
+ }
+
+ ///
+ /// Adds the scene data.
+ ///
+ /// Key.
+ /// Value.
+ public static void AddSceneData (string key, string value)
+ {
+ if (!IsInitialized) {
+ return;
+ }
+
+ DebugLog (null, "Add scene data: [{0}, {1}]", key, value);
+
+ AddKeyAndValueInScene (key, value);
+ }
+
+ ///
+ /// Configs the debug mode.
+ ///
+ /// If set to true debug mode.
+ public static void ConfigDebugMode (bool enable)
+ {
+ EnableDebugMode (enable);
+ DebugLog (null, "{0} the log message print to console", enable ? "Enable" : "Disable");
+ }
+
+ ///
+ /// Configs the auto quit application.
+ ///
+ /// If set to true auto quit.
+ public static void ConfigAutoQuitApplication (bool autoQuit)
+ {
+ _autoQuitApplicationAfterReport = autoQuit;
+ }
+
+ ///
+ /// Configs the auto report log level. Default is LogSeverity.LogError.
+ ///
+ /// LogSeverity { Log, LogDebug, LogInfo, LogWarning, LogAssert, LogError, LogException }
+ ///
+ ///
+ ///
+ /// Level.
+ public static void ConfigAutoReportLogLevel (LogSeverity level)
+ {
+ _autoReportLogLevel = level;
+ }
+
+ ///
+ /// Configs the default.
+ ///
+ /// Channel.
+ /// Version.
+ /// User.
+ /// Delay.
+ public static void ConfigDefault (string channel, string version, string user, long delay)
+ {
+ DebugLog (null, "Config default channel:{0}, version:{1}, user:{2}, delay:{3}", channel, version, user, delay);
+ ConfigDefaultBeforeInit (channel, version, user, delay);
+ }
+
+ ///
+ /// Logs the debug.
+ ///
+ /// Tag.
+ /// Format.
+ /// Arguments.
+ public static void DebugLog (string tag, string format, params object[] args)
+ {
+ if(!_debugMode) {
+ return;
+ }
+
+ if (string.IsNullOrEmpty (format)) {
+ return;
+ }
+
+ Console.WriteLine ("[BuglyAgent] - {0} : {1}", tag, string.Format (format, args));
+ }
+
+ ///
+ /// Prints the log.
+ ///
+ /// Level.
+ /// Format.
+ /// Arguments.
+ public static void PrintLog (LogSeverity level, string format, params object[] args)
+ {
+ if (string.IsNullOrEmpty (format)) {
+ return;
+ }
+
+ LogRecord (level, string.Format (format, args));
+ }
+
+ #if UNITY_EDITOR || UNITY_STANDALONE
+
+ #region Interface(Empty) in Editor
+ private static void InitBuglyAgent (string appId)
+ {
+ }
+
+ private static void ConfigDefaultBeforeInit(string channel, string version, string user, long delay){
+ }
+
+ private static void EnableDebugMode(bool enable){
+ }
+
+ private static void SetUserInfo(string userInfo){
+ }
+
+ private static void ReportException (int type,string name, string message, string stackTrace, bool quitProgram)
+ {
+ }
+
+ private static void SetCurrentScene(int sceneId) {
+ }
+
+ private static void AddKeyAndValueInScene(string key, string value){
+ }
+
+ private static void AddExtraDataWithException(string key, string value) {
+ // only impl for iOS
+ }
+
+ private static void LogRecord(LogSeverity level, string message){
+ }
+
+ private static void SetUnityVersion(){
+
+ }
+ #endregion
+
+ #elif UNITY_ANDROID
+ // #if UNITY_ANDROID
+
+ #region Interface for Android
+ private static readonly string GAME_AGENT_CLASS = "com.tencent.bugly.agent.GameAgent";
+ private static readonly int TYPE_U3D_CRASH = 4;
+ private static readonly int GAME_TYPE_UNITY = 2;
+ private static bool hasSetGameType = false;
+ private static AndroidJavaClass _gameAgentClass = null;
+
+ public static AndroidJavaClass GameAgent {
+ get {
+ if (_gameAgentClass == null) {
+ _gameAgentClass = new AndroidJavaClass(GAME_AGENT_CLASS);
+// using (AndroidJavaClass clazz = new AndroidJavaClass(CLASS_UNITYAGENT)) {
+// _gameAgentClass = clazz.CallStatic ("getInstance");
+// }
+ }
+ if (!hasSetGameType) {
+ // set game type: unity(2).
+ _gameAgentClass.CallStatic ("setGameType", GAME_TYPE_UNITY);
+ hasSetGameType = true;
+ }
+ return _gameAgentClass;
+ }
+ }
+
+ private static string _configChannel;
+ private static string _configVersion;
+ private static string _configUser;
+ private static long _configDelayTime;
+
+ private static void ConfigDefaultBeforeInit(string channel, string version, string user, long delay){
+ _configChannel = channel;
+ _configVersion = version;
+ _configUser = user;
+ _configDelayTime = delay;
+ }
+
+ private static bool _configCrashReporterPackage = false;
+
+ private static void ConfigCrashReporterPackage(){
+
+ if (!_configCrashReporterPackage) {
+ try {
+ GameAgent.CallStatic("setSdkPackageName", _crashReporterPackage);
+ _configCrashReporterPackage = true;
+ } catch {
+
+ }
+ }
+
+ }
+
+ private static void InitBuglyAgent(string appId)
+ {
+ if (IsInitialized) {
+ return;
+ }
+
+ ConfigCrashReporterPackage();
+
+ try {
+ GameAgent.CallStatic("initCrashReport", appId, _configChannel, _configVersion, _configUser, _configDelayTime);
+ _isInitialized = true;
+ } catch {
+
+ }
+ }
+
+ private static void EnableDebugMode(bool enable){
+ _debugMode = enable;
+
+ ConfigCrashReporterPackage();
+
+ try {
+ GameAgent.CallStatic("setLogEnable", enable);
+ } catch {
+
+ }
+ }
+
+ private static void SetUserInfo(string userInfo){
+ ConfigCrashReporterPackage();
+
+ try {
+ GameAgent.CallStatic("setUserId", userInfo);
+ } catch {
+ }
+ }
+
+ private static void ReportException (int type, string name, string reason, string stackTrace, bool quitProgram)
+ {
+ ConfigCrashReporterPackage();
+
+ try {
+ GameAgent.CallStatic("postException", TYPE_U3D_CRASH, name, reason, stackTrace, quitProgram);
+ } catch {
+
+ }
+ }
+
+ private static void SetCurrentScene(int sceneId) {
+ ConfigCrashReporterPackage();
+
+ try {
+ GameAgent.CallStatic("setUserSceneTag", sceneId);
+ } catch {
+
+ }
+ }
+
+ private static void SetUnityVersion(){
+ ConfigCrashReporterPackage();
+
+ try {
+ GameAgent.CallStatic("setSdkConfig", "UnityVersion", Application.unityVersion);
+ } catch {
+
+ }
+ }
+
+ private static void AddKeyAndValueInScene(string key, string value){
+ ConfigCrashReporterPackage();
+
+ try {
+ GameAgent.CallStatic("putUserData", key, value);
+ } catch {
+
+ }
+ }
+
+ private static void AddExtraDataWithException(string key, string value) {
+ // no impl
+ }
+
+ private static void LogRecord(LogSeverity level, string message){
+ if (level < LogSeverity.LogWarning) {
+ DebugLog (level.ToString (), message);
+ }
+
+ ConfigCrashReporterPackage();
+
+ try {
+ GameAgent.CallStatic("printLog", string.Format ("<{0}> - {1}", level.ToString (), message));
+ } catch {
+
+ }
+ }
+
+ #endregion
+
+ #elif UNITY_IPHONE || UNITY_IOS
+
+ #region Interface for iOS
+
+ private static bool _crashReporterTypeConfiged = false;
+
+ private static void ConfigCrashReporterType(){
+ if (!_crashReporterTypeConfiged) {
+ try {
+ _BuglyConfigCrashReporterType(_crashReporterType);
+ _crashReporterTypeConfiged = true;
+ } catch {
+
+ }
+ }
+ }
+
+ private static void ConfigDefaultBeforeInit(string channel, string version, string user, long delay){
+ ConfigCrashReporterType();
+
+ try {
+ _BuglyDefaultConfig(channel, version, user, null);
+ } catch {
+
+ }
+ }
+
+ private static void EnableDebugMode(bool enable){
+ _debugMode = enable;
+ }
+
+ private static void InitBuglyAgent (string appId)
+ {
+ ConfigCrashReporterType();
+
+ if(!string.IsNullOrEmpty(appId)) {
+
+ _BuglyInit(appId, _debugMode, _crashReproterCustomizedLogLevel); // Log level
+ }
+ }
+
+ private static void SetUnityVersion(){
+ ConfigCrashReporterType();
+
+ _BuglySetExtraConfig("UnityVersion", Application.unityVersion);
+ }
+
+ private static void SetUserInfo(string userInfo){
+ if(!string.IsNullOrEmpty(userInfo)) {
+ ConfigCrashReporterType();
+
+ _BuglySetUserId(userInfo);
+ }
+ }
+
+ private static void ReportException (int type, string name, string reason, string stackTrace, bool quitProgram)
+ {
+ ConfigCrashReporterType();
+
+ string extraInfo = "";
+ Dictionary extras = null;
+ if (_LogCallbackExtrasHandler != null) {
+ extras = _LogCallbackExtrasHandler();
+ }
+ if (extras == null || extras.Count == 0) {
+ extras = new Dictionary ();
+ extras.Add ("UnityVersion", Application.unityVersion);
+ }
+
+ if (extras != null && extras.Count > 0) {
+ if (!extras.ContainsKey("UnityVersion")) {
+ extras.Add ("UnityVersion", Application.unityVersion);
+ }
+
+ StringBuilder builder = new StringBuilder();
+ foreach(KeyValuePair kvp in extras){
+ builder.Append(string.Format("\"{0}\" : \"{1}\"", kvp.Key, kvp.Value)).Append(" , ");
+ }
+ extraInfo = string.Format("{{ {0} }}", builder.ToString().TrimEnd(" , ".ToCharArray()));
+ }
+
+ // 4 is C# exception
+ _BuglyReportException(4, name, reason, stackTrace, extraInfo, quitProgram);
+ }
+
+ private static void SetCurrentScene(int sceneId) {
+ ConfigCrashReporterType();
+
+ _BuglySetTag(sceneId);
+ }
+
+ private static void AddKeyAndValueInScene(string key, string value){
+ ConfigCrashReporterType();
+
+ _BuglySetKeyValue(key, value);
+ }
+
+ private static void AddExtraDataWithException(string key, string value) {
+
+ }
+
+ private static void LogRecord(LogSeverity level, string message){
+ if (level < LogSeverity.LogWarning) {
+ DebugLog (level.ToString (), message);
+ }
+
+ ConfigCrashReporterType();
+
+ _BuglyLogMessage(LogSeverityToInt(level), null, message);
+ }
+
+ private static int LogSeverityToInt(LogSeverity logLevel){
+ int level = 5;
+ switch(logLevel) {
+ case LogSeverity.Log:
+ level = 5;
+ break;
+ case LogSeverity.LogDebug:
+ level = 4;
+ break;
+ case LogSeverity.LogInfo:
+ level = 3;
+ break;
+ case LogSeverity.LogWarning:
+ case LogSeverity.LogAssert:
+ level = 2;
+ break;
+ case LogSeverity.LogError:
+ case LogSeverity.LogException:
+ level = 1;
+ break;
+ default:
+ level = 0;
+ break;
+ }
+ return level;
+ }
+
+ // --- dllimport start ---
+ [DllImport("__Internal")]
+ private static extern void _BuglyInit(string appId, bool debug, int level);
+
+ [DllImport("__Internal")]
+ private static extern void _BuglySetUserId(string userId);
+
+ [DllImport("__Internal")]
+ private static extern void _BuglySetTag(int tag);
+
+ [DllImport("__Internal")]
+ private static extern void _BuglySetKeyValue(string key, string value);
+
+ [DllImport("__Internal")]
+ private static extern void _BuglyReportException(int type, string name, string reason, string stackTrace, string extras, bool quit);
+
+ [DllImport("__Internal")]
+ private static extern void _BuglyDefaultConfig(string channel, string version, string user, string deviceId);
+
+ [DllImport("__Internal")]
+ private static extern void _BuglyLogMessage(int level, string tag, string log);
+
+ [DllImport("__Internal")]
+ private static extern void _BuglyConfigCrashReporterType(int type);
+
+ [DllImport("__Internal")]
+ private static extern void _BuglySetExtraConfig(string key, string value);
+
+ // dllimport end
+ #endregion
+
+ #endif
+
+ #region Privated Fields and Methods
+ private static event LogCallbackDelegate _LogCallbackEventHandler;
+
+ private static bool _isInitialized = false;
+ private static LogSeverity _autoReportLogLevel = LogSeverity.LogError;
+
+ private static int _crashReporterType = 1; // Default=0,1=Bugly-V2,MSDKBugly=2, IMSDKBugly=3
+
+#if UNITY_ANDROID
+ // The crash reporter package name, default is 'com.tencent.bugly'
+ private static string _crashReporterPackage = "com.tencent.bugly";
+#endif
+#if UNITY_IPHONE || UNITY_IOS
+ private static int _crashReproterCustomizedLogLevel = 2; // Off=0,Error=1,Warn=2,Info=3,Debug=4
+#endif
+
+ #pragma warning disable 414
+ private static bool _debugMode = false;
+ private static bool _autoQuitApplicationAfterReport = false;
+
+ private static readonly int EXCEPTION_TYPE_UNCAUGHT = 1;
+ private static readonly int EXCEPTION_TYPE_CAUGHT = 2;
+ private static readonly string _pluginVersion = "1.5.1";
+
+ private static Func> _LogCallbackExtrasHandler;
+
+ public static string PluginVersion {
+ get { return _pluginVersion; }
+ }
+
+ public static bool IsInitialized {
+ get { return _isInitialized; }
+ }
+
+ public static bool AutoQuitApplicationAfterReport {
+ get { return _autoQuitApplicationAfterReport; }
+ }
+
+ private static void _SetCrashReporterType(int type){
+ _crashReporterType = type;
+
+ if (_crashReporterType == 2) {
+#if UNITY_ANDROID
+ _crashReporterPackage = "com.tencent.bugly.msdk";
+#endif
+ }
+
+ }
+
+ private static void _SetCrashReporterLogLevel(int logLevel){
+#if UNITY_IPHONE || UNITY_IOS
+ _crashReproterCustomizedLogLevel = logLevel;
+#endif
+ }
+
+ private static void _RegisterExceptionHandler ()
+ {
+ try {
+ // hold only one instance
+
+ #if UNITY_5
+ Application.logMessageReceived += _OnLogCallbackHandler;
+ #else
+#pragma warning disable CS0618
+ Application.RegisterLogCallback (_OnLogCallbackHandler);
+#pragma warning restore CS0618
+#endif
+ AppDomain.CurrentDomain.UnhandledException += _OnUncaughtExceptionHandler;
+
+ _isInitialized = true;
+
+ DebugLog (null, "Register the log callback in Unity {0}", Application.unityVersion);
+ } catch {
+
+ }
+
+ SetUnityVersion ();
+ }
+
+ private static void _UnregisterExceptionHandler ()
+ {
+ try {
+ #if UNITY_5
+ Application.logMessageReceived -= _OnLogCallbackHandler;
+ #else
+#pragma warning disable CS0618
+ Application.RegisterLogCallback (null);
+#pragma warning restore CS0618
+#endif
+ System.AppDomain.CurrentDomain.UnhandledException -= _OnUncaughtExceptionHandler;
+ DebugLog (null, "Unregister the log callback in unity {0}", Application.unityVersion);
+ } catch {
+
+ }
+ }
+
+ private static void _OnLogCallbackHandler (string condition, string stackTrace, LogType type)
+ {
+ if (_LogCallbackEventHandler != null) {
+ _LogCallbackEventHandler (condition, stackTrace, type);
+ }
+
+ if (!IsInitialized) {
+ return;
+ }
+
+ if (!string.IsNullOrEmpty (condition) && condition.Contains ("[BuglyAgent] ")) {
+ return;
+ }
+
+ if (_uncaughtAutoReportOnce) {
+ return;
+ }
+
+ // convert the log level
+ LogSeverity logLevel = LogSeverity.Log;
+ switch (type) {
+ case LogType.Exception:
+ logLevel = LogSeverity.LogException;
+ break;
+ case LogType.Error:
+ logLevel = LogSeverity.LogError;
+ break;
+ case LogType.Assert:
+ logLevel = LogSeverity.LogAssert;
+ break;
+ case LogType.Warning:
+ logLevel = LogSeverity.LogWarning;
+ break;
+ case LogType.Log:
+ logLevel = LogSeverity.LogDebug;
+ break;
+ default:
+ break;
+ }
+
+ if (LogSeverity.Log == logLevel) {
+ return;
+ }
+
+ _HandleException (logLevel, null, condition, stackTrace, true);
+ }
+
+ private static void _OnUncaughtExceptionHandler (object sender, System.UnhandledExceptionEventArgs args)
+ {
+ if (args == null || args.ExceptionObject == null) {
+ return;
+ }
+
+ try {
+ if (args.ExceptionObject.GetType () != typeof(System.Exception)) {
+ return;
+ }
+ } catch {
+ if (UnityEngine.Debug.isDebugBuild == true) {
+ UnityEngine.Debug.Log ("BuglyAgent: Failed to report uncaught exception");
+ }
+
+ return;
+ }
+
+ if (!IsInitialized) {
+ return;
+ }
+
+ if (_uncaughtAutoReportOnce) {
+ return;
+ }
+
+ _HandleException ((System.Exception)args.ExceptionObject, null, true);
+ }
+
+ private static void _HandleException (System.Exception e, string message, bool uncaught)
+ {
+ if (e == null) {
+ return;
+ }
+
+ if (!IsInitialized) {
+ return;
+ }
+
+ string name = e.GetType ().Name;
+ string reason = e.Message;
+
+ if (!string.IsNullOrEmpty (message)) {
+ reason = string.Format ("{0}{1}***{2}", reason, Environment.NewLine, message);
+ }
+
+ StringBuilder stackTraceBuilder = new StringBuilder ("");
+
+ StackTrace stackTrace = new StackTrace (e, true);
+ int count = stackTrace.FrameCount;
+ for (int i = 0; i < count; i++) {
+ StackFrame frame = stackTrace.GetFrame (i);
+
+ stackTraceBuilder.AppendFormat ("{0}.{1}", frame.GetMethod ().DeclaringType.Name, frame.GetMethod ().Name);
+
+ ParameterInfo[] parameters = frame.GetMethod ().GetParameters ();
+ if (parameters == null || parameters.Length == 0) {
+ stackTraceBuilder.Append (" () ");
+ } else {
+ stackTraceBuilder.Append (" (");
+
+ int pcount = parameters.Length;
+
+ ParameterInfo param = null;
+ for (int p = 0; p < pcount; p++) {
+ param = parameters [p];
+ stackTraceBuilder.AppendFormat ("{0} {1}", param.ParameterType.Name, param.Name);
+
+ if (p != pcount - 1) {
+ stackTraceBuilder.Append (", ");
+ }
+ }
+ param = null;
+
+ stackTraceBuilder.Append (") ");
+ }
+
+ string fileName = frame.GetFileName ();
+ if (!string.IsNullOrEmpty (fileName) && !fileName.ToLower ().Equals ("unknown")) {
+ fileName = fileName.Replace ("\\", "/");
+
+ int loc = fileName.ToLower ().IndexOf ("/assets/");
+ if (loc < 0) {
+ loc = fileName.ToLower ().IndexOf ("assets/");
+ }
+
+ if (loc > 0) {
+ fileName = fileName.Substring (loc);
+ }
+
+ stackTraceBuilder.AppendFormat ("(at {0}:{1})", fileName, frame.GetFileLineNumber ());
+ }
+ stackTraceBuilder.AppendLine ();
+ }
+
+ // report
+ _reportException (uncaught, name, reason, stackTraceBuilder.ToString ());
+ }
+
+ private static void _reportException (bool uncaught, string name, string reason, string stackTrace)
+ {
+ if (string.IsNullOrEmpty (name)) {
+ return;
+ }
+
+ if (string.IsNullOrEmpty (stackTrace)) {
+ stackTrace = StackTraceUtility.ExtractStackTrace ();
+ }
+
+ if (string.IsNullOrEmpty (stackTrace)) {
+ stackTrace = "Empty";
+ } else {
+
+ try {
+ string[] frames = stackTrace.Split ('\n');
+
+ if (frames != null && frames.Length > 0) {
+
+ StringBuilder trimFrameBuilder = new StringBuilder ();
+
+ string frame = null;
+ int count = frames.Length;
+ for (int i = 0; i < count; i++) {
+ frame = frames [i];
+
+ if (string.IsNullOrEmpty (frame) || string.IsNullOrEmpty (frame.Trim ())) {
+ continue;
+ }
+
+ frame = frame.Trim ();
+
+ // System.Collections.Generic
+ if (frame.StartsWith ("System.Collections.Generic.") || frame.StartsWith ("ShimEnumerator")) {
+ continue;
+ }
+ if (frame.StartsWith ("Bugly")) {
+ continue;
+ }
+ if (frame.Contains ("..ctor")) {
+ continue;
+ }
+
+ int start = frame.ToLower ().IndexOf ("(at");
+ int end = frame.ToLower ().IndexOf ("/assets/");
+
+ if (start > 0 && end > 0) {
+ trimFrameBuilder.AppendFormat ("{0}(at {1}", frame.Substring (0, start).Replace (":", "."), frame.Substring (end));
+ } else {
+ trimFrameBuilder.Append (frame.Replace (":", "."));
+ }
+
+ trimFrameBuilder.AppendLine ();
+ }
+
+ stackTrace = trimFrameBuilder.ToString ();
+ }
+ } catch {
+ PrintLog(LogSeverity.LogWarning,"{0}", "Error to parse the stack trace");
+ }
+
+ }
+
+ PrintLog (LogSeverity.LogError, "ReportException: {0} {1}\n*********\n{2}\n*********", name, reason, stackTrace);
+
+ _uncaughtAutoReportOnce = uncaught && _autoQuitApplicationAfterReport;
+
+ ReportException (uncaught ? EXCEPTION_TYPE_UNCAUGHT : EXCEPTION_TYPE_CAUGHT, name, reason, stackTrace, uncaught && _autoQuitApplicationAfterReport);
+ }
+
+ private static void _HandleException (LogSeverity logLevel, string name, string message, string stackTrace, bool uncaught)
+ {
+ if (!IsInitialized) {
+ DebugLog (null, "It has not been initialized.");
+ return;
+ }
+
+ if (logLevel == LogSeverity.Log) {
+ return;
+ }
+
+ if ((uncaught && logLevel < _autoReportLogLevel)) {
+ DebugLog (null, "Not report exception for level {0}", logLevel.ToString ());
+ return;
+ }
+
+ string type = null;
+ string reason = null;
+
+ if (!string.IsNullOrEmpty (message)) {
+ try {
+ if ((LogSeverity.LogException == logLevel) && message.Contains ("Exception")) {
+
+ Match match = new Regex (@"^(?\S+):\s*(?.*)", RegexOptions.Singleline).Match (message);
+
+ if (match.Success) {
+ type = match.Groups ["errorType"].Value.Trim();
+ reason = match.Groups ["errorMessage"].Value.Trim ();
+ }
+ } else if ((LogSeverity.LogError == logLevel) && message.StartsWith ("Unhandled Exception:")) {
+
+ Match match = new Regex (@"^Unhandled\s+Exception:\s*(?\S+):\s*(?.*)", RegexOptions.Singleline).Match(message);
+
+ if (match.Success) {
+ string exceptionName = match.Groups ["exceptionName"].Value.Trim();
+ string exceptionDetail = match.Groups ["exceptionDetail"].Value.Trim ();
+
+ //
+ int dotLocation = exceptionName.LastIndexOf(".");
+ if (dotLocation > 0 && dotLocation != exceptionName.Length) {
+ type = exceptionName.Substring(dotLocation + 1);
+ } else {
+ type = exceptionName;
+ }
+
+ int stackLocation = exceptionDetail.IndexOf(" at ");
+ if (stackLocation > 0) {
+ //
+ reason = exceptionDetail.Substring(0, stackLocation);
+ // substring after " at "
+ string callStacks = exceptionDetail.Substring(stackLocation + 3).Replace(" at ", "\n").Replace("in :0","").Replace("[0x00000]","");
+ //
+ stackTrace = string.Format("{0}\n{1}", stackTrace, callStacks.Trim());
+
+ } else {
+ reason = exceptionDetail;
+ }
+
+ // for LuaScriptException
+ if(type.Equals("LuaScriptException") && exceptionDetail.Contains(".lua") && exceptionDetail.Contains("stack traceback:")) {
+ stackLocation = exceptionDetail.IndexOf("stack traceback:");
+ if(stackLocation > 0) {
+ reason = exceptionDetail.Substring(0, stackLocation);
+ // substring after "stack traceback:"
+ string callStacks = exceptionDetail.Substring(stackLocation + 16).Replace(" [", " \n[");
+
+ //
+ stackTrace = string.Format("{0}\n{1}", stackTrace, callStacks.Trim());
+ }
+ }
+ }
+
+ }
+ } catch {
+
+ }
+
+ if (string.IsNullOrEmpty (reason)) {
+ reason = message;
+ }
+ }
+
+ if (string.IsNullOrEmpty (name)) {
+ if (string.IsNullOrEmpty (type)) {
+ type = string.Format ("Unity{0}", logLevel.ToString ());
+ }
+ } else {
+ type = name;
+ }
+
+ _reportException (uncaught, type, reason, stackTrace);
+ }
+
+ private static bool _uncaughtAutoReportOnce = false;
+
+ #endregion
+
+}
\ No newline at end of file
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyAgent.cs.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyAgent.cs.meta
new file mode 100644
index 00000000..20a57a04
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyAgent.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: be621fe31508b4f2ab134ee879ec97b4
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyCallback.cs b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyCallback.cs
new file mode 100644
index 00000000..77c70c64
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyCallback.cs
@@ -0,0 +1,27 @@
+// ----------------------------------------
+//
+// BuglyCallbackDelegate.cs
+//
+// Author:
+// Yeelik,
+//
+// Copyright (c) 2015 Bugly, Tencent. All rights reserved.
+//
+// ----------------------------------------
+//
+using UnityEngine;
+using System.Collections;
+
+public abstract class BuglyCallback
+{
+ // The delegate of callback handler which Call the Application.RegisterLogCallback(Application.LogCallback)
+ ///
+ /// Raises the application log callback handler event.
+ ///
+ /// Condition.
+ /// Stack trace.
+ /// Type.
+ public abstract void OnApplicationLogCallbackHandler (string condition, string stackTrace, LogType type);
+
+}
+
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyCallback.cs.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyCallback.cs.meta
new file mode 100644
index 00000000..a61dcf32
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyCallback.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 78e76f643d1884dcab602d5fe79b08e1
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyInit.cs b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyInit.cs
new file mode 100644
index 00000000..ff6b5a70
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyInit.cs
@@ -0,0 +1,80 @@
+// ----------------------------------------
+//
+// BuglyInit.cs
+//
+// Author:
+// Yeelik,
+//
+// Copyright (c) 2015 Bugly, Tencent. All rights reserved.
+//
+// ----------------------------------------
+//
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+
+public class BuglyInit : MonoBehaviour
+{
+ ///
+ /// Your Bugly App ID. Every app has a special identifier that allows Bugly to associate error monitoring data with your app.
+ /// Your App ID can be found on the "Setting" page of the app you are trying to monitor.
+ ///
+ /// A real App ID looks like this: 90000xxxx
+ private const string BuglyAppID = "YOUR APP ID GOES HERE";
+
+ void Awake ()
+ {
+ // Enable the debug log print
+ BuglyAgent.ConfigDebugMode (false);
+ // Config default channel, version, user
+ BuglyAgent.ConfigDefault (null, null, null, 0);
+ // Config auto report log level, default is LogSeverity.LogError, so the LogError, LogException log will auto report
+ BuglyAgent.ConfigAutoReportLogLevel (LogSeverity.LogError);
+ // Config auto quit the application make sure only the first one c# exception log will be report, please don't set TRUE if you do not known what are you doing.
+ BuglyAgent.ConfigAutoQuitApplication (false);
+ // If you need register Application.RegisterLogCallback(LogCallback), you can replace it with this method to make sure your function is ok.
+ BuglyAgent.RegisterLogCallback (null);
+
+ // Init the bugly sdk and enable the c# exception handler.
+ BuglyAgent.InitWithAppId (BuglyAppID);
+
+ // TODO Required. If you do not need call 'InitWithAppId(string)' to initialize the sdk(may be you has initialized the sdk it associated Android or iOS project),
+ // please call this method to enable c# exception handler only.
+ BuglyAgent.EnableExceptionHandler ();
+
+ // TODO NOT Required. If you need to report extra data with exception, you can set the extra handler
+ BuglyAgent.SetLogCallbackExtrasHandler (MyLogCallbackExtrasHandler);
+
+ Destroy (this);
+ }
+
+ // Extra data handler to packet data and report them with exception.
+ // Please do not do hard work in this handler
+ static Dictionary MyLogCallbackExtrasHandler ()
+ {
+ // TODO Test log, please do not copy it
+ BuglyAgent.PrintLog (LogSeverity.Log, "extra handler");
+
+ // TODO Sample code, please do not copy it
+ Dictionary extras = new Dictionary ();
+ extras.Add ("ScreenSolution", string.Format ("{0}x{1}", Screen.width, Screen.height));
+ extras.Add ("deviceModel", SystemInfo.deviceModel);
+ extras.Add ("deviceName", SystemInfo.deviceName);
+ extras.Add ("deviceType", SystemInfo.deviceType.ToString ());
+
+ extras.Add ("deviceUId", SystemInfo.deviceUniqueIdentifier);
+ extras.Add ("gDId", string.Format ("{0}", SystemInfo.graphicsDeviceID));
+ extras.Add ("gDName", SystemInfo.graphicsDeviceName);
+ extras.Add ("gDVdr", SystemInfo.graphicsDeviceVendor);
+ extras.Add ("gDVer", SystemInfo.graphicsDeviceVersion);
+ extras.Add ("gDVdrID", string.Format ("{0}", SystemInfo.graphicsDeviceVendorID));
+
+ extras.Add ("graphicsMemorySize", string.Format ("{0}", SystemInfo.graphicsMemorySize));
+ extras.Add ("systemMemorySize", string.Format ("{0}", SystemInfo.systemMemorySize));
+ extras.Add ("UnityVersion", Application.unityVersion);
+
+ BuglyAgent.PrintLog (LogSeverity.LogInfo, "Package extra data");
+ return extras;
+ }
+}
+
diff --git a/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyInit.cs.meta b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyInit.cs.meta
new file mode 100644
index 00000000..4c6c0ff8
--- /dev/null
+++ b/Assets/TEngine/Runtime/Plugins/Android/BuglyPlugins/BuglyInit.cs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: a717f6955eddf4463ad541714a1b5483
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData: