h
This commit is contained in:
@@ -0,0 +1,748 @@
|
||||
// SDK Production Version - Uses hardcoded configuration
|
||||
// Designed to work with index.html
|
||||
|
||||
// Production configuration
|
||||
const installProviders = [
|
||||
"adinplay",
|
||||
"cpmstar",
|
||||
"local"
|
||||
];
|
||||
|
||||
const videoAdPriorities = [
|
||||
"cpmstar",
|
||||
"adinplay"
|
||||
];
|
||||
|
||||
const bannerAdPriorities = [
|
||||
"adinplay",
|
||||
"cpmstar",
|
||||
"local"
|
||||
];
|
||||
|
||||
// Global configuration
|
||||
const DEBUG_MODE = window.location.href.includes('test');
|
||||
const IS_MOBILE = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
||||
const MIN_REFRESH_INTERVAL = 24_000; // Minimum showtime before refresh
|
||||
const BANNER_DEBOUNCE_TIME = 100;
|
||||
const MAX_AIPTAG_WAIT_TIME = 1800;
|
||||
const SHOWTIME_CHECK_INTERVAL = 1000; // Check showtime every 1.6 seconds
|
||||
|
||||
// Banner position names for logging
|
||||
const POSITION_NAMES = {
|
||||
0: 'Hidden', 1: 'TopCenter', 2: 'TopRight', 3: 'TopLeft',
|
||||
4: 'BottomCenter', 5: 'BottomRight', 6: 'BottomLeft',
|
||||
7: 'MiddleCenter', 8: 'MiddleLeft', 9: 'MiddleRight',
|
||||
10: 'BelowTopLeft', 11: 'BelowTopRight'
|
||||
};
|
||||
|
||||
// Banner mappings and dimensions
|
||||
window.bannerMapping = {
|
||||
0: '300x250',
|
||||
1: '728x90',
|
||||
2: '300x600'
|
||||
};
|
||||
|
||||
window.bannerDimensions = {
|
||||
0: {
|
||||
width: '300px', height: '250px',
|
||||
scale: 1.3,
|
||||
enableForMobile: true,
|
||||
ratioBoostStops: [
|
||||
{ ratio: 1.0, boost: 1.8 },
|
||||
{ ratio: 1.62, boost: 1.2 },
|
||||
{ ratio: 1.78, boost: 1.1 }
|
||||
]
|
||||
},
|
||||
1: {
|
||||
width: '728px', height: '90px',
|
||||
scale: 1.19,
|
||||
enableForMobile: false,
|
||||
ratioBoostStops: [
|
||||
{ ratio: 0, boost: 1.0 },
|
||||
{ ratio: Infinity, boost: 1.0 }
|
||||
]
|
||||
},
|
||||
2: {
|
||||
width: '300px', height: '600px',
|
||||
scale: 1.06,
|
||||
enableForMobile: false,
|
||||
ratioBoostStops: [
|
||||
{ ratio: 1.0, boost: 1.9 },
|
||||
{ ratio: 1.62, boost: 1.15 },
|
||||
{ ratio: 1.78, boost: 1.0 }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// Sort ratioBoostStops
|
||||
Object.keys(window.bannerDimensions).forEach(key => {
|
||||
window.bannerDimensions[key].ratioBoostStops.sort((a, b) => a.ratio - b.ratio);
|
||||
});
|
||||
|
||||
// Helper functions
|
||||
function debounce(func, wait) {
|
||||
let timeout;
|
||||
return function (...args) {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => func.apply(this, args), wait);
|
||||
};
|
||||
}
|
||||
|
||||
// Create promise for AdinPlay availability
|
||||
window.waitForAdinPlay = function () {
|
||||
return new Promise((resolve) => {
|
||||
if (typeof aipDisplayTag !== "undefined") {
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const timeoutId = setTimeout(() => {
|
||||
resolve(false);
|
||||
}, MAX_AIPTAG_WAIT_TIME);
|
||||
|
||||
const checkInterval = setInterval(() => {
|
||||
if (typeof aipDisplayTag !== "undefined") {
|
||||
clearInterval(checkInterval);
|
||||
clearTimeout(timeoutId);
|
||||
resolve(true);
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
};
|
||||
|
||||
// Load provider scripts dynamically
|
||||
function loadProviderScript(provider) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement('script');
|
||||
script.src = `ads/adapters/${provider}-ads.js`;
|
||||
script.onload = () => {
|
||||
resolve();
|
||||
};
|
||||
script.onerror = () => {
|
||||
reject();
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
|
||||
// Load all configured providers
|
||||
async function loadProviders() {
|
||||
for (const provider of installProviders) {
|
||||
try {
|
||||
await loadProviderScript(provider);
|
||||
} catch (e) {
|
||||
console.error(`Failed to load ${provider}:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main SDK object
|
||||
window.SDK = {
|
||||
_isInitialized: false,
|
||||
_pendingBannerQueue: [],
|
||||
|
||||
gameplayStart() {
|
||||
if (DEBUG_MODE) console.log("[sdk.js] Gameplay started");
|
||||
},
|
||||
|
||||
loadingStart() {
|
||||
if (DEBUG_MODE) console.log("[sdk.js] Loading started");
|
||||
onWindowResize();
|
||||
},
|
||||
|
||||
loadingEnd() {
|
||||
if (DEBUG_MODE) console.log("[sdk.js] Loading finished");
|
||||
onWindowResize();
|
||||
},
|
||||
|
||||
gameplayEnd() {
|
||||
if (DEBUG_MODE) console.log("[sdk.js] Gameplay ended");
|
||||
},
|
||||
|
||||
showMidroll() {
|
||||
if (window.ENABLE_ADS) {
|
||||
showAd('midroll');
|
||||
} else {
|
||||
if (typeof unityInstance !== 'undefined') {
|
||||
unityInstance.SendMessage("SDKManager", "OnVideoAdEnded", "true");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
showRewarded() {
|
||||
if (window.ENABLE_ADS) {
|
||||
showAd('rewarded');
|
||||
} else {
|
||||
if (typeof unityInstance !== 'undefined') {
|
||||
unityInstance.SendMessage("SDKManager", "OnVideoAdEnded", "true");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_bannerAds: {},
|
||||
_occupiedPositions: {},
|
||||
_lastRefreshed: {},
|
||||
_pendingBannerOps: {},
|
||||
_bannerShowtime: {}, // Tracks accumulated visible time per banner
|
||||
_bannerVisibleSince: {}, // Tracks when banner became visible
|
||||
_showtimeInterval: null, // Interval for checking showtime
|
||||
|
||||
_startTrackingShowtime(adTag) {
|
||||
const now = Date.now();
|
||||
if (!this._bannerVisibleSince[adTag]) {
|
||||
this._bannerVisibleSince[adTag] = now;
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] Started tracking showtime for ${adTag}`);
|
||||
}
|
||||
},
|
||||
|
||||
_stopTrackingShowtime(adTag) {
|
||||
if (this._bannerVisibleSince[adTag]) {
|
||||
const now = Date.now();
|
||||
const visibleDuration = now - this._bannerVisibleSince[adTag];
|
||||
this._bannerShowtime[adTag] = (this._bannerShowtime[adTag] || 0) + visibleDuration;
|
||||
delete this._bannerVisibleSince[adTag];
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] Stopped tracking showtime for ${adTag}. Total showtime: ${Math.floor(this._bannerShowtime[adTag] / 1000)}s`);
|
||||
}
|
||||
},
|
||||
|
||||
_resetShowtime(adTag) {
|
||||
this._bannerShowtime[adTag] = 0;
|
||||
delete this._bannerVisibleSince[adTag];
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] Reset showtime for ${adTag}`);
|
||||
},
|
||||
|
||||
_getCurrentShowtime(adTag) {
|
||||
let totalShowtime = this._bannerShowtime[adTag] || 0;
|
||||
if (this._bannerVisibleSince[adTag]) {
|
||||
const now = Date.now();
|
||||
totalShowtime += (now - this._bannerVisibleSince[adTag]);
|
||||
}
|
||||
return totalShowtime;
|
||||
},
|
||||
|
||||
_isBannerVisible(banner) {
|
||||
return banner &&
|
||||
banner.position !== 0 &&
|
||||
banner.container &&
|
||||
banner.container.style.display !== 'none' &&
|
||||
banner.container.offsetParent !== null &&
|
||||
!document.hidden;
|
||||
},
|
||||
|
||||
async _originalSetBanner(bannerType, bannerPosition) {
|
||||
const adTag = window.bannerMapping[bannerType];
|
||||
const dims = window.bannerDimensions[bannerType];
|
||||
const now = Date.now();
|
||||
|
||||
if (!adTag || !dims) {
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] SetBanner: Invalid banner type ${bannerType}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_MOBILE && !dims.enableForMobile) {
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] SetBanner: Banner ${adTag} disabled on mobile`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get position name for logging
|
||||
const posName = POSITION_NAMES[bannerPosition] || `Position${bannerPosition}`;
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
console.log(`[sdk.js] SetBanner called: ${adTag} at ${posName}`);
|
||||
}
|
||||
|
||||
this._pendingBannerOps[bannerType] = {
|
||||
bannerType: bannerType,
|
||||
bannerPosition: bannerPosition,
|
||||
timestamp: now
|
||||
};
|
||||
|
||||
let existingInstance = this._bannerAds[adTag];
|
||||
|
||||
// Handle hiding
|
||||
if (bannerPosition === 0) {
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] Hiding banner ${adTag}`);
|
||||
if (existingInstance && existingInstance.container) {
|
||||
// Stop tracking showtime when hiding
|
||||
this._stopTrackingShowtime(adTag);
|
||||
|
||||
existingInstance.container.style.display = "none";
|
||||
let oldPosKey = existingInstance.position.toString();
|
||||
if (this._occupiedPositions[oldPosKey] === adTag) {
|
||||
delete this._occupiedPositions[oldPosKey];
|
||||
}
|
||||
existingInstance.position = 0;
|
||||
// Remove from pending operations since it's hidden
|
||||
delete this._pendingBannerOps[bannerType];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle existing banner
|
||||
if (existingInstance) {
|
||||
if (existingInstance.position === bannerPosition) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move banner
|
||||
let oldPosKey = existingInstance.position.toString();
|
||||
if (this._occupiedPositions[oldPosKey] === adTag) {
|
||||
delete this._occupiedPositions[oldPosKey];
|
||||
}
|
||||
|
||||
let newPosKey = bannerPosition.toString();
|
||||
if (this._occupiedPositions[newPosKey] && this._occupiedPositions[newPosKey] !== adTag) {
|
||||
let conflictAdTag = this._occupiedPositions[newPosKey];
|
||||
let conflictInstance = this._bannerAds[conflictAdTag];
|
||||
if (conflictInstance && conflictInstance.container) {
|
||||
conflictInstance.container.style.display = "none";
|
||||
}
|
||||
delete this._occupiedPositions[newPosKey];
|
||||
}
|
||||
|
||||
existingInstance.container.style.display = "block";
|
||||
updateContainerPosition(existingInstance.container, bannerPosition);
|
||||
existingInstance.position = bannerPosition;
|
||||
this._occupiedPositions[newPosKey] = adTag;
|
||||
|
||||
// Start tracking showtime when showing
|
||||
this._startTrackingShowtime(adTag);
|
||||
|
||||
// Check if we should refresh based on accumulated showtime
|
||||
const currentShowtime = this._getCurrentShowtime(adTag);
|
||||
const shouldRefresh = currentShowtime >= MIN_REFRESH_INTERVAL;
|
||||
|
||||
if (shouldRefresh) {
|
||||
if (this._pendingBannerOps[bannerType]?.timestamp > now) {
|
||||
return;
|
||||
}
|
||||
// Reset showtime counter before refresh
|
||||
this._resetShowtime(adTag);
|
||||
this._startTrackingShowtime(adTag);
|
||||
this._displayBannerWithProviders(bannerType, adTag, existingInstance.container, now);
|
||||
}
|
||||
} else {
|
||||
// Create new banner
|
||||
let posKey = bannerPosition.toString();
|
||||
|
||||
if (this._occupiedPositions[posKey]) {
|
||||
let conflictAdTag = this._occupiedPositions[posKey];
|
||||
let conflictInstance = this._bannerAds[conflictAdTag];
|
||||
if (conflictInstance && conflictInstance.container) {
|
||||
conflictInstance.container.style.display = "none";
|
||||
}
|
||||
delete this._occupiedPositions[posKey];
|
||||
}
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.className = 'banner-container';
|
||||
container.id = 'banner_' + adTag;
|
||||
container.style.position = 'absolute';
|
||||
container.style.zIndex = 1000;
|
||||
container.style.userSelect = 'none';
|
||||
container.style.pointerEvents = 'all';
|
||||
container.style.width = dims.width;
|
||||
container.style.height = dims.height;
|
||||
container.style.overflow = 'hidden';
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
container.style.backgroundColor = 'rgba(255, 0, 0, 0.66)';
|
||||
} else {
|
||||
container.style.backgroundColor = 'rgba(0, 0, 0, 0.035)';
|
||||
}
|
||||
|
||||
const bannerDiv = document.createElement('div');
|
||||
bannerDiv.id = adTag;
|
||||
bannerDiv.style.width = dims.width;
|
||||
bannerDiv.style.height = dims.height;
|
||||
container.appendChild(bannerDiv);
|
||||
|
||||
updateContainerPosition(container, bannerPosition);
|
||||
document.body.appendChild(container);
|
||||
|
||||
this._bannerAds[adTag] = {
|
||||
bannerType: bannerType,
|
||||
adTag: adTag,
|
||||
container: container,
|
||||
position: bannerPosition
|
||||
};
|
||||
this._occupiedPositions[posKey] = adTag;
|
||||
|
||||
// Start tracking showtime for new banner
|
||||
this._startTrackingShowtime(adTag);
|
||||
|
||||
if (this._pendingBannerOps[bannerType]?.timestamp > now) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._displayBannerWithProviders(bannerType, adTag, container, now);
|
||||
}
|
||||
|
||||
onWindowResize();
|
||||
},
|
||||
|
||||
async _displayBannerWithProviders(bannerType, adTag, container, now) {
|
||||
let providerIndex = 0;
|
||||
const priorities = bannerAdPriorities;
|
||||
|
||||
// Get position name for logging
|
||||
const bannerInstance = this._bannerAds[adTag];
|
||||
const posName = bannerInstance ? (POSITION_NAMES[bannerInstance.position] || `Position${bannerInstance.position}`) : 'Unknown';
|
||||
|
||||
const tryNextProvider = async () => {
|
||||
if (providerIndex >= priorities.length) {
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] All providers failed for banner ${adTag} at ${posName}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
const providerName = priorities[providerIndex];
|
||||
const provider = window.bannerAdProviders?.[providerName];
|
||||
|
||||
if (!provider) {
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] Provider ${providerName} not available for banner ${adTag}`);
|
||||
providerIndex++;
|
||||
return tryNextProvider();
|
||||
}
|
||||
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] Trying to show banner ${adTag} at ${posName} with provider: ${providerName}`);
|
||||
|
||||
try {
|
||||
// Pass bannerType for CPMStar/Nitro/Local, adTag for AdinPlay
|
||||
const param = providerName === 'adinplay' ? adTag : bannerType;
|
||||
const success = await provider.displayBanner(param, container);
|
||||
|
||||
if (success) {
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] Successfully showing banner ${adTag} at ${posName} with ${providerName}`);
|
||||
this._lastRefreshed[adTag] = now;
|
||||
// Reset showtime after successful refresh
|
||||
this._resetShowtime(adTag);
|
||||
this._startTrackingShowtime(adTag);
|
||||
return true;
|
||||
} else {
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] Showing banner ${adTag} at ${posName} with ${providerName} FAILED, trying next...`);
|
||||
providerIndex++;
|
||||
return tryNextProvider();
|
||||
}
|
||||
} catch (error) {
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] Error showing banner ${adTag} with ${providerName}:`, error.message || error);
|
||||
providerIndex++;
|
||||
return tryNextProvider();
|
||||
}
|
||||
};
|
||||
|
||||
return tryNextProvider();
|
||||
}
|
||||
};
|
||||
|
||||
// Debounced SetBanner with initialization queue
|
||||
window.SDK.SetBanner = function (bannerType, bannerPosition) {
|
||||
// If not initialized and trying to show banner (not hide), queue it
|
||||
if (!window.SDK._isInitialized && bannerPosition !== 0) {
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] SDK not initialized yet, queueing banner ${window.bannerMapping[bannerType] || bannerType} for position ${bannerPosition}`);
|
||||
|
||||
// Check if we already have this banner type in queue
|
||||
const existingIndex = window.SDK._pendingBannerQueue.findIndex(item => item.bannerType === bannerType);
|
||||
if (existingIndex >= 0) {
|
||||
// Update existing entry with new position
|
||||
window.SDK._pendingBannerQueue[existingIndex].bannerPosition = bannerPosition;
|
||||
} else {
|
||||
// Add new entry
|
||||
window.SDK._pendingBannerQueue.push({ bannerType, bannerPosition });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If hiding banner (position 0), process immediately even if not initialized
|
||||
// This ensures we can remove queued banners
|
||||
if (bannerPosition === 0) {
|
||||
// Remove from queue if present
|
||||
window.SDK._pendingBannerQueue = window.SDK._pendingBannerQueue.filter(
|
||||
item => item.bannerType !== bannerType
|
||||
);
|
||||
|
||||
// If initialized, hide the banner
|
||||
if (window.SDK._isInitialized) {
|
||||
window.SDK._originalSetBanner.call(window.SDK, bannerType, bannerPosition);
|
||||
}
|
||||
} else {
|
||||
// Normal debounced call for showing banners when initialized
|
||||
if (!window.SDK._debouncedSetBannerPerType) {
|
||||
window.SDK._debouncedSetBannerPerType = {};
|
||||
}
|
||||
|
||||
if (!window.SDK._debouncedSetBannerPerType[bannerType]) {
|
||||
window.SDK._debouncedSetBannerPerType[bannerType] = debounce(
|
||||
(bannerType, bannerPosition) => {
|
||||
window.SDK._originalSetBanner.call(window.SDK, bannerType, bannerPosition);
|
||||
},
|
||||
BANNER_DEBOUNCE_TIME
|
||||
);
|
||||
}
|
||||
|
||||
window.SDK._debouncedSetBannerPerType[bannerType](bannerType, bannerPosition);
|
||||
}
|
||||
};
|
||||
|
||||
// Container positioning helper
|
||||
function updateContainerPosition(container, bannerPosition) {
|
||||
container.style.top = "";
|
||||
container.style.right = "";
|
||||
container.style.bottom = "";
|
||||
container.style.left = "";
|
||||
container.style.transformOrigin = "";
|
||||
|
||||
switch (parseInt(bannerPosition)) {
|
||||
case 0:
|
||||
container.style.display = "none";
|
||||
break;
|
||||
case 1: // TopCenter
|
||||
container.style.display = "block";
|
||||
container.style.top = "1%";
|
||||
container.style.left = "0";
|
||||
container.style.right = "0";
|
||||
container.style.marginLeft = "auto";
|
||||
container.style.marginRight = "auto";
|
||||
container.style.transformOrigin = "top center";
|
||||
break;
|
||||
case 2: // TopRight
|
||||
container.style.display = "block";
|
||||
container.style.top = "1%";
|
||||
container.style.right = "1%";
|
||||
container.style.transformOrigin = "top right";
|
||||
break;
|
||||
case 3: // TopLeft
|
||||
container.style.display = "block";
|
||||
container.style.top = "1%";
|
||||
container.style.left = "1%";
|
||||
container.style.transformOrigin = "top left";
|
||||
break;
|
||||
case 4: // BottomCenter
|
||||
container.style.display = "block";
|
||||
container.style.bottom = "0.5%";
|
||||
container.style.left = "0";
|
||||
container.style.right = "0";
|
||||
container.style.marginLeft = "auto";
|
||||
container.style.marginRight = "auto";
|
||||
container.style.transformOrigin = "bottom center";
|
||||
break;
|
||||
case 5: // BottomRight
|
||||
container.style.display = "block";
|
||||
container.style.bottom = "1%";
|
||||
container.style.right = "1%";
|
||||
container.style.transformOrigin = "bottom right";
|
||||
break;
|
||||
case 6: // BottomLeft
|
||||
container.style.display = "block";
|
||||
container.style.bottom = "1%";
|
||||
container.style.left = "1%";
|
||||
container.style.transformOrigin = "bottom left";
|
||||
break;
|
||||
case 7: // MiddleCenter
|
||||
container.style.display = "block";
|
||||
container.style.position = "absolute";
|
||||
container.style.top = "0";
|
||||
container.style.bottom = "0";
|
||||
container.style.left = "0";
|
||||
container.style.right = "0";
|
||||
container.style.margin = "auto";
|
||||
break;
|
||||
case 8: // MiddleLeft
|
||||
container.style.display = "block";
|
||||
container.style.left = "1%";
|
||||
container.style.top = "0";
|
||||
container.style.bottom = "0";
|
||||
container.style.margin = "auto";
|
||||
container.style.transformOrigin = "center left";
|
||||
break;
|
||||
case 9: // MiddleRight
|
||||
container.style.display = "block";
|
||||
container.style.right = "1%";
|
||||
container.style.top = "0";
|
||||
container.style.bottom = "0";
|
||||
container.style.margin = "auto";
|
||||
container.style.transformOrigin = "center right";
|
||||
break;
|
||||
case 10: // Below TopLeft
|
||||
container.style.display = "block";
|
||||
container.style.position = "absolute";
|
||||
container.style.left = "1%";
|
||||
container.style.top = "14%";
|
||||
container.style.transformOrigin = "top left";
|
||||
break;
|
||||
case 11: // Below TopRight
|
||||
container.style.display = "block";
|
||||
container.style.position = "absolute";
|
||||
container.style.top = "10%";
|
||||
container.style.right = "1%";
|
||||
container.style.transformOrigin = "top right";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Video ad system
|
||||
function showAd(adType) {
|
||||
let providerIndex = 0;
|
||||
const priorities = videoAdPriorities;
|
||||
|
||||
function tryNextProvider() {
|
||||
if (providerIndex >= priorities.length) {
|
||||
if (typeof unityInstance !== 'undefined') {
|
||||
unityInstance.SendMessage("SDKManager", "OnVideoAdEnded", "false");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const providerName = priorities[providerIndex];
|
||||
const provider = window.videoAdProviders?.[providerName];
|
||||
|
||||
if (!provider) {
|
||||
providerIndex++;
|
||||
tryNextProvider();
|
||||
return;
|
||||
}
|
||||
|
||||
const methodName = adType === 'rewarded' ? 'showRewarded' : 'showMidroll';
|
||||
|
||||
provider[methodName](
|
||||
function () {
|
||||
if (typeof unityInstance !== 'undefined') {
|
||||
unityInstance.SendMessage("SDKManager", "OnVideoAdEnded", "true");
|
||||
}
|
||||
},
|
||||
function () {
|
||||
providerIndex++;
|
||||
tryNextProvider();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
tryNextProvider();
|
||||
}
|
||||
|
||||
// Window resize handling
|
||||
function getRatioBoost(stops, aspect) {
|
||||
stops.sort((a, b) => a.ratio - b.ratio);
|
||||
if (aspect <= stops[0].ratio) return stops[0].boost;
|
||||
if (aspect >= stops.at(-1).ratio) return stops.at(-1).boost;
|
||||
for (let i = 0; i < stops.length - 1; i++) {
|
||||
const a = stops[i], b = stops[i + 1];
|
||||
if (aspect >= a.ratio && aspect <= b.ratio) {
|
||||
const t = (aspect - a.ratio) / (b.ratio - a.ratio);
|
||||
return a.boost + (b.boost - a.boost) * t;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
function onWindowResize() {
|
||||
const w = window.innerWidth, h = window.innerHeight;
|
||||
const aspect = w / h;
|
||||
const baseScale = Math.min(w / 1920, h / 960);
|
||||
|
||||
Object.keys(window.bannerMapping).forEach(key => {
|
||||
const tag = window.bannerMapping[key];
|
||||
const dims = window.bannerDimensions[key];
|
||||
const ctr = document.getElementById('banner_' + tag);
|
||||
if (!ctr || (IS_MOBILE && !dims.enableForMobile)) return;
|
||||
|
||||
const boost = getRatioBoost(dims.ratioBoostStops, aspect);
|
||||
const finalScale = baseScale * dims.scale * boost;
|
||||
ctr.style.transform = `scale(${finalScale})`;
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener("resize", onWindowResize);
|
||||
|
||||
// Showtime-based refresh system
|
||||
window.SDK._showtimeInterval = setInterval(async function () {
|
||||
if (!window.ENABLE_ADS) return;
|
||||
|
||||
const now = Date.now();
|
||||
|
||||
// Update showtime for all visible banners
|
||||
Object.keys(window.SDK._bannerAds).forEach(adTag => {
|
||||
const banner = window.SDK._bannerAds[adTag];
|
||||
|
||||
if (window.SDK._isBannerVisible(banner)) {
|
||||
// Banner is visible - ensure we're tracking it
|
||||
if (!window.SDK._bannerVisibleSince[adTag]) {
|
||||
window.SDK._startTrackingShowtime(adTag);
|
||||
}
|
||||
|
||||
// Check if it's time to refresh based on showtime
|
||||
const currentShowtime = window.SDK._getCurrentShowtime(adTag);
|
||||
if (currentShowtime >= MIN_REFRESH_INTERVAL) {
|
||||
if (DEBUG_MODE) console.log(`[sdk.js] Banner ${adTag} reached ${Math.floor(currentShowtime / 1000)}s showtime, refreshing...`);
|
||||
|
||||
const bannerType = Object.keys(window.bannerMapping).find(key => window.bannerMapping[key] === adTag);
|
||||
if (bannerType !== undefined) {
|
||||
// Reset showtime before refresh
|
||||
window.SDK._resetShowtime(adTag);
|
||||
window.SDK._startTrackingShowtime(adTag);
|
||||
window.SDK._displayBannerWithProviders(parseInt(bannerType), adTag, banner.container, now);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Banner is not visible - stop tracking if we were
|
||||
if (window.SDK._bannerVisibleSince[adTag]) {
|
||||
window.SDK._stopTrackingShowtime(adTag);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, SHOWTIME_CHECK_INTERVAL);
|
||||
|
||||
// Handle page visibility changes for showtime tracking
|
||||
document.addEventListener('visibilitychange', function () {
|
||||
if (document.hidden) {
|
||||
// Page is hidden - stop tracking all visible banners
|
||||
Object.keys(window.SDK._bannerAds).forEach(adTag => {
|
||||
if (window.SDK._bannerVisibleSince[adTag]) {
|
||||
window.SDK._stopTrackingShowtime(adTag);
|
||||
}
|
||||
});
|
||||
} else if (window.ENABLE_ADS) {
|
||||
// Page is visible again - restart tracking for visible banners
|
||||
Object.keys(window.SDK._bannerAds).forEach(adTag => {
|
||||
const banner = window.SDK._bannerAds[adTag];
|
||||
if (window.SDK._isBannerVisible(banner)) {
|
||||
window.SDK._startTrackingShowtime(adTag);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Process queued banners after initialization
|
||||
window.SDK._processQueuedBanners = function () {
|
||||
if (DEBUG_MODE && window.SDK._pendingBannerQueue.length > 0) {
|
||||
console.log(`[sdk.js] Processing ${window.SDK._pendingBannerQueue.length} queued banner(s)`);
|
||||
}
|
||||
|
||||
// Process each queued banner
|
||||
const queue = [...window.SDK._pendingBannerQueue];
|
||||
window.SDK._pendingBannerQueue = [];
|
||||
|
||||
queue.forEach(({ bannerType, bannerPosition }) => {
|
||||
if (DEBUG_MODE) {
|
||||
const adTag = window.bannerMapping[bannerType] || bannerType;
|
||||
console.log(`[sdk.js] Processing queued banner: ${adTag} at position ${bannerPosition}`);
|
||||
}
|
||||
// Use SetBanner to ensure debouncing still applies
|
||||
window.SDK.SetBanner(bannerType, bannerPosition);
|
||||
});
|
||||
};
|
||||
|
||||
// Initialize
|
||||
(async function () {
|
||||
if (DEBUG_MODE) console.log("[sdk.js] Starting SDK initialization...");
|
||||
|
||||
await loadProviders();
|
||||
|
||||
// Mark as initialized
|
||||
window.SDK._isInitialized = true;
|
||||
if (DEBUG_MODE) console.log("[sdk.js] SDK initialized, providers loaded");
|
||||
|
||||
// Process any queued banners
|
||||
window.SDK._processQueuedBanners();
|
||||
|
||||
window.SDK.loadingStart();
|
||||
})();
|
||||
Reference in New Issue
Block a user