Przeglądaj źródła

广告SDK加入

lzx 5 dni temu
rodzic
commit
c8b4fcacfc
100 zmienionych plików z 5491 dodań i 1 usunięć
  1. 8 0
      Assets/AnyThinkPlugin.meta
  2. 8 0
      Assets/AnyThinkPlugin/Resources.meta
  3. 8 0
      Assets/AnyThinkPlugin/Resources/Images.meta
  4. BIN
      Assets/AnyThinkPlugin/Resources/Images/alert_icon.png
  5. 92 0
      Assets/AnyThinkPlugin/Resources/Images/alert_icon.png.meta
  6. BIN
      Assets/AnyThinkPlugin/Resources/Images/uninstall_icon.png
  7. 92 0
      Assets/AnyThinkPlugin/Resources/Images/uninstall_icon.png.meta
  8. BIN
      Assets/AnyThinkPlugin/Resources/Images/warning_icon.png
  9. 92 0
      Assets/AnyThinkPlugin/Resources/Images/warning_icon.png.meta
  10. 8 0
      Assets/AnyThinkPlugin/Resources/json.meta
  11. 8 0
      Assets/AnyThinkPlugin/Resources/json/2.1.5.meta
  12. 1 0
      Assets/AnyThinkPlugin/Resources/json/2.1.5/plugin_hot_fix_data.json
  13. 7 0
      Assets/AnyThinkPlugin/Resources/json/2.1.5/plugin_hot_fix_data.json.meta
  14. 1 0
      Assets/AnyThinkPlugin/Resources/json/2.1.5/plugin_setting_data.json
  15. 7 0
      Assets/AnyThinkPlugin/Resources/json/2.1.5/plugin_setting_data.json.meta
  16. 8 0
      Assets/AnyThinkPlugin/Script.meta
  17. 8 0
      Assets/AnyThinkPlugin/Script/Editor.meta
  18. 330 0
      Assets/AnyThinkPlugin/Script/Editor/ATPostProcessBuildAndroid.cs
  19. 11 0
      Assets/AnyThinkPlugin/Script/Editor/ATPostProcessBuildAndroid.cs.meta
  20. 234 0
      Assets/AnyThinkPlugin/Script/Editor/ATPostProcessBuildiOS.cs
  21. 11 0
      Assets/AnyThinkPlugin/Script/Editor/ATPostProcessBuildiOS.cs.meta
  22. 354 0
      Assets/AnyThinkPlugin/Script/Editor/ATProcessBuildGradleAndroid.cs
  23. 11 0
      Assets/AnyThinkPlugin/Script/Editor/ATProcessBuildGradleAndroid.cs.meta
  24. 11 0
      Assets/AnyThinkPlugin/Script/Editor/AnyThinkPlugin.Script.Editor.asmdef
  25. 7 0
      Assets/AnyThinkPlugin/Script/Editor/AnyThinkPlugin.Script.Editor.asmdef.meta
  26. 4 0
      Assets/AnyThinkPlugin/Script/Editor/anythink_network_security_config.xml
  27. 7 0
      Assets/AnyThinkPlugin/Script/Editor/anythink_network_security_config.xml.meta
  28. 8 0
      Assets/AnyThinkPlugin/Script/IntegrationManager.meta
  29. 8 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor.meta
  30. 47 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATAssetPostprocessor.cs
  31. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATAssetPostprocessor.cs.meta
  32. 426 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATConfig.cs
  33. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATConfig.cs.meta
  34. 355 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATDataUtil.cs
  35. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATDataUtil.cs.meta
  36. 66 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATDownloadHandler.cs
  37. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATDownloadHandler.cs.meta
  38. 74 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATEditorCoroutine.cs
  39. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATEditorCoroutine.cs.meta
  40. 447 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntegrationManager.cs
  41. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntegrationManager.cs.meta
  42. 860 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntegrationManagerWindow.cs
  43. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntegrationManagerWindow.cs.meta
  44. 164 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntergrationHotFix.cs
  45. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntergrationHotFix.cs.meta
  46. 37 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATLog.cs
  47. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATLog.cs.meta
  48. 37 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATMenuItems.cs
  49. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATMenuItems.cs.meta
  50. 39 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATNetInfo.cs
  51. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATNetInfo.cs.meta
  52. 220 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATPluginLocalDataModel.cs
  53. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATPluginLocalDataModel.cs.meta
  54. 36 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATSdkUtil.cs
  55. 11 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATSdkUtil.cs.meta
  56. 10 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/AnyThinkPlugin.IntegrationManager.Editor.asmdef
  57. 7 0
      Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/AnyThinkPlugin.IntegrationManager.Editor.asmdef.meta
  58. 8 0
      Assets/ExternalDependencyManager.meta
  59. 8 0
      Assets/ExternalDependencyManager/Editor.meta
  60. 8 0
      Assets/ExternalDependencyManager/Editor/1.2.177.meta
  61. BIN
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll
  62. BIN
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll.mdb
  63. 13 0
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll.mdb.meta
  64. 36 0
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll.meta
  65. BIN
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll
  66. BIN
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll.mdb
  67. 13 0
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll.mdb.meta
  68. 36 0
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll.meta
  69. BIN
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll
  70. BIN
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll.mdb
  71. 13 0
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll.mdb.meta
  72. 36 0
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll.meta
  73. BIN
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll
  74. BIN
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll.mdb
  75. 13 0
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll.mdb.meta
  76. 36 0
      Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll.meta
  77. BIN
      Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll
  78. BIN
      Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll.mdb
  79. 12 0
      Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll.mdb.meta
  80. 36 0
      Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll.meta
  81. 13 0
      Assets/ExternalDependencyManager/Editor/external-dependency-manager_version-1.2.177_manifest.txt
  82. 15 0
      Assets/ExternalDependencyManager/Editor/external-dependency-manager_version-1.2.177_manifest.txt.meta
  83. 8 0
      Assets/Plugins/Android.meta
  84. 2 1
      Assets/Scripts/GameLogic/Fort23.GameLogic.asmdef
  85. 8 0
      Assets/Scripts/GameLogic/SDK.meta
  86. 143 0
      Assets/Scripts/GameLogic/SDK/TakuSDKManager.cs
  87. 11 0
      Assets/Scripts/GameLogic/SDK/TakuSDKManager.cs.meta
  88. 8 0
      Assets/Scripts/ThirdParty/AnyThinkAds.meta
  89. 8 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api.meta
  90. 218 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATAdEventArgs.cs
  91. 11 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATAdEventArgs.cs.meta
  92. 130 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATBannerAd.cs
  93. 11 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATBannerAd.cs.meta
  94. 57 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATBannerAdListener.cs
  95. 11 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATBannerAdListener.cs.meta
  96. 189 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATCallbackInfo.cs
  97. 11 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATCallbackInfo.cs.meta
  98. 25 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATConst.cs
  99. 11 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATConst.cs.meta
  100. 21 0
      Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATDownloadAdListener.cs

+ 8 - 0
Assets/AnyThinkPlugin.meta

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

+ 8 - 0
Assets/AnyThinkPlugin/Resources.meta

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

+ 8 - 0
Assets/AnyThinkPlugin/Resources/Images.meta

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

BIN
Assets/AnyThinkPlugin/Resources/Images/alert_icon.png


+ 92 - 0
Assets/AnyThinkPlugin/Resources/Images/alert_icon.png.meta

@@ -0,0 +1,92 @@
+fileFormatVersion: 2
+guid: 84ee1925ebaa4430587b1697a0cc378a
+TextureImporter:
+  internalIDToNameTable: []
+  externalObjects: {}
+  serializedVersion: 11
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 1
+    sRGBTexture: 1
+    linearTexture: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapsPreserveCoverage: 0
+    alphaTestReferenceValue: 0.5
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: 0.25
+    normalMapFilter: 0
+  isReadable: 0
+  streamingMipmaps: 0
+  streamingMipmapsPriority: 0
+  grayScaleToAlpha: 0
+  generateCubemap: 6
+  cubemapConvolution: 0
+  seamlessCubemap: 0
+  textureFormat: 1
+  maxTextureSize: 2048
+  textureSettings:
+    serializedVersion: 2
+    filterMode: -1
+    aniso: -1
+    mipBias: -100
+    wrapU: -1
+    wrapV: -1
+    wrapW: -1
+  nPOTScale: 1
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: 0.5, y: 0.5}
+  spritePixelsToUnits: 100
+  spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+  spriteGenerateFallbackPhysicsShape: 1
+  alphaUsage: 1
+  alphaIsTransparency: 0
+  spriteTessellationDetail: -1
+  textureType: 0
+  textureShape: 1
+  singleChannelComponent: 0
+  maxTextureSizeSet: 0
+  compressionQualitySet: 0
+  textureFormatSet: 0
+  applyGammaDecoding: 0
+  platformSettings:
+  - serializedVersion: 3
+    buildTarget: DefaultTexturePlatform
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  spriteSheet:
+    serializedVersion: 2
+    sprites: []
+    outline: []
+    physicsShape: []
+    bones: []
+    spriteID: 
+    internalID: 0
+    vertices: []
+    indices: 
+    edges: []
+    weights: []
+    secondaryTextures: []
+  spritePackingTag: 
+  pSDRemoveMatte: 0
+  pSDShowRemoveMatteOption: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/AnyThinkPlugin/Resources/Images/uninstall_icon.png


+ 92 - 0
Assets/AnyThinkPlugin/Resources/Images/uninstall_icon.png.meta

@@ -0,0 +1,92 @@
+fileFormatVersion: 2
+guid: 1ed8e1d1763ee441caf722be644994ba
+TextureImporter:
+  internalIDToNameTable: []
+  externalObjects: {}
+  serializedVersion: 11
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 1
+    sRGBTexture: 1
+    linearTexture: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapsPreserveCoverage: 0
+    alphaTestReferenceValue: 0.5
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: 0.25
+    normalMapFilter: 0
+  isReadable: 0
+  streamingMipmaps: 0
+  streamingMipmapsPriority: 0
+  grayScaleToAlpha: 0
+  generateCubemap: 6
+  cubemapConvolution: 0
+  seamlessCubemap: 0
+  textureFormat: 1
+  maxTextureSize: 2048
+  textureSettings:
+    serializedVersion: 2
+    filterMode: -1
+    aniso: -1
+    mipBias: -100
+    wrapU: -1
+    wrapV: -1
+    wrapW: -1
+  nPOTScale: 1
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: 0.5, y: 0.5}
+  spritePixelsToUnits: 100
+  spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+  spriteGenerateFallbackPhysicsShape: 1
+  alphaUsage: 1
+  alphaIsTransparency: 0
+  spriteTessellationDetail: -1
+  textureType: 0
+  textureShape: 1
+  singleChannelComponent: 0
+  maxTextureSizeSet: 0
+  compressionQualitySet: 0
+  textureFormatSet: 0
+  applyGammaDecoding: 0
+  platformSettings:
+  - serializedVersion: 3
+    buildTarget: DefaultTexturePlatform
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  spriteSheet:
+    serializedVersion: 2
+    sprites: []
+    outline: []
+    physicsShape: []
+    bones: []
+    spriteID: 
+    internalID: 0
+    vertices: []
+    indices: 
+    edges: []
+    weights: []
+    secondaryTextures: []
+  spritePackingTag: 
+  pSDRemoveMatte: 0
+  pSDShowRemoveMatteOption: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

BIN
Assets/AnyThinkPlugin/Resources/Images/warning_icon.png


+ 92 - 0
Assets/AnyThinkPlugin/Resources/Images/warning_icon.png.meta

@@ -0,0 +1,92 @@
+fileFormatVersion: 2
+guid: a64dc878e75e44d2e9ed923628832495
+TextureImporter:
+  internalIDToNameTable: []
+  externalObjects: {}
+  serializedVersion: 11
+  mipmaps:
+    mipMapMode: 0
+    enableMipMap: 1
+    sRGBTexture: 1
+    linearTexture: 0
+    fadeOut: 0
+    borderMipMap: 0
+    mipMapsPreserveCoverage: 0
+    alphaTestReferenceValue: 0.5
+    mipMapFadeDistanceStart: 1
+    mipMapFadeDistanceEnd: 3
+  bumpmap:
+    convertToNormalMap: 0
+    externalNormalMap: 0
+    heightScale: 0.25
+    normalMapFilter: 0
+  isReadable: 0
+  streamingMipmaps: 0
+  streamingMipmapsPriority: 0
+  grayScaleToAlpha: 0
+  generateCubemap: 6
+  cubemapConvolution: 0
+  seamlessCubemap: 0
+  textureFormat: 1
+  maxTextureSize: 2048
+  textureSettings:
+    serializedVersion: 2
+    filterMode: -1
+    aniso: -1
+    mipBias: -100
+    wrapU: -1
+    wrapV: -1
+    wrapW: -1
+  nPOTScale: 1
+  lightmap: 0
+  compressionQuality: 50
+  spriteMode: 0
+  spriteExtrude: 1
+  spriteMeshType: 1
+  alignment: 0
+  spritePivot: {x: 0.5, y: 0.5}
+  spritePixelsToUnits: 100
+  spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+  spriteGenerateFallbackPhysicsShape: 1
+  alphaUsage: 1
+  alphaIsTransparency: 0
+  spriteTessellationDetail: -1
+  textureType: 0
+  textureShape: 1
+  singleChannelComponent: 0
+  maxTextureSizeSet: 0
+  compressionQualitySet: 0
+  textureFormatSet: 0
+  applyGammaDecoding: 0
+  platformSettings:
+  - serializedVersion: 3
+    buildTarget: DefaultTexturePlatform
+    maxTextureSize: 2048
+    resizeAlgorithm: 0
+    textureFormat: -1
+    textureCompression: 1
+    compressionQuality: 50
+    crunchedCompression: 0
+    allowsAlphaSplitting: 0
+    overridden: 0
+    androidETC2FallbackOverride: 0
+    forceMaximumCompressionQuality_BC6H_BC7: 0
+  spriteSheet:
+    serializedVersion: 2
+    sprites: []
+    outline: []
+    physicsShape: []
+    bones: []
+    spriteID: 
+    internalID: 0
+    vertices: []
+    indices: 
+    edges: []
+    weights: []
+    secondaryTextures: []
+  spritePackingTag: 
+  pSDRemoveMatte: 0
+  pSDShowRemoveMatteOption: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/AnyThinkPlugin/Resources/json.meta

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

+ 8 - 0
Assets/AnyThinkPlugin/Resources/json/2.1.5.meta

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

+ 1 - 0
Assets/AnyThinkPlugin/Resources/json/2.1.5/plugin_hot_fix_data.json

@@ -0,0 +1 @@
+{"plugin_version":"2.1.5","hot_fix_version":"1.0.3","download_url":"https://topon-sdk-release.oss-cn-hangzhou.aliyuncs.com/Unity_Release/plugin/2.1.5/hotfix/1.0.3/AnyThinkHotFixPlugin_1.0.3.unitypackage","status":1,"file_name":"AnyThinkHotFixPlugin_1.0.3.unitypackage"}

+ 7 - 0
Assets/AnyThinkPlugin/Resources/json/2.1.5/plugin_hot_fix_data.json.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: CXNOsHyoVnoOdVL9izdgabyGw8PwsVT18GRDMPD39SnJP0s/HVWM6n8mIO4+
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1 - 0
Assets/AnyThinkPlugin/Resources/json/2.1.5/plugin_setting_data.json

@@ -0,0 +1 @@
+{"curCountry":1,"china":{"android_version":"6.4.87","ios_version":"","androidXSetting":1,"country":1,"android_admob_app_id":"","ios_admob_app_id":""},"nonchina":{"android_version":"","ios_version":"","androidXSetting":0,"country":2,"android_admob_app_id":"","ios_admob_app_id":""}}

+ 7 - 0
Assets/AnyThinkPlugin/Resources/json/2.1.5/plugin_setting_data.json.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: By4asn+oAHkVQ2nXiXfyaMUXrvotmaL9x7jyt/YLKX1pqJ7gvWTkj4tTIw/h
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/AnyThinkPlugin/Script.meta

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

+ 8 - 0
Assets/AnyThinkPlugin/Script/Editor.meta

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

+ 330 - 0
Assets/AnyThinkPlugin/Script/Editor/ATPostProcessBuildAndroid.cs

