2017-04-06 12:00:36 +02:00
/ * *
* cemu_UI
*
* Copyright 2017 < @Seil0 >
*
2017-10-15 13:37:45 +02:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
2017-04-06 12:00:36 +02:00
*
2017-10-15 13:37:45 +02:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston ,
* MA 02110 - 1301 , USA .
2017-04-06 12:00:36 +02:00
* /
2017-10-15 13:37:45 +02:00
2017-11-13 16:44:39 +01:00
package com.cemu_UI.controller ;
2017-03-23 13:44:21 +01:00
import java.awt.Graphics2D ;
import java.awt.image.BufferedImage ;
import java.io.File ;
import java.io.IOException ;
import java.net.URL ;
import java.sql.Connection ;
import java.sql.DriverManager ;
import java.sql.ResultSet ;
import java.sql.SQLException ;
import java.sql.Statement ;
2017-03-25 15:18:45 +01:00
import java.util.ArrayList ;
2017-03-23 13:44:21 +01:00
import java.util.List ;
import javax.imageio.ImageIO ;
import javax.xml.parsers.DocumentBuilder ;
import javax.xml.parsers.DocumentBuilderFactory ;
import javax.xml.parsers.ParserConfigurationException ;
import org.apache.commons.io.FileUtils ;
2017-09-12 15:04:21 +02:00
import org.apache.logging.log4j.LogManager ;
import org.apache.logging.log4j.Logger ;
2017-03-23 13:44:21 +01:00
import org.w3c.dom.Document ;
import org.xml.sax.SAXException ;
2017-11-13 16:44:39 +01:00
import com.cemu_UI.application.MainWindowController ;
2017-12-12 11:19:33 +01:00
public class DBController {
2017-03-23 13:44:21 +01:00
2017-12-12 11:19:33 +01:00
public DBController ( MainWindowController mwc ) {
mainWindowController = mwc ;
2017-03-23 13:44:21 +01:00
}
private MainWindowController mainWindowController ;
2017-03-25 15:18:45 +01:00
private ArrayList < String > entries = new ArrayList < > ( ) ;
2017-11-27 10:57:16 +01:00
private String DB_PATH_localRoms ;
2017-03-23 13:44:21 +01:00
private String DB_PATH_games ;
private Connection connection = null ;
private Connection connectionGames = null ;
2017-12-12 11:19:33 +01:00
private static final Logger LOGGER = LogManager . getLogger ( DBController . class . getName ( ) ) ;
2017-03-23 13:44:21 +01:00
2017-12-12 11:19:33 +01:00
/ * *
* initialize the sqlite database controller
* load ROM and games database
* load all games
* /
public void init ( ) {
2017-09-12 15:04:21 +02:00
LOGGER . info ( " <==========starting loading sql==========> " ) ;
2017-03-23 13:44:21 +01:00
loadRomDatabase ( ) ;
loadGamesDatabase ( ) ;
createRomDatabase ( ) ;
2017-11-27 10:57:16 +01:00
loadAllGames ( ) ;
2017-03-23 13:44:21 +01:00
checkRemoveEntry ( ) ;
2017-09-12 15:04:21 +02:00
LOGGER . info ( " <==========finished loading sql==========> " ) ;
2017-03-23 13:44:21 +01:00
}
2017-11-27 10:57:16 +01:00
/ * *
* set the path to the localRoms . db file and initialize the connection
*
* TODO this should be called LocalGames
* /
2017-03-23 13:44:21 +01:00
private void loadRomDatabase ( ) {
if ( System . getProperty ( " os.name " ) . equals ( " Linux " ) ) {
2017-11-27 10:57:16 +01:00
DB_PATH_localRoms = System . getProperty ( " user.home " ) + " /cemu_UI/localRoms.db " ;
2017-03-23 13:44:21 +01:00
} else {
2017-11-27 10:57:16 +01:00
DB_PATH_localRoms = System . getProperty ( " user.home " ) + " \\ Documents \\ cemu_UI " + " \\ " + " localRoms.db " ;
2017-03-23 13:44:21 +01:00
}
try {
// create a database connection
2017-11-27 10:57:16 +01:00
connection = DriverManager . getConnection ( " jdbc:sqlite: " + DB_PATH_localRoms ) ;
2017-03-23 13:44:21 +01:00
connection . setAutoCommit ( false ) ; //AutoCommit to false -> manual commit is active
} catch ( SQLException e ) {
// if the error message is "out of memory", it probably means no database file is found
2017-09-12 15:04:21 +02:00
LOGGER . error ( " error while loading the ROM database " , e ) ;
2017-03-23 13:44:21 +01:00
}
2017-09-12 15:04:21 +02:00
LOGGER . info ( " ROM database loaded successfull " ) ;
2017-03-23 13:44:21 +01:00
}
/ * *
2017-11-27 10:57:16 +01:00
* set the path to the localRoms . db file and initialize the connection
*
* games . dbcontains a reverence list to for the automatic detection mode
2017-12-12 12:02:28 +01:00
* TODO rework paths
2017-03-23 13:44:21 +01:00
* /
2017-11-27 10:57:16 +01:00
private void loadGamesDatabase ( ) {
2017-03-23 13:44:21 +01:00
if ( System . getProperty ( " os.name " ) . equals ( " Linux " ) ) {
2017-12-12 12:02:28 +01:00
DB_PATH_games = System . getProperty ( " user.home " ) + " /cemu_UI/reference_games.db " ;
2017-11-27 10:57:16 +01:00
} else {
2017-12-12 12:02:28 +01:00
DB_PATH_games = System . getProperty ( " user.home " ) + " \\ Documents \\ cemu_UI " + " \\ " + " reference_games.db " ;
2017-03-23 13:44:21 +01:00
}
try {
// create a database connection
connectionGames = DriverManager . getConnection ( " jdbc:sqlite: " + DB_PATH_games ) ;
2017-11-27 10:57:16 +01:00
connectionGames . setAutoCommit ( false ) ; // AutoCommit to false -> manual commit is active
2017-03-23 13:44:21 +01:00
} catch ( SQLException e ) {
2017-09-12 15:04:21 +02:00
LOGGER . error ( " error while loading the games database " , e ) ;
2017-03-23 13:44:21 +01:00
}
2017-09-12 15:04:21 +02:00
LOGGER . info ( " games database loaded successfull " ) ;
2017-03-23 13:44:21 +01:00
}
2017-12-09 13:10:19 +01:00
2017-11-27 10:57:16 +01:00
/ * *
* creating the local_roms table in localRoms . db
* if the table has no entries , call loadRomDirectory
*
* TODO the local_roms table should be called local_games
* /
void createRomDatabase ( ) {
2017-03-23 13:44:21 +01:00
try {
Statement stmt = connection . createStatement ( ) ;
stmt . executeUpdate ( " create table if not exists local_roms (title, coverPath, romPath, titleID, productCode, region, lastPlayed, timePlayed) " ) ;
stmt . close ( ) ;
connection . commit ( ) ;
2017-09-12 15:04:21 +02:00
} catch ( SQLException e ) {
LOGGER . error ( " error while creating ROM database " , e ) ;
2017-03-23 13:44:21 +01:00
}
2017-11-27 10:57:16 +01:00
try {
Statement stmt = connection . createStatement ( ) ;
ResultSet rs = stmt . executeQuery ( " SELECT * FROM local_roms " ) ;
while ( rs . next ( ) ) {
2017-03-25 15:18:45 +01:00
entries . add ( rs . getString ( 2 ) ) ;
}
stmt . close ( ) ;
rs . close ( ) ;
2017-11-27 10:57:16 +01:00
} catch ( SQLException e ) {
2017-09-12 15:04:21 +02:00
LOGGER . error ( " error while loading ROMs from ROM database, local_roms table " , e ) ;
2017-03-25 15:18:45 +01:00
}
2017-11-27 10:57:16 +01:00
if ( entries . size ( ) = = 0 ) {
2017-03-25 15:18:45 +01:00
loadRomDirectory ( mainWindowController . getRomPath ( ) ) ;
}
2017-03-23 13:44:21 +01:00
}
2017-11-27 10:57:16 +01:00
// add a Ggame to the database
public void addGame ( String title , String coverPath , String romPath , String titleID , String productCode , String region , String lastPlayed , String timePlayed ) throws SQLException {
2017-03-23 13:44:21 +01:00
Statement stmt = connection . createStatement ( ) ;
2017-10-31 14:11:17 +01:00
stmt . executeUpdate ( " insert into local_roms values (' " + title + " ',' " + coverPath + " ',' " + romPath + " ',' " + titleID + " ', "
+ " ' " + productCode + " ',' " + region + " ',' " + lastPlayed + " ',' " + timePlayed + " ') " ) ;
2017-03-23 13:44:21 +01:00
connection . commit ( ) ;
stmt . close ( ) ;
2017-09-12 15:04:21 +02:00
LOGGER . info ( " added \" " + title + " \" to ROM database " ) ;
2017-03-23 13:44:21 +01:00
}
2017-11-27 10:57:16 +01:00
public void removeGame ( String titleID ) throws SQLException {
2017-03-23 13:44:21 +01:00
Statement stmt = connection . createStatement ( ) ;
stmt . executeUpdate ( " delete from local_roms where titleID = ' " + titleID + " ' " ) ;
connection . commit ( ) ;
stmt . close ( ) ;
2017-09-12 15:04:21 +02:00
LOGGER . info ( " removed \" " + titleID + " \" from ROM database " ) ;
2017-03-23 13:44:21 +01:00
}
2017-09-12 15:04:21 +02:00
//load all ROMs on startup to the mainWindowController
2017-11-27 10:57:16 +01:00
void loadAllGames ( ) {
LOGGER . info ( " loading all games on startup into the mainWindowController ... " ) ;
2017-03-23 13:44:21 +01:00
try {
Statement stmt = connection . createStatement ( ) ;
ResultSet rs = stmt . executeQuery ( " SELECT * FROM local_roms " ) ;
while ( rs . next ( ) ) {
mainWindowController . addGame ( rs . getString ( 1 ) , rs . getString ( 2 ) , rs . getString ( 3 ) , rs . getString ( 4 ) ) ;
}
stmt . close ( ) ;
rs . close ( ) ;
} catch ( Exception e ) {
2017-11-27 10:57:16 +01:00
LOGGER . error ( " error while loading all games into the mainWindowController " , e ) ;
2017-03-23 13:44:21 +01:00
}
}
2017-09-12 15:04:21 +02:00
//load one single ROM after manual adding into the mainWindowController
2017-11-27 10:57:16 +01:00
public void loadSingleGame ( String titleID ) {
LOGGER . info ( " loading a single game (ID: " + titleID + " ) into the mainWindowController ... " ) ;
2017-03-23 13:44:21 +01:00
try {
Statement stmt = connection . createStatement ( ) ;
ResultSet rs = stmt . executeQuery ( " SELECT * FROM local_roms where titleID = ' " + titleID + " ' " ) ;
while ( rs . next ( ) ) {
mainWindowController . addGame ( rs . getString ( 1 ) , rs . getString ( 2 ) , rs . getString ( 3 ) , rs . getString ( 4 ) ) ;
}
stmt . close ( ) ;
rs . close ( ) ;
} catch ( Exception e ) {
2017-11-27 10:57:16 +01:00
LOGGER . error ( " error while loading a single game into the mainWindowController " , e ) ;
2017-03-23 13:44:21 +01:00
}
}
2017-11-27 10:57:16 +01:00
/ * *
* get all . rpx files from a given directory and add them to the games database if they don ' t exist there
* @param directory where to search for the . rpx files
* /
2017-11-13 16:44:39 +01:00
public void loadRomDirectory ( String directory ) {
2017-03-23 13:44:21 +01:00
File dir = new File ( directory ) ;
2017-04-08 02:25:23 +02:00
File appFile ;
2017-03-23 13:44:21 +01:00
String [ ] extensions = new String [ ] { " rpx " , " jsp " } ;
File pictureCache ;
String coverPath ;
if ( System . getProperty ( " os.name " ) . equals ( " Linux " ) ) {
2017-11-13 16:44:39 +01:00
pictureCache = mainWindowController . getPictureCacheLinux ( ) ;
2017-03-23 13:44:21 +01:00
} else {
2017-11-13 16:44:39 +01:00
pictureCache = mainWindowController . getPictureCacheWin ( ) ;
2017-03-23 13:44:21 +01:00
}
try {
2017-10-31 14:11:17 +01:00
Statement stmt = connectionGames . createStatement ( ) ;
2017-03-23 13:44:21 +01:00
List < File > files = ( List < File > ) FileUtils . listFiles ( dir , extensions , true ) ;
2017-10-31 14:11:17 +01:00
LOGGER . info ( " Getting all .rpx files in " + dir . getCanonicalPath ( ) + " including those in subdirectories " ) ;
2017-11-27 10:57:16 +01:00
// for all files in dir get the app.xml
2017-03-23 13:44:21 +01:00
for ( File file : files ) {
2017-12-12 19:19:01 +01:00
appFile = new File ( file . getParent ( ) + " /app.xml " ) ;
2017-03-23 13:44:21 +01:00
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory . newInstance ( ) ;
DocumentBuilder documentBuilder = documentBuilderFactory . newDocumentBuilder ( ) ;
Document document = documentBuilder . parse ( appFile ) ;
2017-12-12 19:19:01 +01:00
String title_ID = document . getElementsByTagName ( " title_id " ) . item ( 0 ) . getTextContent ( ) ; // get titile_ID from app.xml
2017-03-23 13:44:21 +01:00
title_ID = title_ID . substring ( 0 , 8 ) + " - " + title_ID . substring ( 8 , title_ID . length ( ) ) ;
2017-12-12 19:19:01 +01:00
LOGGER . info ( " Name: " + file . getName ( ) + " ; Title ID: " + title_ID ) ;
ResultSet rs = stmt . executeQuery ( " SELECT * FROM games WHERE TitleID = ' " + title_ID + " '; " ) ;
2017-11-27 10:57:16 +01:00
// for all elements in the games table check if it's already present, else add it
2017-03-23 13:44:21 +01:00
while ( rs . next ( ) ) {
if ( checkEntry ( rs . getString ( 2 ) ) ) {
2017-09-12 15:04:21 +02:00
LOGGER . info ( rs . getString ( 2 ) + " : game already in database " ) ;
2017-12-12 19:19:01 +01:00
} else {
2017-09-12 15:04:21 +02:00
LOGGER . info ( " adding cover to cache ... " ) ;
2017-12-12 19:19:01 +01:00
BufferedImage originalImage = ImageIO . read ( new URL ( rs . getString ( 6 ) ) ) ; // change path to where file is located
int type = originalImage . getType ( ) = = 0 ? BufferedImage . TYPE_INT_ARGB : originalImage . getType ( ) ;
BufferedImage resizeImagePNG = resizeImage ( originalImage , type , 400 , 600 ) ;
ImageIO . write ( resizeImagePNG , " png " , new File ( pictureCache + " / " + rs . getString ( 3 ) + " .png " ) ) ;
coverPath = pictureCache + " / " + rs . getString ( 3 ) + " .png " ;
2017-09-12 15:04:21 +02:00
LOGGER . info ( rs . getString ( 2 ) + " : adding ROM " ) ;
2017-12-12 19:19:01 +01:00
addGame ( rs . getString ( 2 ) , coverPath , file . getCanonicalPath ( ) , rs . getString ( 1 ) , rs . getString ( 3 ) ,
rs . getString ( 5 ) , " " , " 0 " ) ;
2017-03-23 13:44:21 +01:00
}
}
}
} catch ( IOException | SQLException | ParserConfigurationException | SAXException e ) {
2017-09-12 15:04:21 +02:00
LOGGER . error ( " error while loading ROMs from directory " , e ) ;
2017-03-23 13:44:21 +01:00
}
}
private boolean checkEntry ( String title ) throws SQLException {
Statement stmt = connection . createStatement ( ) ;
boolean check = false ;
ResultSet rs = stmt . executeQuery ( " SELECT * FROM local_roms WHERE title = ' " + title + " '; " ) ;
while ( rs . next ( ) ) {
check = true ;
}
return check ;
}
private void checkRemoveEntry ( ) {
2017-09-12 15:04:21 +02:00
/ * *
* TODO needs to be implemented !
* don ' t show ROM on the UI , but keep all parameter in case it ' s showing up again ask if old data should be used
* /
//LOGGER.info("check if entry removed not done yet!");
2017-03-23 13:44:21 +01:00
}
private static BufferedImage resizeImage ( BufferedImage originalImage , int type , int IMG_WIDTH , int IMG_HEIGHT ) {
BufferedImage resizedImage = new BufferedImage ( IMG_WIDTH , IMG_HEIGHT , type ) ;
Graphics2D g = resizedImage . createGraphics ( ) ;
g . drawImage ( originalImage , 0 , 0 , IMG_WIDTH , IMG_HEIGHT , null ) ;
g . dispose ( ) ;
return resizedImage ;
}
2017-10-31 14:11:17 +01:00
/ * *
* getting info for a game with titleID
* @param titleID Title - ID of the Game
* @return title , coverPath , romPath , titleID ( in this order )
* /
2017-11-13 16:44:39 +01:00
public String [ ] getGameInfo ( String titleID ) {
2017-10-31 14:11:17 +01:00
String [ ] gameInfo = new String [ 4 ] ;
LOGGER . info ( " getting game info for titleID: " + titleID + " ... " ) ;
try {
Statement stmt = connection . createStatement ( ) ;
ResultSet rs = stmt . executeQuery ( " SELECT * FROM local_roms where titleID = ' " + titleID + " ' " ) ;
while ( rs . next ( ) ) {
gameInfo [ 0 ] = rs . getString ( 1 ) ; // title
gameInfo [ 1 ] = rs . getString ( 2 ) ; // coverPath
gameInfo [ 2 ] = rs . getString ( 3 ) ; // romPath
gameInfo [ 3 ] = rs . getString ( 4 ) ; // titleID
}
stmt . close ( ) ;
rs . close ( ) ;
} catch ( Exception e ) {
LOGGER . error ( " error while getting game info " , e ) ;
}
return gameInfo ;
}
2017-11-15 21:21:52 +01:00
public void setGameInfo ( String title , String coverPath , String romPath , String titleID ) {
2017-10-31 14:11:17 +01:00
LOGGER . info ( " setting game info for titleID: " + titleID + " ... " ) ;
try {
Statement stmt = connection . createStatement ( ) ;
stmt . executeUpdate ( " UPDATE local_roms SET title = ' " + title + " ', coverPath = ' " + coverPath + " ', "
+ " romPath = ' " + romPath + " ' WHERE titleID = ' " + titleID + " '; " ) ;
connection . commit ( ) ;
stmt . close ( ) ;
} catch ( Exception e ) {
LOGGER . error ( " error while setting game info " , e ) ;
}
}
2017-11-13 16:44:39 +01:00
public void setLastPlayed ( String titleID ) {
2017-03-23 13:44:21 +01:00
try {
Statement stmt = connection . createStatement ( ) ;
stmt . executeUpdate ( " UPDATE local_roms SET lastPlayed=date('now') WHERE titleID = ' " + titleID + " '; " ) ;
connection . commit ( ) ;
stmt . close ( ) ;
} catch ( SQLException e ) {
2017-09-12 15:04:21 +02:00
LOGGER . error ( " failed to set the last played " , e ) ;
2017-03-23 13:44:21 +01:00
}
}
2017-11-13 16:44:39 +01:00
public String getLastPlayed ( String titleID ) {
2017-03-23 13:44:21 +01:00
String lastPlayed = null ;
try {
Statement stmt = connection . createStatement ( ) ;
ResultSet rs = stmt . executeQuery ( " SELECT lastPlayed FROM local_roms WHERE titleID = ' " + titleID + " '; " ) ;
lastPlayed = rs . getString ( 1 ) ;
stmt . close ( ) ;
rs . close ( ) ;
} catch ( SQLException e ) {
2017-09-12 15:04:21 +02:00
LOGGER . error ( " failed to get the last played " , e ) ;
2017-03-23 13:44:21 +01:00
}
return lastPlayed ;
}
2017-11-13 16:44:39 +01:00
public void setTotalPlaytime ( String timePlayed , String titleID ) {
2017-03-23 13:44:21 +01:00
try {
Statement stmt = connection . createStatement ( ) ;
2017-03-25 15:18:45 +01:00
stmt . executeUpdate ( " UPDATE local_roms SET timePlayed=' " + timePlayed + " ' WHERE titleID = ' " + titleID + " '; " ) ;
2017-03-23 13:44:21 +01:00
connection . commit ( ) ;
stmt . close ( ) ;
} catch ( SQLException e ) {
2017-09-12 15:04:21 +02:00
LOGGER . error ( " failed to set total play time " , e ) ;
2017-03-23 13:44:21 +01:00
e . printStackTrace ( ) ;
}
}
2017-11-13 16:44:39 +01:00
public String getTotalPlaytime ( String titleID ) {
2017-03-23 13:44:21 +01:00
String timePlayed = null ;
try {
Statement stmt = connection . createStatement ( ) ;
ResultSet rs = stmt . executeQuery ( " SELECT timePlayed FROM local_roms WHERE titleID = ' " + titleID + " '; " ) ;
2017-03-25 15:18:45 +01:00
timePlayed = rs . getString ( 1 ) ;
2017-03-23 13:44:21 +01:00
stmt . close ( ) ;
rs . close ( ) ;
} catch ( SQLException e ) {
2017-09-12 15:04:21 +02:00
LOGGER . error ( " failed to get total play time " , e ) ;
2017-03-23 13:44:21 +01:00
}
return timePlayed ;
}
2017-03-25 15:18:45 +01:00
2017-10-31 14:11:17 +01:00
2017-03-23 13:44:21 +01:00
}