init commit
commit
bb1a4b8cce
|
|
@ -0,0 +1 @@
|
||||||
|
*.DS_Store
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9bb2904375c2a46eb90e2a3cace489a0
|
||||||
|
timeCreated: 1702610996
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: df5ee84bbb0c0495eb6f89444802ffd9
|
||||||
|
timeCreated: 1703231056
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 44aa37ed74dd4407a9d04a07ccf97247
|
||||||
|
timeCreated: 1702611095
|
||||||
|
|
@ -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 = "";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 加载配置
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static GuruServiceConfig LoadConfig()
|
||||||
|
{
|
||||||
|
var a = AssetDatabase.FindAssets($"*{DefaultFileName}* t:TextAsset");
|
||||||
|
if (a == null || a.Length == 0)
|
||||||
|
{
|
||||||
|
Debug.Log($"<color=orange>--- Can't ind guru-services file</color>");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var p = AssetDatabase.GUIDToAssetPath(a[0]);
|
||||||
|
var fp = Path.GetFullPath(p);
|
||||||
|
if (File.Exists(fp)) _selectedFilePath = fp;
|
||||||
|
var t = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
|
||||||
|
// Debug.Log($"<color=#88ff00>--- find services file:{p} \n{t.text}</color>");
|
||||||
|
return JsonMapper.ToObject<GuruServiceConfig>(t.text);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存配置
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config"></param>
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建空配置
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 043619bc8571240f6b8926c2ccffbd29
|
||||||
|
timeCreated: 1702877769
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: eec1c72fa3d0c493b9b30091a81043ee
|
||||||
|
timeCreated: 1703413024
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="ball.sort.puzzle.color.game.bubble.sorting.free" android:versionCode="1" android:versionName="1.0">
|
||||||
|
<application android:label="@string/app_name" android:icon="@drawable/app_icon">
|
||||||
|
<!-- The MessagingUnityPlayerActivity is a class that extends
|
||||||
|
UnityPlayerActivity to work around a known issue when receiving
|
||||||
|
notification data payloads in the background. -->
|
||||||
|
<activity android:name="com.google.firebase.MessagingUnityPlayerActivity"
|
||||||
|
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
|
||||||
|
</activity>
|
||||||
|
<service android:name="com.google.firebase.messaging.MessageForwardingService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="false">
|
||||||
|
</service>
|
||||||
|
<receiver android:name="com.adjust.sdk.AdjustReferrerReceiver" android:permission="android.permission.INSTALL_PACKAGES" android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.android.vending.INSTALL_REFERRER" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
<activity android:name="com.facebook.unity.FBUnityLoginActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
|
||||||
|
<activity android:name="com.facebook.unity.FBUnityDialogsActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
|
||||||
|
<activity android:name="com.facebook.unity.FBUnityGamingServicesFriendFinderActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
|
||||||
|
<activity android:name="com.facebook.unity.FBUnityAppLinkActivity" android:exported="true" />
|
||||||
|
<activity android:name="com.facebook.unity.FBUnityDeepLinkingActivity" android:exported="true" />
|
||||||
|
<activity android:name="com.facebook.unity.FBUnityGameRequestActivity" />
|
||||||
|
<activity android:name="com.facebook.unity.FBUnityCreateGameGroupActivity" />
|
||||||
|
<activity android:name="com.facebook.unity.FBUnityJoinGameGroupActivity" />
|
||||||
|
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="fb111111111111111" />
|
||||||
|
<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="false" />
|
||||||
|
<meta-data android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled" android:value="true" />
|
||||||
|
<provider android:name="com.facebook.FacebookContentProvider" android:authorities="com.facebook.app.FacebookContentProvider.000" android:exported="true" />
|
||||||
|
<meta-data name="com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION" value="true" />
|
||||||
|
<meta-data name="com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING" value="true" />
|
||||||
|
</application>
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />
|
||||||
|
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
|
||||||
|
</manifest>
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ad463c22214a24eecba0c3d3428cd2bc
|
||||||
|
timeCreated: 1703413179
|
||||||
|
|
@ -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**
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 91158a71185444f2798701c44312902f
|
||||||
|
timeCreated: 1703468454
|
||||||
|
|
@ -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**
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5ca7eb01ab20749d7b9254c3a4825e31
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6cf3317fddf61454181264b523a2804e
|
||||||
|
TextScriptImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f9253ec9aa37d4fd28af570d9427c00b
|
||||||
|
timeCreated: 1702629767
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9ce9c7008577c4c04b10eb96a3244867
|
||||||
|
timeCreated: 1703409620
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3e096221d72bd44baa543f1629092c4a
|
||||||
|
timeCreated: 1703412483
|
||||||
|
|
@ -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 "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d05ef4ba47b6e4cb7bf95cb073af4915
|
||||||
|
timeCreated: 1703413245
|
||||||
|
|
@ -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("<color=#88ff00>found guru-services file on disk</color>");
|
||||||
|
// TODO:
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log("<color=yellow>Can't find guru-services.json on load...</color>");
|
||||||
|
// GuruSDKManager.Open();
|
||||||
|
EditorGuruServiceIO.LoadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4012c7bdb57bc4bfbb3b313a86ea3901
|
||||||
|
timeCreated: 1702627784
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
using Guru.Editor;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
|
public class GuruSDKMenuItems
|
||||||
|
{
|
||||||
|
|
||||||
|
[MenuItem("Guru/Guru SDK")]
|
||||||
|
private static void ShowGuruManager()
|
||||||
|
{
|
||||||
|
GuruSDKManager.Open();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7e6a90bd7ba03491d87943c2c1fcf17e
|
||||||
|
timeCreated: 1702861089
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 627835e82d65043cf8996da4a8377fa7
|
||||||
|
timeCreated: 1703231041
|
||||||
|
|
@ -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<GuruSDKManager>();
|
||||||
|
}
|
||||||
|
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($"<color=#88ff00>[Guru] Load <guru-services> success.</color>");
|
||||||
|
CheckServicesCompletion();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Log($"<color=red>[Guru] <guru-services> file not found...</color>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Service Checker
|
||||||
|
|
||||||
|
private const string MARK_FAIL = "#FAIL";
|
||||||
|
private const string MARK_INDENT = " ";
|
||||||
|
private List<string> _completionCheckResult;
|
||||||
|
private int _serviceCriticalFail = 0;
|
||||||
|
private int _serviceNormalFail = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查服务文件的配置完整性
|
||||||
|
/// </summary>
|
||||||
|
private void CheckServicesCompletion()
|
||||||
|
{
|
||||||
|
_serviceCriticalFail = 0;
|
||||||
|
_serviceNormalFail = 0;
|
||||||
|
|
||||||
|
_completionCheckResult = new List<string>(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} <guru-services> 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<string>(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置不可用
|
||||||
|
/// </summary>
|
||||||
|
private void GUI_OnConfigDisabled()
|
||||||
|
{
|
||||||
|
GUI_Color(new Color(1,0.2f, 0), () =>
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField("<>", StyleItemTitle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置可用
|
||||||
|
/// </summary>
|
||||||
|
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<GuruSettings>(GURU_SETTINGS_PATH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
settings = CreateInstance<GuruSettings>();
|
||||||
|
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<AppLovinSettings>(APPLOVIN_SETTINGS_PATH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
settings = CreateInstance<AppLovinSettings>();
|
||||||
|
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<FacebookSettings>(FACEBOOK_SETTINGS_PATH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
settings = CreateInstance<FacebookSettings>();
|
||||||
|
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
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取Assets路径
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filter"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
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
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0a6aed96e95b747cdbb3c19c8d01b5f1
|
||||||
|
timeCreated: 1702786341
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 65cafb0a78f2a474eb82c73f624745d8
|
||||||
|
timeCreated: 1702611049
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c0ee5782432f84c0a8d70e660102aabe
|
||||||
|
timeCreated: 1702610991
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8e84534c908cf44e3bb7d315216557da
|
||||||
|
timeCreated: 1702611028
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e8c2747c350c2451089422bf119c2094
|
||||||
|
timeCreated: 1703505490
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 99b9bdd32c352412598d6d22bf5438b6
|
||||||
|
timeCreated: 1702628339
|
||||||
|
|
@ -0,0 +1,223 @@
|
||||||
|
|
||||||
|
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
|
using UnityEngine;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
public partial class GuruSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动广告服务
|
||||||
|
/// </summary>
|
||||||
|
public static void StartAds()
|
||||||
|
{
|
||||||
|
if (InitConfig.UseCustomConsent)
|
||||||
|
{
|
||||||
|
Debug.Log($"{Tag} --- Call <color=orange>StartAdsWithCustomConsent</color> when you use custom consent, and pass the result (boolean) to the method.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 默认的启动顺序是先启动Consent后, 根据用户回调的结果来启动广告
|
||||||
|
Instance.StartConsentFlow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用自定义的Consent, 获取用户授权后, 调用此方法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userAllow"></param>
|
||||||
|
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
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动Consent流程
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
/// <summary>
|
||||||
|
/// iOS 平台检查 ATT 状态
|
||||||
|
/// </summary>
|
||||||
|
private void CheckATTStatus()
|
||||||
|
{
|
||||||
|
AttManager.Instance.CheckATTStatus(OnATTStatus);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Ad Services
|
||||||
|
|
||||||
|
private static bool _initAdsCompleted = false;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动广告服务
|
||||||
|
/// </summary>
|
||||||
|
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 <GuruSDk.StartAdService> first.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示Banner广告
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="placement"></param>
|
||||||
|
public static void ShowBanner(string placement = "")
|
||||||
|
{
|
||||||
|
if (!CheckAdsReady()) return;
|
||||||
|
ADService.Instance.ShowBanner(placement);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 隐藏Banner广告
|
||||||
|
/// </summary>
|
||||||
|
public static void HideBanner()
|
||||||
|
{
|
||||||
|
if (!CheckAdsReady()) return;
|
||||||
|
ADService.Instance.HideBanner();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LoadInterstitialAd()
|
||||||
|
{
|
||||||
|
if (!CheckAdsReady()) return;
|
||||||
|
ADService.Instance.RequestInterstitialAD();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示插屏广告
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="placement"></param>
|
||||||
|
/// <param name="onDismissed"></param>
|
||||||
|
public static void ShowInterstitialAd(string placement = "", Action onDismissed = null)
|
||||||
|
{
|
||||||
|
if (!CheckAdsReady()) return;
|
||||||
|
if (!ADService.Instance.IsInterstitialADReady())
|
||||||
|
{
|
||||||
|
LogE("Interstitial is not ready. Call <GuruSDk.ShowInterstitialAd> again.");
|
||||||
|
LoadInterstitialAd();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ADService.Instance.ShowInterstitialAD(placement, onDismissed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LoadRewardAd()
|
||||||
|
{
|
||||||
|
if (!CheckAdsReady()) return;
|
||||||
|
ADService.Instance.RequestRewardedAD();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示激励视频广告
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="placement"></param>
|
||||||
|
/// <param name="onRewarded"></param>
|
||||||
|
/// <param name="onFailed"></param>
|
||||||
|
public static void ShowRewardAd(string placement = "", Action onRewarded = null, Action<string> onFailed = null)
|
||||||
|
{
|
||||||
|
if (!CheckAdsReady()) return;
|
||||||
|
if (!ADService.Instance.IsRewardedADReady())
|
||||||
|
{
|
||||||
|
LogE("RewardAd is not ready. Call <GuruSDk.LoadRewardAd> again.");
|
||||||
|
LoadRewardAd();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ADService.Instance.ShowRewardedAD(placement, onRewarded, onFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region MaxServices
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示Max调试菜单
|
||||||
|
/// </summary>
|
||||||
|
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 <GuruSDK.StartAds> first.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ADService.Instance.ShowMaxDebugPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d1320ee3985cd4265906c63a00fd12d4
|
||||||
|
timeCreated: 1702628352
|
||||||
|
|
@ -0,0 +1,216 @@
|
||||||
|
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 打点管理
|
||||||
|
/// </summary>
|
||||||
|
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 通用接口
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义事件打点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventName"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
|
public static void LogEvent(string eventName, Dictionary<string, dynamic> data = null)
|
||||||
|
=> Analytics.Track(eventName, data);
|
||||||
|
|
||||||
|
public static void SetScreen(string screen, string extra = "")
|
||||||
|
=> Analytics.SetCurrentScreen(screen, extra);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 游戏打点
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 游戏启动打点
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="level"></param>
|
||||||
|
/// <param name="levelName"></param>
|
||||||
|
/// <param name="levelCategory"></param>
|
||||||
|
/// <param name="levelID"></param>
|
||||||
|
/// <param name="startType"></param>
|
||||||
|
/// <param name="isReplay"></param>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 游戏点击 Continue 重开始游戏
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="level"></param>
|
||||||
|
/// <param name="levelCategory"></param>
|
||||||
|
/// <param name="levelName"></param>
|
||||||
|
/// <param name="levelID"></param>
|
||||||
|
public static void LogLevelContinue(int level, string levelCategory = "main",
|
||||||
|
string levelName = "", string levelID = "")
|
||||||
|
{
|
||||||
|
LogLevelStart(level, EventLevelStartModeContinue, levelCategory, levelName, levelID, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 游戏点击 Continue 重开始游戏
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="level"></param>
|
||||||
|
/// <param name="levelCategory"></param>
|
||||||
|
/// <param name="levelName"></param>
|
||||||
|
/// <param name="levelID"></param>
|
||||||
|
public static void LogLevelReplay(int level, string levelCategory = "main",
|
||||||
|
string levelName = "", string levelID = "")
|
||||||
|
{
|
||||||
|
LogLevelStart(level, EventLevelStartModeReplay,levelCategory, levelName, levelID, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 游戏胜利打点
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 游戏失败打点
|
||||||
|
/// 需要为游戏记录详细的失败原因
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 因退出关卡导致游戏失败
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 因关卡超时导致游戏失败
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 玩家(角色)升级事件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="playerLevel"></param>
|
||||||
|
/// <param name="playerName"></param>
|
||||||
|
public static void LogLevelUp(int playerLevel, string playerName)
|
||||||
|
{
|
||||||
|
Analytics.LevelUp(playerLevel, playerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 玩家解锁成就
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="achievementName"></param>
|
||||||
|
public static void LogAchievement(string achievementName)
|
||||||
|
{
|
||||||
|
Analytics.UnlockAchievement(achievementName);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 用户属性
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置用户属性
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b2b75eb78fc3c4f148365eb7e3d89bd7
|
||||||
|
timeCreated: 1703308617
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
|
public partial class GuruSDK
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回调参数类
|
||||||
|
/// </summary>
|
||||||
|
public class Callbacks
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// GDPR Consent
|
||||||
|
/// </summary>
|
||||||
|
public static class ConsentFlow
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 当Consent启动结束后返回状态码
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<int> OnConsentResult
|
||||||
|
{
|
||||||
|
add => _onConsentResult += value;
|
||||||
|
remove => _onConsentResult -= value;
|
||||||
|
}
|
||||||
|
internal static Action<int> _onConsentResult;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ATT 状态返回
|
||||||
|
/// </summary>
|
||||||
|
public static event Action<int> OnAttResult
|
||||||
|
{
|
||||||
|
add => _onAttResult += value;
|
||||||
|
remove => _onAttResult -= value;
|
||||||
|
}
|
||||||
|
internal static Action<int> _onAttResult;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 广告回调
|
||||||
|
/// </summary>
|
||||||
|
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<bool> _onIAPInitComplete;
|
||||||
|
public static event Action<bool> OnIAPInitComplete
|
||||||
|
{
|
||||||
|
add => _onIAPInitComplete += value;
|
||||||
|
remove => _onIAPInitComplete -= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Action<string> _onPurchaseStart;
|
||||||
|
public static event Action<string> OnPurchaseStart
|
||||||
|
{
|
||||||
|
add => _onPurchaseStart += value;
|
||||||
|
remove => _onPurchaseStart -= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 971089341f7a64ee38f8d3f82e40f59c
|
||||||
|
timeCreated: 1703307770
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
|
using UnityEngine;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
|
||||||
|
public partial class GuruSDK
|
||||||
|
{
|
||||||
|
public static bool IsIAPReady = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化IAP 功能
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化结果
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="success"></param>
|
||||||
|
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 <GuruSDK.InitIAP> 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<string, bool> _onPurchaseCallback;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 购买商品, 通过商品Name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="productId"></param>
|
||||||
|
/// <param name="purchaseCallback"></param>
|
||||||
|
public static void Purchase(string productName, Action<string, bool> purchaseCallback = null)
|
||||||
|
{
|
||||||
|
if (CheckIAPReady())
|
||||||
|
{
|
||||||
|
_onPurchaseCallback = purchaseCallback;
|
||||||
|
GuruIAP.Instance.Buy(productName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 购买商品, 通过商品ID
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="productId"></param>
|
||||||
|
/// <param name="purchaseCallback"></param>
|
||||||
|
public static bool PurchaseById(string productId, Action<string, bool> purchaseCallback = null)
|
||||||
|
{
|
||||||
|
var productName = GetProductSettingById(productId)?.ProductName ?? "";
|
||||||
|
|
||||||
|
if (CheckIAPReady() && !string.IsNullOrEmpty(productName))
|
||||||
|
{
|
||||||
|
Purchase(productName, purchaseCallback);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支付回调
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="productId"></param>
|
||||||
|
/// <param name="success"></param>
|
||||||
|
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<bool> _onRestored;
|
||||||
|
/// <summary>
|
||||||
|
/// 恢复购买
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="restoreCallback"></param>
|
||||||
|
public static void Restore(Action<bool> restoreCallback)
|
||||||
|
{
|
||||||
|
if (CheckIAPReady())
|
||||||
|
{
|
||||||
|
_onRestored = restoreCallback;
|
||||||
|
GuruIAP.Instance.Restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void OnRestored(bool success)
|
||||||
|
{
|
||||||
|
_onRestored?.Invoke(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2613bac8a776048ac9fd924c6dc7244f
|
||||||
|
timeCreated: 1703320826
|
||||||
|
|
@ -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;
|
||||||
|
/// <summary>
|
||||||
|
/// 单利引用
|
||||||
|
/// </summary>
|
||||||
|
public static GuruSDK Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(null == _instance)
|
||||||
|
{
|
||||||
|
_instance = CreateInstance();
|
||||||
|
}
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private GuruSDKInitConfig _initConfig;
|
||||||
|
private Action<bool> _onCompleteCallback;
|
||||||
|
|
||||||
|
private static GuruSDKModel _model;
|
||||||
|
|
||||||
|
internal static GuruSDKInitConfig InitConfig => Instance._initConfig;
|
||||||
|
internal static GuruSDKModel Model => GuruSDKModel.Instance;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Debug Mode
|
||||||
|
/// </summary>
|
||||||
|
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<GuruSDK>();
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void Init(Action<bool> onComplete)
|
||||||
|
{
|
||||||
|
Init(GuruSDKInitConfig.Build(), onComplete);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Init(GuruSDKInitConfig config, Action<bool> onComplete)
|
||||||
|
{
|
||||||
|
LogI($"---- Guru SDK init ----");
|
||||||
|
LogI(config.ToString());
|
||||||
|
Instance.StartWithConfig(config, onComplete);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动SDK
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config"></param>
|
||||||
|
/// <param name="onComplete"></param>
|
||||||
|
private void StartWithConfig(GuruSDKInitConfig config, Action<bool> 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始各种组件初始化
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 打开页面
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
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
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 62635518506334610aeaf54c9c29fe75
|
||||||
|
timeCreated: 1703035168
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
/// <summary>
|
||||||
|
/// 启动参数配置
|
||||||
|
/// </summary>
|
||||||
|
public partial class GuruSDKInitConfig
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 使用自定义的ConsentFlow启动流程
|
||||||
|
/// </summary>
|
||||||
|
public bool UseCustomConsent = false;
|
||||||
|
/// <summary>
|
||||||
|
/// SDK初始化完成后自动加载广告
|
||||||
|
/// </summary>
|
||||||
|
public bool AutoLoadWhenAdsReady = true;
|
||||||
|
/// <summary>
|
||||||
|
/// 使用IAP支付插件功能
|
||||||
|
/// </summary>
|
||||||
|
public bool IAPEnabled = true;
|
||||||
|
/// <summary>
|
||||||
|
/// 自动记录完成的关卡
|
||||||
|
/// </summary>
|
||||||
|
public bool AutoRecordFinishedLevels = true;
|
||||||
|
/// <summary>
|
||||||
|
/// 显示Debug日志
|
||||||
|
/// </summary>
|
||||||
|
public bool ShowDebugLog = false;
|
||||||
|
/// <summary>
|
||||||
|
/// 运控参数的默认配置
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Dictionary<string, object> DefaultRemoteData = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 支付初始化Keys
|
||||||
|
/// </summary>
|
||||||
|
public byte[] GoogleKeys;
|
||||||
|
public byte[] AppleRootCerts;
|
||||||
|
|
||||||
|
#region Initialization
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构建启动配置
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static GuruSDKInitConfig Build(
|
||||||
|
bool useCustomConsent = false,
|
||||||
|
bool autoLoadAds = true,
|
||||||
|
bool iapEnabled = true,
|
||||||
|
bool autoRecordFinishedLevels = true,
|
||||||
|
bool showDebugLog = false,
|
||||||
|
Dictionary<string, object> 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<string, object>(),
|
||||||
|
};
|
||||||
|
#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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e6c57dd4792204f5f9b778eb7e7cb920
|
||||||
|
timeCreated: 1703039335
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5c9728047bb1049639340975b4e8d7ee
|
||||||
|
timeCreated: 1702861449
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2b0ce7d06a8234e3f9a0eb466c38f041
|
||||||
|
timeCreated: 1702627775
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
|
internal class GuruIAP: IAPServiceBase<GuruIAP>
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取BLevel
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected override int GetBLevel() => GuruSDKModel.Instance.SuccessLevelCount; // BLevel
|
||||||
|
|
||||||
|
protected override void OnPurchaseOver(bool success, string productName)
|
||||||
|
{
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
GuruSDKModel.Instance.PurchasedCount++; // 记录成功购买次数
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f22899a5bf889441fba95e634696a74b
|
||||||
|
timeCreated: 1703320926
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2093caa07830a41d5958de2faf589f13
|
||||||
|
timeCreated: 1703321414
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
namespace Guru
|
||||||
|
{
|
||||||
|
using UnityEngine;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
internal class BindableProperty<T>
|
||||||
|
{
|
||||||
|
private T _value;
|
||||||
|
|
||||||
|
public T Value
|
||||||
|
{
|
||||||
|
get => _value;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_value = value;
|
||||||
|
OnValueChanged?.Invoke(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public event Action<T> OnValueChanged;
|
||||||
|
|
||||||
|
|
||||||
|
public BindableProperty()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public BindableProperty(Action<T> onChanged)
|
||||||
|
{
|
||||||
|
OnValueChanged = onChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BindableProperty(T initValue, Action<T> onChanged)
|
||||||
|
{
|
||||||
|
_value = initValue;
|
||||||
|
OnValueChanged = onChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cc7bbb7d0d6ed42d7985198f9cfc3cb0
|
||||||
|
timeCreated: 1703323782
|
||||||
|
|
@ -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<int> _successLevel;
|
||||||
|
private BindableProperty<int> _totalPlayed;
|
||||||
|
private BindableProperty<int> _purchasedCount;
|
||||||
|
|
||||||
|
public BindableProperty<int> PropBLevel => _successLevel;
|
||||||
|
public BindableProperty<int> PropBPlay => _totalPlayed;
|
||||||
|
public BindableProperty<int> 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<GuruSDKModel>(json);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(model == null) model = new GuruSDKModel();
|
||||||
|
model.InitProperties();
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存至数据
|
||||||
|
/// </summary>
|
||||||
|
private void SaveToPlayerPrefs()
|
||||||
|
{
|
||||||
|
var json = JsonUtility.ToJson(this);
|
||||||
|
PlayerPrefs.SetString(SaveKey, json);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitProperties()
|
||||||
|
{
|
||||||
|
_successLevel = new BindableProperty<int>(b_level, OnLevelChanged);
|
||||||
|
_totalPlayed = new BindableProperty<int>(b_play, OnPlayedChanged);
|
||||||
|
_purchasedCount = new BindableProperty<int>(buy_count, OnPurchasedNumChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 保存数据
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="force"></param>
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9d518492c434042c6aeb20ce679df8ab
|
||||||
|
timeCreated: 1703321428
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 85fac0454e8c64a0da25f1f632acaa75
|
||||||
|
timeCreated: 1702611014
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fc679813f31644f20b79c6f24939c6a9
|
||||||
|
timeCreated: 1702611035
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<linker>
|
||||||
|
<assembly fullname="GuruSDK">
|
||||||
|
<namespace fullname="Guru" preserve="all"/>
|
||||||
|
</assembly>
|
||||||
|
</linker>
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 33d446758bba24852bac2e3d9c6bf6fc
|
||||||
|
timeCreated: 1703388178
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2e68608e12de34fa69d2e96e7dcb8892
|
||||||
|
timeCreated: 1702610734
|
||||||
Loading…
Reference in New Issue