using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using TapSDK.UI;
using TapTap.AntiAddiction.Internal;
using TapTap.AntiAddiction.Model;
using TapTap.Common;
using UnityEngine;
using Network = TapTap.AntiAddiction.Internal.Network;
namespace TapTap.AntiAddiction
{
public abstract class BaseAntiAddictionWorker
{
protected AntiAddictionConfig config => TapTapAntiAddictionManager.AntiAddictionConfig;
#region Abstract
public abstract Region Region { get; }
///
/// 传送身份验证等敏感信息时的key
///
///
///
internal abstract string RsaPublicKey { get; }
///
/// 完成身份验证窗口
///
///
protected abstract Task CompleteVerificationWindowAsync();
///
/// 检查未成年人可玩性
///
///
protected abstract PlayableResult CheckOfflineMinorPlayable();
///
/// 是否激活单机模式
///
///
internal abstract Task IsStandaloneEnabled();
#endregion
#region Virutal
///
/// 检查可玩性后,已知成年人时的处理
///
///
protected virtual void OnCheckedPlayableWithAdult(PlayableResult playable)
{
TryStartPoll();
}
///
/// 检查可玩性后,已知未成年人时的处理
///
///
///
protected virtual async Task OnCheckedPlayableWithMinorAsync(PlayableResult playable)
{
var tcs = new TaskCompletionSource();
Action onOk;
if (playable.CanPlay)
{
onOk = () =>
{
tcs.TrySetResult(StartUpResult.LOGIN_SUCCESS);
TryStartPoll();
};
}
else
{
tcs.TrySetResult(StartUpResult.PERIOD_RESTRICT);
onOk = () =>
{
Application.Quit();
};
}
Action onSwitchAccount = null;
if (config.showSwitchAccount)
{
onSwitchAccount = () =>
{
Logout();
AntiAddictionUIKit.ExternalCallback?.Invoke(StartUpResult.SWITCH_ACCOUNT, null);
};
}
TapTapAntiAddictionUIKit.OpenHealthReminderPanel(playable, onOk, onSwitchAccount);
return await tcs.Task;
}
///
/// 检查可玩性,如果出现异常就会用本地的计算方式
///
///
protected virtual async Task CheckPlayableAsyncWithFallback()
{
try
{
var playableResult = await CheckPlayableAsync();
return playableResult;
}
catch (AntiAddictionException e)
{
if (e.Code == 401)
{
throw;
}
return CheckOfflinePlayable();
}
catch (Exception e)
{
TapLogger.Error(e);
// 单机判断是否可玩
return CheckOfflinePlayable();
}
}
///
/// 检查可玩性
///
/// 当内部发生错误的时候,是否抛出异常.默认不抛出异常,就会按照本地规则计算playable
///
protected virtual async Task CheckPlayableAsync()
{
try
{
if (!Config.NeedUploadUserAction) return CheckOfflinePlayable();
var playableResult = await Network.CheckPlayable();
return playableResult;
}
catch (Exception e)
{
TapLogger.Error(e);
throw;
}
}
///
/// 本地判断可玩性
///
///
protected virtual PlayableResult CheckOfflinePlayable()
{
// 成年人
if (Verification.IsAdult)
{
// 可玩
return new PlayableResult
{
RestrictType = PlayableResult.ADULT,
CanPlay = true,
};
}
return CheckOfflineMinorPlayable();
}
///
/// 是否需要开启轮询检查可玩性
///
///
protected virtual bool IsNeedStartPoll()
{
return !Verification.IsAdult || Config.NeedUploadUserAction;
}
///
/// 轮询时,检查可玩性判断
///
///
internal virtual async Task CheckPlayableOnPollingAsync()
{
try
{
var playable = await CheckPlayableAsyncWithFallback();
if (!playable.CanPlay)
{
OnUnplayablePostPoll(playable);
}
return playable;
}
catch (AntiAddictionException e)
{
if (e.Code == 401) {
// TapTapAntiAddictionManager.Logout();
}
return CheckOfflinePlayable();
}
}
///
/// 轮询时,发现不可玩处理
///
///
protected virtual void OnUnplayablePostPoll(PlayableResult playable)
{
Action onExitGame = Application.Quit;
Action onSwitch = null;
if (config.showSwitchAccount)
{
onSwitch = () => {
Logout();
AntiAddictionUIKit.ExternalCallback?.Invoke(StartUpResult.SWITCH_ACCOUNT, null);
};
}
TapTapAntiAddictionUIKit.OpenHealthReminderPanel(playable, onExitGame, onSwitch);
AntiAddictionUIKit.ExternalCallback?.Invoke(StartUpResult.PERIOD_RESTRICT, null);
}
///
/// 通过检查,发现不可支付时的处理
///
///
protected virtual void OnCheckedUnpayable(PayableResult payable)
{
TapTapAntiAddictionUIKit.OpenHealthPaymentPanel(payable);
}
///
/// 获得配置后的处理
///
internal virtual void OnConfigFetched()
{
Config.OnFetched();
}
///
/// 登出处理
///
internal virtual void Logout()
{
Verification.Logout();
AntiAddictionPoll.Logout();
TapTapAntiAddictionManager.UserId = null;
}
#endregion
#region Internal
///
/// 获得实名信息
///
internal async Task FetchVerificationAsync()
{
var userId = TapTapAntiAddictionManager.UserId;
// 拉取服务端实名信息
do
{
try
{
await Verification.Fetch(userId);
UIManager.Instance.CloseLoading();
break;
}
catch (HttpRequestException e)
{
TapLogger.Error(e);
UIManager.Instance.CloseLoading();
// 网络异常,则提示重新查询
await TapTapAntiAddictionUIKit.ShowRetryDialog(TapTapAntiAddictionManager.LocalizationItems.Current.NetError);
UIManager.Instance.OpenLoading();
}
catch (Exception e)
{
TapLogger.Error(e);
UIManager.Instance.CloseLoading();
var aae = e as AntiAddictionException;
if (aae != null && aae.code == (int)HttpStatusCode.Unauthorized)
{
await TapTapAntiAddictionUIKit.ShowRetryDialog(TapTapAntiAddictionManager.LocalizationItems.Current.NoVerification);
}
else if (aae != null && aae.code >= (int)HttpStatusCode.InternalServerError)
{
await TapTapAntiAddictionUIKit.ShowRetryDialog(TapTapAntiAddictionManager.LocalizationItems.Current.NoVerification);
}
else if (e.Message.Contains("Interval server error."))
{
await TapTapAntiAddictionUIKit.ShowRetryDialog(TapTapAntiAddictionManager.LocalizationItems.Current.NoVerification);
}
else
{
await TapTapAntiAddictionUIKit.ShowRetryDialog(TapTapAntiAddictionManager.LocalizationItems.Current.NetError);
}
UIManager.Instance.OpenLoading();
}
}
while (true);
}
///
/// 获得实名信息后的处理
///
///
internal async Task OnVerificationFetched()
{
// 1. 如果没验证过,需要弹出验证窗口,并完成验证----------------------
if (!Verification.IsVerified)
{
var result = await CompleteVerificationWindowAsync();
if (result != 0)
return result;
}
// 2. 检查可玩性
return await ProcessPlayableAsync();
}
///
/// 检查可玩性
///
///
private async Task ProcessPlayableAsync()
{
int tryCount = 0;
do
{
try
{
tryCount++;
PlayableResult playable = await CheckPlayableAsyncWithFallback();
TapTapAntiAddictionManager.CurrentPlayableResult = playable;
// 2.1 成年人-后处理
if (playable.IsAdult)
{
OnCheckedPlayableWithAdult(playable);
return StartUpResult.LOGIN_SUCCESS;
}
// 2.2 未成年人-后处理
else
{
return await OnCheckedPlayableWithMinorAsync(playable);
}
}
catch (Exception e)
{
var aae = e as AntiAddictionException;
if (aae.Code == 401)
{
return StartUpResult.INTERNAL_ERROR;
}
if (Verification.IsVerified)
{
if (!Verification.IsAdult)
await TapTapAntiAddictionUIKit.ShowRetryDialog(TapTapAntiAddictionManager.LocalizationItems.Current.NetError);
else if (tryCount >= 3)
{
var playableResult = new PlayableResult
{
RestrictType = PlayableResult.ADULT,
CanPlay = true,
};
TapTapAntiAddictionManager.CurrentPlayableResult = playableResult;
OnCheckedPlayableWithAdult(playableResult);
return StartUpResult.LOGIN_SUCCESS;
}
}
}
}while (true);
}
///
/// 尝试开启轮询检查
///
protected void TryStartPoll()
{
if (IsNeedStartPoll())
{
AntiAddictionPoll.StartUp();
}
}
///
/// 检查是否可以支付
///
///
///
internal async virtual Task CheckPayableAsync(long amount)
{
PayableResult payable = await Network.CheckPayable(amount);
if (!payable.Status)
{
OnCheckedUnpayable(payable);
}
return payable;
}
///
/// 提交充值结果
///
///
///
internal virtual Task SubmitPayResult(long amount)
{
return Network.SubmitPayment(amount);
}
///
/// 获取配置
///
internal async Task FetchConfigAsync()
{
await Config.Fetch();
}
#endregion
}
}