1 Commits
1.4.8 ... upm

Author SHA1 Message Date
d653b06c8d release: 1.4.9 2026-04-23 17:15:19 +08:00
23 changed files with 31 additions and 446 deletions

View File

@@ -156,7 +156,7 @@ namespace AnyThinkAds.Android
}catch(System.Exception e){ }catch(System.Exception e){
System.Console.WriteLine("Exception caught: {0}", e); System.Console.WriteLine("Exception caught: {0}", e);
Debug.Log ("ATInterstitialAdClient : error."+e.Message); Debug.Log ("ATInterstitialAdClient : error."+e.Message);
throw;
} }
} }
@@ -403,6 +403,7 @@ namespace AnyThinkAds.Android
{ {
System.Console.WriteLine("Exception caught: {0}", e); System.Console.WriteLine("Exception caught: {0}", e);
Debug.Log("Unity: ATInterstitialAdClient:showAutoAd() : error." + e.Message); Debug.Log("Unity: ATInterstitialAdClient:showAutoAd() : error." + e.Message);
throw;
} }
} }

View File

@@ -160,7 +160,7 @@ namespace AnyThinkAds.Android
}catch(System.Exception e){ }catch(System.Exception e){
System.Console.WriteLine("Exception caught: {0}", e); System.Console.WriteLine("Exception caught: {0}", e);
Debug.Log ("ATRewardedVideoAdClient : error."+e.Message); Debug.Log ("ATRewardedVideoAdClient : error."+e.Message);
throw;
} }
} }
@@ -390,6 +390,7 @@ namespace AnyThinkAds.Android
{ {
System.Console.WriteLine("Exception caught: {0}", e); System.Console.WriteLine("Exception caught: {0}", e);
Debug.Log("Unity: ATRewardedVideoAdClient:showAutoAd() : error." + e.Message); Debug.Log("Unity: ATRewardedVideoAdClient:showAutoAd() : error." + e.Message);
throw;
} }
} }

View File

@@ -1,3 +1,15 @@
# [1.4.9]
### 新增
* 示例改为 `Samples~` 可选导入内容,业务项目默认引用主包时不再自动带入 sample 菜单和调试场景。
### 修复
* 重构激励视频与插屏展示阶段状态机,补齐 `show/showAutoAd` 同步异常后的失败收口,避免卡死在播放前遮罩。
* 按官方语义调整激励视频生命周期:奖励回调只记录奖励结果,关闭回调统一完成会话结算。
* 去除广告源级失败对主链的误判,`AdSource` 加载/竞价失败不再错误打断播放器流程。
# [1.4.8] # [1.4.8]
### 修复 ### 修复

View File

