광고 추가 보상 서버 시청 검증 · 사용자 퀘스트 승인 후 공개 · TIME ATTACK 모드 · 만보기 퀘스트 · 위치 퀘스트 지도 선택 · 운영 퀘스트 보상 재원
This commit is contained in:
@@ -35,7 +35,13 @@ abstract interface class RewardedAdHandle {
|
||||
///
|
||||
/// 불러오지 못하면(채울 광고 없음 · 네트워크 · 시간 초과) `E-AD-01` 로 끊는다 —
|
||||
/// 원장 B-03 「광고 로드 실패 시 기본 보상은 지급하고 추가 보상·횟수는 차감하지 않음」.
|
||||
///
|
||||
/// [userId] · [customData] 는 **서버측 시청 검증(AdMob SSV)** 에 실린다 — Google 이 시청 완료를
|
||||
/// 서버(`fn-ad-ssv`)로 직접 알릴 때 이 두 값이 「누가 · 어느 기본 보상(txId)에 붙여」 본 광고인지
|
||||
/// 가리킨다. 서버는 그 기록이 있어야만 증분을 지급한다(앱의 보상 콜백은 근거가 아니다).
|
||||
Future<RewardedAdHandle> loadGoogleRewardedAd({
|
||||
required String userId,
|
||||
required String customData,
|
||||
Duration timeout = const Duration(seconds: 15),
|
||||
}) async {
|
||||
await (_initialized ??= MobileAds.instance.initialize());
|
||||
@@ -49,7 +55,11 @@ Future<RewardedAdHandle> loadGoogleRewardedAd({
|
||||
),
|
||||
);
|
||||
try {
|
||||
return _GoogleRewardedAd(await loaded.future.timeout(timeout));
|
||||
final ad = await loaded.future.timeout(timeout);
|
||||
await ad.setServerSideOptions(
|
||||
ServerSideVerificationOptions(userId: userId, customData: customData),
|
||||
);
|
||||
return _GoogleRewardedAd(ad);
|
||||
} catch (_) {
|
||||
// 시간 초과 뒤에 늦게 도착한 광고는 띄우지 않고 버린다.
|
||||
unawaited(loaded.future.then((ad) => ad.dispose(), onError: (_) {}));
|
||||
@@ -75,7 +85,7 @@ class _GoogleRewardedAd implements RewardedAdHandle {
|
||||
try {
|
||||
await _ad.show(
|
||||
onUserEarnedReward: (_, _) {
|
||||
// 서버가 이 값으로 같은 노출의 이중 지급을 막는다(`adRewardLogs/{id}`).
|
||||
// 화면 분기용(끝까지 봤는가)일 뿐 지급 근거가 아니다 — 근거는 SSV 콜백이다.
|
||||
impression = _ad.responseInfo?.responseId ??
|
||||
'gma-${DateTime.now().microsecondsSinceEpoch}';
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user