2017-02-01 04:44:59 -08:00
package magic.data.stats ;
import java.sql.SQLException ;
import java.util.ArrayList ;
import java.util.List ;
2020-01-15 12:02:42 -08:00
import org.h2.api.ErrorCode ;
2017-02-01 04:44:59 -08:00
import magic.data.DeckType ;
import magic.data.DuelConfig ;
import magic.data.GeneralConfig ;
import magic.data.stats.h2.H2Database ;
import magic.model.MagicDeck ;
import magic.model.MagicDuel ;
import magic.model.MagicGame ;
import magic.ui.ScreenController ;
import magic.utility.DeckUtils ;
import magic.utility.MagicSystem ;
public final class MagicStats {
private MagicStats ( ) { }
private static final GeneralConfig CONFIG = GeneralConfig . getInstance ( ) ;
// do not access directly, use getDB().
private static H2Database db ;
private static H2Database getDB ( ) throws SQLException {
// primarily to prevent multiple threads trying
// to update the schema at the same time.
synchronized ( MagicStats . class ) {
if ( db = = null ) {
db = new H2Database ( ) ;
}
return db ;
}
}
public static void init ( ) {
try {
getDB ( ) ;
} catch ( Exception ex ) {
HandleErrorDisableStats ( ex ) ;
}
}
private static boolean isDatabaseAlreadyOpenError ( Exception ex ) {
return ex instanceof SQLException
& & ( ( SQLException ) ex ) . getErrorCode ( ) = = ErrorCode . DATABASE_ALREADY_OPEN_1 ;
}
private static void HandleErrorDisableStats ( Exception ex ) {
CONFIG . setGameStatsEnabled ( false ) ;
if ( isDatabaseAlreadyOpenError ( ex ) ) {
ScreenController . showWarningMessage ( H2Database . getDatabaseFile ( ) + "\n\nCannot connect to stats database as it is already open.\nStats have been switched off (see setting in preferences)." ) ;
} else {
CONFIG . save ( ) ;
throw new RuntimeException ( ex ) ;
}
}
/ * *
2017-05-17 06:13:31 -07:00
* Only log game stats for a normal human vs AI game .
* /
private static boolean isNormalGame ( MagicGame game ) {
return ! game . isArtificial ( )
& & ! MagicSystem . isTestGame ( )
& & ! MagicSystem . isDevMode ( )
& & ! MagicSystem . isAiVersusAi ( ) ;
}
/ * *
* Currently stats are only logged when , at the end of game , you click on
2017-02-01 04:44:59 -08:00
* the resume button to take you back to the duel decks screen . If after the
* game ends you open the menu and click back to the main menu no stats are logged .
* /
public static void logStats ( MagicDuel duel , MagicGame game ) {
2017-05-17 06:13:31 -07:00
if ( isNormalGame ( game ) ) {
saveGameData ( game ) ;
logFileBasedStats ( duel , game ) ;
2017-02-01 04:44:59 -08:00
}
}
/ * *
* Logs player stats using the old , file - based way and which are currently
* displayed on the new duel and player selection screens .
*
* TODO : phase out / replace with database system .
* /
private static void logFileBasedStats ( MagicDuel duel , MagicGame game ) {
if ( ! MagicSystem . isAiVersusAi ( ) ) {
// log player stats using the old way.
final DuelConfig duelConfig = duel . getConfiguration ( ) ;
final boolean won = game . getLosingPlayer ( ) ! = game . getPlayers ( ) [ 0 ] ;
duelConfig . getPlayerProfile ( 0 ) . getStats ( ) . update ( won , game . getPlayer ( 0 ) , game ) ;
duelConfig . getPlayerProfile ( 1 ) . getStats ( ) . update ( ! won , game . getPlayer ( 1 ) , game ) ;
}
}
/ * *
* Saves detailed game data to database .
* /
public static void saveGameData ( MagicGame game ) {
if ( CONFIG . isGameStatsEnabled ( ) ) {
try {
getDB ( ) . logGameStats ( game ) ;
} catch ( Exception ex ) {
HandleErrorDisableStats ( ex ) ;
}
}
}
public static String getPlayedWonLost ( MagicDeck deck ) {
if ( CONFIG . isGameStatsEnabled ( ) ) {
try {
return getDB ( ) . getPlayedWonLost ( deck ) ;
} catch ( Exception ex ) {
HandleErrorDisableStats ( ex ) ;
}
}
return "" ;
}
public static int getTotalGamesPlayed ( ) {
if ( CONFIG . isGameStatsEnabled ( ) ) {
try {
return getDB ( ) . getTotalGamesPlayed ( ) ;
} catch ( Exception ex ) {
HandleErrorDisableStats ( ex ) ;
}
}
return 0 ;
}
public static int getTotalGamesPlayed ( MagicDeck deck ) {
if ( CONFIG . isGameStatsEnabled ( ) ) {
try {
return getDB ( ) . getTotalGamesPlayed ( deck ) ;
} catch ( Exception ex ) {
HandleErrorDisableStats ( ex ) ;
}
}
return 0 ;
}
public static List < GameStatsInfo > getGameStats ( int limit , int rowsToSkip ) {
if ( CONFIG . isGameStatsEnabled ( ) ) {
try {
return getDB ( ) . getGameStats ( limit , rowsToSkip ) ;
} catch ( Exception ex ) {
HandleErrorDisableStats ( ex ) ;
}
}
return new ArrayList < > ( ) ;
}
public static List < GameStatsInfo > getGameStats ( MagicDeck deck , int limit , int page ) {
if ( CONFIG . isGameStatsEnabled ( ) ) {
try {
return getDB ( ) . getGameStats ( deck , limit , page ) ;
} catch ( Exception ex ) {
HandleErrorDisableStats ( ex ) ;
}
}
return new ArrayList < > ( ) ;
}
2017-01-31 18:38:45 -08:00
public static String getSchemaVersion ( ) {
if ( CONFIG . isGameStatsEnabled ( ) ) {
try {
return getDB ( ) . getSchemaVersion ( ) ;
} catch ( Exception ex ) {
HandleErrorDisableStats ( ex ) ;
}
}
return "" ;
}
2017-03-31 02:57:02 -07:00
private static List < MagicDeck > getTopDecks ( List < DeckStatsInfo > decksInfo ) {
List < MagicDeck > decks = new ArrayList < > ( ) ;
for ( DeckStatsInfo info : decksInfo ) {
MagicDeck deck = DeckUtils . loadDeckFromFile (
info . deckName , DeckType . valueOf ( info . deckType )
) ;
if ( DeckUtils . getDeckFileChecksum ( deck ) = = info . deckCheckSum ) {
decks . add ( deck ) ;
}
}
return decks ;
}
2017-02-01 04:44:59 -08:00
private static List < DeckStatsInfo > getMostPlayedDecks ( int limit ) {
if ( CONFIG . isGameStatsEnabled ( ) ) {
try {
return getDB ( ) . getMostPlayedDecks ( limit ) ;
} catch ( Exception ex ) {
HandleErrorDisableStats ( ex ) ;
}
}
return new ArrayList < > ( ) ;
}
public static List < MagicDeck > getMostPlayedDecks ( ) {
2017-03-31 02:57:02 -07:00
return getTopDecks ( getMostPlayedDecks ( 20 ) ) ;
2017-02-01 04:44:59 -08:00
}
2017-01-31 18:38:45 -08:00
private static List < DeckStatsInfo > getTopWinningDecks ( int limit ) {
2017-02-01 04:44:59 -08:00
if ( CONFIG . isGameStatsEnabled ( ) ) {
try {
2017-01-31 18:38:45 -08:00
return getDB ( ) . getTopWinningDecks ( limit ) ;
2017-02-01 04:44:59 -08:00
} catch ( Exception ex ) {
HandleErrorDisableStats ( ex ) ;
}
}
2017-01-31 18:38:45 -08:00
return new ArrayList < > ( ) ;
}
public static List < MagicDeck > getTopWinningDecks ( ) {
2017-03-31 02:57:02 -07:00
return getTopDecks ( getTopWinningDecks ( 20 ) ) ;
2017-02-01 04:44:59 -08:00
}
2017-01-31 18:50:01 -08:00
private static List < DeckStatsInfo > getRecentlyPlayedDecks ( int limit ) {
if ( CONFIG . isGameStatsEnabled ( ) ) {
try {
return getDB ( ) . getRecentlyPlayedDecks ( limit ) ;
} catch ( Exception ex ) {
HandleErrorDisableStats ( ex ) ;
}
}
return new ArrayList < > ( ) ;
}
public static List < MagicDeck > getRecentlyPlayedDecks ( ) {
2017-03-31 02:57:02 -07:00
return getTopDecks ( getRecentlyPlayedDecks ( 20 ) ) ;
2017-01-31 18:50:01 -08:00
}
2017-02-01 04:44:59 -08:00
}