import {EventEmitter, Inject, Injectable} from '@angular/core'; import {GameActionsService} from '../game-actions.service'; import { SettingsService, CommunicationOxService, } from 'ox-core'; import {MicroLessonMetricsService} from '../metrics/micro-lesson-metrics.service'; import {AppInfoOxService} from '../app-info-ox.service'; import {CollectiblesService} from '../collectibles.service'; import {SurpriseService} from '../surprise.service'; import {pairwise} from 'rxjs/operators'; import {ChallengeService} from '../challenge.service'; import {IPostMessageBridge, IPostMessageEventTarget, PostMessageBridgeFactory} from 'ngox-post-message'; import {Translation} from '@ngneat/transloco'; import {BehaviorSubject} from 'rxjs'; import {SoundOxService} from '../sound-ox.service'; import {MicroLessonInfoOxDefault, SettingsOxDefault, ScreenTypeOx} from 'ox-types'; import {ResourceStateService} from '../resource-state.service'; import { CollectiblesOxBridge, ExerciseMetricsOxBridge, GoToResultsScreenOxBridge, I18NInfoOxBridge, MicroLessonCompleteOxBridge, MicroLessonConfigurationOxBridge, NextGameOxBridge, RestartGameOxBridge, SettingsInfoOxBridge, StartGameOxBridge, SurpriseOxBridge, ResourceInitialStateOxBridge, ResourceFinalStateOxBridge, AssetsLoadedForGameBridge, GameAskForScreenChangeBridge, GameSoundOnBridge, LoadAssetsForGameBridge, ShowTutorialOxBridge, TutorialEndOxBridge, HasTutorialOxBridge } from 'ox-types'; // export const LoadAssetsForGameBridge = 'LoadAssetsForGameBridge'; // export const AssetsLoadedForGameBridge = 'AssetsLoadedForGameBridge'; // export const GameAskForScreenChangeBridge = 'GameAskForScreenChangeBridge'; // export const GameSoundOnBridge = 'GameSoundOnBridge'; @Injectable({ providedIn: 'root' }) export class MicroLessonCommunicationService { // TODO find a better solution. private metricsSended: boolean; private managerToMLBridge: IPostMessageBridge; private mlToManagerBridge: IPostMessageBridge; constructor(private settings: SettingsService, private gameActions: GameActionsService, private challengeService: ChallengeService, private appInfo: AppInfoOxService, private wumboxCommunication: CommunicationOxService, private metricsService: MicroLessonMetricsService, private collectibles: CollectiblesService, private soundService: SoundOxService, private resourceStateService: ResourceStateService, @Inject(PostMessageBridgeFactory) private bridgeFactory: PostMessageBridgeFactory, private surpriseService: SurpriseService) { this.manageCommunicationWithWumbox(); this.gameActions.microLessonCompleted.subscribe(x => { this.sendMessageMLToManager(ResourceFinalStateOxBridge, this.resourceStateService.currentState.value); }); this.wumboxCommunication.receiveResourceState.subscribe(state => { console.log('initial state receive in ' + window.location.href, state); this.resourceStateService.currentState.next(state); }); } /*updateState(state: any): void { this.resourceStateService.currentState.next(state); this.sendMessageMLToManager(ResourceFinalStateOxBridge, this.resourceStateService.currentState.value); }*/ private manageCommunicationWithWumbox() { this.gameActions.goToResults.subscribe(() => { this.wumboxCommunication.sendMessage(GoToResultsScreenOxBridge, {}); // this.wumboxCommunication.sendMessage(SettingsInfoOxBridge, JSON.stringify(this.settings.currentSettings)); // if (this.resourceStateService.currentState.value) { // this.wumboxCommunication.sendMessage(ResourceFinalStateOxBridge, this.resourceStateService.currentState.value); // } }); this.metricsService.finishedMetrics.subscribe(e => { if (!this.metricsSended) { console.log('Sending finished metrics..', this.metricsService, this.metricsService.currentMetrics); this.metricsSended = true; this.wumboxCommunication.sendMessage(MicroLessonCompleteOxBridge, JSON.stringify(this.metricsService.currentMetrics)); this.sendMessageMLToManager(MicroLessonCompleteOxBridge, JSON.stringify(this.metricsService.currentMetrics)); } this.wumboxCommunication.sendMessage(CollectiblesOxBridge, JSON.stringify(this.collectibles.currentCollectibles)); }); this.metricsService.startedMetrics.subscribe(e => { this.metricsSended = false; }); this.metricsService.updateMetrics.subscribe(x => { console.log('Sending updated metrics..', this.metricsService, this.metricsService.currentMetrics); this.wumboxCommunication.sendMessage(ExerciseMetricsOxBridge, JSON.stringify( this.metricsService.currentMetrics)); // this.metricsService.currentMetrics.exerciseMetrics[this.metricsService.currentMetrics.exerciseMetrics.length - 1])); }); this.surpriseService.surprise.subscribe(surpriseInfoToSend => { this.wumboxCommunication.sendMessage(SurpriseOxBridge, JSON.stringify(surpriseInfoToSend)); }); this.gameActions.nextGame.subscribe(_ => { this.wumboxCommunication.sendMessage(NextGameOxBridge, {}); }); this.challengeService.currentExercise.pipe(pairwise()).subscribe(exercises => { if (exercises[0] === undefined && exercises[1] !== undefined) { this.wumboxCommunication.sendMessage(StartGameOxBridge, {}); // First exercise. } }); this.gameActions.restartGame.subscribe(params => { if (params.triggeredFrom === ScreenTypeOx.InGameMenu || params.triggeredFrom === ScreenTypeOx.Game) { this.wumboxCommunication.sendMessage(RestartGameOxBridge, {}); // Restart with existing exercise. } }); } public setBridgesManagerToML(): void { if (!this.managerToMLBridge) { const iFrame: IPostMessageEventTarget = window.frames[window.frames.length - 1]; const currentWindow: IPostMessageEventTarget = window; this.managerToMLBridge = this.bridgeFactory.makeInstance() .setEnableLogging(false) // By default, the smart logger is enabled .connect(currentWindow, iFrame) .makeBridge(MicroLessonConfigurationOxBridge) .makeBridge(I18NInfoOxBridge) .makeBridge(SettingsInfoOxBridge) .makeBridge(ResourceFinalStateOxBridge) .makeBridge(ResourceInitialStateOxBridge) .makeBridge(LoadAssetsForGameBridge) .makeBridge(AssetsLoadedForGameBridge) .makeBridge(RestartGameOxBridge) .makeBridge(StartGameOxBridge) .makeBridge(ShowTutorialOxBridge) // New tutorial bridges .makeBridge(TutorialEndOxBridge) .makeBridge(GameSoundOnBridge); // esto es para recibir mensajes desde la ML al manager this.addListenerToBridge(this.managerToMLBridge, ResourceFinalStateOxBridge, undefined, (data) => { console.log('receive state in manager', data); if (data) { this.resourceStateService.currentState.next(data); this.wumboxCommunication.sendMessage(ResourceFinalStateOxBridge, data); } // this.resourceStateService.currentState.next(data); // could be any }); } else { console.log('aready isntatined this.managerToMLBridge'); } /*this.addListenerToBridge(this.managerToMLBridge, ResourceInitialStateOxBridge, undefined, (data) => { console.log('receive INITAL state in ml', data); this.resourceStateService.currentState.next(data); // this.resourceStateService.currentState.next(data); // could be any if (this.resourceStateService.currentState.value) { this.sendMessageManagerToML(ResourceInitialStateOxBridge, this.resourceStateService.currentState.value); } });*/ } public setBridgesMLToManger(): void { const iFrame: IPostMessageEventTarget = window; const parentWindow: IPostMessageEventTarget = window.parent; this.mlToManagerBridge = this.bridgeFactory.makeInstance(); this.mlToManagerBridge.setEnableLogging(false) .connect(iFrame, parentWindow) .makeBridge(GameSoundOnBridge) .makeBridge(GameAskForScreenChangeBridge) .makeBridge(StartGameOxBridge) .makeBridge(RestartGameOxBridge) .makeBridge(LoadAssetsForGameBridge) .makeBridge(ResourceFinalStateOxBridge) .makeBridge(ResourceInitialStateOxBridge) .makeBridge(MicroLessonCompleteOxBridge) .makeBridge(ShowTutorialOxBridge) .makeBridge(TutorialEndOxBridge) .makeBridge(HasTutorialOxBridge) .makeBridge(AssetsLoadedForGameBridge); this.addListenerToBridge(this.mlToManagerBridge, ShowTutorialOxBridge, this.gameActions.showTutorial); this.addListenerToBridge(this.mlToManagerBridge, StartGameOxBridge, this.gameActions.startGame); // this.addListenerToBridge(this.mlToManagerBridge, StartGameOxBridge, this.managerSendStartGame); this.addListenerToBridge(this.mlToManagerBridge, RestartGameOxBridge, this.gameActions.restartGame); this.addListenerToBridge(this.mlToManagerBridge, GameSoundOnBridge, undefined, (data) => { this.soundService.currentScreen = data ? ScreenTypeOx.Game : ScreenTypeOx.InGameMenu; // could be any }); this.addListenerToBridge(this.mlToManagerBridge, ResourceInitialStateOxBridge, undefined, (data) => { // this.resourceStateService.currentState.next(data); // could be any }); // this.addListenerToBridge(this.mlToManagerBridge, MicroLessonCompleteOxBridge, this.managerReceivedCompleteMetrics); } private addListenerToBridge(bridgeInstance: IPostMessageBridge, bridge: string, event: (BehaviorSubject | EventEmitter), extraFunc?: (data?) => void): void { bridgeInstance.addListener(bridge, (message: { data: any, flugvelSecret: string }) => { if (event !== undefined && CommunicationOxService.checkFlugvelSecret(message.flugvelSecret)) { event.next(message.data); } if (extraFunc !== undefined) { extraFunc(message.data); } }); } public sendResourceInitialStateToML(state: any) { this.sendMessageManagerToML(ResourceInitialStateOxBridge, state); } public sendSettingsToML(settings: SettingsOxDefault) { this.sendMessageManagerToML(SettingsInfoOxBridge, settings); } public sendI18NToML(i18n: Translation) { this.sendMessageManagerToML(I18NInfoOxBridge, i18n); } public sendMicroLessonInfoToML(info: MicroLessonInfoOxDefault) { this.sendMessageManagerToML(MicroLessonConfigurationOxBridge, info); } public sendMessageManagerToML(bridge: string, message: any) { this.managerToMLBridge.sendMessage(bridge, {data: message, flugvelSecret: CommunicationOxService.getFlugvelSecret()}); } public sendMessageMLToManager(bridge: string, message: any) { this.mlToManagerBridge.sendMessage(bridge, {data: message, flugvelSecret: CommunicationOxService.getFlugvelSecret()}); } }