From bb1a4b8ccee822b42b837ec4103eb7758cbbd17c Mon Sep 17 00:00:00 2001 From: HuYufei Date: Tue, 26 Dec 2023 11:40:48 +0800 Subject: [PATCH] init commit --- .gitignore | 1 + Editor.meta | 3 + Editor/GuruManager.meta | 3 + Editor/GuruManager/Config.meta | 3 + .../GuruManager/Config/EditorGuruServiceIO.cs | 93 ++ .../Config/EditorGuruServiceIO.cs.meta | 3 + Editor/GuruManager/Files.meta | 3 + Editor/GuruManager/Files/AndroidManifest.txt | 40 + .../Files/AndroidManifest.txt.meta | 3 + Editor/GuruManager/Files/gradleTemplate.txt | 9 + .../GuruManager/Files/gradleTemplate.txt.meta | 3 + Editor/GuruManager/Files/launcherTemplate.txt | 66 ++ .../Files/launcherTemplate.txt.meta | 7 + Editor/GuruManager/Files/mainTemplate.txt | 0 .../GuruManager/Files/mainTemplate.txt.meta | 7 + Editor/GuruManager/Helper.meta | 3 + .../GuruManager/Helper/AndroidManifestMod.cs | 113 +++ .../Helper/AndroidManifestMod.cs.meta | 3 + .../GuruManager/Helper/AndroidProjectMod.cs | 117 +++ .../Helper/AndroidProjectMod.cs.meta | 3 + Editor/GuruManager/Helper/GuruEditorHelper.cs | 17 + .../Helper/GuruEditorHelper.cs.meta | 3 + Editor/GuruManager/Helper/GuruSDKBooster.cs | 69 ++ .../GuruManager/Helper/GuruSDKBooster.cs.meta | 3 + Editor/GuruManager/Helper/GuruSDKMenuItems.cs | 16 + .../Helper/GuruSDKMenuItems.cs.meta | 3 + Editor/GuruManager/Manager.meta | 3 + Editor/GuruManager/Manager/GuruSDKManager.cs | 887 ++++++++++++++++++ .../Manager/GuruSDKManager.cs.meta | 3 + Editor/GuruSDK.Editor.asmdef | 22 + Editor/GuruSDK.Editor.asmdef.meta | 3 + Runtime.meta | 3 + Runtime/Code.meta | 3 + Runtime/Code/Config.meta | 3 + Runtime/Code/Core.meta | 3 + Runtime/Code/Core/GuruSDK.Ads.cs | 223 +++++ Runtime/Code/Core/GuruSDK.Ads.cs.meta | 3 + Runtime/Code/Core/GuruSDK.Analytics.cs | 216 +++++ Runtime/Code/Core/GuruSDK.Analytics.cs.meta | 3 + Runtime/Code/Core/GuruSDK.Callback.cs | 119 +++ Runtime/Code/Core/GuruSDK.Callback.cs.meta | 3 + Runtime/Code/Core/GuruSDK.IAP.cs | 136 +++ Runtime/Code/Core/GuruSDK.IAP.cs.meta | 3 + Runtime/Code/Core/GuruSDK.cs | 175 ++++ Runtime/Code/Core/GuruSDK.cs.meta | 3 + Runtime/Code/Core/GuruSDKInitConfig.cs | 97 ++ Runtime/Code/Core/GuruSDKInitConfig.cs.meta | 3 + Runtime/Code/Core/GuruServiceConfig.cs | 94 ++ Runtime/Code/Core/GuruServiceConfig.cs.meta | 3 + Runtime/Code/IAP.meta | 3 + Runtime/Code/IAP/GuruIAP.cs | 20 + Runtime/Code/IAP/GuruIAP.cs.meta | 3 + Runtime/Code/Model.meta | 3 + Runtime/Code/Model/BindableProperty.cs | 38 + Runtime/Code/Model/BindableProperty.cs.meta | 3 + Runtime/Code/Model/GuruSDKModel.cs | 171 ++++ Runtime/Code/Model/GuruSDKModel.cs.meta | 3 + Runtime/GuruSDK.asmdef | 19 + Runtime/GuruSDK.asmdef.meta | 3 + Runtime/Prefab.meta | 3 + link.xml | 5 + link.xml.meta | 3 + package.json | 15 + package.json.meta | 3 + 64 files changed, 2900 insertions(+) create mode 100644 .gitignore create mode 100644 Editor.meta create mode 100644 Editor/GuruManager.meta create mode 100644 Editor/GuruManager/Config.meta create mode 100644 Editor/GuruManager/Config/EditorGuruServiceIO.cs create mode 100644 Editor/GuruManager/Config/EditorGuruServiceIO.cs.meta create mode 100644 Editor/GuruManager/Files.meta create mode 100644 Editor/GuruManager/Files/AndroidManifest.txt create mode 100644 Editor/GuruManager/Files/AndroidManifest.txt.meta create mode 100644 Editor/GuruManager/Files/gradleTemplate.txt create mode 100644 Editor/GuruManager/Files/gradleTemplate.txt.meta create mode 100644 Editor/GuruManager/Files/launcherTemplate.txt create mode 100644 Editor/GuruManager/Files/launcherTemplate.txt.meta create mode 100644 Editor/GuruManager/Files/mainTemplate.txt create mode 100644 Editor/GuruManager/Files/mainTemplate.txt.meta create mode 100644 Editor/GuruManager/Helper.meta create mode 100644 Editor/GuruManager/Helper/AndroidManifestMod.cs create mode 100644 Editor/GuruManager/Helper/AndroidManifestMod.cs.meta create mode 100644 Editor/GuruManager/Helper/AndroidProjectMod.cs create mode 100644 Editor/GuruManager/Helper/AndroidProjectMod.cs.meta create mode 100644 Editor/GuruManager/Helper/GuruEditorHelper.cs create mode 100644 Editor/GuruManager/Helper/GuruEditorHelper.cs.meta create mode 100644 Editor/GuruManager/Helper/GuruSDKBooster.cs create mode 100644 Editor/GuruManager/Helper/GuruSDKBooster.cs.meta create mode 100644 Editor/GuruManager/Helper/GuruSDKMenuItems.cs create mode 100644 Editor/GuruManager/Helper/GuruSDKMenuItems.cs.meta create mode 100644 Editor/GuruManager/Manager.meta create mode 100644 Editor/GuruManager/Manager/GuruSDKManager.cs create mode 100644 Editor/GuruManager/Manager/GuruSDKManager.cs.meta create mode 100644 Editor/GuruSDK.Editor.asmdef create mode 100644 Editor/GuruSDK.Editor.asmdef.meta create mode 100644 Runtime.meta create mode 100644 Runtime/Code.meta create mode 100644 Runtime/Code/Config.meta create mode 100644 Runtime/Code/Core.meta create mode 100644 Runtime/Code/Core/GuruSDK.Ads.cs create mode 100644 Runtime/Code/Core/GuruSDK.Ads.cs.meta create mode 100644 Runtime/Code/Core/GuruSDK.Analytics.cs create mode 100644 Runtime/Code/Core/GuruSDK.Analytics.cs.meta create mode 100644 Runtime/Code/Core/GuruSDK.Callback.cs create mode 100644 Runtime/Code/Core/GuruSDK.Callback.cs.meta create mode 100644 Runtime/Code/Core/GuruSDK.IAP.cs create mode 100644 Runtime/Code/Core/GuruSDK.IAP.cs.meta create mode 100644 Runtime/Code/Core/GuruSDK.cs create mode 100644 Runtime/Code/Core/GuruSDK.cs.meta create mode 100644 Runtime/Code/Core/GuruSDKInitConfig.cs create mode 100644 Runtime/Code/Core/GuruSDKInitConfig.cs.meta create mode 100644 Runtime/Code/Core/GuruServiceConfig.cs create mode 100644 Runtime/Code/Core/GuruServiceConfig.cs.meta create mode 100644 Runtime/Code/IAP.meta create mode 100644 Runtime/Code/IAP/GuruIAP.cs create mode 100644 Runtime/Code/IAP/GuruIAP.cs.meta create mode 100644 Runtime/Code/Model.meta create mode 100644 Runtime/Code/Model/BindableProperty.cs create mode 100644 Runtime/Code/Model/BindableProperty.cs.meta create mode 100644 Runtime/Code/Model/GuruSDKModel.cs create mode 100644 Runtime/Code/Model/GuruSDKModel.cs.meta create mode 100644 Runtime/GuruSDK.asmdef create mode 100644 Runtime/GuruSDK.asmdef.meta create mode 100644 Runtime/Prefab.meta create mode 100644 link.xml create mode 100644 link.xml.meta create mode 100644 package.json create mode 100644 package.json.meta diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5509140 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.DS_Store diff --git a/Editor.meta b/Editor.meta new file mode 100644 index 0000000..f40e72e --- /dev/null +++ b/Editor.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9bb2904375c2a46eb90e2a3cace489a0 +timeCreated: 1702610996 \ No newline at end of file diff --git a/Editor/GuruManager.meta b/Editor/GuruManager.meta new file mode 100644 index 0000000..4ab819c --- /dev/null +++ b/Editor/GuruManager.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: df5ee84bbb0c0495eb6f89444802ffd9 +timeCreated: 1703231056 \ No newline at end of file diff --git a/Editor/GuruManager/Config.meta b/Editor/GuruManager/Config.meta new file mode 100644 index 0000000..f873ec9 --- /dev/null +++ b/Editor/GuruManager/Config.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 44aa37ed74dd4407a9d04a07ccf97247 +timeCreated: 1702611095 \ No newline at end of file diff --git a/Editor/GuruManager/Config/EditorGuruServiceIO.cs b/Editor/GuruManager/Config/EditorGuruServiceIO.cs new file mode 100644 index 0000000..c079790 --- /dev/null +++ b/Editor/GuruManager/Config/EditorGuruServiceIO.cs @@ -0,0 +1,93 @@ +using UnityEngine; +using Guru; +using NUnit.Framework; + +namespace Guru.Editor +{ + using System.IO; + using UnityEditor; + using Guru.LitJson; + + public class EditorGuruServiceIO + { + private static readonly string DefaultFileName = "guru-service"; + + private static string DefaultFilePath = + Path.GetFullPath(Path.Combine(Application.dataPath, $"{DefaultFileName}.json")); + + private static string _selectedFilePath = ""; + + /// + /// 加载配置 + /// + /// + public static GuruServiceConfig LoadConfig() + { + var a = AssetDatabase.FindAssets($"*{DefaultFileName}* t:TextAsset"); + if (a == null || a.Length == 0) + { + Debug.Log($"--- Can't ind guru-services file"); + } + else + { + var p = AssetDatabase.GUIDToAssetPath(a[0]); + var fp = Path.GetFullPath(p); + if (File.Exists(fp)) _selectedFilePath = fp; + var t = AssetDatabase.LoadAssetAtPath(p); + // Debug.Log($"--- find services file:{p} \n{t.text}"); + return JsonMapper.ToObject(t.text); + } + return null; + } + + /// + /// 保存配置 + /// + /// + internal static void SaveConfig(GuruServiceConfig config = null) + { + if (config == null) + { + config = new GuruServiceConfig(); + } + + var jw = new JsonWriter() + { + PrettyPrint = true, + }; + JsonMapper.ToJson(config, jw); + + var json = jw.ToString(); + + if (string.IsNullOrEmpty(_selectedFilePath)) _selectedFilePath = DefaultFilePath; + File.WriteAllText(_selectedFilePath, json); + Debug.Log($"Save config to {_selectedFilePath}"); + } + + /// + /// 创建空配置 + /// + /// + internal static GuruServiceConfig CreateEmpty() + { + var cfg = new GuruServiceConfig(); + cfg.version = GuruSDK.Version; + cfg.app_settings = new GuruAppSettings(); + cfg.ad_settings = new GuruAdSettings(); + cfg.adjust_settings = new GuruAdjustSettings(); + cfg.fb_settings = new GuruFbSettings(); + return cfg; + } + + + [Test] + public static void Test_SaveConfig() + { + var cfg = CreateEmpty(); + SaveConfig(cfg); + } + + + + } +} \ No newline at end of file diff --git a/Editor/GuruManager/Config/EditorGuruServiceIO.cs.meta b/Editor/GuruManager/Config/EditorGuruServiceIO.cs.meta new file mode 100644 index 0000000..dd81da5 --- /dev/null +++ b/Editor/GuruManager/Config/EditorGuruServiceIO.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 043619bc8571240f6b8926c2ccffbd29 +timeCreated: 1702877769 \ No newline at end of file diff --git a/Editor/GuruManager/Files.meta b/Editor/GuruManager/Files.meta new file mode 100644 index 0000000..cce3ef9 --- /dev/null +++ b/Editor/GuruManager/Files.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: eec1c72fa3d0c493b9b30091a81043ee +timeCreated: 1703413024 \ No newline at end of file diff --git a/Editor/GuruManager/Files/AndroidManifest.txt b/Editor/GuruManager/Files/AndroidManifest.txt new file mode 100644 index 0000000..a40a356 --- /dev/null +++ b/Editor/GuruManager/Files/AndroidManifest.txt @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Editor/GuruManager/Files/AndroidManifest.txt.meta b/Editor/GuruManager/Files/AndroidManifest.txt.meta new file mode 100644 index 0000000..dbdc0d5 --- /dev/null +++ b/Editor/GuruManager/Files/AndroidManifest.txt.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ad463c22214a24eecba0c3d3428cd2bc +timeCreated: 1703413179 \ No newline at end of file diff --git a/Editor/GuruManager/Files/gradleTemplate.txt b/Editor/GuruManager/Files/gradleTemplate.txt new file mode 100644 index 0000000..abf3dec --- /dev/null +++ b/Editor/GuruManager/Files/gradleTemplate.txt @@ -0,0 +1,9 @@ +org.gradle.jvmargs=-Xmx**JVM_HEAP_SIZE**M +org.gradle.parallel=true +android.enableR8=**MINIFY_WITH_R_EIGHT** +unityStreamingAssets=**STREAMING_ASSETS** +# Android Resolver Properties Start +android.useAndroidX=true +android.enableJetifier=true +# Android Resolver Properties End +**ADDITIONAL_PROPERTIES** diff --git a/Editor/GuruManager/Files/gradleTemplate.txt.meta b/Editor/GuruManager/Files/gradleTemplate.txt.meta new file mode 100644 index 0000000..2c0e4db --- /dev/null +++ b/Editor/GuruManager/Files/gradleTemplate.txt.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 91158a71185444f2798701c44312902f +timeCreated: 1703468454 \ No newline at end of file diff --git a/Editor/GuruManager/Files/launcherTemplate.txt b/Editor/GuruManager/Files/launcherTemplate.txt new file mode 100644 index 0000000..8ec32cf --- /dev/null +++ b/Editor/GuruManager/Files/launcherTemplate.txt @@ -0,0 +1,66 @@ +apply plugin: 'com.android.application' + +dependencies { + implementation project(':unityLibrary') + } + +android { + compileSdkVersion **APIVERSION** + buildToolsVersion '**BUILDTOOLS**' + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + defaultConfig { + minSdkVersion **MINSDKVERSION** + targetSdkVersion **TARGETSDKVERSION** + applicationId '**APPLICATIONID**' + ndk { + abiFilters **ABIFILTERS** + } + versionCode **VERSIONCODE** + versionName '**VERSIONNAME**' + } + + aaptOptions { + noCompress = **BUILTIN_NOCOMPRESS** + unityStreamingAssets.tokenize(', ') + ignoreAssetsPattern = "!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~" + }**SIGN** + + lintOptions { + abortOnError false + checkReleaseBuilds false + } + + buildTypes { + debug { + minifyEnabled **MINIFY_DEBUG** + proguardFiles getDefaultProguardFile('proguard-android.txt')**SIGNCONFIG** + jniDebuggable true + } + release { + minifyEnabled **MINIFY_RELEASE** + proguardFiles getDefaultProguardFile('proguard-android.txt')**SIGNCONFIG** + } + } + + packagingOptions { + exclude("META-INF/*.kotlin_module") + } + + **PLAY_ASSET_PACKS****SPLITS** +**BUILT_APK_LOCATION** + bundle { + language { + enableSplit = false + } + density { + enableSplit = false + } + abi { + enableSplit = true + } + } +}**SPLITS_VERSION_CODE****LAUNCHER_SOURCE_BUILD_SETUP** diff --git a/Editor/GuruManager/Files/launcherTemplate.txt.meta b/Editor/GuruManager/Files/launcherTemplate.txt.meta new file mode 100644 index 0000000..e092817 --- /dev/null +++ b/Editor/GuruManager/Files/launcherTemplate.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5ca7eb01ab20749d7b9254c3a4825e31 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/GuruManager/Files/mainTemplate.txt b/Editor/GuruManager/Files/mainTemplate.txt new file mode 100644 index 0000000..e69de29 diff --git a/Editor/GuruManager/Files/mainTemplate.txt.meta b/Editor/GuruManager/Files/mainTemplate.txt.meta new file mode 100644 index 0000000..4a37cf8 --- /dev/null +++ b/Editor/GuruManager/Files/mainTemplate.txt.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6cf3317fddf61454181264b523a2804e +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/GuruManager/Helper.meta b/Editor/GuruManager/Helper.meta new file mode 100644 index 0000000..540efaa --- /dev/null +++ b/Editor/GuruManager/Helper.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f9253ec9aa37d4fd28af570d9427c00b +timeCreated: 1702629767 \ No newline at end of file diff --git a/Editor/GuruManager/Helper/AndroidManifestMod.cs b/Editor/GuruManager/Helper/AndroidManifestMod.cs new file mode 100644 index 0000000..090fe98 --- /dev/null +++ b/Editor/GuruManager/Helper/AndroidManifestMod.cs @@ -0,0 +1,113 @@ +using System.Collections; +using Unity.EditorCoroutines.Editor; + +namespace Guru.Editor +{ + using NUnit.Framework; + using UnityEditor; + using UnityEngine; + using System; + using System.IO; + using System.Xml; + + public static class AndroidManifestMod + { + private const string TargetPath = "Plugins/Android/AndroidManifest.xml"; + private const string ValOptimizeInitialization = "com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION"; + private const string ValOptimizeAdLoading = "com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING"; + + private static string TargetFullPath = Path.Combine(Application.dataPath, TargetPath); + + public static bool IsManifestExist() => File.Exists(TargetFullPath); + + public static void Apply() + { + if (!IsManifestExist()) + { + CopyManifest(); + return; + } + + var doc = new XmlDocument(); + doc.Load(TargetFullPath); + + var rootNode = doc.SelectSingleNode("manifest/application"); + int item1 = 0; + int item2 = 0; + + XmlNodeList metadatas = rootNode.SelectNodes("meta-data"); + if (metadatas != null && metadatas.Count > 0) + { + bool isDirty = false; + + foreach (XmlElement e in metadatas) + { + if (e != null) + { + if (e.HasAttribute("android:name")) + { + if (e.Attributes["android:name"].Value == ValOptimizeInitialization) item1 = 1; + if (e.Attributes["android:name"].Value == ValOptimizeAdLoading) item2 = 1; + } + } + } + } + + string androidSP = "http://schemas.android.com/apk/res/android"; + + if (item1 == 0) + { + var e = doc.CreateElement("meta-data"); + e.SetAttribute("name",androidSP, ValOptimizeInitialization); + e.SetAttribute("value",androidSP, "true"); + rootNode.AppendChild(e); + } + + if (item2 == 0) + { + var e = doc.CreateElement("meta-data"); + e.SetAttribute("name",androidSP,ValOptimizeAdLoading); + e.SetAttribute("value",androidSP, "true"); + rootNode.AppendChild(e); + } + + var rootE = doc.SelectSingleNode("manifest") as XmlElement; + if (rootE != null) + { + rootE.Attributes["package"].Value = PlayerSettings.applicationIdentifier; // 写入包名 + } + + doc.Save(TargetFullPath); + } + + private static void CopyManifest() + { + if (File.Exists(TargetFullPath)) return; + + var path = GuruEditorHelper.GetFilePath($"{nameof(AndroidManifestMod)}.cs t:Script"); + if (!string.IsNullOrEmpty(path)) + { + var files = Path.GetFullPath($"{path}/../Files"); + var from = $"{files}/AndroidManifest.txt"; + if (File.Exists(from)) + { + File.Copy(from, TargetFullPath); + } + } + } + + + + + #region Testing + + [Test] + public static void Test_Injection() + { + Apply(); + } + + #endregion + + } +} \ No newline at end of file diff --git a/Editor/GuruManager/Helper/AndroidManifestMod.cs.meta b/Editor/GuruManager/Helper/AndroidManifestMod.cs.meta new file mode 100644 index 0000000..6a8d2d0 --- /dev/null +++ b/Editor/GuruManager/Helper/AndroidManifestMod.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9ce9c7008577c4c04b10eb96a3244867 +timeCreated: 1703409620 \ No newline at end of file diff --git a/Editor/GuruManager/Helper/AndroidProjectMod.cs b/Editor/GuruManager/Helper/AndroidProjectMod.cs new file mode 100644 index 0000000..3301cb3 --- /dev/null +++ b/Editor/GuruManager/Helper/AndroidProjectMod.cs @@ -0,0 +1,117 @@ +using System.Linq; + +namespace Guru.Editor +{ + using UnityEditor; + using UnityEngine; + using System; + using System.IO; + public class AndroidProjectMod + { + private static readonly int TargetSDKVersion = 33; + + private static readonly string LauncherName = "launcherTemplate"; + private static string LauncherFullPath = Path.Combine(Application.dataPath, $"Plugins/Android/{LauncherName}.gradle"); + + private static readonly string MainName = "mainTemplate"; + private static string MainFullPath = Path.Combine(Application.dataPath, $"Plugins/Android/{MainName}.gradle"); + + private static readonly string PropertiesName = "gradleTemplate"; + private static string PropertiesFullPath = Path.Combine(Application.dataPath, $"Plugins/Android/{PropertiesName}.properties"); + + public static void Apply() + { + FixLauncher(); + FixMain(); + FixProperties(); + CheckTargetSDKVersion(); + } + + + private static void FixLauncher() + { + if (!File.Exists(LauncherFullPath)) + { + CopyFile($"{LauncherName}.txt", LauncherFullPath); + Debug.Log($"[MOD] --- Copy file to: {LauncherFullPath}"); + return; + } + + var ptn1 = "**PACKAGING_OPTIONS**"; + var ptn2 = "abortOnError false"; + var lines = File.ReadAllLines(LauncherFullPath); + + string line = ""; + for (int i = 0; i < lines.Length; i++) + { + line = lines[i]; + if (line.Contains(ptn1)) + { + lines[i] = line.Replace(ptn1, "\n\n\tpackagingOptions {\n\t\texclude(\"META-INF/*.kotlin_module\")\n\t}\n\n"); + } + + if (line.Contains(ptn2)) + { + if (lines[i + 1].Contains("}")) + { + lines[i + 1] = lines[i + 1].Replace("}", "\tcheckReleaseBuilds false\n\t}"); + } + } + } + Debug.Log($"[MOD] --- Fix file at: {LauncherFullPath}"); + File.WriteAllLines(LauncherFullPath, lines); + + } + private static void FixMain() + { + if (!File.Exists(MainFullPath)) + { + Debug.Log($"[MOD] --- Copy file to: {MainFullPath}"); + CopyFile($"{MainName}.txt", MainFullPath); + } + } + private static void FixProperties() + { + if (!File.Exists(PropertiesFullPath)) + { + Debug.Log($"[MOD] --- Copy file to: {PropertiesFullPath}"); + CopyFile($"{PropertiesName}.txt", PropertiesFullPath); + } + } + + private static void CheckTargetSDKVersion() + { + var ver = (int) PlayerSettings.Android.targetSdkVersion; + if (ver < TargetSDKVersion) + { + Debug.Log($"[MOD] --- Fix target sdk version -> {TargetSDKVersion}"); + PlayerSettings.Android.targetSdkVersion = (AndroidSdkVersions)TargetSDKVersion; + } + } + + #region File IO + + private static string GetMoveFilePath(string fileName) + { + var path = GuruEditorHelper.GetFilePath($"{nameof(AndroidProjectMod)}.cs t:Script"); + var files = Path.GetFullPath($"{path}/../Files"); + return $"{files}/{fileName}"; + } + private static void CopyFile(string fileName, string toPath) + { + var from = GetMoveFilePath(fileName); + if (!string.IsNullOrEmpty(from)) + { + if (File.Exists(from)) + { + File.Copy(from, toPath); + } + } + } + + #endregion + + + + } +} \ No newline at end of file diff --git a/Editor/GuruManager/Helper/AndroidProjectMod.cs.meta b/Editor/GuruManager/Helper/AndroidProjectMod.cs.meta new file mode 100644 index 0000000..a8dc436 --- /dev/null +++ b/Editor/GuruManager/Helper/AndroidProjectMod.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3e096221d72bd44baa543f1629092c4a +timeCreated: 1703412483 \ No newline at end of file diff --git a/Editor/GuruManager/Helper/GuruEditorHelper.cs b/Editor/GuruManager/Helper/GuruEditorHelper.cs new file mode 100644 index 0000000..0a2d9cb --- /dev/null +++ b/Editor/GuruManager/Helper/GuruEditorHelper.cs @@ -0,0 +1,17 @@ +namespace Guru.Editor +{ + using UnityEditor; + public class GuruEditorHelper + { + public static string GetFilePath(string filter) + { + var guids = AssetDatabase.FindAssets(filter); + if (guids != null && guids.Length > 0) + { + var path = AssetDatabase.GUIDToAssetPath(guids[0]); + return path; + } + return ""; + } + } +} \ No newline at end of file diff --git a/Editor/GuruManager/Helper/GuruEditorHelper.cs.meta b/Editor/GuruManager/Helper/GuruEditorHelper.cs.meta new file mode 100644 index 0000000..88b6553 --- /dev/null +++ b/Editor/GuruManager/Helper/GuruEditorHelper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d05ef4ba47b6e4cb7bf95cb073af4915 +timeCreated: 1703413245 \ No newline at end of file diff --git a/Editor/GuruManager/Helper/GuruSDKBooster.cs b/Editor/GuruManager/Helper/GuruSDKBooster.cs new file mode 100644 index 0000000..1f8d63a --- /dev/null +++ b/Editor/GuruManager/Helper/GuruSDKBooster.cs @@ -0,0 +1,69 @@ + + +namespace Guru.Editor +{ + using UnityEditor; + using System.IO; + using UnityEngine; + using System.Collections; + using Guru.Editor; + using Unity.EditorCoroutines.Editor; + + public class GuruSDKBooster + { + + // [MenuItem("Test/API/Test CR")] + static void TestCR() + { + // EditorHelper.StartCoroutine(OnTestRun()); + EditorCoroutineUtility.StartCoroutineOwnerless(OnTestRun()); + } + + static IEnumerator OnTestRun() + { + int i = 0; + while (i < 5) + { + Debug.Log($"--- ticket: {i}"); + i++; + yield return new EditorWaitForSeconds(1); + } + Debug.Log($"------- runner end -------"); + } + } + + + + // [InitializeOnLoad] + internal class BoostOnLoad + { + static BoostOnLoad() + { + var config = EditorGuruServiceIO.LoadConfig(); + if (null != config) + { + Debug.Log("found guru-services file on disk"); + // TODO: + } + else + { + Debug.Log("Can't find guru-services.json on load..."); + // GuruSDKManager.Open(); + EditorGuruServiceIO.LoadConfig(); + } + + } + + + + + } + + + + + + + + +} \ No newline at end of file diff --git a/Editor/GuruManager/Helper/GuruSDKBooster.cs.meta b/Editor/GuruManager/Helper/GuruSDKBooster.cs.meta new file mode 100644 index 0000000..bb6fb62 --- /dev/null +++ b/Editor/GuruManager/Helper/GuruSDKBooster.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4012c7bdb57bc4bfbb3b313a86ea3901 +timeCreated: 1702627784 \ No newline at end of file diff --git a/Editor/GuruManager/Helper/GuruSDKMenuItems.cs b/Editor/GuruManager/Helper/GuruSDKMenuItems.cs new file mode 100644 index 0000000..b0984fd --- /dev/null +++ b/Editor/GuruManager/Helper/GuruSDKMenuItems.cs @@ -0,0 +1,16 @@ +using Guru.Editor; +using UnityEditor; + +namespace Guru +{ + public class GuruSDKMenuItems + { + + [MenuItem("Guru/Guru SDK")] + private static void ShowGuruManager() + { + GuruSDKManager.Open(); + } + + } +} \ No newline at end of file diff --git a/Editor/GuruManager/Helper/GuruSDKMenuItems.cs.meta b/Editor/GuruManager/Helper/GuruSDKMenuItems.cs.meta new file mode 100644 index 0000000..8b82b83 --- /dev/null +++ b/Editor/GuruManager/Helper/GuruSDKMenuItems.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7e6a90bd7ba03491d87943c2c1fcf17e +timeCreated: 1702861089 \ No newline at end of file diff --git a/Editor/GuruManager/Manager.meta b/Editor/GuruManager/Manager.meta new file mode 100644 index 0000000..8c158ab --- /dev/null +++ b/Editor/GuruManager/Manager.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 627835e82d65043cf8996da4a8377fa7 +timeCreated: 1703231041 \ No newline at end of file diff --git a/Editor/GuruManager/Manager/GuruSDKManager.cs b/Editor/GuruManager/Manager/GuruSDKManager.cs new file mode 100644 index 0000000..3b0dfe8 --- /dev/null +++ b/Editor/GuruManager/Manager/GuruSDKManager.cs @@ -0,0 +1,887 @@ + + +using System.Collections.Generic; +using System.IO; +using Facebook.Unity.Settings; +using UnityEditor.Compilation; + +namespace Guru.Editor +{ + using System; + using UnityEditor; + using UnityEngine; + using Guru; + using AppLovinMax.Scripts.IntegrationManager.Editor; + + + public class GuruSDKManager: EditorWindow + { + private const string GURU_SETTINGS_PATH = "Assets/Guru/Resources/GuruSettings.asset"; + private const string APPLOVIN_SETTINGS_PATH = "Assets/Guru/Resources/AppLovinSettings.asset"; + private const string FACEBOOK_SETTINGS_PATH = "Assets/FacebookSDK/SDK/Resources/FacebookSettings.asset"; + private const string ANDROID_KEYSTORE_PATH = "Packages/com.guru.unity.sdk.core/Keystore/guru.jks"; + private const string KeyMaxAutoUpdateEnabled = "com.applovin.auto_update_enabled"; + + + private static GuruSDKManager _instance; + public static GuruSDKManager Instance { + get + { + if (_instance == null) + { + _instance = GetWindow(); + } + return _instance; + } + } + + private GuruServiceConfig _serviceConfig; + private static GUIStyle _itemTitleStyle; + private static GUIStyle StyleItemTitle + { + get + { + if (_itemTitleStyle == null) + { + _itemTitleStyle = new GUIStyle("BOX") + { + fontSize = 12, + fontStyle = FontStyle.Bold, + stretchWidth = true, + alignment = TextAnchor.MiddleLeft, + padding = new RectOffset(4, 4, 4, 4), + }; + } + return _itemTitleStyle; + } + } + + private bool _hasCheckingCompleted = false; + + + public GuruSDKManager() + { + this.minSize = new Vector2(480, 640); + } + + + public static void Open() + { + Instance.Show(); + } + + + private void OnEnable() + { + titleContent = new GUIContent("Guru SDK Manager"); + _serviceConfig = EditorGuruServiceIO.LoadConfig(); + if (_serviceConfig != null) + { + Debug.Log($"[Guru] Load success."); + CheckServicesCompletion(); + } + else + { + Debug.Log($"[Guru] file not found..."); + } + } + + + #region Service Checker + + private const string MARK_FAIL = "#FAIL"; + private const string MARK_INDENT = " "; + private List _completionCheckResult; + private int _serviceCriticalFail = 0; + private int _serviceNormalFail = 0; + + /// + /// 检查服务文件的配置完整性 + /// + private void CheckServicesCompletion() + { + _serviceCriticalFail = 0; + _serviceNormalFail = 0; + + _completionCheckResult = new List(40); + string mk_yes = " ( \u2714 ) "; + string mk_no = " ( \u2718 ) "; + string mk_star = " ( \u2605 ) "; + string check_passed = $"{MARK_INDENT}{mk_yes} All items passed!"; + if (_serviceConfig == null) + { + AddResultLine($"{mk_yes} guru-services is missing", false); + AddResultLine($"Please contact Guru tech support to get help.", false); + _serviceCriticalFail++; + } + else + { + bool passed = true; + AddResultLine($"{mk_star} exists!"); + AddResultLine($"--------------------------------"); + + //-------- APP Settings -------- + passed = true; + AddResultLine($"[ App ]"); + if (_serviceConfig.app_settings == null) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} settings is missing!", false); + _serviceCriticalFail++; + } + else + { + if (_serviceConfig.app_settings.app_id.IsNullOrEmpty()) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} AppID is missing!", false); + _serviceCriticalFail++; + } + if (_serviceConfig.app_settings.bundle_id.IsNullOrEmpty()) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} BundleID is missing!", false); + _serviceCriticalFail++; + } + if (_serviceConfig.app_settings.product_name.IsNullOrEmpty()) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Product Name is missing!", false); + _serviceCriticalFail++; + } + if (_serviceConfig.app_settings.support_email.IsNullOrEmpty()) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Support Email is missing!", false); + _serviceNormalFail++; + } + } + + if (passed) AddResultLine(check_passed); + + //-------- ADS Settings -------- + passed = true; + AddResultLine($"[ Ads ]"); + if (_serviceConfig.ad_settings == null) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} settings is missing!", false); + _serviceCriticalFail++; + } + else + { + if (_serviceConfig.ad_settings.sdk_key.IsNullOrEmpty()) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} SDK Key is missing!", false); + _serviceCriticalFail++; + } + if (!IsArrayNotEmpty(_serviceConfig.ad_settings.admob_app_id)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Admob ID is missing!", false); + _serviceCriticalFail++; + } + if (!IsArrayNotEmpty(_serviceConfig.ad_settings.max_ids_android)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} AppLovin Android IDs is missing!", false); + _serviceCriticalFail++; + } + if (!IsArrayNotEmpty(_serviceConfig.ad_settings.max_ids_ios)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} AppLovin iOS IDs is missing!", false); + _serviceCriticalFail++; + } + if (!IsArrayNotEmpty(_serviceConfig.ad_settings.amazon_ids_android)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Amazon Android IDs is missing!", false); + _serviceCriticalFail++; + } + if (!IsArrayNotEmpty(_serviceConfig.ad_settings.amazon_ids_ios)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Amazon iOS IDs is missing!", false); + _serviceCriticalFail++; + } + if (!IsArrayNotEmpty(_serviceConfig.ad_settings.pubmatic_ids_android)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Pubmatic Android IDs is missing!", false); + _serviceCriticalFail++; + } + if (!IsArrayNotEmpty(_serviceConfig.ad_settings.pubmatic_ids_ios)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Pubmatic iOS IDs is missing!", false); + _serviceCriticalFail++; + } + if (!IsArrayNotEmpty(_serviceConfig.ad_settings.moloco_ids_android)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Moloco Android Test IDs is missing!", false); + _serviceNormalFail++; + } + if (!IsArrayNotEmpty(_serviceConfig.ad_settings.moloco_ids_ios)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Moloco iOS Test IDs is missing!", false); + _serviceNormalFail++; + } + } + if (passed) AddResultLine(check_passed); + + //-------- Channels Settings -------- + passed = true; + AddResultLine($"[ Channels ]"); + if (_serviceConfig.fb_settings == null) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Facebook settings is missing!", false); + _serviceCriticalFail++; + } + else + { + if (_serviceConfig.fb_settings.app_id.IsNullOrEmpty()) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Facebook AppID is missing!", false); + _serviceCriticalFail++; + } + if (_serviceConfig.fb_settings.client_token.IsNullOrEmpty()) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Facebook Client Token is missing!", false); + _serviceCriticalFail++; + } + } + + if (_serviceConfig.adjust_settings == null) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Adjust settings is missing!", false); + _serviceCriticalFail++; + } + else + { + if(!IsArrayNotEmpty(_serviceConfig.adjust_settings.app_token)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Adjust AppToken is missing!", false); + _serviceCriticalFail++; + } + + if (!IsArrayNotEmpty(_serviceConfig.adjust_settings.events)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Adjust Events is missing!", false); + _serviceCriticalFail++; + } + } + if (passed) AddResultLine(check_passed); + + //-------- IAP -------- + passed = true; + AddResultLine($"[ IAP ]"); + if (!IsArrayNotEmpty(_serviceConfig.products)) + { + passed = false; + AddResultLine($"{MARK_INDENT}{mk_no} Product list is missing!", false); + _serviceNormalFail++; + } + if (passed) AddResultLine(check_passed); + } + + } + + private void AddResultLine(string msg, bool passed = true) + { + if (_completionCheckResult == null) + { + _completionCheckResult = new List(40); + } + string mk = passed? "" : MARK_FAIL; + _completionCheckResult.Add($"{msg}{mk}"); + } + + private void GUI_ServiceCheckResult() + { + if (_completionCheckResult != null) + { + Color green = new Color(0.7f, 1, 0); + Color red = new Color(1, 0.2f, 0); + Color c; + string line = ""; + for (int i = 0; i < _completionCheckResult.Count; i++) + { + c = green; + line = _completionCheckResult[i]; + if (line.EndsWith(MARK_FAIL)) + { + line = line.Replace(MARK_FAIL, ""); + c = red; + } + GUI_Color(c, () => + { + EditorGUILayout.LabelField(line); + GUILayout.Space(2); + }); + + } + } + + } + + + #endregion + + + + #region GUI + + void OnGUI() + { + // TITLE + GUI_WindowTitle(); + + // CONTENT + if (_serviceConfig == null) + { + GUI_OnConfigDisabled(); + } + else + { + GUI_OnConfigEnabled(); + } + + } + + private void GUI_WindowTitle() + { + GUILayout.Space(4); + + var s = new GUIStyle("BOX") + { + fontSize = 36, + fontStyle = FontStyle.Bold, + alignment = TextAnchor.MiddleCenter, + stretchWidth = true, + stretchHeight = true, + fixedHeight = 60, + }; + + + EditorGUILayout.LabelField("Guru SDK",s); + s.fontSize = 13; + s.fixedHeight = 20; + EditorGUILayout.LabelField($"Version {GuruSDK.Version}", s); + + GUILayout.Space(4); + } + + + /// + /// 配置不可用 + /// + private void GUI_OnConfigDisabled() + { + GUI_Color(new Color(1,0.2f, 0), () => + { + EditorGUILayout.LabelField("<>", StyleItemTitle); + }); + } + + + /// + /// 配置可用 + /// + private void GUI_OnConfigEnabled() + { + var box = new GUIStyle("BOX"); + float btnH = 40; + + //------------ check allsettings ------------- + EditorGUILayout.LabelField("[ Guru Service ]", StyleItemTitle); + GUILayout.Space(2); + GUI_ServiceCheckResult(); + GUILayout.Space(16); + + if (_serviceCriticalFail > 0) + { + // 严重错误过多 + } + else + { + GUI_Button("IMPORT ALL SETTINGS", () => + { + CheckAllComponents(); + }, null, GUILayout.Height(btnH)); + } + + GUILayout.Space(4); + + } + + + #endregion + + + #region Check Components + + private string logBuffer; + + + private void CheckAllComponents() + { + string barTitle = "Setup All Components"; + EditorUtility.DisplayCancelableProgressBar(barTitle, "Start collect all components", 0); + Debug.Log("--- Setup All Components ---"); + ImportGuruSettings(); + EditorUtility.DisplayCancelableProgressBar(barTitle, "GuruSettings is done", 0.2f); + ImportAppLovinSettings(); + EditorUtility.DisplayCancelableProgressBar(barTitle, "AppLovinSettings is done", 0.4f); + ImportFacebookSettings(); + EditorUtility.DisplayCancelableProgressBar(barTitle, "FacebookSettings is done", 0.6f); + ApplyMods(); + EditorUtility.DisplayCancelableProgressBar(barTitle, "All Mods is done", 0.8f); + + AssetDatabase.SaveAssets(); + + CompilationPipeline.RequestScriptCompilation(); + CompilationPipeline.compilationFinished += o => + { + EditorUtility.ClearProgressBar(); + AssetDatabase.Refresh(); + + EditorUtility.DisplayDialog("Importing Guru Services", "All the settings importing success!", "OK"); + }; + } + + //------------------------- GuruSettings -------------------------------- + private void ImportGuruSettings() + { + GuruSettings settings = null; + if (IsAssetExists(nameof(GuruSettings), GURU_SETTINGS_PATH)) + { + settings = AssetDatabase.LoadAssetAtPath(GURU_SETTINGS_PATH); + } + else + { + settings = CreateInstance(); + AssetDatabase.CreateAsset(settings, GURU_SETTINGS_PATH); + } + settings.CompanyName = "Guru"; + settings.ProductName = _serviceConfig.app_settings.product_name; + settings.GameIdentifier = _serviceConfig.app_settings.bundle_id; + settings.PriacyUrl = _serviceConfig.app_settings.privacy_url; + settings.TermsUrl = _serviceConfig.app_settings.terms_url; + settings.SupportEmail = _serviceConfig.app_settings.support_email; + settings.AndroidStoreUrl = _serviceConfig.app_settings.android_store; + settings.IOSStoreUrl = _serviceConfig.app_settings.ios_store; + + SerializedObject so = new SerializedObject(settings); + SerializedProperty n; + SerializedObject nn; + SerializedProperty p; + string[] arr; + + n = so.FindProperty("IPMSetting"); + if (null != n) + { + p = n.serializedObject.FindProperty("IPMSetting.appID"); + p.stringValue = _serviceConfig.app_settings.app_id; + + p = n.serializedObject.FindProperty("IPMSetting.tokenValidTime"); + p.intValue = _serviceConfig.app_settings.token_vaild_time; + } + + //---------- AMAZON ----------------------- + n = so.FindProperty("AmazonSetting"); + if (null != n) + { + p = n.serializedObject.FindProperty("AmazonSetting.Enable"); + p.boolValue = true; + + arr = _serviceConfig.ad_settings.amazon_ids_android; + if (IsArrayHasLength(arr, 4)) + { + p = n.serializedObject.FindProperty("AmazonSetting.Android.appID"); + p.stringValue = arr[0]; + p = n.serializedObject.FindProperty("AmazonSetting.Android.bannerSlotID"); + p.stringValue = arr[1]; + p = n.serializedObject.FindProperty("AmazonSetting.Android.interSlotID"); + p.stringValue = arr[2]; + p = n.serializedObject.FindProperty("AmazonSetting.Android.rewardSlotID"); + p.stringValue = arr[3]; + } + + arr = _serviceConfig.ad_settings.amazon_ids_ios; + if (IsArrayHasLength(arr, 4)) + { + p = n.serializedObject.FindProperty("AmazonSetting.iOS.appID"); + p.stringValue = arr[0]; + p = n.serializedObject.FindProperty("AmazonSetting.iOS.bannerSlotID"); + p.stringValue = arr[1]; + p = n.serializedObject.FindProperty("AmazonSetting.iOS.interSlotID"); + p.stringValue = arr[2]; + p = n.serializedObject.FindProperty("AmazonSetting.iOS.rewardSlotID"); + p.stringValue = arr[3]; + } + } + + //---------- PUBMATIC ----------------------- + n = so.FindProperty("PubmaticSetting"); + if (null != n) + { + p = n.serializedObject.FindProperty("PubmaticSetting.Enable"); + p.boolValue = true; + + arr = _serviceConfig.ad_settings.pubmatic_ids_android; + if (IsArrayHasLength(arr, 4)) + { + p = n.serializedObject.FindProperty("PubmaticSetting.Android.storeUrl"); + p.stringValue = arr[0]; + p = n.serializedObject.FindProperty("PubmaticSetting.Android.bannerUnitID"); + p.stringValue = arr[1]; + p = n.serializedObject.FindProperty("PubmaticSetting.Android.interUnitID"); + p.stringValue = arr[2]; + p = n.serializedObject.FindProperty("PubmaticSetting.Android.rewardUnitID"); + p.stringValue = arr[3]; + } + + arr = _serviceConfig.ad_settings.pubmatic_ids_ios; + if (IsArrayHasLength(arr, 4)) + { + p = n.serializedObject.FindProperty("PubmaticSetting.iOS.storeUrl"); + p.stringValue = arr[0]; + p = n.serializedObject.FindProperty("PubmaticSetting.iOS.bannerUnitID"); + p.stringValue = arr[1]; + p = n.serializedObject.FindProperty("PubmaticSetting.iOS.interUnitID"); + p.stringValue = arr[2]; + p = n.serializedObject.FindProperty("PubmaticSetting.iOS.rewardUnitID"); + p.stringValue = arr[3]; + } + } + + //---------- MOLOCO ----------------------- + n = so.FindProperty("MolocoSetting"); + if (null != n) + { + p = n.serializedObject.FindProperty("MolocoSetting.Enable"); + p.boolValue = true; + + arr = _serviceConfig.ad_settings.moloco_ids_android; + if (IsArrayHasLength(arr, 3)) + { + p = n.serializedObject.FindProperty("MolocoSetting.Android.bannerTestUnitID"); + p.stringValue = arr[0]; + p = n.serializedObject.FindProperty("MolocoSetting.Android.interTestUnitID"); + p.stringValue = arr[1]; + p = n.serializedObject.FindProperty("MolocoSetting.Android.rewardTestUnitID"); + p.stringValue = arr[2]; + } + + arr = _serviceConfig.ad_settings.moloco_ids_ios; + if (IsArrayHasLength(arr, 3)) + { + p = n.serializedObject.FindProperty("MolocoSetting.iOS.bannerTestUnitID"); + p.stringValue = arr[0]; + p = n.serializedObject.FindProperty("MolocoSetting.iOS.interTestUnitID"); + p.stringValue = arr[1]; + p = n.serializedObject.FindProperty("MolocoSetting.iOS.rewardTestUnitID"); + p.stringValue = arr[2]; + } + } + + //----------- ADSettings ------------------- + n = so.FindProperty("ADSetting"); + if (null != n) + { + p = n.serializedObject.FindProperty("ADSetting.SDK_KEY"); + p.stringValue = _serviceConfig.ad_settings.sdk_key; + + arr = _serviceConfig.ad_settings.max_ids_android; + if(IsArrayHasLength(arr, 3)) + { + p = n.serializedObject.FindProperty("ADSetting.Android_Banner_ID"); + p.stringValue = arr[0]; + p = n.serializedObject.FindProperty("ADSetting.Android_Interstitial_ID"); + p.stringValue = arr[1]; + p = n.serializedObject.FindProperty("ADSetting.Android_Rewarded_ID"); + p.stringValue = arr[2]; + } + + arr = _serviceConfig.ad_settings.max_ids_ios; + if (IsArrayHasLength(arr, 3)) + { + p = n.serializedObject.FindProperty("ADSetting.IOS_Banner_ID"); + p.stringValue = arr[0]; + p = n.serializedObject.FindProperty("ADSetting.IOS_Interstitial_ID"); + p.stringValue = arr[1]; + p = n.serializedObject.FindProperty("ADSetting.IOS_Rewarded_ID"); + p.stringValue = arr[2]; + } + } + + //----------- AdjustSetting ------------------- + n = so.FindProperty("AdjustSetting"); + if (null != n + && IsArrayHasLength(_serviceConfig.adjust_settings.app_token, 2)) + { + p = n.serializedObject.FindProperty("AdjustSetting.androidAppToken"); + p.stringValue = _serviceConfig.adjust_settings.app_token[0]; + + p = n.serializedObject.FindProperty("AdjustSetting.iOSAppToken"); + p.stringValue = _serviceConfig.adjust_settings.app_token[1]; + } + + //----------- AnalyticsSetting ------------------- + n = so.FindProperty("AnalyticsSetting"); + if (null != n) + { + p = n.serializedObject.FindProperty("AnalyticsSetting.levelEndSuccessNum"); + p.intValue = _serviceConfig.app_settings.level_end_success_num; + p = n.serializedObject.FindProperty("AnalyticsSetting.enalbeFirebaseAnalytics"); + p.boolValue = _serviceConfig.app_settings.enable_firebase; + p = n.serializedObject.FindProperty("AnalyticsSetting.enalbeFacebookAnalytics"); + p.boolValue = _serviceConfig.app_settings.enable_facebook; + p = n.serializedObject.FindProperty("AnalyticsSetting.enalbeAdjustAnalytics"); + p.boolValue = _serviceConfig.app_settings.enable_adjust; + p = n.serializedObject.FindProperty("AnalyticsSetting.adjustEventList"); + if (null != p && IsArrayNotEmpty(_serviceConfig.adjust_settings.events)) + { + p.ClearArray(); + for (int i = 0; i < _serviceConfig.adjust_settings.events.Length; i++) + { + arr = _serviceConfig.adjust_settings.events[i].Split(","); + if (IsArrayHasLength(arr, 3)) + { + p.InsertArrayElementAtIndex(i); + nn = p.GetArrayElementAtIndex(i).serializedObject; + nn.FindProperty($"AnalyticsSetting.adjustEventList.Array.data[{i}].EventName").stringValue = arr[0]; + nn.FindProperty($"AnalyticsSetting.adjustEventList.Array.data[{i}].AndroidToken").stringValue = arr[1]; + nn.FindProperty($"AnalyticsSetting.adjustEventList.Array.data[{i}].IOSToken").stringValue = arr[2]; + } + } + } + } + + //---------------- Productions ------------------------ + n = so.FindProperty("Products"); + if (n != null && IsArrayNotEmpty(_serviceConfig.products)) + { + n.ClearArray(); + for (int i = 0; i < _serviceConfig.products.Length; i++) + { + arr = _serviceConfig.products[i].Split(","); + if (IsArrayHasLength(arr, 5)) + { + n.InsertArrayElementAtIndex(i); + nn = n.GetArrayElementAtIndex(i).serializedObject; + nn.FindProperty($"Products.Array.data[{i}].ProductName").stringValue = arr[0]; + nn.FindProperty($"Products.Array.data[{i}].GooglePlayProductId").stringValue = arr[1]; + nn.FindProperty($"Products.Array.data[{i}].AppStoreProductId").stringValue = arr[2]; + nn.FindProperty($"Products.Array.data[{i}].Price").doubleValue = double.Parse(arr[3]); + nn.FindProperty($"Products.Array.data[{i}].Type").enumValueIndex = int.Parse(arr[4]); + nn.FindProperty($"Products.Array.data[{i}].IsFree").boolValue = false; + nn.FindProperty($"Products.Array.data[{i}].Category").stringValue = "Store"; + } + } + } + + //------- Save SO ---------- + so.ApplyModifiedProperties(); + EditorUtility.SetDirty(settings); + AssetDatabase.SaveAssetIfDirty(settings); + } + + //------------------------- AppLovinSettings -------------------------------- + private void ImportAppLovinSettings() + { + EditorPrefs.SetBool(KeyMaxAutoUpdateEnabled, false); // 关闭Max自动升级功能 + + AppLovinSettings settings = null; + if (IsAssetExists(nameof(AppLovinSettings), APPLOVIN_SETTINGS_PATH)) + { + settings = AssetDatabase.LoadAssetAtPath(APPLOVIN_SETTINGS_PATH); + } + else + { + settings = CreateInstance(); + AssetDatabase.CreateAsset(settings, APPLOVIN_SETTINGS_PATH); + } + + settings.SetAttributionReportEndpoint = true; + settings.QualityServiceEnabled = true; + settings.SdkKey = _serviceConfig.ad_settings.sdk_key; + if (IsArrayHasLength(_serviceConfig.ad_settings.admob_app_id, 2)) + { + settings.AdMobAndroidAppId = _serviceConfig.ad_settings.admob_app_id[0]; + settings.AdMobIosAppId = _serviceConfig.ad_settings.admob_app_id[1]; + } + settings.ConsentFlowEnabled = false; + EditorUtility.SetDirty(settings); + AssetDatabase.SaveAssetIfDirty(settings); + } + + //------------------------- FacebookSettings -------------------------------- + private void ImportFacebookSettings() + { + FacebookSettings settings = null; + if (IsAssetExists(nameof(FacebookSettings), FACEBOOK_SETTINGS_PATH)) + { + settings = AssetDatabase.LoadAssetAtPath(FACEBOOK_SETTINGS_PATH); + } + else + { + settings = CreateInstance(); + AssetDatabase.CreateAsset(settings, FACEBOOK_SETTINGS_PATH); + } + + var so = new SerializedObject(settings); + SerializedProperty n; + + n = so.FindProperty("appLabels"); + if (n != null) + { + n.ClearArray(); + n.InsertArrayElementAtIndex(0); + n.GetArrayElementAtIndex(0).stringValue = _serviceConfig.app_settings.product_name; + } + + n = so.FindProperty("appIds"); + if (n != null) + { + n.ClearArray(); + n.InsertArrayElementAtIndex(0); + n.GetArrayElementAtIndex(0).stringValue = _serviceConfig.fb_settings.app_id; + } + + n = so.FindProperty("clientTokens"); + if (n != null) + { + n.ClearArray(); + n.InsertArrayElementAtIndex(0); + n.GetArrayElementAtIndex(0).stringValue = _serviceConfig.fb_settings.client_token; + } + + n = so.FindProperty("androidKeystorePath"); + n.stringValue = ANDROID_KEYSTORE_PATH; + + so.ApplyModifiedProperties(); + EditorUtility.SetDirty(settings); + AssetDatabase.SaveAssetIfDirty(settings); + } + + private void ApplyMods() + { + PlayerSettings.applicationIdentifier = _serviceConfig.app_settings.bundle_id; // 设置包名 + +#if UNITY_ANDROID + AndroidManifestMod.Apply(); + AndroidProjectMod.Apply(); +#endif + } + + + + #endregion + + #region GUI Utils + + + private void GUI_Color(Color color, Action content) + { + var c = GUI.color; + GUI.color = color; + content?.Invoke(); + GUI.color = c; + } + + + + private void GUI_Button(string label, Action content, Color color, GUIStyle style = null, params GUILayoutOption[] options) + { + GUI_Color(color, ()=> GUI_Button(label, content, style, options)); + } + private void GUI_Button(string label, Action content, GUIStyle style = null, params GUILayoutOption[] options) + { + + + + + + if (style != null) + { + if (GUILayout.Button(label,style, options)) + { + content?.Invoke(); + } + } + else + { + if (GUILayout.Button(label, options)) + { + content?.Invoke(); + } + } + + + } + + + #endregion + + #region Utils + + /// + /// 获取Assets路径 + /// + /// + /// + private static bool IsAssetExists(string typeName, string defaultPath) + { + bool result = false; + var guids = AssetDatabase.FindAssets($"t:{typeName}"); + string p = ""; + if (guids != null && guids.Length > 0) + { + for (int i = 0; i < guids.Length; i++) + { + p = AssetDatabase.GUIDToAssetPath(guids[i]); + if (File.Exists(p)) + { + if (p == defaultPath) + { + result = true; + } + else + { + File.Delete(p); + } + } + } + } + return result; + } + + private static bool IsArrayNotEmpty(Array array) + { + if (array == null) return false; + if (array.Length == 0) return false; + return true; + } + + private static bool IsArrayHasLength(Array array, int length) + { + if(!IsArrayNotEmpty(array)) return false; + return array.Length >= length; + } + + + #endregion + + } +} \ No newline at end of file diff --git a/Editor/GuruManager/Manager/GuruSDKManager.cs.meta b/Editor/GuruManager/Manager/GuruSDKManager.cs.meta new file mode 100644 index 0000000..da3e5fe --- /dev/null +++ b/Editor/GuruManager/Manager/GuruSDKManager.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0a6aed96e95b747cdbb3c19c8d01b5f1 +timeCreated: 1702786341 \ No newline at end of file diff --git a/Editor/GuruSDK.Editor.asmdef b/Editor/GuruSDK.Editor.asmdef new file mode 100644 index 0000000..0b68aad --- /dev/null +++ b/Editor/GuruSDK.Editor.asmdef @@ -0,0 +1,22 @@ +{ + "name": "GuruSDK.Editor", + "rootNamespace": "Guru.Editor", + "references": [ + "Unity.EditorCoroutines.Editor", + "GuruSDK", + "Guru.LitJson", + "Guru.Runtime", + "MaxSdk.Scripts.IntegrationManager.Editor" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Editor/GuruSDK.Editor.asmdef.meta b/Editor/GuruSDK.Editor.asmdef.meta new file mode 100644 index 0000000..41b9f4c --- /dev/null +++ b/Editor/GuruSDK.Editor.asmdef.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 65cafb0a78f2a474eb82c73f624745d8 +timeCreated: 1702611049 \ No newline at end of file diff --git a/Runtime.meta b/Runtime.meta new file mode 100644 index 0000000..d349ec7 --- /dev/null +++ b/Runtime.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c0ee5782432f84c0a8d70e660102aabe +timeCreated: 1702610991 \ No newline at end of file diff --git a/Runtime/Code.meta b/Runtime/Code.meta new file mode 100644 index 0000000..5f2f225 --- /dev/null +++ b/Runtime/Code.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8e84534c908cf44e3bb7d315216557da +timeCreated: 1702611028 \ No newline at end of file diff --git a/Runtime/Code/Config.meta b/Runtime/Code/Config.meta new file mode 100644 index 0000000..7cb6576 --- /dev/null +++ b/Runtime/Code/Config.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e8c2747c350c2451089422bf119c2094 +timeCreated: 1703505490 \ No newline at end of file diff --git a/Runtime/Code/Core.meta b/Runtime/Code/Core.meta new file mode 100644 index 0000000..99d6642 --- /dev/null +++ b/Runtime/Code/Core.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 99b9bdd32c352412598d6d22bf5438b6 +timeCreated: 1702628339 \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDK.Ads.cs b/Runtime/Code/Core/GuruSDK.Ads.cs new file mode 100644 index 0000000..403b81a --- /dev/null +++ b/Runtime/Code/Core/GuruSDK.Ads.cs @@ -0,0 +1,223 @@ + + +namespace Guru +{ + using UnityEngine; + using System; + + + public partial class GuruSDK + { + + /// + /// 启动广告服务 + /// + public static void StartAds() + { + if (InitConfig.UseCustomConsent) + { + Debug.Log($"{Tag} --- Call StartAdsWithCustomConsent when you use custom consent, and pass the result (boolean) to the method."); + } + else + { + // 默认的启动顺序是先启动Consent后, 根据用户回调的结果来启动广告 + Instance.StartConsentFlow(); + } + } + + /// + /// 使用自定义的Consent, 获取用户授权后, 调用此方法 + /// + /// + public static void StartAdsWithCustomConsent(bool userAllow = true) + { + if (userAllow) + { + StartAdService(); + } + else + { + Debug.Log($"{Tag} --- User refuse to provide ads Id, Ads Service will be cancelled"); + } + } + + + + #region Guru Consent + + /// + /// 启动Consent流程 + /// + private void StartConsentFlow() + { + LogI($"StartConsentFlow"); + GuruConsent.StartConsent(OnConsentOver); + } + + private void OnConsentOver(int code) + { + Callbacks.ConsentFlow._onConsentResult?.Invoke(code); + switch(code) + { + case GuruConsent.StatusCode.OBTAINED: + case GuruConsent.StatusCode.NOT_AVAILABLE: + // 已获取授权, 或者地区不可用 +#if UNITY_IOS + CheckATTStatus(); +#else + StartAdService(); +#endif + break; + } + } + +#if UNITY_IOS + /// + /// iOS 平台检查 ATT 状态 + /// + private void CheckATTStatus() + { + AttManager.Instance.CheckATTStatus(OnATTStatus); + } +#endif + + + #endregion + + #region Ad Services + + private static bool _initAdsCompleted = false; + + + /// + /// 启动广告服务 + /// + public static void StartAdService() + { + LogI($"StartAdService"); + ADService.Instance.StartService(OnAdsInitComplete, + InitConfig.AutoLoadWhenAdsReady, IsDebugMode); + + //--------- Callbacks ----------- + ADService.OnInterstitialLoaded = OnInterstitialLoaded; + ADService.OnInterstitialFailed = OnInterstitialFailed; + ADService.OnRewardLoaded = OnRewardLoaded; + ADService.OnRewardFailed = OnRewardFailed; + } + + private static void OnInterstitialLoaded() + => Callbacks.Ads._onInterstitialADLoaded?.Invoke(); + private static void OnInterstitialFailed() + => Callbacks.Ads._onInterstitialADFailed?.Invoke(); + private static void OnRewardLoaded() + => Callbacks.Ads._onRewardedADLoaded?.Invoke(); + private static void OnRewardFailed() + => Callbacks.Ads._onRewardADFailed?.Invoke(); + + private static void OnAdsInitComplete() + { + _initAdsCompleted = true; + Callbacks.Ads._onAdsInitComplete?.Invoke(); + } + + private static bool CheckAdsReady() + { + if (!_initAdsCompleted) + { + LogE("Ads is not ready. Call first."); + return false; + } + return true; + } + + /// + /// 显示Banner广告 + /// + /// + public static void ShowBanner(string placement = "") + { + if (!CheckAdsReady()) return; + ADService.Instance.ShowBanner(placement); + } + /// + /// 隐藏Banner广告 + /// + public static void HideBanner() + { + if (!CheckAdsReady()) return; + ADService.Instance.HideBanner(); + } + + public static void LoadInterstitialAd() + { + if (!CheckAdsReady()) return; + ADService.Instance.RequestInterstitialAD(); + } + + /// + /// 显示插屏广告 + /// + /// + /// + public static void ShowInterstitialAd(string placement = "", Action onDismissed = null) + { + if (!CheckAdsReady()) return; + if (!ADService.Instance.IsInterstitialADReady()) + { + LogE("Interstitial is not ready. Call again."); + LoadInterstitialAd(); + return; + } + ADService.Instance.ShowInterstitialAD(placement, onDismissed); + } + + public static void LoadRewardAd() + { + if (!CheckAdsReady()) return; + ADService.Instance.RequestRewardedAD(); + } + + /// + /// 显示激励视频广告 + /// + /// + /// + /// + public static void ShowRewardAd(string placement = "", Action onRewarded = null, Action onFailed = null) + { + if (!CheckAdsReady()) return; + if (!ADService.Instance.IsRewardedADReady()) + { + LogE("RewardAd is not ready. Call again."); + LoadRewardAd(); + return; + } + ADService.Instance.ShowRewardedAD(placement, onRewarded, onFailed); + } + + + #endregion + + #region MaxServices + + /// + /// 显示Max调试菜单 + /// + public static void ShowMaxDebugPanel() + { +#if UNITY_EDITOR + + LogI($"Can not show Max Debug Panel in Editor, skipped."); + return; +#endif + if (!ADService.Instance.IsInitialized) + { + LogI($"ADService is not initialized, call first."); + return; + } + ADService.Instance.ShowMaxDebugPanel(); + } + + #endregion + } +} \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDK.Ads.cs.meta b/Runtime/Code/Core/GuruSDK.Ads.cs.meta new file mode 100644 index 0000000..49deb71 --- /dev/null +++ b/Runtime/Code/Core/GuruSDK.Ads.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d1320ee3985cd4265906c63a00fd12d4 +timeCreated: 1702628352 \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDK.Analytics.cs b/Runtime/Code/Core/GuruSDK.Analytics.cs new file mode 100644 index 0000000..8e9aeac --- /dev/null +++ b/Runtime/Code/Core/GuruSDK.Analytics.cs @@ -0,0 +1,216 @@ + +namespace Guru +{ + using System.Collections.Generic; + + + /// + /// 打点管理 + /// + public partial class GuruSDK + { + //----------------- 关卡开始类型 --------------------- + public const string EventLevelStartModePlay = "play"; + public const string EventLevelStartModeReplay = "replay"; + public const string EventLevelStartModeContinue= "continue"; + + //----------------- 关卡结束类型 --------------------- + public const string EventLevelEndSuccess = "success"; + public const string EventLevelEndFail = "fail"; + public const string EventLevelEndExit = "exit"; + public const string EventLevelEndTimeout = "timeout"; + + #region 通用接口 + /// + /// 自定义事件打点 + /// + /// + /// + public static void LogEvent(string eventName, Dictionary data = null) + => Analytics.Track(eventName, data); + + public static void SetScreen(string screen, string extra = "") + => Analytics.SetCurrentScreen(screen, extra); + + + + #endregion + + #region 游戏打点 + + /// + /// 游戏启动打点 + /// + /// + /// + /// + /// + /// + /// + public static void LogLevelStart(int level, string startType = EventLevelStartModePlay, + string levelCategory = "main", string levelName = "", string levelID = "", + bool isReplay = false) + { + Analytics.LogLevelStart(level, levelName, levelCategory, levelID, startType, isReplay); + } + + /// + /// 游戏点击 Continue 重开始游戏 + /// + /// + /// + /// + /// + public static void LogLevelContinue(int level, string levelCategory = "main", + string levelName = "", string levelID = "") + { + LogLevelStart(level, EventLevelStartModeContinue, levelCategory, levelName, levelID, true); + } + + /// + /// 游戏点击 Continue 重开始游戏 + /// + /// + /// + /// + /// + public static void LogLevelReplay(int level, string levelCategory = "main", + string levelName = "", string levelID = "") + { + LogLevelStart(level, EventLevelStartModeReplay,levelCategory, levelName, levelID, true); + } + + /// + /// 游戏胜利打点 + /// + public static void LogLevelEnd(int level, string result = EventLevelEndSuccess, + string levelCategory = "main", string levelName = "", string levelID = "", + int? duration = null, int? step = null, int? score = null ) + { + if (InitConfig.AutoRecordFinishedLevels) + { + if(result == EventLevelEndSuccess) Model.SuccessLevelCount++; // 自动记录关卡完成次数 + Model.TotalPlayedCount++; // 自动记录关卡总次数 + + Analytics.BLevel = Model.SuccessLevelCount; // 记录 BLevel + Analytics.BPlay = Model.TotalPlayedCount; // 记录 BPlay + } + + Analytics.LogLevelEnd(level, result, + levelName, levelCategory, levelCategory, + duration, step, score); + } + + + /// + /// 游戏失败打点 + /// 需要为游戏记录详细的失败原因 + /// + public static void LogLevelFail(int level, + string levelCategory = "main",string levelName = "", string levelID = "", + int? duration = null, int? step = null, int? score = null ) + { + LogLevelEnd(level, EventLevelEndFail, levelCategory, levelName, levelID, duration, step, score); + } + + /// + /// 因退出关卡导致游戏失败 + /// + public static void LogLevelFailExit(int level, + string levelCategory = "main", string levelName = "", string levelID = "", + int? duration = null, int? step = null, int? score = null) + { + LogLevelEnd(level, EventLevelEndExit, levelCategory, levelName, levelID, duration, step, score); + } + + /// + /// 因关卡超时导致游戏失败 + /// + public static void LogLevelFailTimeout(int level, + string levelCategory = "main", string levelName = "", string levelID = "", + int? duration = null, int? step = null, int? score = null) + { + LogLevelEnd(level, EventLevelEndTimeout, levelCategory, levelName, levelID, duration, step, score); + } + + + /// + /// 玩家(角色)升级事件 + /// + /// + /// + public static void LogLevelUp(int playerLevel, string playerName) + { + Analytics.LevelUp(playerLevel, playerName); + } + + /// + /// 玩家解锁成就 + /// + /// + public static void LogAchievement(string achievementName) + { + Analytics.UnlockAchievement(achievementName); + } + + #endregion + + #region 用户属性 + + /// + /// 设置用户属性 + /// + /// + /// + public static void SetUserProperty(string key, string value) + => Analytics.SetUserProperty(key, value); + + public static void SetUID(string uid) + { + SetUserProperty(Analytics.PropertyUserID, uid); + } + + public static void SetUserBLevel(int blevel) + { + SetUserProperty(Analytics.PropertyLevel, $"{blevel}"); + } + + public static void SetUserBPlay(int bplay) + { + SetUserProperty(Analytics.PropertyPlay, $"{bplay}"); + } + + public static void SetUserTotalCoins(int totalCoins) + { + SetUserProperty(Analytics.PropertyCoin, $"{totalCoins}"); + } + + public static void SetUserCoins(int coins) + { + SetUserProperty(Analytics.PropertyNonIAPCoin, $"{coins}"); + } + + public static void SetUserPaidCoins(int paidCoins) + { + SetUserProperty(Analytics.PropertyIAPCoin, $"{paidCoins}"); + } + + public static void SetUserExp(int exp) + { + SetUserProperty(Analytics.PropertyExp, $"{exp}"); + } + + public static void SetUserHp(int hp) + { + SetUserProperty(Analytics.PropertyHp, $"{hp}"); + } + + public static void SetUserGrade(int grade) + { + SetUserProperty(Analytics.PropertyGrade, $"{grade}"); + } + + + #endregion + } +} \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDK.Analytics.cs.meta b/Runtime/Code/Core/GuruSDK.Analytics.cs.meta new file mode 100644 index 0000000..7627c3c --- /dev/null +++ b/Runtime/Code/Core/GuruSDK.Analytics.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b2b75eb78fc3c4f148365eb7e3d89bd7 +timeCreated: 1703308617 \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDK.Callback.cs b/Runtime/Code/Core/GuruSDK.Callback.cs new file mode 100644 index 0000000..88714e5 --- /dev/null +++ b/Runtime/Code/Core/GuruSDK.Callback.cs @@ -0,0 +1,119 @@ +namespace Guru +{ + using System; + using UnityEngine; + + + public partial class GuruSDK + { + + + /// + /// 回调参数类 + /// + public class Callbacks + { + + + /// + /// GDPR Consent + /// + public static class ConsentFlow + { + /// + /// 当Consent启动结束后返回状态码 + /// + public static event Action OnConsentResult + { + add => _onConsentResult += value; + remove => _onConsentResult -= value; + } + internal static Action _onConsentResult; + + /// + /// ATT 状态返回 + /// + public static event Action OnAttResult + { + add => _onAttResult += value; + remove => _onAttResult -= value; + } + internal static Action _onAttResult; + + } + + /// + /// 广告回调 + /// + public static class Ads + { + internal static Action _onAdsInitComplete; + public static event Action OnAdsInitComplete + { + add => _onAdsInitComplete += value; + remove => _onAdsInitComplete -= value; + } + + internal static Action _onInterstitialADLoaded; + public static event Action OnInterstitialADLoaded + { + add => _onInterstitialADLoaded += value; + remove => _onInterstitialADLoaded -= value; + } + + internal static Action _onInterstitialADFailed; + public static event Action OnInterstitialADFailed + { + add => _onInterstitialADFailed += value; + remove => _onInterstitialADFailed -= value; + } + + internal static Action _onRewardedADLoaded; + public static event Action OnRewardedADLoaded + { + add => _onRewardedADLoaded += value; + remove => _onRewardedADLoaded -= value; + } + + internal static Action _onRewardADFailed; + public static event Action OnRewardADFailed + { + add => _onRewardADFailed += value; + remove => _onRewardADFailed -= value; + } + } + + + public static class Remote + { + internal static Action _onRemoteInitComplete; + public static event Action OnRemoteInitComplete; + + internal static Action _onRemoteFetchComplete; + public static event Action OnRemoteFetchComplete; + } + + + public static class IAP + { + internal static Action _onIAPInitComplete; + public static event Action OnIAPInitComplete + { + add => _onIAPInitComplete += value; + remove => _onIAPInitComplete -= value; + } + + internal static Action _onPurchaseStart; + public static event Action OnPurchaseStart + { + add => _onPurchaseStart += value; + remove => _onPurchaseStart -= value; + } + + } + + } + + + } +} \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDK.Callback.cs.meta b/Runtime/Code/Core/GuruSDK.Callback.cs.meta new file mode 100644 index 0000000..149a646 --- /dev/null +++ b/Runtime/Code/Core/GuruSDK.Callback.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 971089341f7a64ee38f8d3f82e40f59c +timeCreated: 1703307770 \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDK.IAP.cs b/Runtime/Code/Core/GuruSDK.IAP.cs new file mode 100644 index 0000000..b056005 --- /dev/null +++ b/Runtime/Code/Core/GuruSDK.IAP.cs @@ -0,0 +1,136 @@ +namespace Guru +{ + using UnityEngine; + using System; + using System.Linq; + + + public partial class GuruSDK + { + public static bool IsIAPReady = false; + + /// + /// 初始化IAP 功能 + /// + public static void InitIAP(byte[] googleKey, byte[] appleRootCerts) + { + GuruIAP.Instance.OnInitResult += OnIAPInitResult; + GuruIAP.Instance.OnRestored += OnRestored; + GuruIAP.Instance.OnBuyStart += OnBuyStart; + GuruIAP.Instance.OnBuyEnd += OnBuyEnd; + + GuruIAP.Instance.InitWithKeys(googleKey, appleRootCerts, IsDebugMode); + } + + + /// + /// 初始化结果 + /// + /// + private static void OnIAPInitResult(bool success) + { + LogI($"IAP init result: {success}"); + + IsIAPReady = success; + Callbacks.IAP._onIAPInitComplete?.Invoke(success); + } + + private static bool CheckIAPReady() + { + if (!IsIAPReady) + { + LogE("IAP is not ready, call first."); + return false; + } + + return true; + } + + #region Purchase + + public static ProductSetting GetProductSettingById(string productId) + { + var products = GuruSettings.Instance.Products; + if (products != null && products.Length > 0) + { + return products.FirstOrDefault(p => p.ProductId == productId); + } + return null; + } + + private static Action _onPurchaseCallback; + + /// + /// 购买商品, 通过商品Name + /// + /// + /// + public static void Purchase(string productName, Action purchaseCallback = null) + { + if (CheckIAPReady()) + { + _onPurchaseCallback = purchaseCallback; + GuruIAP.Instance.Buy(productName); + } + } + + /// + /// 购买商品, 通过商品ID + /// + /// + /// + public static bool PurchaseById(string productId, Action purchaseCallback = null) + { + var productName = GetProductSettingById(productId)?.ProductName ?? ""; + + if (CheckIAPReady() && !string.IsNullOrEmpty(productName)) + { + Purchase(productName, purchaseCallback); + return true; + } + return false; + } + + + /// + /// 支付回调 + /// + /// + /// + private static void OnBuyEnd(string productId, bool success) + { + _onPurchaseCallback?.Invoke(productId, success); + } + + + private static void OnBuyStart(string productId) + { + Callbacks.IAP._onPurchaseStart?.Invoke(productId); + } + + #endregion + + #region Restore Purchase + + private static Action _onRestored; + /// + /// 恢复购买 + /// + /// + public static void Restore(Action restoreCallback) + { + if (CheckIAPReady()) + { + _onRestored = restoreCallback; + GuruIAP.Instance.Restore(); + } + } + private static void OnRestored(bool success) + { + _onRestored?.Invoke(success); + } + + #endregion + + } +} \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDK.IAP.cs.meta b/Runtime/Code/Core/GuruSDK.IAP.cs.meta new file mode 100644 index 0000000..19e0f28 --- /dev/null +++ b/Runtime/Code/Core/GuruSDK.IAP.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2613bac8a776048ac9fd924c6dc7244f +timeCreated: 1703320826 \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDK.cs b/Runtime/Code/Core/GuruSDK.cs new file mode 100644 index 0000000..d12620c --- /dev/null +++ b/Runtime/Code/Core/GuruSDK.cs @@ -0,0 +1,175 @@ +namespace Guru +{ + using UnityEngine; + using System; + + public partial class GuruSDK: MonoBehaviour + { + public const string Version = "0.1.0"; + public static readonly string Tag = "[Guru]"; + + private static GuruSDK _instance; + /// + /// 单利引用 + /// + public static GuruSDK Instance + { + get + { + if(null == _instance) + { + _instance = CreateInstance(); + } + return _instance; + } + + } + + private GuruSDKInitConfig _initConfig; + private Action _onCompleteCallback; + + private static GuruSDKModel _model; + + internal static GuruSDKInitConfig InitConfig => Instance._initConfig; + internal static GuruSDKModel Model => GuruSDKModel.Instance; + + + /// + /// Debug Mode + /// + public static bool IsDebugMode + { + get + { +#if UNITY_EDITOR || DEBUG + return true; +#endif + return false; + } + } + + #region 初始化 + + + private static GuruSDK CreateInstance() + { + var go = new GameObject(nameof(GuruSDK)); + DontDestroyOnLoad(go); + _instance = go.AddComponent(); + return _instance; + } + + + public static void Init(Action onComplete) + { + Init(GuruSDKInitConfig.Build(), onComplete); + } + + public static void Init(GuruSDKInitConfig config, Action onComplete) + { + LogI($"---- Guru SDK init ----"); + LogI(config.ToString()); + Instance.StartWithConfig(config, onComplete); + } + + + /// + /// 启动SDK + /// + /// + /// + private void StartWithConfig(GuruSDKInitConfig config, Action onComplete) + { + Model.PropBLevel.OnValueChanged += OnBLevelChanged; + Model.PropBPlay.OnValueChanged += OnBPlayChanged; + + _initConfig = config; + _onCompleteCallback = onComplete; + + //---------- Start Firebase ------------ + FirebaseUtil.InitFirebase(OnFirebaseReady); + FirebaseUtil.OnFetchRemoteSuccess += OnFetchRemoteSuccess; + //---------- Start Facebook ------------ + FBService.Instance.StartService(); + } + + private void OnFetchRemoteSuccess() + { + Callbacks.Remote._onRemoteFetchComplete?.Invoke(); + } + + /// + /// 开始各种组件初始化 + /// + private void OnFirebaseReady() + { + LogI($"--- #1 SDK Init complete ---"); + if (InitConfig.IAPEnabled) + { + LogI($"--- #2 Init IAP ---"); + InitIAP(_initConfig.GoogleKeys, _initConfig.AppleRootCerts); // 初始化IAP + } + + if (!InitConfig.UseCustomConsent) + { + LogI($"--- #3 Start Consent Flow ---"); + StartConsentFlow(); + } + + //TODO: 开始Remote初始化 + + if(!string.IsNullOrEmpty(IPMConfig.IPM_UID)) SetUID(IPMConfig.IPM_UID); + + _onCompleteCallback?.Invoke(true); + } + + private void OnBLevelChanged(int blevel) + { + SetUserBLevel(blevel); + } + + private void OnBPlayChanged(int bplay) + { + SetUserBPlay(bplay); + } + + + + #endregion + + #region Misc + + /// + /// 打开页面 + /// + /// + public static void OpenURL(string url) + { + GuruWebview.OpenPage(url); + } + + + #endregion + + #region Logging + + + public static void LogI(object message) + { + Debug.Log($"{Tag} {message}"); + } + + public static void LogW(object message) + { + Debug.LogWarning($"{Tag} {message}"); + } + + public static void LogE(object message) + { + Debug.LogError($"{Tag} {message}"); + } + + #endregion + + } +} \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDK.cs.meta b/Runtime/Code/Core/GuruSDK.cs.meta new file mode 100644 index 0000000..4080b60 --- /dev/null +++ b/Runtime/Code/Core/GuruSDK.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 62635518506334610aeaf54c9c29fe75 +timeCreated: 1703035168 \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDKInitConfig.cs b/Runtime/Code/Core/GuruSDKInitConfig.cs new file mode 100644 index 0000000..b213d97 --- /dev/null +++ b/Runtime/Code/Core/GuruSDKInitConfig.cs @@ -0,0 +1,97 @@ +namespace Guru +{ + using System.Collections.Generic; + using System.Text; + /// + /// 启动参数配置 + /// + public partial class GuruSDKInitConfig + { + /// + /// 使用自定义的ConsentFlow启动流程 + /// + public bool UseCustomConsent = false; + /// + /// SDK初始化完成后自动加载广告 + /// + public bool AutoLoadWhenAdsReady = true; + /// + /// 使用IAP支付插件功能 + /// + public bool IAPEnabled = true; + /// + /// 自动记录完成的关卡 + /// + public bool AutoRecordFinishedLevels = true; + /// + /// 显示Debug日志 + /// + public bool ShowDebugLog = false; + /// + /// 运控参数的默认配置 + /// + /// + public Dictionary DefaultRemoteData = new Dictionary(); + + /// + /// 支付初始化Keys + /// + public byte[] GoogleKeys; + public byte[] AppleRootCerts; + + #region Initialization + + /// + /// 构建启动配置 + /// + /// + public static GuruSDKInitConfig Build( + bool useCustomConsent = false, + bool autoLoadAds = true, + bool iapEnabled = true, + bool autoRecordFinishedLevels = true, + bool showDebugLog = false, + Dictionary defaultRemoteData = null, + byte[] googleKeys = null, + byte[] appleRootCerts = null) + { + // 创建启动用参数 + GuruSDKInitConfig config = new GuruSDKInitConfig() + { + UseCustomConsent = useCustomConsent, + AutoLoadWhenAdsReady = autoLoadAds, + IAPEnabled = iapEnabled, + AutoRecordFinishedLevels = autoRecordFinishedLevels, + ShowDebugLog = showDebugLog, + GoogleKeys = googleKeys, + AppleRootCerts = appleRootCerts, + DefaultRemoteData = defaultRemoteData ?? new Dictionary(), + }; +#if UNITY_EDITOR + config.ShowDebugLog = true; +#endif + return config; + } + + + #endregion + + #region Print + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine($"------- Custom init Config -------"); + sb.AppendLine($"\tUseCustomConsent: {UseCustomConsent}"); + sb.AppendLine($"\tAutoLoadWhenAdsReady: {AutoLoadWhenAdsReady}"); + sb.AppendLine($"\tIAPEnabled: {IAPEnabled}"); + sb.AppendLine($"\tShowDebugLog: {ShowDebugLog}"); + sb.AppendLine($"------- Custom init Config -------"); + return sb.ToString(); + } + + + + #endregion + } +} \ No newline at end of file diff --git a/Runtime/Code/Core/GuruSDKInitConfig.cs.meta b/Runtime/Code/Core/GuruSDKInitConfig.cs.meta new file mode 100644 index 0000000..8b8c860 --- /dev/null +++ b/Runtime/Code/Core/GuruSDKInitConfig.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e6c57dd4792204f5f9b778eb7e7cb920 +timeCreated: 1703039335 \ No newline at end of file diff --git a/Runtime/Code/Core/GuruServiceConfig.cs b/Runtime/Code/Core/GuruServiceConfig.cs new file mode 100644 index 0000000..d9dde6e --- /dev/null +++ b/Runtime/Code/Core/GuruServiceConfig.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using UnityEngine.Serialization; + +namespace Guru +{ + + [Serializable] + public class GuruServiceConfig + { + public string version; + public GuruAppSettings app_settings; + public GuruAdjustSettings adjust_settings; + public GuruFbSettings fb_settings; + public GuruAdSettings ad_settings; + public string[] products; + + //-------------------------------- 配置检测 -------------------------------- + public bool IsIAPEnabled() => products != null && products.Length > 0; + + public bool IsAmazonAndroidEnabled() => ad_settings != null && + ad_settings.amazon_ids_android != null && + ad_settings.amazon_ids_android.Length > 0; + public bool IsAmazonIOSEnabled() => ad_settings != null && + ad_settings.amazon_ids_ios != null && + ad_settings.amazon_ids_ios.Length > 0; + public bool IsPubmaticAndroidEnabled() => ad_settings != null && + ad_settings.pubmatic_ids_android != null && + ad_settings.pubmatic_ids_android.Length > 0; + public bool IsPubmaticIOSEnabled() => ad_settings != null && + ad_settings.pubmatic_ids_ios != null && + ad_settings.pubmatic_ids_ios.Length > 0; + public bool IsMolocoAndroidEnabled() => ad_settings != null && + ad_settings.moloco_ids_android != null && + ad_settings.moloco_ids_android.Length > 0; + public bool IsMolocoIOSEnabled() => ad_settings != null && + ad_settings.moloco_ids_ios != null && + ad_settings.moloco_ids_ios.Length > 0; + //-------------------------------- 配置检测 -------------------------------- + + + } + + [Serializable] + public class GuruAppSettings + { + public string app_id; + public string product_name; + public string bundle_id; + public string support_email; + public string privacy_url; + public string terms_url; + public string android_store; + public string ios_store; + public int token_vaild_time = 604800; + public int level_end_success_num = 50; + public bool enable_firebase = true; + public bool enable_facebook = true; + public bool enable_adjust = true; + public bool enable_iap = false; + } + + [Serializable] + public class GuruAdjustSettings + { + public string[] app_token; + public string[] events; + } + + [Serializable] + public class GuruFbSettings + { + public string app_id; + public string client_token; + } + + [Serializable] + public class GuruAdSettings + { + public string sdk_key; + public string[] admob_app_id; + public string[] max_ids_android; + public string[] max_ids_ios; + public string[] amazon_ids_android; + public string[] amazon_ids_ios; + public string[] pubmatic_ids_android; + public string[] pubmatic_ids_ios; + public string[] moloco_ids_android; + public string[] moloco_ids_ios; + } + + + +} \ No newline at end of file diff --git a/Runtime/Code/Core/GuruServiceConfig.cs.meta b/Runtime/Code/Core/GuruServiceConfig.cs.meta new file mode 100644 index 0000000..687e14d --- /dev/null +++ b/Runtime/Code/Core/GuruServiceConfig.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5c9728047bb1049639340975b4e8d7ee +timeCreated: 1702861449 \ No newline at end of file diff --git a/Runtime/Code/IAP.meta b/Runtime/Code/IAP.meta new file mode 100644 index 0000000..8315cc2 --- /dev/null +++ b/Runtime/Code/IAP.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2b0ce7d06a8234e3f9a0eb466c38f041 +timeCreated: 1702627775 \ No newline at end of file diff --git a/Runtime/Code/IAP/GuruIAP.cs b/Runtime/Code/IAP/GuruIAP.cs new file mode 100644 index 0000000..b7f2d27 --- /dev/null +++ b/Runtime/Code/IAP/GuruIAP.cs @@ -0,0 +1,20 @@ +namespace Guru +{ + internal class GuruIAP: IAPServiceBase + { + + /// + /// 获取BLevel + /// + /// + protected override int GetBLevel() => GuruSDKModel.Instance.SuccessLevelCount; // BLevel + + protected override void OnPurchaseOver(bool success, string productName) + { + if (success) + { + GuruSDKModel.Instance.PurchasedCount++; // 记录成功购买次数 + } + } + } +} \ No newline at end of file diff --git a/Runtime/Code/IAP/GuruIAP.cs.meta b/Runtime/Code/IAP/GuruIAP.cs.meta new file mode 100644 index 0000000..1c2458b --- /dev/null +++ b/Runtime/Code/IAP/GuruIAP.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f22899a5bf889441fba95e634696a74b +timeCreated: 1703320926 \ No newline at end of file diff --git a/Runtime/Code/Model.meta b/Runtime/Code/Model.meta new file mode 100644 index 0000000..9ad25ba --- /dev/null +++ b/Runtime/Code/Model.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2093caa07830a41d5958de2faf589f13 +timeCreated: 1703321414 \ No newline at end of file diff --git a/Runtime/Code/Model/BindableProperty.cs b/Runtime/Code/Model/BindableProperty.cs new file mode 100644 index 0000000..11b3bb8 --- /dev/null +++ b/Runtime/Code/Model/BindableProperty.cs @@ -0,0 +1,38 @@ +namespace Guru +{ + using UnityEngine; + using System; + + internal class BindableProperty + { + private T _value; + + public T Value + { + get => _value; + set + { + _value = value; + OnValueChanged?.Invoke(value); + } + } + public event Action OnValueChanged; + + + public BindableProperty() + { + + } + + public BindableProperty(Action onChanged) + { + OnValueChanged = onChanged; + } + + public BindableProperty(T initValue, Action onChanged) + { + _value = initValue; + OnValueChanged = onChanged; + } + } +} \ No newline at end of file diff --git a/Runtime/Code/Model/BindableProperty.cs.meta b/Runtime/Code/Model/BindableProperty.cs.meta new file mode 100644 index 0000000..e82ef6c --- /dev/null +++ b/Runtime/Code/Model/BindableProperty.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cc7bbb7d0d6ed42d7985198f9cfc3cb0 +timeCreated: 1703323782 \ No newline at end of file diff --git a/Runtime/Code/Model/GuruSDKModel.cs b/Runtime/Code/Model/GuruSDKModel.cs new file mode 100644 index 0000000..cc8bcc4 --- /dev/null +++ b/Runtime/Code/Model/GuruSDKModel.cs @@ -0,0 +1,171 @@ +using System; +using UnityEngine; +using UnityEngine.Serialization; + +namespace Guru +{ + [Serializable] + internal class GuruSDKModel + { + private static GuruSDKModel _instance; + public static GuruSDKModel Instance + { + get + { + if (null == _instance) _instance = Load(); + return _instance; + } + } + + //-------------- data --------------- + public int b_level = 0; + public int b_play = 0; + public int buy_count = 0; + //-------------- data --------------- + + private float _lastSavedTime = 0; + + public int SuccessLevelCount + { + get + { + if(_successLevel == null) InitProperties(); + return _successLevel.Value; + } + set => _successLevel.Value = value; + } + + public int TotalPlayedCount + { + get + { + if(_totalPlayed == null) InitProperties(); + return _totalPlayed.Value; + } + set => _totalPlayed.Value = value; + } + + public int PurchasedCount + { + get + { + if(_purchasedCount == null) InitProperties(); + return _purchasedCount.Value; + } + set => _purchasedCount.Value = value; + } + + public bool IsIAPUser => PurchasedCount > 0; + + + private BindableProperty _successLevel; + private BindableProperty _totalPlayed; + private BindableProperty _purchasedCount; + + public BindableProperty PropBLevel => _successLevel; + public BindableProperty PropBPlay => _totalPlayed; + public BindableProperty PropBuyCount => _purchasedCount; + + + #region 初始化 + + private const float SaveInterval = 3; + private const string SaveKey = "com.guru.sdk.model.save"; + public static GuruSDKModel Load() + { + GuruSDKModel model = null; + if (PlayerPrefs.HasKey(SaveKey)) + { + var json = PlayerPrefs.GetString(SaveKey, ""); + if (!string.IsNullOrEmpty(json)) + { + try + { + model = JsonUtility.FromJson(json); + } + catch (Exception e) + { + Debug.LogError(e); + } + } + } + if(model == null) model = new GuruSDKModel(); + model.InitProperties(); + return model; + } + + /// + /// 保存至数据 + /// + private void SaveToPlayerPrefs() + { + var json = JsonUtility.ToJson(this); + PlayerPrefs.SetString(SaveKey, json); + } + + public void InitProperties() + { + _successLevel = new BindableProperty(b_level, OnLevelChanged); + _totalPlayed = new BindableProperty(b_play, OnPlayedChanged); + _purchasedCount = new BindableProperty(buy_count, OnPurchasedNumChanged); + } + + /// + /// 保存数据 + /// + /// + public void Save(bool force = false) + { + bool save = force || (Time.realtimeSinceStartup - _lastSavedTime>= SaveInterval); + if (save) + { + _lastSavedTime = Time.realtimeSinceStartup; + SaveToPlayerPrefs(); + } + } + + + #endregion + + #region 数据绑定变化 + private void OnLevelChanged(int value) + { + b_level = value; + Save(); + } + private void OnPlayedChanged(int value) + { + b_play = value; + Save(); + } + + private void OnPurchasedNumChanged(int value) + { + buy_count = value; + Save(); + } + #endregion + + + + + + + + + + + + + + } + + + + + + + + + +} \ No newline at end of file diff --git a/Runtime/Code/Model/GuruSDKModel.cs.meta b/Runtime/Code/Model/GuruSDKModel.cs.meta new file mode 100644 index 0000000..176ac43 --- /dev/null +++ b/Runtime/Code/Model/GuruSDKModel.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9d518492c434042c6aeb20ce679df8ab +timeCreated: 1703321428 \ No newline at end of file diff --git a/Runtime/GuruSDK.asmdef b/Runtime/GuruSDK.asmdef new file mode 100644 index 0000000..bd8919a --- /dev/null +++ b/Runtime/GuruSDK.asmdef @@ -0,0 +1,19 @@ +{ + "name": "GuruSDK", + "rootNamespace": "Guru", + "references": [ + "Guru.Runtime", + "UnityEngine.Purchasing.Security", + "UnityEngine.Purchasing.SecurityStub", + "UnityEngine.Purchasing.SecurityCore" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Runtime/GuruSDK.asmdef.meta b/Runtime/GuruSDK.asmdef.meta new file mode 100644 index 0000000..6da5c09 --- /dev/null +++ b/Runtime/GuruSDK.asmdef.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 85fac0454e8c64a0da25f1f632acaa75 +timeCreated: 1702611014 \ No newline at end of file diff --git a/Runtime/Prefab.meta b/Runtime/Prefab.meta new file mode 100644 index 0000000..7d802c8 --- /dev/null +++ b/Runtime/Prefab.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fc679813f31644f20b79c6f24939c6a9 +timeCreated: 1702611035 \ No newline at end of file diff --git a/link.xml b/link.xml new file mode 100644 index 0000000..7374ba9 --- /dev/null +++ b/link.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/link.xml.meta b/link.xml.meta new file mode 100644 index 0000000..145154d --- /dev/null +++ b/link.xml.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 33d446758bba24852bac2e3d9c6bf6fc +timeCreated: 1703388178 \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..389c65b --- /dev/null +++ b/package.json @@ -0,0 +1,15 @@ +{ + "name": "com.guru.unity.sdk", + "displayName": "Guru SDK", + "version": "0.0.1", + "description": "Guru SDK for unity project", + "unity": "2020.3", + "author":{ + "name": "Guru Fungames Studio" + }, + "license": "MIT", + "category": "Game,Tool,Development", + "dependencies": { + "com.guru.unity.sdk.core": "git@github.com:castbox/upm-guru-sdk-core-proto.git" + } +} \ No newline at end of file diff --git a/package.json.meta b/package.json.meta new file mode 100644 index 0000000..bf7fed0 --- /dev/null +++ b/package.json.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2e68608e12de34fa69d2e96e7dcb8892 +timeCreated: 1702610734 \ No newline at end of file