@@ -1,166 +0,0 @@
#if UNITY_EDITOR
using System;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEngine;
public static class IAAAdAndroidBuild
{
private const string OutputDirectory = "Build/Android";
private const string OutputApkPath = OutputDirectory + "/IAAAdDebugSample-starveg.apk";
private const string KeystorePath = "Build/Android/keys/starveg-test.keystore";
private const string KeystorePassword = "Foldcc123!";
private const string KeyAliasName = "starvegtest";
private const string PackageName = "com.foldcc.starveg";
[MenuItem("Topon/Build IAA Android Test APK")]
public static void BuildAndroidTestApk()
{
EnsureBuildFolders();
ConfigurePlayerSettings();
var resolverState = CaptureResolverState();
try
{
ApplyBatchFriendlyResolverSettings();
var scenes = new[] { "Assets/Samples/IAAAdDebugSample/Scenes/IAAAdDebugSample.unity" };
var options = new BuildPlayerOptions
{
scenes = scenes,
target = BuildTarget.Android,
locationPathName = OutputApkPath,
options = BuildOptions.None
};
var report = BuildPipeline.BuildPlayer(options);
if (report.summary.result != BuildResult.Succeeded)
{
throw new Exception(
$"Android APK build failed: {report.summary.result} ({report.summary.totalErrors} errors)");
}
Debug.Log($"[IAA Build] APK generated: {Path.GetFullPath(OutputApkPath)}");
}
finally
{
RestoreResolverState(resolverState);
}
}
public static void BuildAndroidTestApkInBatchMode()
{
BuildAndroidTestApk();
EditorApplication.Exit(0);
}
private static void ConfigurePlayerSettings()
{
PlayerSettings.SetApplicationIdentifier(BuildTargetGroup.Android, PackageName);
PlayerSettings.defaultInterfaceOrientation = UIOrientation.Portrait;
PlayerSettings.Android.targetArchitectures = AndroidArchitecture.ARMv7 | AndroidArchitecture.ARM64;
PlayerSettings.Android.useCustomKeystore = true;
PlayerSettings.Android.keystoreName = Path.GetFullPath(KeystorePath);
PlayerSettings.Android.keystorePass = KeystorePassword;
PlayerSettings.Android.keyaliasName = KeyAliasName;
PlayerSettings.Android.keyaliasPass = KeystorePassword;
PlayerSettings.bundleVersion = string.IsNullOrWhiteSpace(PlayerSettings.bundleVersion)
? "1.0.0"
: PlayerSettings.bundleVersion;
PlayerSettings.Android.bundleVersionCode = Mathf.Max(1, PlayerSettings.Android.bundleVersionCode);
AssetDatabase.SaveAssets();
}
private static void EnsureBuildFolders()
{
Directory.CreateDirectory(Path.GetFullPath(OutputDirectory));
Directory.CreateDirectory(Path.GetFullPath(Path.GetDirectoryName(KeystorePath) ?? OutputDirectory));
}
private static ResolverState CaptureResolverState()
{
var settingsType = GetResolverSettingsType();
return new ResolverState
{
EnableAutoResolution = GetResolverBool(settingsType, "EnableAutoResolution"),
AutoResolveOnBuild = GetResolverBool(settingsType, "AutoResolveOnBuild"),
PromptBeforeAutoResolution = GetResolverBool(settingsType, "PromptBeforeAutoResolution")
};
}
private static void ApplyBatchFriendlyResolverSettings()
{
var settingsType = GetResolverSettingsType();
SetResolverBool(settingsType, "EnableAutoResolution", false);
SetResolverBool(settingsType, "AutoResolveOnBuild", false);
SetResolverBool(settingsType, "PromptBeforeAutoResolution", false);
}
private static void RestoreResolverState(ResolverState state)
{
var settingsType = GetResolverSettingsType();
SetResolverBool(settingsType, "EnableAutoResolution", state.EnableAutoResolution);
SetResolverBool(settingsType, "AutoResolveOnBuild", state.AutoResolveOnBuild);
SetResolverBool(settingsType, "PromptBeforeAutoResolution", state.PromptBeforeAutoResolution);
}
private static Type GetResolverSettingsType()
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var type = assembly.GetType("GooglePlayServices.SettingsDialog");
if (type != null)
{
return type;
}
}
return null;
}
private static bool GetResolverBool(Type settingsType, string propertyName)
{
if (settingsType == null)
{
return false;
}
var property = settingsType.GetProperty(
propertyName,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (property == null)
{
return false;
}
return (bool)property.GetValue(null, null);
}
private static void SetResolverBool(Type settingsType, string propertyName, bool value)
{
if (settingsType == null)
{
return;
}
var property = settingsType.GetProperty(
propertyName,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (property == null)
{
return;
}
property.SetValue(null, value, null);
}
private struct ResolverState
{
public bool EnableAutoResolution;
public bool AutoResolveOnBuild;
public bool PromptBeforeAutoResolution;
}
}
#endif

View File

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

View File

@@ -1,159 +0,0 @@
#if UNITY_EDITOR
using System.Collections.Generic;
using System.IO;
using Runtime.ADAggregator;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
public static class IAAAdDebugSampleCreator
{
private const string SampleRoot = "Assets/Samples/IAAAdDebugSample";
private const string SampleSceneDirectory = SampleRoot + "/Scenes";
private const string SampleConfigDirectory = SampleRoot + "/Configs";
private const string SampleScenePath = SampleSceneDirectory + "/IAAAdDebugSample.unity";
private const string SampleConfigPath = SampleConfigDirectory + "/IAAAdDebugSampleConfig.asset";
[MenuItem("Topon/Create IAA IMGUI Debug Sample")]
public static void CreateOrUpdateSample()
{
EnsureDirectory(SampleRoot);
EnsureDirectory(SampleSceneDirectory);
EnsureDirectory(SampleConfigDirectory);
var config = LoadOrCreateConfig();
CreateOrUpdateScene(config);
AppendSceneToBuildSettings(SampleScenePath);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
EditorUtility.DisplayDialog(
"IAA Sample Created",
$"Scene: {SampleScenePath}\nConfig: {SampleConfigPath}",
"OK");
}
public static void CreateOrUpdateSampleInBatchMode()
{
CreateOrUpdateSample();
EditorApplication.Exit(0);
}
private static ADConfig LoadOrCreateConfig()
{
var config = AssetDatabase.LoadAssetAtPath<ADConfig>(SampleConfigPath);
if (config == null)
{
config = ScriptableObject.CreateInstance<ADConfig>();
AssetDatabase.CreateAsset(config, SampleConfigPath);
}
config.ConfigName = "IAA Ad Debug Sample";
config.Id = string.IsNullOrWhiteSpace(config.Id) ? "fill_taku_app_id" : config.Id;
config.Key = string.IsNullOrWhiteSpace(config.Key) ? "fill_taku_app_key" : config.Key;
config.Key2 = string.IsNullOrWhiteSpace(config.Key2) ? string.Empty : config.Key2;
config.BaseAwardAdKeyValue = config.BaseAwardAdKeyValue ?? new AdKeyValue();
config.BaseAwardAdKeyValue.key = "rewarded";
config.BaseAwardAdKeyValue.value = string.IsNullOrWhiteSpace(config.BaseAwardAdKeyValue.value)
? "fill_rewarded_placement"
: config.BaseAwardAdKeyValue.value;
config.BaseInteractionAdKeyValue = config.BaseInteractionAdKeyValue ?? new AdKeyValue();
config.BaseInteractionAdKeyValue.key = "interstitial";
config.BaseInteractionAdKeyValue.value = string.IsNullOrWhiteSpace(config.BaseInteractionAdKeyValue.value)
? "fill_interstitial_placement"
: config.BaseInteractionAdKeyValue.value;
config.BaseSplashAdKeyValue = config.BaseSplashAdKeyValue ?? new AdKeyValue();
config.BaseSplashAdKeyValue.key = "splash";
config.BaseSplashAdKeyValue.value = string.IsNullOrWhiteSpace(config.BaseSplashAdKeyValue.value)
? "optional_splash_placement"
: config.BaseSplashAdKeyValue.value;
config.CommonKeyValues ??= new List<AdKeyValue>();
SetOrAddCommonKey(config, "topon.rewarded_auto_load", "true");
SetOrAddCommonKey(config, "topon.rewarded_prewarm_on_init", "true");
SetOrAddCommonKey(config, "topon.rewarded_max_load_attempts", "3");
SetOrAddCommonKey(config, "topon.rewarded_load_retry_delay_ms", "1000");
SetOrAddCommonKey(config, "topon.interstitial_auto_load", "true");
SetOrAddCommonKey(config, "topon.interstitial_prewarm_on_init", "true");
SetOrAddCommonKey(config, "topon.interstitial_max_load_attempts", "2");
SetOrAddCommonKey(config, "topon.interstitial_load_retry_delay_ms", "500");
EditorUtility.SetDirty(config);
return config;
}
private static void CreateOrUpdateScene(ADConfig config)
{
var scene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
scene.name = "IAAAdDebugSample";
var root = new GameObject("IAA Ad Debug Sample");
var gui = root.AddComponent<IAAAdDebugSampleGui>();
gui.adConfig = config;
gui.userId = "debug_user_001";
gui.rewardedScenario = "reward_debug";
gui.interstitialScenario = "interstitial_debug";
gui.autoInitialize = true;
gui.forcePortrait = true;
gui.captureUnityLogs = true;
gui.showVerboseState = true;
EditorSceneManager.SaveScene(scene, SampleScenePath);
}
private static void AppendSceneToBuildSettings(string scenePath)
{
var scenes = new List<EditorBuildSettingsScene>(EditorBuildSettings.scenes);
var exists = false;
for (var i = 0; i < scenes.Count; i++)
{
if (scenes[i].path != scenePath)
{
continue;
}
scenes[i] = new EditorBuildSettingsScene(scenePath, true);
exists = true;
break;
}
if (!exists)
{
scenes.Add(new EditorBuildSettingsScene(scenePath, true));
}
EditorBuildSettings.scenes = scenes.ToArray();
}
private static void SetOrAddCommonKey(ADConfig config, string key, string value)
{
foreach (var item in config.CommonKeyValues)
{
if (item != null && item.key == key)
{
item.value = value;
return;
}
}
config.CommonKeyValues.Add(new AdKeyValue
{
key = key,
value = value
});
}
private static void EnsureDirectory(string assetPath)
{
if (AssetDatabase.IsValidFolder(assetPath))
{
return;
}
Directory.CreateDirectory(Path.GetFullPath(assetPath));
AssetDatabase.Refresh();
}
}
#endif

View File

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

View File

@@ -1,78 +0,0 @@
#if UNITY_EDITOR
using System;
using System.IO;
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public static class IAABatchBuildBootstrap
{
private const string TaskFilePath = "Temp/iaa-batch-task.txt";
private static bool _subscribed;
private static bool _taskRunning;
static IAABatchBuildBootstrap()
{
if (!Application.isBatchMode)
{
return;
}
if (_subscribed)
{
return;
}
_subscribed = true;
EditorApplication.update += ExecutePendingTaskWhenReady;
}
private static void ExecutePendingTaskWhenReady()
{
if (!Application.isBatchMode || _taskRunning)
{
return;
}
var fullPath = Path.GetFullPath(TaskFilePath);
if (!File.Exists(fullPath))
{
return;
}
if (EditorApplication.isCompiling || EditorApplication.isUpdating)
{
return;
}
_taskRunning = true;
EditorApplication.update -= ExecutePendingTaskWhenReady;
var task = File.ReadAllText(fullPath).Trim();
File.Delete(fullPath);
try
{
switch (task)
{
case "create-sample":
IAAAdDebugSampleCreator.CreateOrUpdateSample();
break;
case "build-apk":
IAAAdAndroidBuild.BuildAndroidTestApk();
break;
default:
Debug.LogWarning($"[IAA Batch] Unknown task: {task}");
break;
}
EditorApplication.Exit(0);
}
catch (Exception exception)
{
Debug.LogException(exception);
EditorApplication.Exit(1);
}
}
}
#endif

View File

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

View File

@@ -12,6 +12,7 @@ public class AwardVideoPlayer : ADPlayer, ATRewardedVideoListener
private Action<bool> _onVideoComplete; private Action<bool> _onVideoComplete;
private ADListenerAggregator _aggregator; private ADListenerAggregator _aggregator;
private bool _autoLoadRegistered; private bool _autoLoadRegistered;
private bool _rewardGranted;
public override void OnInit() public override void OnInit()
{ {
@@ -28,6 +29,7 @@ public class AwardVideoPlayer : ADPlayer, ATRewardedVideoListener
} }
curState = 0; curState = 0;
_rewardGranted = false;
_onVideoComplete = onVideoComplete; _onVideoComplete = onVideoComplete;
adListener.onClose = onClose; adListener.onClose = onClose;
adListener.onVideoComplete = OnVideoComplete; adListener.onVideoComplete = OnVideoComplete;
@@ -117,6 +119,7 @@ public class AwardVideoPlayer : ADPlayer, ATRewardedVideoListener
public void onRewardedVideoAdPlayStart(string placementId, ATCallbackInfo callbackInfo) public void onRewardedVideoAdPlayStart(string placementId, ATCallbackInfo callbackInfo)
{ {
Debug.Log($"[Topon] Rewarded play start. placementId={placementId}"); Debug.Log($"[Topon] Rewarded play start. placementId={placementId}");
NotifyShowStarted();
} }
public void onRewardedVideoAdPlayEnd(string placementId, ATCallbackInfo callbackInfo) public void onRewardedVideoAdPlayEnd(string placementId, ATCallbackInfo callbackInfo)
@@ -134,7 +137,7 @@ public class AwardVideoPlayer : ADPlayer, ATRewardedVideoListener
public void onRewardedVideoAdPlayClosed(string placementId, bool isReward, ATCallbackInfo callbackInfo) public void onRewardedVideoAdPlayClosed(string placementId, bool isReward, ATCallbackInfo callbackInfo)
{ {
Debug.Log($"[Topon] Rewarded closed. placementId={placementId}, reward={isReward}"); Debug.Log($"[Topon] Rewarded closed. placementId={placementId}, reward={isReward}");
adListener.OnRewardVerify(isReward, 1, ""); adListener.OnRewardVerify(_rewardGranted || isReward, 1, "");
adListener.OnAdClose(); adListener.OnAdClose();
} }
@@ -146,8 +149,7 @@ public class AwardVideoPlayer : ADPlayer, ATRewardedVideoListener
public void onReward(string placementId, ATCallbackInfo callbackInfo) public void onReward(string placementId, ATCallbackInfo callbackInfo)
{ {
Debug.Log($"[Topon] Rewarded reward callback. placementId={placementId}"); Debug.Log($"[Topon] Rewarded reward callback. placementId={placementId}");
adListener.OnRewardVerify(true, 1, ""); _rewardGranted = true;
adListener.OnAdClose();
} }
public void startLoadingADSource(string placementId, ATCallbackInfo callbackInfo) public void startLoadingADSource(string placementId, ATCallbackInfo callbackInfo)
@@ -160,7 +162,6 @@ public class AwardVideoPlayer : ADPlayer, ATRewardedVideoListener
public void failToLoadADSource(string placementId, ATCallbackInfo callbackInfo, string code, string message) public void failToLoadADSource(string placementId, ATCallbackInfo callbackInfo, string code, string message)
{ {
OnError(code, message);
} }
public void startBiddingADSource(string placementId, ATCallbackInfo callbackInfo) public void startBiddingADSource(string placementId, ATCallbackInfo callbackInfo)

View File

@@ -114,6 +114,7 @@ public class InteractionPlayer : ADPlayer, ATInterstitialAdListener
public void onInterstitialAdShow(string placementId, ATCallbackInfo callbackInfo) public void onInterstitialAdShow(string placementId, ATCallbackInfo callbackInfo)
{ {
Debug.Log($"[Topon] Interstitial show. placementId={placementId}"); Debug.Log($"[Topon] Interstitial show. placementId={placementId}");
NotifyShowStarted();
} }
public void onInterstitialAdFailedToShow(string placementId) public void onInterstitialAdFailedToShow(string placementId)
@@ -160,7 +161,6 @@ public class InteractionPlayer : ADPlayer, ATInterstitialAdListener
public void failToLoadADSource(string placementId, ATCallbackInfo callbackInfo, string code, string message) public void failToLoadADSource(string placementId, ATCallbackInfo callbackInfo, string code, string message)
{ {
OnError(code, message);
} }
public void startBiddingADSource(string placementId, ATCallbackInfo callbackInfo) public void startBiddingADSource(string placementId, ATCallbackInfo callbackInfo)
@@ -173,7 +173,6 @@ public class InteractionPlayer : ADPlayer, ATInterstitialAdListener
public void failBiddingADSource(string placementId, ATCallbackInfo callbackInfo, string code, string message) public void failBiddingADSource(string placementId, ATCallbackInfo callbackInfo, string code, string message)
{ {
OnError(code, message);
} }
public override void OnPlayRequestStarted() public override void OnPlayRequestStarted()

View File

@@ -2,7 +2,7 @@
"name": "com.commercialization.topon", "name": "com.commercialization.topon",
"displayName": "Commercialization.topon", "displayName": "Commercialization.topon",
"description": "基于topon的广告sdk封装依赖基础商业化模块", "description": "基于topon的广告sdk封装依赖基础商业化模块",
"version": "1.4.8", "version": "1.4.9",
"unity": "2021.1", "unity": "2021.1",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
@@ -16,8 +16,15 @@
}, },
"dependencies": "dependencies":
{ {
"com.foldcc.cc-framework.commercialization" : "http://private.lightyears.ltd:18640/foldcc/CC-Framework.Commercialization.git#1.0.13" "com.foldcc.cc-framework.commercialization" : "http://private.lightyears.ltd:18640/foldcc/CC-Framework.Commercialization.git#1.0.14"
}, },
"samples": [
{
"displayName": "IAA Ad Debug Sample",
"description": "Optional debug scene and config for validating rewarded and interstitial flows.",
"path": "Samples~/IAAAdDebugSample"
}
],
"keywords": [ "keywords": [
"Framework" "Framework"
] ]