import { Injectable } from '@angular/core' ; import { ReferenceCard } from '@firestone-hs/reference-data' ; import { decode , encode } from 'deckstrings' ; import { Achievement } from '../models/achievement' ; import { DeckCard } from '../models/decktracker/deck-card' ; import { DeckState } from '../models/decktracker/deck-state' ; import { GameState } from '../models/decktracker/game-state' ; import { GameStat } from '../models/mainwindow/stats/game-stat' ; import { GameStats } from '../models/mainwindow/stats/game-stats' ; import { AchievementsMonitor } from './achievement/achievements-monitor.service' ; import { Challenge } from './achievement/achievements/challenges/challenge' ; import { ChallengeBuilderService } from './achievement/achievements/challenges/challenge-builder.service' ; import { AchievementsLoaderService } from './achievement/data/achievements-loader.service' ; import { SetsService } from './collection/sets-service.service' ; import { DeckHandlerService } from './decktracker/deck-handler.service' ; import { DeckParserService } from './decktracker/deck-parser.service' ; import { DeckManipulationHelper } from './decktracker/event-parser/deck-manipulation-helper' ; import { GameStateService } from './decktracker/game-state.service' ; import { Events } from './events.service' ; import { GameEvents } from './game-events.service' ; import { MainWindowStoreService } from './mainwindow/store/main-window-store.service' ; import { OverwolfService } from './overwolf.service' ; import { MemoryInspectionService } from './plugins/memory-inspection.service' ; @ Injectable ( ) export class DevService { constructor ( private events , private ow , private gameEvents , private deckParser , private cards , private gameState , private helper , private store , private challengeBuilder , private achievementLoader , private achievementsMonitor , private memoryService , private handler ) { if ( process . env . NODE_ENV === 'production' ) { return ; } this . addTestCommands ( ) ; } private addTestCommands ( ) { this . addAchievementCommands ( ) ; } private addAchievementCommands ( ) { const achievement = { id : 'dungeon_run_boss_encounter_LOOTA_BOSS_44h' , name : 'Fake Wee Whelp' , text : 'Temp text' , type : 'dungeon_run_boss_encounter' , displayCardId : 'LOOTA_BOSS_44h' , displayCardType : 'minion' , displayName : 'Boss met: Fake Wee Whelp' , difficulty : 'common' , icon : 'boss_encounter' , maxNumberOfRecords : 1 , points : 1 , numberOfCompletions : 0 , canBeCompletedOnlyOnce : false , replayInfo : [ ] , root : null , priority : 0 , emptyText : null , completedText : null , } as any ; window [ 'showAchievementNotification' ] = ( ) => { this . events . broadcast ( Events . ACHIEVEMENT_COMPLETE , achievement , { notificationTimeout : ( ) => 0 , getRecordingDuration : ( ) => 0 , } as Challenge ) ; } ; window [ 'showMatchStatsNotification' ] = ( ) => { this . events . broadcast ( Events . GAME_STATS_UPDATED , Object . assign ( new GameStats ( ) , { stats : [ Object . assign ( new GameStat ( ) , { reviewId : '5ddd7f7f3c4a7900013e16de' , gameMode : 'battlegrounds' , playerRank : '5123' , } as GameStat ) , ] as readonly GameStat [ ] , } as GameStats ) ) ; } ; window [ 'loadEvents' ] = async ( fileName , awaitEvents = false , deckstring ? , timeBetweenEvents ? ) => { const logsLocation = `E:\\Source\\zerotoheroes\\firestone\\integration-tests\\events\\${ fileName }.json` ; let logContents = await this . ow . readTextFile ( logsLocation ) ; let events = JSON . parse ( logContents ) ; await this . loadEvents ( events , awaitEvents , deckstring , timeBetweenEvents ) ; logContents = null ; events = null ; console . debug ( 'processing done' ) ; } ; window [ 'startDeckCycle' ] = async ( logName , repeats , deckString ) => { console . debug ( 'starting new deck cycle' , logName , repeats , deckString ) ; console . debug = console . debug = ( args ) => { } ; const logsLocation = `E:\\Source\\zerotoheroes\\firestone\\integration-tests\\events\\${ logName }.json` ; const logContents = await this . ow . readTextFile ( logsLocation ) ; const events = JSON . parse ( logContents ) ; while ( repeats > 0 ) { console . warn ( 'starting iteration' , repeats ) ; await this . loadEvents ( events , true , deckString ) ; await sleep ( 10000 ) ; repeats -- ; } console . warn ( 'iterations over' ) ; } ; window [ 'decodeDeck' ] = ( deckstring ) => { console . debug ( decode ( deckstring ) ) ; } ; window [ 'buildDeck' ] = async ( decklist , hero ) => { const cards = decklist . split ( '\n' ) ; console . debug ( cards ) ; const allCards = this . cards . getAllCards ( ) ; const cardArray = cards . map ( ( card ) => { const [ name , count ] = card . split ( '#' ) ; const result = [ allCards . filter ( ( card ) => card . id === name ) . length > 0 ? allCards . filter ( ( card ) => card . id === name ) : allCards . filter ( ( card ) => card . name === name ) . filter ( ( card ) => [ 'Battlegrounds' , 'Wild_event' ] . indexOf ( card . set ) === - 1 ) . filter ( ( card ) => ! card . id . startsWith ( 'FB_Champs' ) ) . filter ( ( card ) => ! card . id . startsWith ( 'TB_' ) ) . filter ( ( card ) => card . type !== 'Hero' ) . filter ( ( card ) => card . id . indexOf ( 'o' ) === - 1 ) . filter ( ( card ) => card . id . indexOf ( 't' ) === - 1 ) . filter ( ( card ) => card . id . indexOf ( 'e' ) === - 1 ) , count , ] ; if ( result [ 0 ] . length !== 1 ) { console . warn ( 'issue mapping card' , card , result ) ; throw new Error ( 'done' ) ; } return result ; } ) . map ( ( cards ) => { return [ cards [ 0 ] [ 0 ] . dbfId , parseInt ( cards [ 1 ] || 1 ) ] ; } ) ; console . debug ( cardArray ) ; const deck = { cards : cardArray , heroes : [ hero ] , format : 1 , } ; const deckstring = encode ( deck as any ) ; console . debug ( deckstring ) ; console . debug ( decode ( deckstring ) ) ; } ; window [ 'grantAchievement' ] = async ( id ) => { const challenges = await this . achievementLoader . getChallengeModules ( ) ; const challenge = challenges . find ( ( chal ) => chal . achievementId === id ) ; this . achievementsMonitor [ 'sendUnlockEvent' ] ( challenge ) ; } ; } private async loadEvents ( events , awaitEvents , deckstring ? , timeBetweenEvents ? ) { for ( const event of events ) { if ( event . Type === 'BATTLEGROUNDS_NEXT_OPPONENT' ) { await sleep ( 1000 ) ; } if ( event . Type === 'BATTLEGROUNDS_PLAYER_BOARD' ) { await sleep ( 3000 ) ; } if ( awaitEvents ) { await this . gameEvents . dispatchGameEvent ( { ... event } ) ; if ( timeBetweenEvents ) { await sleep ( timeBetweenEvents ) ; } } else { this . gameEvents . dispatchGameEvent ( { ... event } ) ; } if ( deckstring && event . Type === 'LOCAL_PLAYER' ) { await sleep ( 500 ) ; const decklist = this . handler . buildDeckList ( deckstring ) ; let newDeck = decklist ; const currentState = this . gameState . state ; const deck = currentState . playerDeck ; for ( const card of [ ... deck . hand , ... deck . otherZone , ... deck . board ] ) { newDeck = this . helper . removeSingleCardFromZone ( newDeck , card . cardId , card . entityId ) [ 0 ] ; } const newPlayerDeck = deck . update ( { deckstring : deckstring , deckList : decklist , deck : deckstring ? this . flagCards ( newDeck ) : newDeck , hand : deckstring ? this . flagCards ( deck . hand ) : deck . hand , otherZone : deckstring ? this . flagCards ( deck . otherZone ) : deck . otherZone , } as DeckState ) ; console . debug ( '[opponent-player] newPlayerDeck' , newPlayerDeck ) ; this . gameState . state = currentState . update ( { playerDeck : newPlayerDeck , } as GameState ) ; console . debug ( 'updated decklist' , this . gameState . state ) ; } } } private addCustomLogLoaderCommand ( ) { } private flagCards ( cards ) { return cards . map ( ( card ) => card . update ( { inInitialDeck : true , } as DeckCard ) ) ; } } function sleep ( ms ) { return new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ; }