lzx 1 giorno fa
parent
commit
f18f09da6b
65 ha cambiato i file con 5768 aggiunte e 82 eliminazioni
  1. 1 0
      Assets/Obfuz/SymbolObfus/symbol-mapping.xml
  2. 8 0
      Assets/Plugins/Android/CrashSight.meta
  3. 15 0
      Assets/Plugins/Android/CrashSight/AndroidManifest.xml
  4. 7 0
      Assets/Plugins/Android/CrashSight/AndroidManifest.xml.meta
  5. 8 0
      Assets/Plugins/Android/CrashSight/libs.meta
  6. BIN
      Assets/Plugins/Android/CrashSight/libs/CrashSight_crash_release.jar
  7. 37 0
      Assets/Plugins/Android/CrashSight/libs/CrashSight_crash_release.jar.meta
  8. 8 0
      Assets/Plugins/Android/CrashSight/libs/arm64-v8a.meta
  9. BIN
      Assets/Plugins/Android/CrashSight/libs/arm64-v8a/libCrashSight.so
  10. 39 0
      Assets/Plugins/Android/CrashSight/libs/arm64-v8a/libCrashSight.so.meta
  11. 8 0
      Assets/Plugins/Android/CrashSight/libs/armeabi-v7a.meta
  12. BIN
      Assets/Plugins/Android/CrashSight/libs/armeabi-v7a/libCrashSight.so
  13. 39 0
      Assets/Plugins/Android/CrashSight/libs/armeabi-v7a/libCrashSight.so.meta
  14. 8 0
      Assets/Plugins/Android/CrashSight/libs/x86.meta
  15. BIN
      Assets/Plugins/Android/CrashSight/libs/x86/libCrashSight.so
  16. 39 0
      Assets/Plugins/Android/CrashSight/libs/x86/libCrashSight.so.meta
  17. 8 0
      Assets/Plugins/Android/CrashSight/libs/x86_64.meta
  18. BIN
      Assets/Plugins/Android/CrashSight/libs/x86_64/libCrashSight.so
  19. 39 0
      Assets/Plugins/Android/CrashSight/libs/x86_64/libCrashSight.so.meta
  20. 4 0
      Assets/Plugins/Android/CrashSight/proguard-project.txt
  21. 7 0
      Assets/Plugins/Android/CrashSight/proguard-project.txt.meta
  22. 2 0
      Assets/Plugins/Android/CrashSight/project.properties
  23. 7 0
      Assets/Plugins/Android/CrashSight/project.properties.meta
  24. 4 1
      Assets/Scripts/GameUI/GameApplction.cs
  25. 8 0
      Assets/Scripts/ThirdParty/CrashSight.meta
  26. 8 0
      Assets/Scripts/ThirdParty/CrashSight/Editor.meta
  27. 8 0
      Assets/Scripts/ThirdParty/CrashSight/Editor/Mods.meta
  28. 8 0
      Assets/Scripts/ThirdParty/CrashSight/Editor/Mods/CrashSight.meta
  29. 24 0
      Assets/Scripts/ThirdParty/CrashSight/Editor/Mods/CrashSight/CrashSight.projmods
  30. 7 0
      Assets/Scripts/ThirdParty/CrashSight/Editor/Mods/CrashSight/CrashSight.projmods.meta
  31. 8 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts.meta
  32. 2237 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/CrashSightAgent.cs
  33. 11 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/CrashSightAgent.cs.meta
  34. 8 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore.meta
  35. 8 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM.meta
  36. 63 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/UQM.cs
  37. 11 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/UQM.cs.meta
  38. 1707 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/UQMCrash.cs
  39. 11 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/UQMCrash.cs.meta
  40. 8 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils.meta
  41. 10 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMDefine.cs
  42. 11 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMDefine.cs.meta
  43. 87 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMLog.cs
  44. 11 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMLog.cs.meta
  45. 140 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMMessageCenter.cs
  46. 11 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMMessageCenter.cs.meta
  47. 516 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMMiniJSON.cs
  48. 11 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMMiniJSON.cs.meta
  49. 8 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight.meta
  50. 8 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight.meta
  51. 103 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightAnrMonitor.cs
  52. 11 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightAnrMonitor.cs.meta
  53. 26 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightCallback.cs
  54. 11 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightCallback.cs.meta
  55. 59 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightMonoBehavior.cs
  56. 11 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightMonoBehavior.cs.meta
  57. 161 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightStackTrace.cs
  58. 11 0
      Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightStackTrace.cs.meta
  59. 37 26
      Assets/Scripts/ThirdParty/Crasheye/Crasheye.cs
  60. 2 1
      Assets/Scripts/ThirdParty/Crasheye/CrasheyeForUnityLib.asmdef
  61. 11 0
      Assets/Settings/rpAsset.asset
  62. 5 5
      Packages/manifest.json
  63. 49 46
      Packages/packages-lock.json
  64. 3 3
      ProjectSettings/ProjectVersion.txt
  65. 32 0
      ProjectSettings/ThreadInfoSettings.asset

+ 1 - 0
Assets/Obfuz/SymbolObfus/symbol-mapping.xml

@@ -2196,6 +2196,7 @@
       <method signature="object $Obfuz$ProxyCall::@$Obfuz$Dispatch_36812_10087402(object, object, int)" newName="$z" oldStackTraceSignature="$Obfuz$ProxyCall:$Obfuz$Dispatch_36812_10087402(Object, Object, Int32)" newStackTraceSignature="$p:$z(Object, Object, Int32)" />
       <method signature="string $Obfuz$ProxyCall::@$Obfuz$Dispatch_11150_11558398(object, int)" newName="$bA" oldStackTraceSignature="$Obfuz$ProxyCall:$Obfuz$Dispatch_11150_11558398(Object, Int32)" newStackTraceSignature="$p:$bA(Object, Int32)" />
       <method signature="string $Obfuz$ProxyCall::@$Obfuz$Dispatch_22824_11558398(int)" newName="$BA" oldStackTraceSignature="$Obfuz$ProxyCall:$Obfuz$Dispatch_22824_11558398(Int32)" newStackTraceSignature="$p:$BA(Int32)" />
+      <method signature="string $Obfuz$ProxyCall::@$Obfuz$Dispatch_59003_11558398(float, int)" newName="$M" oldStackTraceSignature="$Obfuz$ProxyCall:$Obfuz$Dispatch_59003_11558398(Single, Int32)" newStackTraceSignature="$p:$M(Single, Int32)" />
       <method signature="System.Threading.Tasks.Task $Obfuz$ProxyCall::@$Obfuz$Dispatch_50754_13355026(object, object, object, int)" newName="$CA" oldStackTraceSignature="$Obfuz$ProxyCall:$Obfuz$Dispatch_50754_13355026(Object, Object, Object, Int32)" newStackTraceSignature="$p:$CA(Object, Object, Object, Int32)" />
       <method signature="System.Threading.Tasks.Task`1&lt;[System.Net.Http]System.Net.Http.HttpResponseMessage&gt; $Obfuz$ProxyCall::@$Obfuz$Dispatch_50754_4049763(object, object, object, int)" newName="$dA" oldStackTraceSignature="$Obfuz$ProxyCall:$Obfuz$Dispatch_50754_4049763(Object, Object, Object, Int32)" newStackTraceSignature="$p:$dA(Object, Object, Object, Int32)" />
       <method signature="System.Threading.Tasks.Task`1&lt;string&gt; $Obfuz$ProxyCall::@$Obfuz$Dispatch_11150_4396324(object, int)" newName="$DA" oldStackTraceSignature="$Obfuz$ProxyCall:$Obfuz$Dispatch_11150_4396324(Object, Int32)" newStackTraceSignature="$p:$DA(Object, Int32)" />

+ 8 - 0
Assets/Plugins/Android/CrashSight.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: WnNNt36uBnPfObm5lm4tJuT8netLQqCQlnn491nLs6wuAQUa9rOhPDRkCpCg
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 15 - 0
Assets/Plugins/Android/CrashSight/AndroidManifest.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+This Google Mobile Ads plugin library manifest will get merged with your
+application's manifest, adding the necessary activity and permissions
+required for displaying ads.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.uqm.gcloud.crashsight">
+    <uses-sdk android:targetSdkVersion="30" android:minSdkVersion="15"/>
+
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+
+</manifest>

+ 7 - 0
Assets/Plugins/Android/CrashSight/AndroidManifest.xml.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: CnNO5HilWnmgjfdNl9yyJnD8DaJ+Hhge6o9RoR1nLkkXAW2KqQa7iaqB7W+A
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Plugins/Android/CrashSight/libs.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: DCketyOsUyjbrkUxN/Z2DMoZ4xrA6onghV8exXR8D4eGPIx/vC+r7w9mT1eV
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/Plugins/Android/CrashSight/libs/CrashSight_crash_release.jar


+ 37 - 0
Assets/Plugins/Android/CrashSight/libs/CrashSight_crash_release.jar.meta

@@ -0,0 +1,37 @@
+fileFormatVersion: 2
+guid: XHIZs3moUX3M+fVKCTEfv+K7ywm8vcHaxXBEbsD7zF9llebAg6l6sWPXSEj9
+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
+  - first:
+      HMIAndroid: HMIAndroid
+    second:
+      enabled: 1
+      settings: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Plugins/Android/CrashSight/libs/arm64-v8a.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: B3sX4yP7BnI+ZoxW/qqjM1NYKP1L7a+95Vmz59k3N93/A9rgD156PteNcWUY
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/Plugins/Android/CrashSight/libs/arm64-v8a/libCrashSight.so


+ 39 - 0
Assets/Plugins/Android/CrashSight/libs/arm64-v8a/libCrashSight.so.meta

@@ -0,0 +1,39 @@
+fileFormatVersion: 2
+guid: XitKsn6kUili7zW1TrGL9fqaV3oyFXKDAm9ySRn1n6lJ6U6JLpNkJ1o0C1Sm
+PluginImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  iconMap: {}
+  executionOrder: {}
+  defineConstraints: []
+  isPreloaded: 0
+  isOverridable: 0
+  isExplicitlyReferenced: 0
+  validateReferences: 1
+  platformData:
+  - first:
+      Android: Android
+    second:
+      enabled: 1
+      settings:
+        CPU: ARM64
+  - first:
+      Any: 
+    second:
+      enabled: 0
+      settings: {}
+  - first:
+      Editor: Editor
+    second:
+      enabled: 0
+      settings:
+        DefaultValueInitialized: true
+  - first:
+      HMIAndroid: HMIAndroid
+    second:
+      enabled: 1
+      settings:
+        CPU: ARM64
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Plugins/Android/CrashSight/libs/armeabi-v7a.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: XH1Ms3upV3rDqztB4dpIHh+ABiFKfDD2EGY5x5e3eX4DsSeXjI6GuTIotJvO
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/Plugins/Android/CrashSight/libs/armeabi-v7a/libCrashSight.so


+ 39 - 0
Assets/Plugins/Android/CrashSight/libs/armeabi-v7a/libCrashSight.so.meta

@@ -0,0 +1,39 @@
+fileFormatVersion: 2
+guid: B35Nsiz5UnhD+pGOepDsru1Vyx3uPbKjwV49qW0QcbYiVqW11jvTd+ujkk7n
+PluginImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  iconMap: {}
+  executionOrder: {}
+  defineConstraints: []
+  isPreloaded: 0
+  isOverridable: 0
+  isExplicitlyReferenced: 0
+  validateReferences: 1
+  platformData:
+  - first:
+      Android: Android
+    second:
+      enabled: 1
+      settings:
+        CPU: ARMv7
+  - first:
+      Any: 
+    second:
+      enabled: 0
+      settings: {}
+  - first:
+      Editor: Editor
+    second:
+      enabled: 0
+      settings:
+        DefaultValueInitialized: true
+  - first:
+      HMIAndroid: HMIAndroid
+    second:
+      enabled: 1
+      settings:
+        CPU: ARMv7
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Plugins/Android/CrashSight/libs/x86.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: Cnwf4C74V3pg/VHLWjBenNL5wWm6qjvEIoYOcDLQ42rM35d+0/3q1vHhY8LM
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/Plugins/Android/CrashSight/libs/x86/libCrashSight.so


+ 39 - 0
Assets/Plugins/Android/CrashSight/libs/x86/libCrashSight.so.meta

@@ -0,0 +1,39 @@
+fileFormatVersion: 2
+guid: DS4WtCioAS3ii6YKujl3BN4oyTSkQN3YzLsE4SV/1qSwdwvIOuVdNzYjd9hX
+PluginImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  iconMap: {}
+  executionOrder: {}
+  defineConstraints: []
+  isPreloaded: 0
+  isOverridable: 0
+  isExplicitlyReferenced: 0
+  validateReferences: 1
+  platformData:
+  - first:
+      Android: Android
+    second:
+      enabled: 1
+      settings:
+        CPU: x86
+  - first:
+      Any: 
+    second:
+      enabled: 0
+      settings: {}
+  - first:
+      Editor: Editor
+    second:
+      enabled: 0
+      settings:
+        DefaultValueInitialized: true
+  - first:
+      HMIAndroid: HMIAndroid
+    second:
+      enabled: 1
+      settings:
+        CPU: x86
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Plugins/Android/CrashSight/libs/x86_64.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: Bi5Mtyr8Wiq2CSq7dsCW8iQSEZ0sCq84bkCn8pMe7IddGssU2t9WcNf2pPJx
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/Plugins/Android/CrashSight/libs/x86_64/libCrashSight.so


+ 39 - 0
Assets/Plugins/Android/CrashSight/libs/x86_64/libCrashSight.so.meta

@@ -0,0 +1,39 @@
+fileFormatVersion: 2
+guid: DC8f5yqqUnKLn1tDEeFT5wCduXa0beGTziBqa2fqLyjdihBwgYySRCjD/Xm9
+PluginImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  iconMap: {}
+  executionOrder: {}
+  defineConstraints: []
+  isPreloaded: 0
+  isOverridable: 0
+  isExplicitlyReferenced: 0
+  validateReferences: 1
+  platformData:
+  - first:
+      Android: Android
+    second:
+      enabled: 1
+      settings:
+        CPU: x86_64
+  - first:
+      Any: 
+    second:
+      enabled: 0
+      settings: {}
+  - first:
+      Editor: Editor
+    second:
+      enabled: 0
+      settings:
+        DefaultValueInitialized: true
+  - first:
+      HMIAndroid: HMIAndroid
+    second:
+      enabled: 1
+      settings:
+        CPU: x86_64
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 4 - 0
Assets/Plugins/Android/CrashSight/proguard-project.txt

@@ -0,0 +1,4 @@
+ # crashsight sdk
+-keep public class com.uqm.crashsight.** { *; }
+-dontwarn com.uqm.crashsight.core.**
+-keep class com.uqm.crashsight.core.** { *; }

+ 7 - 0
Assets/Plugins/Android/CrashSight/proguard-project.txt.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: WSxL43ivVi2hPjxHf6DiIa1Lvxx/G23w/vKrV4LUQPcosgSuzadArd2mmwxs
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 2 - 0
Assets/Plugins/Android/CrashSight/project.properties

@@ -0,0 +1,2 @@
+target=android-26
+android.library=true

+ 7 - 0
Assets/Plugins/Android/CrashSight/project.properties.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: Di4a5y2oVS+1rDqC6xSxRoM49SjXDkIjkm33MRJ4speJHdqdRTIh13aPYVuH
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 4 - 1
Assets/Scripts/GameUI/GameApplction.cs

@@ -144,6 +144,7 @@ public class GameApplction : IGameStart, ILogSend
         RedDotManager.Instance.Init();
         // await GameNetworkClient.Instance.Connect("127.0.0.1", 1000);
         await Login();
+        CrashSightAgent.SetUserId(AccountFileInfo.Instance.playerData.playerId);
     }
 
     private async CTask Login()
@@ -304,7 +305,7 @@ public class GameApplction : IGameStart, ILogSend
         if (_cache.Length > 100 * 1024 || GetLineCount(_cache.ToString()) > 50)
             Flush();
         Crasheye.SendScriptException(massge, massge, "");
-
+        // CrashSightAgent.ReportException(LogType.Error.ToString(), massge, massge);
     }
 
     private void Flush()
@@ -328,6 +329,7 @@ public class GameApplction : IGameStart, ILogSend
         _cache.AppendLine($"{e.Message} {e.StackTrace}");
         Flush();
         Crasheye.SendScriptException(e);
+        CrashSightAgent.ReportException(e, e.Message);
     }
 
     public void UnityLogic(string logString, string stackTrace, LogType type)
@@ -335,6 +337,7 @@ public class GameApplction : IGameStart, ILogSend
         if (type == LogType.Error || type == LogType.Exception)
         {
             Crasheye.SendScriptException(logString, stackTrace, "");
+            CrashSightAgent.ReportException(logString, stackTrace, stackTrace);
         }
     }
 

+ 8 - 0
Assets/Scripts/ThirdParty/CrashSight.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: XClN5CuvV3tzk9s+UQQkVs8HplfCUPzB2PgHU1TIszz8mA72aMaJfzJImyNb
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Scripts/ThirdParty/CrashSight/Editor.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: CSgctCylAHjzm+kvDXbJ+vSXGHuOC59xqbGf8ZT1+Y1iHOhNJdLZH3ApEDCs
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Scripts/ThirdParty/CrashSight/Editor/Mods.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: Dysa5H+uUC4jWB2hjjQh1Clw89O5z+1A5dFpHlZYd+hKFu0VLQ90xmRxizoB
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Scripts/ThirdParty/CrashSight/Editor/Mods/CrashSight.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: DCwd4Hv+B3z3vG7HEX90HC9NAzhR3svISRqv7TTdvFQcORjGiaF/m13PuSoP
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 24 - 0
Assets/Scripts/ThirdParty/CrashSight/Editor/Mods/CrashSight/CrashSight.projmods

@@ -0,0 +1,24 @@
+{
+    "group": "CrashSight",
+    "libs": [
+    			"libz.dylib", 
+    			"libc++.dylib"
+    		],
+    "frameworks": [
+	 				"SystemConfiguration.framework",
+    				"Security.framework",
+                    "JavaScriptCore.framework",
+                    "MetricKit.framework:weak",
+                    "OSLog.framework:weak",
+                    "CFNetwork.framework"
+    			  ],
+    "headerpaths": [],
+    "files":   [],
+    "folders": [],    
+    "excludes": ["^.*.meta$", "^.*.mdown$", "^.*.pdf$"],
+    "compiler_flags": [],
+    "linker_flags": [
+    					"-ObjC"
+    				]
+
+}

+ 7 - 0
Assets/Scripts/ThirdParty/CrashSight/Editor/Mods/CrashSight/CrashSight.projmods.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: DHwdtHv4V3jZkEl5ysHMF0kONI6jccQEUzu1IxHPKU6PZN+ZbMrAbwsHJqcZ
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: C3MetHyuB3lQ9/lEfovBakZJWJ5f+cTgn2Fj7vBKRTEVdnDNL47Cg0ains6g
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 2237 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/CrashSightAgent.cs

