diff --git a/src/const/sdk.ts b/src/const/sdk.ts new file mode 100644 index 00000000..44f712af --- /dev/null +++ b/src/const/sdk.ts @@ -0,0 +1,6 @@ +import { SDKPlatform } from '~type/sdk'; + +export const SDK_PLATFORMS: Record = { + [SDKPlatform.CRAZY_GAMES]: 'https://sdk.crazygames.com/crazygames-sdk-v2.js', + [SDKPlatform.POKI]: 'https://game-cdn.poki.com/scripts/v2/poki-sdk.js', +}; diff --git a/src/game/game.ts b/src/game/game.ts index a91e63ee..e89e5a29 100644 --- a/src/game/game.ts +++ b/src/game/game.ts @@ -4,9 +4,10 @@ import { AUDIO_VOLUME, CONTAINER_ID, DEBUG_MODS, SETTINGS, } from '~const/game'; import { Analytics } from '~lib/analytics'; +import { SDK } from '~lib/sdk'; import { Storage } from '~lib/storage'; import { Tutorial } from '~lib/tutorial'; -import { eachEntries, registerScript } from '~lib/utils'; +import { eachEntries } from '~lib/utils'; import { Gameover } from '~scene/gameover'; import { Menu } from '~scene/menu'; import { Screen } from '~scene/screen'; @@ -27,6 +28,7 @@ import { } from '~type/game'; import { MenuPage } from '~type/menu'; import { IScreen } from '~type/screen'; +import { ISDK, SDKPlatform } from '~type/sdk'; import { IStorage, StorageSave } from '~type/storage'; import { ITutorial } from '~type/tutorial'; import { IWorld } from '~type/world'; @@ -40,6 +42,8 @@ export class Game extends Phaser.Game implements IGame { readonly storage: IStorage; + private sdk: ISDK | null = null; + private flags: string[]; public difficulty: GameDifficulty = GameDifficulty.NORMAL; @@ -104,9 +108,7 @@ export class Game extends Phaser.Game implements IGame { this.readFlags(); this.readSettings(); - if (this.isFlagEnabled(GameFlag.ADS)) { - registerScript('https://sdk.crazygames.com/crazygames-sdk-v2.js'); - } + this.createSDK(); this.events.on(Phaser.Core.Events.READY, () => { this.screen = this.scene.getScene(GameScene.SCREEN); @@ -242,7 +244,7 @@ export class Game extends Phaser.Game implements IGame { defaultPage: MenuPage.NEW_GAME, }); - this.showAd(GameAdType.MIDGAME); + this.showAdv(GameAdType.MIDGAME); if (!IS_DEV_MODE) { window.onbeforeunload = null; @@ -305,29 +307,35 @@ export class Game extends Phaser.Game implements IGame { private readFlags() { const query = new URLSearchParams(window.location.search); - const rawFlags = query.get('flags'); + const value = query.get('flags')?.toUpperCase() ?? ''; - this.flags = rawFlags?.toUpperCase().split(',') ?? []; + this.flags = value.split(','); } - public showAd(type: GameAdType, callback?: () => void) { - if (!this.isFlagEnabled(GameFlag.ADS)) { + public showAdv(type: GameAdType, callback?: () => void) { + if (!this.sdk || !this.isFlagEnabled(GameFlag.ADS)) { return; } - // @ts-ignore - window.CrazyGames?.SDK?.ad?.requestAd(type, { - adStarted: () => { + this.sdk.showAdv( + type, + () => { this.pause(); }, - adFinished: () => { + () => { this.resume(); callback?.(); }, - adError: (error: any) => { - console.warn(`Error ${type} ad:`, error); - }, - }); + ); + } + + private createSDK() { + const query = new URLSearchParams(window.location.search); + const platform = query.get('sdk')?.toUpperCase(); + + if (platform) { + this.sdk = new SDK(platform); + } } private getRecordStat(): Nullable { diff --git a/src/game/scenes/screen/interface/ads-reward/index.tsx b/src/game/scenes/screen/interface/ads-reward/index.tsx index 7790490b..e03be828 100644 --- a/src/game/scenes/screen/interface/ads-reward/index.tsx +++ b/src/game/scenes/screen/interface/ads-reward/index.tsx @@ -24,7 +24,7 @@ export const AdsReward: React.FC = () => { }); const onConfirmAds = () => { - game.showAd(GameAdType.REWARDED, () => { + game.showAdv(GameAdType.REWARDED, () => { world.player.giveExperience(adsReward.experience); world.player.giveResources(adsReward.resources); }); diff --git a/src/lib/sdk.ts b/src/lib/sdk.ts new file mode 100644 index 00000000..8222f7c4 --- /dev/null +++ b/src/lib/sdk.ts @@ -0,0 +1,84 @@ +import { SDK_PLATFORMS } from '~const/sdk'; +import { GameAdType } from '~type/game'; +import { ISDK, SDKPlatform } from '~type/sdk'; + +import { registerScript } from './utils'; + +export class SDK implements ISDK { + private platform: SDKPlatform; + + constructor(platform: SDKPlatform) { + try { + registerScript(SDK_PLATFORMS[platform]).then(() => { + this.platform = platform; + + switch (this.platform) { + case SDKPlatform.POKI: { + window.PokiSDK?.init(); + } + } + }); + } catch (error) { + console.error('SDK initialization error:', error); + } + } + + public showAdv( + type: GameAdType, + callbackBeg: () => void, + callbackEnd: (success: boolean) => void, + ) { + try { + switch (this.platform) { + case SDKPlatform.CRAZY_GAMES: { + window.CrazyGames?.SDK?.ad?.requestAd(type, { + adStarted: callbackBeg, + adFinished: () => callbackEnd(true), + }); + break; + } + case SDKPlatform.POKI: { + const method = type === GameAdType.REWARDED ? 'rewardedBreak' : 'commercialBreak'; + + window.PokiSDK?.[method](callbackBeg).then((success: boolean) => { + callbackEnd(success); + }); + break; + } + } + } catch (error) { + console.error('SDK Show adv error:', error); + } + } + + // public toggleLoadState(state: boolean) { + // switch (this.platform) { + // case SDKPlatform.CRAZY_GAMES: { + // if (state) { + // window.CrazyGames?.SDK?.game?.sdkGameLoadingStart(); + // } else { + // window.CrazyGames?.SDK?.game?.sdkGameLoadingStop(); + // } + // break; + // } + // case SDKPlatform.POKI: { + // if (!state) { + // window.PokiSDK?.gameLoadingFinished(); + // } + // break; + // } + // } + // } + + // public togglePlayState(state: boolean) { + // switch (this.platform) { + // case SDKPlatform.POKI: { + // if (state) { + // window.PokiSDK.gameplayStart(); + // } else { + // window.PokiSDK.gameplayStop(); + // } + // } + // } + // } +} diff --git a/src/types/game.ts b/src/types/game.ts index a38df27c..cc5c3ef1 100644 --- a/src/types/game.ts +++ b/src/types/game.ts @@ -1,5 +1,3 @@ -import Phaser from 'phaser'; - import { IAnalytics } from '~type/analytics'; import { IScreen } from '~type/screen'; import { IStorage, StorageSave } from '~type/storage'; @@ -112,7 +110,7 @@ export interface IGame extends Phaser.Game { * @param type - Ad type * @param callback - Complete callback */ - showAd(type: GameAdType, callback?: () => void): void + showAdv(type: GameAdType, callback?: () => void): void /** * Get data for saving. diff --git a/src/types/sdk.ts b/src/types/sdk.ts new file mode 100644 index 00000000..aac9f071 --- /dev/null +++ b/src/types/sdk.ts @@ -0,0 +1,27 @@ +import { GameAdType } from './game'; + +export interface ISDK { + /** + * Show advertising. + * @param type - Ad type + * @param callbackBeg - Start callback + * @param callbackEnd - Complete callback + */ + showAdv( + type: GameAdType, + callbackBeg: () => void, + callbackEnd: (success: boolean) => void + ): void +} + +export enum SDKPlatform { + CRAZY_GAMES = 'CRAZY_GAMES', + POKI = 'POKI', +} + +declare global { + interface Window { + PokiSDK?: any + CrazyGames?: any + } +}