You've already forked Commercialization.topon
release: 1.4.2
This commit is contained in:
@@ -19,6 +19,18 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
public static string PLUGIN_VERSION = "2.1.7";
|
||||
public static bool isDebug = false;
|
||||
|
||||
public static bool EnableEditorTools
|
||||
{
|
||||
get
|
||||
{
|
||||
#if AnyThinkSDKEditor
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public static int PLUGIN_TYPE = 1;
|
||||
public static int OS_ANDROID = 1;
|
||||
public static int OS_IOS = 2;
|
||||
|
||||
@@ -42,6 +42,12 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
|
||||
public IEnumerator loadPluginData(Action<PluginData> callback)
|
||||
{
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
callback?.Invoke(null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
var anythinkVersionRequest = UnityWebRequest.Get(ATNetInfo.getPluginConfigUrl(ATConfig.PLUGIN_VERSION));
|
||||
var webRequest = anythinkVersionRequest.SendWebRequest();
|
||||
while (!webRequest.isDone)
|
||||
@@ -74,6 +80,11 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
|
||||
public IEnumerator loadNetworksData(PluginData pluginData, Action<PluginData> callback)
|
||||
{
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
callback?.Invoke(pluginData);
|
||||
yield break;
|
||||
}
|
||||
|
||||
Network network = pluginData.anyThink;
|
||||
if (pluginData == null)
|
||||
@@ -125,11 +136,22 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
/// <returns></returns>
|
||||
public void downloadPlugin(Network network, int os =1, bool showImport = false)
|
||||
{
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
ATLog.log("downloadPlugin() >>> AnyThinkSDKEditor disabled, skip remote download.");
|
||||
return;
|
||||
}
|
||||
|
||||
ATEditorCoroutine.startCoroutine(downloadPluginWithEnumerator(network, os, showImport));
|
||||
}
|
||||
|
||||
public IEnumerator downloadPluginWithEnumerator(Network network, int os, bool showImport)
|
||||
{
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
ATLog.log("downloadPluginWithEnumerator() >>> networkName: " + network.Name + " os: " + os);
|
||||
// if (downloadPluginRequest != null)
|
||||
// {
|
||||
@@ -190,6 +212,12 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
//默认下载core包,在下载完network的数据时。
|
||||
public void downloadCorePlugin(PluginData pluginData)
|
||||
{
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
ATLog.log("downloadCorePlugin() >>> AnyThinkSDKEditor disabled, skip remote download.");
|
||||
return;
|
||||
}
|
||||
|
||||
mPluginData = pluginData;
|
||||
var requestParams = pluginData.requestParams;
|
||||
var pluginSettingData = pluginData.pluginSettingData;
|
||||
@@ -278,6 +306,12 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
|
||||
public void networkInstallOrUpdate(PluginData pluginData, Network network, int os)
|
||||
{
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
ATLog.log("networkInstallOrUpdate() >>> AnyThinkSDKEditor disabled, skip remote download.");
|
||||
return;
|
||||
}
|
||||
|
||||
downloadPlugin(network, os);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,11 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
|
||||
public static void ShowManager()
|
||||
{
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var manager = GetWindow<ATIntegrationManagerWindow>(utility: true, title: windowTitle, focus: true);
|
||||
manager.minSize = windowMinSize;
|
||||
// manager.maxSize = windowMinSize;
|
||||
@@ -125,6 +130,11 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
warningIcon = new Texture2D(100, 100, TextureFormat.RGBA32, false);
|
||||
warningIcon.LoadImage(warningIconData);
|
||||
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
loadPluginData();
|
||||
//热更新
|
||||
ATIntegrationHotFix.Instance.loadHotFixData();
|
||||
@@ -158,6 +168,13 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.HelpBox("AnyThinkSDKEditor 未开启,SDK Manager 已禁用。需要维护 SDK 时请先添加 Scripting Define Symbol: AnyThinkSDKEditor。", MessageType.Info);
|
||||
return;
|
||||
}
|
||||
|
||||
// OnGUI is called on each frame draw, so we don't want to do any unnecessary calculation if we can avoid it. So only calculate it when the width actually changed.
|
||||
if (Math.Abs(previousWindowWidth - position.width) > 1)
|
||||
{
|
||||
@@ -242,6 +259,13 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
//获取插件和SDK的版本数据
|
||||
private void loadPluginData()
|
||||
{
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
pluginData = null;
|
||||
pluginDataLoadFailed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (loadDataCoroutine != null)
|
||||
{
|
||||
loadDataCoroutine.Stop();
|
||||
@@ -275,6 +299,11 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
//获取networks
|
||||
private void loadNetworksData(PluginData pluginData)
|
||||
{
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ATEditorCoroutine.startCoroutine(ATIntegrationManager.Instance.loadNetworksData(pluginData, data =>
|
||||
{
|
||||
pluginData = data;
|
||||
|
||||
@@ -26,12 +26,23 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
|
||||
public void loadHotFixData()
|
||||
{
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
ATLog.log("loadHotFixData() >>> AnyThinkSDKEditor disabled, skip hotfix check.");
|
||||
return;
|
||||
}
|
||||
|
||||
var downloadUrl = ATNetInfo.getHotfixPluginDownloadUrl(ATConfig.PLUGIN_VERSION);
|
||||
ATLog.log("loadHotFixData() >>> downloadUrl: " + downloadUrl);
|
||||
ATEditorCoroutine.startCoroutine(loadHotFixDataWithIEnumerator(downloadUrl));
|
||||
}
|
||||
|
||||
private IEnumerator loadHotFixDataWithIEnumerator(string url) {
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
var hotFixDataRequest = UnityWebRequest.Get(url);
|
||||
var webRequest = hotFixDataRequest.SendWebRequest();
|
||||
while (!webRequest.isDone)
|
||||
@@ -86,6 +97,11 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
}
|
||||
|
||||
private IEnumerator loadHotFixPlugin(HotfixPluginData hotFixDataObj) {
|
||||
if (!ATConfig.EnableEditorTools)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
var path = Path.Combine(Application.temporaryCachePath, hotFixDataObj.file_name);
|
||||
ATLog.log("downloadPluginWithEnumerator() >>> path: " + path);
|
||||
#if UNITY_2017_2_OR_NEWER
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
{
|
||||
public class AnyThinkMenuItems : MonoBehaviour
|
||||
{
|
||||
#if AnyThinkSDKEditor
|
||||
/**
|
||||
* The special characters at the end represent a shortcut for this action.
|
||||
*
|
||||
@@ -33,5 +34,6 @@ namespace AnyThink.Scripts.IntegrationManager.Editor
|
||||
// }
|
||||
Application.OpenURL("https://newdocs.toponad.com/docs/lgfbO4");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,16 @@ public class ADListenerAggregator
|
||||
client.onAdClickEvent += this.onRewardedVideoAdPlayClicked;
|
||||
client.onAdLoadEvent += this.onRewardedVideoAdLoaded;
|
||||
client.onAdLoadFailureEvent += this.onRewardedVideoAdLoadFail;
|
||||
client.onAdVideoStartEvent += this.onRewardedVideoAdPlayStart;
|
||||
client.onAdVideoEndEvent += this.onRewardedVideoAdPlayEnd;
|
||||
client.onAdVideoCloseEvent += this.onRewardedVideoAdPlayClosed;
|
||||
client.onAdVideoFailureEvent += this.onRewardedVideoAdPlayFail;
|
||||
client.onAdSourceAttemptEvent += this.startLoadingRewardedAdSource;
|
||||
client.onAdSourceFilledEvent += this.finishLoadingRewardedAdSource;
|
||||
client.onAdSourceLoadFailureEvent += this.failToLoadRewardedAdSource;
|
||||
client.onAdSourceBiddingAttemptEvent += this.startBiddingRewardedAdSource;
|
||||
client.onAdSourceBiddingFilledEvent += this.finishBiddingRewardedAdSource;
|
||||
client.onAdSourceBiddingFailureEvent += this.failBiddingRewardedAdSource;
|
||||
}
|
||||
|
||||
this._awardVideoListener = listener;
|
||||
@@ -62,6 +69,15 @@ public class ADListenerAggregator
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* The Ad play start (note: for Android, all callback methods are not in the main thread of Unity)
|
||||
*/
|
||||
void onRewardedVideoAdPlayStart(object sender, ATAdEventArgs callbackInfo)
|
||||
{
|
||||
ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdPlayStart(callbackInfo.placementId,
|
||||
callbackInfo.callbackInfo));
|
||||
}
|
||||
|
||||
/***
|
||||
* The Ad play end (note: for Android, all callback methods are not in the main thread of Unity)
|
||||
*/
|
||||
@@ -110,6 +126,42 @@ public class ADListenerAggregator
|
||||
callbackInfo.callbackInfo));
|
||||
}
|
||||
|
||||
void startLoadingRewardedAdSource(object sender, ATAdEventArgs callbackInfo)
|
||||
{
|
||||
ToponUnityThread.Post(() => this._awardVideoListener?.startLoadingADSource(callbackInfo.placementId,
|
||||
callbackInfo.callbackInfo));
|
||||
}
|
||||
|
||||
void finishLoadingRewardedAdSource(object sender, ATAdEventArgs callbackInfo)
|
||||
{
|
||||
ToponUnityThread.Post(() => this._awardVideoListener?.finishLoadingADSource(callbackInfo.placementId,
|
||||
callbackInfo.callbackInfo));
|
||||
}
|
||||
|
||||
void failToLoadRewardedAdSource(object sender, ATAdErrorEventArgs callbackInfo)
|
||||
{
|
||||
ToponUnityThread.Post(() => this._awardVideoListener?.failToLoadADSource(callbackInfo.placementId,
|
||||
callbackInfo.callbackInfo, callbackInfo.errorCode, callbackInfo.errorMessage));
|
||||
}
|
||||
|
||||
void startBiddingRewardedAdSource(object sender, ATAdEventArgs callbackInfo)
|
||||
{
|
||||
ToponUnityThread.Post(() => this._awardVideoListener?.startBiddingADSource(callbackInfo.placementId,
|
||||
callbackInfo.callbackInfo));
|
||||
}
|
||||
|
||||
void finishBiddingRewardedAdSource(object sender, ATAdEventArgs callbackInfo)
|
||||
{
|
||||
ToponUnityThread.Post(() => this._awardVideoListener?.finishBiddingADSource(callbackInfo.placementId,
|
||||
callbackInfo.callbackInfo));
|
||||
}
|
||||
|
||||
void failBiddingRewardedAdSource(object sender, ATAdErrorEventArgs callbackInfo)
|
||||
{
|
||||
ToponUnityThread.Post(() => this._awardVideoListener?.failBiddingADSource(callbackInfo.placementId,
|
||||
callbackInfo.callbackInfo, callbackInfo.errorCode, callbackInfo.errorMessage));
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 加载广告成功(注意:对于Android来说,所有回调方法均不在Unity的主线程)
|
||||
|
||||
@@ -103,6 +103,19 @@ public class ToponAdController : IAdController
|
||||
return;
|
||||
}
|
||||
|
||||
if (options.InitCustomMap != null && options.InitCustomMap.Count > 0)
|
||||
{
|
||||
ATSDKAPI.initCustomMap(options.InitCustomMap);
|
||||
}
|
||||
|
||||
var rewardedPlacementId = _adConfig?.BaseAwardAdKeyValue?.value;
|
||||
if (!string.IsNullOrWhiteSpace(rewardedPlacementId) &&
|
||||
options.RewardedCustomData != null &&
|
||||
options.RewardedCustomData.Count > 0)
|
||||
{
|
||||
ATSDKAPI.setCustomDataForPlacementID(options.RewardedCustomData, rewardedPlacementId);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(options.Channel))
|
||||
{
|
||||
ATSDKAPI.setChannel(options.Channel);
|
||||
|
||||
@@ -17,6 +17,8 @@ public sealed class ToponControllerOptions
|
||||
public const string ExcludeBundleIdsKey = "topon.exclude_bundle_ids";
|
||||
public const string RewardedExcludeAdSourceIdsKey = "topon.rewarded_exclude_ad_source_ids";
|
||||
public const string QueryAreaOnInitKey = "topon.query_area_on_init";
|
||||
public const string InitCustomMapKey = "topon.custom_map";
|
||||
public const string RewardedCustomDataKey = "topon.rewarded_custom_data";
|
||||
|
||||
public string Channel { get; set; }
|
||||
public string SubChannel { get; set; }
|
||||
@@ -28,6 +30,8 @@ public sealed class ToponControllerOptions
|
||||
public string[] ExcludeBundleIds { get; set; }
|
||||
public string[] RewardedExcludeAdSourceIds { get; set; }
|
||||
public bool QueryAreaOnInit { get; set; }
|
||||
public Dictionary<string, string> InitCustomMap { get; set; }
|
||||
public Dictionary<string, string> RewardedCustomData { get; set; }
|
||||
public Action<string> OnAreaReceived { get; set; }
|
||||
public Action<string> OnAreaError { get; set; }
|
||||
|
||||
@@ -87,6 +91,8 @@ public sealed class ToponControllerOptions
|
||||
ExcludeBundleIds = GetStringArray(map, ExcludeBundleIdsKey) ?? ExcludeBundleIds;
|
||||
RewardedExcludeAdSourceIds = GetStringArray(map, RewardedExcludeAdSourceIdsKey) ?? RewardedExcludeAdSourceIds;
|
||||
QueryAreaOnInit = GetBool(map, QueryAreaOnInitKey) ?? QueryAreaOnInit;
|
||||
InitCustomMap = MergeMaps(InitCustomMap, GetPrefixedMap(map, InitCustomMapKey + "."));
|
||||
RewardedCustomData = MergeMaps(RewardedCustomData, GetPrefixedMap(map, RewardedCustomDataKey + "."));
|
||||
}
|
||||
|
||||
private void ApplyLegacyArgs(object[] args)
|
||||
@@ -124,6 +130,8 @@ public sealed class ToponControllerOptions
|
||||
ExcludeBundleIds = explicitOptions.ExcludeBundleIds ?? ExcludeBundleIds;
|
||||
RewardedExcludeAdSourceIds = explicitOptions.RewardedExcludeAdSourceIds ?? RewardedExcludeAdSourceIds;
|
||||
QueryAreaOnInit = explicitOptions.QueryAreaOnInit || QueryAreaOnInit;
|
||||
InitCustomMap = MergeMaps(InitCustomMap, explicitOptions.InitCustomMap);
|
||||
RewardedCustomData = MergeMaps(RewardedCustomData, explicitOptions.RewardedCustomData);
|
||||
OnAreaReceived = explicitOptions.OnAreaReceived ?? OnAreaReceived;
|
||||
OnAreaError = explicitOptions.OnAreaError ?? OnAreaError;
|
||||
}
|
||||
@@ -143,7 +151,23 @@ public sealed class ToponControllerOptions
|
||||
continue;
|
||||
}
|
||||
|
||||
map[entry.Key.ToString()] = ConvertDictionaryValue(entry.Value);
|
||||
var key = entry.Key.ToString();
|
||||
if (entry.Value is IDictionary nestedDictionary)
|
||||
{
|
||||
if (string.Equals(key, InitCustomMapKey, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
InitCustomMap = MergeMaps(InitCustomMap, ToStringMap(nestedDictionary));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(key, RewardedCustomDataKey, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
RewardedCustomData = MergeMaps(RewardedCustomData, ToStringMap(nestedDictionary));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
map[key] = ConvertDictionaryValue(entry.Value);
|
||||
}
|
||||
|
||||
Channel = GetString(map, ChannelKey, "channel") ?? Channel;
|
||||
@@ -156,6 +180,8 @@ public sealed class ToponControllerOptions
|
||||
ExcludeBundleIds = GetStringArray(map, ExcludeBundleIdsKey) ?? ExcludeBundleIds;
|
||||
RewardedExcludeAdSourceIds = GetStringArray(map, RewardedExcludeAdSourceIdsKey) ?? RewardedExcludeAdSourceIds;
|
||||
QueryAreaOnInit = GetBool(map, QueryAreaOnInitKey) ?? QueryAreaOnInit;
|
||||
InitCustomMap = MergeMaps(InitCustomMap, GetPrefixedMap(map, InitCustomMapKey + "."));
|
||||
RewardedCustomData = MergeMaps(RewardedCustomData, GetPrefixedMap(map, RewardedCustomDataKey + "."));
|
||||
}
|
||||
|
||||
private static string GetString(IDictionary<string, string> map, params string[] keys)
|
||||
@@ -225,6 +251,54 @@ public sealed class ToponControllerOptions
|
||||
return items.Length > 0 ? items : null;
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> GetPrefixedMap(IDictionary<string, string> map, string prefix)
|
||||
{
|
||||
var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var pair in map)
|
||||
{
|
||||
if (!pair.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var nestedKey = pair.Key.Substring(prefix.Length).Trim();
|
||||
if (string.IsNullOrWhiteSpace(nestedKey) || string.IsNullOrWhiteSpace(pair.Value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result[nestedKey] = pair.Value.Trim();
|
||||
}
|
||||
|
||||
return result.Count > 0 ? result : null;
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> MergeMaps(
|
||||
Dictionary<string, string> current,
|
||||
Dictionary<string, string> incoming)
|
||||
{
|
||||
if (incoming == null || incoming.Count == 0)
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
var result = current != null
|
||||
? new Dictionary<string, string>(current, StringComparer.OrdinalIgnoreCase)
|
||||
: new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (var pair in incoming)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(pair.Key) || string.IsNullOrWhiteSpace(pair.Value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result[pair.Key] = pair.Value;
|
||||
}
|
||||
|
||||
return result.Count > 0 ? result : null;
|
||||
}
|
||||
|
||||
private static bool TryConvertBool(object value, out bool result)
|
||||
{
|
||||
switch (value)
|
||||
@@ -287,4 +361,27 @@ public sealed class ToponControllerOptions
|
||||
|
||||
return value.ToString();
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> ToStringMap(IDictionary dictionary)
|
||||
{
|
||||
var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (DictionaryEntry entry in dictionary)
|
||||
{
|
||||
if (entry.Key == null || entry.Value == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var key = entry.Key.ToString()?.Trim();
|
||||
var value = entry.Value.ToString()?.Trim();
|
||||
if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result[key] = value;
|
||||
}
|
||||
|
||||
return result.Count > 0 ? result : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "com.commercialization.topon",
|
||||
"displayName": "Commercialization.topon",
|
||||
"description": "基于topon的广告sdk封装,依赖基础商业化模块",
|
||||
"version": "1.4.1",
|
||||
"version": "1.4.2",
|
||||
"unity": "2021.1",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
69
README.md
69
README.md
@@ -185,9 +185,77 @@ EDM4U 依赖解析器,负责消费 `Dependencies.xml` 并拉取 Android/iOS
|
||||
|
||||
- `AwardVideoPlayer` 必须通过 `ADListenerAggregator.BindAwardVideoListener(...)` 绑定。
|
||||
- `InteractionPlayer` 必须通过 `ADListenerAggregator.BindInterstitialAdListener(...)` 绑定。
|
||||
- 奖励视频链路的旧 listener 回调必须继续完整桥接到 Unity 主线程,不能直接在 SDK 子线程里触发业务逻辑。
|
||||
|
||||
如果升级后官方再次调整回调模型,优先延续这层桥接,不要直接把抽象层改成强耦合官方回调。
|
||||
|
||||
### 5.4 `ToponAdController` 配置入口规范
|
||||
|
||||
`ToponAdController` 现在支持两类初始化输入:
|
||||
|
||||
1. 兼容旧参数:
|
||||
- `args[0]`:`channel`
|
||||
- `args[1]`:`debug`
|
||||
2. 推荐新参数:
|
||||
- 通过 `ADConfig.CommonKeyValues`
|
||||
- 或额外传入 `ToponControllerOptions`
|
||||
- 或额外传入 `IDictionary`
|
||||
|
||||
当前已支持的配置 key:
|
||||
|
||||
- `topon.channel`
|
||||
- `topon.sub_channel`
|
||||
- `topon.debug`
|
||||
- `topon.debugger_key`
|
||||
- `topon.sdk_area`
|
||||
- `topon.longitude`
|
||||
- `topon.latitude`
|
||||
- `topon.exclude_bundle_ids`
|
||||
- `topon.rewarded_exclude_ad_source_ids`
|
||||
- `topon.query_area_on_init`
|
||||
- `topon.custom_map.<name>`
|
||||
- `topon.rewarded_custom_data.<name>`
|
||||
|
||||
说明:
|
||||
|
||||
- `topon.exclude_bundle_ids`
|
||||
- 用于全局排除指定广告主 bundle id
|
||||
- `topon.rewarded_exclude_ad_source_ids`
|
||||
- 用于当前激励视频广告位排除指定广告源
|
||||
- `topon.query_area_on_init`
|
||||
- 初始化后主动查询 SDK 当前区域
|
||||
- 结果会回写到 `ToponAdController.LastDetectedArea`
|
||||
- `topon.custom_map.<name>`
|
||||
- 对应 `ATSDKAPI.initCustomMap(...)`
|
||||
- 注意先设置 custom map,再设置 channel/sub_channel
|
||||
- `topon.rewarded_custom_data.<name>`
|
||||
- 对应 `ATSDKAPI.setCustomDataForPlacementID(...)`
|
||||
- 当前默认应用到激励视频广告位
|
||||
|
||||
维护约束:
|
||||
|
||||
- 当前 IAA 业务主链路以激励视频为主,新功能配置优先围绕 `AwardVideo` 广告位设计。
|
||||
- 如果后续要补插屏、开屏、原生等广告位的同类配置,优先扩展 `ToponControllerOptions`,不要把 SDK 细节直接散落到业务层。
|
||||
|
||||
### 5.5 `AnyThinkSDKEditor` 编辑器开关规范
|
||||
|
||||
`AnyThinkPlugin/Script/IntegrationManager/Editor` 这套“SDK Manager / 远端版本检查 / hotfix 检查 / 远端 unitypackage 导入”能力,当前应视为维护工具,而不是业务项目默认能力。
|
||||
|
||||
当前约定:
|
||||
|
||||
- 只有在定义了 `AnyThinkSDKEditor` 宏时,才允许显示 `AnyThink` 菜单并启用联网检查。
|
||||
- 未定义 `AnyThinkSDKEditor` 时:
|
||||
- 不显示 `AnyThink/SDK Manager`
|
||||
- 不执行 SDK 版本拉取
|
||||
- 不执行 hotfix 检查
|
||||
- 不执行远端 unitypackage 下载与导入
|
||||
|
||||
这样做的目的:
|
||||
|
||||
- 避免业务项目通过包管理接入后,仍然保留官方集成管理器的远端更新入口。
|
||||
- 降低编辑器侧供应链风险。
|
||||
- 把 SDK 升级动作收敛到维护工程,而不是下游接入工程。
|
||||
|
||||
## 6. Android 构建期自定义规范
|
||||
|
||||
Android 的构建后处理分为两层:
|
||||
@@ -368,4 +436,3 @@ Android 的构建后处理分为两层:
|
||||
2. 动态路径定位不能回退成固定 `Assets/...` 读取。
|
||||
3. `Topon_Adapter` 对 core 抽象层的接口契约不能被官方 SDK 反向污染。
|
||||
4. Android/iOS 构建期补丁必须逐项保留并重新验证。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user