@@ -0,0 +1,2237 @@
+// ----------------------------------------
+//
+//  CrashSightAgent.cs
+//
+//  Author:
+//       Yeelik,
+//
+//  Copyright (c) 2015 CrashSight. All rights reserved.
+//
+// ----------------------------------------
+//
+using UnityEngine;
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Globalization;
+
+using GCloud.UQM;
+
+/// <summary>
+/// [EN] Defines the logType<br/>
+/// [ZH] 定义日志的级别
+/// </summary>
+/// <remarks>
+/// [EN] We dont use LogType enum in Unity as the numerical order doesnt suit our purposes<br/>
+/// [ZH] 我们未使用 Unity 的 LogType 枚举,因其数值顺序不符合需求
+/// </remarks>
+public enum CSLogSeverity
+{
+    LogSilent,
+    LogError,
+    LogWarning,
+    LogInfo,
+    LogDebug,
+    LogVerbose
+}
+
+/// <summary>
+/// [EN] Defines the output type of the log report<br/>
+/// [ZH] 定义日志报告的输出方式类型
+/// </summary>
+public enum CSReportType
+{
+    InterfaceReport,
+    LogCallback,
+    LogCallbackThreaded
+}
+
+/// <summary>
+/// [EN] Defines information options for jank report<br/>
+/// [ZH] 定义卡顿报告的信息选项
+/// </summary>
+public enum JankReportInfoOption
+{
+     JankOnlyBasicInfo = 0,
+     JankSystemLog = 1,
+     JankCustomLog = 2,
+     JankCustomKv = 4,
+     JankCallbackInfo = 8,
+     JankAutoDumpStack = 16,
+     JankAndroidAllJavaStack = 32
+}
+
+/// <summary>
+/// CrashSight agent.
+/// </summary>
+public sealed class CrashSightAgent
+{
+    private static string crashUploadUrl = string.Empty;
+
+    public static List<int> callbackThreads = new List<int>();
+
+    public static object callbackThreadsLock = new object();
+
+    /// <summary>
+    /// [EN] Defines the log callback delegate<br/>
+    /// [ZH] 定义日志回调委托
+    /// </summary>
+    /// <remarks>
+    /// [EN] Defines delegate support multicasting to replace the 'Application.LogCallback'<br/>
+    /// [ZH] 定义支持多播的委托,用于替换'Application.LogCallback'
+    /// </remarks>
+    public delegate void LogCallbackDelegate(string condition, string stackTrace, LogType type);
+
+    private static event LogCallbackDelegate _LogCallbackEventHandler;
+
+    private static bool _isInitialized = false;
+
+    private static LogType _autoReportLogLevel = LogType.Error;
+
+#pragma warning disable 414
+    private static bool _debugMode = false;
+
+    private static bool _autoQuitApplicationAfterReport = false;
+
+    private static Func<Dictionary<string, string>> _LogCallbackExtrasHandler;
+
+    private static bool _uncaughtAutoReportOnce = false;
+
+
+    /************************************全平台接口************************************/
+
+    /// <summary>
+    /// [EN] Initializes CrashSight<br/>
+    /// [ZH] 初始化CrashSight
+    /// </summary>
+    /// <remarks>
+    /// [EN] Initializes as early as possible to enable crash detection and reporting features<br/>
+    /// [ZH] 在尽可能早的位置进行初始化以开启崩溃捕获和上报功能
+    /// </remarks>
+    /// <param name="appId">
+    /// [EN] APPID of registered projects<br/>
+    /// [ZH] 已注册项目的APPID
+    /// </param>
+    public static void InitWithAppId(string appId, bool forceOnUiThread = false)
+    {
+        if (IsInitialized)
+        {
+            DebugLog(null, "CrashSightAgent has already been initialized.");
+
+            return;
+        }
+
+        if (string.IsNullOrEmpty(appId))
+        {
+            return;
+        }
+
+        // init the sdk with app id
+        UQMCrash.InitWithAppId(appId, forceOnUiThread);
+        DebugLog(null, "Initialized with app id: " + appId + " crashUploadUrl: " + crashUploadUrl);
+
+        // Register the LogCallbackHandler by Application.RegisterLogCallback(Application.LogCallback)
+        _RegisterExceptionHandler();
+    }
+
+    /// <summary>
+    /// [EN] Actively reports errors<br/>
+    /// [ZH] 主动上报错误
+    /// </summary>
+    /// <remarks>
+    /// [EN] Used to report captured C# exceptions<br/>
+    /// [ZH] 用于上报捕获的c#异常
+    /// </remarks>
+    /// <param name="e">
+    /// [EN] Caught exception<br/>
+    /// [ZH] 捕获到的异常
+    /// </param>
+    /// <param name="message">
+    /// [EN] Exception message<br/>
+    /// [ZH] 异常信息</param>
+    public static void ReportException(System.Exception e, string message)
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+
+        DebugLog(null, "Report exception: " + message + "\n------------\n" + e + "\n------------");
+
+        _HandleException(e, message, false);
+    }
+
+    /// <summary>
+    /// [EN] Actively reports errors<br/>
+    /// [ZH] 主动上报错误
+    /// </summary>
+    /// <remarks>
+    /// [EN] Can be called manually when an error is caught or needs to be reported, multi-threaded calls are supported<br/>
+    /// [ZH] 可以在捕获到错误或者需要上报的时候手动调用,支持多线程调用
+    /// </remarks>
+    /// <param name="name">
+    /// [EN] Exception Name, cannot be null<br/>
+    /// [ZH] 异常名称,不能为null
+    /// </param>
+    /// <param name="message">
+    /// [EN] Exception message, cannot be null<br/>
+    /// [ZH] 异常信息,不能为null
+    /// </param>
+    /// <param name="stackTrace">
+    /// [EN] Stack, cannot be null<br/>
+    /// [ZH] 堆栈,不能为null
+    /// </param>
+    public static void ReportException(string name, string message, string stackTrace)
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+
+        DebugLog(null, "Report exception: " + name + " " + message + " \n" + stackTrace);
+
+        _HandleException(LogType.Exception, name, message, stackTrace, false, CSReportType.InterfaceReport);
+    }
+
+    /// <summary>
+    /// [EN] Actively reports errors<br/>
+    /// [ZH] 主动上报错误
+    /// </summary>
+    /// <remarks>
+    /// [EN] Can be called manually when an error is caught or needs to be reported, multi-threaded calls are supported<br/>
+    /// [ZH] 可以在捕获到错误或者需要上报的时候手动调用,支持多线程调用<br/>
+    /// </remarks>
+    /// <param name="type">
+    /// [EN] Exception Type, 0~3 are internal reserved types and are invalid if passed in<br/>
+    /// [ZH] 异常类型, 0~3为内部保留类型传入无效, C#: 4, js: 5, lua: 6
+    /// </param>
+    /// <param name="exceptionName">
+    /// [EN] Exception Name, cannot be null<br/>
+    /// [ZH] 异常名称,不能为null
+    /// </param>
+    /// <param name="exceptionMsg">
+    /// [EN] Exception message, cannot be null<br/>
+    /// [ZH] 异常信息,不能为null
+    /// </param>
+    /// <param name="exceptionStack">
+    /// [EN] Stack, cannot be null<br/>
+    /// [ZH] 堆栈,不能为null
+    /// </param>
+    /// <param name="extInfo">
+    /// [EN] Other Info<br/>
+    /// [ZH] 其他信息
+    /// </param>
+    /// <param name="dumpNativeType">
+    /// [EN] 0: close, 1: call system interface dump, 3: minidump (only valid for mobile)<br/>
+    /// [ZH] 0:关闭,1:调用系统接口dump,3:minidump(仅移动端有效)
+    /// </param>
+    /// <param name="errorAttachmentPath">
+    /// [EN] Absolute path of log attachment (only valid for Android)<br/>
+    /// [ZH] 日志附件的绝对路径(仅Android有效)
+    /// </param>
+    public static void ReportException(int type, string exceptionName, string exceptionMsg, string exceptionStack, Dictionary<string, string> extInfo, int dumpNativeType = 0, string errorAttachmentPath = "")
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+        UQMCrash.ReportException(type, exceptionName, exceptionMsg, exceptionStack, extInfo, dumpNativeType, errorAttachmentPath);
+    }
+
+    /// <summary>
+    /// [EN] Sets user ID<br/>
+    /// [ZH] 设置用户ID
+    /// </summary>
+    /// <remarks>
+    /// [EN] The user id defaults to unknown<br/>
+    /// [ZH] 用户ID默认为unknown
+    /// </remarks>
+    /// <param name="userId">
+    /// [EN] User ID<br/>
+    /// [ZH] 用户ID
+    /// </param>
+    public static void SetUserId(string userId)
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+        DebugLog(null, "Set user id: " + userId);
+
+        UQMCrash.SetUserId(userId);
+    }
+
+    /// <summary>
+    /// [EN] Adds custom data<br/>
+    /// [ZH] 添加自定义数据
+    /// </summary>
+    /// <remarks>
+    /// [EN] Set the Key-Value data customized by the user. It will be reported together with exception info when sending the crash<br/>
+    /// [ZH] 设置用户自定义的 Key-Value 数据,将在发送 Crash 时随异常信息一起上报<br/>
+    /// [EN] View page: Crash Details->Download Attachments->valueMapOthers.txt<br/>
+    /// [ZH] 页面查看:崩溃详情页->附件下载->valueMapOthers.txt
+    /// </remarks>
+    /// <param name="key"></param>
+    /// <param name="value"></param>
+    public static void AddSceneData(string key, string value)
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+
+        DebugLog(null, "Add scene data: [" + key + ", " + value + "]");
+
+        UQMCrash.AddSceneData(key, value);
+    }
+
+    /// <summary>
+    /// [EN] Adds custom data<br/>
+    /// [ZH] 添加自定义数据
+    /// </summary>
+    /// <remarks>
+    /// [EN] Call <see cref="AddSceneData"/> to set the Key-Value data customized by the user, where the value is int type. 
+    ///      It will be reported together with exception info when sending the crash<br/>
+    /// [ZH] 调用 <see cref="AddSceneData"/> 设置用户自定义的 Key-Value 数据,其中 value 为 int 类型,将在发送 Crash 时随异常信息一起上报<br/>
+    /// [EN] View page: Crash Details->Download Attachments->valueMapOthers.txt<br/>
+    /// [ZH] 页面查看:崩溃详情页->附件下载->valueMapOthers.txt
+    /// </remarks>
+    /// <param name="key"></param>
+    /// <param name="value"></param>
+    public static void SetUserValue(string key, int value)
+    {
+        AddSceneData("I#" + key, "" + value);
+    }
+
+    /// <summary>
+    /// [EN] Adds custom data<br/>
+    /// [ZH] 添加自定义数据
+    /// </summary>
+    /// <remarks>
+    /// [EN] Call <see cref="AddSceneData"/> to set the Key-Value data customized by the user, where the value is string type. 
+    ///      It will be reported together with exception info when sending the crash<br/>
+    /// [ZH] 调用 <see cref="AddSceneData"/> 设置用户自定义的 Key-Value 数据,其中 value 为 string 类型,将在发送 Crash 时随异常信息一起上报<br/>
+    /// [EN] View page: Crash Details->Download Attachments->valueMapOthers.txt<br/>
+    /// [ZH] 页面查看:崩溃详情页->附件下载->valueMapOthers.txt
+    /// </remarks>
+    /// <param name="key"></param>
+    /// <param name="value"></param>
+    public static void SetUserValue(string key, string value)
+    {
+        AddSceneData("K#" + key, value);
+    }
+
+    /// <summary>
+    /// [EN] Adds custom data<br/>
+    /// [ZH] 添加自定义数据
+    /// </summary>
+    /// <remarks>
+    /// [EN] Call <see cref="AddSceneData"/> to set the Key-Value data customized by the user, where the value is string[] type. 
+    ///      It will be reported together with exception info when sending the crash<br/>
+    /// [ZH] 调用 <see cref="AddSceneData"/> 设置用户自定义的 Key-Value 数据,其中 value 为 string[] 类型,将在发送 Crash 时随异常信息一起上报<br/>
+    /// [EN] View page: Crash Details->Download Attachments->valueMapOthers.txt<br/>
+    /// [ZH] 页面查看:崩溃详情页->附件下载->valueMapOthers.txt
+    /// </remarks>
+    /// <param name="key"></param>
+    /// <param name="value"></param>
+    public static void SetUserValue(string key, string[] value)
+    {
+        string valueStr = string.Join("#", value);
+        AddSceneData("S#" + key, valueStr);
+    }
+
+    /// <summary>
+    /// [EN] Sets application version<br/>
+    /// [ZH] 设置应用版本号
+    /// </summary>
+    /// <remarks>
+    /// [EN] Need to be called before <see cref="InitWithAppId"/> interface<br/>
+    /// [ZH] 需要在 <see cref="InitWithAppId"/> 接口之前调用
+    /// </remarks>
+    /// <param name="appVersion">
+    /// [EN] Version Number<br/>
+    /// [ZH] 版本号
+    /// </param>
+    public static void SetAppVersion(string appVersion)
+    {
+        DebugLog(null, "Set app version: " + appVersion);
+
+        UQMCrash.SetAppVersion(appVersion);
+    }
+
+    /// <summary>
+    /// [EN] Sets the reporting domain name<br/>
+    /// [ZH] 设置上报域名
+    /// </summary>
+    /// <remarks>
+    /// [EN] Need to be called before <see cref="InitWithAppId"/> interface<br/>
+    /// [ZH] 需要在 <see cref="InitWithAppId"/> 接口之前调用
+    /// </remarks>
+    /// <param name="crashServerUrl">
+    /// [EN] Target domain name of reporting<br/>
+    /// [ZH] 要上报的域名
+    /// </param>
+    public static void ConfigCrashServerUrl(string crashServerUrl)
+    {
+        DebugLog(null, "Config crashServerUrl:" + crashServerUrl);
+        UQMCrash.ConfigCrashServerUrl(crashServerUrl);
+    }
+
+    /// <summary>
+    /// [EN] Sets upload path for log after crash<br/>
+    /// [ZH] 设置崩溃后上传的日志路径
+    /// </summary>
+    /// <remarks>
+    /// [EN] Read permission is required. On Android and iOS, this interface has a lower priority than <see cref="RegisterCrashLogCallback"/>. 
+    ///      It is not available on Switch.<br/>
+    /// [ZH] 需要可读权限,在Android和iOS端上,该接口的优先级低于 <see cref="RegisterCrashLogCallback"/> , Switch暂不可用<br/>
+    /// </remarks>
+    /// <param name="logPath">
+    /// [EN] Absolute path for log files<br/>
+    /// [ZH] 日志绝对路径
+    /// </param>
+    public static void SetLogPath(string logPath)
+    {
+        UQMCrash.SetLogPath(logPath);
+    }
+
+    /// <summary>
+    /// [EN] Sets debug mode<br/>
+    /// [ZH] 设置debug模式
+    /// </summary>
+    /// <remarks>
+    /// [EN] Disabled by default. Need to be called before <see cref="InitWithAppId"/> interface. 
+    ///      When enabled, more logs will be printed to facilitate problem location.<br/>
+    /// [ZH] 默认关闭, 需要在 <see cref="InitWithAppId"/> 接口之前调用,开启后会打印更多便于问题定位的Log
+    /// </remarks>
+    /// <param name="enable"></param>
+    public static void ConfigDebugMode(bool enable)
+    {
+        _debugMode = enable;
+        UQMCrash.ConfigDebugMode(enable);
+        DebugLog(null, (enable ? "Enable" : "Disable") + " the log message print to console");
+    }
+
+    /// <summary>
+    /// [EN] Sets device id<br/>
+    /// [ZH] 设置设备Id
+    /// </summary>
+    /// <remarks>
+    /// [EN] By default, uuid is used as the device ID. Need to be called before <see cref="InitWithAppId"/> interface.<br/>
+    /// [ZH] 默认采用uuid作为设备ID, 需要在 <see cref="InitWithAppId"/> 接口之前调用
+    /// </remarks>
+    /// <param name="deviceId">
+    /// [EN] Device ID<br/>
+    /// [ZH] 设备唯一标识
+    /// </param>
+    public static void SetDeviceId(string deviceId)
+    {
+        UQMCrash.SetDeviceId(deviceId);
+    }
+
+    /// <summary>
+    /// [EN] Sets custom log reporting level<br/>
+    /// [ZH] 设置自定义日志上报级别
+    /// </summary>
+    /// <remarks>
+    /// [EN] Need to be called before <see cref="InitWithAppId"/> interface.<br/>
+    /// [ZH] 需要在 <see cref="InitWithAppId"/> 接口之前调用
+    /// </remarks>
+    /// <param name="logLevel">
+    /// [EN] Off=0, Error=1, Warn=2, Info=3, Debug=4, default is Info<br/>
+    /// [ZH] Off=0, Error=1, Warn=2, Info=3, Debug=4, 默认Info
+    /// </param>
+    public static void ConfigCrashReporter(int logLevel)
+    {
+        UQMCrash.ConfigAutoReportLogLevel(logLevel);
+    }
+
+    /// <summary>
+    /// [EN] Sets custom log reporting level<br/>
+    /// [ZH] 设置自定义日志上报级别
+    /// </summary>
+    /// <remarks>
+    /// [EN] Need to be called before <see cref="InitWithAppId"/> interface.<br/>
+    /// [ZH] 需要在 <see cref="InitWithAppId"/> 接口之前调用
+    /// </remarks>
+    /// <param name="logLevel">
+    /// [EN] Off=0, Error=1, Warn=2, Info=3, Debug=4, default is Info, <see cref="CSLogSeverity"/><br/>
+    /// [ZH] Off=0, Error=1, Warn=2, Info=3, Debug=4, 默认Info, <see cref="CSLogSeverity"/>
+    /// </param>
+    public static void ConfigCrashReporter(CSLogSeverity logLevel)
+    {
+        UQMCrash.ConfigAutoReportLogLevel((int)logLevel);
+    }
+
+    /// <summary>
+    /// [EN] Adds custom logs<br/>
+    /// [ZH] 添加自定义日志
+    /// </summary>
+    /// <remarks>
+    /// [EN] The custom log shouldn't exceed 30KB. Custom log view: <br/>
+    ///      Android, iOS, PS4, PS5, Switch: issue details->tracking log->custom log <br/>
+    ///      Windows, Xbox, Linux: issue details -> custom log (from interface)<br/>
+    /// [ZH] 自定义日志,限制30KB。 自定义日志查看:<br/>
+    ///      Android、iOS、PS4、PS5、Switch:问题详情->跟踪日志->custom log <br/>
+    ///      Windows、Xbox、Linux:问题详情->自定义日志(来自接口)
+    /// </remarks>
+    /// <param name="level">
+    /// [EN] Log level, <see cref="CSLogSeverity"/><br/>
+    /// [ZH] 日志级别 <see cref="CSLogSeverity"/>
+    /// </param>
+    /// <param name="format">
+    /// [EN] Log format<br/>
+    /// [ZH] 日志格式
+    /// </param>
+    /// <param name="args">
+    /// [EN] Variable parameter array<br/>
+    /// [ZH] 可变参数数组
+    /// </param>
+    public static void PrintLog(CSLogSeverity level, string format, params object[] args)
+    {
+        if (string.IsNullOrEmpty(format))
+        {
+            return;
+        }
+        if (args == null || args.Length == 0)
+        {
+            UQMCrash.LogRecord((int)level, format);
+        }
+        else
+        {
+            UQMCrash.LogRecord((int)level, string.Format(format, args));
+        }
+    }
+
+    /// <summary>
+    /// [EN] Tests native crash<br/>
+    /// [ZH] 测试 native 崩溃
+    /// </summary>
+    public static void TestNativeCrash()
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+        DebugLog(null, "test native crash");
+
+        UQMCrash.TestNativeCrash();
+    }
+
+    /// <summary>
+    /// [EN] Sets the distribution channel<br/>
+    /// [ZH] 设置发行渠道
+    /// </summary>
+    /// <remarks>
+    /// [EN] Each network connection or report can carry this field to collect statistics for different distribution channels.
+    ///      It is not available on PS4、PS5、Switch and Linux.<br/>
+    /// [ZH] 每一个联网或者上报都可以携带该字段,可实现针对不同的发行渠道统计数据。 PS4、PS5、Switch、Linux暂不可用
+    /// </remarks>
+    /// <param name="serverEnv"></param>
+    public static void SetEnvironmentName(string serverEnv)
+    {
+        UQMCrash.SetServerEnv(serverEnv);
+    }
+
+    /// <summary>
+    /// [EN] Enables Unity ANR monitoring<br/>
+    /// [ZH] 启用 Unity ANR 监控
+    /// </summary>
+    /// <remarks>
+    /// [EN] Here ANR means that the Unity main thread is unresponsive, which is different from Android ANR<br/>
+    /// [ZH] 此处ANR是指Unity主线程无响应,区别于Android ANR
+    /// </remarks>
+    /// <param name="timeoutMs">
+    /// [EN] Timeout in milliseconds to trigger ANR report when main thread is unresponsive<br/>
+    /// [ZH] 主线程无响应多少毫秒触发上报
+    /// </param>
+    public static void EnableAnrMonitor(int timeoutMs = 5000)
+    {
+        CrashSightAnrMonitor.Start(timeoutMs);
+    }
+
+    /// <summary>
+    /// [EN] Disables Unity ANR monitoring<br/>
+    /// [ZH] 停用 Unity ANR 监控
+    /// </summary>
+    public static void DisableAnrMonitor()
+    {
+        CrashSightAnrMonitor.Stop();
+    }
+
+    /// <summary>
+    /// [EN] Registers crash callback<br/>
+    /// [ZH] 注册崩溃回调
+    /// </summary>
+    /// <remarks>
+    /// [EN] Callback is called when a crash occurs and the return value will be included in the crash report.<br/>
+    ///      Create a custom class inheriting from CrashSightCallback and implement OnCrashBaseRetEvent method.<br/>
+    ///      Not available on PS4, PS5, Switch, Linux and HarmonyOS.<br/>
+    /// [ZH] 回调在崩溃时调用,返回值随崩溃信息一起上报<br/>
+    ///      自定义CsCrashCallBack类,继承 CrashSightCallback,实现 OnCrashBaseRetEvent方法<br/>
+    ///      PS4、PS5、Switch、Linux、鸿蒙暂不可用<br/>
+    /// </remarks>
+    /// <example>
+    /// <code>
+    /// public class CsCrashCallBack: CrashSightCallback  {
+    ///     //Put you own code to implemente the callback func
+    ///     public override string OnCrashBaseRetEvent(int methodId)
+    ///     {
+    ///         if (methodId == (int)UQMMethodNameID.UQM_CRASH_CALLBACK_EXTRA_MESSAGE)
+    ///         {
+    ///             // For Android/iOS: return extra message
+    ///             return "this is extra message.";
+    ///         }
+    ///         else if (methodId == (int)UQMMethodNameID.UQM_CRASH_CALLBACK_NO_RET)
+    ///         {
+    ///             // For Win/Xbox: return value is ignored but you can perform operations here
+    ///         }
+    ///         return "";
+    ///     }
+    /// }
+    /// </code>
+    /// </example>
+    /// <param name="callback">
+    /// [EN] Callback instance that inherits from CrashSightCallback<br/>
+    /// [ZH] 继承自 CrashSightCallback 的回调实例
+    /// </param>
+    public static void RegisterCrashCallback(CrashSightCallback callback)
+    {
+        if (callback != null)
+        {
+            UQMCrash.CrashBaseRetEvent += callback.OnCrashBaseRetEvent;
+            UQMCrash.ConfigCallBack();
+        }
+        else
+        {
+            DebugLog(null, "RegisterCallback failed: callback is null.");
+        }
+    }
+
+    /// <summary>
+    /// [EN] Unregisters the crash callback<br/>
+    /// [ZH] 注销崩溃回调
+    /// </summary>
+    public static void UnregisterCrashCallback()
+    {
+        UQMCrash.UnregisterCallBack();
+    }
+
+    /// <summary>
+    /// [EN] Registers crash log upload callback<br/>
+    /// [ZH] 注册上传日志回调
+    /// </summary>
+    /// <remarks>
+    /// [EN] Called after handling a crash.<br/>
+    ///      Customize the CsCrashLogCallback class, inherit CrashSightLogCallback, and use OnSetLogPathEvent and OnLogUploadResultEvent methods.<br/>
+    /// [ZH] 崩溃处理后调用,自定义CsCrashLogCallback类,继承CrashSightLogCallback,实现OnSetLogPathEvent、OnLogUploadResultEvent方法
+    /// </remarks>
+    /// <example>
+    /// <code>
+    /// public class CsCrashLogCallBack : CrashSightLogCallback
+    /// {
+    ///     // Returns absolute path of log file to upload
+    ///     // methodId: Method ID (can be ignored)
+    ///     // crashType: Crash type (0: Java/OC crash, 2: Native crash)
+    ///     public override string OnSetLogPathEvent(int methodId, int crashType)
+    ///     {
+    ///         return "";
+    ///     }
+    /// 
+    ///     // Notifies log upload result
+    ///     // methodId: Method ID (can be ignored)
+    ///     // crashType: Crash type (0: Java/OC crash, 2: Native crash)
+    ///     // result: Upload result (0: success, others: failure)
+    ///     public override void OnLogUploadResultEvent(int methodId, int crashType, int result)
+    ///     {
+    /// 
+    ///     }
+    /// }
+    /// </code>
+    /// </example>
+    /// <param name="callback">
+    /// [EN] Callback instance that inherits from CrashSightLogCallback<br/>
+    /// [ZH] 继承自CrashSightLogCallback的回调实例
+    /// </param>
+    public static void RegisterCrashLogCallback(CrashSightLogCallback callback)
+    {
+        if (callback != null)
+        {
+            UQMCrash.CrashSetLogPathRetEvent += callback.OnSetLogPathEvent;
+            UQMCrash.CrashLogUploadRetEvent += callback.OnLogUploadResultEvent;
+            UQMCrash.ConfigLogCallBack();
+        }
+        else
+        {
+            DebugLog(null, "RegisterCallback failed: callback is null.");
+        }
+    }
+
+    /// <summary>
+    /// [EN] Report Unity Log Error<br/>
+    /// [ZH] 上报Unity Log Error
+    /// </summary>
+    /// <remarks>
+    /// [EN] Enables automatic reporting of Unity log errors to CrashSight.<br/>
+    ///      The triggering frequency of Unity Log Error in the project should be kept low after enabling the feature.<br/>
+    /// [ZH] 调用该接口可以将Unity Log Error作为错误上报到CrashSight<br/>
+    ///      开启该功能后请尽量控制项目中Unity Log Error的触发频率
+    /// </remarks>
+    public static void EnableExceptionHandler()
+    {
+        if (IsInitialized)
+        {
+            DebugLog(null, "CrashSightAgent 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();
+    }
+
+    /// <summary>
+    /// [EN] Registers log callback<br/>
+    /// [ZH] 注册日志回调
+    /// </summary>
+    /// <param name="handler">
+    /// [EN] Log callback delegate<br/>
+    /// [ZH] 日志回调委托
+    /// </param>
+    public static void RegisterLogCallback(LogCallbackDelegate handler)
+    {
+        if (handler != null)
+        {
+            DebugLog(null, "Add log callback handler: " + handler);
+
+            _LogCallbackEventHandler += handler;
+        }
+    }
+
+    /// <summary>
+    /// [EN] Unregisters log callback<br/>
+    /// [ZH] 注销日志回调
+    /// </summary>
+    /// <param name="handler">
+    /// [EN] Log callback delegate to unregister<br/>
+    /// [ZH] 要注销的日志回调委托
+    /// </param>
+    public static void UnregisterLogCallback(LogCallbackDelegate handler)
+    {
+        if (handler != null)
+        {
+            DebugLog(null, "Remove log callback handler");
+
+            _LogCallbackEventHandler -= handler;
+        }
+    }
+
+    /// <summary>
+    /// [EN] Sets the extra data handler for log callbacks<br/>
+    /// [ZH] 设置日志回调的额外数据处理函数
+    /// </summary>
+    /// <param name="handler">
+    /// [EN] Function that returns extra data dictionary<br/>
+    /// [ZH] 返回额外数据的函数
+    /// </param>
+    public static void SetLogCallbackExtrasHandler(Func<Dictionary<string, string>> handler)
+    {
+        if (handler != null)
+        {
+            _LogCallbackExtrasHandler = handler;
+
+            DebugLog(null, "Add log callback extra data handler : " + handler);
+        }
+    }
+
+    /// <summary>
+    /// [EN] Configures whether to automatically quit the application after crash reporting<br/>
+    /// [ZH] 配置崩溃上报后是否自动退出应用
+    /// </summary>
+    /// <param name="autoQuit">
+    /// [EN] Whether to auto quit<br/>
+    /// [ZH] 是否自动退出
+    /// </param>
+    public static void ConfigAutoQuitApplication(bool autoQuit)
+    {
+        _autoQuitApplicationAfterReport = autoQuit;
+    }
+
+    /// <summary>
+    /// [EN] Gets whether the application will auto quit after crash reporting<br/>
+    /// [ZH] 获取崩溃上报后是否自动退出应用的配置
+    /// </summary>
+    /// <returns>
+    /// [EN] Current auto quit configuration<br/>
+    /// [ZH] 当前自动退出配置
+    /// </returns>
+    public static bool AutoQuitApplicationAfterReport
+    {
+        get { return _autoQuitApplicationAfterReport; }
+    }
+
+    /// <summary>
+    /// [EN] Outputs debug log messages<br/>
+    /// [ZH] 调试日志输出
+    /// </summary>
+    /// <remarks>
+    /// [EN] Only works when debugMode is enabled.<br/>
+    /// [ZH] 仅当debugMode为true时有效
+    /// </remarks>
+    /// <param name="tag">
+    /// [EN] Log tag
+    /// [ZH] 日志标签</param>
+    /// <param name="format">
+    /// [EN] Format string with placeholders<br/>
+    /// [ZH] 带占位符的格式化字符串
+    /// </param>
+    public static void DebugLog(string tag, string format)
+    {
+        if (!_debugMode)
+        {
+            return;
+        }
+
+        if (string.IsNullOrEmpty(format))
+        {
+            return;
+        }
+
+        UQMLog.Log(string.Format("{0}:{1}", tag, format));
+    }
+
+    /// <summary>
+    /// [EN] Checks if CrashSight has been initialized<br/>
+    /// [ZH] 获取CrashSight是否已初始化
+    /// </summary>
+    /// <returns>
+    /// [EN] Initialization status<br/>
+    /// [ZH] 初始化状态
+    /// </returns>
+    public static bool IsInitialized
+    {
+        get { return _isInitialized; }
+    }
+
+    /// <summary>
+    /// [EN] Registers exception handler callbacks<br/>
+    /// [ZH] 注册异常处理回调
+    /// </summary>
+    public static void _RegisterExceptionHandler()
+    {
+        try
+        {
+            // hold only one instance
+
+#if UNITY_5 || UNITY_5_3_OR_NEWER
+            Application.logMessageReceived += _OnLogCallbackHandlerMain;
+            Application.logMessageReceivedThreaded += _OnLogCallbackHandlerThreaded;
+#else
+            Application.RegisterLogCallback(_OnLogCallbackHandlerMain);
+            Application.RegisterLogCallbackThreaded(_OnLogCallbackHandlerThreaded);
+#endif
+            AppDomain.CurrentDomain.UnhandledException += _OnUncaughtExceptionHandler;
+
+            string version = Application.unityVersion;
+#if UNITY_EDITOR
+            string buildConfig = "editor";
+#elif DEVELOPMENT_BUILD
+            string buildConfig = "development";
+#else
+            string buildConfig = "release";
+#endif
+            SystemLanguage language = Application.systemLanguage;
+            CultureInfo locale = CultureInfo.CurrentCulture;
+            UQMCrash.SetEngineInfo(version, buildConfig, language.ToString(), locale.ToString());
+
+            _isInitialized = true;
+
+            DebugLog(null, "Register the log callback in Unity " + Application.unityVersion);
+        }
+        catch
+        {
+
+        }
+    }
+
+    /// <summary>
+    /// [EN] Unregisters exception handler callbacks<br/>
+    /// [ZH] 注销异常处理回调
+    /// </summary>
+    public static void _UnregisterExceptionHandler()
+    {
+        try
+        {
+#if UNITY_5 || UNITY_5_3_OR_NEWER
+            Application.logMessageReceived -= _OnLogCallbackHandlerMain;
+            Application.logMessageReceivedThreaded -= _OnLogCallbackHandlerThreaded;
+#else
+            Application.RegisterLogCallback(null);
+            Application.RegisterLogCallbackThreaded(null);
+#endif
+            System.AppDomain.CurrentDomain.UnhandledException -= _OnUncaughtExceptionHandler;
+            DebugLog(null, "Unregister the log callback in unity " + Application.unityVersion);
+        }
+        catch
+        {
+
+        }
+    }
+
+    /// <summary>
+    /// [EN] Enables/disables CrashSight stack trace collection<br/>
+    /// [ZH] 设置是否启用CrashSight堆栈跟踪
+    /// </summary>
+    /// <param name="enable"></param>
+    public static void SetCrashSightStackTraceEnable(bool enable)
+    {
+        CrashSightStackTrace.setEnable(enable);
+    }
+
+    /************************************Android、iOS、Mac端接口************************************/
+
+    /// <summary>
+    /// [EN] Configures callback types for reports (Android, iOS, Mac)<br/>
+    /// [ZH] 设置各类上报的回调开关(Android、iOS、Mac)
+    /// </summary>
+    /// <param name="callbackType">
+    /// [EN] There are currently 5 types of callback represented by 5 digits. The first digit represents crash, the second digit represents anr,
+    ///      the third digit represents u3d c# error, the fourth digit represents js, and the fifth digit represents lua<br/>
+    /// [ZH] 目前是5种类型,用5位表示。第一位表示crash,第二位表示anr,第三位表示u3d c# error第四位表示js,第五位表示lua。默认全开
+    /// </param>
+    public static void ConfigCallbackType(Int32 callbackType)
+    {
+        UQMCrash.ConfigCallbackType(callbackType);
+    }
+
+    /// <summary>
+    /// [EN] Sets device model (Android, iOS, Mac)<br/> 
+    /// [ZH] 设置设备型号(Android、iOS、Mac)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Need to be called before <see cref="InitWithAppId"/> interface.<br/>
+    /// [ZH] 需要在 <see cref="InitWithAppId"/> 接口之前调用
+    /// </remarks>
+    /// <param name="deviceModel">
+    /// [EN] Device model name<br/>
+    /// [ZH] 手机型号
+    /// </param>
+    public static void SetDeviceModel(string deviceModel)
+    {
+        UQMCrash.SetDeviceModel(deviceModel);
+    }
+
+    /// <summary>
+    /// [EN] Reports lightweight log (Android, iOS, Mac)<br/> 
+    /// [ZH] 上报轻量级日志(Android、iOS、Mac)
+    /// </summary>
+    /// <param name="msgType">
+    /// [EN] Message type<br/>
+    /// [ZH] 消息类型
+    /// </param>
+    /// <param name="msg">
+    /// [EN] Message content<br/> 
+    /// [ZH] 消息内容
+    /// </param>
+    public static void ReportLogInfo(string msgType, string msg)
+    {
+        UQMCrash.ReportLogInfo(msgType, msg);
+    }
+
+    /// <summary>
+    /// [EN] Sets the scene field name(Android、iOS、Mac)<br/>
+    /// [ZH] 设置场景字段(Android、iOS、Mac)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Each network connection or report can carry this field to calculate crash rates and other data for different scenes.
+    ///      It is not available on PS4、PS5、Switch and Linux.<br/>
+    /// [ZH] 每一个联网或者上报都可以携带该字段,实现针对不同的子场景计算崩溃率等数据。 PS4、PS5、Switch、Linux暂不可用
+    /// </remarks>
+    /// <param name="sceneId"></param>
+    /// <param name="upload">
+    /// [EN] Whether to report the change of scene<br/>
+    /// [ZH] 是否上报场景变更
+    /// </param>
+    public static void SetScene(string sceneId, bool upload = false)
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+        DebugLog(null, "Set scene: " + sceneId + ", upload:" + upload);
+
+        UQMCrash.SetScene(sceneId, upload);
+    }
+
+    /// <summary>
+    /// [EN] Sets the scene field name(Android、iOS、Mac)<br/>
+    /// [ZH] 设置场景字段(Android、iOS、Mac)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Each network connection or report can carry this field to calculate crash rates and other data for different scenes.
+    ///      It is not available on PS4、PS5、Switch and Linux.<br/>
+    /// [ZH] 每一个联网或者上报都可以携带该字段,实现针对不同的子场景计算崩溃率等数据。 PS4、PS5、Switch、Linux暂不可用
+    /// </remarks>
+    /// <param name="sceneId"></param>
+    /// <param name="upload">
+    /// [EN] Whether to report the change of scene<br/>
+    /// [ZH] 是否上报场景变更
+    /// </param>
+    public static void SetScene(int sceneId, bool upload = false)
+    {
+        SetScene(sceneId.ToString(), upload);
+    }
+
+    /// <summary>
+    /// [EN] Gets crash thread ID (Android, iOS, Mac)<br/>
+    /// [ZH] 获取崩溃线程ID(Android、iOS、Mac)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Can be called in callback<br/> 
+    /// [ZH] 可在回调中调用
+    /// </remarks>
+    /// <returns>
+    /// [EN] Crash thread ID, returns -1 on failure<br/> 
+    /// [ZH] 崩溃线程ID,失败时返回-1
+    /// </returns>
+    public static long GetCrashThreadId()
+    {
+        if (!IsInitialized)
+        {
+            return -1;
+        }
+        DebugLog(null, "GetCrashThreadId");
+
+        return UQMCrash.GetCrashThreadId();
+    }
+
+    /// <summary>
+    /// [EN] Sets customized device ID (Android, iOS, Mac)<br/>
+    /// 设置自定义device ID(Android、iOS、Mac)
+    /// </summary>
+    /// <param name="deviceId">
+    /// [EN] Custom device id<br/>
+    /// [ZH] 自定义device ID
+    /// </param>
+    public static void SetCustomizedDeviceID(string deviceId)
+    {
+        UQMCrash.SetCustomizedDeviceID(deviceId);
+    }
+
+    /// <summary>
+    /// [EN] Gets SDK generated device ID (Android, iOS, Mac)<br/>
+    /// [ZH] 获取SDK生成的device ID(Android、iOS、Mac)
+    /// </summary>
+    /// <returns>
+    /// [EN] SDK generated device ID<br/>
+    /// [ZH] SDK生成的device ID
+    /// </returns>
+    public static string GetSDKDefinedDeviceID()
+    {
+        return UQMCrash.GetSDKDefinedDeviceID();
+    }
+
+    /// <summary>
+    /// [EN] Sets customized match ID (Android, iOS, Mac)<br/>
+    /// [ZH] 设置自定义 match ID(Android、iOS、Mac)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Match ID can be used to search crashes and errors in "Advanced Search"<br/>
+    /// [ZH] match id可用于在"高级搜索"中查找崩溃和错误
+    /// </remarks>
+    /// <param name="matchId">match ID</param>
+    public static void SetCustomizedMatchID(string matchId)
+    {
+        UQMCrash.SetCustomizedMatchID(matchId);
+    }
+
+    /// <summary>
+    /// [EN] Gets SDK generated session ID (Android, iOS, Mac)<br/>
+    /// [ZH] 获取SDK生成的session ID(Android、iOS、Mac)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Session ID uniquely marks a launch session, typically used in callbacks to determine if it's the same launch.<br/>
+    /// [ZH] session ID用于唯一标记一次启动,一般用于在回调中确定是否为同一次启动。
+    /// </remarks>
+    /// <returns>
+    /// [EN] SDK generated session ID<br/>
+    /// [ZH] SDK生成的session ID
+    /// </returns>
+    public static string GetSDKSessionID()
+    {
+        return UQMCrash.GetSDKSessionID();
+    }
+
+    /// <summary>
+    /// [EN] Triggers test OOM crash (Android, iOS, Mac)<br/>
+    /// [ZH] 测试OOM崩溃(Android、iOS、Mac)
+    /// </summary>
+    public static void TestOomCrash()
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+        DebugLog(null, "test oom crash");
+
+        UQMCrash.TestOomCrash();
+    }
+
+    /// <summary>
+    /// [EN] Triggers test Java crash (Android)<br/>
+    /// [ZH] 测试java崩溃(Android)
+    /// </summary>
+    public static void TestJavaCrash()
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+        DebugLog(null, "test java crash");
+
+        UQMCrash.TestJavaCrash();
+    }
+
+    /// <summary>
+    /// [EN] Triggers test ANR (Android only)<br/>
+    /// [ZH] 测试ANR(仅Android)
+    /// </summary>
+    public static void TestANR()
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+        DebugLog(null, "test ANR");
+
+        UQMCrash.TestANR();
+    }
+
+    /// <summary>
+    /// [EN] Gets crash UUID<br/>
+    /// [ZH] 获取崩溃UUID
+    /// </summary>
+    /// <remarks>
+    /// [EN] This UUID is used to uniquely identify a report and is generally used in callbacks.<br/>
+    /// [ZH] 该UUID用于唯一标识一次上报,一般在回调中使用
+    /// </remarks>
+    /// <returns></returns>
+    public static string GetCrashUuid()
+    {
+        return UQMCrash.GetCrashUuid();
+    }
+
+    /// <summary>
+    /// [EN] Sets the logcat buffer size(Android)<br/>
+    /// [ZH] 设置logcat缓存大小(Android)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Default is 10KB in non-debug mode, 128KB in debug mode<br/>
+    /// [ZH] 默认非debug模式下10KB,debug模式下128KB
+    /// </remarks>  
+    /// <param name="size">
+    /// [EN] Buffer size in KB<br/>
+    /// [ZH] logcat缓存大小(单位:KB)
+    /// </param>
+    public static void SetLogcatBufferSize(int size)
+    {
+        UQMCrash.SetLogcatBufferSize(size);
+    }
+
+    /// <summary>
+    /// [EN] Tests Objective-C crash (iOS, Mac)<br/>
+    /// [ZH] 测试Objective-C崩溃(iOS、Mac)
+    /// </summary>
+    public static void TestOcCrash()
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+        DebugLog(null, "test oc crash");
+
+        UQMCrash.TestOcCrash();
+    }
+
+    /// <summary>
+    /// [EN] Starts scheduled dump routine<br/>
+    /// [ZH] 启动定时dump任务
+    /// </summary>
+    /// <remarks>
+    /// [EN] Starts a thread to periodically capture and report dumps.
+    ///      Performance overhead depends on dump interval and count settings.
+    ///      Mainly for testing purposes. Disable before release.<br/>
+    /// [ZH] 启动一个线程定时获取dump并上报。根据dump间隔和次数会产生性能开销。一般用于测试,正式发布前请关闭。
+    /// </remarks>
+    /// <param name="dumpMode">
+    /// [EN] 0: close, 1: call system interface dump, 3: minidump (only valid for mobile)<br/>
+    /// [ZH] 0:关闭,1:调用系统接口dump,3:minidump(仅移动端有效)
+    /// </param>
+    /// <param name="startTimeMode">
+    /// [EN] Start time mode: 0=absolute time, 1=relative time (ms)<br/>
+    /// [ZH] 启动时间模式:0=绝对时间,1=相对时间(毫秒)
+    /// </param>
+    /// <param name="startTime">
+    /// [EN] Start time<br/>
+    /// [ZH] 启动时间
+    /// </param>
+    /// <param name="dumpInterval">
+    /// [EN] Dump interval in milliseconds<br/>
+    /// [ZH] dump间隔(毫秒)
+    /// </param>
+    /// <param name="dumpTimes">
+    /// [EN] Number of dumps to perform<br/>
+    /// [ZH] dump执行次数
+    /// </param>
+    /// <param name="saveLocal">
+    /// [EN] Whether to save dump locally<br/>
+    /// [ZH] 是否本地保存dump
+    /// </param>
+    /// <param name="savePath">
+    /// [EN] Local save path for dumps<br/>
+    /// [ZH] dump本地保存路径
+    /// </param>
+    public static void StartDumpRoutine(int dumpMode, int startTimeMode, long startTime,
+                long dumpInterval, int dumpTimes, bool saveLocal, string savePath)
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+        UQMCrash.StartDumpRoutine(dumpMode, startTimeMode, startTime, dumpInterval, dumpTimes, saveLocal, savePath);
+    }
+
+    /// <summary>
+    /// [EN] Starts monitoring file descriptor count<br/>
+    /// [ZH] 监控FD数量
+    /// </summary>
+    /// <param name="interval">
+    /// [EN] Scan interval in milliseconds<br/>
+    /// [ZH] 扫描间隔,单位:毫秒
+    /// </param>
+    /// <param name="limit">FD数量限制<br/>
+    /// [EN] Maximum allowed FD count
+    /// [ZH] FD数量限制
+    /// </param>
+    /// <param name="dumpType">
+    /// [EN] 0: close, 1: call system interface dump, 3: minidump (only valid for mobile)<br/>
+    /// [ZH] 0:关闭,1:调用系统接口dump,3:minidump(仅移动端有效)
+    /// </param>
+    public static void StartMonitorFdCount(int interval, int limit, int dumpType)
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+        UQMCrash.StartMonitorFdCount(interval, limit, dumpType);
+    }
+
+    /// <summary>
+    /// [EN] Gets exception type code<br/>
+    /// [ZH] 获取异常类型编号
+    /// </summary>
+    /// <param name="name">
+    /// [EN] Exception type name (e.g. "c#", "js", "lua", "custom1")<br/>
+    /// [ZH] 异常类型名(如"c#","js","lua","custom1"等)
+    /// </param>
+    /// <returns>
+    /// [EN] Exception type code for ReportException<br/>
+    /// [ZH] 用于ReportException接口的异常类型编号
+    /// </returns>
+    public static int getExceptionType(string name)
+    {
+        if (!IsInitialized)
+        {
+            return 0;
+        }
+        return UQMCrash.getExceptionType(name);
+    }
+
+    /// <summary>
+    /// [EN] Tests use-after-free memory error (Android)<br/>
+    /// [ZH] 测试释放后使用内存错误(Android)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Only works when GWP-Asan or MTE is enabled<br/>
+    /// [ZH] 仅当GWP-Asan或MTE功能启用时有效
+    /// </remarks>
+    public static void TestUseAfterFree()
+    {
+        if (!IsInitialized)
+        {
+            return;
+        }
+        DebugLog(null, "test UseAfterFree");
+
+        UQMCrash.TestUseAfterFree();
+    }
+
+    /// <summary>
+    /// [EN] Restarts CrashSight monitoring (Android, iOS)<br/>
+    /// [ZH] 重启CrashSight监控(Android, iOS)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Used in native Android integration scenarios<br/>
+    /// [ZH] 用于Android原生接入场景
+    /// </remarks>
+    public static void ReRegistAllMonitors()
+    {
+        _isInitialized = true;
+        UQMCrash.ReRegistAllMonitors();
+        DebugLog(null, "ReRegistAllMonitors");
+    }
+
+    /// <summary>
+    /// [EN] Stops CrashSight monitoring (Android, iOS, Mac)<br/>
+    /// [ZH] 关闭CrashSight监控(Android, iOS, Mac)
+    /// </summary>
+    public static void CloseAllMonitors()
+    {
+        UQMCrash.CloseAllMonitors();
+        DebugLog(null, "CloseAllMonitors");
+    }
+
+    /// <summary>
+    /// [EN] Toggles getPackageInfo system API (Android)<br/>
+    /// [ZH] 设置getPackageInfo系统接口调用开关(Android)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Enabled by default, can be disabled if rejected by Google Play<br/>
+    /// [ZH] 默认开启,谷歌审核不通过时可关闭
+    /// </remarks>
+    /// <param name="enable"></param>
+    public static void setEnableGetPackageInfo(bool enable)
+    {
+        DebugLog(null, "setEnableGetPackageInfo: " + enable);
+
+        UQMCrash.setEnableGetPackageInfo(enable);
+    }
+
+    /// <summary>
+    /// [EN] Sets multi-thread signal handling switch (Android)<br/>
+    /// [ZH] 设置安卓多线程信号处理开关(仅Android)
+    /// </summary>
+    /// <param name="enable"></param>
+    public static void setCatchMultiSignal(bool enable)
+    {
+        DebugLog(null, "setCatchMultiSignal: " + enable);
+
+        UQMCrash.setCatchMultiSignal(enable);
+    }
+
+    /// <summary>
+    /// [EN] Sets Android Fragment Tracking, iOS Page Tracking Switch<br/>
+    /// [ZH] 设置安卓Fragment追踪、iOS页面追踪开关
+    /// </summary>
+    /// <param name="enable"></param>
+    public static void enableDetailedPageTracing(bool enable)
+    {
+        DebugLog(null, "enableDetailedPageTracing: " + enable);
+
+        UQMCrash.enableDetailedPageTracing(enable);
+    }
+
+    /// <summary>
+    /// [EN] Checks if last session crashed<br/>
+    /// [ZH] 判断上次启动会话是否发生崩溃
+    /// </summary>
+    /// <returns></returns>
+    public static bool IsLastSessionCrash()
+    {
+        if (!IsInitialized)
+        {
+            return false;
+        }
+        DebugLog(null, "IsLastSessionCrash");
+
+        return UQMCrash.IsLastSessionCrash();
+    }
+
+    /// <summary>
+    /// [EN] Gets user ID of last session<br/>
+    /// [ZH] 获取上次会话的用户ID
+    /// </summary>
+    /// <returns></returns>
+    public static string GetLastSessionUserId()
+    {
+        if (!IsInitialized)
+        {
+            return "";
+        }
+        DebugLog(null, "GetLastSessionUserId");
+
+        return UQMCrash.GetLastSessionUserId();
+    }
+
+    /// <summary>
+    /// [EN] Checks if file descriptor count exceeds limit<br/>
+    /// [ZH] 检查文件描述符(FD)数量是否超过限制
+    /// </summary>
+    /// <param name="limit">
+    /// [EN] Maximum FD count<br/>
+    /// [ZH] FD数量限制
+    /// </param>
+    /// <param name="dumpType">
+    /// [EN] 0: close, 1: call system interface dump, 3: minidump (only valid for mobile)<br/>
+    /// [ZH] 0:关闭,1:调用系统接口dump,3:minidump(仅移动端有效)
+    /// </param>
+    /// <param name="upload">
+    /// [EN] Whether to upload report<br/>
+    /// [ZH] 是否上报
+    /// </param>
+    /// <returns>
+    /// [EN] true if FD count exceeds limit, false otherwise<br/>
+    /// [ZH] FD数量超过限制返回true,否则返回false
+    /// </returns>
+    public static bool CheckFdCount(int limit, int dumpType, bool upload)
+    {
+        if (!IsInitialized)
+        {
+            return false;
+        }
+        return UQMCrash.CheckFdCount(limit, dumpType, upload);
+    }
+
+    /// <summary>
+    /// [EN] Sets OOM log path (Android, iOS)<br/>
+    /// [ZH] 设置OOM日志路径(Android、iOS)
+    /// </summary>
+    /// <param name="logPath">
+    /// [EN] Path for OOM logs<br/>
+    /// [ZH] OOM日志路径
+    /// </param>
+    public static void SetOomLogPath(string logPath)
+    {
+        UQMCrash.SetOomLogPath(logPath);
+    }
+
+    /// <summary>
+    /// [EN] Reports jank<br/>
+    /// [ZH] 上报卡顿事件
+    /// </summary>
+    /// <param name="type">
+    /// [EN] Jank type (reserved for future use)<br/>
+    /// [ZH] 卡顿类型(保留字段,暂未使用)
+    /// </param>
+    /// <param name="exceptionName">
+    /// [EN] Name of the jank exception<br/>
+    /// [ZH] 卡顿异常名称
+    /// </param>
+    /// <param name="exceptionMsg">
+    /// [EN] Description of the jank event<br/>
+    /// [ZH] 卡顿事件描述信息
+    /// </param>
+    /// <param name="exceptionStack">
+    /// [EN] Stack trace of jank<br/>
+    /// [ZH] 卡顿堆栈内容
+    /// </param>
+    /// <param name="paramsJson">
+    /// [EN] Additional information in JSON format<br/>
+    /// [ZH] 额外信息,JSON格式
+    /// </param>
+    /// <param name="reportInfoOption">
+    /// [EN] Collection options for jank reporting information, represented by 6 binary bits for different options, 0 indicating no collection of additional information.<br/>
+    ///      The 1st bit: Collect system logs, the 2nd bit: Collect custom logs, the 3rd bit: Collect user-defined key-value pairs, 
+    ///      the 4th bit: Trigger user callbacks, the 5th bit: Automatically dump stack traces, the 6th bit:Automatically collect full-thread Java stack.<br/>
+    /// [ZH] jank上报信息收集选项,用6位二进制位表示不同选项,0表示不收集任何额外信息<br/>
+    ///      第1位:收集系统日志,第2位:收集自定义日志,第3位:收集用户自定义键值对,第4位:触发用户回调,第5位:自动dump堆栈,第6位:自动采集全线程Java堆栈
+    /// </param>
+    /// <param name="jankAttachmentPath">
+    /// [EN] Path to attachment file for jank report<br/>
+    /// [ZH] 卡顿报告附件文件路径
+    /// </param>
+    public static void ReportJank(int type, string exceptionName,
+                                 string exceptionMsg, string exceptionStack,
+                                 string paramsJson, int reportInfoOption,
+                                 string jankAttachmentPath)
+    {
+        UQMCrash.ReportJank(type, exceptionName, exceptionMsg, exceptionStack, paramsJson, reportInfoOption, jankAttachmentPath);
+    }
+
+    public static void ReportStuck(int threadId, int maxChecks, long checkInterval,
+                                  string name, string message, Dictionary<string, string> extInfo,
+                                  int dumpNativeType, string attachPath)
+    {
+        UQMCrash.ReportStuck(threadId, maxChecks, checkInterval, name, message, extInfo, dumpNativeType, attachPath);
+    }
+
+    /************************************PC、Xbox端接口************************************/
+
+    /// <summary>
+    /// [EN] Sets VEH(Vectored Exception Handling) enable status (Win, Xbox)<br/>
+    /// [ZH] 设置VEH(向量化异常处理)捕获开关(Win、Xbox)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Enabled by default. Recommended to disable for Unity projects to avoid false crash reports.<br/>
+    /// [ZH] 默认开启,建议所有Unity项目关闭此开关,否则可能产生crash误报。
+    /// </remarks>
+    /// <param name="enable"></param>
+    public static void SetVehEnable(bool enable)
+    {
+        UQMCrash.SetVehEnable(enable);
+        DebugLog(null, "SetVehEnable");
+    }
+
+    /// <summary>
+    /// [EN] Manually reports a crash (Win, Xbox)<br/>
+    /// [ZH] 主动上报崩溃信息(Win、Xbox)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Reports a crash manually. Normally not needed, use only when necessary.<br/>
+    /// [ZH] 主动上报一条崩溃信息,一般没有使用场景,可根据项目需要酌情使用。
+    /// </remarks>
+    public static void ReportCrash()
+    {
+        UQMCrash.ReportCrash();
+        DebugLog(null, "ReportCrash");
+    }
+
+    /// <summary>
+    /// [EN] Manually reports dump file(Win, Xbox)<br/>
+    /// [ZH] 主动上报dump文件(Win、Xbox)
+    /// </summary>
+    /// <param name="dump_path">
+    /// [EN] Directory containing dump files<br/>
+    /// [ZH] dump文件所在目录
+    /// </param>
+    /// <param name="is_async">
+    /// [EN] Whether to report asynchronously<br/>
+    /// [ZH] 是否异步上报
+    /// </param>
+    public static void ReportDump(string dump_path, bool is_async)
+    {
+        UQMCrash.ReportDump(dump_path, is_async);
+        DebugLog(null, "ReportDump");
+    }
+
+    /// <summary>
+    /// [EN] Sets extra exception handler (Win, Xbox)<br/>
+    /// [ZH] 设置额外异常捕获开关(Win、Xbox)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Disabled by default for backward compatibility.<br/>
+    ///      When enabled, can catch illegal parameter crashes from security functions like strcpy_s,
+    ///      and purecall errors from virtual function calls.<br/>
+    /// [ZH] 默认为关闭,与旧版保持一致。<br/>
+    ///      开启后,可以捕获上报strcpy_s一类的安全函数抛出的非法参数崩溃,以及虚函数调用purecall错误导致的崩溃。
+    /// </remarks>
+    /// <param name="extra_handle_enable"></param>
+    public static void SetExtraHandler(bool extra_handle_enable)
+    {
+        UQMCrash.SetExtraHandler(extra_handle_enable);
+        DebugLog(null, "SetExtraHandler");
+    }
+
+    /// <summary>
+    /// [EN] Uploads dump files from specified path (Win, Xbox)<br/>
+    /// [ZH] 上传指定路径下的dump文件(Win、Xbox)
+    /// </summary>
+    /// <param name="dump_dir">
+    /// [EN] Directory containing dump files<br/>
+    /// [ZH] dump文件所在目录
+    /// </param>
+    /// <param name="is_extra_check">
+    /// [EN] Extra validation check, set to false by default<br/>
+    /// [ZH] 额外校验检查,默认填false即可
+    /// </param>
+    public static void UploadGivenPathDump(string dump_dir, bool is_extra_check)
+    {
+        UQMCrash.UploadGivenPathDump(dump_dir, is_extra_check);
+        DebugLog(null, "UploadGivenPathDump");
+    }
+
+    /// <summary>
+    /// [EN] Sets dump type (Win, Xbox)<br/>
+    /// [ZH] 设置dump类型(Win、Xbox)
+    /// </summary>
+    /// <param name="dump_type">
+    /// [EN] Dump type value: see Windows documentation for valid values.<br/>
+    /// [ZH] dump类型值,有效值请参考Windows官方文档
+    /// </param>
+    public static void SetDumpType(int dump_type)
+    {
+        UQMCrash.SetDumpType(dump_type);
+    }
+
+    /// <summary>
+    /// [EN] Adds valid exception code (Win, Xbox)<br/>
+    /// [ZH] 添加可用的异常类型(Win、Xbox)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Consult CrashSight developers before using<br/>
+    /// [ZH] 使用前请咨询CrashSight开发人员
+    /// </remarks>
+    /// <param name="exp_code">
+    /// [EN] Exception code: see Windows  documentation<br/>
+    /// [ZH] 异常代码: 参考Windows官方文档
+    /// </param>
+    public static void AddValidExpCode(ulong exp_code)
+    {
+        UQMCrash.AddValidExpCode(exp_code);
+    }
+
+    /// <summary>
+    /// [EN] Uploads crash with specified GUID (Win, Xbox)<br/>
+    /// [ZH] 上报指定GUID的错误(Win、Xbox)
+    /// </summary>
+    /// <param name="guid">
+    /// [EN] GUID identifying the specific issue, an be obtained through callback.<br/>
+    /// [ZH] 唯一问题的代码,可通过回调获取
+    /// </param>
+    public static void UploadCrashWithGuid(string guid)
+    {
+        UQMCrash.UploadCrashWithGuid(guid);
+    }
+
+    /// <summary>
+    /// [EN] Sets crash upload enable status (Win, Xbox)<br/>
+    /// [ZH] 设置崩溃上报开关(Win、Xbox)
+    /// </summary>
+    /// <param name="enable"></param>
+    public static void SetCrashUploadEnable(bool enable)
+    {
+        UQMCrash.SetCrashUploadEnable(enable);
+    }
+
+    /// <summary>
+    /// [EN] Sets workspace path (Win, Xbox)<br/>
+    /// [ZH] 设置工作空间路径(Win、Xbox)
+    /// </summary>
+    /// <param name="workspace">
+    /// [EN] Absolute path to workspace directory<br/>
+    /// [ZH] 工作空间的绝对路径
+    /// </param>
+    public static void SetWorkSpace(string workspace)
+    {
+        UQMCrash.SetWorkSpace(workspace);
+    }
+
+    /// <summary>
+    /// [EN] Sets custom attachment directory (Win, Xbox)<br/>
+    /// [ZH] 设置自定义附件目录(Win、Xbox)
+    /// </summary>
+    /// <param name="path">
+    /// [EN] Absolute path to attachment directory<br/>
+    /// [ZH] 附件的绝对路径
+    /// </param>
+    public static void SetCustomAttachDir(string path)
+    {
+        UQMCrash.SetCustomAttachDir(path);
+    }
+
+    /************************************PS4、PS5、Switch端接口************************************/
+
+    /// <summary>
+    /// [EN] Sets error report interval (PS4, PS5, Switch)<br/>
+    /// [ZH] 设置错误上报间隔(PS4、PS5、Switch)
+    /// </summary>
+    /// <param name="interval">
+    /// [EN] Report interval in seconds<br/>
+    /// [ZH] 错误上报间隔(单位:秒)
+    /// </param>
+    public static void SetErrorUploadInterval(int interval)
+    {
+        UQMCrash.SetErrorUploadInterval(interval);
+        DebugLog(null, "SetErrorUploadInterval");
+    }
+
+    /// <summary>
+    /// [EN] Enables/disables error reporting (PS4, PS5, Switch)<br/>
+    /// [ZH] 设置错误上报开关(PS4、PS5、Switch)
+    /// </summary>
+    /// <param name="enable"></param>
+    public static void SetErrorUploadEnable(bool enable)
+    {
+        UQMCrash.SetErrorUploadEnable(enable);
+        DebugLog(null, "SetErrorUploadEnable");
+    }
+
+    /************************************Linux端接口************************************/
+
+    /// <summary>
+    /// [EN] Sets directory for all record files (Linux)<br/>
+    /// [ZH] 设置所有记录文件的路径(Linux)
+    /// </summary>
+    /// <remarks>
+    /// [EN] Includes SDK logs and dump files, defaults to executable directory<br/>
+    /// [ZH] 包括SDK日志和dump文件,默认为当前可执行文件的目录下
+    /// </remarks>
+    /// <param name="record_dir">
+    /// [EN] Path to record files directory<br/>
+    /// [ZH] 记录文件的路径
+    /// </param>
+    public static void SetRecordFileDir(string record_dir)
+    {
+        UQMCrash.SetRecordFileDir(record_dir);
+        DebugLog(null, "SetRecordFileDir");
+    }
+
+    /************************************已废弃接口************************************/
+
+    /// <summary>
+    /// [EN] Initializes CrashSight (Windows/Xbox) - DEPRECATED, use <see cref="InitWithAppId"/> instead<br/>
+    /// [ZH] 初始化CrashSight(Windows/Xbox平台)- 已废弃,请使用 <see cref="InitWithAppId"/> 替代
+    /// </summary>
+    /// <param name="userId"></param>
+    /// <param name="version"></param>
+    /// <param name="key"></param>
+    [Obsolete("该接口已废弃,请使用 InitWithAppId 进行初始化")]
+    public static void InitContext(string userId, string version, string key)
+    {
+        if (IsInitialized)
+        {
+            DebugLog(null, "CrashSightAgent has already been initialized.");
+
+            return;
+        }
+
+        if (userId == null || string.IsNullOrEmpty(version) || string.IsNullOrEmpty(key))
+        {
+            return;
+        }
+
+        _isInitialized = true;
+        // init the sdk with app id
+        UQMCrash.InitContext(userId, version, key);
+        DebugLog(null, "Initialized with userId: " + userId +" version: " + version + " key: " + key);
+
+        // Register the LogCallbackHandler by Application.RegisterLogCallback(Application.LogCallback)
+        _RegisterExceptionHandler();
+    }
+
+    /// <summary>
+    /// [EN] Initializes CrashSight (Linux) - DEPRECATED, use <see cref="InitWithAppId"/> instead<br/>
+    /// [ZH] 初始化CrashSight(Linux平台)- 已废弃,请使用 <see cref="InitWithAppId"/> 替代
+    /// </summary>
+    /// <param name="app_id"></param>
+    /// <param name="app_key"></param>
+    /// <param name="app_version"></param>
+    [Obsolete("该接口已废弃,请使用 InitWithAppId 进行初始化")]
+    public static void Init(string app_id, string app_key, string app_version)
+    {
+        if (IsInitialized)
+        {
+            DebugLog(null, "CrashSightAgent has already been initialized.");
+
+            return;
+        }
+
+        if (string.IsNullOrEmpty(app_id) || string.IsNullOrEmpty(app_key) || string.IsNullOrEmpty(app_version))
+        {
+            return;
+        }
+
+        _isInitialized = true;
+        // init the sdk with app id
+        UQMCrash.Init(app_id, app_key, app_version);
+        DebugLog(null, "Initialized with app_id: " + app_id + " app_key: " + app_key + " app_version: " + app_version);
+
+        // Register the LogCallbackHandler by Application.RegisterLogCallback(Application.LogCallback)
+        _RegisterExceptionHandler();
+    }
+
+    /// <summary>
+    /// [EN] Configures default settings (Android/iOS/Switch) - DEPRECATED<br/>
+    /// [ZH] 配置默认设置(Android/iOS/Switch平台)- 已废弃
+    /// </summary>
+    /// <param name="channel"></param>
+    /// <param name="version"></param>
+    /// <param name="user"></param>
+    /// <param name="delay"></param>
+    [Obsolete("该接口已废弃")]
+    public static void ConfigDefault(string channel, string version, string user, long delay)
+    {
+        DebugLog(null, "Config default channel:" + channel + ", version:" + version + ", user:" + user + ", delay:" + delay);
+        UQMCrash.ConfigDefault(channel, version, user, delay);
+    }
+
+    #region Privated Fields and Methods
+    /************************************private部分************************************/
+
+    private static void _OnLogCallbackHandlerMain(string condition, string stackTrace, LogType type)
+    {
+        _OnLogCallbackHandler(condition, stackTrace, type, CSReportType.LogCallback);
+    }
+
+    private static void _OnLogCallbackHandlerThreaded(string condition, string stackTrace, LogType type)
+    {
+        _OnLogCallbackHandler(condition, stackTrace, type, CSReportType.LogCallbackThreaded);
+    }
+
+    private static void _OnLogCallbackHandler(string condition, string stackTrace, LogType type, CSReportType rType)
+    {
+        if (_LogCallbackEventHandler != null)
+        {
+            _LogCallbackEventHandler(condition, stackTrace, type);
+        }
+
+        if (!IsInitialized)
+        {
+            return;
+        }
+
+        if (!string.IsNullOrEmpty(condition) && condition.Contains("[CrashSightAgent] <Log>"))
+        {
+            return;
+        }
+
+        if (_uncaughtAutoReportOnce)
+        {
+            return;
+        }
+
+        if (callbackThreads.Contains(Thread.CurrentThread.ManagedThreadId))
+        {
+            return;
+        }
+
+        _HandleException(type, null, condition, stackTrace, true, rType);
+    }
+
+    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("CrashSightAgent: 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(512);
+
+        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 bool ShouldSkipFrame(string frame)
+    {
+        string[] skipPatterns = { "System.Collections.Generic.", "ShimEnumerator", "CrashSight" };
+
+        foreach (var pattern in skipPatterns)
+        {
+            if (frame.StartsWith(pattern, StringComparison.Ordinal))
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    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(512);
+
+                    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();
+
+                        if (string.IsNullOrEmpty(frame) || ShouldSkipFrame(frame) || frame.Contains("..ctor"))
+                        {
+                            continue;
+                        }
+
+                        int start = -1;
+                        int end = -1;
+                        if (frame.Contains("(at") && frame.Contains("/assets/"))
+                        {
+                            start = frame.IndexOf("(at", StringComparison.OrdinalIgnoreCase);
+                            end = frame.IndexOf("/assets/", StringComparison.OrdinalIgnoreCase);
+
+                        }
+                        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(CSLogSeverity.LogWarning, "{0}", "Error to parse the stack trace");
+            }
+
+        }
+
+//        PrintLog(CSLogSeverity.LogError, "ReportException: " + name + " " + reason + "\n*********\n" + stackTrace + "\n*********");
+
+        _uncaughtAutoReportOnce = uncaught && _autoQuitApplicationAfterReport;
+
+        string extraInfo = string.Empty;
+        Dictionary<string, string> extras = null;
+        if (_LogCallbackExtrasHandler != null)
+        {
+            extras = _LogCallbackExtrasHandler();
+        }
+
+        if (extras != null && extras.Count > 0)
+        {
+            StringBuilder builder = new StringBuilder(128);
+            foreach (KeyValuePair<string, string> kvp in extras)
+            {
+                builder.AppendFormat("\"{0}\" : \"{1}\", ", kvp.Key, kvp.Value);
+            }
+            builder.Length -= 2;  // 去掉最后一个逗号和空格
+            extraInfo = "{" + builder.ToString() + "}";
+        }
+        UQMCrash.ReportException(4, name, reason, stackTrace, extraInfo, uncaught && AutoQuitApplicationAfterReport);
+    }
+
+    private static int valueOf(LogType logLevel)
+    {
+        switch(logLevel)
+        {
+            case LogType.Exception:
+                return 1;
+            case LogType.Error:
+                return 2;
+            case LogType.Assert:
+                return 3;
+            case LogType.Warning:
+                return 4;
+            case LogType.Log:
+                return 5;
+            default:
+                return 6;
+        }
+    }
+
+    private static bool isEnableAutoReport(LogType logLevel)
+    {
+        return valueOf(logLevel) <= valueOf(_autoReportLogLevel);
+    }
+
+    private static void _HandleException(LogType logLevel, string name, string message, string stackTrace, bool uncaught, CSReportType rType)
+    {
+        if (!IsInitialized)
+        {
+            DebugLog(null, "It has not been initialized.");
+            return;
+        }
+
+        if ((uncaught && !isEnableAutoReport(logLevel)))
+        {
+            DebugLog(null, "Not report exception for level " + logLevel.ToString());
+            return;
+        }
+
+        string type = null;
+        string reason = "";
+
+        if (!string.IsNullOrEmpty(message))
+        {
+            try
+            {
+                if ((LogType.Exception == logLevel) && message.Contains("Exception"))
+                {
+
+                    Match match = new Regex(@"^(?<errorType>\S+):\s*(?<errorMessage>.*)", RegexOptions.Singleline).Match(message);
+
+                    if (match.Success)
+                    {
+                        if (stackTrace.Contains("UnityEngine.Debug:LogException"))
+                        {
+                            if (rType == CSReportType.LogCallback)
+                            {
+                                return;
+                            }
+                        }
+                        else
+                        {
+                            if (rType == CSReportType.LogCallbackThreaded)
+                            {
+                                return;
+                            }
+                        }
+                        type = match.Groups["errorType"].Value.Trim();
+                        reason = match.Groups["errorMessage"].Value.Trim();
+                    }
+                    else if (rType == CSReportType.LogCallback)
+                    {
+                        return;
+                    }
+                }
+                else if ((LogType.Error == logLevel) && message.StartsWith("Unhandled Exception:", StringComparison.Ordinal))
+                {
+
+                    Match match = new Regex(@"^Unhandled\s+Exception:\s*(?<exceptionName>\S+):\s*(?<exceptionDetail>.*)", RegexOptions.Singleline).Match(message);
+
+                    if (match.Success)
+                    {
+                        if (rType == CSReportType.LogCallbackThreaded)
+                        {
+                            return;
+                        }
+                        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 <filename unknown>:0", string.Empty).Replace("[0x00000]", string.Empty);
+                            //
+                            stackTrace = stackTrace + "\n" + 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 = stackTrace + "\n" + callStacks.Trim();
+                            }
+                        }
+                    }
+                    else if (rType == CSReportType.LogCallback)
+                    {
+                        return;
+                    }
+                }
+                else if (rType == CSReportType.LogCallback)
+                {
+                    return;
+                }
+            }
+            catch
+            {
+
+            }
+
+            if (string.IsNullOrEmpty(reason))
+            {
+                reason = message;
+            }
+        }
+
+        if (string.IsNullOrEmpty(name))
+        {
+            if (string.IsNullOrEmpty(type))
+            {
+                string sLogLevel = "Log";
+                switch (logLevel)
+                {
+                    case LogType.Log:
+                        sLogLevel = "Log";
+                        break;
+                    case LogType.Warning:
+                        sLogLevel = "LogWarning";
+                        break;
+                    case LogType.Assert:
+                        sLogLevel = "LogAssert";
+                        break;
+                    case LogType.Error:
+                        sLogLevel = "LogError";
+                        break;
+                    case LogType.Exception:
+                        sLogLevel = "LogException";
+                        break;
+                }
+                type = "Unity" + sLogLevel;
+                if (CrashSightStackTrace.enable)
+                {
+                    try
+                    {
+                        stackTrace = CrashSightStackTrace.ExtractStackTrace();
+                        //去掉前三行
+                        if (stackTrace.Contains("CrashSightAgent:_HandleException(LogType, String, String, String, Boolean)")
+                            && stackTrace.Contains("CrashSightAgent:_OnLogCallbackHandler(String, String, LogType)")
+                            && stackTrace.Contains("UnityEngine.Application:CallLogCallback(String, String, LogType, Boolean)"))
+                        {
+                            int count = stackTrace.IndexOf("\n");
+                            count = stackTrace.IndexOf("\n", count + 1);
+                            count = stackTrace.IndexOf("\n", count + 1);
+                            stackTrace = stackTrace.Substring(count + 1);
+                        }
+                    }
+                    catch
+                    {
+                    }
+                }
+            }
+        }
+        else
+        {
+            type = name;
+        }
+
+        _reportException(uncaught, type, reason, stackTrace);
+    }
+
+    #endregion
+}