@@ -0,0 +1,330 @@
+#if UNITY_ANDROID && UNITY_2018_2_OR_NEWER
+using AnyThink.Scripts.IntegrationManager.Editor;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using UnityEditor;
+using UnityEditor.Android;
+
+namespace AnyThink.Scripts.Editor
+{
+    public class ATPostProcessBuildAndroid: IPostGenerateGradleAndroidProject
+    {
+#if UNITY_2019_3_OR_NEWER
+        private static string PropertyAndroidX = "android.useAndroidX";
+        private static string PropertyJetifier = "android.enableJetifier";
+        private static string EnableProperty = "=true";
+#endif
+        private static string PropertyDexingArtifactTransform = "android.enableDexingArtifactTransform";
+        private static string DisableProperty = "=false";
+
+        private static string KeyMetaDataGoogleApplicationId = "com.google.android.gms.ads.APPLICATION_ID";
+        private static string KeyMetaDataGoogleAdManagerApp = "com.google.android.gms.ads.AD_MANAGER_APP";
+
+        private static readonly XNamespace AndroidNamespace = "http://schemas.android.com/apk/res/android";
+        private static readonly XNamespace ToolsNamespace = "http://schemas.android.com/tools";
+
+        public void OnPostGenerateGradleAndroidProject(string path)
+        {
+             ATLog.log("OnPostGenerateGradleAndroidProject() >>> path: " + path);
+           
+#if UNITY_2019_3_OR_NEWER
+            var gradlePropertiesPath = Path.Combine(path, "../gradle.properties");
+#else
+            var gradlePropertiesPath = Path.Combine(path, "gradle.properties");
+#endif
+            if (!ATConfig.isDefaultAndroidX()) {
+                processGradleProperties(gradlePropertiesPath);
+            }
+            processAndroidManifest(path);
+            processNetworkConfigXml(path);
+            ATProcessBuildGradleAndroid.processBuildGradle(path);
+        }
+
+        public int callbackOrder
+        {
+            get { return int.MaxValue; }
+        }
+
+        private static void processGradleProperties(string gradlePropertiesPath)
+        {
+            ATLog.log("OnPostGenerateGradleAndroidProject() >>> gradlePropertiesPath: " + gradlePropertiesPath + " File.Exists(gradlePropertiesPath): " + File.Exists(gradlePropertiesPath));
+            bool isChina = ATConfig.isSelectedChina();
+         
+            var gradlePropertiesUpdated = new List<string>();
+
+            // If the gradle properties file already exists, make sure to add any previous properties.
+            if (File.Exists(gradlePropertiesPath))
+            {
+                var lines = File.ReadAllLines(gradlePropertiesPath);
+
+#if UNITY_2019_3_OR_NEWER
+                // Add all properties except AndroidX, Jetifier, and DexingArtifactTransform since they may already exist. We will re-add them below.
+                gradlePropertiesUpdated.AddRange(lines.Where(line => !line.Contains(PropertyAndroidX) && !line.Contains(PropertyJetifier) && !line.Contains(PropertyDexingArtifactTransform)));
+#else
+                // Add all properties except DexingArtifactTransform since it may already exist. We will re-add it below.
+                gradlePropertiesUpdated.AddRange(lines.Where(line => !line.Contains(PropertyDexingArtifactTransform)));
+#endif
+            }
+
+#if UNITY_2019_3_OR_NEWER
+            //如果是国内,则根据选择来决定是否用AndroidX
+            if (isChina)    
+            {
+                if (!ATConfig.enableAndroidX()) {
+                    EnableProperty = "=false"; 
+                } else {
+                    EnableProperty = "=true"; 
+                }
+            } else {
+                EnableProperty = "=true"; 
+            }
+            ATLog.log("[AnyThink] AndroidX EnableProperty" + EnableProperty);
+            // Enable AndroidX and Jetifier properties 
+            gradlePropertiesUpdated.Add(PropertyAndroidX + EnableProperty);
+            gradlePropertiesUpdated.Add(PropertyJetifier + EnableProperty);
+#endif
+            // Disable dexing using artifact transform (it causes issues for ExoPlayer with Gradle plugin 3.5.0+)
+            gradlePropertiesUpdated.Add(PropertyDexingArtifactTransform + DisableProperty);
+
+            try
+            {
+                File.WriteAllText(gradlePropertiesPath, string.Join("\n", gradlePropertiesUpdated.ToArray()) + "\n");
+            }
+            catch (Exception exception)
+            {
+                ATLog.logError("Failed to enable AndroidX and Jetifier. gradle.properties file write failed.");
+                Console.WriteLine(exception);
+            }
+        }
+
+        private static void processAndroidManifest(string path)
+        {
+#if UNITY_2019_3_OR_NEWER
+            var manifestPath = Path.Combine(path, "src/main/AndroidManifest.xml");
+#else
+            var manifestPath = Path.Combine(path, "unityLibrary/src/main/AndroidManifest.xml");
+#endif
+            // var manifestPath = Path.Combine(path, "src/main/AndroidManifest.xml");
+            XDocument manifest;
+            try
+            {
+                manifest = XDocument.Load(manifestPath);
+            }
+#pragma warning disable 0168
+            catch (IOException exception)
+#pragma warning restore 0168
+            {
+                ATLog.log("[AnyThink] AndroidManifest.xml is missing.");
+                return;
+            }
+
+            // Get the `manifest` element.
+            var elementManifest = manifest.Element("manifest");
+            if (elementManifest == null)
+            {
+                ATLog.log("[AnyThink] AndroidManifest.xml is invalid.");
+                return;
+            }
+
+            var elementApplication = elementManifest.Element("application");
+            if (elementApplication == null)
+            {
+                ATLog.log("[AnyThink] AndroidManifest.xml is invalid.");
+                return;
+            }
+
+            var metaDataElements = elementApplication.Descendants().Where(element => element.Name.LocalName.Equals("meta-data"));
+            addGoogleApplicationIdIfNeeded(elementApplication, metaDataElements);
+            // Save the updated manifest file.
+            manifest.Save(manifestPath);
+        }
+
+        private static void addGoogleApplicationIdIfNeeded(XElement elementApplication, IEnumerable<XElement> metaDataElements)
+        {
+            var googleApplicationIdMetaData = GetElementByName(metaDataElements, KeyMetaDataGoogleApplicationId);
+
+            if (!ATConfig.isNetworkInstalledByName("Admob", ATConfig.OS_ANDROID))
+            {   
+                ATLog.log("addGoogleApplicationIdIfNeeded() >>> Admob not install.");
+                if (googleApplicationIdMetaData != null) googleApplicationIdMetaData.Remove();
+                return;
+            }
+
+            var appId = ATConfig.getAdmobAppIdByOs(ATConfig.OS_ANDROID);
+            // Log error if the App ID is not set.
+            if (string.IsNullOrEmpty(appId) || !appId.StartsWith("ca-app-pub-"))
+            {
+                ATLog.logError("AdMob App ID is not set. Please enter a valid app ID within the AnyThink Integration Manager window.");
+                return;
+            }
+
+            // Check if the Google App ID meta data already exists. Update if it already exists.
+            if (googleApplicationIdMetaData != null)
+            {
+                googleApplicationIdMetaData.SetAttributeValue(AndroidNamespace + "value", appId);
+            }
+            // Meta data doesn't exist, add it.
+            else
+            {
+                elementApplication.Add(CreateMetaDataElement(KeyMetaDataGoogleApplicationId, appId));
+            }
+        }
+
+        /// <summary>
+        /// Looks through all the given meta-data elements to check if the required one exists. Returns <c>null</c> if it doesn't exist.
+        /// </summary>
+        private static XElement GetElementByName(IEnumerable<XElement> elements, string name)
+        {
+            foreach (var element in elements)
+            {
+                var attributes = element.Attributes();
+                if (attributes.Any(attribute => attribute.Name.Namespace.Equals(AndroidNamespace)
+                                                && attribute.Name.LocalName.Equals("name")
+                                                && attribute.Value.Equals(name)))
+                {
+                    return element;
+                }
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Creates and returns a <c>meta-data</c> element with the given name and value. 
+        /// </summary>
+        private static XElement CreateMetaDataElement(string name, object value)
+        {
+            var metaData = new XElement("meta-data");
+            metaData.Add(new XAttribute(AndroidNamespace + "name", name));
+            metaData.Add(new XAttribute(AndroidNamespace + "value", value));
+
+            return metaData;
+        }
+
+        private static void processNetworkConfigXml(string path)
+        {   
+            bool isChina = ATConfig.isSelectedChina();
+            // bool isChina = true;
+            
+            //在application标签加上:android:networkSecurityConfig="@xml/anythink_network_security_config"
+            addNetworkSecurityConfigInApplication(path, isChina);
+
+#if UNITY_2019_3_OR_NEWER
+            var resXmlPath = Path.Combine(path, "src/main/res/xml");
+#else
+            var resXmlPath = Path.Combine(path, "unityLibrary/src/main/res/xml");
+#endif
+            
+            var rexXmlDir = Path.Combine(resXmlPath, "anythink_network_security_config.xml");
+            if (File.Exists(rexXmlDir))
+            { 
+                if (!isChina)   //海外不用配置这个xml
+                {
+                   FileUtil.DeleteFileOrDirectory(rexXmlDir);
+                } 
+                return;
+            }
+            if (!Directory.Exists(resXmlPath))
+            {
+                Directory.CreateDirectory(resXmlPath);
+            }
+            
+            saveFile("Assets/AnyThinkPlugin/Script/Editor/anythink_network_security_config.xml", resXmlPath);
+        }
+
+        public static void saveFile(string filePathName , string toFilesPath)
+        {
+            FileInfo file = new FileInfo(filePathName);
+            string newFileName= file.Name;
+            file.CopyTo(toFilesPath + "/" + newFileName, true);
+        }
+
+        private static void addNetworkSecurityConfigInApplication(string path, bool isChina)
+        {
+#if UNITY_2019_3_OR_NEWER
+            var manifestPath = Path.Combine(path, "src/main/AndroidManifest.xml");
+#else
+            var manifestPath = Path.Combine(path, "unityLibrary/src/main/AndroidManifest.xml");
+#endif
+            // var manifestPath = Path.Combine(path, "src/main/AndroidManifest.xml");
+            XDocument manifest;
+            try
+            {
+                manifest = XDocument.Load(manifestPath);
+            }
+#pragma warning disable 0168
+            catch (IOException exception)
+#pragma warning restore 0168
+            {
+                ATLog.log("[AnyThink] AndroidManifest.xml is missing.");
+                return;
+            }
+
+            // Get the `manifest` element.
+            var elementManifest = manifest.Element("manifest");
+            if (elementManifest == null)
+            {
+                ATLog.log("[AnyThink] AndroidManifest.xml is invalid.");
+                return;
+            }
+
+            var elementApplication = elementManifest.Element("application");
+            if (elementApplication == null)
+            {
+                ATLog.log("[AnyThink] AndroidManifest.xml is invalid.");
+                return;
+            }
+            //handle anythink_network_security_config.xml
+            XAttribute networkConfigAttribute = elementApplication.Attribute(AndroidNamespace + "networkSecurityConfig");
+            if (networkConfigAttribute != null) {
+                networkConfigAttribute.Remove();
+            }
+            if (isChina)
+            {
+                elementApplication.Add(new XAttribute(AndroidNamespace + "networkSecurityConfig", "@xml/anythink_network_security_config"));
+            }
+
+            //这个设置主要是为了适配9.0以上的机器
+            //<uses-library android:name="org.apache.http.legacy" android:required="false" />
+            var usesLibraryElements = elementApplication.Descendants().Where(element => element.Name.LocalName.Equals("uses-library"));
+            if (usesLibraryElements == null)
+            {
+                elementApplication.Add(createHttpLegacyElement());
+            }
+            else 
+            {
+               XElement httpLegacyElement = GetElementByName(usesLibraryElements, "org.apache.http.legacy");
+               if (httpLegacyElement == null)
+               {
+                    elementApplication.Add(createHttpLegacyElement());
+               }
+            }
+            manifest.Save(manifestPath);
+        }
+
+        public static XElement createHttpLegacyElement()
+        {
+            var httpFeautre = new XElement("uses-library");
+            httpFeautre.Add(new XAttribute(AndroidNamespace + "name", "org.apache.http.legacy"));
+            httpFeautre.Add(new XAttribute(AndroidNamespace + "required", "false"));
+
+            return httpFeautre;
+        }
+
+        private static XElement CreateMetaDataElement(string name, object value, object toolsNode)
+        {
+            var metaData = new XElement("meta-data");
+            metaData.Add(new XAttribute(AndroidNamespace + "name", name));
+            metaData.Add(new XAttribute(AndroidNamespace + "value", value));
+            metaData.Add(new XAttribute(ToolsNamespace + "node", toolsNode));
+
+            return metaData;
+        }
+    }
+    
+}
+
+#endif

+ 11 - 0
Assets/AnyThinkPlugin/Script/Editor/ATPostProcessBuildAndroid.cs.meta

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

+ 234 - 0
Assets/AnyThinkPlugin/Script/Editor/ATPostProcessBuildiOS.cs

@@ -0,0 +1,234 @@
+#if UNITY_IOS || UNITY_IPHONE
+
+using AnyThink.Scripts.IntegrationManager.Editor;
+#if UNITY_2019_3_OR_NEWER
+using UnityEditor.iOS.Xcode.Extensions;
+#endif
+using UnityEngine.Networking;
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using System.IO;
+using UnityEditor;
+using UnityEditor.Callbacks;
+using UnityEditor.iOS.Xcode;
+using UnityEngine;
+
+namespace AnyThink.Scripts.Editor
+{
+    [Serializable]
+    public class SkAdNetworkData
+    {
+        [SerializeField] public string[] SkAdNetworkIds;
+    }
+
+    public class TopOnPostProcessBuildiOS
+    {
+        private static string mBuildPath;
+
+        private static readonly List<string> AtsRequiringNetworks = new List<string>
+        {
+            "AdColony",
+            "ByteDance",
+            "Fyber",
+            "Google",
+            "GoogleAdManager",
+            "HyprMX",
+            "InMobi",
+            "IronSource",
+            "Smaato"
+        };
+
+        private static List<string> DynamicLibraryPathsToEmbed
+        {
+            get
+            {
+                var dynamicLibraryPathsToEmbed = new List<string>();
+                dynamicLibraryPathsToEmbed.Add(Path.Combine("Pods/", "KSAdSDK/KSAdSDK.xcframework"));
+                dynamicLibraryPathsToEmbed.Add(Path.Combine("Pods/", "StartAppSDK/StartApp.xcframework"));
+                dynamicLibraryPathsToEmbed.Add(Path.Combine("Pods/", "BigoADS/BigoADS/BigoADS.xcframework"));
+                dynamicLibraryPathsToEmbed.Add(Path.Combine("Pods/", "BigoADS/BigoADS/OMSDK_Bigosg.xcframework"));
+                dynamicLibraryPathsToEmbed.Add(Path.Combine("Pods/", "Fyber_Marketplace_SDK/IASDKCore/IASDKCore.xcframework"));
+                dynamicLibraryPathsToEmbed.Add(Path.Combine("Pods/", "InMobiSDK/InMobiSDK.xcframework"));
+                dynamicLibraryPathsToEmbed.Add(Path.Combine("Pods/", "GDTMobSDK/GDTFramework/GDTMobSDK.xcframework"));
+                dynamicLibraryPathsToEmbed.Add(Path.Combine("Pods/", "GDTMobSDK/GDTFramework/Tquic.xcframework"));
+
+                //pubnative
+                dynamicLibraryPathsToEmbed.Add(Path.Combine("Pods/", "ATOM-Standalone/ATOM.xcframework"));
+                string pubNativePath = Path.Combine(mBuildPath, "Pods/HyBid/PubnativeLite/PubnativeLite");
+                if (Directory.Exists(pubNativePath)) {
+                    // 获取所有以"OMSDK-"开头的子目录
+                    string[] subDirectories = Directory.GetDirectories(pubNativePath, "OMSDK-*");
+                    if (subDirectories.Length > 0) {
+                        string versionDirectory= subDirectories[0];
+                        string versionDirectoryName = Path.GetFileName(versionDirectory);
+                        // ATLog.logError("DynamicLibraryPathsToEmbed() >>> pubNative versionDirectoryName: " + versionDirectoryName);
+                        dynamicLibraryPathsToEmbed.Add(Path.Combine("Pods/", "HyBid/PubnativeLite/PubnativeLite/" + versionDirectoryName + "/OMSDK_Pubnativenet.xcframework"));
+                    }
+                }
+                //applovin
+                string applovinPath = Path.Combine(mBuildPath, "Pods/AppLovinSDK");
+                if (Directory.Exists(applovinPath)) {
+                    // 获取所有以"applovin-ios-sdk-"开头的子目录
+                    string[] applovinSubDirectories = Directory.GetDirectories(applovinPath, "applovin-ios-sdk-*");
+                    if (applovinSubDirectories.Length > 0) {
+                        string applovinVersionDirectory = applovinSubDirectories[0];
+                        string applovinVersionDirectoryName = Path.GetFileName(applovinVersionDirectory);
+                         // ATLog.logError("DynamicLibraryPathsToEmbed() >>> applovinVersionDirectoryName: " + applovinVersionDirectoryName);
+                        dynamicLibraryPathsToEmbed.Add(Path.Combine("Pods/", "AppLovinSDK/" + applovinVersionDirectoryName + "/AppLovinSDK.xcframework"));
+                    }
+                }
+
+                return dynamicLibraryPathsToEmbed;
+            }
+        }
+
+        //读取本地已安装network的版本号:network_data.json
+        // private static string getNetworkVersion(string networkDataJsonFilePath)
+        // {
+        //     if (!File.Exists(networkDataJsonFilePath)) {
+        //         return "";
+        //     }
+        //     string jsonData = File.ReadAllText(networkDataJsonFilePath);
+        //     var networkLocalData = JsonUtility.FromJson<NetworkLocalData>(a_json);
+        //     if (networkLocalData != null) {
+        //         return networkLocalData.version;
+        //     }
+        //     retrun "";
+        // }
+
+        private static List<string> BunldePathsToAdd {
+            get {
+
+                var bunldePathsToAdd = new List<string>();
+                bunldePathsToAdd.Add(Path.Combine("Pods/", "BigoADS/BigoADS/BigoADSRes.bundle"));
+                bunldePathsToAdd.Add(Path.Combine("Pods/", "Ads-Global/SDK/PAGAdSDK.bundle"));
+                bunldePathsToAdd.Add(Path.Combine("Pods/", "Ads-CN/SDK/CSJAdSDK.bundle"));
+                bunldePathsToAdd.Add(Path.Combine("Pods/", "Ads-CN-Beta/SDK/CSJAdSDK.bundle"));
+
+                return bunldePathsToAdd;
+            }
+        }
+
+        private static readonly List<string> SwiftLanguageNetworks = new List<string>
+        {
+            "MoPub"
+        };
+
+        private static readonly List<string> EmbedSwiftStandardLibrariesNetworks = new List<string>
+        {
+            "Facebook",
+            "MoPub"
+        };
+
+        [PostProcessBuildAttribute(int.MaxValue)]
+        public static void TopOnPostProcessPbxProject(BuildTarget buildTarget, string buildPath)
+        {
+            var projectPath = PBXProject.GetPBXProjectPath(buildPath);
+            var project = new PBXProject();
+            project.ReadFromFile(projectPath);
+
+#if UNITY_2019_3_OR_NEWER
+            var unityMainTargetGuid = project.GetUnityMainTargetGuid();
+            var unityFrameworkTargetGuid = project.GetUnityFrameworkTargetGuid();
+#else
+            var unityMainTargetGuid = project.TargetGuidByName(UnityMainTargetName);
+            var unityFrameworkTargetGuid = project.TargetGuidByName(UnityMainTargetName);
+#endif
+
+            project.SetBuildProperty(unityMainTargetGuid, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES");
+            project.SetBuildProperty(unityMainTargetGuid, "ENABLE_BITCODE", "NO");
+
+            project.SetBuildProperty(unityFrameworkTargetGuid, "GCC_ENABLE_OBJC_EXCEPTIONS", "YES");
+            project.SetBuildProperty(unityFrameworkTargetGuid, "ENABLE_BITCODE", "NO");
+
+            EmbedDynamicLibrariesIfNeeded(buildPath, project, unityMainTargetGuid);
+            AddBunleIfNeeded(buildPath, project, unityMainTargetGuid);
+
+            project.WriteToFile(projectPath);
+        }
+
+        [PostProcessBuildAttribute(int.MaxValue)]
+        public static void TopOnPostProcessPlist(BuildTarget buildTarget, string path)
+        {
+            var plistPath = Path.Combine(path, "Info.plist");
+            var plist = new PlistDocument();
+            plist.ReadFromFile(plistPath);
+
+#if UNITY_2018_2_OR_NEWER
+            AddGoogleApplicationIdIfNeeded(plist);
+#endif
+
+            plist.WriteToFile(plistPath);
+        }
+
+        private static void AddBunleIfNeeded(string buildPath, PBXProject project, string targetGuid)
+        {
+            var bunldePathsPresentInProject = BunldePathsToAdd.Where(bunldePath => Directory.Exists(Path.Combine(buildPath, bunldePath))).ToList();
+            if (bunldePathsPresentInProject.Count <= 0) return;
+            ATLog.log("AddBunleIfNeeded");
+
+#if UNITY_2019_3_OR_NEWER
+            foreach (var bunldePath in bunldePathsPresentInProject)
+            {
+                var fileGuid = project.AddFile(bunldePath, bunldePath, PBXSourceTree.Source);
+                project.AddFileToBuild(targetGuid, fileGuid);
+            }
+#endif
+        }
+
+        private static void EmbedDynamicLibrariesIfNeeded(string buildPath, PBXProject project, string targetGuid)
+        {
+            mBuildPath = buildPath;
+            ATLog.log("EmbedDynamicLibrariesIfNeeded() >>> buildPath: " + buildPath);
+            var dynamicLibraryPathsPresentInProject = DynamicLibraryPathsToEmbed.Where(dynamicLibraryPath => Directory.Exists(Path.Combine(buildPath, dynamicLibraryPath))).ToList();
+            if (dynamicLibraryPathsPresentInProject.Count <= 0) return;
+
+#if UNITY_2019_3_OR_NEWER
+            foreach (var dynamicLibraryPath in dynamicLibraryPathsPresentInProject)
+            {
+                var fileGuid = project.AddFile(dynamicLibraryPath, dynamicLibraryPath);
+                project.AddFileToEmbedFrameworks(targetGuid, fileGuid);
+            }
+#else
+            string runpathSearchPaths;
+#if UNITY_2018_2_OR_NEWER
+            runpathSearchPaths = project.GetBuildPropertyForAnyConfig(targetGuid, "LD_RUNPATH_SEARCH_PATHS");
+#else
+            runpathSearchPaths = "$(inherited)";          
+#endif
+            runpathSearchPaths += string.IsNullOrEmpty(runpathSearchPaths) ? "" : " ";
+
+            // Check if runtime search paths already contains the required search paths for dynamic libraries.
+            if (runpathSearchPaths.Contains("@executable_path/Frameworks")) return;
+
+            runpathSearchPaths += "@executable_path/Frameworks";
+            project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", runpathSearchPaths);
+#endif
+        }
+
+#if UNITY_2018_2_OR_NEWER
+
+        private static void AddGoogleApplicationIdIfNeeded(PlistDocument plist)
+        {
+            if (!ATConfig.isNetworkInstalledByName("Admob", ATConfig.OS_IOS))
+            {   
+                ATLog.log("addGoogleApplicationIdIfNeeded() >>> Admob not install.");
+                return;
+            }
+            //获取admob app id
+            var appId = ATConfig.getAdmobAppIdByOs(ATConfig.OS_IOS);
+
+            if (string.IsNullOrEmpty(appId) || !appId.StartsWith("ca-app-pub-"))
+            {
+                ATLog.logError("AdMob App ID is not set. Please enter a valid app ID within the AnyThink Integration Manager window.");
+                return;
+            }
+
+            const string googleApplicationIdentifier = "GADApplicationIdentifier";
+            plist.root.SetString(googleApplicationIdentifier, appId);
+        }
+#endif
+    }
+}
+#endif

+ 11 - 0
Assets/AnyThinkPlugin/Script/Editor/ATPostProcessBuildiOS.cs.meta

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

+ 354 - 0
Assets/AnyThinkPlugin/Script/Editor/ATProcessBuildGradleAndroid.cs

@@ -0,0 +1,354 @@
+#if UNITY_ANDROID && UNITY_2018_2_OR_NEWER
+using AnyThink.Scripts.IntegrationManager.Editor;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using UnityEditor;
+using UnityEditor.Android;
+using System.Text.RegularExpressions;
+using System.Diagnostics;
+using UnityEngine;
+using System.Text;
+
+
+namespace AnyThink.Scripts.Editor
+{
+
+    public class ATProcessBuildGradleAndroid
+    {
+
+        // public void OnPostGenerateGradleAndroidProject(string path)
+        // {
+
+        // }
+
+        public static void processBuildGradle(string path)
+        {
+#if UNITY_2019_3_OR_NEWER
+            var buildGradlePath = Path.Combine(path, "../build.gradle");
+#else
+            var buildGradlePath = Path.Combine(path, "build.gradle");
+#endif  
+
+#if UNITY_2022_1_OR_NEWER
+            ATLog.log("processBuildGradle() >>> called");
+#else 
+            replaceBuildPluginVersion(buildGradlePath);
+            // replaceAppBuildPluginVersion(path);
+#endif
+            // replaceAppBuildPluginVersion(path);
+            handleNetworksConfit(path);
+            // handleNetworkResMerge(path);
+            // callGradleTask(path);
+        }
+        //修改项目的根目录下的build.gradle文件的插件版本号
+        private static void replaceBuildPluginVersion(string buildGradlePath)
+        {
+            if (!File.Exists(buildGradlePath))
+            {
+                return;
+            }
+            string gradleFileContent = "";
+            using (StreamReader reader = new StreamReader(buildGradlePath))
+            {
+                gradleFileContent = reader.ReadToEnd();
+            }
+            if (string.IsNullOrEmpty(gradleFileContent))
+            {
+                return;
+            }
+            
+            string buildGradleVersion = "";
+            string buildGradlePattern = "";
+
+            string buildGradleVersion3 = "3.3.3";    // 新gradle插件版本号
+            string buildGradlePattern3 = @"(?<=gradle:)3\.3\.\d+";
+            string buildGradleVersion4 = "3.4.3"; 
+            string buildGradlePattern4 = @"(?<=gradle:)3\.4\.\d+";
+            string buildGradleVersion5 = "3.5.4";
+            string buildGradlePattern5 = @"(?<=gradle:)3\.5\.\d+";
+            string buildGradleVersion6 = "3.6.4";
+            string buildGradlePattern6 = @"(?<=gradle:)3\.6\.\d+";
+
+            if (isMatchGradleVersion(gradleFileContent, buildGradleVersion3))
+            {
+                buildGradleVersion = buildGradleVersion3;
+                buildGradlePattern = buildGradlePattern3;
+            } 
+            else if(isMatchGradleVersion(gradleFileContent, buildGradleVersion4))
+            {
+                buildGradleVersion = buildGradleVersion4;
+                buildGradlePattern = buildGradlePattern4;
+            }
+            else if(isMatchGradleVersion(gradleFileContent, buildGradleVersion5))
+            {
+                buildGradleVersion = buildGradleVersion5;
+                buildGradlePattern = buildGradlePattern5;
+            }
+            else if(isMatchGradleVersion(gradleFileContent, buildGradleVersion6))
+            {
+                buildGradleVersion = buildGradleVersion6;
+                buildGradlePattern = buildGradlePattern6;
+            }
+
+            if (!string.IsNullOrEmpty(buildGradlePattern) && !string.IsNullOrEmpty(buildGradleVersion))
+            {
+                replaceContent(buildGradlePath, buildGradlePattern, buildGradleVersion);
+            }
+        }
+
+        private static void replaceContent(string filePath, string pattern, string content)
+        {
+            if (!File.Exists(filePath))
+            {
+                return;
+            }
+            string buildGradle = "";
+            using (StreamReader reader = new StreamReader(filePath))
+            {
+                buildGradle = reader.ReadToEnd();
+            }
+            // Regex regex = new Regex(pattern);
+            buildGradle = Regex.Replace(buildGradle, pattern, content);
+
+            // 修改gradle-wrapper版本号
+            // string oldWrapperVersion = "distributionUrl=https\\://services.gradle.org/d
+            using (StreamWriter writer = new StreamWriter(filePath))
+            {
+                writer.Write(buildGradle);
+            }
+        }
+
+        private static bool isMatchGradleVersion(string gradleFileContent, string version)
+        {
+            string matchStr = String.Format("gradle:{0}", version.Substring(0, 3));
+            return gradleFileContent.Contains(matchStr);
+        }
+        //修改app module下的build.gradle
+        private static void replaceAppBuildPluginVersion(string path)
+        {
+#if UNITY_2019_3_OR_NEWER
+            var buildGradlePath = Path.Combine(path, "../launcher/build.gradle");
+#else
+            var buildGradlePath = Path.Combine(path, "launcher/build.gradle");
+#endif  
+            if (!File.Exists(buildGradlePath))
+            {
+                return;
+            }
+            string buildGradleVersion = "30";
+            string compileSdkVersionPattern = "compileSdkVersion";
+            string targetSdkVersionPattern = "targetSdkVersion";
+
+            List<string> lines = new List<string>();
+            using (StreamReader reader = new StreamReader(buildGradlePath))
+            {
+                string line;
+                while ((line = reader.ReadLine()) != null)
+                {
+                    lines.Add(line);
+                }
+            }
+            int indexToReplace = -1;
+            int indexToReplace1 = -1;
+            int removeIndex = -1;
+            int addIndex = -1;
+            for (int i = 0; i < lines.Count; i++)
+            {
+                if (lines[i].Contains(compileSdkVersionPattern))
+                {
+                    indexToReplace = i;
+                }
+                else if (lines[i].Contains(targetSdkVersionPattern))
+                {
+                    indexToReplace1 = i;
+                }
+                else if (lines[i].Contains("buildToolsVersion"))
+                {
+                    removeIndex = i;
+                }
+                else if (lines[i].Contains("defaultConfig"))
+                {
+                    addIndex = i;
+                }
+            }
+            if (indexToReplace != -1)
+            {
+                lines[indexToReplace] = "  " + compileSdkVersionPattern + " " + buildGradleVersion;
+            }
+            if (indexToReplace1 != -1)
+            {
+                lines[indexToReplace1] = "  " + targetSdkVersionPattern + " " + buildGradleVersion;
+            }
+            if (removeIndex != -1)
+            {
+                lines.RemoveAt(removeIndex);
+            }
+            if (addIndex != -1)
+            {
+                lines.Insert(addIndex + 1, "  multiDexEnabled true");
+            }
+            using (StreamWriter writer = new StreamWriter(buildGradlePath))
+            {
+                foreach (string line in lines)
+                {
+                    writer.WriteLine(line);
+                }
+            }
+        }
+
+        private static void handleNetworksConfit(string path)
+        {
+            if (ATConfig.isSelectedChina())
+            {
+                return;
+            }
+#if UNITY_2019_3_OR_NEWER
+            var buildGradlePath = Path.Combine(path, "../launcher/build.gradle");
+#else
+            var buildGradlePath = Path.Combine(path, "launcher/build.gradle");
+#endif  
+            if (!File.Exists(buildGradlePath))
+            {
+                return;
+            }
+            List<string> lines = new List<string>();
+            using (StreamReader reader = new StreamReader(buildGradlePath))
+            {
+                string line;
+                while ((line = reader.ReadLine()) != null)
+                {
+                    lines.Add(line);
+                }
+            }
+            var androidStartIndex = 0;
+            var isConfigAll = false;
+            var isExcludeModule = false;
+
+            for (int i = 0; i < lines.Count; i++)
+            {
+                if (lines[i].Contains("android {"))
+                {
+                    androidStartIndex = i;
+                }
+                else if (lines[i].Contains("configurations.all"))
+                {
+                    isConfigAll = true;
+                }
+                else if (lines[i].Contains("META-INF/*.kotlin_module"))
+                {
+                    isExcludeModule = true;
+                }
+            }   
+            if (androidStartIndex > 0)
+            {
+                if (!isExcludeModule)
+                {
+                    lines.Insert(androidStartIndex + 1, "  packagingOptions {\n     merge 'META-INF/com.android.tools/proguard/coroutines.pro'\n     exclude 'META-INF/*.kotlin_module'\n   }");
+                }
+                // if (!isConfigAll)
+                // {
+                //     lines.Insert(androidStartIndex -1, "configurations.all {\n     resolutionStrategy {\n      force 'androidx.core:core:1.6.0'\n      force 'androidx.recyclerview:recyclerview:1.1.0' \n    }\n}");
+                // }
+            }
+            // configurations.all {
+            //     resolutionStrategy {
+            //         force 'androidx.core:core:1.6.0'
+            //         force 'androidx.recyclerview:recyclerview:1.1.0'
+            //     }
+            // }
+            // packagingOptions {
+            //     merge "META-INF/com.android.tools/proguard/coroutines.pro"
+            //     exclude "META-INF/*.kotlin_module"
+            // }
+            using (StreamWriter writer = new StreamWriter(buildGradlePath))
+            {
+                foreach (string line in lines)
+                {
+                    writer.WriteLine(line);
+                }
+            }
+        }
+
+        private static void handleNetworkResMerge(string path) {
+            ATLog.log("handleNetworkResMerge() >>> path: " + path);
+#if UNITY_2019_3_OR_NEWER
+            var buildGradlePath = Path.Combine(path, "../launcher/build.gradle");
+#else
+            var buildGradlePath = Path.Combine(path, "launcher/build.gradle");
+#endif 
+            List<string> lines = new List<string>();
+            bool isAdded = false;
+
+            using (StreamReader reader = new StreamReader(buildGradlePath))
+            {
+                string line;
+                while ((line = reader.ReadLine()) != null)
+                {
+                    if (line.Contains("task handleNetworkResMerge")) {
+                        isAdded = true;
+                    }
+                    lines.Add(line);
+                }
+            }
+            if (isAdded) {
+                return;
+            }
+            using (StreamReader reader = new StreamReader("Assets/AnyThinkPlugin/Script/Editor/network_res_handle.gradle"))
+            {
+                string line;
+                while ((line = reader.ReadLine()) != null)
+                {
+                    lines.Add(line);
+                }
+            }
+            using (StreamWriter writer = new StreamWriter(buildGradlePath))
+            {
+                foreach (string line in lines)
+                {
+                    writer.WriteLine(line);
+                }
+            }
+        }
+
+        private static void callGradleTask(string path) {
+            // 设置你想要启动的Gradle任务
+            string gradleTask = "handleNetworkResMerge"; // 例如: assembleDebug or assembleRelease
+
+            // 开始一个新的进程来执行Gradle任务
+            ProcessStartInfo psi = new ProcessStartInfo();
+            psi.FileName = Application.platform == RuntimePlatform.WindowsEditor ? "cmd" : "bash";
+            psi.Arguments = Application.platform == RuntimePlatform.WindowsEditor ?
+                $"/c gradlew {gradleTask}" : // Windows cmd命令
+                $"-c './gradlew {gradleTask}'"; // UNIX bash命令
+            psi.UseShellExecute = false;
+            psi.StandardOutputEncoding = Encoding.UTF8;
+            psi.StandardErrorEncoding = Encoding.UTF8;
+            psi.RedirectStandardOutput = true;
+            psi.RedirectStandardError = true;
+            psi.CreateNoWindow = true;
+            psi.WorkingDirectory = "/Users/quinx/Desktop/workspace_topon/sdk_source/a_unity_demo/TestAnyThinkUnityPlugin/Library/Bee/Android/Prj/Mono2x/Gradle"; // 这里应该是你的Android项目路径
+
+            ATLog.log("callGradleTask() >>> path: " + path);
+
+            using (var process = Process.Start(psi))
+            {
+                // 读取输出信息
+                while (!process.StandardOutput.EndOfStream)
+                {
+                    var line = process.StandardOutput.ReadLine();
+                    UnityEngine.Debug.Log(line);
+                }
+                // 读取错误信息
+                while (!process.StandardError.EndOfStream)
+                {
+                    var line = process.StandardError.ReadLine();
+                    UnityEngine.Debug.LogError(line);
+                }
+            }
+        }
+    }
+}
+#endif

+ 11 - 0
Assets/AnyThinkPlugin/Script/Editor/ATProcessBuildGradleAndroid.cs.meta

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

+ 11 - 0
Assets/AnyThinkPlugin/Script/Editor/AnyThinkPlugin.Script.Editor.asmdef

@@ -0,0 +1,11 @@
+{
+    "name": "AnyThinkPlugin.Script.Editor",
+    "references": [
+        "AnyThinkPlugin.Script",
+        "AnyThinkPlugin.Script.IntegrationManager.Editor"
+    ],
+    "includePlatforms": [
+        "Editor"
+    ],
+    "excludePlatforms": []
+}

+ 7 - 0
Assets/AnyThinkPlugin/Script/Editor/AnyThinkPlugin.Script.Editor.asmdef.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: fe7f15635ecfd4b0a9b59690ece5d0c6
+AssemblyDefinitionImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 4 - 0
Assets/AnyThinkPlugin/Script/Editor/anythink_network_security_config.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+    <base-config cleartextTrafficPermitted="true" />
+</network-security-config>

+ 7 - 0
Assets/AnyThinkPlugin/Script/Editor/anythink_network_security_config.xml.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 9d4c4072cdc0f40c0b81bc2dc3d2dac2
+TextScriptImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager.meta

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

+ 8 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor.meta

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

+ 47 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATAssetPostprocessor.cs

@@ -0,0 +1,47 @@
+using System;
+using UnityEditor;
+using UnityEngine;
+using AnyThink.Scripts.IntegrationManager.Editor;
+
+[InitializeOnLoad]
+public class ATAssetPostprocessor : AssetPostprocessor
+{
+    private static readonly string TAG = "ATAssetPostprocessor";
+
+    static ATAssetPostprocessor()
+    {
+        log("ATAssetPostprocessor is now initialized!");
+    }
+    void OnPostprocessAsset(string path)
+    {
+        log("OnPostprocessAsset() >>> path: " + path + " assetPath: " + assetPath);
+    }
+
+    static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
+    {
+        foreach (string str in importedAssets)
+        {
+            log("imported Asset: " + str);
+        }
+        foreach (string str in deletedAssets)
+        {
+            log("Deleted Asset: " + str);
+        }
+
+        for (int i = 0; i < movedAssets.Length; i++)
+        {
+            log("Moved Asset: " + movedAssets[i] + " from: " + movedFromAssetPaths[i]);
+        }
+        
+    }
+
+    void OnPreprocessAsset()
+    {
+        log("OnPreprocessAsset() >>> called assetPath: " + assetPath);
+    }
+
+    private static void log(string msg)
+    {
+        ATLog.log(TAG, msg);
+    }
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATAssetPostprocessor.cs.meta

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

+ 426 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATConfig.cs

@@ -0,0 +1,426 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml.Linq;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.Networking;
+// using AnyThink.Scripts.Assets;
+using System.Text.RegularExpressions;
+
+namespace AnyThink.Scripts.IntegrationManager.Editor
+{
+
+    public class ATConfig
+    {
+public static string PLUGIN_VERSION = "2.1.5";
+public static bool isDebug = false;
+
+        public static int PLUGIN_TYPE = 1;
+        public static int OS_ANDROID = 1;
+        public static int OS_IOS = 2;
+        public static int CHINA_COUNTRY = 1;
+        public static int NONCHINA_COUNTRY = 2;
+        public static string ANYTHINK_SDK_FILES_PATH = "Assets/AnyThinkPlugin/AnyThinkAds";
+        //国内Android core包的相关目录
+        public static string[] CHINA_ANDROID_CORE_FILES_ARRAY = {Path.Combine(ANYTHINK_SDK_FILES_PATH, "Plugins/Android/China/Editor"), 
+        Path.Combine(ANYTHINK_SDK_FILES_PATH, "Plugins/Android/China/anythink_base"), 
+        Path.Combine(ANYTHINK_SDK_FILES_PATH, "Plugins/Android/China/mediation_plugin")};
+        //海外Android core包的相关目录
+        public static string[] NON_CHINA_ANDROID_CORE_FILES_ARRAY = {Path.Combine(ANYTHINK_SDK_FILES_PATH, "Plugins/Android/NonChina/anythink_base"), 
+        Path.Combine(ANYTHINK_SDK_FILES_PATH, "Plugins/Android/NonChina/Editor")};
+
+        //国内core aar包的父目录
+        public static string CHINA_ANDROID_CORE_FILES_PATH = Path.Combine(ANYTHINK_SDK_FILES_PATH, "Plugins/Android/China/anythink_base/");
+        public static string NONCHINA_ANDROID_CORE_FILES_PATH = Path.Combine(ANYTHINK_SDK_FILES_PATH, "Plugins/Android/NonChina/anythink_base/");
+        //国内Android network aar包的父目录
+        public static string CHINA_ANDROID_NETWORK_FILES_PARENT_PATH = Path.Combine(ANYTHINK_SDK_FILES_PATH, "Plugins/Android/China/mediation/");
+        //海外Android network 依赖文件的目录
+        public static string NONCHINA_ANDROID_NETWORK_FILES_PARENT_PATH = Path.Combine(ANYTHINK_SDK_FILES_PATH, "Plugins/Android/NonChina/mediation/");
+        //iOS network依赖文件的目录,不区分国家
+        public static string IOS_NETWORK_FILES_PARENT_PATH = Path.Combine(ANYTHINK_SDK_FILES_PATH, "Plugins/iOS/China/");
+        public static string NONCHINA_IOS_NETWORK_FILES_PARENT_PATH = Path.Combine(ANYTHINK_SDK_FILES_PATH, "Plugins/iOS/NonChina/");
+        //network json文件名
+        public static string network_data_file_name = "network_data.json";
+        //插件设置的数据
+        public static string plugin_setting_data_path = "Assets/AnyThinkPlugin/Resources/json/" + PLUGIN_VERSION;
+        private static string plugin_setting_data_file_name = "plugin_setting_data.json";
+
+        //保存插件设置的数据,保存时机:安装core包、选择国家、切换SDK、androidX设置发生变化时
+        public static void savePluginSettingData(PluginSettingData settingData)
+        {
+            var directoryPath = plugin_setting_data_path;
+            // 确保目标文件夹存在
+            if (!Directory.Exists(directoryPath))
+            {
+                // 如果目录不存在,则创建它
+                Directory.CreateDirectory(directoryPath);
+            }
+            string fullPath = Path.Combine(directoryPath, plugin_setting_data_file_name);
+            string settingDataStr = JsonUtility.ToJson(settingData);
+            ATLog.log("savePluginSettingData() >>> fullPath: " + fullPath + " settingDataStr: " + settingDataStr);
+            File.WriteAllText(fullPath, settingDataStr);
+        }
+        //获取插件设置的数据
+        public static PluginSettingData getPluginSettingData()
+        {
+            string fullPath = Path.Combine(plugin_setting_data_path, plugin_setting_data_file_name);
+            if (!File.Exists(fullPath)) {
+                return null;
+            }
+            string json = File.ReadAllText(fullPath);
+            if(json == "") {
+                return null;
+            }
+            return JsonUtility.FromJson<PluginSettingData>(json);
+        }
+
+        public static bool removeSdk(int country, int os) {
+            string path = ANYTHINK_SDK_FILES_PATH + "/Plugins";
+             if (os == OS_ANDROID) {
+                path = path + "/Android";
+            } else {
+                path = path + "/iOS";
+            }
+            if (country == CHINA_COUNTRY) {
+                path = path + "/China";
+            } else {
+                path = path + "/NonChina";
+            }
+            if (Directory.Exists(path)) {
+                FileUtil.DeleteFileOrDirectory(path);
+            }
+            if (File.Exists(path + ".meta")) {
+                FileUtil.DeleteFileOrDirectory(path + ".meta");
+            }
+            return true;
+        }
+
+        //移除本地的network
+        public static bool removeInstalledNetwork(Network network, int os)
+        {
+             //修改sdk的配置
+            if (isCoreNetwork(network.Name) && os == OS_ANDROID) {
+                var paths = CHINA_ANDROID_CORE_FILES_ARRAY;
+                if (network.Country == NONCHINA_COUNTRY) {
+                    paths = NON_CHINA_ANDROID_CORE_FILES_ARRAY;
+                }
+                foreach(string p in paths) {
+                    if (Directory.Exists(p)) {
+                        FileUtil.DeleteFileOrDirectory(p);
+                    }
+                    if (File.Exists(p + ".meta")) {
+                        FileUtil.DeleteFileOrDirectory(p + ".meta");
+                    }
+                }
+                return true;
+            }
+            var path = getAndroidNetworkPath(network);
+            if (os == OS_IOS) {
+                path = getIosNetworkPath(network);
+            }
+            if (Directory.Exists(path)) {
+                FileUtil.DeleteFileOrDirectory(path);
+                if (File.Exists(path + ".meta")) {
+                    FileUtil.DeleteFileOrDirectory(path + ".meta");
+                }
+            }
+            //针对mintegral改名字为gtm后,旧版升级到新版,旧版的mintegral目录需要删除
+            var displayName = network.DisplayName;
+            var name = network.Name;
+            ATLog.log("removeInstalledNetwork() >>> displayName: " + displayName + " name: " + name);
+            if (Equals(displayName, "Mintegral") && Equals(name, "Gtm"))
+            {
+                displayName = "mintegral";
+                var mtgPath = getNetworkInstallPath(displayName, os, network.Country);
+                if (Directory.Exists(mtgPath))
+                {
+                    FileUtil.DeleteFileOrDirectory(mtgPath);
+                    if (File.Exists(mtgPath + ".meta"))
+                    {
+                        FileUtil.DeleteFileOrDirectory(mtgPath + ".meta");
+                    }
+                }
+            }
+            return true;
+        }
+
+        // 保存已安装的network到本地
+        public static void saveInstalledNetworkVersion(Network network, int os)
+        {
+            if (isCoreNetwork(network.Name)) {
+                return;
+            }
+            var networkDataFileName = network_data_file_name;
+            var networkName = network.Name.ToLower();
+            int country = network.Country;
+            var installedVersions = network.CurrentVersions;
+            if (installedVersions != null) {
+                if (os == OS_ANDROID) {
+                    var android_version = installedVersions.Android;
+                    //Android 
+                    if (!string.IsNullOrEmpty(android_version)) {
+                        var networkPath = getAndroidNetworkPath(network);
+                        Directory.CreateDirectory(networkPath);
+                        ATLog.log("saveInstalledNetworkVersion() >>> android networkPath: " + networkPath + " exist: " + Directory.Exists(networkPath));
+                        if (Directory.Exists(networkPath)) {
+                            string fullPath = Path.Combine(networkPath, networkDataFileName);
+                            var networkData = new NetworkLocalData();
+                            networkData.name = networkName;
+                            networkData.country = country;
+                            networkData.version = android_version;
+                            networkData.path = networkPath;
+
+                            File.WriteAllText(fullPath, JsonUtility.ToJson(networkData));
+                        }
+                    }
+                } else {
+                    //iOS
+                    var ios_version = installedVersions.Ios;
+                    if (!string.IsNullOrEmpty(ios_version)) {
+                        var networkPath = getIosNetworkPath(network);
+                        Directory.CreateDirectory(networkPath);
+                        ATLog.log("saveInstalledNetworkVersion() >>> ios networkPath: " + networkPath);
+                        if (Directory.Exists(networkPath)) {
+                            string fullPath = Path.Combine(networkPath, networkDataFileName);
+                            var networkData = new NetworkLocalData();
+                            networkData.name = networkName;
+                            networkData.country = country;
+                            networkData.version = ios_version;
+                            networkData.path = networkPath;
+
+                            File.WriteAllText(fullPath, JsonUtility.ToJson(networkData));
+                        }
+                    }
+                }
+            }
+        }
+
+        //Core 是否已安装
+        public static bool isCoreNetworkInstalled(PluginSettingData pluginSettingData, int os) {
+            var countrySettingData = pluginSettingData.getCountrySettingData();
+            if (os == OS_ANDROID) {
+                return !string.IsNullOrEmpty(countrySettingData.android_version);
+            } else {
+                return !string.IsNullOrEmpty(countrySettingData.ios_version);
+            }
+        }
+
+        //Network是否已安装
+        public static bool isNetworkInstalled(Network network, int os)
+        {
+            if (isCoreNetwork(network.Name)) {
+                var pluginSettingData = getPluginSettingData();
+                return isCoreNetworkInstalled(pluginSettingData, os);
+            }
+            var path = getIosNetworkPath(network);
+            if (os == OS_ANDROID) {
+                path = getAndroidNetworkPath(network);
+            }
+            return File.Exists(Path.Combine(path, network_data_file_name));
+        }
+
+        //Network是否已安装,根据name
+        public static bool isNetworkInstalledByName(string name, int os)
+        {
+            var pluginSettingData = getPluginSettingData();
+            if (pluginSettingData != null) {
+                var country = pluginSettingData.curCountry;
+                var network = new Network();
+                network.Name = name;
+                network.Country = country;
+                return isNetworkInstalled(network, os);
+            }
+            return false;
+        }
+
+        private static string getAndroidNetworkPath(Network network)
+        {
+            var networkName = network.Name.ToLower();
+            var country = network.Country;
+            if (isCoreNetwork(networkName))
+            {
+                return country == CHINA_COUNTRY ? CHINA_ANDROID_CORE_FILES_PATH : NONCHINA_ANDROID_CORE_FILES_PATH;
+            }
+            else
+            {
+                return country == CHINA_COUNTRY ? CHINA_ANDROID_NETWORK_FILES_PARENT_PATH + networkName.ToLower() : NONCHINA_ANDROID_NETWORK_FILES_PARENT_PATH + networkName.ToLower();
+            }
+        }
+
+        private static string getIosNetworkPath(Network network)
+        {
+            var networkName = network.Name.ToLower();
+            var country = network.Country;
+            // if (isCoreNetwork(networkName))
+            // {
+            //     return IOS_NETWORK_FILES_PARENT_PATH;
+            // } else {
+            // }
+            return country == CHINA_COUNTRY ? IOS_NETWORK_FILES_PARENT_PATH + networkName : NONCHINA_IOS_NETWORK_FILES_PARENT_PATH + networkName;
+        }
+
+        //根据network名字去获取安装路径
+        private static string getNetworkInstallPath(string networkName, int os, int country)
+        {
+            if (os == OS_ANDROID) {
+                return country == CHINA_COUNTRY ? CHINA_ANDROID_NETWORK_FILES_PARENT_PATH + networkName.ToLower() : NONCHINA_ANDROID_NETWORK_FILES_PARENT_PATH + networkName.ToLower();
+            } else {
+                return country == CHINA_COUNTRY ? IOS_NETWORK_FILES_PARENT_PATH + networkName : NONCHINA_IOS_NETWORK_FILES_PARENT_PATH + networkName;
+            }
+        }
+
+        
+        public static int getSelectedCountry()
+        {
+            var pluginSettingData = getPluginSettingData();
+            if (pluginSettingData != null)
+            {
+                return pluginSettingData.curCountry;
+            }
+            return CHINA_COUNTRY;
+        }
+
+
+        public static bool isCoreNetwork(string networkName) {
+            return Equals(networkName.ToLower(), ATIntegrationManager.AnyThinkNetworkName.ToLower());
+        }
+
+        //查找本地是否有已安装network,并进行版本赋值
+        public static void initNetworkLocalData(Network network) {
+            var networkDataFileName = network_data_file_name;
+            var androidPath = getAndroidNetworkPath(network);
+            var iosPath = getIosNetworkPath(network);
+
+            var androidDataFile = Path.Combine(androidPath, networkDataFileName);
+            var iosDataFile = Path.Combine(iosPath, networkDataFileName);
+
+            var curVersions = network.CurrentVersions;
+            if (curVersions == null) {
+                curVersions = new Versions();
+            }
+
+            if (File.Exists(androidDataFile)) {
+                string a_json = File.ReadAllText(androidDataFile);
+                var a_data = JsonUtility.FromJson<NetworkLocalData>(a_json);
+                curVersions.Android = a_data.version;
+            }
+           
+            if (File.Exists(iosDataFile)) {
+                string i_json = File.ReadAllText(iosDataFile);
+                var i_data = JsonUtility.FromJson<NetworkLocalData>(i_json);
+                curVersions.Ios = i_data.version;
+            }
+            network.CurrentVersions = curVersions;
+        }
+
+        //当前是否选择国内地区
+        public static bool isSelectedChina() {
+            var pluginSettingData = getPluginSettingData();
+            if (pluginSettingData != null) {
+                return pluginSettingData.curCountry == CHINA_COUNTRY;
+            }
+            return true;
+        }
+
+        //获取admob app id
+        public static string getAdmobAppIdByOs(int os) {
+            var pluginSettingData = getPluginSettingData();
+            if (pluginSettingData == null) {
+                return "";
+            }
+            var settingData = pluginSettingData.getCountrySettingData();
+            return settingData.getAdmobAppId(os);
+        }
+
+        public static bool enableAndroidX() {
+            var pluginSettingData = getPluginSettingData();
+            if (pluginSettingData == null) {
+                return false;
+            }
+            return pluginSettingData.getCountrySettingData().androidXSetting == 1;
+        }
+
+        public static bool isDefaultAndroidX() {
+            var pluginSettingData = getPluginSettingData();
+            if (pluginSettingData == null) {
+                return false;
+            }
+            return pluginSettingData.getCountrySettingData().androidXSetting == 0;
+        }
+
+        //获取默认选中的地区
+        public static int getDefCountry() {
+            // string version = PLUGIN_VERSION;
+            // int lastIndex = version.LastIndexOf('.');
+        
+            // if (lastIndex != -1)
+            // {   
+            //     //2.1.0:是区分国内海外的插件,2.1.01:后缀多了1,是只有海外的插件
+            //     string lastPart = version.Substring(lastIndex + 1);
+            //     if (lastPart.Length == 2) {
+            //         return NONCHINA_COUNTRY;
+            //     }
+            // }
+            if(PLUGIN_TYPE == 2) {
+                return NONCHINA_COUNTRY;
+            }
+            return CHINA_COUNTRY;
+        }
+
+        public static string[] getCountryArray() {
+            // new string[] { "ChinaMainland", "Overseas" }
+            // string version = PLUGIN_VERSION;
+            // int lastIndex = version.LastIndexOf('.');
+        
+            // if (lastIndex != -1)
+            // {   
+            //     //2.1.0:是区分国内海外的插件,2.1.01:后缀多了1,是只有海外的插件
+            //     string lastPart = version.Substring(lastIndex + 1);
+            //     if (lastPart.Length == 2) {
+            //         return new string[] { "Overseas" };
+            //     }
+            // }
+            if(PLUGIN_TYPE == 2) {
+                return new string[] { "Overseas" };
+            }
+            return new string[] { "ChinaMainland", "Overseas" };
+        }
+
+        public static string getRegionIntegrateTip()
+        {
+            //Tips: If ChinaMainland and Oversea are integrated at the same time, there will be compilation conflicts, whether it is Android or iOS platform.
+            //Currently, the Android platform integrates ChinaMainland and Oversea at the same time, which may cause compilation errors or other errors.
+            var pluginSettingData = getPluginSettingData();
+            if (pluginSettingData == null) {
+                return "";
+            }
+            var sb = new StringBuilder();
+            sb.Append("Tips: Currently, ");
+            var android_tip = false;
+            if (pluginSettingData.isBothInstallAndroid()) {
+                sb.Append("the Android platform ");
+                android_tip = true;
+            }
+            var ios_tip = false;
+            if (pluginSettingData.isBothInstallIOS()) {
+                if (android_tip) {
+                    sb.Append("and ");
+                }
+                sb.Append("iOS platform ");
+                ios_tip = true;
+            }
+
+            if (android_tip || ios_tip) {
+                sb.Append("integrates ChinaMainland and Oversea at the same time, which may cause compilation error or other errors.");
+                return sb.ToString();
+            } else {
+                return "";
+            }
+        }
+    }
+
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATConfig.cs.meta

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

+ 355 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATDataUtil.cs

@@ -0,0 +1,355 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.Networking;
+
+namespace AnyThink.Scripts.IntegrationManager.Editor
+{
+    public class ATDataUtil
+    {
+
+        public static Network coreNetwork;
+
+        public static Network[] parseNetworksJson(PluginData pluginData, string netowrksJson)
+        {
+            try
+            {
+                int country = pluginData.country;
+                bool isChinaCountry = isChina(country);
+
+                ServerNetworks serverNetworks = JsonUtility.FromJson<ServerNetworks>(netowrksJson);
+
+                Network network = pluginData.anyThink;
+                if (network == null) {
+                    return null;
+                }
+                var android_version = pluginData.requestParams.androidVersion;
+                var ios_version = pluginData.requestParams.iosVersion;
+
+                var androidSdkVersionList = serverNetworks.android_sdk;
+                var iosSdkVersionList = serverNetworks.ios_sdk;
+
+                ServerNetworkSdk androidNeworkSdk = null;
+                if (!string.IsNullOrEmpty(android_version)) {
+                    foreach(ServerNetworkSdk sdk in androidSdkVersionList) {
+                        if (Equals(sdk.version, android_version)) {
+                            androidNeworkSdk = sdk;
+                        }
+                    }
+                }
+             
+                ServerNetworkSdk iosNeworkSdk = null;
+                if (!string.IsNullOrEmpty(ios_version)) {     
+                    foreach(ServerNetworkSdk sdk in iosSdkVersionList) {
+                        if (Equals(sdk.version, ios_version)) {
+                            iosNeworkSdk = sdk;
+                        }
+                    }
+                }
+                ATLog.log("parseNetworksJson() >>> androidNeworkSdk: " + androidNeworkSdk + " iosNeworkSdk: " + iosNeworkSdk);
+
+                ServerNetworkInfo[] serverNetworkInfoList;
+                Network[] networks = mergeAndroidIosNetworks(getServerNetworkInfo(isChinaCountry, androidNeworkSdk, ATConfig.OS_ANDROID), getServerNetworkInfo(isChinaCountry, iosNeworkSdk,  ATConfig.OS_IOS));
+                Array.Sort(networks);
+                ATLog.log("parseNetworksJson() >>> networks.Length: " + networks.Length);
+                //处理本地已安装过的Core和Network数据
+                var countrySettingData = pluginData.pluginSettingData.getCountrySettingData();
+
+                List<Network> networkList = new List<Network>();
+                foreach(var item in networks) {
+                    if (Equals(item.Name, ATIntegrationManager.AnyThinkNetworkName)) {
+                        network.Name = item.Name;
+                        network.DisplayName = item.DisplayName;
+                        network.AndroidDownloadUrl = item.AndroidDownloadUrl;
+                        network.iOSDownloadloadUrl = item.iOSDownloadloadUrl;
+                        network.PluginFileName = item.PluginFileName;
+                        //本地是否有安装core
+                        var version = network.CurrentVersions;
+                        if (version == null) {
+                            version = new Versions();
+                        }
+                        version.Android = countrySettingData.android_version;
+                        version.Ios = countrySettingData.ios_version;
+                        network.CurrentVersions = version;
+                        network.LatestVersions = item.LatestVersions;
+                    } else {
+                        // ATLog.log("parseNetworksJson() >>> lastAndroidVersion: " + item.LatestVersions.Android + " lastIosVerion: " + item.LatestVersions.Ios);
+                        //本地是否有安装network
+                        ATConfig.initNetworkLocalData(item);
+                        networkList.Add(item);
+                    }
+                }
+
+                return networkList.ToArray();
+            }
+            catch (Exception e)
+            {
+                // 错误处理代码
+                ATLog.log("parseNetworksJson() >>> failed: " + e);
+            }
+
+            return null;
+        }
+
+        public static PluginData parsePluginDataJson(string serverPluginVersionJson)
+        {
+            ATLog.log("parsePluginDataJson plugin version data: " + serverPluginVersionJson);
+
+            try
+            {
+                var pluginData = new PluginData();
+
+                ServerPluginVersion serverPluginVersion = JsonUtility.FromJson<ServerPluginVersion>(serverPluginVersionJson);
+
+                pluginData.androidVersions = serverPluginVersion.android_versions;
+                pluginData.iosVersions = serverPluginVersion.ios_versions;
+                pluginData.pluginVersion = serverPluginVersion.pluginVersion;
+                // 初始化本地的core包数据
+                var settingData = ATConfig.getPluginSettingData();
+                if (settingData == null) {
+                   settingData = new PluginSettingData();
+                   ATConfig.savePluginSettingData(settingData);
+                }
+                pluginData.country = settingData.curCountry;
+                pluginData.pluginSettingData = settingData;
+                pluginData.anyThink = initCoreNetworkWithLocalData(settingData);
+                return pluginData;
+            }
+            catch (Exception e)
+            {
+                // 错误处理代码
+                ATLog.log("parse version data failed: " + e);
+            }
+
+            return null;
+        }
+
+        public static Network initCoreNetworkWithLocalData(PluginSettingData settingData) {
+            var network = new Network();
+            var versions = new Versions();
+            var countryData = settingData.getCountrySettingData();
+            if (countryData != null) {
+                versions.Android = countryData.android_version;
+                versions.Ios = countryData.ios_version;
+            }
+            network.CurrentVersions = versions;
+            network.Country = settingData.curCountry;
+            return network;
+        }
+
+        public static ServerNetworkInfo[] getServerNetworkInfo(bool isChina, ServerNetworkSdk serverNetworks, int os) {
+            if (serverNetworks == null) {
+                return null;
+            }
+            if (isChina) {
+                return serverNetworks.network_list.china;
+            } else {
+                return serverNetworks.network_list.nonchina;
+            }
+        }
+
+        private static IEnumerable<ServerNetworkInfo> GetUniqueNetworkInfo(ServerNetworkInfo[] androidNetworks, ServerNetworkInfo[] iosNetworks)
+        {
+            // Android独有的
+            var uniqueToAndroid = androidNetworks.Where(a => !iosNetworks.Any(i => i.displayName == a.displayName));
+
+            // iOS独有的
+            var uniqueToIos = iosNetworks.Where(i => !androidNetworks.Any(a => a.displayName == i.displayName));
+                
+            // 合并结果
+            return uniqueToAndroid.Concat(uniqueToIos);
+        }
+
+        //合并Android和iOS的network数据
+        public static Network[] mergeAndroidIosNetworks(ServerNetworkInfo[] androidNetworks, ServerNetworkInfo[] iosNetworks)
+        {
+            int a_length = 0;
+            int i_length = 0;
+            if (androidNetworks != null) {
+               a_length = androidNetworks.Length;
+            }
+            if (iosNetworks != null) {
+               i_length = iosNetworks.Length;
+            }
+            ATLog.log("mergeAndroidIosNetworks() >>> a_length: " + a_length + " i_length: " + i_length);
+
+            int max_length = Math.Max(a_length, i_length);
+            int min_length = Math.Min(a_length, i_length);
+
+            var externalNetworks = androidNetworks;
+            var internalNetworks = iosNetworks;
+            if (a_length < i_length) {
+                externalNetworks = iosNetworks;
+                internalNetworks = androidNetworks;
+            }
+
+            List<Network> networkList = new List<Network>();
+            ATLog.log("mergeAndroidIosNetworks() >>> max_length: " + max_length + " min_length: " + min_length);
+            for (int i = 0; i < max_length; i++) {
+                var network = new Network();
+                var iNetwork = externalNetworks[i];
+                if (min_length == 0) {
+                    //只有集成一个平台
+                    network = flatServerNetwork(iNetwork, network);
+                    networkList.Add(network);
+                } else {
+                    //合并相同的network
+                    for (int j = 0; j < min_length; j++) {
+                        var jNetwork = internalNetworks[j];
+                        if (Equals(iNetwork.displayName, jNetwork.displayName)) {
+                            network = flatServerNetwork(iNetwork, network);
+                            network = flatServerNetwork(jNetwork, network);
+                            networkList.Add(network);
+                        }
+                    }
+                }
+            }
+            //过滤平台的唯一network
+            if (i_length > 0 && a_length > 0) {
+                var serverNetworkInfos = GetUniqueNetworkInfo(androidNetworks, iosNetworks);
+                foreach (var serverNetworkInfo in serverNetworkInfos)
+                {
+                    var network = new Network();
+                    networkList.Add(flatServerNetwork(serverNetworkInfo, network));
+                }
+            }
+
+            return networkList.ToArray();
+        }
+
+        //后台下载数据转换成本地数据
+        public static Network flatServerNetwork(ServerNetworkInfo serverInfo, Network network)
+        {
+            network.Name = serverInfo.name;
+            network.DisplayName = serverInfo.displayName;
+            network.Country = serverInfo.country;
+            network.PluginFileName = serverInfo.pluginFileName;
+
+            var versions = network.LatestVersions;
+            if (versions == null) {
+                versions = new Versions();
+            }
+            if (serverInfo.os == ATConfig.OS_ANDROID) { //Android
+                network.AndroidDownloadUrl = serverInfo.downloadUrl;
+                versions.Android = serverInfo.version;
+            } else { //iOS
+                network.iOSDownloadloadUrl = serverInfo.downloadUrl;
+                versions.Ios = serverInfo.version;
+            }
+            ATLog.log("flatServerNetwork() >>> name: " + network.Name + " androidVersion: " + versions.Android + " iosVersion: " + versions.Ios);
+            network.LatestVersions = versions;
+            return network;
+        }
+
+        public static bool isChina(int country)
+        {
+            return country == ATConfig.CHINA_COUNTRY;
+        }
+
+
+        //只比较Android、iOS
+        public static VersionComparisonResult CompareVersions(string versionA, string versionB)
+        {
+            if (string.IsNullOrEmpty(versionA) || string.IsNullOrEmpty(versionB) || versionA.Equals(versionB))
+            {
+                return VersionComparisonResult.Equal;
+            }
+
+            try
+            {
+                var aVersionArrays = versionA.Split('.');
+                var bVersionArrays = versionB.Split('.');
+
+                var arrayLength = Mathf.Min(aVersionArrays.Length, bVersionArrays.Length);
+                for (var i = 0; i < arrayLength; i++)
+                {
+                    var aVersionStr = aVersionArrays[i];
+                    var bVersionStr = bVersionArrays[i];
+
+                    var aVersionInt = int.Parse(aVersionStr);
+                    var bVersionInt = int.Parse(bVersionStr);
+
+                    if (i == arrayLength - 1) //末尾最后一个
+                    {
+                        if (aVersionStr.Length > bVersionStr.Length)
+                        {
+                            int gapLength = aVersionStr.Length - bVersionStr.Length;
+                            bVersionInt = bVersionInt * (gapLength * 10);
+                        }
+                        else if (aVersionStr.Length < bVersionStr.Length)
+                        {
+                            int gapLength = bVersionStr.Length - aVersionStr.Length;
+                            aVersionInt = aVersionInt * (gapLength * 10);
+                        }
+                    }
+                    if (aVersionInt < bVersionInt) return VersionComparisonResult.Lesser;
+                    if (aVersionInt > bVersionInt) return VersionComparisonResult.Greater;
+                }
+            }
+            catch (Exception e)
+            {
+                ATLog.logError("CompareVersions failed: " + e.Message);
+            }
+
+            return VersionComparisonResult.Equal;
+        }
+    }
+
+    //下发的插件数据:{"pluginVersion": "2.1.0", "platformName": "AnyThink", "ios_versions": ["6.2.88"], "android_versions": ["6.2.93"]}
+    [Serializable]
+    public class ServerPluginVersion
+    {
+        public string platformName;
+        // public string networkUrlVersion;
+        public string pluginVersion;
+        public string[] android_versions;
+        public string[] ios_versions;
+    }
+
+    [Serializable]
+    public class ServerNetworks
+    {
+        public string plugin_version;
+        public ServerNetworkSdk[] ios_sdk;
+        public ServerNetworkSdk[] android_sdk;
+    }
+
+    [Serializable]
+    public class ServerNetworkSdk
+    {
+        public string version;
+        public ServerNetworkListObj network_list; 
+    }
+
+    [Serializable]
+    public class ServerNetworkListObj
+    {
+        public ServerNetworkInfo[] china;
+        public ServerNetworkInfo[] nonchina;
+    }
+
+    [Serializable]
+    public class ServerNetworkInfo
+    {
+        public string name;
+        public string displayName;
+        public string downloadUrl;
+        public string pluginFileName;
+        public string version;
+        public int os;
+        public int country;
+        // public ServerNetworkVersion versions;
+    }
+    [Serializable]
+    public class ServerNetworkVersion
+    {
+        public string android;
+        public string ios;
+        public string unity;
+    }
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATDataUtil.cs.meta

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

+ 66 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATDownloadHandler.cs

@@ -0,0 +1,66 @@
+#if !UNITY_2017_2_OR_NEWER
+using System;
+using System.IO;
+using UnityEngine.Networking;
+
+namespace AnyThink.Scripts.IntegrationManager.Editor
+{
+    public class ATDownloadHandler : DownloadHandlerScript
+    {
+        // Required by DownloadHandler base class. Called when you address the 'bytes' property.
+        protected override byte[] GetData()
+        {
+            return null;
+        }
+
+        private FileStream fileStream;
+
+        public ATDownloadHandler(string path) : base(new byte[2048])
+        {
+            var downloadDirectory = Path.GetDirectoryName(path);
+            if (!Directory.Exists(downloadDirectory))
+            {
+                Directory.CreateDirectory(downloadDirectory);
+            }
+
+            try
+            {
+                //Open the current file to write to
+                fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
+            }
+            catch (Exception exception)
+            {
+                // MaxSdkLogger.UserError(string.Format("Failed to create file at {0}\n{1}", path, exception.Message));
+                ATLog.logError(string.Format("Failed to create file at {0}\n{1}", path, exception.Message));
+            }
+        }
+
+        protected override bool ReceiveData(byte[] byteFromServer, int dataLength)
+        {
+            if (byteFromServer == null || byteFromServer.Length < 1 || fileStream == null)
+            {
+                return false;
+            }
+
+            try
+            {
+                //Write the current data to the file
+                fileStream.Write(byteFromServer, 0, dataLength);
+            }
+            catch (Exception exception)
+            {
+                fileStream.Close();
+                fileStream = null;
+                ATLog.logError(string.Format("Failed to download file{0}", exception.Message));
+            }
+
+            return true;
+        }
+
+        protected override void CompleteContent()
+        {
+            fileStream.Close();
+        }
+    }
+}
+#endif

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATDownloadHandler.cs.meta

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

+ 74 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATEditorCoroutine.cs

@@ -0,0 +1,74 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+
+namespace AnyThink.Scripts.IntegrationManager.Editor
+{
+    public class ATEditorCoroutine
+    {
+        /// <summary>
+        /// Keeps track of the coroutine currently running.
+        /// </summary>
+        private IEnumerator enumerator;
+
+        /// <summary>
+        /// Keeps track of coroutines that have yielded to the current enumerator.
+        /// </summary>
+        private readonly List<IEnumerator> history = new List<IEnumerator>();
+
+        private ATEditorCoroutine(IEnumerator enumerator) {
+            this.enumerator = enumerator;
+        }
+
+
+        public static ATEditorCoroutine startCoroutine(IEnumerator enumerator) {
+            var coroutine = new ATEditorCoroutine(enumerator);
+            coroutine.Start();
+            return coroutine;
+        }
+
+        private void Start()
+        {
+            EditorApplication.update += OnEditorUpdate;
+        }
+
+        /// <summary>
+        /// Stops the coroutine.
+        /// </summary>
+        public void Stop()
+        {
+            if (EditorApplication.update == null) return;
+
+            EditorApplication.update -= OnEditorUpdate;
+        }
+
+        private void OnEditorUpdate()
+        {
+            if (enumerator.MoveNext())
+            {
+                // If there is a coroutine to yield for inside the coroutine, add the initial one to history and continue the second one
+                if (enumerator.Current is IEnumerator)
+                {
+                    history.Add(enumerator);
+                    enumerator = (IEnumerator) enumerator.Current;
+                }
+            }
+            else
+            {
+                // Current coroutine has ended, check if we have more coroutines in history to be run.
+                if (history.Count == 0)
+                {
+                    // No more coroutines to run, stop updating.
+                    Stop();
+                }
+                // Step out and finish the code in the coroutine that yielded to it
+                else
+                {
+                    var index = history.Count - 1;
+                    enumerator = history[index];
+                    history.RemoveAt(index);
+                }
+            }
+        }
+    }
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATEditorCoroutine.cs.meta

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

+ 447 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntegrationManager.cs

@@ -0,0 +1,447 @@
+
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.Networking;
+using UnityEditor.PackageManager.Requests;
+using UnityEditor.PackageManager;
+using System.Threading.Tasks;
+using System.Threading;
+
+namespace AnyThink.Scripts.IntegrationManager.Editor
+{
+    public class ATIntegrationManager
+    {
+        public static ATIntegrationManager Instance = new ATIntegrationManager();
+
+        // private UnityWebRequest downloadPluginRequest;
+
+        private const string AnyThinkAds = "AnyThinkAds";
+        //AnyThink的unity插件
+        public static string AnyThinkNetworkName = "Core";
+
+        private PluginData mPluginData;
+
+        private ATIntegrationManager()
+        {
+
+        }
+
+        public void CancelDownload()
+        {
+            // if (downloadPluginRequest == null) return;
+
+            // downloadPluginRequest.Abort();
+        }
+
+        public IEnumerator loadPluginData(Action<PluginData> callback)
+        {
+            var anythinkVersionRequest = UnityWebRequest.Get(ATNetInfo.getPluginConfigUrl(ATConfig.PLUGIN_VERSION));
+            var webRequest = anythinkVersionRequest.SendWebRequest();
+            while (!webRequest.isDone)
+            {
+                yield return new WaitForSeconds(0.1f);
+            }
+
+#if UNITY_2020_1_OR_NEWER
+            if (anythinkVersionRequest.result != UnityWebRequest.Result.Success)
+#elif UNITY_2017_2_OR_NEWER
+            if (anythinkVersionRequest.isNetworkError || anythinkVersionRequest.isHttpError)
+#else
+            if (anythinkVersionRequest.isError)
+#endif
+            {
+                Debug.Log("loadPluginData failed.");
+                callback(null);
+            }
+            else
+            {
+                //解析Anythink的版本数据
+                string anythinkVersionJson = anythinkVersionRequest.downloadHandler.text;
+                PluginData pluginData = ATDataUtil.parsePluginDataJson(anythinkVersionJson);
+                Debug.Log("loadPluginData succeed. country: " + pluginData.country + " androidVersions: " 
+                + pluginData.androidVersions + " iosVersions: " + pluginData.iosVersions);
+                mPluginData = pluginData;
+                callback(pluginData);
+            }
+        }
+
+        public IEnumerator loadNetworksData(PluginData pluginData, Action<PluginData> callback)
+        {
+
+            Network network = pluginData.anyThink;
+            if (pluginData == null)
+            {
+                callback(null);
+            }
+            else if (pluginData.requestParams == null) {
+                ATLog.log("loadNetworksData() >>> pluginData.requestParams is null");
+                callback(pluginData);
+            }
+            else
+            {
+                var networksRequest = UnityWebRequest.Get(ATNetInfo.getNetworkListUrl(ATConfig.PLUGIN_VERSION));
+                var webRequest = networksRequest.SendWebRequest();
+                while (!webRequest.isDone)
+                {
+                    yield return new WaitForSeconds(0.1f);
+                }
+
+#if UNITY_2020_1_OR_NEWER
+            if (networksRequest.result != UnityWebRequest.Result.Success)
+#elif UNITY_2017_2_OR_NEWER
+            if (networksRequest.isNetworkError || networksRequest.isHttpError)
+#else
+                if (networksRequest.isError)
+#endif
+                {
+                    Debug.Log("loadNetworksData failed.");
+                    callback(pluginData);
+                }
+                else
+                {
+                    //解析network列表的版本数据
+                    string netowrksJson = networksRequest.downloadHandler.text;
+                    ATLog.log("loadNetworksData() >>> netowrksJson: " + netowrksJson);
+                    pluginData.mediatedNetworks = ATDataUtil.parseNetworksJson(pluginData, netowrksJson);
+                    ATLog.log("loadNetworksData() >>> mediatedNetworks: " + pluginData.mediatedNetworks);
+                    mPluginData = pluginData;
+                    callback(pluginData);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Downloads the plugin file for a given network.
+        /// </summary>
+        /// <param name="network">Network for which to download the current version.</param>
+        /// <param name="showImport">Whether or not to show the import window when downloading. Defaults to <c>true</c>.</param>
+        /// <returns></returns>
+        public void downloadPlugin(Network network, int os =1, bool showImport = false)
+        {
+            ATEditorCoroutine.startCoroutine(downloadPluginWithEnumerator(network, os, showImport));
+        }
+
+        public IEnumerator downloadPluginWithEnumerator(Network network, int os, bool showImport)
+        {
+            ATLog.log("downloadPluginWithEnumerator() >>> networkName: " + network.Name + " os: " + os);
+            // if (downloadPluginRequest != null)
+            // {
+            //     downloadPluginRequest.Dispose();
+            // }
+            var path = Path.Combine(Application.temporaryCachePath, network.PluginFileName);
+            ATLog.log("downloadPluginWithEnumerator() >>> path: " + path);
+#if UNITY_2017_2_OR_NEWER
+            var downloadHandler = new DownloadHandlerFile(path);
+#else
+            var downloadHandler = new ATDownloadHandler(path);
+#endif
+            var downloadUrl = network.AndroidDownloadUrl;
+            if (os == ATConfig.OS_IOS) 
+            {
+                downloadUrl = network.iOSDownloadloadUrl;
+            }
+            UnityWebRequest downloadPluginRequest = new UnityWebRequest(downloadUrl) 
+            {    method = UnityWebRequest.kHttpVerbGET,
+                downloadHandler = downloadHandler
+            };
+
+#if UNITY_2017_2_OR_NEWER
+            var operation = downloadPluginRequest.SendWebRequest();
+#else
+            var operation = downloadPluginRequest.Send();
+#endif
+            while (!operation.isDone)
+            {
+                yield return new WaitForSeconds(0.1f); // Just wait till downloadPluginRequest is completed. Our coroutine is pretty rudimentary.
+                if (operation.progress != 1 && operation.isDone)
+                {
+                    // CallDownloadPluginProgressCallback(network.DisplayName, operation.progress, operation.isDone, os);
+                    UpdateCurrentVersions(network, os);
+                }
+            }
+
+#if UNITY_2020_1_OR_NEWER
+            if (downloadPluginRequest.result != UnityWebRequest.Result.Success)
+#elif UNITY_2017_2_OR_NEWER
+            if (downloadPluginRequest.isNetworkError || downloadPluginRequest.isHttpError)
+#else
+            if (downloadPluginRequest.isError)
+#endif
+            {
+                ATLog.logError(downloadPluginRequest.error);
+            }
+            else
+            {
+                AssetDatabase.ImportPackage(path, showImport);
+                UpdateCurrentVersions(network, os);
+                AssetDatabase.Refresh();
+            }
+            downloadPluginRequest.Dispose();
+            downloadPluginRequest = null;
+        }
+
+         //默认下载core包,在下载完network的数据时。
+        public void downloadCorePlugin(PluginData pluginData)
+        {   
+            mPluginData = pluginData;
+            var requestParams = pluginData.requestParams;
+            var pluginSettingData = pluginData.pluginSettingData;
+
+            bool isIosInstalled = ATConfig.isCoreNetworkInstalled(pluginSettingData, ATConfig.OS_IOS);
+            bool isAndroidInstalled = ATConfig.isCoreNetworkInstalled(pluginSettingData, ATConfig.OS_ANDROID);
+            ATLog.log("downloadCorePlugin() >>> isIosInstalled: " + isIosInstalled + " isAndroidInstalled: " + isAndroidInstalled);
+
+            Network network = pluginData.anyThink;
+            int os = requestParams.os;
+            if (os == ATConfig.OS_ANDROID) {
+                if (!isAndroidInstalled) {
+                    downloadPlugin(network, os);
+                } else {
+                    //判断是否需要切换SDK
+                    var latestVersions = network.LatestVersions;
+                    var curVersion = network.CurrentVersions;
+                    if (latestVersions.Android != curVersion.Android) {
+                        //先删除掉core包
+                        ATConfig.removeSdk(pluginData.country, os);
+                        removeNetworkVersions(pluginData, os);
+                        //赋值当前版本为空
+                        curVersion.Android = "";
+                        //重新下载core包
+                        downloadPlugin(network, os);
+                        //重新下载已安装的network
+                        redownloadNetworksPlugin(pluginData, os);
+                    }
+                }
+            } else if (os == ATConfig.OS_IOS){
+                if (!isIosInstalled) {
+                    downloadPlugin(network, os);
+                } else {
+                    //判断是否需要切换SDK
+                    var latestVersions = network.LatestVersions;
+                    var curVersion = network.CurrentVersions;
+                    if (latestVersions.Ios != curVersion.Ios) {
+                        //先删除掉core包
+                        ATConfig.removeSdk(pluginData.country, os);
+                        removeNetworkVersions(pluginData, os);
+                        //赋值当前版本为空
+                        curVersion.Ios = "";
+                        //重新下载core包
+                        downloadPlugin(network, os);
+                        //重新下载已安装的network
+                        redownloadNetworksPlugin(pluginData, os);
+                    }
+                }
+            }
+        }
+
+        //当切换SDK版本时,需要重新下载已安装的network
+        private void redownloadNetworksPlugin(PluginData pluginData, int os) {
+            var mediatedNetworks = pluginData.mediatedNetworks;
+            var needInstallNetworkList = new List<Network>();
+            foreach(Network network in mediatedNetworks) {
+                var currentVersion = network.CurrentVersions;
+                if (currentVersion != null) {
+                    if (os == ATConfig.OS_ANDROID) {
+                        if (!string.IsNullOrEmpty(currentVersion.Android)) {
+                            needInstallNetworkList.Add(network);
+                        }
+                    } else {
+                        if (!string.IsNullOrEmpty(currentVersion.Ios)) {
+                            needInstallNetworkList.Add(network);
+                        }
+                    }
+                }
+            }
+            if (needInstallNetworkList.Count() == 0) {
+                return;
+            }
+            Thread.Sleep(500);
+            ATEditorCoroutine.startCoroutine(UpgradeAllNetworks(needInstallNetworkList, os));
+        }
+
+        private IEnumerator UpgradeAllNetworks(List<Network> networks, int os) {
+            EditorApplication.LockReloadAssemblies();
+            foreach (var network in networks)
+            {
+
+                yield return downloadPluginWithEnumerator(network, os, false);
+            }
+            EditorApplication.UnlockReloadAssemblies();
+        }
+
+        public void networkInstallOrUpdate(PluginData pluginData, Network network, int os)
+        {
+            downloadPlugin(network, os);
+        }
+
+        //更新network已安装的版本
+        private void UpdateCurrentVersions(Network network, int os)
+        {
+            var latestVersions = network.LatestVersions;
+            var versions = network.CurrentVersions;
+            if (versions == null) {
+                versions = new Versions();
+            }
+            if (os == ATConfig.OS_ANDROID) {
+                versions.Android = latestVersions.Android;
+            } else {
+                versions.Ios = latestVersions.Ios;
+            }
+            network.CurrentVersions = versions;
+
+            // await Task.Delay(1000);
+            // Thread.Sleep(1000);
+            //下面的逻辑会延迟一秒后执行,确保unitypackage先解压到本地
+            ATConfig.saveInstalledNetworkVersion(network, os);
+            ATLog.log("UpdateCurrentVersions() >>> AndroidVersion: " + versions.Android);
+            //保存Core Networkde
+            if (ATConfig.isCoreNetwork(network.Name)) {
+                var countrySettingData = mPluginData.pluginSettingData.getCountrySettingData();
+                if (os == ATConfig.OS_ANDROID) {
+                    countrySettingData.android_version = latestVersions.Android;
+                } else {
+                    countrySettingData.ios_version = latestVersions.Ios;
+                }
+                
+                ATConfig.savePluginSettingData(mPluginData.pluginSettingData);
+            }
+            // ATLog.log("UpdateCurrentVersions() >>> Name: " + network.Name + " latest Unity Version: " + network.LatestVersions.Unity);
+        }
+
+        //点击了界面的network删除按钮
+        public void uninstallNetwork(Network network, int os)
+        {
+            var result = ATConfig.removeInstalledNetwork(network, os);
+            if (result) {
+                if (os == ATConfig.OS_ANDROID){
+                    network.CurrentVersions.Android = "";
+                } else {
+                    network.CurrentVersions.Ios = "";
+                }
+            }
+        }
+
+        //切换国家
+        public void switchCountry(PluginData pluginData, int country) {
+            pluginData.country = country;
+
+            var pluginSettingData = pluginData.pluginSettingData;
+            pluginSettingData.curCountry = country;
+
+            ATConfig.savePluginSettingData(pluginSettingData);
+        }
+
+        //获取AndroidX开关状态
+        public int getAndroidXSetting(PluginData pluginData) {
+            if (pluginData == null) {
+                return 0;
+            }
+            var pluginSettingData = pluginData.pluginSettingData;
+            if (pluginSettingData == null) {
+                return 0;
+            }
+            CountrySettingData countrySettingData = pluginSettingData.getCountrySettingData();
+            return countrySettingData.androidXSetting;
+        }
+
+        //设置并保存AndroidX开关状态
+        public void saveAndroidXSetting(PluginData pluginData, int androidXSetting) {
+            ATLog.log("saveAndroidXSetting() >>> androidXSetting: " + androidXSetting);
+            var pluginSettingData = pluginData.pluginSettingData;
+            CountrySettingData countrySettingData = pluginSettingData.getCountrySettingData();
+            countrySettingData.androidXSetting = androidXSetting;
+
+            ATConfig.savePluginSettingData(pluginSettingData);
+        }
+
+        //根据系统判断Admob是否有安装
+        public bool isAdmobInstalled(int os) {
+            return ATConfig.isNetworkInstalledByName("Admob", os);
+        }
+
+        public string getAdmobAppIdByOs(PluginData pluginData, int os) {
+            if (pluginData == null) {
+                return "";
+            }
+            //android_admob_app_id
+            var countrySettingData = pluginData.pluginSettingData.getCountrySettingData();
+            return countrySettingData.getAdmobAppId(os);
+        }
+
+        //设置保存Admob app id
+        public void setAdmobAppidByOs(PluginData pluginData, int os, string appId) {
+            if (pluginData == null || pluginData.pluginSettingData == null) {
+                return;
+            }
+            var countrySettingData = pluginData.pluginSettingData.getCountrySettingData();
+            countrySettingData.setAdmobAppId(appId, os);
+
+            ATConfig.savePluginSettingData(pluginData.pluginSettingData);
+        }
+
+        //删除某个版本的SDK
+        public void deleteSdk(PluginData pluginData, string sdkVersion, int os) {
+            ATLog.log("deleteSdk() >>> sdkVersion: " + sdkVersion + " os: " + os);
+            //删除本地文件
+            ATConfig.removeSdk(pluginData.country, os);
+            //修改UI显示
+            removeNetworkVersions(pluginData, os, true);
+            var curVersions = pluginData.anyThink.CurrentVersions;
+            //修改sdk本地配置文件
+            var pluginSettingData = pluginData.pluginSettingData;
+            CountrySettingData countrySettingData = pluginSettingData.getCountrySettingData();
+
+            if (os == ATConfig.OS_ANDROID) {
+                curVersions.Android = "";
+                countrySettingData.android_version = "";
+            } else {
+                curVersions.Ios = "";
+                countrySettingData.ios_version = "";
+            }
+
+            ATConfig.savePluginSettingData(pluginSettingData);
+        }
+
+        private void removeNetworkVersions(PluginData pluginData, int os, bool isDeleteSdk = false) {
+            if (isDeleteSdk) {
+                var mediatedNetworks = pluginData.mediatedNetworks;
+                if (mediatedNetworks != null && mediatedNetworks.Length > 0) {
+                    foreach(Network network in mediatedNetworks) {
+                        var currentVersion = network.CurrentVersions;
+                        if (currentVersion != null) {
+                            if (os == ATConfig.OS_ANDROID) {
+                                currentVersion.Android = "";
+                            } else {
+                                currentVersion.Ios = "";
+                            }
+                        }
+                        var latestVersions = network.LatestVersions;
+                        if (latestVersions != null) {
+                            if (os == ATConfig.OS_ANDROID) {
+                                latestVersions.Android = "";
+                            } else {
+                                latestVersions.Ios = "";
+                            }
+                        }
+                    }
+                }
+                NetworkRequestParams requestParams = pluginData.requestParams;
+                if (requestParams == null) {
+                    return;
+                }
+                if (os == ATConfig.OS_ANDROID) {  //Android 
+                    requestParams.androidVersion = "";
+                } else {
+                    requestParams.iosVersion = "";
+                }
+            }         
+        }
+    }
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntegrationManager.cs.meta

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

+ 860 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntegrationManagerWindow.cs

@@ -0,0 +1,860 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Linq;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.UI;
+using System.Collections.Generic;
+using System.Text;
+
+namespace AnyThink.Scripts.IntegrationManager.Editor
+{
+    public class ATIntegrationManagerWindow : EditorWindow
+    {
+
+        private const string windowTitle = "AnyThink Integration Manager";
+        private const string uninstallIconExportPath = "AnyThinkPlugin/Resources/Images/uninstall_icon.png";
+        private const string alertIconExportPath = "AnyThinkPlugin/Resources/Images/alert_icon.png";
+        private const string warningIconExportPath = "AnyThinkPlugin/Resources/Images/warning_icon.png";
+
+        private static readonly Color darkModeTextColor = new Color(0.29f, 0.6f, 0.8f);
+        private GUIStyle titleLabelStyle;
+        private GUIStyle headerLabelStyle;
+        private GUIStyle environmentValueStyle;
+        private GUIStyle wrapTextLabelStyle;
+        private GUIStyle linkLabelStyle;
+        private GUIStyle iconStyle;
+        private GUIStyle tipTextStyle;
+        private Texture2D uninstallIcon;
+        private Texture2D alertIcon;
+        private Texture2D warningIcon;
+        private Vector2 scrollPosition;
+        private static readonly Vector2 windowMinSize = new Vector2(850, 750);
+        private const float actionFieldWidth = 80f;
+        private const float upgradeAllButtonWidth = 80f;
+        private const float networkFieldMinWidth = 200f;
+        private const float versionFieldMinWidth = 200f;
+        private const float privacySettingLabelWidth = 200f;
+        private const float networkFieldWidthPercentage = 0.22f;
+        private const float versionFieldWidthPercentage = 0.36f; // There are two version fields. Each take 40% of the width, network field takes the remaining 20%.
+        private static float previousWindowWidth = windowMinSize.x;
+        private static GUILayoutOption networkWidthOption = GUILayout.Width(networkFieldMinWidth);
+        private static GUILayoutOption versionWidthOption = GUILayout.Width(versionFieldMinWidth);
+
+        private static GUILayoutOption sdkKeyTextFieldWidthOption = GUILayout.Width(520);
+
+        private static GUILayoutOption privacySettingFieldWidthOption = GUILayout.Width(400);
+        private static readonly GUILayoutOption fieldWidth = GUILayout.Width(actionFieldWidth);
+        private static readonly GUILayoutOption upgradeAllButtonFieldWidth = GUILayout.Width(upgradeAllButtonWidth);
+
+        private ATEditorCoroutine loadDataCoroutine;
+        private PluginData pluginData;
+        private bool pluginDataLoadFailed;
+        private bool networkButtonsEnabled = true;
+        private bool shouldShowGoogleWarning;
+        private int curSelectCountryInt;
+        // private int dropdownIndex = 0;
+        private int androidVersionPopupIndex;
+        private int iosVersionPopupIndex;
+
+
+        public static void ShowManager()
+        {
+            var manager = GetWindow<ATIntegrationManagerWindow>(utility: true, title: windowTitle, focus: true);
+            manager.minSize = windowMinSize;
+            // manager.maxSize = windowMinSize;
+        }
+        //定义UI的Style
+        private void Awake()
+        {
+            titleLabelStyle = new GUIStyle(EditorStyles.label)
+            {
+                fontSize = 14,
+                fontStyle = FontStyle.Bold,
+                fixedHeight = 20
+            };
+
+            headerLabelStyle = new GUIStyle(EditorStyles.label)
+            {
+                fontSize = 12,
+                fontStyle = FontStyle.Bold,
+                fixedHeight = 18
+            };
+
+            environmentValueStyle = new GUIStyle(EditorStyles.label)
+            {
+                alignment = TextAnchor.MiddleRight
+            };
+
+            linkLabelStyle = new GUIStyle(EditorStyles.label)
+            {
+                wordWrap = true,
+                normal = { textColor = EditorGUIUtility.isProSkin ? darkModeTextColor : Color.blue }
+            };
+
+            wrapTextLabelStyle = new GUIStyle(EditorStyles.label)
+            {
+                wordWrap = true
+            };
+
+            iconStyle = new GUIStyle(EditorStyles.miniButton)
+            {
+                fixedWidth = 18,
+                fixedHeight = 18,
+                padding = new RectOffset(1, 1, 1, 1)
+            };
+
+            tipTextStyle = new GUIStyle(EditorStyles.label)
+            {
+                normal = { textColor = Color.yellow }
+            };
+
+            // Load uninstall icon texture.
+            var uninstallIconData = File.ReadAllBytes(ATSdkUtil.GetAssetPathForExportPath(uninstallIconExportPath));
+            uninstallIcon = new Texture2D(100, 100, TextureFormat.RGBA32, false); // 1. Initial size doesn't matter here, will be automatically resized once the image asset is loaded. 2. Set mipChain to false, else the texture has a weird blurry effect.
+            uninstallIcon.LoadImage(uninstallIconData);
+
+            // Load alert icon texture.
+            var alertIconData = File.ReadAllBytes(ATSdkUtil.GetAssetPathForExportPath(alertIconExportPath));
+            alertIcon = new Texture2D(100, 100, TextureFormat.RGBA32, false);
+            alertIcon.LoadImage(alertIconData);
+
+            // Load warning icon texture.
+            var warningIconData = File.ReadAllBytes(ATSdkUtil.GetAssetPathForExportPath(warningIconExportPath));
+            warningIcon = new Texture2D(100, 100, TextureFormat.RGBA32, false);
+            warningIcon.LoadImage(warningIconData);
+
+            loadPluginData();
+            //热更新
+            ATIntegrationHotFix.Instance.loadHotFixData();
+        }
+
+        //这个方法在插件启动时会调用,然后脚本重新加载时也会重新调用,所以加载数据放在Awake中
+        private void OnEnable()
+        {
+
+        }
+
+        private void OnDisable()
+        {
+            if (loadDataCoroutine != null)
+            {
+                loadDataCoroutine.Stop();
+                loadDataCoroutine = null;
+            }
+
+            ATIntegrationManager.Instance.CancelDownload();
+            EditorUtility.ClearProgressBar();
+
+            // Saves the AppLovinSettings object if it has been changed.
+            AssetDatabase.SaveAssets();
+        }
+
+        private void OnDestroy() {
+            ATLog.log("OnDestroy() >>> called");
+        }
+
+
+        private void OnGUI()
+        {
+            // OnGUI is called on each frame draw, so we don't want to do any unnecessary calculation if we can avoid it. So only calculate it when the width actually changed.
+            if (Math.Abs(previousWindowWidth - position.width) > 1)
+            {
+                previousWindowWidth = position.width;
+                CalculateFieldWidth();
+            }
+            using (var scrollView = new EditorGUILayout.ScrollViewScope(scrollPosition, false, false))
+            {
+                scrollPosition = scrollView.scrollPosition;
+                GUILayout.Space(5);
+                // EditorGUILayout.LabelField("Region (Only for Android, iOS is not affected by region)", titleLabelStyle);
+                EditorGUILayout.LabelField("Region", titleLabelStyle);
+                DrawCountryUI();
+                DrawCountrySwitchTip();
+                DrawAndroidXUI();
+                DrawAdombAppId();
+                EditorGUILayout.LabelField("AnyThink Plugin Details", titleLabelStyle);
+                //显示插件版本号
+                DrawPluginDetails();
+                //绘制SDK版本下架提示
+                DrawSdkVersionOffTip();
+                //绘制Networks
+                DrawMediatedNetworks();
+            }
+            if (GUI.changed)
+            {
+                AssetDatabase.SaveAssets();
+            }
+        }
+
+        /// <summary>
+        /// Callback method that will be called with progress updates when the plugin is being downloaded.
+        /// </summary>
+        public static void OnDownloadPluginProgress(string pluginName, float progress, bool done)
+        {
+            ATLog.logFormat("OnDownloadPluginProgress() >>> pluginName: {0}, progress: {1}, done: {2}", new object[] { pluginName, progress, done });
+            // Download is complete. Clear progress bar.
+            if (done || progress == 1)
+            {
+                EditorUtility.ClearProgressBar();
+                AssetDatabase.Refresh();
+            }
+            // Download is in progress, update progress bar.
+            else
+            {
+                if (EditorUtility.DisplayCancelableProgressBar(windowTitle, string.Format("Downloading {0} plugin...", pluginName), progress))
+                {
+                    ATLog.log("OnDownloadPluginProgress() >>> click cancel download");
+                    ATIntegrationManager.Instance.CancelDownload();
+                    EditorUtility.ClearProgressBar();
+                    AssetDatabase.Refresh();
+                }
+            }
+        }
+
+        public void DeleteSdkVersion(PluginData pluginData, int index, int os) {
+            var sdkVersion = pluginData.androidVersions[index];
+            if (os == ATConfig.OS_IOS) {
+                sdkVersion = pluginData.iosVersions[index];
+            }
+            ATIntegrationManager.Instance.deleteSdk(pluginData, sdkVersion, os);
+        }
+
+        public void ExChangeSDKVersion(PluginData pluginData, int index, int os) {
+            NetworkRequestParams requestParams = pluginData.requestParams;
+            if (requestParams == null) {
+                requestParams = new NetworkRequestParams();
+            }
+            requestParams.os = os;
+            if (os == ATConfig.OS_ANDROID) {  //Android 
+                requestParams.androidVersion = pluginData.androidVersions[index];
+            } else {
+                requestParams.iosVersion = pluginData.iosVersions[index];
+            }
+            pluginData.requestParams = requestParams;
+            // ATLog.log("ExChangeSDKVersion() >>> versions.Android: " + versions.Android + " versions.Ios: " + versions.Ios);
+            loadNetworksData(pluginData);
+        }
+
+        //获取插件和SDK的版本数据
+        private void loadPluginData()
+        {
+            if (loadDataCoroutine != null)
+            {
+                loadDataCoroutine.Stop();
+            }
+            loadDataCoroutine = ATEditorCoroutine.startCoroutine(ATIntegrationManager.Instance.loadPluginData(data =>
+            {
+                if (data == null)
+                {
+                    pluginDataLoadFailed = true;
+                }
+                else
+                {
+                    ATLog.log("loadNetworksData() >>> pluginData: " + data);
+                    pluginData = data;
+                    pluginDataLoadFailed = false;
+
+                    var versions = pluginData.anyThink.CurrentVersions;
+                    if (versions != null) {
+                        var requestParams = new NetworkRequestParams();
+                        requestParams.androidVersion = versions.Android;
+                        requestParams.iosVersion = versions.Ios;
+                        pluginData.requestParams = requestParams;
+                    }
+                    loadNetworksData(pluginData);
+                }
+
+                CalculateFieldWidth();
+                Repaint();
+            }));
+        }
+        //获取networks
+        private void loadNetworksData(PluginData pluginData)
+        {
+            ATEditorCoroutine.startCoroutine(ATIntegrationManager.Instance.loadNetworksData(pluginData, data =>
+            {
+                pluginData = data;
+                Network network = pluginData.anyThink;
+                if (!string.IsNullOrEmpty(network.AndroidDownloadUrl) || !string.IsNullOrEmpty(network.iOSDownloadloadUrl)) {
+                    ATIntegrationManager.Instance.downloadCorePlugin(data);
+                }
+                Repaint();
+            }));
+        }
+        //切换国家,重新加载数据
+        private void switchCountry(int country)
+        {
+            ATIntegrationManager.Instance.switchCountry(pluginData, country);
+            //重新开始走network
+            loadPluginData();
+        }
+
+        private void CalculateFieldWidth()
+        {
+            var currentWidth = position.width;
+            var availableWidth = currentWidth - actionFieldWidth - 80; // NOTE: Magic number alert. This is the sum of all the spacing the fields and other UI elements.
+            var networkLabelWidth = Math.Max(networkFieldMinWidth, availableWidth * networkFieldWidthPercentage);
+            networkWidthOption = GUILayout.Width(networkLabelWidth);
+
+            var versionLabelWidth = Math.Max(versionFieldMinWidth, availableWidth * versionFieldWidthPercentage);
+            versionWidthOption = GUILayout.Width(versionLabelWidth);
+
+            const int textFieldOtherUiElementsWidth = 45; // NOTE: Magic number alert. This is the sum of all the spacing the fields and other UI elements.
+            var availableTextFieldWidth = currentWidth - networkLabelWidth - textFieldOtherUiElementsWidth;
+            sdkKeyTextFieldWidthOption = GUILayout.Width(availableTextFieldWidth);
+
+            var availableUserDescriptionTextFieldWidth = currentWidth - privacySettingLabelWidth - textFieldOtherUiElementsWidth;
+            privacySettingFieldWidthOption = GUILayout.Width(availableUserDescriptionTextFieldWidth);
+        }
+
+        private void DrawCountryUI()
+        {
+            // GUILayout.BeginHorizontal();
+            GUILayout.Space(4);
+            using (new EditorGUILayout.HorizontalScope("box"))
+            {
+                GUILayout.Space(5);
+
+                int countryInt = ATConfig.getDefCountry(); //默认是中国
+                if (pluginData != null)
+                {
+                    countryInt = pluginData.country;
+                }
+
+                string[] options = ATConfig.getCountryArray();
+                // 创建Dropdown组件
+                int curDropdownIndex = ATDataUtil.isChina(countryInt) ? 0 : 1;
+                if (options.Length == 1) {
+                    curDropdownIndex = 0;
+                }
+                int dropdownIndex = EditorGUILayout.Popup("Select Region:", curDropdownIndex, options);
+
+                if (options.Length > 1) {
+                    curSelectCountryInt = dropdownIndex == 0 ? ATConfig.CHINA_COUNTRY : ATConfig.NONCHINA_COUNTRY;
+                    //变化才设置
+                    if (pluginData != null && curSelectCountryInt != countryInt)
+                    {
+                        ATLog.log("DrawCountryUI() >>> curSelectCountryInt: " + curSelectCountryInt + " countryInt: " + countryInt);
+                        //Unity需要更换Network
+                        switchCountry(curSelectCountryInt);
+                    }
+                }
+                GUILayout.Space(5);
+            }
+            GUILayout.Space(4);
+            // GUILayout.EndHorizontal();
+        }
+
+        private void DrawCountrySwitchTip()
+        {
+            var integratedTip = ATConfig.getRegionIntegrateTip();
+            if (string.IsNullOrEmpty(integratedTip)) {
+                return;
+            }
+            GUILayout.Space(4);
+            // textStyle.fontStyle = FontStyle.Bold;
+            EditorGUILayout.LabelField(integratedTip, tipTextStyle);
+            GUILayout.Space(4);
+        }
+
+        private void DrawAndroidXUI()
+        {   
+            bool isChina = ATConfig.isSelectedChina();
+            // if (!ATConfig.isSelectedChina()) {
+            //     return;
+            // }
+            EditorGUILayout.LabelField("AndroidX (Only for Android)", titleLabelStyle);
+            GUILayout.Space(4);
+            using (new EditorGUILayout.HorizontalScope("box"))
+            {
+                GUILayout.Space(5);
+
+                int androidXSetting = ATIntegrationManager.Instance.getAndroidXSetting(pluginData);
+                string[] options = new string[] { "Default", "Enable", "Disable" };
+                if (!isChina) {
+                    options = new string[] { "Default", "Enable" };
+                }
+                // 创建Dropdown组件
+                int lastDropdownIndex = androidXSetting;
+                int curDropdownIndex = EditorGUILayout.Popup("Enable AndroidX:", lastDropdownIndex, options);
+
+                //变化才设置
+                if (curDropdownIndex != lastDropdownIndex)
+                {
+                    ATLog.log("DrawAndroidXUI() >>> curDropdownIndex: " + curDropdownIndex + " lastDropdownIndex: " + lastDropdownIndex);
+                    ATIntegrationManager.Instance.saveAndroidXSetting(pluginData, curDropdownIndex);
+                }
+                GUILayout.Space(5);
+            }
+            GUILayout.Space(4);
+        }
+
+        private void DrawPluginDetails()
+        {
+            // GUILayout.BeginHorizontal();
+            GUILayout.Space(10);
+            using (new EditorGUILayout.VerticalScope("box"))
+            {
+                // Draw plugin version details
+                DrawHeaders("Platform", true);
+                DrawPluginDetailRow("Unity Plugin", ATConfig.PLUGIN_VERSION, "", "");
+                if (pluginData == null)
+                {
+                    DrawEmptyPluginData("loading sdk data ...");
+                    return;
+                }
+
+                var anythink = pluginData.anyThink;
+                var android_version = "";
+                var ios_version = "";
+                if (anythink != null) {
+                    android_version = anythink.CurrentVersions.Android;
+                    ios_version = anythink.CurrentVersions.Ios;
+                }
+                //绘制Android
+                using (new EditorGUILayout.HorizontalScope())
+                {
+                    GUILayout.Space(5);
+                    EditorGUILayout.LabelField(new GUIContent("Android"), networkWidthOption);
+                    EditorGUILayout.LabelField(new GUIContent(android_version), versionWidthOption);
+                    GUILayout.Space(3);
+
+                    string[] androidVersions = pluginData.androidVersions;
+                    if (androidVersions != null && androidVersions.Length > 0) {
+                        List<int> androidVersionsInt = new List<int>();
+                        int androidLength = androidVersions.Length;
+                        for (int i = 0; i < androidLength; i = i + 1)
+                        {
+                            androidVersionsInt.Add(i);
+                        }
+
+                        // 创建Dropdown组件
+                        androidVersionPopupIndex = EditorGUILayout.IntPopup(androidVersionPopupIndex, androidVersions, androidVersionsInt.ToArray(), versionWidthOption);
+                        GUILayout.FlexibleSpace();
+                        string selectedAndroidVersion = androidVersions[androidVersionPopupIndex];
+                        string action = "Exchange";
+                        if (!string.IsNullOrEmpty(android_version) && Equals(android_version, selectedAndroidVersion)) {
+                            action = "Delete";
+                        }
+                        GUI.enabled = (!Equals(android_version, selectedAndroidVersion)) || action == "Delete";
+                        if (GUILayout.Button(new GUIContent(action), fieldWidth))
+                        {
+                            //切换AndroidSDK版本
+                            if (action == "Delete") {
+                                DeleteSdkVersion(pluginData, androidVersionPopupIndex, ATConfig.OS_ANDROID);
+                            } else {
+                                ExChangeSDKVersion(pluginData, androidVersionPopupIndex, ATConfig.OS_ANDROID);
+                            }
+                        }
+                        GUI.enabled = true;
+                        GUILayout.Space(5);    
+                    } else {
+                        EditorGUILayout.LabelField(new GUIContent("loading..."), versionWidthOption);
+                    }
+                
+                    GUILayout.Space(3);
+                }
+                //绘制iOS
+                using (new EditorGUILayout.HorizontalScope())
+                {
+                    GUILayout.Space(5);
+                    EditorGUILayout.LabelField(new GUIContent("iOS"), networkWidthOption);
+                    EditorGUILayout.LabelField(new GUIContent(ios_version), versionWidthOption);
+                    GUILayout.Space(3);
+
+                    string[] iosVersions = pluginData.iosVersions;
+                    if (iosVersions != null && iosVersions.Length > 0) {
+                        List<int> iosVersionsInt = new List<int>();
+                        int androidLength = iosVersions.Length;
+                        for (int i = 0; i < androidLength; i = i + 1)
+                        {
+                            iosVersionsInt.Add(i);
+                        }
+
+                        // 创建Dropdown组件
+                        iosVersionPopupIndex = EditorGUILayout.IntPopup(iosVersionPopupIndex, iosVersions, iosVersionsInt.ToArray(), versionWidthOption);
+                        GUILayout.FlexibleSpace();
+                        string selectedIosVersion = iosVersions[iosVersionPopupIndex];
+
+                        string action = "Exchange";
+                        if (!string.IsNullOrEmpty(ios_version) && Equals(ios_version, selectedIosVersion)) {
+                            action = "Delete";
+                        }
+                        GUI.enabled = !Equals(ios_version, selectedIosVersion) || action == "Delete";
+                        if (GUILayout.Button(new GUIContent(action), fieldWidth))
+                        {
+                            if (action == "Delete") {
+                                DeleteSdkVersion(pluginData, iosVersionPopupIndex, ATConfig.OS_IOS);
+                            } else {
+                                ExChangeSDKVersion(pluginData, iosVersionPopupIndex, ATConfig.OS_IOS);
+                            }
+                        }
+                        GUI.enabled = true;
+                        GUILayout.Space(5);    
+                    } else {
+                        EditorGUILayout.LabelField(new GUIContent("loading..."), versionWidthOption);
+                    }
+                
+                    GUILayout.Space(3);
+                }
+
+                GUILayout.Space(4);
+
+#if !UNITY_2018_2_OR_NEWER
+                EditorGUILayout.HelpBox("AnyThink Unity plugin will soon require Unity 2018.2 or newer to function. Please upgrade to a newer Unity version.", MessageType.Warning);
+#endif
+            }
+
+            GUILayout.Space(5);
+            // GUILayout.EndHorizontal();
+        }
+
+        private void DrawSdkVersionOffTip()
+        {
+            if (pluginData == null) {
+                return;
+            }
+            var anythink = pluginData.anyThink;
+            if (anythink == null) {
+                return;
+            }
+            var android_version = "";
+            var ios_version = "";
+            if (anythink != null) {
+                android_version = anythink.CurrentVersions.Android;
+                ios_version = anythink.CurrentVersions.Ios;
+                //判断android版本是否版本列表中
+                string[] androidVersions = pluginData.androidVersions;
+                string[] iosVersions = pluginData.iosVersions;
+
+                //The currently installed Android version and io version have been offline
+                StringBuilder sb = new StringBuilder();
+                sb.Append("Tips: The currently installed ");
+               
+                var android_version_off = false;
+                if (!string.IsNullOrEmpty(android_version) && androidVersions != null && androidVersions.Length > 0) {
+                    if (!IsCharInStringArray(android_version, androidVersions)) {
+                        sb.Append("Android version(");
+                        sb.Append(android_version);
+                        sb.Append(") ");
+                        android_version_off = true;
+                    }
+                }
+                var ios_version_off = false;
+                if (!string.IsNullOrEmpty(ios_version) && iosVersions != null && iosVersions.Length > 0) {
+                    if (!IsCharInStringArray(ios_version, iosVersions)) {
+                        if (android_version_off) {
+                            sb.Append("and ");
+                        }
+                        sb.Append("iOS version(");
+                        sb.Append(ios_version);
+                        sb.Append(") ");
+                        ios_version_off = true;
+                    }
+                }
+                if (android_version_off || ios_version_off) {
+                    sb.Append("have been offline, please install the latest version.");
+                    GUILayout.Space(4);
+                    EditorGUILayout.LabelField(sb.ToString(), tipTextStyle);
+                    GUILayout.Space(4);
+                } else {
+                    sb.Clear();
+                }
+            }
+        }
+
+        private bool IsCharInStringArray(string character, string[] array)
+        {
+            // 遍历数组中的每个字符串
+            foreach (string str in array)
+            {
+                // 如果当前字符串包含指定的字符,则返回true
+                if (str == character)
+                {
+                    return true;
+                }
+            }
+
+            // 如果没有找到字符,则返回false
+            return false;
+        }
+
+
+        private void DrawHeaders(string firstColumnTitle, bool drawAction)
+        {
+            using (new EditorGUILayout.HorizontalScope())
+            {
+                GUILayout.Space(5);
+                EditorGUILayout.LabelField(firstColumnTitle, headerLabelStyle, networkWidthOption);
+                EditorGUILayout.LabelField("Current Version", headerLabelStyle, versionWidthOption);
+                GUILayout.Space(3);
+                EditorGUILayout.LabelField("SDK Versions", headerLabelStyle, versionWidthOption);
+                GUILayout.Space(3);
+                if (drawAction)
+                {
+                    GUILayout.FlexibleSpace();
+                    GUILayout.Button("Actions", headerLabelStyle, fieldWidth);
+                    GUILayout.Space(5);
+                }
+            }
+
+            GUILayout.Space(4);
+        }
+
+        private void DrawPluginDetailRow(string platform, string currentVersion, string sdkversions, string actions)
+        {
+            using (new EditorGUILayout.HorizontalScope())
+            {
+                GUILayout.Space(5);
+                EditorGUILayout.LabelField(new GUIContent(platform), networkWidthOption);
+                EditorGUILayout.LabelField(new GUIContent(currentVersion), versionWidthOption);
+                GUILayout.Space(3);
+                EditorGUILayout.LabelField(new GUIContent(sdkversions), versionWidthOption);
+                GUILayout.Space(3);
+                // EditorGUILayout.LabelField(new GUIContent(actions), versionWidthOption);
+                // GUILayout.Space(3);
+            }
+
+            GUILayout.Space(4);
+        }
+
+        private void DrawEmptyPluginData(string tip)
+        {
+            GUILayout.Space(5);
+
+            // Plugin data failed to load. Show error and retry button.
+            if (pluginDataLoadFailed)
+            {
+                GUILayout.Space(10);
+                GUILayout.BeginHorizontal();
+                GUILayout.Space(5);
+                EditorGUILayout.LabelField("Failed to load plugin data. Please click retry or restart the integration manager.", titleLabelStyle);
+                if (GUILayout.Button("Retry", fieldWidth))
+                {
+                    pluginDataLoadFailed = false;
+                    loadPluginData();
+                }
+
+                GUILayout.Space(5);
+                GUILayout.EndHorizontal();
+                GUILayout.Space(10);
+            }
+            // Still loading, show loading label.
+            else
+            {
+                GUILayout.Space(10);
+                GUILayout.BeginHorizontal();
+                // GUILayout.FlexibleSpace();
+                EditorGUILayout.LabelField(tip, titleLabelStyle);
+                // GUILayout.FlexibleSpace();
+                GUILayout.EndHorizontal();
+                GUILayout.Space(10);
+            }
+
+            GUILayout.Space(5);
+        }
+        //绘制Admob Id
+        private void DrawAdombAppId() {
+            var integrationManager = ATIntegrationManager.Instance;
+            bool isAdmobInstalledForAndroid = integrationManager.isAdmobInstalled(ATConfig.OS_ANDROID);
+            bool isAdmobInstalledForIos = integrationManager.isAdmobInstalled(ATConfig.OS_IOS);
+
+            if (isAdmobInstalledForAndroid || isAdmobInstalledForIos) {
+                EditorGUILayout.LabelField("Admob AppId", titleLabelStyle);
+                GUILayout.Space(5);
+                using (new EditorGUILayout.VerticalScope("box"))
+                {
+                    GUILayout.Space(10);
+                    if (isAdmobInstalledForAndroid) {
+                        var androidAdmobAppId = DrawTextField("App ID (Android)", integrationManager.getAdmobAppIdByOs(pluginData, ATConfig.OS_ANDROID), networkWidthOption);
+                        integrationManager.setAdmobAppidByOs(pluginData, ATConfig.OS_ANDROID, androidAdmobAppId);
+                    }
+                    if (isAdmobInstalledForIos) {
+                        if (isAdmobInstalledForAndroid) {
+                            GUILayout.Space(10);
+                        }
+                        var iosAdmobAppId = DrawTextField("App ID (iOS)", integrationManager.getAdmobAppIdByOs(pluginData, ATConfig.OS_IOS), networkWidthOption);
+                        integrationManager.setAdmobAppidByOs(pluginData, ATConfig.OS_IOS, iosAdmobAppId);
+                    }
+                }
+            }
+        }
+
+        private string DrawTextField(string fieldTitle, string text, GUILayoutOption labelWidth,    GUILayoutOption textFieldWidthOption = null)
+        {
+            GUILayout.BeginHorizontal();
+            GUILayout.Space(4);
+            EditorGUILayout.LabelField(new GUIContent(fieldTitle), labelWidth);
+            GUILayout.Space(4);
+            text = (textFieldWidthOption == null) ? GUILayout.TextField(text) : GUILayout.TextField(text, textFieldWidthOption);
+            GUILayout.Space(4);
+            GUILayout.EndHorizontal();
+            GUILayout.Space(4);
+
+            return text;
+        }
+
+
+        private void DrawMediatedNetworks()
+        {
+            GUILayout.Space(5);
+            EditorGUILayout.LabelField("Ad Networks", titleLabelStyle);
+            GUILayout.Space(5);
+            GUILayout.BeginHorizontal();
+            using (new EditorGUILayout.VerticalScope("box"))
+            {
+                DrawHeaders("Network", true);
+                string clickTip = "You need to select an sdk version and click the Exchange button.";
+                // Immediately after downloading and importing a plugin the entire IDE reloads and current versions can be null in that case. Will just show loading text in that case.
+                if (pluginData == null)
+                {
+                    ATLog.log("DrawMediatedNetworks failed.");
+                    DrawEmptyPluginData("loading sdk data ...");
+                } else if(pluginData.mediatedNetworks == null) {
+                    DrawEmptyPluginData(clickTip);
+                } else {
+                    var networks = pluginData.mediatedNetworks;
+                    var length = networks.Length;
+                    ATLog.log("DrawMediatedNetworks() >>> networks length: " + length);
+                    if (length == 0) {
+                        DrawEmptyPluginData(clickTip);
+                        return;
+                    }
+                    int versionEmptyLength = 0;
+                    foreach (var network in networks)
+                    {
+                        if (network.isVersionEmpty()) {
+                            // ATLog.log("DrawMediatedNetworks() >>> isVersionEmpty name: " + network.Name);
+                            versionEmptyLength = versionEmptyLength + 1;
+                        } else {
+                            DrawNetworkDetailRow2(network);
+                        }
+                    }
+                    ATLog.log("DrawMediatedNetworks() >>> versionEmptyLength: " + versionEmptyLength);
+                    if (versionEmptyLength == length) {
+                        DrawEmptyPluginData(clickTip);
+                    }
+
+                    GUILayout.Space(10);
+                }
+            }
+
+            GUILayout.Space(5);
+            GUILayout.EndHorizontal();
+        }
+        //绘制network的每一行
+        private void DrawNetworkDetailRow2(Network network) {
+            using (new EditorGUILayout.VerticalScope("box"))
+            {
+                GUILayout.Space(4);
+                string a_action = "";    
+                string i_action = "";
+                string cur_a_version = "";
+                string cur_i_version = "";
+                string last_a_version = "";
+                string last_i_version = "";
+                if (network.CurrentVersions != null)
+                {
+                    cur_a_version = network.CurrentVersions.Android;
+                    cur_i_version = network.CurrentVersions.Ios;
+                }
+                if (network.LatestVersions != null) 
+                {
+                    last_a_version = network.LatestVersions.Android;
+                    last_i_version = network.LatestVersions.Ios;
+                }
+                //Android Action按钮状态
+                ATLog.log("DrawNetworkDetailRow2() >>> cur_a_version: " + cur_a_version + " last_i_version: " + last_i_version + 
+                " name: " + network.DisplayName + " last_a_version: " + last_a_version);
+                if (string.IsNullOrEmpty(cur_a_version)) {
+                    a_action = "Install";
+                } else if (ATDataUtil.CompareVersions(cur_a_version, last_a_version) == VersionComparisonResult.Lesser) {
+                    a_action = "Upgrade";
+                } else if(ATDataUtil.CompareVersions(cur_a_version, last_a_version) == VersionComparisonResult.Equal) {
+                    a_action = "Installed";
+                } 
+                bool hasAndroid = false;
+                if (!string.IsNullOrEmpty(last_a_version)) {
+                    hasAndroid = true;
+                    DrawRowNetwork(network, ATConfig.OS_ANDROID, cur_a_version, last_a_version, a_action, true);
+                }
+                //iOS Action按钮状态
+                // var i_compare_result = ATDataUtil.CompareVersions(cur_i_version, last_i_version);
+                if (string.IsNullOrEmpty(cur_i_version)) {
+                    i_action = "Install";
+                } else if (ATDataUtil.CompareVersions(cur_i_version, last_i_version) == VersionComparisonResult.Lesser) {
+                    i_action = "Upgrade";
+                } else if(ATDataUtil.CompareVersions(cur_i_version, last_i_version) == VersionComparisonResult.Equal) {
+                    i_action = "Installed";
+                } 
+                if (!string.IsNullOrEmpty(last_i_version)) {
+                    DrawRowNetwork(network, ATConfig.OS_IOS, cur_i_version, last_i_version, i_action, !hasAndroid);
+                }
+                GUILayout.Space(4);
+            }
+        }
+
+        private void DrawRowNetwork(Network network, int os, string curVersion, string lastVersion, string action, bool isShowNetworkName)
+        {
+             GUILayout.Space(5);
+            if (os == ATConfig.OS_ANDROID) {
+                if (!string.IsNullOrEmpty(curVersion)) {
+                    curVersion = "Android-" + curVersion;
+                } else {
+                    curVersion = "Not Installed";
+                }
+                lastVersion = "Android-" + lastVersion;
+            } else {
+                if (!string.IsNullOrEmpty(curVersion)) {
+                    curVersion = "iOS-" + curVersion;
+                } else {
+                    curVersion = "Not Installed";
+                }
+                lastVersion = "iOS-" + lastVersion;
+            }
+            using (new EditorGUILayout.HorizontalScope(GUILayout.ExpandHeight(false)))
+            {
+                GUILayout.Space(5);
+                if (isShowNetworkName) {
+                    EditorGUILayout.LabelField(new GUIContent(network.DisplayName), networkWidthOption);
+                } else {
+                    EditorGUILayout.LabelField(new GUIContent(""), networkWidthOption);
+                }
+               
+                EditorGUILayout.LabelField(new GUIContent(curVersion), versionWidthOption);
+                GUILayout.Space(3);
+                EditorGUILayout.LabelField(new GUIContent(lastVersion), versionWidthOption);
+                GUILayout.Space(3);
+                GUILayout.FlexibleSpace();
+
+                if (network.isReqiureUpdate())
+                {
+                    GUILayout.Label(new GUIContent { image = alertIcon, tooltip = "Adapter not compatible, please update to the latest version." }, iconStyle);
+                }
+
+                GUI.enabled = action != "Installed";
+                if (GUILayout.Button(new GUIContent(action), fieldWidth))
+                {   
+                    ATIntegrationManager.Instance.networkInstallOrUpdate(pluginData, network, os);
+                }
+                GUI.enabled = true;
+                GUILayout.Space(2);
+
+                GUI.enabled = action == "Installed";
+                if (GUILayout.Button(new GUIContent { image = uninstallIcon, tooltip = "Uninstall" }, iconStyle))
+                {
+                    EditorUtility.DisplayProgressBar("Integration Manager", "Deleting " + network.Name + "...", 0.5f);
+                    ATIntegrationManager.Instance.uninstallNetwork(network, os);
+                    //Refresh UI
+                    AssetDatabase.Refresh();
+                    EditorUtility.ClearProgressBar();
+                }
+
+                GUI.enabled = true;
+                GUILayout.Space(5);
+            }
+        }
+    }
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntegrationManagerWindow.cs.meta

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

+ 164 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntergrationHotFix.cs

@@ -0,0 +1,164 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.Networking;
+using UnityEditor.PackageManager.Requests;
+using UnityEditor.PackageManager;
+using System.Threading.Tasks;
+using System.Threading;
+
+namespace AnyThink.Scripts.IntegrationManager.Editor
+{
+    public class ATIntegrationHotFix {
+        public static ATIntegrationHotFix Instance = new ATIntegrationHotFix();
+
+        private ATIntegrationHotFix()
+        {
+            
+        }
+
+        private static string plugin_hot_fix_data_file_name = "plugin_hot_fix_data.json";
+
+        public void loadHotFixData()
+        {
+            var downloadUrl = ATNetInfo.getHotfixPluginDownloadUrl(ATConfig.PLUGIN_VERSION);
+            ATLog.log("loadHotFixData() >>> downloadUrl: " + downloadUrl);
+            ATEditorCoroutine.startCoroutine(loadHotFixDataWithIEnumerator(downloadUrl));
+        }
+
+        private IEnumerator loadHotFixDataWithIEnumerator(string url) {
+            var hotFixDataRequest = UnityWebRequest.Get(url);
+            var webRequest = hotFixDataRequest.SendWebRequest();
+            while (!webRequest.isDone)
+            {
+                yield return new WaitForSeconds(0.1f);
+            }
+
+#if UNITY_2020_1_OR_NEWER
+            if (hotFixDataRequest.result != UnityWebRequest.Result.Success)
+#elif UNITY_2017_2_OR_NEWER
+            if (hotFixDataRequest.isNetworkError || hotFixDataRequest.isHttpError)
+#else
+            if (hotFixDataRequest.isError)
+#endif
+            {
+                // Debug.Log("loadPluginData failed.");
+                // callback(null);
+                ATLog.log("load hotfix data failed.");
+            }
+            else
+            {
+                //解析热修复的数据
+                try {
+                    string hotFixData = hotFixDataRequest.downloadHandler.text;
+                    var hotFixDataObj = JsonUtility.FromJson<HotfixPluginData>(hotFixData);
+                    ATLog.log("loadHotFixDataWithIEnumerator() >>> hotFixData: " + hotFixData);
+                    //判断status是否需要进行热更新
+                    if (hotFixDataObj.status != 1) {
+                         ATLog.log("loadHotFixDataWithIEnumerator() >>> 热更新被禁止");
+                    } else {
+                         var localHotFixDataObj = getHotfixPluginData();
+                        if (localHotFixDataObj == null) {
+                            //本地未曾下载过热更新
+                            ATLog.log("loadHotFixDataWithIEnumerator() >>> 本地未曾下载过热更新");
+                            ATEditorCoroutine.startCoroutine(loadHotFixPlugin(hotFixDataObj));
+                        } else {
+                            var compareVersionResult = ATDataUtil.CompareVersions(localHotFixDataObj.hot_fix_version, hotFixDataObj.hot_fix_version);
+                            ATLog.log("loadHotFixDataWithIEnumerator() >>> compareVersionResult: " + compareVersionResult);
+                            //本地版本比远端版本低,则需要更新
+                            if (compareVersionResult == VersionComparisonResult.Lesser) {
+                                ATEditorCoroutine.startCoroutine(loadHotFixPlugin(hotFixDataObj));
+                            } else {
+                                //不需要热更新
+                                saveHotfixData(hotFixData);
+                            }
+                        }
+                    }
+                } catch(Exception e) {
+                    ATLog.logError("parseNetworksJson() >>> failed: " + e);
+                }
+            }
+        }
+
+        private IEnumerator loadHotFixPlugin(HotfixPluginData hotFixDataObj) {
+            var path = Path.Combine(Application.temporaryCachePath, hotFixDataObj.file_name);
+            ATLog.log("downloadPluginWithEnumerator() >>> path: " + path);
+#if UNITY_2017_2_OR_NEWER
+            var downloadHandler = new DownloadHandlerFile(path);
+#else
+            var downloadHandler = new ATDownloadHandler(path);
+#endif
+            var downloadUrl = hotFixDataObj.download_url;
+            UnityWebRequest downloadPluginRequest = new UnityWebRequest(downloadUrl) 
+            {    method = UnityWebRequest.kHttpVerbGET,
+                downloadHandler = downloadHandler
+            };
+
+#if UNITY_2017_2_OR_NEWER
+            var operation = downloadPluginRequest.SendWebRequest();
+#else
+            var operation = downloadPluginRequest.Send();
+#endif
+            while (!operation.isDone)
+            {
+                yield return new WaitForSeconds(0.1f); // Just wait till downloadPluginRequest is completed. Our coroutine is pretty rudimentary.
+                if (operation.progress != 1 && operation.isDone)
+                {
+
+                }
+            }
+
+#if UNITY_2020_1_OR_NEWER
+            if (downloadPluginRequest.result != UnityWebRequest.Result.Success)
+#elif UNITY_2017_2_OR_NEWER
+            if (downloadPluginRequest.isNetworkError || downloadPluginRequest.isHttpError)
+#else
+            if (downloadPluginRequest.isError)
+#endif
+            {
+                ATLog.log(downloadPluginRequest.error);
+            }
+            else
+            {
+                AssetDatabase.ImportPackage(path, false);
+                AssetDatabase.Refresh();
+
+                string hotFixData = JsonUtility.ToJson(hotFixDataObj);
+                saveHotfixData(hotFixData);
+            }
+            downloadPluginRequest.Dispose();
+            downloadPluginRequest = null;
+        }
+
+
+        private void saveHotfixData(string hotfixPluginData) {
+            var directoryPath = ATConfig.plugin_setting_data_path;
+             // 确保目标文件夹存在
+            if (!Directory.Exists(directoryPath))
+            {
+                // 如果目录不存在,则创建它
+                Directory.CreateDirectory(directoryPath);
+            }
+            string fullPath = Path.Combine(directoryPath, plugin_hot_fix_data_file_name);
+            ATLog.log("saveHotfixData() >>> fullPath: " + fullPath + " hotfixPluginData: " + hotfixPluginData);
+            File.WriteAllText(fullPath, hotfixPluginData);
+        }
+
+        private HotfixPluginData getHotfixPluginData() {
+            string fullPath = Path.Combine(ATConfig.plugin_setting_data_path, plugin_hot_fix_data_file_name);
+            if (!File.Exists(fullPath)) {
+                return null;
+            }
+            string json = File.ReadAllText(fullPath);
+            if(json == "") {
+                return null;
+            }
+            return JsonUtility.FromJson<HotfixPluginData>(json);
+        }
+    }
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATIntergrationHotFix.cs.meta

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

+ 37 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATLog.cs

@@ -0,0 +1,37 @@
+using System;
+using System.Collections;
+using System.IO;
+using System.Linq;
+using UnityEditor;
+using UnityEngine;
+
+public class ATLog {
+    public static bool isDebug = false;
+
+    public static void log(string msg) 
+    {
+        // string msg = 
+        if (isDebug) {
+            Debug.Log(msg);
+        }
+    }
+
+    public static void log(string tag, string msg)
+    {
+        if (isDebug) {
+            Debug.Log(tag + ": " + msg);
+        }
+    }
+
+    public static void logFormat(string msg, object[] args)
+    {   
+        if (isDebug) {
+            Debug.LogFormat(msg, args);
+        }
+    }
+
+    public static void logError(string msg)
+    {
+        Debug.LogError(msg);
+    }
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATLog.cs.meta

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

+ 37 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATMenuItems.cs

@@ -0,0 +1,37 @@
+//菜单栏
+using UnityEditor;
+using UnityEngine;
+// using DownloadManager;
+
+namespace AnyThink.Scripts.IntegrationManager.Editor
+{
+    public class AnyThinkMenuItems : MonoBehaviour
+    {
+        /**
+         * The special characters at the end represent a shortcut for this action.
+         * 
+         * % - ctrl on Windows, cmd on macOS
+         * # - shift
+         * & - alt
+         * 
+         * So, (shift + cmd/ctrl + t) will launch the integration manager
+         */
+        [MenuItem("AnyThink/SDK Manager %#t")]
+        private static void IntegrationManager()
+        {
+            
+            ATIntegrationManagerWindow.ShowManager();
+        }
+
+        [MenuItem("AnyThink/Documentation")]
+        public static void Documentation()
+        {
+            // if (ATConfig.isSelectedChina()) {
+            //     Application.OpenURL("https://newdocs.toponad.com/docs/lgfbO4");
+            // } else {
+            //     Application.OpenURL("https://docs.toponad.com/#/en-us/unity/unity_doc/unity_access_doc_new?id=_3-integration");
+            // }
+            Application.OpenURL("https://newdocs.toponad.com/docs/lgfbO4");
+        }
+    }
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATMenuItems.cs.meta

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

+ 39 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATNetInfo.cs

@@ -0,0 +1,39 @@
+using System;
+using System.IO;
+using System.Collections;
+using System.Collections.Generic;
+
+
+using UnityEngine;
+
+namespace AnyThink.Scripts.IntegrationManager.Editor
+{
+    public static class ATNetInfo {
+        //插件的配置文件:unity_plugin_config.json
+        public static string getPluginConfigUrl(String plugin_version) 
+        {
+            return "https://topon-sdk-release.oss-cn-hangzhou.aliyuncs.com/Unity_Release/plugin/" + plugin_version + "/unity_plugin_config.json";
+        }
+        //插件版本对应的network列表文件:unity_plugin_config_network.json
+        public static string getNetworkListUrl(String plugin_version)
+        {
+            return "https://topon-sdk-release.oss-cn-hangzhou.aliyuncs.com/Unity_Release/plugin/" + plugin_version + "/unity_plugin_config_network.json";
+        }
+        //插件unitypackage名字
+        public static string getPluginFileName(string pluginVersion)
+        {
+            return "AnyThinkPlugin_" + pluginVersion + ".unitypackage";
+        }
+        //插件unitypackage的下载链接
+        public static string getPluginDownloadUrl(string pluginVersion)
+        {
+            return "https://topon-sdk-release.oss-cn-hangzhou.aliyuncs.com/Unity_Release/plugin/" + pluginVersion + "/" + getPluginFileName(pluginVersion);
+        }
+
+        public static string getHotfixPluginDownloadUrl(string pluginVersion)
+        {
+            return "https://topon-sdk-release.oss-cn-hangzhou.aliyuncs.com/Unity_Release/plugin/" + pluginVersion + "/hotfix/hotfix_config.json";
+        }
+    }
+    
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATNetInfo.cs.meta

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

+ 220 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATPluginLocalDataModel.cs

@@ -0,0 +1,220 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Xml.Linq;
+using UnityEditor;
+using UnityEngine;
+using UnityEngine.Networking;
+
+namespace AnyThink.Scripts.IntegrationManager.Editor
+{
+    [Serializable]
+    public class PluginData
+    {
+        public string pluginVersion;    //插件版本
+        public string[] androidVersions;
+        public string[] iosVersions;
+        public int country = ATConfig.getDefCountry(); //默认是1=china
+        public Network anyThink;
+        public Network[] mediatedNetworks;
+        public PluginSettingData pluginSettingData;
+        public NetworkRequestParams requestParams;
+    }
+    //请求network参数
+    public class NetworkRequestParams {
+        public int os;
+        public string androidVersion;
+        public string iosVersion;
+    }
+
+    [Serializable]
+    public class Network : IComparable<Network>
+    {
+        //
+        // Sample network data:
+        //
+        // {
+        //   "Name": "adcolony",
+        //   "DisplayName": "AdColony",
+        //   "DownloadUrl": "https://bintray.com/applovin/Unity-Mediation-Packages/download_file?file_path=AppLovin-AdColony-Adapters-Android-3.3.10.1-iOS-3.3.7.2.unitypackage",
+        //   "PluginFileName": "AppLovin-AdColony-Adapters-Android-3.3.10.1-iOS-3.3.7.2.unitypackage",
+        //   "DependenciesFilePath": "MaxSdk/Mediation/AdColony/Editor/Dependencies.xml",
+        //   "LatestVersions" : {
+        //     "Unity": "android_3.3.10.1_ios_3.3.7.2",
+        //     "Android": "3.3.10.1",
+        //     "Ios": "3.3.7.2"
+        //   }
+        // }
+        //
+
+        public string Name;
+        public string DisplayName;
+        public string AndroidDownloadUrl;
+        public string iOSDownloadloadUrl;
+        // public string DependenciesFilePath;
+        public string PluginFileName;
+        public int Country;
+        public Versions LatestVersions; //最新版本
+        public Versions CurrentVersions;    //当前版本
+        [NonSerialized] public VersionComparisonResult CurrentToLatestVersionComparisonResult = VersionComparisonResult.Equal;
+        // [NonSerialized] public bool RequiresUpdate = CurrentToLatestVersionComparisonResult == VersionComparisonResult.Lesser;
+
+        public bool isVersionEmpty() {
+            if (LatestVersions != null) {
+                ATLog.log("isVersionEmpty() >>> name: " + Name + " android: " + LatestVersions.Android + " ios: " + LatestVersions.Ios);
+                return string.IsNullOrEmpty(LatestVersions.Android) && string.IsNullOrEmpty(LatestVersions.Ios);
+            }
+            return false;
+        }
+
+        public bool isReqiureUpdate()
+        {
+            return CurrentToLatestVersionComparisonResult == VersionComparisonResult.Lesser;
+        }
+
+        public int CompareTo(Network other)
+        {
+            return this.DisplayName.CompareTo(other.DisplayName);
+        }
+
+        public string ToString() {
+            return DisplayName + "-" + AndroidDownloadUrl + "-" + iOSDownloadloadUrl + "-" + Country;
+        }
+    }
+
+    /// <summary>
+    /// A helper data class used to get current versions from Dependency.xml files.
+    /// </summary>
+    [Serializable]
+    public class Versions
+    {
+
+        public string Unity;
+
+        public string Android;
+
+        public string Ios;
+
+        public override bool Equals(object value)
+        {
+            var versions = value as Versions;
+
+            return versions != null
+                   && (Unity == null || Unity.Equals(versions.Unity))
+                   && (Android == null || Android.Equals(versions.Android))
+                   && (Ios == null || Ios.Equals(versions.Ios));
+        }
+
+        public bool HasEqualSdkVersions(Versions versions)
+        {
+            return versions != null && versions.Android == Android && versions.Ios == Ios;
+        }
+
+        public override int GetHashCode()
+        {
+            return new { Unity, Android, Ios }.GetHashCode();
+        }
+
+        public Versions clone()
+        {
+            Versions cloneObj = new Versions();
+            cloneObj.Android = Android;
+            cloneObj.Ios = Ios;
+            cloneObj.Unity = Unity;
+
+            return cloneObj;
+        }
+    }
+
+    public enum VersionComparisonResult
+    {
+        Lesser = -1,
+        Equal = 0,
+        Greater = 1
+    }
+
+    //存在本地插件设置数据并序列化为json文件
+    [Serializable]
+    public class PluginSettingData
+    {
+        public int curCountry = ATConfig.getDefCountry();  //当前选择的国家
+
+        public CountrySettingData china = new CountrySettingData(ATConfig.CHINA_COUNTRY);    //国内地区
+        public CountrySettingData nonchina = new CountrySettingData(ATConfig.NONCHINA_COUNTRY); //海外地区
+
+        public CountrySettingData getCountrySettingData() {
+            if (curCountry == ATConfig.CHINA_COUNTRY) {
+                return china;
+            } else {
+                return nonchina;
+            }
+        }
+
+        //Android 是否同时安装了国内海外地区
+        public bool isBothInstallAndroid() {
+            return !string.IsNullOrEmpty(china.android_version) && !string.IsNullOrEmpty(nonchina.android_version);
+        }
+
+        //iOS 是否同时安装了国内海外地区
+        public bool isBothInstallIOS() {
+            return !string.IsNullOrEmpty(china.ios_version) && !string.IsNullOrEmpty(nonchina.ios_version);
+        }
+    }
+    //已安装的sdk版本
+    [Serializable]
+    public class CountrySettingData
+    {
+    
+        public string android_version;  //当前已安装Android sdk的版本号
+
+        public string ios_version;  //当前已安装的iOS sdk的版本号
+
+        public int androidXSetting = 0; //当前的AndroidX设置,0=default; 1=修改为AndroidX;2=修改为非AndroidX
+
+        public int country;
+
+        public string android_admob_app_id;
+        public string ios_admob_app_id;
+
+        public CountrySettingData(int country) {
+            this.country = country;
+        }
+
+        public string getAdmobAppId(int os) {
+            if (os == ATConfig.OS_ANDROID) {
+                return android_admob_app_id;
+            } else {
+                return ios_admob_app_id;
+            }
+        }
+
+        public void setAdmobAppId(string appId, int os) {
+            if (os == ATConfig.OS_ANDROID) {
+                android_admob_app_id = appId;
+            } else {
+                ios_admob_app_id = appId;  
+            }
+        }
+    }
+    //存储在本地的Network json数据
+    [Serializable]
+    public class NetworkLocalData
+    {
+        public string name;
+        public string version;
+        public int country;
+        public string path;
+    }
+
+    [Serializable]
+    public class HotfixPluginData
+    {
+        public string plugin_version;
+        public string hot_fix_version;
+        public string download_url;
+        public int status;
+        public string file_name;
+    }
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATPluginLocalDataModel.cs.meta

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

+ 36 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATSdkUtil.cs

@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using UnityEngine;
+// #if UNITY_EDITOR    //是Unity编辑器才引入
+using UnityEditor;
+// #endif
+
+
+public class ATSdkUtil
+{
+// #if UNITY_EDITOR
+    /// <summary>
+    /// Gets the path of the asset in the project for a given Anythink plugin export path.
+    /// </summary>
+    /// <param name="exportPath">The actual exported path of the asset.</param>
+    /// <returns>The exported path of the MAX plugin asset or the default export path if the asset is not found.</returns>
+    public static string GetAssetPathForExportPath(string exportPath)
+    {
+        var defaultPath = Path.Combine("Assets", exportPath);
+        var assetLabelToFind = "l:al_max_export_path-" + exportPath.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
+        var assetGuids = AssetDatabase.FindAssets(assetLabelToFind);
+
+        return assetGuids.Length < 1 ? defaultPath : AssetDatabase.GUIDToAssetPath(assetGuids[0]);
+    }
+
+    public static bool Exists(string filePath)
+    {
+        return Directory.Exists(filePath) || File.Exists(filePath);
+    }
+// #endif
+}

+ 11 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/ATSdkUtil.cs.meta

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

+ 10 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/AnyThinkPlugin.IntegrationManager.Editor.asmdef

@@ -0,0 +1,10 @@
+{
+    "name": "AnyThinkPlugin.Script.IntegrationManager.Editor",
+    "references": [
+        "AnyThinkPlugin.Script"
+    ],
+    "includePlatforms": [
+        "Editor"
+    ],
+    "excludePlatforms": []
+}

+ 7 - 0
Assets/AnyThinkPlugin/Script/IntegrationManager/Editor/AnyThinkPlugin.IntegrationManager.Editor.asmdef.meta

@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 483a01338fa974b4498cd71261d6e8b9
+AssemblyDefinitionImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/ExternalDependencyManager.meta

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

+ 8 - 0
Assets/ExternalDependencyManager/Editor.meta

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

+ 8 - 0
Assets/ExternalDependencyManager/Editor/1.2.177.meta

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

BIN
Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll


BIN
Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll.mdb


+ 13 - 0
Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll.mdb.meta

@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: Xi5O5n77US0ObUOB9tj1D3+ebDL8926onFU6QXSHdnO8a1FtX3wc0BtzMuyJ
+labels:
+- gvh
+- gvh_rename_to_disable
+- gvh_version-1.2.177
+- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll.mdb
+- gvhp_targets-editor
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 36 - 0
Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll.meta

@@ -0,0 +1,36 @@
+fileFormatVersion: 2
+guid: 5552c54c11d94016bcfe740f27df44a6
+labels:
+- gvh
+- gvh_version-1.2.177
+- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll
+- gvhp_targets-editor
+timeCreated: 1480838400
+PluginImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  iconMap: {}
+  executionOrder: {}
+  isPreloaded: 0
+  isOverridable: 0
+  platformData:
+  - first:
+      Any:
+    second:
+      enabled: 0
+      settings: {}
+  - first:
+      Editor: Editor
+    second:
+      enabled: 1
+      settings:
+        DefaultValueInitialized: true
+  - first:
+      Windows Store Apps: WindowsStoreApps
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+  userData:
+  assetBundleName:
+  assetBundleVariant:

BIN
Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll


BIN
Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll.mdb


+ 13 - 0
Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll.mdb.meta

@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: XHwetimpUH1y2Es19WZszezwR1ZJb6RQJRYN9fatUTrOwHLk5cKIVYU3Wpf+
+labels:
+- gvh
+- gvh_rename_to_disable
+- gvh_version-1.2.177
+- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll.mdb
+- gvhp_targets-editor
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 36 - 0
Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll.meta

@@ -0,0 +1,36 @@
+fileFormatVersion: 2
+guid: 1f4f113972f04c3695341dfb3ba48d3b
+labels:
+- gvh
+- gvh_version-1.2.177
+- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll
+- gvhp_targets-editor
+timeCreated: 1480838400
+PluginImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  iconMap: {}
+  executionOrder: {}
+  isPreloaded: 0
+  isOverridable: 0
+  platformData:
+  - first:
+      Any:
+    second:
+      enabled: 0
+      settings: {}
+  - first:
+      Editor: Editor
+    second:
+      enabled: 1
+      settings:
+        DefaultValueInitialized: true
+  - first:
+      Windows Store Apps: WindowsStoreApps
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+  userData:
+  assetBundleName:
+  assetBundleVariant:

BIN
Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll


BIN
Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll.mdb


+ 13 - 0
Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll.mdb.meta

@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: XXwf4CmtVy08hkLmCPhTjMHSZYAKLokhjXFFNeP9xssEWxHrZwdnb9+VwZf0
+labels:
+- gvh
+- gvh_rename_to_disable
+- gvh_version-1.2.177
+- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll.mdb
+- gvhp_targets-editor
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 36 - 0
Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll.meta

@@ -0,0 +1,36 @@
+fileFormatVersion: 2
+guid: 413ed4abd14645c38ebbd8c5ff26e9de
+labels:
+- gvh
+- gvh_version-1.2.177
+- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll
+- gvhp_targets-editor
+timeCreated: 1480838400
+PluginImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  iconMap: {}
+  executionOrder: {}
+  isPreloaded: 0
+  isOverridable: 0
+  platformData:
+  - first:
+      Any:
+    second:
+      enabled: 0
+      settings: {}
+  - first:
+      Editor: Editor
+    second:
+      enabled: 1
+      settings:
+        DefaultValueInitialized: true
+  - first:
+      Windows Store Apps: WindowsStoreApps
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+  userData:
+  assetBundleName:
+  assetBundleVariant:

BIN
Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll


BIN
Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll.mdb


+ 13 - 0
Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll.mdb.meta

@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: XS4dtSn7BXq/2sTLNx+lTSTonkKKI0ZkT9/DVDOoszs/FGFGqarpaTYCtLoY
+labels:
+- gvh
+- gvh_rename_to_disable
+- gvh_version-1.2.177
+- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll.mdb
+- gvhp_targets-editor
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 36 - 0
Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll.meta

@@ -0,0 +1,36 @@
+fileFormatVersion: 2
+guid: 38d0b40a7b2d44c6a6a2362599bfc41e
+labels:
+- gvh
+- gvh_version-1.2.177
+- gvhp_exportpath-ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll
+- gvhp_targets-editor
+timeCreated: 1480838400
+PluginImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  iconMap: {}
+  executionOrder: {}
+  isPreloaded: 0
+  isOverridable: 0
+  platformData:
+  - first:
+      Any:
+    second:
+      enabled: 0
+      settings: {}
+  - first:
+      Editor: Editor
+    second:
+      enabled: 1
+      settings:
+        DefaultValueInitialized: true
+  - first:
+      Windows Store Apps: WindowsStoreApps
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+  userData:
+  assetBundleName:
+  assetBundleVariant:

BIN
Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll


BIN
Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll.mdb


+ 12 - 0
Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll.mdb.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 5855ffeab65945dc8f9cb3dc063f9eba
+labels:
+- gvh
+- gvh_version-1.2.177
+- gvhp_exportpath-ExternalDependencyManager/Editor/Google.VersionHandler.dll.mdb
+timeCreated: 1538009133
+licenseType: Pro
+DefaultImporter:
+  userData:
+  assetBundleName:
+  assetBundleVariant:

+ 36 - 0
Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll.meta

@@ -0,0 +1,36 @@
+fileFormatVersion: 2
+guid: 86460262ea60447dbb6a62d21167790f
+labels:
+- gvh
+- gvh_version-1.2.177
+- gvhp_exportpath-ExternalDependencyManager/Editor/Google.VersionHandler.dll
+- gvhp_targets-editor
+timeCreated: 1480838400
+PluginImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  iconMap: {}
+  executionOrder: {}
+  isPreloaded: 0
+  isOverridable: 0
+  platformData:
+  - first:
+      Any:
+    second:
+      enabled: 0
+      settings: {}
+  - first:
+      Editor: Editor
+    second:
+      enabled: 1
+      settings:
+        DefaultValueInitialized: true
+  - first:
+      Windows Store Apps: WindowsStoreApps
+    second:
+      enabled: 0
+      settings:
+        CPU: AnyCPU
+  userData:
+  assetBundleName:
+  assetBundleVariant:

+ 13 - 0
Assets/ExternalDependencyManager/Editor/external-dependency-manager_version-1.2.177_manifest.txt

@@ -0,0 +1,13 @@
+Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll
+Assets/ExternalDependencyManager/Editor/1.2.177/Google.IOSResolver.dll.mdb
+Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll
+Assets/ExternalDependencyManager/Editor/1.2.177/Google.JarResolver.dll.mdb
+Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll
+Assets/ExternalDependencyManager/Editor/1.2.177/Google.PackageManagerResolver.dll.mdb
+Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll
+Assets/ExternalDependencyManager/Editor/1.2.177/Google.VersionHandlerImpl.dll.mdb
+Assets/ExternalDependencyManager/Editor/CHANGELOG.md
+Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll
+Assets/ExternalDependencyManager/Editor/Google.VersionHandler.dll.mdb
+Assets/ExternalDependencyManager/Editor/LICENSE
+Assets/ExternalDependencyManager/Editor/README.md

+ 15 - 0
Assets/ExternalDependencyManager/Editor/external-dependency-manager_version-1.2.177_manifest.txt.meta

@@ -0,0 +1,15 @@
+fileFormatVersion: 2
+guid: 2764c5ea3b354f3cb7ca80028fd08da2
+labels:
+- gvh
+- gvh_manifest
+- gvh_version-1.2.177
+- gvhp_exportpath-ExternalDependencyManager/Editor/external-dependency-manager_version-1.2.177_manifest.txt
+- gvhp_manifestname-0External Dependency Manager
+- gvhp_manifestname-play-services-resolver
+timeCreated: 1474401009
+licenseType: Pro
+TextScriptImporter:
+  userData:
+  assetBundleName:
+  assetBundleVariant:

+ 8 - 0
Assets/Plugins/Android.meta

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

+ 2 - 1
Assets/Scripts/GameLogic/Fort23.GameLogic.asmdef

@@ -10,7 +10,8 @@
         "GUID:d8b63aba1907145bea998dd612889d6b",
         "GUID:5efd170ecd8084500bed5692932fe14e",
         "GUID:8097be56b8f8a81458fa9b1971038cec",
-        "GUID:9aacf4a871662084382dfb2f67105436"
+        "GUID:9aacf4a871662084382dfb2f67105436",
+        "ThirdParty"
     ],
     "includePlatforms": [],
     "excludePlatforms": [],

+ 8 - 0
Assets/Scripts/GameLogic/SDK.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: XixMt3moBXL1QtO+LWkr1Ivmd0Qa546T+ksvAPcFZBfhbWI0QsWuivyVk0/z
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 143 - 0
Assets/Scripts/GameLogic/SDK/TakuSDKManager.cs

@@ -0,0 +1,143 @@
+using System.Collections.Generic;
+using AnyThinkAds.Api;
+using AnyThinkAds.ThirdParty.LitJson;
+using Fort23.Core;
+using Fort23.UTool;
+using Utility;
+
+public class TakuSDKManager : Singleton<TakuSDKManager>, ATSDKInitListener
+{
+    private bool isOK;
+    private CTask<bool> _cTask;
+    private ATSDKInitListener _atsdkInitListener;
+
+    public void CustomInit()
+    {
+        //(可选配置)设置子渠道的信息,开发者可以通过该渠道信息在后台来区分看各个渠道的子渠道广告数据
+        //注意:如果有使用initCustomMap()方法,必须在initCustomMap()方法之后调用此方法
+        ATSDKAPI.setSubChannel("Google");
+
+        //设置开启Debug日志(强烈建议测试阶段开启,方便排查问题)
+        ATSDKAPI.setLogDebug(true);
+
+        //(必须配置)SDK的初始化
+        ATSDKAPI.initSDK("h67dd01a5e182e", "a3a3e17270711ba83fdc200d98cf67888", this); //Use your own app_id & app_key here
+
+     
+    }
+
+    public void AddAutoLoadAdPlacementID()
+    {
+        //广告加载成功
+        ATRewardedAutoVideo.Instance.client.onAdLoadEvent += onAdLoad;
+        //广告加载失败
+        ATRewardedAutoVideo.Instance.client.onAdLoadFailureEvent += onAdLoadFail;
+        //广告展示的回调(可依赖这个回调统计展示数据)
+        ATRewardedAutoVideo.Instance.client.onAdVideoStartEvent += onAdVideoStartEvent;
+        //广告播放结束
+        ATRewardedAutoVideo.Instance.client.onAdVideoEndEvent += onAdVideoEndEvent;
+        //广告视频播放失败
+        ATRewardedAutoVideo.Instance.client.onAdVideoFailureEvent += onAdVideoPlayFail;
+        //广告点击
+        ATRewardedAutoVideo.Instance.client.onAdClickEvent += onAdClick;
+        //广告激励回调(可依赖该监听下发游戏激励)
+        ATRewardedAutoVideo.Instance.client.onRewardEvent += onReward;
+        //广告被关闭
+        ATRewardedAutoVideo.Instance.client.onAdVideoCloseEvent += onAdVideoClosedEvent;
+
+        string[] jsonList = { "n67dd01ce07ec2" };
+
+        ATRewardedAutoVideo.Instance.addAutoLoadAdPlacementID(jsonList);
+    }
+
+    public bool IsReady()
+    {
+        return ATRewardedAutoVideo.Instance.autoLoadRewardedVideoReadyForPlacementID("n67dd01ce07ec2");
+    }
+
+    public async CTask<bool> ShowAutoAd()
+    {
+        _cTask = CTask<bool>.Create();
+        isOK = false;
+        if (IsReady())
+        {
+            ATRewardedAutoVideo.Instance.showAutoAd("n67dd01ce07ec2");
+        }
+        else
+        {
+            return false;
+        }
+
+        return await _cTask;
+    }
+
+
+    // 广告加载成功
+    public void onAdLoad(object sender, ATAdEventArgs erg)
+    {
+        LogTool.Error("开发者回调 广告加载成功 :" + erg.placementId);
+    }
+
+    // 广告加载失败
+    public void onAdLoadFail(object sender, ATAdErrorEventArgs erg)
+    {
+        LogTool.Error("开发者回调 广告加载失败 :" + erg.placementId + " erroCode:" + erg.errorCode + " eroMsg:" + erg.errorMessage);
+    }
+
+    // 广告视频开始播放
+    public void onAdVideoStartEvent(object sender, ATAdEventArgs erg)
+    {
+        LogTool.Error("开发者回调 广告视频开始播放------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toDictionary()));
+    }
+
+    // 广告视频播放结束
+    public void onAdVideoEndEvent(object sender, ATAdEventArgs erg)
+    {
+        LogTool.Error("开发者回调 广告视频播放结束------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toDictionary()));
+    }
+
+    // 广告视频播放失败
+    public void onAdVideoPlayFail(object sender, ATAdErrorEventArgs erg)
+    {
+        LogTool.Error("开发者回调 广告视频播放失败------" + "->" + JsonMapper.ToJson(erg.errorMessage));
+        isOK = false;
+    }
+
+
+    // 广告被点击
+    public void onAdClick(object sender, ATAdEventArgs erg)
+    {
+        LogTool.Error("开发者回调 广告被点击 :" + erg.placementId);
+    }
+
+    // 广告奖励发放
+    public void onReward(object sender, ATAdEventArgs erg)
+    {
+        LogTool.Error("开发者回调 广告奖励发放------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toDictionary()));
+        isOK = true;
+    }
+
+    // 广告视频被关闭
+    public void onAdVideoClosedEvent(object sender, ATAdEventArgs erg)
+    {
+        LogTool.Error("开发者回调 广告视频被关闭------" + "->" + JsonMapper.ToJson(erg.callbackInfo.toDictionary()));
+        _cTask.SetResult(isOK);
+    }
+
+    public void initSuccess()
+    {
+        // string[] deniedInfos = new string[] { "gaid" };
+        // foreach (var deniedInfo in deniedInfos)
+        // {
+        //     LogTool.Error("gdis:" + deniedInfo);
+        // }
+        //
+        // ATSDKAPI.deniedUploadDeviceInfo(deniedInfos);
+
+        //ATSDKAPI.showDebuggerUI("417b0c4ec2dad1d3ebffbcbb43e5da28d2bfefed");
+    }
+
+    public void initFail(string message)
+    {
+    }
+}

+ 11 - 0
Assets/Scripts/GameLogic/SDK/TakuSDKManager.cs.meta

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

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

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

+ 8 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api.meta

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

+ 218 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATAdEventArgs.cs

@@ -0,0 +1,218 @@
+        
+using System;
+using System.Collections;
+using AnyThinkAds.Api;
+
+namespace AnyThinkAds.Api
+{
+    
+    public class ATAdEventArgs
+    {
+        public String placementId { get; }
+        public ATCallbackInfo callbackInfo { get; }
+        public bool isTimeout { get; }
+
+        public bool isDeeplinkSucceed { get; }
+
+        public ATAdEventArgs(string id, string callbackJson = "", bool timeout = false, bool isDeeplinkSucceess = false)
+        {
+            placementId = id;
+            callbackInfo = new ATCallbackInfo(callbackJson);
+            isTimeout = timeout;
+            isDeeplinkSucceed = isDeeplinkSucceess;
+        }
+
+        // public ATAdEventArgs(String id, String callbackJson)
+        // {
+        //     placementId = id;
+        //     callbackInfo = new ATCallbackInfo(callbackJson);
+        // }
+    }
+
+    public class ATAdErrorEventArgs : ATAdEventArgs
+    {
+        public String errorMessage { get; }
+        public String errorCode { get; }
+
+        public ATAdErrorEventArgs(String placementId, String code, String message)
+            : base(placementId)
+        {
+            errorMessage = message;
+            errorCode = code;
+        }
+
+        public ATAdErrorEventArgs(String placementId, String callbackJson, String code, String message)
+            : base(placementId, callbackJson)
+        {
+            errorMessage = message;
+            errorCode = code;
+        }
+    }
+
+    public class ATAdProgressEventArgs : ATAdEventArgs
+    {
+        public int adProgress { get; }
+
+        public ATAdProgressEventArgs(String placementId, String callbackJson, int progress)
+            : base(placementId, callbackJson)
+        {
+            adProgress = progress;
+        }
+    }
+
+    public class ATAdRewardEventArgs : ATAdEventArgs
+    {
+        public bool isRewarded { get; }
+
+        public ATAdRewardEventArgs(String placementId, String callbackJson, bool doReward)
+            : base(placementId, callbackJson)
+        {
+            isRewarded = doReward;
+        }
+    }
+
+
+    public interface IHCommonEvents
+    {
+        // triggers when the ad has been succesfully loaded
+        event EventHandler<ATAdEventArgs> onAdLoadEvent;
+
+        // triggers when the ad has failed to load
+        event EventHandler<ATAdErrorEventArgs> onAdLoadFailureEvent;
+
+        // triggers when a the ad has started to load
+        event EventHandler<ATAdEventArgs> onAdSourceAttemptEvent;
+
+        // triggers when a the ad has finished to load
+        event EventHandler<ATAdEventArgs> onAdSourceFilledEvent;
+
+        // triggers when a the ad has started to load
+        event EventHandler<ATAdErrorEventArgs> onAdSourceLoadFailureEvent;
+
+        // triggers when a the ad has started to load
+        event EventHandler<ATAdEventArgs> onAdSourceBiddingAttemptEvent;
+
+        // triggers when a the ad has started to load
+        event EventHandler<ATAdEventArgs> onAdSourceBiddingFilledEvent;
+
+        // triggers when a the ad has started to load
+        event EventHandler<ATAdErrorEventArgs> onAdSourceBiddingFailureEvent;
+    }
+
+
+    public interface IATBannerEvents: IHCommonEvents
+    {
+        // triggers when a banner ad generates an impression
+        event EventHandler<ATAdEventArgs> onAdImpressEvent;
+
+        // triggers when the user clicks a banner ad
+        event EventHandler<ATAdEventArgs> onAdClickEvent;
+
+        // triggers when the ad refreshes
+        event EventHandler<ATAdEventArgs> onAdAutoRefreshEvent;
+
+        // triggers when the ad fails to auto refresh
+        event EventHandler<ATAdErrorEventArgs> onAdAutoRefreshFailureEvent;
+
+        // triggers when the banner ad is closed
+        event EventHandler<ATAdEventArgs> onAdCloseEvent;
+
+        // triggers when the users closes the ad via the button
+        event EventHandler<ATAdEventArgs> onAdCloseButtonTappedEvent;
+    }
+    
+    public interface IATInterstitialAdEvents : IHCommonEvents
+    {
+        // called when the ad is shown
+        event EventHandler<ATAdEventArgs> onAdShowEvent;
+
+        // called if the ad has failed to be shown
+        event EventHandler<ATAdErrorEventArgs> onAdShowFailureEvent;
+
+        // called when the ad is closed
+        event EventHandler<ATAdEventArgs> onAdCloseEvent;
+
+        // called when an user has clicked an ad
+        event EventHandler<ATAdEventArgs> onAdClickEvent;
+
+        // called when a video ad has started playing
+        event EventHandler<ATAdEventArgs> onAdVideoStartEvent;
+
+        // called if an ad video has failed to be displayed
+        event EventHandler<ATAdErrorEventArgs> onAdVideoFailureEvent;
+
+        // called when ad video has finished
+        event EventHandler<ATAdEventArgs> onAdVideoEndEvent;          
+    }
+
+    public interface IATNativeAdEvents : IHCommonEvents
+    {
+        // triggers when the ad generates an impression
+        event EventHandler<ATAdEventArgs> onAdImpressEvent;
+
+        // triggers when the user clicks the ad
+        event EventHandler<ATAdEventArgs> onAdClickEvent;
+
+        // triggers when the ad video starts
+        event EventHandler<ATAdEventArgs> onAdVideoStartEvent;
+
+        // triggers when the ad video ends
+        event EventHandler<ATAdEventArgs> onAdVideoEndEvent;
+
+        // triggers if the ad progresses
+        event EventHandler<ATAdProgressEventArgs> onAdVideoProgressEvent;
+
+        // triggers when the ad is closed
+        event EventHandler<ATAdEventArgs> onAdCloseEvent;           
+    }
+
+    public interface IATRewardedVideoEvents : IHCommonEvents
+    {
+        // triggers on video start
+        event EventHandler<ATAdEventArgs> onAdVideoStartEvent;
+
+        // triggers on video end
+        event EventHandler<ATAdEventArgs> onAdVideoEndEvent;
+
+        // triggers if the video fails to play
+        event EventHandler<ATAdErrorEventArgs> onAdVideoFailureEvent;
+
+        // triggers when the user has closed the ad
+        event EventHandler<ATAdRewardEventArgs> onAdVideoCloseEvent;
+
+        // triggers when the user has clicked the ad
+        event EventHandler<ATAdEventArgs> onAdClickEvent;
+
+        // triggers when the user has finsihed watching the ad and should be rewarded
+        event EventHandler<ATAdEventArgs> onRewardEvent;
+
+        event EventHandler<ATAdEventArgs> onPlayAgainStart;
+
+        event EventHandler<ATAdEventArgs> onPlayAgainEnd;
+
+        event EventHandler<ATAdErrorEventArgs> onPlayAgainFailure;
+
+        event EventHandler<ATAdEventArgs> onPlayAgainClick;
+
+        event EventHandler<ATAdEventArgs> onPlayAgainReward;
+    }
+
+    public interface IATSplashEvents : IHCommonEvents
+    {
+        // called when the ad is shown
+        event EventHandler<ATAdEventArgs> onAdShowEvent;
+
+        // called if the ad has failed to be shown
+        event EventHandler<ATAdErrorEventArgs> onAdShowFailureEvent;
+
+        // called when the ad is closed
+        event EventHandler<ATAdEventArgs> onAdCloseEvent;
+
+        // called when an user has clicked an ad
+        event EventHandler<ATAdEventArgs> onAdClickEvent; 
+
+        event EventHandler<ATAdEventArgs>    onAdLoadTimeoutEvent;
+        event EventHandler<ATAdEventArgs>    onDeeplinkEvent;
+        event EventHandler<ATAdEventArgs>    onDownloadConfirmEvent;    
+    }
+}

+ 11 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATAdEventArgs.cs.meta

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

+ 130 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATBannerAd.cs

@@ -0,0 +1,130 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using System.Reflection;
+using System;
+
+using AnyThinkAds.Common;
+using AnyThinkAds.ThirdParty.LitJson;
+
+namespace AnyThinkAds.Api
+{
+    public class ATBannerAdLoadingExtra
+    {
+        public static readonly string kATBannerAdLoadingExtraBannerAdSize = "banner_ad_size";
+        public static readonly string kATBannerAdLoadingExtraBannerAdSizeStruct = "banner_ad_size_struct";
+        public static readonly string kATBannerAdSizeUsesPixelFlagKey = "uses_pixel";
+        public static readonly string kATBannerAdShowingPisitionTop = "top";
+        public static readonly string kATBannerAdShowingPisitionBottom = "bottom";
+
+        //Deprecated in v5.7.3
+        public static readonly string kATBannerAdLoadingExtraInlineAdaptiveWidth = "inline_adaptive_width";
+        public static readonly string kATBannerAdLoadingExtraInlineAdaptiveOrientation = "inline_adaptive_orientation";
+        public static readonly int kATBannerAdLoadingExtraInlineAdaptiveOrientationCurrent = 0;
+        public static readonly int kATBannerAdLoadingExtraInlineAdaptiveOrientationPortrait = 1;
+        public static readonly int kATBannerAdLoadingExtraInlineAdaptiveOrientationLandscape = 2;
+        //Deprecated in v5.7.3
+
+        public static readonly string kATBannerAdLoadingExtraAdaptiveWidth = "adaptive_width";
+        public static readonly string kATBannerAdLoadingExtraAdaptiveOrientation = "adaptive_orientation";
+        public static readonly int kATBannerAdLoadingExtraAdaptiveOrientationCurrent = 0;
+        public static readonly int kATBannerAdLoadingExtraAdaptiveOrientationPortrait = 1;
+        public static readonly int kATBannerAdLoadingExtraAdaptiveOrientationLandscape = 2;
+
+    }
+    public class ATBannerAd 
+	{
+		private static readonly ATBannerAd instance = new ATBannerAd();
+		public IATBannerAdClient client;
+
+		private ATBannerAd() 
+		{
+            client = GetATBannerAdClient();
+            
+		}
+
+		public static ATBannerAd Instance 
+		{
+			get 
+			{
+				return instance;
+			}
+		}
+
+		/**
+		API
+		*/
+		public void loadBannerAd(string placementId, Dictionary<string,object> pairs)
+		{   
+            if (pairs != null && pairs.ContainsKey(ATBannerAdLoadingExtra.kATBannerAdLoadingExtraBannerAdSize))
+            {
+                client.loadBannerAd(placementId, JsonMapper.ToJson(pairs));
+            }
+            else if (pairs != null && pairs.ContainsKey(ATBannerAdLoadingExtra.kATBannerAdLoadingExtraBannerAdSizeStruct))
+            {
+                ATSize size = (ATSize)(pairs[ATBannerAdLoadingExtra.kATBannerAdLoadingExtraBannerAdSizeStruct]);
+                pairs.Add(ATBannerAdLoadingExtra.kATBannerAdLoadingExtraBannerAdSize, size.width + "x" + size.height);
+                pairs.Add(ATBannerAdLoadingExtra.kATBannerAdSizeUsesPixelFlagKey, size.usesPixel);
+
+                //Dictionary<string, object> newPaires = new Dictionary<string, object> { { ATBannerAdLoadingExtra.kATBannerAdLoadingExtraBannerAdSize, size.width + "x" + size.height }, { ATBannerAdLoadingExtra.kATBannerAdSizeUsesPixelFlagKey, size.usesPixel } };
+                client.loadBannerAd(placementId, JsonMapper.ToJson(pairs));
+            }
+            else
+            {
+                client.loadBannerAd(placementId, JsonMapper.ToJson(pairs));
+            }
+			
+		}
+
+        public string checkAdStatus(string placementId)
+        {
+            return client.checkAdStatus(placementId);
+        }
+
+        public string getValidAdCaches(string placementId)
+        {
+            return client.getValidAdCaches(placementId);
+        }
+
+
+        public void showBannerAd(string placementId, ATRect rect)
+        {
+            client.showBannerAd(placementId, rect, "");
+        }
+
+        public void showBannerAd(string placementId, ATRect rect, Dictionary<string,string> pairs)
+        {
+            client.showBannerAd(placementId, rect, JsonMapper.ToJson(pairs));
+        }
+
+        public void showBannerAd(string placementId, string position)
+        {
+            client.showBannerAd(placementId, position, "");
+        }
+
+        public void showBannerAd(string placementId, string position, Dictionary<string,string> pairs)
+        {
+            client.showBannerAd(placementId, position, JsonMapper.ToJson(pairs));
+        }
+
+        public void showBannerAd(string placementId)
+        {
+            client.showBannerAd(placementId);
+        }
+
+        public void hideBannerAd(string placementId)
+        {
+            client.hideBannerAd(placementId);
+        }
+
+        public void cleanBannerAd(string placementId)
+        {
+            client.cleanBannerAd(placementId);
+        }
+
+        public IATBannerAdClient GetATBannerAdClient()
+        {
+            return AnyThinkAds.ATAdsClientFactory.BuildBannerAdClient();
+        }
+	}
+}

+ 11 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATBannerAd.cs.meta

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

+ 57 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATBannerAdListener.cs

@@ -0,0 +1,57 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace AnyThinkAds.Api
+{
+    public interface ATBannerAdListener
+    {
+		/***
+		 * 广告请求成功(注意:对于Android来说,所有回调方法均不在Unity的主线程)
+		 */
+        void onAdLoad(string placementId);
+		/***
+		 * 广告请求失败(注意:对于Android来说,所有回调方法均不在Unity的主线程)
+		 */ 
+        void onAdLoadFail(string placementId, string code, string message);
+		/***
+		 * 广告展示(注意:对于Android来说,所有回调方法均不在Unity的主线程)
+		 */ 
+        void onAdImpress(string placementId, ATCallbackInfo callbackInfo);
+		/**
+		 * 广告点击(注意:对于Android来说,所有回调方法均不在Unity的主线程)
+		 */ 
+        void onAdClick(string placementId, ATCallbackInfo callbackInfo);
+		/**
+		 * 广告自动刷新(注意:对于Android来说,所有回调方法均不在Unity的主线程)
+		 */
+        void onAdAutoRefresh(string placementId, ATCallbackInfo callbackInfo);
+        /**
+        *广告自动刷新失败(注意:对于Android来说,所有回调方法均不在Unity的主线程)
+        */
+        void onAdAutoRefreshFail(string placementId, string code, string message);
+        /**
+        *广告关闭;某些厂商不支持(注意:对于Android来说,所有回调方法均不在Unity的主线程)
+        */
+        void onAdClose(string placementId);
+        /**
+        *广告关闭;某些厂商不支持(注意:对于Android来说,所有回调方法均不在Unity的主线程)
+        */
+        void onAdCloseButtonTapped(string placementId, ATCallbackInfo callbackInfo);
+        
+
+		void startLoadingADSource(string placementId, ATCallbackInfo callbackInfo);
+
+		void finishLoadingADSource(string placementId, ATCallbackInfo callbackInfo);
+
+		void failToLoadADSource(string placementId,ATCallbackInfo callbackInfo,string code, string message);
+
+		void startBiddingADSource(string placementId, ATCallbackInfo callbackInfo);
+
+		void finishBiddingADSource(string placementId, ATCallbackInfo callbackInfo);
+
+		void failBiddingADSource(string placementId,ATCallbackInfo callbackInfo,string code, string message);
+
+
+    }
+}

+ 11 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATBannerAdListener.cs.meta

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

+ 189 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATCallbackInfo.cs

@@ -0,0 +1,189 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using AnyThinkAds.ThirdParty.LitJson;
+
+namespace AnyThinkAds.Api
+{
+    public class ATCallbackInfo
+    {
+
+        public readonly int network_firm_id;
+        public readonly string adsource_id;
+        public readonly int adsource_index;
+        public readonly double adsource_price;
+        public readonly int adsource_isheaderbidding;
+
+        public readonly string id;
+        public readonly double publisher_revenue;
+        public readonly string currency;
+        public readonly string country;
+        public readonly string adunit_id;
+
+        public readonly string adunit_format;
+        public readonly string precision;
+        public readonly string network_type;
+        public readonly string network_placement_id;
+        public readonly int ecpm_level;
+
+        public readonly int segment_id;
+        public readonly string scenario_id;
+        public readonly string scenario_reward_name;
+        public readonly int scenario_reward_number;
+
+        public readonly string sub_channel;
+        public readonly string channel;
+        public readonly Dictionary<string, object> custom_rule;
+        
+        public readonly Dictionary<string, object> ext_info;
+        public readonly Dictionary<string, object> user_load_extra_data;
+        public readonly int abtest_id;
+
+        public readonly string reward_custom_data;
+        public readonly int placement_type;
+        public readonly string shared_placement_id;
+        public readonly string bid_floor;
+        public readonly int dismiss_type;
+        public readonly int ad_source_type;
+        public readonly string ad_source_custom_ext;
+        public readonly string network_name;
+        public readonly string show_custom_ext;
+        public readonly string e_c;
+        public readonly int s_id;
+
+        private string callbackJson;
+
+        public ATCallbackInfo(string callbackJson)
+        {
+            try
+            {
+                this.callbackJson = callbackJson;
+
+
+                JsonData jsonData = JsonMapper.ToObject(callbackJson);
+
+                network_firm_id = int.Parse(jsonData.ContainsKey("network_firm_id") ? jsonData["network_firm_id"].ToString() : "0");
+                adsource_id = jsonData.ContainsKey("adsource_id") ? (string)jsonData["adsource_id"] : "";
+                adsource_index = int.Parse(jsonData.ContainsKey("adsource_index") ? jsonData["adsource_index"].ToString() : "-1");
+                adsource_price = double.Parse(jsonData.ContainsKey("adsource_price") ? jsonData["adsource_price"].ToString() : "0");
+
+                adsource_isheaderbidding = 0;
+                if (jsonData.ContainsKey("adsource_isheaderbidding")) {
+                    adsource_isheaderbidding = int.Parse(jsonData.ContainsKey("adsource_isheaderbidding") ? jsonData["adsource_isheaderbidding"].ToString() : "0");
+                }
+
+                id = jsonData.ContainsKey("id") ? (string)jsonData["id"] : "";
+                publisher_revenue = double.Parse(jsonData.ContainsKey("publisher_revenue") ? jsonData["publisher_revenue"].ToString() : "0");
+                currency = jsonData.ContainsKey("currency") ? (string)jsonData["currency"] : "";
+                country = jsonData.ContainsKey("country") ? (string)jsonData["country"] : "";
+
+                adunit_format = jsonData.ContainsKey("adunit_format") ? (string)jsonData["adunit_format"] : "";
+                adunit_id = jsonData.ContainsKey("adunit_id") ? (string)jsonData["adunit_id"] : "";
+
+                precision = jsonData.ContainsKey("precision") ? (string)jsonData["precision"] : "";
+
+                network_type = jsonData.ContainsKey("network_type") ? (string)jsonData["network_type"] : "";
+
+                network_placement_id = jsonData.ContainsKey("network_placement_id") ? (string)jsonData["network_placement_id"] : "";
+                ecpm_level = int.Parse(jsonData.ContainsKey("ecpm_level") ? jsonData["ecpm_level"].ToString() : "0");
+                abtest_id = int.Parse(jsonData.ContainsKey("abtest_id") ? jsonData["abtest_id"].ToString() : "0");
+                segment_id = int.Parse(jsonData.ContainsKey("segment_id") ? jsonData["segment_id"].ToString() : "0");
+                scenario_id = jsonData.ContainsKey("scenario_id") ? (string)jsonData["scenario_id"] : "";// RewardVideo & Interstitial
+
+                if (jsonData.ContainsKey("user_load_extra_data")) {
+                        user_load_extra_data = JsonMapper.ToObject<Dictionary<string, object>>(jsonData["user_load_extra_data"].ToJson());
+                }
+
+                scenario_reward_name = jsonData.ContainsKey("scenario_reward_name") ? (string)jsonData["scenario_reward_name"] : "";
+                scenario_reward_number = int.Parse(jsonData.ContainsKey("scenario_reward_number") ? jsonData["scenario_reward_number"].ToString() : "0");
+
+                channel = jsonData.ContainsKey("channel") ? (string)jsonData["channel"] : "";
+                sub_channel = jsonData.ContainsKey("sub_channel") ? (string)jsonData["sub_channel"] : "";
+                custom_rule = jsonData.ContainsKey("custom_rule") ? JsonMapper.ToObject<Dictionary<string, object>>(jsonData["custom_rule"].ToJson()) : null;
+                ext_info = jsonData.ContainsKey("ext_info") ? JsonMapper.ToObject<Dictionary<string, object>>(jsonData["ext_info"].ToJson()) : null;
+
+                reward_custom_data = jsonData.ContainsKey("reward_custom_data") ? (string)jsonData["reward_custom_data"] : "";
+
+                placement_type = int.Parse(jsonData.ContainsKey("placement_type") ? jsonData["placement_type"].ToString() : "0");
+                shared_placement_id = jsonData.ContainsKey("shared_placement_id") ? jsonData["shared_placement_id"].ToString() : "";
+                bid_floor = jsonData.ContainsKey("bid_floor") ? jsonData["bid_floor"].ToString() : "";
+                dismiss_type = int.Parse(jsonData.ContainsKey("dismiss_type") ? jsonData["dismiss_type"].ToString() : "0");
+                ad_source_type = int.Parse(jsonData.ContainsKey("ad_source_type") ? jsonData["ad_source_type"].ToString() : "0");
+                ad_source_custom_ext = jsonData.ContainsKey("ad_source_custom_ext") ? jsonData["ad_source_custom_ext"].ToString() : "";
+                network_name = jsonData.ContainsKey("network_name") ? jsonData["network_name"].ToString() : "";
+                show_custom_ext = jsonData.ContainsKey("show_custom_ext") ? jsonData["show_custom_ext"].ToString() : "";
+                e_c = jsonData.ContainsKey("e_c") ? jsonData["e_c"].ToString() : "";
+                s_id = int.Parse(jsonData.ContainsKey("s_id") ? jsonData["s_id"].ToString() : "0");
+            }
+            catch (System.Exception e) {
+                System.Console.WriteLine("Exception caught: {0}", e);
+            }
+        }
+
+        public string getOriginJSONString()
+                {
+            return callbackJson;
+        }
+
+        public Dictionary<string, object> toAdsourceDictionary()
+        {
+            Dictionary<string, object> dataDictionary = new Dictionary<string, object>();
+
+            dataDictionary.Add("adsource_id", adsource_id);
+            dataDictionary.Add("adsource_price", adsource_price);
+            dataDictionary.Add("adunit_id", adunit_id);
+            dataDictionary.Add("currency", currency);
+            dataDictionary.Add("network_firm_id",network_firm_id);
+            dataDictionary.Add("network_placement_id",network_placement_id);
+            return dataDictionary;
+
+        }
+
+        public Dictionary<string, object> toDictionary()
+        {
+            Dictionary<string, object> dataDictionary = new Dictionary<string, object>();
+
+            dataDictionary.Add("network_firm_id",network_firm_id);
+            dataDictionary.Add("adsource_id", adsource_id);
+            dataDictionary.Add("adsource_index", adsource_index);
+            dataDictionary.Add("adsource_price", adsource_price);
+            dataDictionary.Add("adsource_isheaderbidding", adsource_isheaderbidding);
+            dataDictionary.Add("id", id);
+            dataDictionary.Add("publisher_revenue", publisher_revenue);
+            dataDictionary.Add("currency", currency);
+            dataDictionary.Add("country", country);
+            dataDictionary.Add("adunit_id", adunit_id);
+            dataDictionary.Add("adunit_format", adunit_format);
+            dataDictionary.Add("precision", precision);
+            dataDictionary.Add("network_type", network_type);
+            dataDictionary.Add("network_placement_id",network_placement_id);
+            dataDictionary.Add("ecpm_level", ecpm_level);
+            dataDictionary.Add("segment_id", segment_id);
+            dataDictionary.Add("scenario_id", scenario_id);
+            dataDictionary.Add("user_load_extra_data", user_load_extra_data);
+            dataDictionary.Add("scenario_reward_name", scenario_reward_name);
+            dataDictionary.Add("scenario_reward_number", scenario_reward_number);
+            dataDictionary.Add("abtest_id", abtest_id);
+
+            dataDictionary.Add("sub_channel", sub_channel);
+            dataDictionary.Add("channel", channel);
+            dataDictionary.Add("custom_rule", custom_rule);
+            dataDictionary.Add("ext_info", ext_info);
+            dataDictionary.Add("reward_custom_data", reward_custom_data);
+            dataDictionary.Add("placement_type", placement_type);
+            dataDictionary.Add("shared_placement_id", shared_placement_id);
+            dataDictionary.Add("bid_floor", bid_floor);
+            dataDictionary.Add("dismiss_type", dismiss_type);
+            dataDictionary.Add("ad_source_type", ad_source_type);
+            dataDictionary.Add("ad_source_custom_ext", ad_source_custom_ext);
+            dataDictionary.Add("network_name", network_name);
+            dataDictionary.Add("show_custom_ext", show_custom_ext);
+            dataDictionary.Add("e_c", e_c);
+            dataDictionary.Add("s_id", s_id);
+
+            return dataDictionary;
+        }
+
+
+    }
+}

+ 11 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATCallbackInfo.cs.meta

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

+ 25 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATConst.cs

@@ -0,0 +1,25 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace AnyThinkAds.Api
+{
+	public class ATConst  {
+        public const string ADAPTIVE_HEIGHT = "AdaptiveHeight";//value is string
+        public const string ADAPTIVE_HEIGHT_YES = "1";
+        public const string POSITION = "Position";//value is string
+        public const string POSITION_TOP = "Top";
+        public const string POSITION_BOTTOM = "Bottom";
+
+
+        public const string SCENARIO = "Scenario";//value is string
+        public const string USERID_KEY = "UserId";//value is string
+        public const string USER_EXTRA_DATA = "UserExtraData"; //value is string
+        public const string USE_REWARDED_VIDEO_AS_INTERSTITIAL = "UseRewardedVideoAsInterstitial";//value is string
+        public const string USE_REWARDED_VIDEO_AS_INTERSTITIAL_YES = "1";
+        public const string USE_REWARDED_VIDEO_AS_INTERSTITIAL_NO = "0";
+
+        public const string WIDTH = "Width";//value is string
+        public const string HEIGHT = "Height";//value is string
+    }
+}

+ 11 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATConst.cs.meta

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

+ 21 - 0
Assets/Scripts/ThirdParty/AnyThinkAds/Api/ATDownloadAdListener.cs

@@ -0,0 +1,21 @@
+
+
+namespace AnyThinkAds.Api
+{
+    public interface ATDownloadAdListener
+    {
+		
+        void onDownloadStart(string placementId, ATCallbackInfo callbackInfo, long totalBytes, long currBytes, string fileName, string appName);
+        
+        void onDownloadUpdate(string placementId, ATCallbackInfo callbackInfo, long totalBytes, long currBytes, string fileName, string appName);
+        
+        void onDownloadPause(string placementId, ATCallbackInfo callbackInfo, long totalBytes, long currBytes, string fileName, string appName);
+		
+        void onDownloadFinish(string placementId, ATCallbackInfo callbackInfo, long totalBytes, string fileName, string appName);
+        
+        void onDownloadFail(string placementId, ATCallbackInfo callbackInfo, long totalBytes, long currBytes, string fileName, string appName);
+        
+        void onInstalled(string placementId, ATCallbackInfo callbackInfo, string fileName, string appName);
+       
+    }
+}

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików