3 Commits
1.0.5 ... 1.0.8

7 changed files with 171 additions and 9 deletions

View File

@@ -1,3 +1,22 @@
# [1.0.8]
### 修复
* 修复 Editor 广告位诊断在编译期触发 `CS0165` 未赋值变量错误的问题。
# [1.0.7]
### 修复
* 接入 `CC-Framework.Commercialization` 的 Editor 诊断接口Unity Editor 模拟点击广告时也会输出 TapADN 当前解析出的广告位 ID。
# [1.0.6]
### 修复
* 兼容 `CommonKeyValues` 中直接使用业务场景名作为 key、SpaceId 作为 value 的激励视频广告位配置,避免只识别 `tapadn.rewarded_scene_slot.<scene_id>` 时回退到默认激励广告位。
* 激励视频进入场景、加载和播放请求会输出当前解析到的 SpaceId 及来源,便于 Editor Console 和样例调试面板确认实际使用的广告位。
# [1.0.5] # [1.0.5]
### 调整 ### 调整

View File

@@ -162,6 +162,7 @@ public sealed class TapadnIAAAdDebugSampleGui : MonoBehaviour
GUILayout.Label($"Last EventLog: {_lastEventLog}", _textStyle); GUILayout.Label($"Last EventLog: {_lastEventLog}", _textStyle);
GUILayout.Label($"Last SDK Version: {DisplayValue(TapadnAdController.LastSdkVersion)}", _textStyle); GUILayout.Label($"Last SDK Version: {DisplayValue(TapadnAdController.LastSdkVersion)}", _textStyle);
GUILayout.Label($"Last Init Error: {DisplayValue(TapadnAdController.LastInitError)}", _textStyle); GUILayout.Label($"Last Init Error: {DisplayValue(TapadnAdController.LastInitError)}", _textStyle);
GUILayout.Label($"Rewarded Selected SpaceId: {GetResolvedRewardedSlotForDisplay(rewardedScenario)}", _textStyle);
} }
else else
{ {
@@ -250,6 +251,7 @@ public sealed class TapadnIAAAdDebugSampleGui : MonoBehaviour
if (EnsureInitialized(label)) if (EnsureInitialized(label))
{ {
LogRewardedResolvedSlot(adType, scenario, "Enter scenario");
ADManager.Instance.EnterAdScenario(adType, scenario); ADManager.Instance.EnterAdScenario(adType, scenario);
AppendLog($"Enter scenario requested. type={adType}, scenario={scenario}"); AppendLog($"Enter scenario requested. type={adType}, scenario={scenario}");
} }
@@ -278,6 +280,7 @@ public sealed class TapadnIAAAdDebugSampleGui : MonoBehaviour
if (EnsureInitialized(label)) if (EnsureInitialized(label))
{ {
LogRewardedResolvedSlot(adType, scenario, "AsyncPlayAD");
ADManager.Instance.AsyncPlayAD(adType, scenario, result => ADManager.Instance.AsyncPlayAD(adType, scenario, result =>
{ {
AppendLog($"{adType} callback: {result}"); AppendLog($"{adType} callback: {result}");
@@ -424,6 +427,30 @@ public sealed class TapadnIAAAdDebugSampleGui : MonoBehaviour
} }
AppendLog($"Options => mediaId={options.MediaId}, channel={options.Channel}, sub={options.SubChannel}, debug={options.Debug}, rewardAuto={options.RewardedAutoLoad}, interAuto={options.InterstitialAutoLoad}, splashAuto={options.SplashAutoLoad}"); AppendLog($"Options => mediaId={options.MediaId}, channel={options.Channel}, sub={options.SubChannel}, debug={options.Debug}, rewardAuto={options.RewardedAutoLoad}, interAuto={options.InterstitialAutoLoad}, splashAuto={options.SplashAutoLoad}");
AppendLog($"Rewarded selected slot => {GetResolvedRewardedSlotForDisplay(rewardedScenario)}, configuredSceneSlots={options.RewardedSceneSlotIds?.Count ?? 0}");
}
private void LogRewardedResolvedSlot(AD_Type adType, string scenario, string actionName)
{
if (adType != AD_Type.AwardVideo)
{
return;
}
AppendLog($"{actionName} rewarded slot => {GetResolvedRewardedSlotForDisplay(scenario)}");
}
private string GetResolvedRewardedSlotForDisplay(string scenario)
{
var defaultSlotId = adConfig?.BaseAwardAdKeyValue?.value;
var options = TapadnAdController.CurrentOptions;
if (options == null)
{
return $"{DisplayValue(defaultSlotId)} (source=default, scenario={DisplayValue(scenario)})";
}
var slotId = options.ResolveRewardedSlotId(defaultSlotId, scenario, out var mapped);
return $"{DisplayValue(slotId)} (source={(mapped ? "scene" : "default")}, scenario={DisplayValue(scenario)})";
} }
private void OnRewardedBefore(string placementId, string scenario) private void OnRewardedBefore(string placementId, string scenario)

View File

@@ -3,7 +3,7 @@ using Dirichlet.Mediation;
using Runtime.ADAggregator; using Runtime.ADAggregator;
using UnityEngine; using UnityEngine;
public sealed class TapadnAdController : IAdController public sealed class TapadnAdController : IAdController, IAdEditorDiagnostics
{ {
public static TapadnControllerOptions CurrentOptions { get; private set; } public static TapadnControllerOptions CurrentOptions { get; private set; }
public static string LastSdkVersion { get; private set; } public static string LastSdkVersion { get; private set; }
@@ -73,4 +73,41 @@ public sealed class TapadnAdController : IAdController
{ {
_maskAction?.Invoke(isOpen); _maskAction?.Invoke(isOpen);
} }
public void LogEditorAdPlacement(ADConfig adConfig, AD_Type adType, string adScene, string action, object[] args)
{
var options = TapadnControllerOptions.Resolve(adConfig, args);
var normalizedScene = string.IsNullOrWhiteSpace(adScene) ? "__default__" : adScene.Trim();
var slotSource = "default";
var slotId = ResolveEditorSlotId(adConfig, options, adType, normalizedScene, out slotSource);
Debug.Log($"[TapADN] Editor ad {action}. type={adType}, scene={normalizedScene}, slot={DisplayEditorValue(slotId)}, source={slotSource}");
}
private static string ResolveEditorSlotId(ADConfig adConfig, TapadnControllerOptions options, AD_Type adType, string adScene, out string slotSource)
{
slotSource = "default";
switch (adType)
{
case AD_Type.AwardVideo:
var defaultRewardedSlotId = adConfig?.BaseAwardAdKeyValue?.value;
var mapped = false;
var rewardedSlotId = options == null
? defaultRewardedSlotId
: options.ResolveRewardedSlotId(defaultRewardedSlotId, adScene, out mapped);
slotSource = mapped ? "scene" : "default";
return rewardedSlotId;
case AD_Type.Interaction:
return adConfig?.BaseInteractionAdKeyValue?.value;
case AD_Type.Splash:
return adConfig?.BaseSplashAdKeyValue?.value;
default:
slotSource = "unsupported";
return null;
}
}
private static string DisplayEditorValue(string value)
{
return string.IsNullOrWhiteSpace(value) ? "<empty>" : value.Trim();
}
} }

View File

@@ -62,7 +62,8 @@ public sealed class TapadnAwardVideoPlayer : ADPlayer, IDirichletRewardVideoAuto
public override void LoadAD() public override void LoadAD()
{ {
var slotId = ResolveCurrentSlotId(); var slotId = ResolveCurrentSlotId(out var mapped);
Debug.Log($"[TapADN] Rewarded load requested. scene={NormalizeScenario(AdScene)}, slot={slotId}, source={GetSlotSource(mapped)}, auto={UseAutoLoad()}");
if (!TapadnAdRequestFactory.TryParseSlotId(slotId, out _)) if (!TapadnAdRequestFactory.TryParseSlotId(slotId, out _))
{ {
Debug.LogError($"[TapADN] Invalid rewarded slot id: {slotId}"); Debug.LogError($"[TapADN] Invalid rewarded slot id: {slotId}");
@@ -128,9 +129,10 @@ public sealed class TapadnAwardVideoPlayer : ADPlayer, IDirichletRewardVideoAuto
_showSettled = false; _showSettled = false;
_rewardCloseSettleHandler?.Kill(); _rewardCloseSettleHandler?.Kill();
_rewardCloseSettleHandler = null; _rewardCloseSettleHandler = null;
_activeSlotId = ResolveCurrentSlotId(); _activeSlotId = ResolveCurrentSlotId(out var mapped);
Key = _activeSlotId; Key = _activeSlotId;
curState = 0; curState = 0;
Debug.Log($"[TapADN] Rewarded show requested. scene={NormalizeScenario(AdScene)}, slot={_activeSlotId}, source={GetSlotSource(mapped)}, auto={UseAutoLoad()}");
if (UseAutoLoad()) if (UseAutoLoad())
{ {
@@ -203,25 +205,43 @@ public sealed class TapadnAwardVideoPlayer : ADPlayer, IDirichletRewardVideoAuto
public override void OnPlayRequestStarted() public override void OnPlayRequestStarted()
{ {
var slotId = ResolveCurrentSlotId(); var slotId = ResolveCurrentSlotId(out var mapped);
Key = slotId; Key = slotId;
Debug.Log($"[TapADN] Rewarded play request. scene={NormalizeScenario(AdScene)}, slot={slotId}, source={GetSlotSource(mapped)}, auto={UseAutoLoad()}");
TapadnSmartLoadOrchestrator.OnPlayRequestStarted(AD_Type.AwardVideo, AdScene, !UseAutoLoad() && IsReadly(), slotId); TapadnSmartLoadOrchestrator.OnPlayRequestStarted(AD_Type.AwardVideo, AdScene, !UseAutoLoad() && IsReadly(), slotId);
} }
public override void EnterAdScenario(string scenario) public override void EnterAdScenario(string scenario)
{ {
AdScene = NormalizeScenario(scenario); AdScene = NormalizeScenario(scenario);
var slotId = ResolveCurrentSlotId(); var slotId = ResolveCurrentSlotId(out var mapped);
Key = slotId; Key = slotId;
Debug.Log($"[TapADN] Rewarded enter scene. scene={AdScene}, slot={slotId}, source={GetSlotSource(mapped)}");
TapadnSmartLoadOrchestrator.OnEnterAdScenario(AD_Type.AwardVideo, AdScene, slotId); TapadnSmartLoadOrchestrator.OnEnterAdScenario(AD_Type.AwardVideo, AdScene, slotId);
} }
private string ResolveCurrentSlotId() private string ResolveCurrentSlotId()
{ {
var slotId = TapadnAdController.CurrentOptions?.ResolveRewardedSlotId(_defaultSlotId, AdScene) ?? _defaultSlotId; return ResolveCurrentSlotId(out _);
}
private string ResolveCurrentSlotId(out bool mapped)
{
if (TapadnAdController.CurrentOptions == null)
{
mapped = false;
return string.IsNullOrWhiteSpace(_defaultSlotId) ? _defaultSlotId : _defaultSlotId.Trim();
}
var slotId = TapadnAdController.CurrentOptions.ResolveRewardedSlotId(_defaultSlotId, AdScene, out mapped);
return string.IsNullOrWhiteSpace(slotId) ? _defaultSlotId : slotId.Trim(); return string.IsNullOrWhiteSpace(slotId) ? _defaultSlotId : slotId.Trim();
} }
private static string GetSlotSource(bool mapped)
{
return mapped ? "scene" : "default";
}
private bool UseAutoLoad() private bool UseAutoLoad()
{ {
return TapadnAdController.CurrentOptions?.RewardedAutoLoad ?? true; return TapadnAdController.CurrentOptions?.RewardedAutoLoad ?? true;

View File

@@ -9,6 +9,8 @@ using UnityEngine;
public sealed class TapadnControllerOptions public sealed class TapadnControllerOptions
{ {
private const string TapadnKeyPrefix = "tapadn.";
public const string MediaNameKey = "tapadn.media_name"; public const string MediaNameKey = "tapadn.media_name";
public const string MediaIdKey = "tapadn.media_id"; public const string MediaIdKey = "tapadn.media_id";
public const string MediaKeyKey = "tapadn.media_key"; public const string MediaKeyKey = "tapadn.media_key";
@@ -300,20 +302,29 @@ public sealed class TapadnControllerOptions
} }
public string ResolveRewardedSlotId(string defaultSlotId, string scenario) public string ResolveRewardedSlotId(string defaultSlotId, string scenario)
{
return ResolveRewardedSlotId(defaultSlotId, scenario, out _);
}
public string ResolveRewardedSlotId(string defaultSlotId, string scenario, out bool mapped)
{ {
var normalizedScenario = NormalizeScenario(scenario); var normalizedScenario = NormalizeScenario(scenario);
if (RewardedSceneSlotIds != null && if (RewardedSceneSlotIds != null &&
RewardedSceneSlotIds.TryGetValue(normalizedScenario, out var mappedSlotId) && RewardedSceneSlotIds.TryGetValue(normalizedScenario, out var mappedSlotId) &&
TapadnAdRequestFactory.TryParseSlotId(mappedSlotId, out _)) TapadnAdRequestFactory.TryParseSlotId(mappedSlotId, out _))
{ {
mapped = true;
return mappedSlotId; return mappedSlotId;
} }
mapped = false;
return defaultSlotId; return defaultSlotId;
} }
private void ApplyRewardedSceneSlots(IDictionary<string, string> map) private void ApplyRewardedSceneSlots(IDictionary<string, string> map)
{ {
ApplyLegacyRewardedSceneSlots(map);
foreach (var entry in map) foreach (var entry in map)
{ {
if (entry.Key == null || !entry.Key.StartsWith(RewardedSceneSlotPrefix, StringComparison.OrdinalIgnoreCase)) if (entry.Key == null || !entry.Key.StartsWith(RewardedSceneSlotPrefix, StringComparison.OrdinalIgnoreCase))
@@ -329,6 +340,19 @@ public sealed class TapadnControllerOptions
ParseSceneSlotJson(GetString(map, RewardedSceneSlotsJsonKey), AddRewardedSceneSlot); ParseSceneSlotJson(GetString(map, RewardedSceneSlotsJsonKey), AddRewardedSceneSlot);
} }
private void ApplyLegacyRewardedSceneSlots(IDictionary<string, string> map)
{
foreach (var entry in map)
{
if (!IsLegacyRewardedSceneSlotEntry(entry.Key, entry.Value))
{
continue;
}
AddRewardedSceneSlot(entry.Key, entry.Value);
}
}
private void AddRewardedSceneSlot(string scene, string slotId) private void AddRewardedSceneSlot(string scene, string slotId)
{ {
scene = NormalizeScenario(scene); scene = NormalizeScenario(scene);
@@ -341,6 +365,30 @@ public sealed class TapadnControllerOptions
RewardedSceneSlotIds[scene] = slotId.Trim(); RewardedSceneSlotIds[scene] = slotId.Trim();
} }
private static bool IsLegacyRewardedSceneSlotEntry(string key, string value)
{
var normalizedKey = key?.Trim();
if (string.IsNullOrWhiteSpace(normalizedKey) ||
string.IsNullOrWhiteSpace(value) ||
normalizedKey.StartsWith(TapadnKeyPrefix, StringComparison.OrdinalIgnoreCase))
{
return false;
}
switch (normalizedKey.ToLowerInvariant())
{
case "media_id":
case "media_name":
case "media_key":
case "channel":
case "sub_channel":
case "debug":
return false;
}
return TapadnAdRequestFactory.TryParseSlotId(value.Trim(), out _);
}
private static void ParseSceneSlotPairs(string value, Action<string, string> add) private static void ParseSceneSlotPairs(string value, Action<string, string> add)
{ {
if (string.IsNullOrWhiteSpace(value) || add == null) if (string.IsNullOrWhiteSpace(value) || add == null)

View File

@@ -2,7 +2,7 @@
"name": "com.commercialization.tapadn", "name": "com.commercialization.tapadn",
"displayName": "Commercialization.tapadn", "displayName": "Commercialization.tapadn",
"description": "TapADN / Dirichlet mediation implementation for CC-Framework.Commercialization.", "description": "TapADN / Dirichlet mediation implementation for CC-Framework.Commercialization.",
"version": "1.0.5", "version": "1.0.8",
"unity": "2022.3", "unity": "2022.3",
"license": "MIT", "license": "MIT",
"repository": { "repository": {
@@ -15,7 +15,7 @@
"url": "https://gitee.com/foldcc" "url": "https://gitee.com/foldcc"
}, },
"dependencies": { "dependencies": {
"com.foldcc.cc-framework.commercialization": "http://private.lightyears.ltd:18650/foldcc/CC-Framework.Commercialization.git#1.0.15" "com.foldcc.cc-framework.commercialization": "http://private.lightyears.ltd:18650/foldcc/CC-Framework.Commercialization.git#1.0.16"
}, },
"samples": [ "samples": [
{ {

View File

@@ -100,9 +100,10 @@ ADManager.Instance.Init(callback, userId, adConfig, new TapadnAdController());
激励视频支持按游戏场景路由不同 TapADN SpaceId。项目层继续调用 `ADManager.EnterAdScenario(AD_Type.AwardVideo, sceneId)``ADManager.AsyncPlayAD(AD_Type.AwardVideo, sceneId, callback)`TapADN adapter 会按 `sceneId` 查表: 激励视频支持按游戏场景路由不同 TapADN SpaceId。项目层继续调用 `ADManager.EnterAdScenario(AD_Type.AwardVideo, sceneId)``ADManager.AsyncPlayAD(AD_Type.AwardVideo, sceneId, callback)`TapADN adapter 会按 `sceneId` 查表:
* 命中 `tapadn.rewarded_scene_slot.<scene_id>` 或批量配置时,使用该场景 SpaceId。 * 命中 `tapadn.rewarded_scene_slot.<scene_id>`、批量配置,或 `CommonKeyValues``scene_id=SpaceId` 的兼容配置时,使用该场景 SpaceId。
* 未传场景、场景为空、场景未配置、配置的 SpaceId 非法时,回退到 `BaseAwardAdKeyValue.value` 默认激励视频广告位。 * 未传场景、场景为空、场景未配置、配置的 SpaceId 非法时,回退到 `BaseAwardAdKeyValue.value` 默认激励视频广告位。
* 手动 load/show 模式下,缓存按 SpaceId 隔离A 场景加载的激励视频不会被 B 场景误认为 ready。 * 手动 load/show 模式下,缓存按 SpaceId 隔离A 场景加载的激励视频不会被 B 场景误认为 ready。
* Editor/样例调试时,进入场景、加载和播放请求会在 Console 输出当前解析到的 SpaceId 及来源,格式类似 `slot=200101, source=scene`
单项配置示例: 单项配置示例:
@@ -114,6 +115,16 @@ adConfig.CommonKeyValues.Add(new AdKeyValue
}); });
``` ```
兼容已有业务配置示例:
```csharp
adConfig.CommonKeyValues.Add(new AdKeyValue
{
key = "PlantUnlock",
value = "200101"
});
```
批量字符串配置示例: 批量字符串配置示例:
```csharp ```csharp