+ 11 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/CrashSightAgent.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 34047571c56b3c94f92a828719fbabce
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 81a06a3bb7606664d93044a9c50eb28e
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bca1e29d2ac885d428e49570f70a71c0
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 63 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/UQM.cs

@@ -0,0 +1,63 @@
+using UnityEngine;
+
+namespace GCloud.UQM
+{
+    #region UQM
+	/// <summary>
+	/// 回调的范型
+	/// </summary>
+	public delegate void OnUQMRetEventHandler<T> (T ret);
+	public delegate string OnUQMStringRetEventHandler<T> (T ret, T crashType);
+
+    public delegate string OnUQMStringRetSetLogPathEventHandler<T>(T ret, T crashType);
+    public delegate void OnUQMRetLogUploadEventHandler<T>(T ret, T crashType, T result);
+    
+
+    public class UQM
+    {
+#if UNITY_ANDROID
+        public const string LibName = "CrashSight";
+#elif UNITY_IOS
+        public const string LibName = "__Internal";
+#elif UNITY_STANDALONE_WIN
+#if UNITY_64//win64
+        public const string LibName = "CrashSight64";
+#else//win32
+        public const string LibName = "CrashSight";
+#endif
+#elif UNITY_STANDALONE_OSX
+        public const string LibName = "CrashSight";
+#elif UNITY_XBOXONE
+        public const string LibName = "CrashSightXbox";
+#elif UNITY_PS4 || UNITY_PS5
+        public const string LibName = "libcs";
+#elif UNITY_SWITCH
+        public const string LibName = "__Internal";
+#elif UNITY_STANDALONE_LINUX
+        public const string LibName = "CrashSight";
+#elif UNITY_OPENHARMONY
+        public const string LibName = "CrashSight";
+#else
+        public const string LibName = "__Internal";
+#endif
+        private static bool initialized;
+
+        public static bool isDebug = true;
+
+		/// <summary>
+		/// UQM init,游戏开始的时候设置
+		/// </summary>
+        public static void Init()
+		{
+            if (initialized) return;
+            initialized = true;
+            if (isDebug)
+                UQMLog.SetLevel(UQMLog.Level.Log);
+            else
+                UQMLog.SetLevel(UQMLog.Level.Error);
+			UQMLog.Log ("UQM initialed !");
+        }
+    }
+
+    #endregion
+}

+ 11 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/UQM.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 28b1e81b8fa4086468b902ed1d439949
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1707 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/UQMCrash.cs

@@ -0,0 +1,1707 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using UnityEngine;
+
+namespace GCloud.UQM
+{
+    public enum UQMCrashLevel
+    {
+        CSLogLevelSilent = 0, //关闭日志记录功能
+        CSLogLevelError = 1,
+        CSLogLevelWarn = 2,
+        CSLogLevelInfo = 3,
+        CSLogLevelDebug = 4,
+        CSLogLevelVerbose = 5,
+    }
+
+    public static class UQMCrash
+    {
+#if !UNITY_EDITOR
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX || UNITY_OPENHARMONY)
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_configAutoReportLogLevelAdapter(int level);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_configGameTypeAdapter(int gameType);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_configCallbackTypeAdapter(Int32 callbackType);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_configDefaultAdapter([MarshalAs(UnmanagedType.LPStr)] string channel,
+            [MarshalAs(UnmanagedType.LPStr)] string version,
+            [MarshalAs(UnmanagedType.LPStr)] string user,
+            long delay);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_configCrashServerUrlAdapter([MarshalAs(UnmanagedType.LPStr)] string serverUrl);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_configDebugModeAdapter(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_initWithAppIdAdapter([MarshalAs(UnmanagedType.LPStr)] string appId, bool forceOnUiThread);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_logRecordAdapter(int level, [MarshalAs(UnmanagedType.LPStr)] string message);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_addSceneDataAdapter([MarshalAs(UnmanagedType.LPStr)] string k, [MarshalAs(UnmanagedType.LPStr)] string v);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_reportExceptionAdapter(int type, [MarshalAs(UnmanagedType.LPStr)] string exceptionName,
+            [MarshalAs(UnmanagedType.LPStr)] string exceptionMsg, [MarshalAs(UnmanagedType.LPStr)] string exceptionStack, [MarshalAs(UnmanagedType.LPStr)] string extras, 
+            [MarshalAs(UnmanagedType.LPStr)] string paramsJson, bool quitProgram, int dumpNativeType, [MarshalAs(UnmanagedType.LPStr)] string errorAttachmentPath);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setUserIdAdapter([MarshalAs(UnmanagedType.LPStr)] string userId);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setSceneAdapter([MarshalAs(UnmanagedType.LPStr)] string sceneId, bool upload);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_unityCrashCallback();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_unregisterUnityCrashCallback();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_unityCrashLogCallback();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_reRegistAllMonitorsAdapter();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_closeAllMonitorsAdapter();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_reportLogInfo([MarshalAs(UnmanagedType.LPStr)] string msgType,[MarshalAs(UnmanagedType.LPStr)] string msg);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setAppVersionAdapter([MarshalAs(UnmanagedType.LPStr)] string appVersion);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setDeviceIdAdapter([MarshalAs(UnmanagedType.LPStr)] string deviceId);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setCustomizedDeviceIDAdapter([MarshalAs(UnmanagedType.LPStr)] string deviceId);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern IntPtr cs_getSDKDefinedDeviceIDAdapter();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setCustomizedMatchIDAdapter([MarshalAs(UnmanagedType.LPStr)] string matchId);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern IntPtr cs_getSDKSessionIDAdapter();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern IntPtr cs_getCrashUuidAdapter();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setDeviceModelAdapter([MarshalAs(UnmanagedType.LPStr)] string deviceModel);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setLogPathAdapter([MarshalAs(UnmanagedType.LPStr)] string logPath);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_testOomCrashAdapter();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_testJavaCrashAdapter();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_testOcCrashAdapter();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_testNativeCrashAdapter();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_testANRAdapter();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern long cs_getCrashThreadId();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setLogcatBufferSize(int size);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setCallbackMsgAdapter([MarshalAs(UnmanagedType.LPStr)] string deviceModel);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_startDumpRoutine(int dumpMode, int startTimeMode, long startTime,
+         long dumpInterval, int dumpTimes, bool saveLocal, [MarshalAs(UnmanagedType.LPStr)] string savePath);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_startMonitorFdCount(int interval, int limit, int dumpType);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int cs_getExceptionType(string name);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_testUseAfterFreeAdapter();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setEnableGetPackageInfo(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setServerEnv([MarshalAs(UnmanagedType.LPStr)] string serverEnv);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setEngineInfo([MarshalAs(UnmanagedType.LPStr)] string version, [MarshalAs(UnmanagedType.LPStr)] string buildConfig, [MarshalAs(UnmanagedType.LPStr)] string language, [MarshalAs(UnmanagedType.LPStr)] string locale);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setGpuInfo([MarshalAs(UnmanagedType.LPStr)] string version, [MarshalAs(UnmanagedType.LPStr)] string vendor, [MarshalAs(UnmanagedType.LPStr)] string renderer);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setCatchMultiSignal(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_enableDetailedPageTracing(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_useSavedUserId(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern bool cs_isLastSessionCrash();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern IntPtr cs_getLastSessionUserId();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern bool cs_checkFdCount(int limit, int dumpType, bool upload);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setOomLogPath([MarshalAs(UnmanagedType.LPStr)] string logPath);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_reportJank(int type, [MarshalAs(UnmanagedType.LPStr)] string exceptionName,
+                 [MarshalAs(UnmanagedType.LPStr)] string exceptionMsg, [MarshalAs(UnmanagedType.LPStr)] string exceptionStack,
+                 [MarshalAs(UnmanagedType.LPStr)] string paramsJson, int reportInfoOption,
+                 [MarshalAs(UnmanagedType.LPStr)] string jankAttachmentPath);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_processEngineAnr(int type);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setEngineMainThread();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_reportStuck(int threadId, int maxChecks, int checkInterval,
+                 [MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string message,
+                 [MarshalAs(UnmanagedType.LPStr)] string extraInfo, int dumpNativeType,
+                 [MarshalAs(UnmanagedType.LPStr)] string attachPath);
+#elif UNITY_STANDALONE_WIN || UNITY_XBOXONE
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_InitContext([MarshalAs(UnmanagedType.LPStr)] string id, [MarshalAs(UnmanagedType.LPStr)] string version, [MarshalAs(UnmanagedType.LPStr)] string key);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ReportExceptionW(int type,[MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string message,[MarshalAs(UnmanagedType.LPStr)] string stack_trace,
+                                   [MarshalAs(UnmanagedType.LPStr)] string extras, bool is_async, [MarshalAs(UnmanagedType.LPWStr)] string attachmentPath = "");
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetUserValue([MarshalAs(UnmanagedType.LPStr)] string key, [MarshalAs(UnmanagedType.LPStr)] string value);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetVehEnable(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetExtraHandler(bool extra_handle_enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetCustomLogDirW([MarshalAs(UnmanagedType.LPWStr)] string log_path);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetUserId([MarshalAs(UnmanagedType.LPStr)] string user_id);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_MonitorEnable(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_PrintLog(int level, [MarshalAs(UnmanagedType.LPStr)] string tag, [MarshalAs(UnmanagedType.LPStr)] string format, [MarshalAs(UnmanagedType.LPStr)] string arg);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_UploadGivenPathDump([MarshalAs(UnmanagedType.LPStr)] string dump_dir, bool is_extra_check);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ReportCrash();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ReportDump([MarshalAs(UnmanagedType.LPStr)] string dump_dir, bool is_async);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetEnvironmentName([MarshalAs(UnmanagedType.LPStr)] string name);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_InitWithAppId([MarshalAs(UnmanagedType.LPStr)] string app_id);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetAppVersion([MarshalAs(UnmanagedType.LPStr)] string app_version);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ConfigCrashServerUrl([MarshalAs(UnmanagedType.LPStr)] string crash_server_url);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ConfigDebugMode(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetDeviceId([MarshalAs(UnmanagedType.LPStr)] string device_id);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ConfigCrashReporter(int log_level);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_TestNativeCrash();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetDumpType(int dump_type);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_AddValidExpCode(ulong exp_code);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_UploadCrashWithGuid([MarshalAs(UnmanagedType.LPStr)] string guid);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetCrashUploadEnable(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetWorkSpaceW([MarshalAs(UnmanagedType.LPWStr)] string workspace);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetEngineInfo([MarshalAs(UnmanagedType.LPStr)] string version, [MarshalAs(UnmanagedType.LPStr)] string buildConfig, [MarshalAs(UnmanagedType.LPStr)] string language, [MarshalAs(UnmanagedType.LPStr)] string locale);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetCustomAttachDirW([MarshalAs(UnmanagedType.LPWStr)] string log_path);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_UseSavedUserId(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ReportStuck(int threadId, int maxChecks, int checkInterval,
+                 [MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string message,
+                 [MarshalAs(UnmanagedType.LPStr)] string extraInfo, int dumpNativeType,
+                 [MarshalAs(UnmanagedType.LPStr)] string attachPath);
+#elif UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_InitWithAppId([MarshalAs(UnmanagedType.LPStr)] string appId);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetAppVersion([MarshalAs(UnmanagedType.LPStr)] string appVersion);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ReportException(int type, [MarshalAs(UnmanagedType.LPStr)] string name,
+                                [MarshalAs(UnmanagedType.LPStr)] string message, [MarshalAs(UnmanagedType.LPStr)] string stack_trace,
+                                [MarshalAs(UnmanagedType.LPStr)] string extras, bool quit);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetUserId([MarshalAs(UnmanagedType.LPStr)] string userId);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_EnableDebugMode(bool isDebug);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetErrorUploadInterval(int interval);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetCrashServerUrl([MarshalAs(UnmanagedType.LPStr)] string crashServerUrl);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetUserValue([MarshalAs(UnmanagedType.LPStr)] string key, [MarshalAs(UnmanagedType.LPStr)] string value);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetErrorUploadEnable(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_PrintLog(int level, [MarshalAs(UnmanagedType.LPStr)] string tag, [MarshalAs(UnmanagedType.LPStr)] string data);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetDeviceId([MarshalAs(UnmanagedType.LPStr)] string deviceId);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ConfigCrashReporter(int logLevel);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_TestNativeCrash();
+#if UNITY_PS4 || UNITY_PS5
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetLogPath([MarshalAs(UnmanagedType.LPStr)] string path);
+#endif
+#elif UNITY_STANDALONE_LINUX
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ConfigCrashServerUrl([MarshalAs(UnmanagedType.LPStr)] string user_id);  //需要传入Uid
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_Init([MarshalAs(UnmanagedType.LPStr)] string app_id, [MarshalAs(UnmanagedType.LPStr)] string app_key,
+                                [MarshalAs(UnmanagedType.LPStr)] string app_version);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetUserId([MarshalAs(UnmanagedType.LPStr)] string user_id);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetDeviceId([MarshalAs(UnmanagedType.LPStr)] string device_id);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetAppVersion([MarshalAs(UnmanagedType.LPStr)] string app_version);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_PrintLog(int level, [MarshalAs(UnmanagedType.LPStr)] string format, [MarshalAs(UnmanagedType.LPStr)] string arg);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetRecordFileDir([MarshalAs(UnmanagedType.LPStr)] string record_dir);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetUserValue([MarshalAs(UnmanagedType.LPStr)] string key, [MarshalAs(UnmanagedType.LPStr)] string value);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_SetLogPath([MarshalAs(UnmanagedType.LPStr)] string log_path);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ReportException(int type, [MarshalAs(UnmanagedType.LPStr)] string name,
+                                [MarshalAs(UnmanagedType.LPStr)] string reason, [MarshalAs(UnmanagedType.LPStr)] string stackTrace,
+                                [MarshalAs(UnmanagedType.LPStr)] string extras, bool quit, int dumpNativeType = 0);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_InitWithAppId([MarshalAs(UnmanagedType.LPStr)] string app_id);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ConfigDebugMode(bool enable);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_ConfigCrashReporter(int log_level);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_TestNativeCrash();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_CloseCrashReport();
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setEngineInfo([MarshalAs(UnmanagedType.LPStr)] string version, [MarshalAs(UnmanagedType.LPStr)] string buildConfig, [MarshalAs(UnmanagedType.LPStr)] string language, [MarshalAs(UnmanagedType.LPStr)] string locale);
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void CS_PostLogStatics([MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string message);
+#endif
+#endif
+
+#if UNITY_OPENHARMONY
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_reportExceptionV1Adapter(int type, [MarshalAs(UnmanagedType.LPStr)] string name,
+            [MarshalAs(UnmanagedType.LPStr)] string message, [MarshalAs(UnmanagedType.LPStr)] string stackTrace,
+            [MarshalAs(UnmanagedType.LPStr)] string extras, bool quitProgram);
+#endif
+
+        /// <summary>
+        /// Crash回调方法,提供上报用户数据能力
+        /// </summary>
+        public static event OnUQMStringRetEventHandler<int> CrashBaseRetEvent;
+
+        public static event OnUQMStringRetSetLogPathEventHandler<int> CrashSetLogPathRetEvent;
+        public static event OnUQMRetLogUploadEventHandler<int> CrashLogUploadRetEvent;
+
+        private static AndroidJavaClass _gameAgentClass = null;
+        private static bool _isLoadedSo = false;
+        private static int _gameType = 0; // COCOS=1, UNITY=2, UNREAL=3
+        private static readonly string GAME_AGENT_CLASS = "com.uqm.crashsight.core.api.CrashSightPlatform";
+
+        public static AndroidJavaClass CrashSightPlatform
+        {
+            get
+            {
+                if (_gameAgentClass == null)
+                {
+                    _gameAgentClass = new AndroidJavaClass(GAME_AGENT_CLASS);
+                }
+                return _gameAgentClass;
+            }
+        }
+
+        private static void LoadCrashSightCoreSo()
+        {
+#if UNITY_ANDROID && !UNITY_EDITOR
+            if (_isLoadedSo)
+            {
+                return;
+            }
+            try
+            {
+                CrashSightPlatform.CallStatic<bool>("loadCrashSightCoreSo");
+                _isLoadedSo = true;
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("loadSo with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+#endif
+        }
+
+        public static void ConfigCallbackType(Int32 callbackType)
+        {
+            try
+            {
+                UQMLog.Log("ConfigCallbackType  callbackType=" + callbackType);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+            cs_configCallbackTypeAdapter(callbackType);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ConfigCallbackType with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ConfigGameType(int gameType)
+        {
+            try
+            {
+                UQMLog.Log("SetGameType gameType=" + gameType);
+                _gameType = gameType;
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_configGameTypeAdapter(gameType);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetGameType with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ConfigAutoReportLogLevel(int level)
+        {
+            try
+            {
+                UQMLog.Log("ConfigAutoReportLogLevel  level=" + level);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_configAutoReportLogLevelAdapter(level);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_ConfigCrashReporter(level);
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_ConfigCrashReporter(level);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_ConfigCrashReporter(level);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ConfigAutoReportLogLevel with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ConfigCrashServerUrl(string serverUrl)
+        {
+            try
+            {
+                UQMLog.Log("ConfigCrashServerUrl  serverUrl=" + serverUrl);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX || UNITY_OPENHARMONY) && !UNITY_EDITOR
+                cs_configCrashServerUrlAdapter(serverUrl);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_ConfigCrashServerUrl(serverUrl);
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_SetCrashServerUrl(serverUrl);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_ConfigCrashServerUrl(serverUrl);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ConfigCrashServerUrl with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ConfigDebugMode(bool enable)
+        {
+            try
+            {
+                if (enable)
+                {
+                    UQMLog.SetLevel(UQMLog.Level.Log);
+                }
+                LoadCrashSightCoreSo();
+                UQMLog.Log("ConfigDebugMode  enable=" + enable);
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_configDebugModeAdapter(enable);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_ConfigDebugMode(enable);
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_EnableDebugMode(enable);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_ConfigDebugMode(enable);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ConfigDebugMode with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ConfigDefault(string channel, string version, string user, long delay)
+        {
+            try
+            {
+                UQMLog.Log("ConfigDefault  channel=" + channel + " version=" + version + " user=" + user + " delay=" + delay);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_configDefaultAdapter(channel, version, user, delay);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ConfigDefault with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void InitWithAppId(string appId, bool forceOnUiThread)
+        {
+            try
+            {
+                UQMLog.Log("InitWithAppId appId = " + appId);
+                LoadCrashSightCoreSo();
+                if (_gameType == 0) {
+                    ConfigGameType(2);  // 默认Unity
+                }
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+#if UNITY_5_3_OR_NEWER
+                    string Vendor = SystemInfo.graphicsDeviceVendor;
+                    string Render = SystemInfo.graphicsDeviceName;
+                    string Version = SystemInfo.graphicsDeviceVersion;
+                    cs_setGpuInfo(Version, Vendor, Render);
+#endif
+                    cs_initWithAppIdAdapter(appId, forceOnUiThread);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                    CS_InitWithAppId(appId);
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                    CS_InitWithAppId(appId);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                    CS_InitWithAppId(appId);
+#elif UNITY_OPENHARMONY && !UNITY_EDITOR
+                    OpenHarmonyJSObject CrashSightObject = null;
+                    CrashSightObject = new OpenHarmonyJSObject("CrashSightObj");
+                    CrashSightObject.Call<int>("initContext");
+                    cs_initWithAppIdAdapter(appId);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("InitWithAppId with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void InitContext(string userId, string version, string key)
+        {
+            try
+            {
+                UQMLog.Log("InitContext user_id = " + userId);
+#if (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_MonitorEnable(false);
+                CS_InitContext(userId,version, key );
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("InitWithAppId with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+
+        public static void LogRecord(int level, string message)
+        {
+            try
+            {
+                UQMLog.Log("LogRecord  level=" + level + " message=" + message);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_logRecordAdapter (level, message);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_PrintLog(level, "", "%s", message);
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_PrintLog(level, "", message);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_PrintLog(level, "%s", message);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("LogRecord with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void AddSceneData(string k, string v)
+        {
+            try
+            {
+                UQMLog.Log("AddSceneData  key=" + k + " value=" + v);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX || UNITY_OPENHARMONY) && !UNITY_EDITOR
+                cs_addSceneDataAdapter(k, v);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_SetUserValue(k, v);
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_SetUserValue(k, v);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_SetUserValue(k, v);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("AddSceneData with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ReportException(int type, string name, string message, string stackTrace, string extras, bool quitProgram)
+        {
+            try
+            {
+                UQMLog.Log("ReportException  name=" + name + " quitProgram=" + quitProgram);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_reportExceptionAdapter (type, name, message, stackTrace, extras, null, quitProgram, 0, null);
+#endif
+#if (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_ReportExceptionW(type, name, message, stackTrace, extras, true, "");
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_ReportException(type, name, message, stackTrace, extras, quitProgram);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_ReportException(type, name, message, stackTrace, extras, quitProgram, 0);
+#elif ( UNITY_OPENHARMONY) && !UNITY_EDITOR
+                cs_reportExceptionV1Adapter (type, name, message, stackTrace, extras, quitProgram);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ReportException with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ReportException(int type, string exceptionName, string exceptionMsg, string exceptionStack, Dictionary<string, string> extInfo, int dumpNativeType = 0, string errorAttachmentPath = "")
+        {
+            try
+            {
+                UQMLog.Log(string.Format("ReportException exceptionName={0} exceptionMsg={1} dumpNativeType={2}", exceptionName, exceptionMsg, dumpNativeType));
+                LoadCrashSightCoreSo();
+                string paramsJson = MiniJSON.Json.Serialize(extInfo);
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_reportExceptionAdapter (type, exceptionName, exceptionMsg, exceptionStack, null, paramsJson, false, dumpNativeType, errorAttachmentPath);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_ReportExceptionW(type, exceptionName, exceptionMsg, exceptionStack, paramsJson, true, errorAttachmentPath);
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_ReportException(type, exceptionName, exceptionMsg, exceptionStack, paramsJson, false);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_ReportException(type, exceptionName, exceptionMsg, exceptionStack, paramsJson, false, dumpNativeType);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ReportException with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetUserId(string userId)
+        {
+            try
+            {
+                UQMLog.Log("SetUserId userId = " + userId);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX || UNITY_OPENHARMONY) && !UNITY_EDITOR
+                cs_setUserIdAdapter(userId);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_SetUserId(userId);
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_SetUserId(userId);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_SetUserId(userId);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetUserId with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetScene(string sceneId, bool upload)
+        {
+            try
+            {
+                UQMLog.Log("SetScene sceneId = " + sceneId + ", upload = " + upload);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                    cs_setSceneAdapter(sceneId, upload);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetScene with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ReRegistAllMonitors()
+        {
+            try
+            {
+                UQMLog.Log("ReRegistAllMonitors");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_reRegistAllMonitorsAdapter();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ReRegistAllMonitors with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void CloseAllMonitors()
+        {
+            try
+            {
+                UQMLog.Log("CloseAllMonitors");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_closeAllMonitorsAdapter();
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_CloseCrashReport();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("CloseAllMonitors with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ReportLogInfo(string msgType, string msg) {
+            try
+            {
+                UQMLog.Log("ReportLogInfo");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_reportLogInfo(msgType, msg);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_PostLogStatics(msgType, msg);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ReportLogInfo with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetAppVersion(string appVersion)
+        {
+            try
+            {
+                UQMLog.Log("SetAppVersion appVersion = " + appVersion);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX || UNITY_OPENHARMONY) && !UNITY_EDITOR
+                    cs_setAppVersionAdapter(appVersion);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                    CS_SetAppVersion(appVersion);
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                    CS_SetAppVersion(appVersion);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetAppVersion with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetDeviceId(string deviceId)
+        {
+            try
+            {
+                UQMLog.Log("SetDeviceId deviceId = " + deviceId);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_setDeviceIdAdapter(deviceId);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_SetDeviceId(deviceId);
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_SetDeviceId(deviceId);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_SetDeviceId(deviceId);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetDeviceId with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetCustomizedDeviceID(string deviceId)
+        {
+            try
+            {
+                UQMLog.Log("SetCustomizedDeviceID deviceId = " + deviceId);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                    cs_setCustomizedDeviceIDAdapter(deviceId);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetCustomizedDeviceID with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static string GetSDKDefinedDeviceID()
+        {
+            try
+            {
+                UQMLog.Log("GetSDKDefinedDeviceID");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                IntPtr tranResult = cs_getSDKDefinedDeviceIDAdapter();
+                return Marshal.PtrToStringAnsi(tranResult);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("GetSDKDefinedDeviceID with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+            return "";
+        }
+
+
+        public static void SetCustomizedMatchID(string matchId)
+        {
+            try
+            {
+                UQMLog.Log("SetCustomizedMatchID matchId = " + matchId);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                    cs_setCustomizedMatchIDAdapter(matchId);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetCustomizedMatchID with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static string GetSDKSessionID()
+        {
+            try
+            {
+                UQMLog.Log("GetSDKSessionID");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                IntPtr tranResult = cs_getSDKSessionIDAdapter();
+                return Marshal.PtrToStringAnsi(tranResult);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("GetSDKSessionID with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+            return "";
+        }
+
+        public static string GetCrashUuid()
+        {
+            try
+            {
+                UQMLog.Log("GetCrashUuid");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                IntPtr tranResult = cs_getCrashUuidAdapter();
+                return Marshal.PtrToStringAnsi(tranResult);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("GetCrashUuid with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+            return "";
+        }
+
+        public static void SetDeviceModel(string deviceModel)
+        {
+            try
+            {
+                UQMLog.Log("SetDeviceModel deviceModel = " + deviceModel);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                    cs_setDeviceModelAdapter(deviceModel);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetDeviceModel with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetLogPath(string logPath)
+        {
+            try
+            {
+                UQMLog.Log("SetLogPath logPath = " + logPath);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_setLogPathAdapter(logPath);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_SetCustomLogDirW(logPath);
+#elif (UNITY_PS4 || UNITY_PS5) && !UNITY_EDITOR
+                CS_SetLogPath(logPath);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_SetLogPath(logPath);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetLogPath with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetCrashCallback()
+        {
+            try
+            {
+                UQMLog.Log("SetCrashCallback");
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_unityCrashCallback();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetCrashCallback with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+
+        }
+
+        public static void UnsetCrashCallback()
+        {
+            try
+            {
+                UQMLog.Log("UnsetCrashCallback");
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_unregisterUnityCrashCallback();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("UnsetCrashCallback with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+
+        }
+
+        public static void SetCrashLogCallback()
+        {
+            try
+            {
+                UQMLog.Log("SetCrashLogCallback");
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_unityCrashLogCallback();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetCrashLogCallback with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+
+        }
+
+        //callback
+        internal static string OnCrashCallbackMessage(int methodId, int crashType)
+        {
+            UQMLog.Log("OnCrashCallbackMessage  methodId= " + methodId + " crashType=" + crashType);
+            if (CrashBaseRetEvent != null)
+            {
+                try
+                {
+                    return CrashBaseRetEvent(methodId, crashType);
+                }
+                catch (Exception e)
+                {
+                    UQMLog.LogError(e.StackTrace);
+                }
+            }
+            else
+            {
+                UQMLog.LogError("No callback for OnCrashCallbackMessage !");
+            }
+            return "";
+        }
+
+        internal static string OnCrashCallbackData(int methodId, int crashType)
+        {
+            UQMLog.Log("OnCrashCallbackData  methodId= " + methodId + " crashType=" + crashType);
+            if (CrashBaseRetEvent != null)
+            {
+                try
+                {
+                    return CrashBaseRetEvent(methodId, crashType);
+                }
+                catch (Exception e)
+                {
+                    UQMLog.LogError(e.StackTrace);
+                }
+            }
+            else
+            {
+                UQMLog.LogError("No callback for OnCrashCallbackData !");
+            }
+            return "";
+        }
+
+        internal static string OnCrashSetLogPathMessage(int methodId, int crashType)
+        {
+            UQMLog.Log("OnCrashSetLogPathMessage  methodId= " + methodId + " crashType=" + crashType);
+            if (CrashSetLogPathRetEvent != null)
+            {
+                try
+                {
+                    return CrashSetLogPathRetEvent(methodId, crashType);
+                }
+                catch (Exception e)
+                {
+                    UQMLog.LogError(e.StackTrace);
+                }
+            }
+            else
+            {
+                UQMLog.LogError("No callback for OnCrashSetLogPathMessage !");
+            }
+            return "";
+        }
+
+        internal static string OnCrashLogUploadMessage(int methodId, int crashType, int result)
+        {
+            UQMLog.Log("OnCrashLogUploadMessage  methodId= " + methodId + " crashType=" + crashType);
+            if (CrashLogUploadRetEvent != null)
+            {
+                try
+                {
+                    CrashLogUploadRetEvent(methodId, crashType, result);
+                }
+                catch (Exception e)
+                {
+                    UQMLog.LogError(e.StackTrace);
+                }
+            }
+            else
+            {
+                UQMLog.LogError("No callback for OnCrashLogUploadMessage !");
+            }
+            return "";
+        }
+
+        internal static string OnCrashCallbackNoRet(int methodId, int crashType)
+        {
+            UQMLog.Log("OnCrashCallbackNoRet  methodId= " + methodId + " crashType=" + crashType);
+            if (CrashBaseRetEvent != null)
+            {
+                try
+                {
+                    return CrashBaseRetEvent(methodId, crashType);
+                }
+                catch (Exception e)
+                {
+                    UQMLog.LogError(e.StackTrace);
+                }
+            }
+            else
+            {
+                UQMLog.LogError("No callback for OnCrashCallbackNoRet !");
+            }
+            return "";
+        }
+
+        public static void ConfigCallBack()
+        {
+            SetCrashCallback();
+            UQMMessageCenter.Instance.Init();
+        }
+
+        public static void UnregisterCallBack()
+        {
+            UnsetCrashCallback();
+            UQMMessageCenter.Instance.Uninit();
+        }
+
+        public static void ConfigLogCallBack()
+        {
+            SetCrashLogCallback();
+            UQMMessageCenter.Instance.Init();
+        }
+
+        // Test cases
+        public static void TestOomCrash()
+        {
+            try
+            {
+                UQMLog.Log("TestOomCrash");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_testOomCrashAdapter();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("TestOomCrash with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void TestJavaCrash()
+        {
+            try
+            {
+                UQMLog.Log("TestJavaCrash");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_testJavaCrashAdapter();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("TestJavaCrash with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void TestOcCrash()
+        {
+            try
+            {
+                UQMLog.Log("TestOcCrash");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_testOcCrashAdapter();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("TestOcCrash with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void TestNativeCrash()
+        {
+            try
+            {
+                UQMLog.Log("TestNativeCrash");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_testNativeCrashAdapter();
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_TestNativeCrash();
+#elif (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_TestNativeCrash();
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_TestNativeCrash();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("TestNativeCrash with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void TestANR()
+        {
+            try
+            {
+                UQMLog.Log("TestANR");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_testANRAdapter();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("TestANR with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+
+        public static long GetCrashThreadId()
+        {
+            long thread_id = -1;
+            try
+            {
+                UQMLog.Log("GetCrashThreadId");
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                thread_id = cs_getCrashThreadId();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("GetCrashThreadId with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+            return thread_id;
+        }
+
+        public static void SetLogcatBufferSize(int size)
+        {
+            try
+            {
+                UQMLog.Log("SetLogcatBufferSize:" + size);
+#if UNITY_ANDROID && !UNITY_EDITOR
+                cs_setLogcatBufferSize(size);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetLogcatBufferSize with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetCallbackMsg(string data)
+        {
+             try
+             {
+                  UQMLog.Log("SetCallBackMsg SetCallBackMsg = " + data);
+                  LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                  cs_setCallbackMsgAdapter(data);
+#endif
+             }
+             catch (Exception ex)
+             {
+                  UQMLog.LogError("SetDeviceModel with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+             }
+        }
+
+        public static void StartDumpRoutine(int dumpMode, int startTimeMode, long startTime,
+            long dumpInterval, int dumpTimes, bool saveLocal, string savePath)
+        {
+             try
+             {
+                  UQMLog.Log("StartDumpRoutine dumpMode = " + dumpMode
+                      + ", startTimeMode = " + startTimeMode
+                      + ", startTime = " + startTime
+                      + ", dumpInterval = " + dumpInterval
+                      + ", dumpTimes = " + dumpTimes
+                      + ", saveLocal = " + saveLocal
+                      + ", savePath = " + savePath);
+                  LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                  cs_startDumpRoutine(dumpMode, startTimeMode, startTime, dumpInterval, dumpTimes, saveLocal, savePath);
+#endif
+             }
+             catch (Exception ex)
+             {
+                  UQMLog.LogError("StartDumpRoutine with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+             }
+        }
+
+        public static void StartMonitorFdCount(int interval, int limit, int dumpType)
+        {
+             try
+             {
+                  UQMLog.Log("StartMonitorFdCount interval = " + interval
+                      + ", limit = " + limit + ", dumpType = " + dumpType);
+                  LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                  cs_startMonitorFdCount(interval, limit, dumpType);
+#endif
+             }
+             catch (Exception ex)
+             {
+                  UQMLog.LogError("StartMonitorFdCount with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+             }
+        }
+
+        public static int getExceptionType(string name)
+        {
+             int type = 0;
+             try
+             {
+                  UQMLog.Log("getExceptionType name = " + name);
+                  LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                  type = cs_getExceptionType(name);
+#endif
+             }
+             catch (Exception ex)
+             {
+                  UQMLog.LogError("getExceptionType with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+             }
+             return type;
+        }
+        
+        public static void TestUseAfterFree()
+        {
+            try
+            {
+                UQMLog.Log("TestUseAfterFree");
+                LoadCrashSightCoreSo();
+#if UNITY_ANDROID && !UNITY_EDITOR
+                cs_testUseAfterFreeAdapter();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("TestUseAfterFree with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetServerEnv(string serverEnv)
+        {
+             try
+             {
+                  UQMLog.Log("SetServerEnv serverEnv = " + serverEnv);
+                  LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                  cs_setServerEnv(serverEnv);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                  CS_SetEnvironmentName(serverEnv);
+#endif
+             }
+             catch (Exception ex)
+             {
+                  UQMLog.LogError("SetServerEnv with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+             }
+        }
+
+        public static void SetVehEnable(bool enable)
+        {
+            try
+            {
+                UQMLog.Log("SetVehEnable:" + enable);
+#if (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_SetVehEnable(enable);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetVehEnable with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ReportCrash()
+        {
+            try
+            {
+                UQMLog.Log("ReportCrash");
+#if (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_ReportCrash();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ReportCrash with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ReportDump(string dump_path, bool is_async)
+        {
+            try
+            {
+                UQMLog.Log("ReportDump:" + dump_path + ", is_async:" + is_async);
+#if (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_ReportDump(dump_path, is_async);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ReportDump with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetExtraHandler(bool extra_handle_enable)
+        {
+            try
+            {
+                UQMLog.Log("SetExtraHandler:" + extra_handle_enable);
+#if (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_SetExtraHandler(extra_handle_enable);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetExtraHandler with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void UploadGivenPathDump(string dump_dir, bool is_extra_check)
+        {
+            try
+            {
+                UQMLog.Log("UploadGivenPathDump:" + dump_dir + ", is_extra_check:" + is_extra_check);
+#if (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_UploadGivenPathDump(dump_dir, is_extra_check);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("UploadGivenPathDump with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetErrorUploadInterval(int interval)
+        {
+            try
+            {
+                UQMLog.Log("SetErrorUploadInterval:" + interval);
+#if (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_SetErrorUploadInterval(interval);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetErrorUploadInterval with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetErrorUploadEnable(bool enable)
+        {
+            try
+            {
+                UQMLog.Log("SetErrorUploadEnable:" + enable);
+#if (UNITY_PS4 || UNITY_PS5 || UNITY_SWITCH) && !UNITY_EDITOR
+                CS_SetErrorUploadEnable(enable);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetErrorUploadEnable with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetRecordFileDir(string record_dir)
+        {
+            try
+            {
+                UQMLog.Log("SetRecordFileDir:" + record_dir);
+#if UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_SetRecordFileDir(record_dir);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetRecordFileDir with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void Init(string app_id, string app_key, string app_version)
+        {
+            try
+            {
+                UQMLog.Log("Init:" + app_id + ", app_key:" + app_key +", app_version:" + app_version);
+#if UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                CS_Init(app_id, app_key, app_version);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("Init with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+        
+        public static void setEnableGetPackageInfo(bool enable)
+        {
+            try
+            {
+                LoadCrashSightCoreSo();
+                UQMLog.Log("setEnableGetPackageInfo  enable=" + enable);
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_setEnableGetPackageInfo(enable);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("setEnableGetPackageInfo with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetDumpType(int dump_type)
+        {
+            try
+            {
+                UQMLog.Log("SetDumpType  dump_type=" + dump_type);
+#if (UNITY_STANDALONE_WIN) && !UNITY_EDITOR
+                CS_SetDumpType(dump_type);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetDumpType with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void AddValidExpCode(ulong exp_code)
+        {
+            try
+            {
+                UQMLog.Log("AddValidExpCode  exp_code=" + exp_code);
+#if (UNITY_STANDALONE_WIN) && !UNITY_EDITOR
+                CS_AddValidExpCode(exp_code);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("AddValidExpCode with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void UploadCrashWithGuid(string guid)
+        {
+            try
+            {
+                UQMLog.Log("UploadCrashWithGuid  guid=" + guid);
+#if (UNITY_STANDALONE_WIN) && !UNITY_EDITOR
+                CS_UploadCrashWithGuid(guid);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("UploadCrashWithGuid with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetCrashUploadEnable(bool enable)
+        {
+            try
+            {
+                UQMLog.Log("SetCrashUploadEnable  enable=" + enable);
+#if (UNITY_STANDALONE_WIN) && !UNITY_EDITOR
+                CS_SetCrashUploadEnable(enable);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetCrashUploadEnable with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetWorkSpace(string workspace)
+        {
+            try
+            {
+                UQMLog.Log("SetWorkSpace  workspace=" + workspace);
+#if (UNITY_STANDALONE_WIN) && !UNITY_EDITOR
+                CS_SetWorkSpaceW(workspace);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetWorkSpace with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetEngineInfo(string version, string buildConfig, string language, string locale)
+        {
+             try
+             {
+                  UQMLog.Log("SetEngineInfo version = " + version + ", buildConfig = " + buildConfig + ", language = " + language + ", locale = " + locale);
+                  LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                  cs_setEngineInfo(version, buildConfig, language, locale);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                  CS_SetEngineInfo(version, buildConfig, language, locale);
+#elif UNITY_STANDALONE_LINUX && !UNITY_EDITOR
+                  cs_SetEngineInfo(version, buildConfig, language, locale);
+#endif
+             }
+             catch (Exception ex)
+             {
+                  UQMLog.LogError("SetEngineInfo with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+             }
+        }
+
+        public static void setCatchMultiSignal(bool enable)
+        {
+            try
+            {
+                LoadCrashSightCoreSo();
+                UQMLog.Log("setCatchMultiSignal  enable=" + enable);
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_setCatchMultiSignal(enable);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("setCatchMultiSignal with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void enableDetailedPageTracing(bool enable)
+        {
+            try
+            {
+                LoadCrashSightCoreSo();
+                UQMLog.Log("enableDetailedPageTracing  enable=" + enable);
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_enableDetailedPageTracing(enable);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("enableDetailedPageTracing with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void useSavedUserId(bool enable)
+        {
+            try
+            {
+                LoadCrashSightCoreSo();
+                UQMLog.Log("useSavedUserId  enable=" + enable);
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX) && !UNITY_EDITOR
+                cs_useSavedUserId(enable);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_UseSavedUserId(enable);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("useSavedUserId with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+		
+		public static void SetCustomAttachDir(string path)
+        {
+#if (UNITY_STANDALONE_WIN) && !UNITY_EDITOR
+            CS_SetCustomAttachDirW(path);
+#endif
+        }
+
+
+        public static bool IsLastSessionCrash()
+        {
+            bool isCrash = false;
+            try
+            {
+                UQMLog.Log("IsLastSessionCrash");
+#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
+                isCrash = cs_isLastSessionCrash();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("IsLastSessionCrash with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+            return isCrash;
+        }
+
+        public static string GetLastSessionUserId()
+        {
+            try
+            {
+                UQMLog.Log("GetLastSessionUserId");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
+                IntPtr tranResult = cs_getLastSessionUserId();
+                return Marshal.PtrToStringAnsi(tranResult);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("GetLastSessionUserId with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+            return "";
+        }
+
+        public static bool CheckFdCount(int limit, int dumpType, bool upload)
+        {
+             try
+             {
+                  UQMLog.Log("CheckFdCount limit = " + limit + ", dumpType = " + dumpType + ", upload = " + upload);
+                  LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
+                  return cs_checkFdCount(limit, dumpType, upload);
+#endif
+             }
+             catch (Exception ex)
+             {
+                  UQMLog.LogError("CheckFdCount with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+             }
+             return false;
+        }
+
+        public static void SetOomLogPath(string logPath)
+        {
+            try
+            {
+                UQMLog.Log("SetOomLogPath logPath = " + logPath);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
+                cs_setOomLogPath(logPath);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetOomLogPath with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ReportJank(int type, string exceptionName,
+                                       string exceptionMsg, string exceptionStack,
+                                       string paramsJson, int reportInfoOption,
+                                       string jankAttachmentPath)
+        {
+            try
+            {
+                UQMLog.Log("ReportJank  type=" + type
+                                    + ", exceptionName=" + exceptionName
+                                    + ", exceptionMsg=" + exceptionMsg
+                                    + ", exceptionStack=" + exceptionStack
+                                    + ", paramsJson=" + paramsJson
+                                    + ", reportInfoOption=" + reportInfoOption
+                                    + ", jankAttachmentPath=" + jankAttachmentPath);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_OPENHARMONY) && !UNITY_EDITOR
+                cs_reportJank(type, exceptionName, exceptionMsg, exceptionStack, paramsJson, reportInfoOption, jankAttachmentPath);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ReportJank with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ProcessEngineAnr(int type)
+        {
+            try
+            {
+                UQMLog.Log("ProcessEngineAnr type = " + type);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID) && !UNITY_EDITOR
+                cs_processEngineAnr(type);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ProcessEngineAnr with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void SetEngineMainThread()
+        {
+            try
+            {
+                UQMLog.Log("SetEngineMainThread");
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID) && !UNITY_EDITOR
+                cs_setEngineMainThread();
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("SetEngineMainThread with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+
+        public static void ReportStuck(int threadId, int maxChecks, long checkInterval,
+                                       string name, string message, Dictionary<string, string> extInfo,
+                                       int dumpNativeType, string attachPath)
+        {
+            try
+            {
+                string paramsJson = MiniJSON.Json.Serialize(extInfo);
+                UQMLog.Log("ReportStuck  threadId=" + threadId
+                                    + ", maxChecks=" + maxChecks
+                                    + ", checkInterval=" + checkInterval
+                                    + ", name=" + name
+                                    + ", message=" + message
+                                    + ", extraInfo=" + paramsJson
+                                    + ", dumpNativeType=" + dumpNativeType
+                                    + ", attachPath=" + attachPath);
+                LoadCrashSightCoreSo();
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_OPENHARMONY) && !UNITY_EDITOR
+                cs_reportStuck(threadId, maxChecks, (int)checkInterval, name, message, paramsJson, dumpNativeType, attachPath);
+#elif (UNITY_STANDALONE_WIN || UNITY_XBOXONE) && !UNITY_EDITOR
+                CS_ReportStuck(threadId, maxChecks, (int)checkInterval, name, message, paramsJson, dumpNativeType, attachPath);
+#endif
+            }
+            catch (Exception ex)
+            {
+                UQMLog.LogError("ReportStuck with unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+            }
+        }
+    }
+}

+ 11 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/UQMCrash.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 23cacf0f55b6da543b1acb95f0e14ed3
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b52276a529d7da24182db01f818363b1
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 10 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMDefine.cs

@@ -0,0 +1,10 @@
+namespace GCloud.UQM
+{
+    public enum UQMMethodNameID
+    {
+		UQM_CRASH_CALLBACK_EXTRA_DATA           = 1011,
+		UQM_CRASH_CALLBACK_EXTRA_MESSAGE        = 1012,
+        UQM_CRASH_CALLBACK_SET_LOG_PATH         = 1013,
+        UQM_CRASH_CALLBACK_LOG_UPLOAD_RESULT    = 1014
+    }
+}

+ 11 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMDefine.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 831d916e1a2a1e24abc60bb7258090ea
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 87 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMLog.cs

@@ -0,0 +1,87 @@
+using System;
+namespace GCloud.UQM
+{
+	/// <summary>
+	/// UQM log
+	/// </summary>
+	class UQMLog
+	{
+		/// <summary>
+		/// UQM SDK Log level
+		/// </summary>
+		public enum Level
+		{
+			None = 0,
+			Log,
+			Warning,
+			Error
+		}
+
+		/// <summary>
+		/// The level, Error by default
+		/// </summary>
+        private static Level level = Level.Error;
+
+		private const string header = "[CrashSightPlugin-Unity]";
+
+		/// <summary>
+		/// Sets the level.
+		/// </summary>
+		/// <param name="l">Level</param>
+		public static void SetLevel (Level l)
+		{
+			level = l;
+		}
+
+		/// <summary>
+		/// Log the specified message.
+		/// </summary>
+		/// <param name="message">Message.</param>
+		public static void Log (string message)
+		{
+			if (level <= Level.Log) {
+				UnityEngine.Debug.Log (header + message);
+			}
+		}
+
+		/// <summary>
+		/// Warning the specified message.
+		/// </summary>
+		/// <param name="message">Message.</param>
+		public static void LogWarning (string message)
+		{
+			if (level <= Level.Warning) {
+				UnityEngine.Debug.LogWarning (header + message);
+			}
+		}
+
+		/// <summary>
+		/// Error the specified message.
+		/// </summary>
+		/// <param name="message">Message.</param>
+		public static void LogError (string message)
+		{
+			if (level <= Level.Error) {
+				UnityEngine.Debug.LogError (header + message);
+			}
+		}
+
+		public static void FullLog (string message)
+		{
+			try {
+				var counter = 0;
+				const int step = 512;
+				var all = message.Length;
+				while (counter < all) {
+					var start = counter;
+					var length = start + step > all ? all - start : step;
+					//UnityEngine.Debug.LogError(header + "all : " + all + " start : " + start + " length : " +  length);
+					UnityEngine.Debug.Log (header + message.Substring (start, length));
+					counter += step;
+				}
+			} catch (Exception e) {
+				UnityEngine.Debug.LogWarning (e.Message);
+			}
+		}
+	}
+}

+ 11 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMLog.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2dacb082ac621aa4c9f4eedad0e683b7
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 140 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMMessageCenter.cs

@@ -0,0 +1,140 @@
+using AOT;
+using System.Runtime.InteropServices;
+using System.Threading;
+using UnityEngine;
+
+
+namespace GCloud.UQM
+{
+    public class RetArgsWrapper
+    {
+        private readonly int methodId;
+        private readonly int crashType;
+        private readonly int logUploadResult;
+
+        public int MethodId
+        {
+            get { return methodId; }
+        }
+
+        public int CrashType
+        {
+            get { return crashType; }
+        }
+
+        public int LogUploadResult
+        {
+            get { return logUploadResult; }
+        }
+
+        public RetArgsWrapper(int _methodId, int _crashType, int _logUploadResult)
+        {
+            methodId = _methodId;
+            crashType = _crashType;
+            logUploadResult = _logUploadResult;
+        }
+    }
+
+    #region UQMMessageCenter
+
+    public class UQMMessageCenter : MonoBehaviour
+    {
+        #region json ret and callback
+
+        private static bool initialzed = false;
+
+        private delegate string UQMRetJsonEventHandler(int methodId, int callType, int logUploadResult);
+
+        [MonoPInvokeCallback(typeof(UQMRetJsonEventHandler))]
+        public static string OnUQMRet(int methodId, int crashType, int logUploadResult)
+        {
+            var argsWrapper = new RetArgsWrapper(methodId, crashType, logUploadResult);
+            UQMLog.Log("OnUQMRet, the methodId is ( " + methodId + " )  crashType=" + crashType);
+            if (methodId == (int)UQMMethodNameID.UQM_CRASH_CALLBACK_EXTRA_MESSAGE
+                || methodId == (int)UQMMethodNameID.UQM_CRASH_CALLBACK_EXTRA_DATA
+                || methodId == (int)UQMMethodNameID.UQM_CRASH_CALLBACK_SET_LOG_PATH
+                || methodId == (int)UQMMethodNameID.UQM_CRASH_CALLBACK_LOG_UPLOAD_RESULT
+                )
+            {
+                lock (CrashSightAgent.callbackThreadsLock) {
+                    CrashSightAgent.callbackThreads.Add(Thread.CurrentThread.ManagedThreadId);
+                }
+                string result = SynchronousDelegate(argsWrapper);
+                lock (CrashSightAgent.callbackThreadsLock) {
+                    CrashSightAgent.callbackThreads.Remove(Thread.CurrentThread.ManagedThreadId);
+                }
+                return result;
+            }
+            return "";
+        }
+
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_OPENHARMONY || UNITY_STANDALONE_LINUX) && !UNITY_EDITOR
+        [DllImport(UQM.LibName, CallingConvention = CallingConvention.Cdecl)]
+        private static extern void cs_setUnityCallback(UQMRetJsonEventHandler eventHandler);
+#endif
+        #endregion
+
+        static UQMMessageCenter instance;
+
+        public static UQMMessageCenter Instance
+        {
+            get
+            {
+                if (instance != null) return instance;
+                var bridgeGameObject = new GameObject { name = "UQMMessageCenter" };
+                DontDestroyOnLoad(bridgeGameObject);
+                instance = bridgeGameObject.AddComponent(typeof(UQMMessageCenter)) as UQMMessageCenter;
+                UQMLog.Log("UQMMessageCenter  instance=" + instance);
+                return instance;
+            }
+        }
+
+        public void Init()
+        {
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_OPENHARMONY || UNITY_STANDALONE_LINUX) && !UNITY_EDITOR
+           if (initialzed) {
+                return;
+            }
+            cs_setUnityCallback(OnUQMRet);
+            initialzed = true;
+#endif
+            UQMLog.Log("UQM Init, set unity callback");
+        }
+
+        public void Uninit()
+        {
+#if (UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_OPENHARMONY || UNITY_STANDALONE_LINUX) && !UNITY_EDITOR
+            cs_setUnityCallback(null);
+#endif
+            UQMLog.Log("UQM Uninit, set unity callback to null");
+        }
+
+        static string SynchronousDelegate(object arg)
+        {
+            var argsWrapper = (RetArgsWrapper)arg;
+            var methodId = argsWrapper.MethodId;
+            var crashType = argsWrapper.CrashType;
+
+            UQMLog.Log("the methodId is ( " + methodId + " ) and crashType=" + crashType);
+            switch (methodId)
+            {
+#if UNITY_WSA
+#else
+                case (int)UQMMethodNameID.UQM_CRASH_CALLBACK_EXTRA_MESSAGE:
+                    return UQMCrash.OnCrashCallbackMessage(methodId, crashType);
+
+                case (int)UQMMethodNameID.UQM_CRASH_CALLBACK_EXTRA_DATA:
+                    return UQMCrash.OnCrashCallbackData(methodId, crashType);
+
+                case (int)UQMMethodNameID.UQM_CRASH_CALLBACK_SET_LOG_PATH:
+                    return UQMCrash.OnCrashSetLogPathMessage(methodId, crashType);
+
+                case (int)UQMMethodNameID.UQM_CRASH_CALLBACK_LOG_UPLOAD_RESULT:
+                    return UQMCrash.OnCrashLogUploadMessage(methodId, crashType, argsWrapper.LogUploadResult);
+#endif
+            }
+            return "";
+        }
+#endregion
+    }
+}

+ 11 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMMessageCenter.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 524f6583d96f8ef4ca16ac5cf1e72745
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 516 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMMiniJSON.cs

@@ -0,0 +1,516 @@
+/*
+ * Copyright (c) 2013 Calvin Rien
+ *
+ * Based on the JSON parser by Patrick van Bergen
+ * http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
+ *
+ * Simplified it so that it doesn't throw exceptions
+ * and can be used in Unity iOS with maximum code stripping.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace GCloud.UQM.MiniJSON 
+{
+
+    /// <summary>
+    /// This class encodes and decodes JSON strings.
+    /// Spec. details, see http://www.json.org/
+    ///
+    /// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary.
+    /// All numbers are parsed to doubles.
+    /// </summary>
+    public static class Json {
+        /// <summary>
+        /// Parses the string json into a value
+        /// </summary>
+        /// <param name="json">A JSON string.</param>
+        /// <returns>An List&lt;object&gt;, a Dictionary&lt;string, object&gt;, a double, an integer,a string, null, true, or false</returns>
+        public static object Deserialize(string json) {
+            // save the string for debug information
+            if (json == null) {
+                return null;
+            }
+
+            return Parser.Parse(json);
+        }
+
+        sealed class Parser : IDisposable {
+            const string WORD_BREAK = "{}[],:\"";
+
+            public static bool IsWordBreak(char c) {
+                return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1;
+            }
+
+            enum TOKEN {
+                NONE,
+                CURLY_OPEN,
+                CURLY_CLOSE,
+                SQUARED_OPEN,
+                SQUARED_CLOSE,
+                COLON,
+                COMMA,
+                STRING,
+                NUMBER,
+                TRUE,
+                FALSE,
+                NULL
+            };
+
+            StringReader json;
+
+            Parser(string jsonString) {
+                json = new StringReader(jsonString);
+            }
+
+            public static object Parse(string jsonString) {
+                using (var instance = new Parser(jsonString)) {
+                    return instance.ParseValue();
+                }
+            }
+
+            public void Dispose() {
+                json.Dispose();
+                json = null;
+            }
+
+            Dictionary<string, object> ParseObject() {
+                Dictionary<string, object> table = new Dictionary<string, object>();
+
+                // ditch opening brace
+                json.Read();
+
+                // {
+                while (true) {
+                    switch (NextToken) {
+                    case TOKEN.NONE:
+                        return null;
+                    case TOKEN.COMMA:
+                        continue;
+                    case TOKEN.CURLY_CLOSE:
+                        return table;
+                    default:
+                        // name
+                        string name = ParseString();
+                        if (name == null) {
+                            return null;
+                        }
+
+                        // :
+                        if (NextToken != TOKEN.COLON) {
+                            return null;
+                        }
+                        // ditch the colon
+                        json.Read();
+
+                        // value
+                        table[name] = ParseValue();
+                        break;
+                    }
+                }
+            }
+
+            List<object> ParseArray() {
+                List<object> array = new List<object>();
+
+                // ditch opening bracket
+                json.Read();
+
+                // [
+                var parsing = true;
+                while (parsing) {
+                    TOKEN nextToken = NextToken;
+
+                    switch (nextToken) {
+                    case TOKEN.NONE:
+                        return null;
+                    case TOKEN.COMMA:
+                        continue;
+                    case TOKEN.SQUARED_CLOSE:
+                        parsing = false;
+                        break;
+                    default:
+                        object value = ParseByToken(nextToken);
+
+                        array.Add(value);
+                        break;
+                    }
+                }
+
+                return array;
+            }
+
+            object ParseValue() {
+                TOKEN nextToken = NextToken;
+                return ParseByToken(nextToken);
+            }
+
+            object ParseByToken(TOKEN token) {
+                switch (token) {
+                case TOKEN.STRING:
+                    return ParseString();
+                case TOKEN.NUMBER:
+                    return ParseNumber();
+                case TOKEN.CURLY_OPEN:
+                    return ParseObject();
+                case TOKEN.SQUARED_OPEN:
+                    return ParseArray();
+                case TOKEN.TRUE:
+                    return true;
+                case TOKEN.FALSE:
+                    return false;
+                case TOKEN.NULL:
+                    return null;
+                default:
+                    return null;
+                }
+            }
+
+            string ParseString() {
+                StringBuilder s = new StringBuilder();
+                char c;
+
+                // ditch opening quote
+                json.Read();
+
+                bool parsing = true;
+                while (parsing) {
+
+                    if (json.Peek() == -1) {
+                        parsing = false;
+                        break;
+                    }
+
+                    c = NextChar;
+                    switch (c) {
+                    case '"':
+                        parsing = false;
+                        break;
+                    case '\\':
+                        if (json.Peek() == -1) {
+                            parsing = false;
+                            break;
+                        }
+
+                        c = NextChar;
+                        switch (c) {
+                        case '"':
+                        case '\\':
+                        case '/':
+                            s.Append(c);
+                            break;
+                        case 'b':
+                            s.Append('\b');
+                            break;
+                        case 'f':
+                            s.Append('\f');
+                            break;
+                        case 'n':
+                            s.Append('\n');
+                            break;
+                        case 'r':
+                            s.Append('\r');
+                            break;
+                        case 't':
+                            s.Append('\t');
+                            break;
+                        case 'u':
+                            var hex = new char[4];
+
+                            for (int i=0; i< 4; i++) {
+                                hex[i] = NextChar;
+                            }
+
+                            s.Append((char) Convert.ToInt32(new string(hex), 16));
+                            break;
+                        }
+                        break;
+                    default:
+                        s.Append(c);
+                        break;
+                    }
+                }
+
+                return s.ToString();
+            }
+
+            object ParseNumber() {
+                string number = NextWord;
+
+                if (number.IndexOf('.') == -1) {
+                    long parsedInt;
+                    Int64.TryParse(number, out parsedInt);
+                    return parsedInt;
+                }
+
+                double parsedDouble;
+                Double.TryParse(number, out parsedDouble);
+                return parsedDouble;
+            }
+
+            void EatWhitespace() {
+                while (Char.IsWhiteSpace(PeekChar)) {
+                    json.Read();
+
+                    if (json.Peek() == -1) {
+                        break;
+                    }
+                }
+            }
+
+            char PeekChar {
+                get {
+                    return Convert.ToChar(json.Peek());
+                }
+            }
+
+            char NextChar {
+                get {
+                    return Convert.ToChar(json.Read());
+                }
+            }
+
+            string NextWord {
+                get {
+                    StringBuilder word = new StringBuilder();
+
+                    while (!IsWordBreak(PeekChar)) {
+                        word.Append(NextChar);
+
+                        if (json.Peek() == -1) {
+                            break;
+                        }
+                    }
+
+                    return word.ToString();
+                }
+            }
+
+            TOKEN NextToken {
+                get {
+                    EatWhitespace();
+
+                    if (json.Peek() == -1) {
+                        return TOKEN.NONE;
+                    }
+
+                    switch (PeekChar) {
+                    case '{':
+                        return TOKEN.CURLY_OPEN;
+                    case '}':
+                        json.Read();
+                        return TOKEN.CURLY_CLOSE;
+                    case '[':
+                        return TOKEN.SQUARED_OPEN;
+                    case ']':
+                        json.Read();
+                        return TOKEN.SQUARED_CLOSE;
+                    case ',':
+                        json.Read();
+                        return TOKEN.COMMA;
+                    case '"':
+                        return TOKEN.STRING;
+                    case ':':
+                        return TOKEN.COLON;
+                    case '0':
+                    case '1':
+                    case '2':
+                    case '3':
+                    case '4':
+                    case '5':
+                    case '6':
+                    case '7':
+                    case '8':
+                    case '9':
+                    case '-':
+                        return TOKEN.NUMBER;
+                    }
+
+                    switch (NextWord) {
+                    case "false":
+                        return TOKEN.FALSE;
+                    case "true":
+                        return TOKEN.TRUE;
+                    case "null":
+                        return TOKEN.NULL;
+                    }
+
+                    return TOKEN.NONE;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string
+        /// </summary>
+        /// <param name="json">A Dictionary&lt;string, object&gt; / List&lt;object&gt;</param>
+        /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>
+        public static string Serialize(object obj) {
+            return Serializer.Serialize(obj);
+        }
+
+        sealed class Serializer {
+            StringBuilder builder;
+
+            Serializer() {
+                builder = new StringBuilder();
+            }
+
+            public static string Serialize(object obj) {
+                var instance = new Serializer();
+
+                instance.SerializeValue(obj);
+
+                return instance.builder.ToString();
+            }
+
+            void SerializeValue(object value) {
+                IList asList;
+                IDictionary asDict;
+                string asStr;
+
+                if (value == null) {
+                    builder.Append("null");
+                } else if ((asStr = value as string) != null) {
+                    SerializeString(asStr);
+                } else if (value is bool) {
+                    builder.Append((bool) value ? "true" : "false");
+                } else if ((asList = value as IList) != null) {
+                    SerializeArray(asList);
+                } else if ((asDict = value as IDictionary) != null) {
+                    SerializeObject(asDict);
+                } else if (value is char) {
+                    SerializeString(new string((char) value, 1));
+                } else {
+                    SerializeOther(value);
+                }
+            }
+
+            void SerializeObject(IDictionary obj) {
+                bool first = true;
+
+                builder.Append('{');
+
+                foreach (object e in obj.Keys) {
+                    if (!first) {
+                        builder.Append(',');
+                    }
+
+                    SerializeString(e.ToString());
+                    builder.Append(':');
+
+                    SerializeValue(obj[e]);
+
+                    first = false;
+                }
+
+                builder.Append('}');
+            }
+
+            void SerializeArray(IList anArray) {
+                builder.Append('[');
+
+                bool first = true;
+
+                foreach (object obj in anArray) {
+                    if (!first) {
+                        builder.Append(',');
+                    }
+
+                    SerializeValue(obj);
+
+                    first = false;
+                }
+
+                builder.Append(']');
+            }
+
+            void SerializeString(string str) {
+                builder.Append('\"');
+
+                char[] charArray = str.ToCharArray();
+                foreach (var c in charArray) {
+                    switch (c) {
+                    case '"':
+                        builder.Append("\\\"");
+                        break;
+                    case '\\':
+                        builder.Append("\\\\");
+                        break;
+                    case '\b':
+                        builder.Append("\\b");
+                        break;
+                    case '\f':
+                        builder.Append("\\f");
+                        break;
+                    case '\n':
+                        builder.Append("\\n");
+                        break;
+                    case '\r':
+                        builder.Append("\\r");
+                        break;
+                    case '\t':
+                        builder.Append("\\t");
+                        break;
+                    default:
+                        int codepoint = Convert.ToInt32(c);
+                        if ((codepoint >= 32) && (codepoint <= 126)) {
+                            builder.Append(c);
+                        } else {
+                            builder.Append("\\u");
+                            builder.Append(codepoint.ToString("x4"));
+                        }
+                        break;
+                    }
+                }
+
+                builder.Append('\"');
+            }
+
+            void SerializeOther(object value) {
+                // NOTE: decimals lose precision during serialization.
+                // They always have, I'm just letting you know.
+                // Previously floats and doubles lost precision too.
+                if (value is float) {
+                    builder.Append(((float) value).ToString("R"));
+                } else if (value is int
+                    || value is uint
+                    || value is long
+                    || value is sbyte
+                    || value is byte
+                    || value is short
+                    || value is ushort
+                    || value is ulong) {
+                    builder.Append(value);
+                } else if (value is double
+                    || value is decimal) {
+                    builder.Append(Convert.ToDouble(value).ToString("R"));
+                } else {
+                    SerializeString(value.ToString());
+                }
+            }
+        }
+    }
+}

+ 11 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCcore/UQM/Utils/UQMMiniJSON.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5f7a61f19ec6f294a8c26f6050e199dd
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 23ccfd9225778c242b44692e9fa9540a
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 8e00bc6bd174cae4c869cf1b29186e43
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 103 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightAnrMonitor.cs

@@ -0,0 +1,103 @@
+using GCloud.UQM;
+using System;
+using System.Collections;
+using System.Threading;
+using UnityEngine;
+
+public class CrashSightAnrMonitor
+{
+    private static CrashSightMonoBehaviour monoBehaviour = CrashSightMonoBehaviour.Instance;
+    private static int anrTimeoutMs = 5000;
+    private static int detectionTimeoutMs = 1000;
+    protected static bool Paused { get; private set; } = false;
+    private static int ticksSinceUiUpdate = 0;
+    private static bool reported = false;
+    private static bool running = false;
+    private static Thread thread;
+
+    public static void Start(int timeoutMs = 5000)
+    {
+        if (running)
+        {
+            return;
+        }
+        else
+        {
+            running = true;
+        }
+        anrTimeoutMs = timeoutMs;
+        detectionTimeoutMs = Math.Max(1, anrTimeoutMs / 5);
+
+        monoBehaviour.ApplicationPausing += () => Paused = true;
+        monoBehaviour.ApplicationResuming += () => Paused = false;
+        monoBehaviour.ApplicationQuitting += () => Stop();
+
+        thread = new Thread(Run)
+        {
+            Name = "CrashSight-ANR-Monitor",
+            IsBackground = true,
+            Priority = System.Threading.ThreadPriority.BelowNormal,
+        };
+        thread.Start();
+        
+        monoBehaviour.StartCoroutine(UpdateUiStatus());
+    }
+    public static void Stop()
+    {
+        running = false;
+    }
+
+    private static IEnumerator UpdateUiStatus()
+    {
+        UQMCrash.SetEngineMainThread();
+        var waitForSeconds = new WaitForSecondsRealtime((float)detectionTimeoutMs / 1000);
+
+        yield return waitForSeconds;
+        while (running)
+        {
+            ticksSinceUiUpdate = 0;
+            reported = false;
+            yield return waitForSeconds;
+        }
+    }
+
+    private static void Run()
+    {
+        try
+        {
+            while (running)
+            {
+                ticksSinceUiUpdate += detectionTimeoutMs;
+                Thread.Sleep(detectionTimeoutMs);
+
+                if (Paused)
+                {
+                    ticksSinceUiUpdate = 0;
+                }
+                else if (ticksSinceUiUpdate >= anrTimeoutMs && !reported)
+                {
+                    Report();
+                    reported = true;
+                }
+            }
+        }
+        catch (Exception ex)
+        {
+            UQMLog.LogError("CrashSightAnrMonitor meets an unknown error = \n" + ex.Message + "\n" + ex.StackTrace);
+        }
+    }
+
+    private static void Report()
+    {
+        string message = $"Application not responding for at least {anrTimeoutMs} ms.";
+        UQMLog.Log(message);
+        UQMCrash.ProcessEngineAnr(1);
+    }
+}
+
+public class UnityAnrException : Exception
+{
+    internal UnityAnrException() : base() { }
+    internal UnityAnrException(string message) : base(message) { }
+    internal UnityAnrException(string message, Exception innerException) : base(message, innerException) { }
+}

+ 11 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightAnrMonitor.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: CSsd4XyqVCrqtX4M8fcfY8w0n3+HWxNxcb2zrOM5bUC+bPGxq5h3kmr538Nu
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 26 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightCallback.cs

@@ -0,0 +1,26 @@
+// ----------------------------------------
+//
+//  CrashSightCallbackDelegate.cs
+//
+//  Author:
+//       Yeelik,
+//
+//  Copyright (c) 2015 CrashSight.  All rights reserved.
+//
+// ----------------------------------------
+//
+
+public abstract class CrashSightCallback
+{
+	public abstract string OnCrashBaseRetEvent(int methodId, int crashType);
+
+}
+
+public abstract class CrashSightLogCallback
+{
+	public abstract string OnSetLogPathEvent(int methodId, int crashType);
+
+	public abstract void OnLogUploadResultEvent(int methodId, int crashType, int result);
+
+}
+

+ 11 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightCallback.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: ba1b54454a2619141b38d419338ee9aa
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 59 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightMonoBehavior.cs

@@ -0,0 +1,59 @@
+using System;
+using UnityEngine;
+
+[AddComponentMenu("")]
+public partial class CrashSightMonoBehaviour : MonoBehaviour
+{
+    private static CrashSightMonoBehaviour _instance;
+    public static CrashSightMonoBehaviour Instance
+    {
+        get
+        {
+            if (_instance == null)
+            {
+                var gameObject = new GameObject("CrashSightMonoBehaviour") { hideFlags = HideFlags.HideAndDontSave };
+                DontDestroyOnLoad(gameObject);
+                _instance = gameObject.AddComponent<CrashSightMonoBehaviour>();
+            }
+
+            return _instance;
+        }
+    }
+
+    public event Action ApplicationResuming;
+    
+    public event Action ApplicationPausing;
+
+    public event Action ApplicationQuitting;
+
+    internal bool _isRunning = true;
+    
+    public void UpdatePauseStatus(bool paused)
+    {
+        if (paused && _isRunning)
+        {
+            _isRunning = false;
+            ApplicationPausing?.Invoke();
+        }
+        else if (!paused && !_isRunning)
+        {
+            _isRunning = true;
+            ApplicationResuming?.Invoke();
+        }
+    }
+    
+    internal void OnApplicationPause(bool pauseStatus) => UpdatePauseStatus(pauseStatus);
+    
+    internal void OnApplicationFocus(bool hasFocus) => UpdatePauseStatus(!hasFocus);
+
+    private void OnApplicationQuit()
+    {
+        ApplicationQuitting?.Invoke();
+        Destroy(gameObject);
+    }
+
+    private void Awake()
+    {
+        DontDestroyOnLoad(gameObject);
+    }
+}

+ 11 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightMonoBehavior.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: CnMf4SKsWyqKRY6lSyBjy8yW9MbO4ec1eQn7d0ub5l816Bp81rEL/XYDSL2a
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 161 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightStackTrace.cs

@@ -0,0 +1,161 @@
+using AOT;
+using System;
+using System.Runtime.InteropServices;
+using UnityEngine;
+
+// 使用前请先打开ENABLE_CRASHSIGHT_STACKTRACE宏
+public class CrashSightStackTrace
+{
+    public static bool enable = false;
+
+    //CrashSightStackTrace开关,仅在il2cpp编译时允许打开
+    public static void setEnable(bool enable)
+    {
+#if ENABLE_IL2CPP && ENABLE_CRASHSIGHT_STACKTRACE
+        CrashSightStackTrace.enable = enable;
+#endif
+    }
+
+#if UNITY_ANDROID
+    public const string lib = "il2cpp";
+#elif UNITY_IOS
+    public const string lib = "__Internal";
+#endif
+
+#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR && ENABLE_IL2CPP && ENABLE_CRASHSIGHT_STACKTRACE
+    [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+    public static extern void il2cpp_current_thread_walk_frame_stack(Il2CppFrameWalkFunc func, IntPtr data);
+
+    [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+    public static extern IntPtr il2cpp_method_get_name(IntPtr method);
+
+    [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+    public static extern int il2cpp_method_get_param_count(IntPtr method);
+
+    [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+    public static extern IntPtr il2cpp_method_get_class(IntPtr method);
+
+    [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+    public static extern IntPtr il2cpp_method_get_param(IntPtr method, int index);
+
+    [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+    public static extern IntPtr il2cpp_class_get_name(IntPtr klass);
+
+    [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+    public static extern IntPtr il2cpp_class_get_namespace(IntPtr klass);
+
+    [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+    public static extern IntPtr il2cpp_type_get_name(IntPtr type);
+
+    [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+    public static extern IntPtr il2cpp_class_get_declaring_type(IntPtr klass);
+
+    [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+    public static extern IntPtr il2cpp_class_from_il2cpp_type(IntPtr type);
+
+#if UNITY_2018_1_OR_NEWER
+    [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+    public static extern bool il2cpp_type_is_byref(IntPtr type);
+#endif
+
+    //type结构体,用于直接读取指针指向的内容,能不用则不用,尽量使用il2cpp的API
+    public struct Il2CppType
+    {
+        public IntPtr unionData;
+        public Int16 attrs;
+        public Byte type;
+        public Byte num_mods; 
+        public bool byref()
+        {
+            return (num_mods & 64) != 0;//0b01000000
+        }
+    };
+
+    public delegate void Il2CppFrameWalkFunc(IntPtr info, IntPtr user_data);
+
+    //FrameWalk回调,每次处理一帧的信息
+    [MonoPInvokeCallback(typeof(Il2CppFrameWalkFunc))]
+    public static void Il2CppFrameWalkFuncImp(IntPtr info, IntPtr data)
+    {
+        string stackFrame = "";
+        IntPtr method = (IntPtr)Marshal.PtrToStructure(info, typeof(IntPtr));
+        string name = Marshal.PtrToStringAnsi(il2cpp_method_get_name(method));
+        IntPtr klass = il2cpp_method_get_class(method);
+        string klassName = Marshal.PtrToStringAnsi(il2cpp_class_get_name(klass));
+        string klassNamespaze = Marshal.PtrToStringAnsi(il2cpp_class_get_namespace(klass));
+
+        //模板类等,额外执行命名空间查找
+        if(string.IsNullOrEmpty(klassNamespaze))
+        {
+            IntPtr declaring_type = il2cpp_class_get_declaring_type(klass);
+            if (declaring_type != IntPtr.Zero)
+            {
+                klassNamespaze = Marshal.PtrToStringAnsi(il2cpp_class_get_namespace(declaring_type));
+            }
+        }
+
+        if (!string.IsNullOrEmpty(klassNamespaze))
+            stackFrame += klassNamespaze + ".";
+        stackFrame += klassName + ":" + name + "(";
+
+        //遍历参数
+        int paraCount = il2cpp_method_get_param_count(method);
+        for (int i = 0; i < paraCount; i++)
+        {
+            if (i != 0)
+            {
+                stackFrame += ", ";
+            }
+            IntPtr type = il2cpp_method_get_param(method, i);
+            IntPtr typeClass = il2cpp_class_from_il2cpp_type(type);
+            string typeName = Marshal.PtrToStringAnsi(il2cpp_class_get_name(typeClass));
+            stackFrame += typeName;
+#if UNITY_2018_1_OR_NEWER
+            //il2cpp_type_is_byref可用时,直接使用它判断参数是否为引用
+            bool byref = il2cpp_type_is_byref(type);
+            if (byref)
+            {
+                stackFrame += "&";
+            }
+#else
+            //il2cpp_type_is_byref不可用时,只能通过指针访问结构(可能不安全)
+            Il2CppType typeimpl = (Il2CppType)Marshal.PtrToStructure(type, typeof(Il2CppType));
+            if (typeimpl.byref())
+            {
+                stackFrame += "&";
+            }
+#endif
+        }
+        stackFrame += ")\n";
+        stackTrace = stackFrame + stackTrace;
+    }
+#endif
+
+    static string stackTrace;
+    
+    //stacktrace入口,默认使用StackTraceUtility.ExtractStackTrace(),需要setEnable来切换到CrashSightStackTrace
+    public static string ExtractStackTrace()
+    {
+        if (!enable)
+        {
+            return StackTraceUtility.ExtractStackTrace();
+        }
+        stackTrace = string.Empty;
+#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR && ENABLE_IL2CPP && ENABLE_CRASHSIGHT_STACKTRACE
+        il2cpp_current_thread_walk_frame_stack(Il2CppFrameWalkFuncImp, new IntPtr());
+
+        //有些il2cpp版本会把il2cpp_current_thread_walk_frame_stack打出来,有些则不会,判断并丢弃
+        int line1 = stackTrace.IndexOf('\n');
+        int line2 = stackTrace.IndexOf('\n', line1 + 1);
+        if (stackTrace.Substring(0, line1) == "CrashSightStackTrace:ExtractStackTrace()")
+        {
+            stackTrace = stackTrace.Substring(line1 + 1);
+        }
+        else
+        {
+            stackTrace = stackTrace.Substring(line2 + 1);
+        }
+#endif
+        return stackTrace;
+    }
+}

+ 11 - 0
Assets/Scripts/ThirdParty/CrashSight/Scripts/UQMCrashSight/CrashSight/CrashSightStackTrace.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 134a5ecbf5aa66d4d9214b3669828a24
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 37 - 26
Assets/Scripts/ThirdParty/Crasheye/Crasheye.cs

@@ -1,10 +1,11 @@
 /**
  *  Unity Plugins Version   2.2.10
- *  
+ *
  *      android version     2.2.9
  *      iOS version         2.7.3
  *      window version      1.0.0
  */
+
 using System.Text;
 using UnityEngine;
 using System.Collections;
@@ -29,7 +30,7 @@ using com.xsj.Crasheye.U3D.IOS;
 public class Crasheye : MonoBehaviour
 {
     public delegate void FnOnCrashCallback(bool bCaptureSucceed, string cpszCrashReportFile);
-    
+
     public string YourAppKeyForAndroid = "YourAppKeyForAndroid";
     public string YourChannelIdForAndroid = "YourChannelIdForAndroid";
 
@@ -42,7 +43,7 @@ public class Crasheye : MonoBehaviour
 #if UNITY_ANDROID || UNITY_IPHONE || UNITY_IOS
     public static CrasheyeLib crasheyeLib = null;
 #endif
-    
+
 #if UNITY_ANDROID || UNITY_IPHONE || UNITY_IOS || UNITY_STANDALONE_WIN
     private static string YourChannelId = "NA";
 #endif
@@ -70,6 +71,12 @@ public class Crasheye : MonoBehaviour
 #if UNITY_ANDROID
             SetChannelID(YourChannelIdForAndroid);
             StartInitCrasheye(YourAppKeyForAndroid);
+            CrashSightAgent.ConfigDebugMode(false);
+            // 设置上报的目标域名,请根据项目需求进行填写。(必填)
+            CrashSightAgent.ConfigCrashServerUrl("https://android.crashsight.qq.com/pb/async");
+            CrashSightAgent.ConfigCrashReporter(1);
+            // 设置上报所指向的APP ID, 并进行初始化。APPID可以在管理端更多->产品设置->产品信息中找到。
+            CrashSightAgent.InitWithAppId("3115889696");
 #endif
         }
         else if (Application.platform == RuntimePlatform.IPhonePlayer)
@@ -113,7 +120,7 @@ public class Crasheye : MonoBehaviour
 #endif
         }
     }
-    
+
     /// <summary>
     ///  设置Dump是否强制上报(忽略玩家在DumpReport界面上的选择)
     ///
@@ -122,18 +129,19 @@ public class Crasheye : MonoBehaviour
     public static void SetForceUpload(bool isForceUpload)
     {
         Debug.Log("SetForceUpload");
-#if UNITY_STANDALONE_WIN  && !UNITY_EDITOR
+#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
         DumpForPC.SetForceUpload(isForceUpload);
 #endif
     }
+
     /// <summary>
     /// 启动Crasheye
     /// </summary>
     /// <param name="Your_AppKey"></param>
     public static void StartInitCrasheye(string Your_AppKey)
-    {        
+    {
         RegisterLogCallback();
-        
+
         if (Application.platform == RuntimePlatform.Android)
         {
 #if UNITY_ANDROID
@@ -148,7 +156,7 @@ public class Crasheye : MonoBehaviour
         }
         else if (Application.platform == RuntimePlatform.WindowsPlayer)
         {
-#if UNITY_STANDALONE_WIN  && !UNITY_EDITOR
+#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
             DumpForPC.Init(Your_AppKey, YourChannelId);
 #endif
         }
@@ -178,7 +186,7 @@ public class Crasheye : MonoBehaviour
         }
         else if (Application.platform == RuntimePlatform.WindowsPlayer)
         {
-#if UNITY_STANDALONE_WIN  && !UNITY_EDITOR
+#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
             Debug.Log("RegisterLogCallback");
             AppDomain.CurrentDomain.UnhandledException += DumpForPC.OnHandleUnresolvedException;
             SetRegisterLogFunction(DumpForPC.OnHandleLogCallback);
@@ -192,14 +200,15 @@ public class Crasheye : MonoBehaviour
             return;
         }
 
-        System.AppDomain.CurrentDomain.UnhandledException += new System.UnhandledExceptionEventHandler(crasheyeLib.OnHandleUnresolvedException);
+        System.AppDomain.CurrentDomain.UnhandledException +=
+            new System.UnhandledExceptionEventHandler(crasheyeLib.OnHandleUnresolvedException);
 
         SetRegisterLogFunction(crasheyeLib.OnHandleLogCallback);
 
 #if UNITY_5
                 Application.logMessageReceived += RegisterLogFunction;
 #else
-                Application.RegisterLogCallback(RegisterLogFunction);
+        Application.RegisterLogCallback(RegisterLogFunction);
 #endif
 #endif
     }
@@ -238,8 +247,9 @@ public class Crasheye : MonoBehaviour
     }
 
     public delegate void RegisterLog(string logString, string stackTrace, LogType type);
+
     private static RegisterLog m_RegisterLog = null;
-   
+
     /// <summary>
     /// 设置用户的脚本回调的函数
     /// </summary>
@@ -249,13 +259,13 @@ public class Crasheye : MonoBehaviour
         Debug.Log("SetRegisterLogFunction");
         m_RegisterLog += registerLogCBFun;
     }
-    
+
     /// <summary>
     /// 发送脚本异常
     /// </summary>
     /// <param name="ex">Excepiton Info</param>
     public static void SendScriptException(Exception ex)
-    {        
+    {
         if (Application.platform == RuntimePlatform.Android)
         {
 #if UNITY_ANDROID
@@ -284,19 +294,20 @@ public class Crasheye : MonoBehaviour
             crasheyeLib.LibSendScriptException(errorTitle, stacktrace, language);
 #endif
         }
-        else if(Application.platform == RuntimePlatform.IPhonePlayer)
+        else if (Application.platform == RuntimePlatform.IPhonePlayer)
         {
 #if UNITY_IPHONE || UNITY_IOS
             crasheyeLib.LibSendScriptException(errorTitle, stacktrace);
 #endif
-        } else if (Application.platform == RuntimePlatform.WindowsPlayer)
+        }
+        else if (Application.platform == RuntimePlatform.WindowsPlayer)
         {
-#if UNITY_STANDALONE_WIN  && !UNITY_EDITOR
+#if UNITY_STANDALONE_WIN && !UNITY_EDITOR
             DumpForPC.SendScriptException(errorTitle, stacktrace, language);
 #endif
         }
     }
-    
+
     /// <summary>
     /// 设置渠道号
     /// </summary>
@@ -398,7 +409,7 @@ public class Crasheye : MonoBehaviour
     /// <param name="setUserIdentifier">用户标识</param>
     public static void SetUserIdentifier(string userIdentifier)
     {
-        if(string.IsNullOrEmpty(userIdentifier))
+        if (string.IsNullOrEmpty(userIdentifier))
         {
             return;
         }
@@ -529,7 +540,7 @@ public class Crasheye : MonoBehaviour
             CrasheyeForAndroid.RemoveExtraData(key);
 #endif
         }
-        else if(Application.platform == RuntimePlatform.IPhonePlayer)
+        else if (Application.platform == RuntimePlatform.IPhonePlayer)
         {
 #if UNITY_IPHONE || UNITY_IOS
             CrasheyeForIOS.RemoveExtraData(key);
@@ -604,7 +615,8 @@ public class Crasheye : MonoBehaviour
 #if UNITY_IPHONE || UNITY_IOS
             CrasheyeForIOS.LeaveBreadcrumb(breadcrumb);
 #endif
-        } else if (Application.platform == RuntimePlatform.WindowsPlayer)
+        }
+        else if (Application.platform == RuntimePlatform.WindowsPlayer)
         {
 #if UNITY_STANDALONE_WIN && !UNITY_EDITOR
             DumpForPC.leaveBreadcrumb(breadcrumb);
@@ -669,7 +681,7 @@ public class Crasheye : MonoBehaviour
             CrasheyeForAndroid.SetLogging(lines, filter);
 #endif
         }
-        else if(Application.platform == RuntimePlatform.IPhonePlayer)
+        else if (Application.platform == RuntimePlatform.IPhonePlayer)
         {
 #if UNITY_IPHONE || UNITY_IOS
             CrasheyeForIOS.SetLogging(lines, filter);
@@ -695,21 +707,20 @@ public class Crasheye : MonoBehaviour
             return CrasheyeForIOS.GetAppVersion();
 #endif
         }
+
         return "NA";
     }
 
     public static bool SetBackgroundUpload(bool isBackgroundUpload)
     {
-        
 #if UNITY_STANDALONE_WIN && !UNITY_EDITOR
         return DumpForPC.SetBackgroundUpload(isBackgroundUpload);
 #endif
         return false;
     }
-    
+
     public static bool SetCrashCallback(FnOnCrashCallback pCallback)
     {
-
 #if UNITY_STANDALONE_WIN && !UNITY_EDITOR
         return DumpForPC.SetOnMiniDumpCreateCallBack((bCaptureSucceed, cpszCrashReportFile)=>{
             string  szCrashReportFile = Marshal.PtrToStringUni(cpszCrashReportFile);
@@ -718,7 +729,7 @@ public class Crasheye : MonoBehaviour
 #endif
         return false;
     }
-    
+
     public static bool PushLogTrace(string cpszMessage)
     {
 #if UNITY_STANDALONE_WIN && !UNITY_EDITOR

+ 2 - 1
Assets/Scripts/ThirdParty/Crasheye/CrasheyeForUnityLib.asmdef

@@ -1,3 +1,4 @@
 {
-	"name": "CrasheyeForUnityLib"
+	"name": "CrasheyeForUnityLib",
+	"references":[ "ThirdParty" ]
 }

+ 11 - 0
Assets/Settings/rpAsset.asset

@@ -73,6 +73,13 @@ MonoBehaviour:
   m_ColorGradingLutSize: 32
   m_UseFastSRGBLinearConversion: 0
   m_SupportDataDrivenLensFlare: 1
+  m_PostProcessPreserveAlpha: 0
+  m_GPUResidentDrawerStat: 0
+  m_GRDEnableCollectTransform: 1
+  m_GRDEnableCollectLightMap: 0
+  m_GRDEnableCollectLightProbe: 0
+  m_GRDEnableCollectMotionVector: 0
+  m_BRGShaderVariantStorageStripType: 0
   m_ShadowType: 1
   m_LocalShadowsSupported: 0
   m_LocalShadowsAtlasResolution: 256
@@ -82,6 +89,7 @@ MonoBehaviour:
   m_Textures:
     blueNoise64LTex: {fileID: 2800000, guid: e3d24661c1e055f45a7560c033dbb837, type: 3}
     bayerMatrixTex: {fileID: 2800000, guid: f9ee4ed84c1d10c49aabb9b210b0fc44, type: 3}
+  testURPForceGRD: 0
   m_PrefilteringModeMainLightShadows: 3
   m_PrefilteringModeAdditionalLight: 3
   m_PrefilteringModeAdditionalLightShadows: 2
@@ -110,5 +118,8 @@ MonoBehaviour:
   m_PrefilterSoftShadows: 0
   m_PrefilterScreenCoord: 1
   m_PrefilterNativeRenderPass: 1
+  m_PrefilterPreserveAlpha: 1
+  m_PrefilterUseLightmapSingle: 0
+  m_PrefilterBRGVariantStorageStrip: 0
   m_ShaderVariantLogLevel: 0
   m_ShadowCascades: 0

+ 5 - 5
Packages/manifest.json

@@ -16,17 +16,17 @@
     "com.unity.entities": "1.0.16",
     "com.unity.entities.graphics": "1.0.16",
     "com.unity.feature.2d": "2.0.1",
-    "com.unity.ide.rider": "3.0.31",
+    "com.unity.ide.rider": "3.0.35",
     "com.unity.ide.visualstudio": "2.0.22",
     "com.unity.ide.vscode": "1.2.5",
-    "com.unity.memoryprofiler": "1.1.1",
+    "com.unity.memoryprofiler": "1.1.6",
     "com.unity.recorder": "4.0.3",
-    "com.unity.render-pipelines.universal": "14.0.11",
+    "com.unity.render-pipelines.universal": "14.1.0",
     "com.unity.test-framework": "1.1.33",
-    "com.unity.timeline": "1.7.6",
+    "com.unity.timeline": "1.7.7",
     "com.unity.ugui": "1.0.0",
     "com.unity.visualscripting": "1.9.4",
-    "com.unity.xr.legacyinputhelpers": "2.1.10",
+    "com.unity.xr.legacyinputhelpers": "2.1.12",
     "com.unity.modules.ai": "1.0.0",
     "com.unity.modules.androidjni": "1.0.0",
     "com.unity.modules.animation": "1.0.0",

+ 49 - 46
Packages/packages-lock.json

@@ -70,11 +70,11 @@
       }
     },
     "com.unity.2d.animation": {
-      "version": "9.1.2",
+      "version": "9.2.0",
       "depth": 1,
       "source": "registry",
       "dependencies": {
-        "com.unity.2d.common": "8.0.3",
+        "com.unity.2d.common": "8.1.0",
         "com.unity.2d.sprite": "1.0.0",
         "com.unity.collections": "1.1.0",
         "com.unity.modules.animation": "1.0.0",
@@ -83,19 +83,19 @@
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.2d.aseprite": {
-      "version": "1.1.6",
+      "version": "1.1.8",
       "depth": 1,
       "source": "registry",
       "dependencies": {
-        "com.unity.2d.sprite": "1.0.0",
         "com.unity.2d.common": "6.0.6",
+        "com.unity.2d.sprite": "1.0.0",
         "com.unity.mathematics": "1.2.6",
         "com.unity.modules.animation": "1.0.0"
       },
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.2d.common": {
-      "version": "8.0.3",
+      "version": "8.1.0",
       "depth": 2,
       "source": "registry",
       "dependencies": {
@@ -108,20 +108,22 @@
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.2d.pixel-perfect": {
-      "version": "5.0.3",
+      "version": "5.1.0",
       "depth": 1,
       "source": "registry",
-      "dependencies": {},
+      "dependencies": {
+        "com.unity.modules.imgui": "1.0.0"
+      },
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.2d.psdimporter": {
-      "version": "8.0.5",
+      "version": "8.1.0",
       "depth": 1,
       "source": "registry",
       "dependencies": {
-        "com.unity.2d.animation": "9.1.1",
-        "com.unity.2d.common": "8.0.2",
-        "com.unity.2d.sprite": "1.0.0"
+        "com.unity.2d.common": "8.1.0",
+        "com.unity.2d.sprite": "1.0.0",
+        "com.unity.2d.animation": "9.2.0"
       },
       "url": "https://packages.tuanjie.cn"
     },
@@ -132,12 +134,12 @@
       "dependencies": {}
     },
     "com.unity.2d.spriteshape": {
-      "version": "9.0.4",
+      "version": "9.1.0",
       "depth": 1,
       "source": "registry",
       "dependencies": {
+        "com.unity.2d.common": "8.1.0",
         "com.unity.mathematics": "1.1.0",
-        "com.unity.2d.common": "8.0.3",
         "com.unity.modules.physics2d": "1.0.0"
       },
       "url": "https://packages.tuanjie.cn"
@@ -152,13 +154,13 @@
       }
     },
     "com.unity.2d.tilemap.extras": {
-      "version": "3.1.2",
+      "version": "3.1.3",
       "depth": 1,
       "source": "registry",
       "dependencies": {
-        "com.unity.modules.tilemap": "1.0.0",
-        "com.unity.2d.tilemap": "1.0.0",
         "com.unity.ugui": "1.0.0",
+        "com.unity.2d.tilemap": "1.0.0",
+        "com.unity.modules.tilemap": "1.0.0",
         "com.unity.modules.jsonserialize": "1.0.0"
       },
       "url": "https://packages.tuanjie.cn"
@@ -183,7 +185,7 @@
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.burst": {
-      "version": "1.8.17",
+      "version": "1.8.19",
       "depth": 1,
       "source": "registry",
       "dependencies": {
@@ -266,18 +268,18 @@
       "depth": 0,
       "source": "builtin",
       "dependencies": {
-        "com.unity.2d.animation": "9.1.2",
-        "com.unity.2d.pixel-perfect": "5.0.3",
-        "com.unity.2d.psdimporter": "8.0.5",
+        "com.unity.2d.animation": "9.2.0",
+        "com.unity.2d.pixel-perfect": "5.1.0",
+        "com.unity.2d.psdimporter": "8.1.0",
         "com.unity.2d.sprite": "1.0.0",
-        "com.unity.2d.spriteshape": "9.0.4",
+        "com.unity.2d.spriteshape": "9.1.0",
         "com.unity.2d.tilemap": "1.0.0",
-        "com.unity.2d.tilemap.extras": "3.1.2",
-        "com.unity.2d.aseprite": "1.1.6"
+        "com.unity.2d.tilemap.extras": "3.1.3",
+        "com.unity.2d.aseprite": "1.1.8"
       }
     },
     "com.unity.ide.rider": {
-      "version": "3.0.31",
+      "version": "3.0.35",
       "depth": 0,
       "source": "registry",
       "dependencies": {
@@ -309,11 +311,15 @@
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.memoryprofiler": {
-      "version": "1.1.1",
+      "version": "1.1.6",
       "depth": 0,
       "source": "registry",
       "dependencies": {
-        "com.unity.editorcoroutines": "1.0.0"
+        "com.unity.editorcoroutines": "1.0.0",
+        "com.unity.collections": "1.2.3",
+        "com.unity.mathematics": "1.2.1",
+        "com.unity.burst": "1.8.0",
+        "com.unity.profiling.core": "1.0.0"
       },
       "url": "https://packages.tuanjie.cn"
     },
@@ -348,7 +354,7 @@
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.render-pipelines.core": {
-      "version": "14.0.11",
+      "version": "14.1.0",
       "depth": 1,
       "source": "builtin",
       "dependencies": {
@@ -359,14 +365,14 @@
       }
     },
     "com.unity.render-pipelines.universal": {
-      "version": "14.0.11",
+      "version": "14.1.0",
       "depth": 0,
       "source": "builtin",
       "dependencies": {
         "com.unity.mathematics": "1.2.1",
         "com.unity.burst": "1.8.9",
-        "com.unity.render-pipelines.core": "14.0.11",
-        "com.unity.shadergraph": "14.0.11",
+        "com.unity.render-pipelines.core": "14.1.0",
+        "com.unity.shadergraph": "14.1.0",
         "com.unity.render-pipelines.universal-config": "14.0.9"
       }
     },
@@ -379,7 +385,7 @@
       }
     },
     "com.unity.scriptablebuildpipeline": {
-      "version": "1.21.24",
+      "version": "1.21.25",
       "depth": 1,
       "source": "registry",
       "dependencies": {},
@@ -403,33 +409,33 @@
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.services.analytics": {
-      "version": "5.0.0",
+      "version": "6.0.3",
       "depth": 1,
       "source": "registry",
       "dependencies": {
         "com.unity.ugui": "1.0.0",
-        "com.unity.modules.jsonserialize": "1.0.0",
-        "com.unity.services.core": "1.10.1"
+        "com.unity.services.core": "1.12.4",
+        "com.unity.modules.jsonserialize": "1.0.0"
       },
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.services.core": {
-      "version": "1.12.5",
+      "version": "1.14.0",
       "depth": 2,
       "source": "registry",
       "dependencies": {
-        "com.unity.modules.unitywebrequest": "1.0.0",
+        "com.unity.modules.androidjni": "1.0.0",
         "com.unity.nuget.newtonsoft-json": "3.2.1",
-        "com.unity.modules.androidjni": "1.0.0"
+        "com.unity.modules.unitywebrequest": "1.0.0"
       },
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.shadergraph": {
-      "version": "14.0.11",
+      "version": "14.1.0",
       "depth": 1,
       "source": "builtin",
       "dependencies": {
-        "com.unity.render-pipelines.core": "14.0.11",
+        "com.unity.render-pipelines.core": "14.1.0",
         "com.unity.searcher": "4.9.2"
       }
     },
@@ -464,13 +470,13 @@
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.timeline": {
-      "version": "1.7.6",
+      "version": "1.7.7",
       "depth": 0,
       "source": "registry",
       "dependencies": {
+        "com.unity.modules.audio": "1.0.0",
         "com.unity.modules.director": "1.0.0",
         "com.unity.modules.animation": "1.0.0",
-        "com.unity.modules.audio": "1.0.0",
         "com.unity.modules.particlesystem": "1.0.0"
       },
       "url": "https://packages.tuanjie.cn"
@@ -495,7 +501,7 @@
       "url": "https://packages.tuanjie.cn"
     },
     "com.unity.xr.legacyinputhelpers": {
-      "version": "2.1.10",
+      "version": "2.1.12",
       "depth": 0,
       "source": "registry",
       "dependencies": {
@@ -526,10 +532,7 @@
       "version": "1.0.0",
       "depth": 0,
       "source": "builtin",
-      "dependencies": {
-        "com.unity.modules.audio": "1.0.0",
-        "com.unity.modules.animation": "1.0.0"
-      }
+      "dependencies": {}
     },
     "com.unity.modules.audio": {
       "version": "1.0.0",

+ 3 - 3
ProjectSettings/ProjectVersion.txt

@@ -1,3 +1,3 @@
-m_EditorVersion: 2022.3.48t6
-m_EditorVersionWithRevision: 2022.3.48t6 (b281c1694403)
-m_TuanjieEditorVersion: 1.4.3
+m_EditorVersion: 2022.3.61t8
+m_EditorVersionWithRevision: 2022.3.61t8 (4d1c4dc33c81)
+m_TuanjieEditorVersion: 1.6.7

+ 32 - 0
ProjectSettings/ThreadInfoSettings.asset

@@ -0,0 +1,32 @@
+%YAML 1.1
+%TAG !u! tag:yousandi.cn,2023:
+--- !u!9625 &1
+ThreadInfoSettings:
+  m_ObjectHideFlags: 0
+  m_TargetPlatform: 0
+  m_HMIAndroidPlatformThreadInfoSettings:
+    m_BasePlatformThreadInfoSettings:
+      m_MainThreadPriority: -2
+      m_JobWorkerThreadPriority: 0
+      m_GFXDeviceWorkerThreadPriority: -2
+      m_MainThreadAffinity: 2
+      m_JobWorkerThreadAffinity: 2
+      m_GFXDeviceWorkerThreadAffinity: 2
+    m_AndroidChoreographerThreadPriority: 0
+    m_AndroidChoreographerThreadAffinity: 0
+  m_EmbeddedLinuxPlatformThreadInfoSettings:
+    m_BasePlatformThreadInfoSettings:
+      m_MainThreadPriority: 0
+      m_JobWorkerThreadPriority: 0
+      m_GFXDeviceWorkerThreadPriority: -2
+      m_MainThreadAffinity: 2
+      m_JobWorkerThreadAffinity: 0
+      m_GFXDeviceWorkerThreadAffinity: 2
+  m_QnxPlatformThreadInfoSettings:
+    m_BasePlatformThreadInfoSettings:
+      m_MainThreadPriority: 10
+      m_JobWorkerThreadPriority: 10
+      m_GFXDeviceWorkerThreadPriority: 50
+      m_MainThreadAffinity: 2
+      m_JobWorkerThreadAffinity: 0
+      m_GFXDeviceWorkerThreadAffinity: 2