diff --git a/pom.xml b/pom.xml
index 3a37a6d..c52bdad 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com
cemu_UI
- 0.2.2-SNAPSHOT
+ 0.2.3-SNAPSHOT
jar
cemu_UI
diff --git a/src/main/java/com/cemu_UI/application/Main.java b/src/main/java/com/cemu_UI/application/Main.java
index 18778cd..652b049 100644
--- a/src/main/java/com/cemu_UI/application/Main.java
+++ b/src/main/java/com/cemu_UI/application/Main.java
@@ -51,11 +51,11 @@ import javafx.scene.layout.AnchorPane;
public class Main extends Application {
- Stage primaryStage;
- public MainWindowController mainWindowController; // TODO find a better way
- CloudController cloudController;
- AnchorPane pane;
- Scene scene; // TODO make private
+ private Stage primaryStage;
+ private MainWindowController mainWindowController;
+ private CloudController cloudController;
+ private AnchorPane pane;
+ private Scene scene;
private static String userHome = System.getProperty("user.home");
private static String userName = System.getProperty("user.name");
private static String osName = System.getProperty("os.name");
@@ -69,8 +69,7 @@ public class Main extends Application {
private File directory;
private File configFile;
private File gamesDBFile;
- @SuppressWarnings("unused")
- private File localDB;
+ private File reference_gamesFile;
private File pictureCache;
private static Logger LOGGER;
@@ -97,7 +96,7 @@ public class Main extends Application {
primaryStage.setTitle("cemu_UI");
// primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("/resources/Homeflix_Icon_64x64.png"))); //adds application icon
- mainWindowController = loader.getController(); // Link of FXMLController and controller class
+ mainWindowController = loader.getController(); // Link of FXMLController and controller class
mainWindowController.setMain(this); // call setMain
cloudController = new CloudController(mainWindowController); // call cloudController constructor
@@ -106,13 +105,13 @@ public class Main extends Application {
directory = new File(dirLinux);
configFile = new File(dirLinux + "/config.xml");
gamesDBFile = new File(dirLinux + "/games.db");
- localDB = new File(dirLinux+"/localRoms.db");
+ reference_gamesFile = new File(dirLinux + "/reference_games.db");
pictureCache= new File(dirLinux+"/picture_cache");
} else {
directory = new File(dirWin);
configFile = new File(dirWin + "/config.xml");
gamesDBFile = new File(dirWin + "/games.db");
- localDB = new File(dirWin+"/localRoms.db");
+ reference_gamesFile = new File(dirWin + "/reference_games.db");
pictureCache= new File(dirWin+"/picture_cache");
}
@@ -139,6 +138,8 @@ public class Main extends Application {
firstStart();
mainWindowController.setColor("00a8cc");
mainWindowController.setAutoUpdate(false);
+ mainWindowController.setLanguage("en_US");
+ mainWindowController.setLastLocalSync(0);
mainWindowController.setxPosHelper(0);
mainWindowController.saveSettings();
Runtime.getRuntime().exec("java -jar cemu_UI.jar"); //start again (preventing Bugs)
@@ -149,12 +150,16 @@ public class Main extends Application {
pictureCache.mkdir();
}
- if (gamesDBFile.exists() != true) {
+
+ if (!reference_gamesFile.exists()) {
+ if (gamesDBFile.exists()) {
+ gamesDBFile.delete();
+ }
try {
- LOGGER.info("downloading games.db... ");
+ LOGGER.info("downloading ReferenceGameList.db... ");
URL website = new URL(gamesDBdownloadURL);
ReadableByteChannel rbc = Channels.newChannel(website.openStream());
- FileOutputStream fos = new FileOutputStream(gamesDBFile);
+ FileOutputStream fos = new FileOutputStream(reference_gamesFile);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
LOGGER.info("finished downloading games.db");
@@ -165,11 +170,12 @@ public class Main extends Application {
// loading settings and initialize UI, dbController.main() loads all databases
mainWindowController.init();
- mainWindowController.dbController.main();
+ mainWindowController.dbController.init();
+
// if cloud sync is activated start sync
if(mainWindowController.isCloudSync()) {
cloudController.initializeConnection(mainWindowController.getCloudService(), mainWindowController.getCemuPath());
- cloudController.stratupCheck(mainWindowController.getCloudService(), mainWindowController.getCemuPath());
+ cloudController.sync(mainWindowController.getCloudService(), mainWindowController.getCemuPath(), directory.getPath());
}
mainWindowController.addUIData();
@@ -224,8 +230,6 @@ public class Main extends Application {
@Override
public void changed(ObservableValue extends Number> observable, Number oldValue, final Number newValue) {
int xPosHelperMax = (int) Math.floor((mainWindowController.getMainAnchorPane().getWidth() - 36) / 217);
-
- mainWindowController.refreshplayBtnPosition();
// call only if there is enough space for a new row
if (mainWindowController.getOldXPosHelper() != xPosHelperMax) {
@@ -308,4 +312,36 @@ public class Main extends Application {
public void stop() {
System.exit(0);
}
+
+ public Stage getPrimaryStage() {
+ return primaryStage;
+ }
+
+ public void setPrimaryStage(Stage primaryStage) {
+ this.primaryStage = primaryStage;
+ }
+
+ public CloudController getCloudController() {
+ return cloudController;
+ }
+
+ public void setCloudController(CloudController cloudController) {
+ this.cloudController = cloudController;
+ }
+
+ public AnchorPane getPane() {
+ return pane;
+ }
+
+ public void setPane(AnchorPane pane) {
+ this.pane = pane;
+ }
+
+ public File getDirectory() {
+ return directory;
+ }
+
+ public void setDirectory(File directory) {
+ this.directory = directory;
+ }
}
diff --git a/src/main/java/com/cemu_UI/application/MainWindowController.java b/src/main/java/com/cemu_UI/application/MainWindowController.java
index 14a7c71..55fb730 100644
--- a/src/main/java/com/cemu_UI/application/MainWindowController.java
+++ b/src/main/java/com/cemu_UI/application/MainWindowController.java
@@ -42,7 +42,9 @@ import java.sql.SQLException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
+import java.util.Locale;
import java.util.Properties;
+import java.util.ResourceBundle;
import javax.imageio.ImageIO;
import javax.swing.ProgressMonitor;
@@ -54,7 +56,7 @@ import org.apache.logging.log4j.Logger;
import com.cemu_UI.controller.SmmdbAPIController;
import com.cemu_UI.controller.UpdateController;
-import com.cemu_UI.controller.dbController;
+import com.cemu_UI.controller.DBController;
import com.cemu_UI.datatypes.CourseTableDataType;
import com.cemu_UI.datatypes.SmmdbApiDataType;
import com.cemu_UI.datatypes.UIROMDataType;
@@ -170,6 +172,9 @@ public class MainWindowController {
@FXML
private JFXToggleButton fullscreenToggleBtn;
+
+ @FXML
+ private ChoiceBox languageChoisBox;
@FXML
private ChoiceBox branchChoisBox;
@@ -203,6 +208,9 @@ public class MainWindowController {
@FXML
private HBox topHBox;
+
+ @FXML
+ private HBox bottomHBox;
@FXML
private ImageView smmdbImageView;
@@ -221,6 +229,9 @@ public class MainWindowController {
@FXML
private Label mainColorLbl;
+
+ @FXML
+ private Label languageLbl;
@FXML
private Label updateLbl;
@@ -253,7 +264,7 @@ public class MainWindowController {
private JFXTreeTableColumn timeColumn = new JFXTreeTableColumn<>("time");
Main main;
- dbController dbController;
+ DBController dbController;
SmmdbAPIController smmdbAPIController;
playGame playGame;
private static MainWindowController MWC;
@@ -275,8 +286,8 @@ public class MainWindowController {
private String selectedGameTitleID;
private String selectedGameTitle;
private String id;
- private String version = "0.2.2";
- private String buildNumber = "061";
+ private String version = "0.2.3";
+ private String buildNumber = "071";
private String versionName = "Puzzle Plank Galaxy";
private int xPos = -200;
private int yPos = 17;
@@ -284,6 +295,7 @@ public class MainWindowController {
private int oldXPosHelper;
private int selectedUIDataIndex;
private int selected;
+ private long lastLocalSync;
private double windowWidth;
private double windowHeight;
private DirectoryChooser directoryChooser = new DirectoryChooser();
@@ -294,6 +306,7 @@ public class MainWindowController {
private File pictureCacheWin = new File(dirWin + "/picture_cache");
private File pictureCacheLinux = new File(dirLinux + "/picture_cache");
private ObservableList branches = FXCollections.observableArrayList("stable", "beta");
+ private ObservableList languages = FXCollections.observableArrayList("English (en_US)", "Deutsch (de_DE)");
private ObservableList smmIDs = FXCollections.observableArrayList("fe31b7f2", "44fc5929"); // TODO add more IDs
private ObservableList games = FXCollections.observableArrayList();
ObservableList courses = FXCollections.observableArrayList();
@@ -322,10 +335,45 @@ public class MainWindowController {
private ImageView cached_white = new ImageView(new Image("icons/ic_cached_white_24dp_1x.png"));
private ImageView smmdb_white = new ImageView(new Image("icons/ic_get_app_white_24dp_1x.png"));
private Image close_black = new Image("icons/close_black_2048x2048.png");
-
- public void setMain(Main main) {
- this.main = main;
- dbController = new dbController(this);
+
+ // language support
+ private ResourceBundle bundle;
+ private String language;
+ private String editHeadingText;
+ private String editBodyText;
+ private String removeHeadingText;
+ private String removeBodyText;
+ private String addUpdateHeadingText;
+ private String addUpdateBodyText;
+ private String addDLCHeadingText;
+ private String addDLCBodyText;
+ private String licensesLblHeadingText;
+ private String licensesLblBodyText;
+ private String showLicenses;
+ private String aboutBtnHeadingText;
+ private String aboutBtnBodyText;
+ private String cloudSyncWaringHeadingText;
+ private String cloudSyncWaringBodyText;
+ private String cloudSyncErrorHeadingText;
+ private String cloudSyncErrorBodyText;
+ private String addGameBtnHeadingText;
+ private String addGameBtnBodyText;
+ private String addBtnReturnErrorHeadingText;
+ private String addBtnReturnErrorBodyText;
+ private String lastPlayed;
+ private String today;
+ private String yesterday;
+ private String never;
+
+ private String playBtnPlay;
+ private String playBtnUpdating;
+ private String playBtnCopyingFiles;
+ private String smmdbDownloadBtnLoading;
+ private String smmdbDownloadBtnDownload;
+
+ public void setMain(Main m) {
+ this.main = m;
+ dbController = new DBController(this);
smmdbAPIController = new SmmdbAPIController();
}
@@ -349,7 +397,6 @@ public class MainWindowController {
if (getWindowWidth() > 100 && getWindowHeight() > 100) {
mainAnchorPane.setPrefSize(getWindowWidth(), getWindowHeight());
}
- refreshplayBtnPosition();
cemuTextField.setText(cemuPath);
romTextField.setText(romPath);
@@ -358,6 +405,8 @@ public class MainWindowController {
cloudSyncToggleBtn.setSelected(isCloudSync());
autoUpdateToggleBtn.setSelected(isAutoUpdate());
branchChoisBox.setItems(branches);
+ languageChoisBox.setItems(languages);
+ bottomHBox.setPickOnBounds(false);
if (isUseBeta()) {
branchChoisBox.getSelectionModel().select(1);
@@ -387,6 +436,8 @@ public class MainWindowController {
courseTreeTable.getColumns().add(idColumn);
courseTreeTable.getColumns().get(3).setVisible(false); // the idColumn should not bee displayed
+ setUILanguage();
+
LOGGER.info("initializing UI done");
}
@@ -433,10 +484,9 @@ public class MainWindowController {
String[] gameInfo = dbController.getGameInfo(selectedGameTitleID);
// new edit dialog
- String headingText = "edit a game";
- String bodyText = "You can edit the tile and rom/cover path.";
- JFXEditGameDialog editGameDialog = new JFXEditGameDialog(headingText, bodyText, dialogBtnStyle, 450,
- 300, 1, MWC, main.primaryStage, main.pane);
+ String headingText = editHeadingText + " \"" + selectedGameTitle + "\"";
+ JFXEditGameDialog editGameDialog = new JFXEditGameDialog(headingText, editBodyText, dialogBtnStyle, 450,
+ 300, 1, MWC, main.getPrimaryStage(), main.getPane());
editGameDialog.setTitle(gameInfo[0]);
editGameDialog.setCoverPath(gameInfo[1]);
editGameDialog.setRomPath(gameInfo[2]);
@@ -453,8 +503,8 @@ public class MainWindowController {
public void handle(ActionEvent event) {
try {
LOGGER.info("remove " + selectedGameTitle + "(" + selectedGameTitleID + ")");
- String headingText = "remove \"" + selectedGameTitle + "\"";
- String bodyText = "Are you sure you want to delete " + selectedGameTitle + " ?";
+ String headingText = removeHeadingText + " \"" + selectedGameTitle + "\"";
+ String bodyText = removeBodyText + " " + selectedGameTitle + " ?";
EventHandler okayAction = new EventHandler() {
@Override
public void handle(ActionEvent event) {
@@ -471,12 +521,12 @@ public class MainWindowController {
EventHandler cancelAction = new EventHandler() {
@Override
public void handle(ActionEvent event) {
- // do nothing
+ LOGGER.info("Action canceld by user!");
}
};
JFXOkayCancelDialog removeGameDialog = new JFXOkayCancelDialog(headingText, bodyText,
- dialogBtnStyle, 350, 170, okayAction, cancelAction, main.pane);
+ dialogBtnStyle, 350, 170, okayAction, cancelAction, main.getPane(), bundle);
removeGameDialog.show();
} catch (Exception e) {
LOGGER.error("error while removing " + selectedGameTitle + "(" + selectedGameTitleID + ")", e);
@@ -489,23 +539,16 @@ public class MainWindowController {
public void handle(ActionEvent event) {
try {
LOGGER.info("update: " + selectedGameTitleID);
- String headingText = "update \"" + selectedGameTitle + "\"";
- String bodyText = "pleas select the update root directory";
+ String headingText = addUpdateHeadingText + " \"" + selectedGameTitle + "\"";
EventHandler okayAction = new EventHandler() {
@Override
public void handle(ActionEvent event) {
DirectoryChooser directoryChooser = new DirectoryChooser();
- File selectedDirecroty = directoryChooser.showDialog(main.primaryStage);
+ File selectedDirecroty = directoryChooser.showDialog(main.getPrimaryStage());
String updatePath = selectedDirecroty.getAbsolutePath();
String[] parts = selectedGameTitleID.split("-"); // split string into 2 parts at "-"
File srcDir = new File(updatePath);
- File destDir;
-
- if (System.getProperty("os.name").equals("Linux")) {
- destDir = new File(cemuPath + "/mlc01/usr/title/" + parts[0] + "/" + parts[1]);
- } else {
- destDir = new File(cemuPath + "\\mlc01\\usr\\title\\" + parts[0] + "\\" + parts[1]);
- }
+ File destDir = new File(cemuPath + "/mlc01/usr/title/" + parts[0] + "/" + parts[1]);
// if directory doesn't exist create it
if (destDir.exists() != true) {
@@ -514,10 +557,10 @@ public class MainWindowController {
try {
LOGGER.info("copying the content of " + updatePath + " to " + destDir.toString());
- playBtn.setText("updating...");
+ playBtn.setText(playBtnUpdating);
playBtn.setDisable(true);
- FileUtils.copyDirectory(srcDir, destDir); // TODO progress indicator
- playBtn.setText("play");
+ FileUtils.copyDirectory(srcDir, destDir);
+ playBtn.setText(playBtnPlay);
playBtn.setDisable(false);
LOGGER.info("copying files done!");
} catch (IOException e) {
@@ -529,12 +572,12 @@ public class MainWindowController {
EventHandler cancelAction = new EventHandler() {
@Override
public void handle(ActionEvent event) {
- // do nothing
+ LOGGER.info("Action canceld by user!");
}
};
- JFXOkayCancelDialog updateGameDialog = new JFXOkayCancelDialog(headingText, bodyText,
- dialogBtnStyle, 350, 170, okayAction, cancelAction, main.pane);
+ JFXOkayCancelDialog updateGameDialog = new JFXOkayCancelDialog(headingText, addUpdateBodyText,
+ dialogBtnStyle, 350, 170, okayAction, cancelAction, main.getPane(), bundle);
updateGameDialog.show();
} catch (Exception e) {
LOGGER.warn("trying to update " + selectedGameTitleID + ",which is not a valid type!", e);
@@ -547,23 +590,16 @@ public class MainWindowController {
public void handle(ActionEvent event) {
try {
LOGGER.info("add DLC: " + selectedGameTitleID);
- String headingText = "add a DLC to \"" + selectedGameTitle + "\"";
- String bodyText = "pleas select the DLC root directory";
+ String headingText = addDLCHeadingText + " \"" + selectedGameTitle + "\"";
EventHandler okayAction = new EventHandler() {
@Override
public void handle(ActionEvent event) {
DirectoryChooser directoryChooser = new DirectoryChooser();
- File selectedDirecroty = directoryChooser.showDialog(main.primaryStage);
+ File selectedDirecroty = directoryChooser.showDialog(main.getPrimaryStage());
String dlcPath = selectedDirecroty.getAbsolutePath();
String[] parts = selectedGameTitleID.split("-"); // split string into 2 parts at "-"
File srcDir = new File(dlcPath);
- File destDir;
- if (System.getProperty("os.name").equals("Linux")) {
- destDir = new File(cemuPath + "/mlc01/usr/title/" + parts[0] + "/" + parts[1] + "/aoc");
- } else {
- destDir = new File(
- cemuPath + "\\mlc01\\usr\\title\\" + parts[0] + "\\" + parts[1] + "\\aoc");
- }
+ File destDir = new File(cemuPath + "/mlc01/usr/title/" + parts[0] + "/" + parts[1] + "/aoc");
// if directory doesn't exist create it
if (destDir.exists() != true) {
@@ -572,10 +608,10 @@ public class MainWindowController {
try {
LOGGER.info("copying the content of " + dlcPath + " to " + destDir.toString());
- playBtn.setText("copying files...");
+ playBtn.setText(playBtnCopyingFiles);
playBtn.setDisable(true);
- FileUtils.copyDirectory(srcDir, destDir); // TODO progress indicator
- playBtn.setText("play");
+ FileUtils.copyDirectory(srcDir, destDir);
+ playBtn.setText(playBtnPlay);
playBtn.setDisable(false);
LOGGER.info("copying files done!");
} catch (IOException e) {
@@ -587,12 +623,12 @@ public class MainWindowController {
EventHandler cancelAction = new EventHandler() {
@Override
public void handle(ActionEvent event) {
- // do nothing
+ LOGGER.info("Action canceld by user!");
}
};
- JFXOkayCancelDialog addDLCDialog = new JFXOkayCancelDialog(headingText, bodyText, dialogBtnStyle,
- 350, 170, okayAction, cancelAction, main.pane);
+ JFXOkayCancelDialog addDLCDialog = new JFXOkayCancelDialog(headingText, addDLCBodyText, dialogBtnStyle,
+ 350, 170, okayAction, cancelAction, main.getPane(), bundle);
addDLCDialog.show();
} catch (Exception e) {
LOGGER.warn("trying to add a dlc to " + selectedGameTitleID + ",which is not a valid type!", e);
@@ -650,7 +686,6 @@ public class MainWindowController {
public void changed(ObservableValue> observable, Object oldVal, Object newVal) {
selected = courseTreeTable.getSelectionModel().getSelectedIndex(); // get selected item
- // FIXME if a item is selected and you change the sorting,you can't select a new item
id = idColumn.getCellData(selected); // get name of selected item
for (int i = 0; i < courses.size(); i++) {
@@ -695,6 +730,17 @@ public class MainWindowController {
}
}
});
+
+ languageChoisBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() {
+ @Override
+ public void changed(ObservableValue extends Number> ov, Number value, Number new_value) {
+ String language = languageChoisBox.getItems().get((int) new_value).toString();
+ language = language.substring(language.length()-6,language.length()-1); //reading only en_US from English (en_US)
+ setLanguage(language);
+ setUILanguage();
+ saveSettings();
+ }
+ });
branchChoisBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener() {
@Override
@@ -712,17 +758,7 @@ public class MainWindowController {
@Override
public void handle(MouseEvent mouseEvent) {
if(mouseEvent.getButton().equals(MouseButton.PRIMARY)){
-
- String headingText = "cemu_UI";
- String bodyText = "cemu_UI is licensed under the terms of GNU GPL 3.\n\n"
- + "JFoenix, Apache License 2.0\n"
- + "minimal-json, MIT License\n"
- + "sqlite-jdbc, Apache License 2.0\n"
- + "Apache Commons IO, Apache License 2.0\n"
- + "Apache Commons Logging, Apache License 2.0\n"
- + "Apache Commons Codec, Apache License 2.0\n"
- + "Apache Log4j 2, Apache License 2.0\n";
-
+
EventHandler okayAction = new EventHandler() {
@Override
public void handle(ActionEvent event) {
@@ -750,16 +786,17 @@ public class MainWindowController {
}
JFXTextAreaInfoDialog licenseDialog = new JFXTextAreaInfoDialog(headingText, bodyText,
- dialogBtnStyle, 510, 450, main.pane);
+ dialogBtnStyle, 510, 450, main.getPane());
licenseDialog.show();
licenseDialog.getTextArea().setEditable(false);
}
};
- JFXOkayCancelDialog licenseOverviewDialog = new JFXOkayCancelDialog(headingText, bodyText, dialogBtnStyle,
- 350, 275, okayAction, cancelAction, main.pane);
- licenseOverviewDialog.setCancelText("show licenses");
- licenseOverviewDialog.show();
+ JFXOkayCancelDialog licenseOverviewDialog = new JFXOkayCancelDialog(licensesLblHeadingText,
+ licensesLblBodyText, dialogBtnStyle, 350, 275, okayAction, cancelAction, main.getPane(),
+ bundle);
+ licenseOverviewDialog.setCancelText(showLicenses);
+ licenseOverviewDialog.show();
}
}
});
@@ -774,12 +811,9 @@ public class MainWindowController {
@FXML
void aboutBtnAction() {
- String headingText = "cemu_UI";
String bodyText = "cemu_UI by @Seil0 \nVersion: " + version + " (" + buildNumber + ") \"" + versionName + "\" \n"
- + "This Application is made with free Software\n"
- + "and licensed under the terms of GNU GPL 3.\n\n"
- + "www.kellerkinder.xyz";
- JFXInfoDialog aboutDialog = new JFXInfoDialog(headingText, bodyText, dialogBtnStyle, 350, 200, main.pane);
+ + aboutBtnBodyText;
+ JFXInfoDialog aboutDialog = new JFXInfoDialog(aboutBtnHeadingText, bodyText, dialogBtnStyle, 350, 200, main.getPane());
aboutDialog.show();
}
@@ -805,9 +839,9 @@ public class MainWindowController {
JFXSpinner spinner = new JFXSpinner();
spinner.setPrefSize(30, 30);
spinner.setStyle(" -fx-background-color: #f4f4f4;");
- main.pane.getChildren().add(spinner);
- AnchorPane.setTopAnchor(spinner, (main.pane.getHeight()-spinner.getPrefHeight())/2);
- AnchorPane.setLeftAnchor(spinner, (main.pane.getWidth()-spinner.getPrefWidth())/2);
+ main.getPane().getChildren().add(spinner);
+ AnchorPane.setTopAnchor(spinner, (main.getPane().getHeight()-spinner.getPrefHeight())/2);
+ AnchorPane.setLeftAnchor(spinner, (main.getPane().getWidth()-spinner.getPrefWidth())/2);
Thread thread = new Thread(new Runnable() {
@Override
@@ -816,7 +850,7 @@ public class MainWindowController {
Platform.runLater(() -> {
refreshUIData(); // refresh the list of games displayed on screen
- main.pane.getChildren().remove(spinner);
+ main.getPane().getChildren().remove(spinner);
});
}
});
@@ -838,7 +872,7 @@ public class MainWindowController {
@Override
public void run() {
Platform.runLater(() -> {
- smmdbDownloadBtn.setText("loading ...");
+ smmdbDownloadBtn.setText(smmdbDownloadBtnLoading);
smmdbDownloadBtn.setDisable(true);
root.getChildren().remove(0,root.getChildren().size());
});
@@ -852,7 +886,7 @@ public class MainWindowController {
Platform.runLater(() -> {
root.getChildren().add(new TreeItem(helpCourse)); // add data to root-node
- smmdbDownloadBtn.setText("Download");
+ smmdbDownloadBtn.setText(smmdbDownloadBtnDownload);
smmdbDownloadBtn.setDisable(false);
});
}
@@ -882,7 +916,7 @@ public class MainWindowController {
@FXML
void cemuTFBtnAction(ActionEvent event) {
- File cemuDirectory = directoryChooser.showDialog(main.primaryStage);
+ File cemuDirectory = directoryChooser.showDialog(main.getPrimaryStage());
if (cemuDirectory == null) {
LOGGER.info("No Directory selected");
} else {
@@ -900,7 +934,7 @@ public class MainWindowController {
@FXML
void romTFBtnAction(ActionEvent event) {
- File romDirectory = directoryChooser.showDialog(main.primaryStage);
+ File romDirectory = directoryChooser.showDialog(main.getPrimaryStage());
if (romDirectory == null) {
LOGGER.info("No Directory selected");
} else {
@@ -1034,10 +1068,6 @@ public class MainWindowController {
if(cloudSync) {
cloudSync = false;
} else {
- String headingText = "activate cloud savegame sync (beta)";
- String bodyText = "You just activate the cloud savegame sync function of cemu_UI, "
- + "\nwhich is currently in beta. Are you sure you want to do this?";
-
EventHandler okayAction = new EventHandler(){
@Override
public void handle(ActionEvent event){
@@ -1050,19 +1080,16 @@ public class MainWindowController {
@Override
public void run() {
- if (main.cloudController.initializeConnection(getCloudService(), getCemuPath())) {
- main.cloudController.sync(getCloudService(), getCemuPath());
+ if (main.getCloudController().initializeConnection(getCloudService(), getCemuPath())) {
+ main.getCloudController().sync(getCloudService(), getCemuPath(), main.getDirectory().getPath());
saveSettings();
} else {
cloudSyncToggleBtn.setSelected(false);
//cloud sync init error dialog
- String headingText = "Error while initializing cloud sync!";
- String bodyText = "There was some truble adding your game."
- + "\nPlease upload the app.log (which can be found in the cemu_UI directory)"
- + "\nto \"https://github.com/Seil0/cemu_UI/issues\" so we can fix this.";
- JFXInfoDialog cloudSyncErrorDialog = new JFXInfoDialog(headingText, bodyText, dialogBtnStyle, 450, 170, main.pane);
- cloudSyncErrorDialog.show();
+ JFXInfoDialog cloudSyncErrorDialog = new JFXInfoDialog(cloudSyncErrorHeadingText,
+ cloudSyncErrorBodyText, dialogBtnStyle, 450, 170, main.getPane());
+ cloudSyncErrorDialog.show();
}
}
@@ -1078,9 +1105,10 @@ public class MainWindowController {
}
};
- JFXOkayCancelDialog cloudSyncErrorDialog = new JFXOkayCancelDialog(headingText, bodyText, dialogBtnStyle,
- 419, 140, okayAction, cancelAction, main.pane);
- cloudSyncErrorDialog.show();
+ JFXOkayCancelDialog cloudSyncWarningDialog = new JFXOkayCancelDialog(cloudSyncWaringHeadingText,
+ cloudSyncWaringBodyText, dialogBtnStyle, 419, 140, okayAction, cancelAction, main.getPane(),
+ bundle);
+ cloudSyncWarningDialog.show();
}
}
@@ -1092,10 +1120,10 @@ public class MainWindowController {
@FXML
void addBtnAction(ActionEvent event) {
- String headingText = "add a new game to cemu_UI";
- String bodyText = "";
+ String headingText = addGameBtnHeadingText;
+ String bodyText = addGameBtnBodyText;
JFXEditGameDialog addGameDialog = new JFXEditGameDialog(headingText, bodyText, dialogBtnStyle, 450, 300, 0,
- this, main.primaryStage, main.pane);
+ this, main.getPrimaryStage(), main.getPane());
addGameDialog.show();
}
@@ -1104,25 +1132,21 @@ public class MainWindowController {
* and add them to the database and the UI
*/
public void addBtnReturn(String title, String coverPath, String romPath, String titleID) {
- File pictureCache;
-
/**
* if one parameter dosen't contain any value do not add the game
* else convert the cover to .png add copy it into the picture cache,
* then add the rom to the local_roms database
*/
- System.out.println(romPath.length());
if (romPath.length() == 0 || coverPath.length() == 0 || title.length() == 0 || titleID.length() == 0) {
LOGGER.info("No parameter set!");
//addGame error dialog
- String headingTextError = "Error while adding a new Game!";
- String bodyTextError = "There was some truble adding your game."
- + "\nOne of the needed values was empty, please try again to add your game.";
- JFXInfoDialog errorDialog = new JFXInfoDialog(headingTextError, bodyTextError, dialogBtnStyle, 350, 170, main.pane);
- errorDialog.show();
+ JFXInfoDialog errorDialog = new JFXInfoDialog(addBtnReturnErrorHeadingText, addBtnReturnErrorBodyText,
+ dialogBtnStyle, 350, 170, main.getPane());
+ errorDialog.show();
- } else {
+ } else {
+ File pictureCache;
String coverName = new File(coverPath).getName();
try {
if (System.getProperty("os.name").equals("Linux")) {
@@ -1134,8 +1158,8 @@ public class MainWindowController {
BufferedImage originalImage = ImageIO.read(new File(coverPath)); //load cover
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+"\\"+coverName)); //save image to pictureCache
- coverPath = pictureCache+"\\"+coverName;
+ coverPath = pictureCache + "/" + coverName;
+ ImageIO.write(resizeImagePNG, "png", new File(coverPath)); //save image to pictureCache
} catch (IOException e) {
LOGGER.error("Ops something went wrong! Error while resizing cover.", e);
}
@@ -1218,21 +1242,21 @@ public class MainWindowController {
// setting last played, if lastPlayed is empty game was never played before, else set correct date
if (dbController.getLastPlayed(titleID).equals("") || dbController.getLastPlayed(titleID).equals(null)) {
- lastTimePlayedBtn.setText("Last played, never");
+ lastTimePlayedBtn.setText(lastPlayed + never);
totalPlaytimeBtn.setText(dbController.getTotalPlaytime(titleID) + " min");
} else {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- int today = Integer.parseInt(dtf.format(LocalDate.now()).replaceAll("-", ""));
- int yesterday = Integer.parseInt(dtf.format(LocalDate.now().minusDays(1)).replaceAll("-", ""));
- int lastPlayedDay = Integer.parseInt(dbController.getLastPlayed(titleID).replaceAll("-", ""));
+ int tToday = Integer.parseInt(dtf.format(LocalDate.now()).replaceAll("-", ""));
+ int tYesterday = Integer.parseInt(dtf.format(LocalDate.now().minusDays(1)).replaceAll("-", ""));
+ int tLastPlayedDay = Integer.parseInt(dbController.getLastPlayed(titleID).replaceAll("-", ""));
- if (lastPlayedDay == today) {
- lastTimePlayedBtn.setText("Last played, today");
- } else if (lastPlayedDay == yesterday) {
- lastTimePlayedBtn.setText("Last played, yesterday");
+ if (tLastPlayedDay == tToday) {
+ lastTimePlayedBtn.setText(lastPlayed + today);
+ } else if (tLastPlayedDay == tYesterday) {
+ lastTimePlayedBtn.setText(lastPlayed + yesterday);
} else {
- lastTimePlayedBtn.setText("Last played, " + dbController.getLastPlayed(titleID));
+ lastTimePlayedBtn.setText(lastPlayed + dbController.getLastPlayed(titleID));
}
}
@@ -1295,17 +1319,86 @@ public class MainWindowController {
}
}
- void refreshplayBtnPosition() {
- double width;
-
- if (mainAnchorPane.getWidth() < 10) {
- width = mainAnchorPane.getPrefWidth();
- } else {
- width = mainAnchorPane.getWidth();
- }
- playBtn.setLayoutX((width / 2) - 50);
- totalPlaytimeBtn.setLayoutX((width / 2) - 50 - 20.5 - 100);
- lastTimePlayedBtn.setLayoutX((width / 2) + 50 + 20.5);
+ void setUILanguage(){
+ switch(getLanguage()){
+ case "en_US":
+ bundle = ResourceBundle.getBundle("locals.cemu_UI-Local", Locale.US); //us_English
+ languageChoisBox.getSelectionModel().select(0);
+ break;
+ case "de_DE":
+ bundle = ResourceBundle.getBundle("locals.cemu_UI-Local", Locale.GERMAN); //German
+ languageChoisBox.getSelectionModel().select(1);
+ break;
+ default:
+ bundle = ResourceBundle.getBundle("locals.cemu_UI-Local", Locale.US); //default local
+ languageChoisBox.getSelectionModel().select(0);
+ break;
+ }
+
+ // Buttons
+ aboutBtn.setText(bundle.getString("aboutBtn"));
+ settingsBtn.setText(bundle.getString("settingsBtn"));
+ addBtn.setText(bundle.getString("addBtn"));
+ reloadRomsBtn.setText(bundle.getString("reloadRomsBtn"));
+ smmdbBtn.setText(bundle.getString("smmdbBtn"));
+ cemuTFBtn.setText(bundle.getString("cemuTFBtn"));
+ romTFBtn.setText(bundle.getString("romTFBtn"));
+ updateBtn.setText(bundle.getString("updateBtnCheckNow"));
+ smmdbDownloadBtn.setText(bundle.getString("smmdbDownloadBtn"));
+ playBtn.setText(bundle.getString("playBtn"));
+ cloudSyncToggleBtn.setText(bundle.getString("cloudSyncToggleBtn"));
+ autoUpdateToggleBtn.setText(bundle.getString("autoUpdateToggleBtn"));
+ fullscreenToggleBtn.setText(bundle.getString("fullscreenToggleBtn"));
+
+ // Labels
+ cemu_UISettingsLbl.setText(bundle.getString("cemu_UISettingsLbl"));
+ cemuDirectoryLbl.setText(bundle.getString("cemuDirectoryLbl"));
+ romDirectoryLbl.setText(bundle.getString("romDirectoryLbl"));
+ mainColorLbl.setText(bundle.getString("mainColorLbl"));
+ languageLbl.setText(bundle.getString("languageLbl"));
+ updateLbl.setText(bundle.getString("updateLbl"));
+ branchLbl.setText(bundle.getString("branchLbl"));
+ cemuSettingsLbl.setText(bundle.getString("cemuSettingsLbl"));
+ licensesLbl.setText(bundle.getString("licensesLbl"));
+
+ // Columns
+ titleColumn.setText(bundle.getString("titleColumn"));
+ idColumn.setText(bundle.getString("idColumn"));
+ starsColumn.setText(bundle.getString("starsColumn"));
+ timeColumn.setText(bundle.getString("timeColumn"));
+
+ // Strings
+ editHeadingText = bundle.getString("editHeadingText");
+ editBodyText = bundle.getString("editBodyText");
+ removeHeadingText = bundle.getString("removeHeadingText");
+ removeBodyText = bundle.getString("removeBodyText");
+ addUpdateHeadingText = bundle.getString("addUpdateHeadingText");
+ addUpdateBodyText = bundle.getString("addUpdateBodyText");
+ addDLCHeadingText = bundle.getString("addDLCHeadingText");
+ addDLCBodyText = bundle.getString("addDLCBodyText");
+ licensesLblHeadingText = bundle.getString("licensesLblHeadingText");
+ licensesLblBodyText = bundle.getString("licensesLblBodyText");
+ showLicenses = bundle.getString("showLicenses");
+ aboutBtnHeadingText = bundle.getString("aboutBtnHeadingText");
+ aboutBtnBodyText = bundle.getString("aboutBtnBodyText");
+ cloudSyncWaringHeadingText = bundle.getString("cloudSyncWaringHeadingText");
+ cloudSyncWaringBodyText = bundle.getString("cloudSyncWaringBodyText");
+ cloudSyncErrorHeadingText = bundle.getString("cloudSyncErrorHeadingText");
+ cloudSyncErrorBodyText = bundle.getString("cloudSyncErrorBodyText");
+ addGameBtnHeadingText = bundle.getString("addGameBtnHeadingText");
+ addGameBtnBodyText = bundle.getString("addGameBtnBodyText");
+ addBtnReturnErrorHeadingText = bundle.getString("addBtnReturnErrorHeadingText");
+ addBtnReturnErrorBodyText = bundle.getString("addBtnReturnErrorBodyText");
+ lastPlayed = bundle.getString("lastPlayed");
+ today = bundle.getString("today");
+ yesterday = bundle.getString("yesterday");
+ never = bundle.getString("never");
+
+ playBtnPlay = bundle.getString("playBtnPlay");
+ playBtnUpdating = bundle.getString("playBtnUpdating");
+ playBtnCopyingFiles = bundle.getString("playBtnCopyingFiles");
+ smmdbDownloadBtnLoading = bundle.getString("smmdbDownloadBtnLoading");
+ smmdbDownloadBtnDownload = bundle.getString("smmdbDownloadBtnDownload");
}
private void checkAutoUpdate() {
@@ -1547,6 +1640,7 @@ public class MainWindowController {
props.setProperty("cemuPath", getCemuPath());
props.setProperty("romPath", getRomPath());
props.setProperty("color", getColor());
+ props.setProperty("language", getLanguage());
props.setProperty("fullscreen", String.valueOf(isFullscreen()));
props.setProperty("cloudSync", String.valueOf(isCloudSync()));
props.setProperty("autoUpdate", String.valueOf(isAutoUpdate()));
@@ -1556,7 +1650,8 @@ public class MainWindowController {
} else {
props.setProperty("cloudService", getCloudService());
}
- props.setProperty("folderID", main.cloudController.getFolderID(getCloudService()));
+ props.setProperty("folderID", main.getCloudController().getFolderID(getCloudService()));
+ props.setProperty("lastLocalSync", String.valueOf(getLastLocalSync()));
props.setProperty("windowWidth", String.valueOf(mainAnchorPane.getWidth()));
props.setProperty("windowHeight", String.valueOf(mainAnchorPane.getHeight()));
if(System.getProperty("os.name").equals("Linux")){
@@ -1608,6 +1703,13 @@ public class MainWindowController {
setColor("00a8cc");
}
+ if (props.getProperty("language") == null) {
+ LOGGER.error("cloud not load language, setting default instead");
+ setLanguage("en_US");
+ } else {
+ setLanguage(props.getProperty("language"));
+ }
+
try {
setFullscreen(Boolean.parseBoolean(props.getProperty("fullscreen")));
} catch (Exception e) {
@@ -1644,11 +1746,18 @@ public class MainWindowController {
}
try {
- main.cloudController.setFolderID(props.getProperty("folderID"), getCloudService());
+ main.getCloudController().setFolderID(props.getProperty("folderID"), getCloudService());
} catch (Exception e) {
LOGGER.error("could not load folderID, disable cloud sync. Please contact an developer", e);
setCloudSync(false);
}
+
+ try {
+ setLastLocalSync(Long.parseLong(props.getProperty("lastLocalSync")));
+ } catch (Exception e) {
+ LOGGER.error("could not load lastSuccessSync, setting default instead", e);
+ setLastLocalSync(0);
+ }
try {
setWindowWidth(Double.parseDouble(props.getProperty("windowWidth")));
@@ -1689,43 +1798,21 @@ public class MainWindowController {
}
private void playBtnSlideIn(){
- playBtn.setVisible(true);
- lastTimePlayedBtn.setVisible(true);
- totalPlaytimeBtn.setVisible(true);
+ bottomHBox.setVisible(true);
playTrue = true;
- TranslateTransition playBtnTransition = new TranslateTransition(Duration.millis(300), playBtn);
+ TranslateTransition playBtnTransition = new TranslateTransition(Duration.millis(300), bottomHBox);
playBtnTransition.setFromY(56);
playBtnTransition.setToY(0);
playBtnTransition.play();
-
- TranslateTransition lastTimePlayedBtnTransition = new TranslateTransition(Duration.millis(300), lastTimePlayedBtn);
- lastTimePlayedBtnTransition.setFromY(56);
- lastTimePlayedBtnTransition.setToY(0);
- lastTimePlayedBtnTransition.play();
-
- TranslateTransition timePlayedBtnTransition = new TranslateTransition(Duration.millis(300), totalPlaytimeBtn);
- timePlayedBtnTransition.setFromY(56);
- timePlayedBtnTransition.setToY(0);
- timePlayedBtnTransition.play();
}
private void playBtnSlideOut(){
playTrue = false;
- TranslateTransition playBtnTransition = new TranslateTransition(Duration.millis(300), playBtn);
+ TranslateTransition playBtnTransition = new TranslateTransition(Duration.millis(300), bottomHBox);
playBtnTransition.setFromY(0);
playBtnTransition.setToY(56);
playBtnTransition.play();
-
- TranslateTransition lastTimePlayedBtnTransition = new TranslateTransition(Duration.millis(300), lastTimePlayedBtn);
- lastTimePlayedBtnTransition.setFromY(0);
- lastTimePlayedBtnTransition.setToY(56);
- lastTimePlayedBtnTransition.play();
-
- TranslateTransition timePlayedBtnTransition = new TranslateTransition(Duration.millis(300), totalPlaytimeBtn);
- timePlayedBtnTransition.setFromY(0);
- timePlayedBtnTransition.setToY(56);
- timePlayedBtnTransition.play();
}
private void editColor(String input){
@@ -1831,6 +1918,14 @@ public class MainWindowController {
this.xPosHelper = xPosHelper;
}
+ public long getLastLocalSync() {
+ return lastLocalSync;
+ }
+
+ public void setLastLocalSync(long lastLocalSync) {
+ this.lastLocalSync = lastLocalSync;
+ }
+
public boolean isFullscreen() {
return fullscreen;
}
@@ -1919,6 +2014,22 @@ public class MainWindowController {
this.oldXPosHelper = oldXPosHelper;
}
+ public String getLanguage() {
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public ResourceBundle getBundle() {
+ return bundle;
+ }
+
+ public void setBundle(ResourceBundle bundle) {
+ this.bundle = bundle;
+ }
+
public AnchorPane getMainAnchorPane() {
return mainAnchorPane;
}
diff --git a/src/main/java/com/cemu_UI/application/playGame.java b/src/main/java/com/cemu_UI/application/playGame.java
index 89d8474..b6afd6b 100644
--- a/src/main/java/com/cemu_UI/application/playGame.java
+++ b/src/main/java/com/cemu_UI/application/playGame.java
@@ -22,21 +22,22 @@
package com.cemu_UI.application;
import java.io.IOException;
+import java.time.Instant;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import com.cemu_UI.controller.dbController;
+import com.cemu_UI.controller.DBController;
import javafx.application.Platform;
public class playGame extends Thread{
MainWindowController mainWindowController;
- dbController dbController;
+ DBController dbController;
private static final Logger LOGGER = LogManager.getLogger(playGame.class.getName());
- public playGame(MainWindowController m, com.cemu_UI.controller.dbController db){
+ public playGame(MainWindowController m, com.cemu_UI.controller.DBController db){
mainWindowController = m;
dbController = db;
}
@@ -52,7 +53,7 @@ public class playGame extends Thread{
Process p;
Platform.runLater(() -> {
- mainWindowController.main.primaryStage.setIconified(true);
+ mainWindowController.main.getPrimaryStage().setIconified(true); // minimize cemu_UI
});
startTime = System.currentTimeMillis();
try{
@@ -86,14 +87,15 @@ public class playGame extends Thread{
}else{
mainWindowController.totalPlaytimeBtn.setText(dbController.getTotalPlaytime(selectedGameTitleID)+ " min");
}
- mainWindowController.main.primaryStage.setIconified(false);
+ mainWindowController.main.getPrimaryStage().setIconified(false); // maximize cemu_UI
});
-// System.out.println(mainWindowController.getCemuPath()+"/mlc01/emulatorSave/"+);
//sync savegame with cloud service
- if(mainWindowController.isCloudSync()) {
- mainWindowController.main.cloudController.sync(mainWindowController.getCloudService(), mainWindowController.getCemuPath());
- }
+ if (mainWindowController.isCloudSync()) {
+ mainWindowController.setLastLocalSync(Instant.now().getEpochSecond());
+ mainWindowController.main.getCloudController().sync(mainWindowController.getCloudService(),
+ mainWindowController.getCemuPath(), mainWindowController.main.getDirectory().getPath());
+ }
}catch (IOException | InterruptedException e){
e.printStackTrace();
diff --git a/src/main/java/com/cemu_UI/controller/CloudController.java b/src/main/java/com/cemu_UI/controller/CloudController.java
index f2db2fd..3358eb4 100644
--- a/src/main/java/com/cemu_UI/controller/CloudController.java
+++ b/src/main/java/com/cemu_UI/controller/CloudController.java
@@ -22,7 +22,12 @@
package com.cemu_UI.controller;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.time.Instant;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -31,6 +36,8 @@ import com.cemu_UI.application.MainWindowController;
import com.cemu_UI.vendorCloudController.GoogleDriveController;
import javafx.application.Platform;
+import net.lingala.zip4j.core.ZipFile;
+import net.lingala.zip4j.exception.ZipException;
public class CloudController {
@@ -63,105 +70,144 @@ public class CloudController {
LOGGER.info("cloud initialisation done!");
return success;
}
-
- public void stratupCheck(String cloudService, String cemuDirectory) {
- if(cloudService.equals("GoogleDrive")) {
- LOGGER.info("starting startup check google drive ...");
- try {
- if (!googleDriveController.checkFolder()) {
- googleDriveController.creatFolder();
- mwc.saveSettings();
-
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run() {
- Platform.runLater(() -> {
- mwc.getPlayBtn().setText("syncing...");
- });
- googleDriveController.uploadAllFiles();
- Platform.runLater(() -> {
- mwc.getPlayBtn().setText("play");
- });
- }
- });
- thread.start();
- } else {
- sync(cloudService, cemuDirectory);
- }
- } catch (IOException e) {
- LOGGER.error("google drive startup check failed", e);
- }
- }
- if(cloudService.equals("Dropbox")) {
-
- }
- }
-
-
-
- public void sync(String cloudService, String cemuDirectory) {
-
- //running sync in a new thread, instead of blocking the main thread
+
+ /**
+ * to trigger a new sync set the mwc LastLocalSync to the actual time and call the sync method
+ * @param cloudService
+ * @param cemuDirectory
+ * @param cemu_UIDirectory
+ */
+ public void sync(String cloudService, String cemuDirectory, String cemu_UIDirectory) {
+
+ // running sync in a new thread, instead of blocking the main thread
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
- Platform.runLater(() -> {
- mwc.getPlayBtn().setText("syncing...");
- });
- LOGGER.info("starting synchronization in new thread ...");
-
- if(cloudService.equals("GoogleDrive")) {
- try {
- googleDriveController.sync(cemuDirectory);
- } catch (IOException e) {
- LOGGER.error("google drive synchronization failed", e);
- }
- }
- if(cloudService.equals("Dropbox")) {
-
- }
- Platform.runLater(() -> {
- mwc.getPlayBtn().setText("play");
- mwc.saveSettings();
- });
- LOGGER.info("synchronization successful!");
- }
- });
- thread.start();
-
- }
-
- void uploadFile(String cloudService, File file) {
-
- //running uploadFile in a new thread, instead of blocking the main thread
- new Thread() {
- @Override
- public void run() {
- LOGGER.info("starting uploadFile in new thread ...");
-
- if(cloudService.equals("GoogleDrive")) {
- try {
- googleDriveController.uploadFile(file);
- } catch (IOException e) {
- LOGGER.error("google drive uploadFile failed" ,e);
- }
- }
- if(cloudService.equals("Dropbox")) {
+ try {
+ Platform.runLater(() -> {
+ mwc.getPlayBtn().setDisable(true);
+ mwc.getPlayBtn().setText("syncing...");
+ });
+ LOGGER.info("starting synchronization in new thread ...");
+
+ // zip the saves folder
+ File zipFile = zipSavegames(cemu_UIDirectory, cemuDirectory);
- }
- }
- }.start();
+ // upload the zip
+ switch (cloudService) {
+
+ // use GoogleDriveController
+ case "GoogleDrive":
+ LOGGER.info("using GoogleDriveController");
+ long lastCloudSync = googleDriveController.getLastCloudSync();
+
+ if (!googleDriveController.checkFolder()) {
+ LOGGER.info("cloud sync folder dosen't exist, creating one!");
+ googleDriveController.creatFolder();
+ googleDriveController.uploadZipFile(zipFile);
+ } else if (mwc.getLastLocalSync() > lastCloudSync) {
+ LOGGER.info("local is new, going to upload zip");
+ googleDriveController.uploadZipFile(zipFile);
+ } else if(mwc.getLastLocalSync() < lastCloudSync) {
+ LOGGER.info("cloud is new, going to download zip");
+ unzipSavegames(cemuDirectory, googleDriveController.downloadZipFile(cemu_UIDirectory));
+ mwc.setLastLocalSync(lastCloudSync);
+ break;
+ } else {
+ LOGGER.info("nothing to do");
+ break;
+ }
+ mwc.setLastLocalSync(Long.parseLong(zipFile.getName().substring(0, zipFile.getName().length()-4))); // set time of last sucessfull sync
+ break;
+
+
+
+ case "Dropbox":
+
+ break;
+
+
+ default:
+ LOGGER.warn("no cloud vendor found!");
+ break;
+ }
+
+ zipFile.delete(); // delete zipfile in cem_UI directory
+
+ Platform.runLater(() -> {
+ mwc.getPlayBtn().setText("play");
+ mwc.getPlayBtn().setDisable(false);
+ mwc.saveSettings();
+ });
+
+
+ LOGGER.info("synchronization successful!");
+ } catch (Exception e) {
+ LOGGER.error("There was an error during syncronisation! Please open a new issue on the cemu_UI github page:", e);
+ }
+ }
+ });
+ thread.start();
+ }
+ private File zipSavegames(String cemu_UIDirectory, String cemuDirectory) throws Exception {
+ long unixTimestamp = Instant.now().getEpochSecond();
+ FileOutputStream fos = new FileOutputStream(cemu_UIDirectory + "/" + unixTimestamp + ".zip");
+ ZipOutputStream zos = new ZipOutputStream(fos);
+ addDirToZipArchive(zos, new File(cemuDirectory + "/mlc01/usr/save"), null);
+ zos.flush();
+ fos.flush();
+ zos.close();
+ fos.close();
+ return new File(cemu_UIDirectory + "/" + unixTimestamp + ".zip");
+ }
+
+ private static void addDirToZipArchive(ZipOutputStream zos, File fileToZip, String parrentDirectoryName) throws Exception {
+ if (fileToZip == null || !fileToZip.exists()) {
+ return;
+ }
+
+ String zipEntryName = fileToZip.getName();
+ if (parrentDirectoryName!=null && !parrentDirectoryName.isEmpty()) {
+ zipEntryName = parrentDirectoryName + "/" + fileToZip.getName();
+ }
+
+ if (fileToZip.isDirectory()) {
+ for (File file : fileToZip.listFiles()) {
+ addDirToZipArchive(zos, file, zipEntryName);
+ }
+ } else {
+ byte[] buffer = new byte[1024];
+ FileInputStream fis = new FileInputStream(fileToZip);
+ zos.putNextEntry(new ZipEntry(zipEntryName));
+ int length;
+ while ((length = fis.read(buffer)) > 0) {
+ zos.write(buffer, 0, length);
+ }
+ zos.closeEntry();
+ fis.close();
+ }
+ }
+
+ private void unzipSavegames(String cemuDirectory, File outputFile) {
+ try {
+ ZipFile zipFile = new ZipFile(outputFile);
+ zipFile.extractAll(cemuDirectory + "/mlc01/usr");
+ outputFile.delete();
+ LOGGER.info("unzip successfull");
+ } catch (ZipException e) {
+ LOGGER.error("an error occurred during unziping the file!", e);
+ }
}
public String getFolderID(String cloudService) {
String folderID = "";
if (cloudService != null) {
- if(cloudService.equals("GoogleDrive")) {
+ if (cloudService.equals("GoogleDrive")) {
folderID = googleDriveController.getFolderID();
}
- if(cloudService.equals("Dropbox")) {
-
+ if (cloudService.equals("Dropbox")) {
+
}
}
return folderID;
@@ -173,8 +219,9 @@ public class CloudController {
googleDriveController.setFolderID(folderID);
}
if (cloudService.equals("Dropbox")) {
-
+
}
}
}
+
}
diff --git a/src/main/java/com/cemu_UI/controller/dbController.java b/src/main/java/com/cemu_UI/controller/DBController.java
similarity index 88%
rename from src/main/java/com/cemu_UI/controller/dbController.java
rename to src/main/java/com/cemu_UI/controller/DBController.java
index be4facf..394b7ca 100644
--- a/src/main/java/com/cemu_UI/controller/dbController.java
+++ b/src/main/java/com/cemu_UI/controller/DBController.java
@@ -47,10 +47,10 @@ import org.xml.sax.SAXException;
import com.cemu_UI.application.MainWindowController;
-public class dbController {
+public class DBController {
- public dbController(MainWindowController m) {
- mainWindowController = m;
+ public DBController(MainWindowController mwc) {
+ mainWindowController = mwc;
}
private MainWindowController mainWindowController;
@@ -59,9 +59,14 @@ public class dbController {
private String DB_PATH_games;
private Connection connection = null;
private Connection connectionGames = null;
- private static final Logger LOGGER = LogManager.getLogger(dbController.class.getName());
+ private static final Logger LOGGER = LogManager.getLogger(DBController.class.getName());
- public void main(){
+ /**
+ * initialize the sqlite database controller
+ * load ROM and games database
+ * load all games
+ */
+ public void init(){
LOGGER.info("<==========starting loading sql==========>");
loadRomDatabase();
loadGamesDatabase();
@@ -97,13 +102,13 @@ public class dbController {
* set the path to the localRoms.db file and initialize the connection
*
* games.dbcontains a reverence list to for the automatic detection mode
- * TODO this should be called ReferenceGameList the games table should be called reference_games
+ * TODO rework paths
*/
private void loadGamesDatabase() {
if (System.getProperty("os.name").equals("Linux")) {
- DB_PATH_games = System.getProperty("user.home") + "/cemu_UI/games.db";
+ DB_PATH_games = System.getProperty("user.home") + "/cemu_UI/reference_games.db";
} else {
- DB_PATH_games = System.getProperty("user.home") + "\\Documents\\cemu_UI" + "\\" + "games.db";
+ DB_PATH_games = System.getProperty("user.home") + "\\Documents\\cemu_UI" + "\\" + "reference_games.db";
}
try {
// create a database connection
@@ -221,37 +226,30 @@ public class dbController {
LOGGER.info("Getting all .rpx files in " + dir.getCanonicalPath()+" including those in subdirectories");
// for all files in dir get the app.xml
for (File file : files) {
- if(System.getProperty("os.name").equals("Linux")){
- appFile = new File(file.getParent()+"/app.xml");
- } else {
- appFile = new File(file.getParent()+"\\app.xml");
- }
+ appFile = new File(file.getParent() + "/app.xml");
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(appFile);
- String title_ID = document.getElementsByTagName("title_id").item(0).getTextContent(); //get titile_ID from app.xml
+ String title_ID = document.getElementsByTagName("title_id").item(0).getTextContent(); // get titile_ID from app.xml
title_ID = title_ID.substring(0, 8) + "-" + title_ID.substring(8, title_ID.length());
- LOGGER.info("Name: "+file.getName()+"; Title ID: "+title_ID);
- ResultSet rs = stmt.executeQuery("SELECT * FROM games WHERE TitleID = '"+title_ID+"';");
+ LOGGER.info("Name: " + file.getName() + "; Title ID: " + title_ID);
+ ResultSet rs = stmt.executeQuery("SELECT * FROM games WHERE TitleID = '" + title_ID + "';");
+
// for all elements in the games table check if it's already present, else add it
while (rs.next()) {
if (checkEntry(rs.getString(2))) {
LOGGER.info(rs.getString(2) + ": game already in database");
- }else{
+ } else {
LOGGER.info("adding cover to cache ...");
- 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);
- if(System.getProperty("os.name").equals("Linux")) {
- ImageIO.write(resizeImagePNG, "png", new File(pictureCache+"/"+rs.getString(3)+".png")); //change path where you want it saved
- coverPath = pictureCache+"/"+rs.getString(3)+".png";
- } else {
- ImageIO.write(resizeImagePNG, "png", new File(pictureCache+"\\"+rs.getString(3)+".png")); //change path where you want it saved
- coverPath = pictureCache+"\\"+rs.getString(3)+".png";
- }
-
+ 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";
LOGGER.info(rs.getString(2) + ": adding ROM");
- addGame(rs.getString(2), coverPath, file.getCanonicalPath(), rs.getString(1), rs.getString(3), rs.getString(5),"","0");
+ addGame(rs.getString(2), coverPath, file.getCanonicalPath(), rs.getString(1), rs.getString(3),
+ rs.getString(5), "", "0");
}
}
}
diff --git a/src/main/java/com/cemu_UI/controller/UpdateController.java b/src/main/java/com/cemu_UI/controller/UpdateController.java
index 6b7d820..a7d69be 100644
--- a/src/main/java/com/cemu_UI/controller/UpdateController.java
+++ b/src/main/java/com/cemu_UI/controller/UpdateController.java
@@ -40,7 +40,6 @@ import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;
-
import javafx.application.Platform;
public class UpdateController implements Runnable {
@@ -49,9 +48,12 @@ public class UpdateController implements Runnable {
private String buildNumber;
private String apiOutput;
private String updateBuildNumber; // tag_name from Github
+// private String updateName;
+// private String updateChanges;
private String browserDownloadUrl; // update download link
private String githubApiRelease = "https://api.github.com/repos/Seil0/cemu_UI/releases/latest";
private String githubApiBeta = "https://api.github.com/repos/Seil0/cemu_UI/releases";
+
private URL githubApiUrl;
private boolean useBeta;
private static final Logger LOGGER = LogManager.getLogger(UpdateController.class.getName());
@@ -70,7 +72,7 @@ public class UpdateController implements Runnable {
public void run() {
LOGGER.info("beta:" + useBeta + "; checking for updates ...");
Platform.runLater(() -> {
- mainWindowController.getUpdateBtn().setText("checking for updates ...");
+ mainWindowController.getUpdateBtn().setText(mainWindowController.getBundle().getString("updateBtnChecking"));
});
try {
@@ -97,8 +99,8 @@ public class UpdateController implements Runnable {
JsonArray objectAssets = object.asObject().get("assets").asArray();
updateBuildNumber = object.asObject().getString("tag_name", "");
- // updateName = object.asObject().getString("name", "");
- // updateChanges = object.asObject().getString("body", "");
+// updateName = object.asObject().getString("name", "");
+// updateChanges = object.asObject().getString("body", "");
for (JsonValue asset : objectAssets) {
browserDownloadUrl = asset.asObject().getString("browser_download_url", "");
@@ -109,8 +111,8 @@ public class UpdateController implements Runnable {
JsonArray objectAssets = Json.parse(apiOutput).asObject().get("assets").asArray();
updateBuildNumber = object.getString("tag_name", "");
- // updateName = object.getString("name", "");
- // updateChanges = object.getString("body", "");
+// updateName = object.getString("name", "");
+// updateChanges = object.getString("body", "");
for (JsonValue asset : objectAssets) {
browserDownloadUrl = asset.asObject().getString("browser_download_url", "");
@@ -126,26 +128,26 @@ public class UpdateController implements Runnable {
if (iversion >= iaktVersion) {
Platform.runLater(() -> {
- mainWindowController.getUpdateBtn().setText("no update available");
+ mainWindowController.getUpdateBtn().setText(mainWindowController.getBundle().getString("updateBtnNoUpdateAvailable"));
});
LOGGER.info("no update available");
} else {
Platform.runLater(() -> {
- mainWindowController.getUpdateBtn().setText("update available");
+ mainWindowController.getUpdateBtn().setText(mainWindowController.getBundle().getString("updateBtnUpdateAvailable"));
});
LOGGER.info("update available");
LOGGER.info("download link: " + browserDownloadUrl);
try {
// open new Http connection, ProgressMonitorInputStream for downloading the data
- HttpURLConnection conn = (HttpURLConnection) new URL(browserDownloadUrl).openConnection();
- ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(null, "Downloading...", conn.getInputStream());
+ HttpURLConnection connection = (HttpURLConnection) new URL(browserDownloadUrl).openConnection();
+ ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(null, "Downloading...", connection.getInputStream());
ProgressMonitor pm = pmis.getProgressMonitor();
pm.setMillisToDecideToPopup(0);
pm.setMillisToPopup(0);
- pm.setMinimum(0);// tell the progress bar that we start at the beginning of the stream
- pm.setMaximum(conn.getContentLength());// tell the progress bar the total number of bytes we are going to read.
+ pm.setMinimum(0);// set beginning of the progress bar to 0
+ pm.setMaximum(connection.getContentLength());// set the end to the file length
FileUtils.copyInputStreamToFile(pmis, new File("cemu_UI_update.jar")); // download update
- org.apache.commons.io.FileUtils.copyFile(new File("cemu_UI_update.jar"), new File("cemu_UI.jar")); // TODO rename update to old name
+ org.apache.commons.io.FileUtils.copyFile(new File("cemu_UI_update.jar"), new File("cemu_UI.jar"));
org.apache.commons.io.FileUtils.deleteQuietly(new File("cemu_UI_update.jar")); // delete update
Runtime.getRuntime().exec("java -jar cemu_UI.jar"); // start again
System.exit(0); // finishes itself
diff --git a/src/main/java/com/cemu_UI/uiElements/JFXEditGameDialog.java b/src/main/java/com/cemu_UI/uiElements/JFXEditGameDialog.java
index 3e25f36..c5cdb67 100644
--- a/src/main/java/com/cemu_UI/uiElements/JFXEditGameDialog.java
+++ b/src/main/java/com/cemu_UI/uiElements/JFXEditGameDialog.java
@@ -88,18 +88,15 @@ public class JFXEditGameDialog {
StackPane stackPane = new StackPane();
stackPane.autosize();
JFXDialog dialog = new JFXDialog(stackPane, content, JFXDialog.DialogTransition.LEFT, true);
-
- Label placeholder = new Label();
- placeholder.setPrefSize(15, 10);
-
+
TextField gameTitleTF = new TextField();
- gameTitleTF.setPromptText("game tile");
+ gameTitleTF.setPromptText(mwc.getBundle().getString("gameTitle"));
TextField gameTitleIDTF = new TextField();
- gameTitleIDTF.setPromptText("title ID");
+ gameTitleIDTF.setPromptText(mwc.getBundle().getString("titleID"));
TextField romPathTF = new TextField();
- romPathTF.setPromptText("ROM path");
+ romPathTF.setPromptText(mwc.getBundle().getString("romPath"));
TextField gameCoverTF = new TextField();
- gameCoverTF.setPromptText("cover path");
+ gameCoverTF.setPromptText(mwc.getBundle().getString("coverPath"));
if (mode == 1) {
gameTitleTF.setText(title);
@@ -110,7 +107,7 @@ public class JFXEditGameDialog {
gameTitleIDTF.setEditable(false);
}
- JFXButton okayBtn = new JFXButton("Okay");
+ JFXButton okayBtn = new JFXButton(mwc.getBundle().getString("okayBtnText"));
okayBtn.setOnAction(new EventHandler() {
@Override
public void handle(ActionEvent event) {
@@ -120,9 +117,8 @@ public class JFXEditGameDialog {
// LOGGER.info("No parameter set!");
// addGame error dialog
- String headingTextError = "Error while adding a new Game!";
- String bodyTextError = "There was some truble adding your game."
- + "\nOne of the needed values was empty, please try again to add your game.";
+ String headingTextError = mwc.getBundle().getString("editGameDialogHeadingTextError");
+ String bodyTextError = mwc.getBundle().getString("editGameDialogBodyTextError");
JFXInfoDialog errorDialog = new JFXInfoDialog(headingTextError, bodyTextError, dialogBtnStyle, 350,170, pane);
errorDialog.show();
} else {
@@ -150,7 +146,7 @@ public class JFXEditGameDialog {
okayBtn.setPrefHeight(32);
okayBtn.setStyle(dialogBtnStyle);
- JFXButton cancelBtn = new JFXButton("Cancel");
+ JFXButton cancelBtn = new JFXButton(mwc.getBundle().getString("cancelBtnText"));
cancelBtn.setOnAction(new EventHandler() {
@Override
public void handle(ActionEvent event) {
@@ -161,7 +157,7 @@ public class JFXEditGameDialog {
cancelBtn.setPrefHeight(32);
cancelBtn.setStyle(dialogBtnStyle);
- JFXButton selectPathBtn = new JFXButton("select .rpx file");
+ JFXButton selectPathBtn = new JFXButton(mwc.getBundle().getString("editGameDialogSelectPathBtn"));
selectPathBtn.setPrefWidth(110);
selectPathBtn.setStyle(dialogBtnStyle);
selectPathBtn.setOnAction(new EventHandler() {
@@ -173,7 +169,7 @@ public class JFXEditGameDialog {
}
});
- JFXButton selectCoverBtn = new JFXButton("select cover file");
+ JFXButton selectCoverBtn = new JFXButton(mwc.getBundle().getString("editGameDialogSelectCoverBtn"));
selectCoverBtn.setPrefWidth(110);
selectCoverBtn.setStyle(dialogBtnStyle);
selectCoverBtn.setOnAction(new EventHandler() {
@@ -189,14 +185,14 @@ public class JFXEditGameDialog {
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(15, 10, 10, 10));
- grid.add(new Label("game title:"), 0, 0);
+ grid.add(new Label(mwc.getBundle().getString("gameTitle") + ":"), 0, 0);
grid.add(gameTitleTF, 1, 0);
- grid.add(new Label("title id:"), 0, 1);
+ grid.add(new Label(mwc.getBundle().getString("titleID") + ":"), 0, 1);
grid.add(gameTitleIDTF, 1, 1);
- grid.add(new Label("ROM path:"), 0, 2);
+ grid.add(new Label(mwc.getBundle().getString("romPath") + ":"), 0, 2);
grid.add(romPathTF, 1, 2);
grid.add(selectPathBtn, 2, 2);
- grid.add(new Label("cover path:"), 0, 3);
+ grid.add(new Label(mwc.getBundle().getString("coverPath") + ":"), 0, 3);
grid.add(gameCoverTF, 1, 3);
grid.add(selectCoverBtn, 2, 3);
@@ -207,7 +203,7 @@ public class JFXEditGameDialog {
content.setHeading(new Text(headingText));
content.setBody(vbox);
- content.setActions(cancelBtn, placeholder, okayBtn);
+ content.setActions(cancelBtn, okayBtn);
content.setPrefSize(dialogWidth, dialogHeight);
pane.getChildren().add(stackPane);
AnchorPane.setTopAnchor(stackPane, (pane.getHeight()-content.getPrefHeight())/2);
diff --git a/src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java b/src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java
index 4bf378f..5dd4d1a 100644
--- a/src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java
+++ b/src/main/java/com/cemu_UI/uiElements/JFXOkayCancelDialog.java
@@ -22,13 +22,14 @@
package com.cemu_UI.uiElements;
+import java.util.ResourceBundle;
+
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDialog;
import com.jfoenix.controls.JFXDialogLayout;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
-import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
@@ -39,8 +40,8 @@ public class JFXOkayCancelDialog {
private String headingText;
private String bodyText;
private String dialogBtnStyle;
- private String okayText = "okay";
- private String cancelText = "cancel";
+ private String okayText;
+ private String cancelText;
private int dialogWidth;
private int dialogHeight;
private EventHandler okayAction;
@@ -59,7 +60,8 @@ public class JFXOkayCancelDialog {
* @param pane pane to which the dialog belongs
*/
public JFXOkayCancelDialog(String headingText, String bodyText, String dialogBtnStyle, int dialogWidth,
- int dialogHeight, EventHandler okayAction, EventHandler cancelAction, Pane pane) {
+ int dialogHeight, EventHandler okayAction, EventHandler cancelAction, Pane pane,
+ ResourceBundle bundle) {
this.headingText = headingText;
this.bodyText = bodyText;
this.dialogBtnStyle = dialogBtnStyle;
@@ -68,9 +70,12 @@ public class JFXOkayCancelDialog {
this.okayAction = okayAction;
this.cancelAction = cancelAction;
this.pane = pane;
+ okayText = bundle.getString("okayBtnText");
+ cancelText = bundle.getString("cancelBtnText");
}
public void show() {
+
JFXDialogLayout content = new JFXDialogLayout();
content.setHeading(new Text(headingText));
content.setBody(new Text(bodyText));
@@ -93,9 +98,7 @@ public class JFXOkayCancelDialog {
cancelBtn.setButtonType(com.jfoenix.controls.JFXButton.ButtonType.RAISED);
cancelBtn.setPrefHeight(32);
cancelBtn.setStyle(dialogBtnStyle);
- Label placeholder = new Label();
- placeholder.setPrefSize(15, 10);
- content.setActions(cancelBtn, placeholder, okayBtn);
+ content.setActions(cancelBtn, okayBtn);
content.setPrefSize(dialogWidth, dialogHeight);
pane.getChildren().add(stackPane);
AnchorPane.setTopAnchor(stackPane, (pane.getHeight()-content.getPrefHeight())/2);
diff --git a/src/main/java/com/cemu_UI/vendorCloudController/GoogleDriveController.java b/src/main/java/com/cemu_UI/vendorCloudController/GoogleDriveController.java
index 51d55ab..485ceef 100644
--- a/src/main/java/com/cemu_UI/vendorCloudController/GoogleDriveController.java
+++ b/src/main/java/com/cemu_UI/vendorCloudController/GoogleDriveController.java
@@ -21,17 +21,12 @@
package com.cemu_UI.vendorCloudController;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.List;
-
-import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -56,15 +51,11 @@ import com.google.api.services.drive.model.FileList;
public class GoogleDriveController {
Drive service;
- private String saveDirectory;
private String folderID;
- private ArrayList localSavegames = new ArrayList<>();
- private ArrayList cloudSavegames = new ArrayList<>();
- private ArrayList localSavegamesName = new ArrayList<>();
- private ArrayList cloudSavegamesName = new ArrayList<>();
+ private File downloadFile;
private static final Logger LOGGER = LogManager.getLogger(GoogleDriveController.class.getName());
- private final String APPLICATION_NAME ="cemu_Ui Drive API Controller"; //TODO add Google
+ private final String APPLICATION_NAME ="cemu_Ui Google Drive API Controller";
//Directory to store user credentials for this application
private final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".credentials/cemu_UI_credential");
@@ -125,69 +116,15 @@ public class GoogleDriveController {
.build();
}
-
- public void main(String cemuDirectory) throws IOException {
- java.io.File dir = new java.io.File(cemuDirectory + "/mlc01/usr/save");
-
- service = getDriveService();
-
- // cemu >= 1.11 uses /mlc01/usr/save/... instead of /mlc01/emulatorSave/...
- if (dir.exists()) {
- LOGGER.info("using new save path");
- saveDirectory = cemuDirectory + "/mlc01/usr/save";
- } else {
- LOGGER.info("using old save path");
- saveDirectory = cemuDirectory + "/mlc01/emulatorSave";
- }
- }
-
- public void sync(String cemuDirectory) throws IOException {
- //in case there is no folderID saved, look it up first
+ public void main(String cemuDirectory) throws IOException {
+ service = getDriveService();
+
if (getFolderID() == "" || getFolderID() == null) {
getSavegamesFolderID();
}
- getLocalSavegames();
- getCloudSavegames();
-
- // download files from cloud which don't exist locally
- for (int i = 0; i < cloudSavegames.size(); i++) {
-
- // if the file exists locally, check which one is newer
- if (localSavegamesName.contains(cloudSavegames.get(i).getName())) {
-
- int localSavegamesNumber = localSavegamesName.indexOf(cloudSavegames.get(i).getName());
- long localModified = new DateTime(localSavegames.get(localSavegamesNumber).lastModified()).getValue();
- long cloudModified = cloudSavegames.get(i).getModifiedTime().getValue();
- FileInputStream fis = new FileInputStream(localSavegames.get(localSavegamesNumber));
-
- if (cloudSavegames.get(i).getMd5Checksum().equals(org.apache.commons.codec.digest.DigestUtils.md5Hex(fis))) {
- LOGGER.info("both files are the same, nothing to do");
- } else {
- if (localModified >= cloudModified) {
- LOGGER.info("local is newer");
- updateFile(cloudSavegames.get(i), localSavegames.get(localSavegamesNumber));
- } else {
- LOGGER.info("cloud is newer");
- downloadFile(cloudSavegames.get(i));
- }
- }
-
- } else {
- LOGGER.info("file doesn't exist locally");
- downloadFile(cloudSavegames.get(i));
- }
- }
-
- // upload file to cloud which don't exist in the cloud
- for (int j = 0; j < localSavegames.size(); j++) {
- if (!cloudSavegamesName.contains(localSavegamesName.get(j))) {
- LOGGER.info("file doesn't exist in the cloud");
- uploadFile(localSavegames.get(j));
- }
- }
}
- //create a folder in google drive
+ // create a folder in google drive
public void creatFolder() throws IOException {
LOGGER.info("creating new folder");
File fileMetadata = new File();
@@ -199,8 +136,8 @@ public class GoogleDriveController {
folderID = file.getId();
}
- //check if folder already exist
- public boolean checkFolder() {
+ // check if folder already exist
+ public boolean checkFolder() {
try {
Files.List request = service.files().list().setQ("mimeType = 'application/vnd.google-apps.folder' and name = 'cemu_savegames'");
FileList files = request.execute();
@@ -215,32 +152,58 @@ public class GoogleDriveController {
}
}
- //reading all local savegames
- private void getLocalSavegames() throws IOException {
- java.io.File dir = new java.io.File(saveDirectory);
- String[] extensions = new String[] { "dat","sav","bin" };
- localSavegames.removeAll(localSavegames);
- localSavegamesName.removeAll(localSavegamesName);
- LOGGER.info("Getting all dat,sav,bin files in " + dir.getCanonicalPath()+" including those in subdirectories");
- List files = (List) FileUtils.listFiles(dir, extensions, true);
- for (java.io.File file : files) {
- localSavegamesName.add(file.getParentFile().getName()+"_"+file.getName());
- localSavegames.add(file);
- }
- }
-
- //reading all cloud savegames
- private void getCloudSavegames() throws IOException {
- LOGGER.info("getting all cloud savegames");
- cloudSavegames.removeAll(cloudSavegames);
- cloudSavegamesName.removeAll(cloudSavegamesName);
+ // FIXME it seams like there is a bug in this method
+ // get the name of the zip in the semu_savegames folder, which is the last upload Unix time
+ public long getLastCloudSync() throws IOException {
+ LOGGER.info("getting last cloud sync");
+ long lastCloudSync = 0;
Files.List request = service.files().list().setQ("'"+folderID+"' in parents").setFields("nextPageToken, files(id, name, size, modifiedTime, createdTime, md5Checksum)");
FileList files = request.execute();
for (File file : files.getFiles()) {
- cloudSavegamesName.add(file.getName());
- cloudSavegames.add(file);
+ downloadFile = file;
+ lastCloudSync = Long.parseLong(file.getName().substring(0, file.getName().length()-4));
+ }
+
+ return lastCloudSync;
+ }
+
+ /**
+ * delete all existing files in cemu_savegames at first
+ * upload the new savegames zip file
+ * @param uploadFile savegames zip file
+ * @throws IOException
+ */
+ public void uploadZipFile(java.io.File uploadFile) throws IOException{
+
+ LOGGER.info("deleting old savegames ...");
+ Files.List request = service.files().list().setQ("'"+folderID+"' in parents").setFields("nextPageToken, files(id, name, size, modifiedTime, createdTime, md5Checksum)");
+ FileList files = request.execute();
+
+ for (File file : files.getFiles()) {
+ service.files().delete(file.getId()).execute(); // deleting old file
}
+
+ LOGGER.info("uploading " + uploadFile.getName() + " ...");
+ File fileMetadata = new File();
+ fileMetadata.setName(uploadFile.getName());
+ fileMetadata.setParents(Collections.singletonList(folderID));
+ fileMetadata.setModifiedTime(new DateTime(uploadFile.lastModified()));
+ FileContent mediaContent = new FileContent("", uploadFile);
+ File file = service.files().create(fileMetadata, mediaContent).setFields("id, parents").execute();
+ LOGGER.info("upload successfull, File ID: " + file.getId());
+ }
+
+ // download zip file from the cloud and unzip it
+ public java.io.File downloadZipFile(String cemu_UIDirectory) throws IOException{
+ LOGGER.info("downloading "+downloadFile.getName()+" ...");
+ java.io.File outputFile = new java.io.File(cemu_UIDirectory + "/" + downloadFile.getName());
+
+ OutputStream outputStream = new FileOutputStream(outputFile);
+ service.files().get(downloadFile.getId()).executeMediaAndDownloadTo(outputStream);
+ outputStream.close();
+ LOGGER.info("download successfull: " + downloadFile.getName());
+ return outputFile;
}
private void getSavegamesFolderID() throws IOException {
@@ -253,72 +216,14 @@ public class GoogleDriveController {
} catch (Exception e) {
LOGGER.error("Oops, something went wrong! It seems that you have more than one folder called 'cemu_savegames'!", e);
}
- }
-
+}
- //upload a file to the cloud from the local savegames folder
- public void uploadFile(java.io.File uploadFile) throws IOException{
- LOGGER.info("uploading " + uploadFile.getName() + " ...");
- File fileMetadata = new File();
- fileMetadata.setName(uploadFile.getParentFile().getName()+"_"+uploadFile.getName());
- fileMetadata.setParents(Collections.singletonList(folderID));
- fileMetadata.setModifiedTime(new DateTime(uploadFile.lastModified()));
- FileContent mediaContent = new FileContent("", uploadFile);
- File file = service.files().create(fileMetadata, mediaContent).setFields("id, parents").execute();
- LOGGER.info("upload successfull, File ID: " + file.getId());
- }
-
- //download a file from the cloud to the local savegames folder
- private void downloadFile(File downloadFile) throws IOException{
- LOGGER.info("downloading "+downloadFile.getName()+" ...");
- java.io.File directory = new java.io.File(saveDirectory + "/" + downloadFile.getName().substring(0,8));
- String file = downloadFile.getName().substring(9,downloadFile.getName().length());
- if(!directory.exists()) {
- LOGGER.info("dir dosent exist");
- directory.mkdir();
- }
-
- OutputStream outputStream = new FileOutputStream(directory +"/"+ file);
- service.files().get(downloadFile.getId()).executeMediaAndDownloadTo(outputStream);
- outputStream.close();
- LOGGER.info("download successfull, File ID: " + file); //TODO add FileID
- }
-
- //update a file in the cloud, by deleting the old one and uploading an new with the same id
- private void updateFile(File oldFile, java.io.File newFile) throws IOException {
- LOGGER.info("updating " +oldFile.getName()+" ...");
- service.files().delete(oldFile.getId()).execute(); //deleting old file
-
- //uploading new file
- File fileMetadata = new File();
- fileMetadata.setName(newFile.getParentFile().getName()+"_"+newFile.getName());
- fileMetadata.setParents(Collections.singletonList(folderID));
- fileMetadata.setModifiedTime(new DateTime(newFile.lastModified()));
-
- FileContent mediaContent = new FileContent("", newFile);
- File file = service.files().create(fileMetadata, mediaContent).setFields("id, parents").execute();
- LOGGER.info("update successfull, File ID: " + file.getId());
- }
-
- public void uploadAllFiles() {
- try {
- getLocalSavegames();
- LOGGER.info("uploading " + localSavegames.size() + " files ...");
- for (int i = 0; i < localSavegames.size(); i++) {
- uploadFile(localSavegames.get(i));
- }
- LOGGER.info("finished uploading all files");
- } catch (IOException e) {
- LOGGER.error("error while uploading all files", e);
- }
- }
-
-
public String getFolderID() {
return folderID;
}
public void setFolderID(String folderID) {
this.folderID = folderID;
- }
+}
+
}
diff --git a/src/main/resources/fxml/MainWindow.fxml b/src/main/resources/fxml/MainWindow.fxml
index 4f85bb4..d67e830 100644
--- a/src/main/resources/fxml/MainWindow.fxml
+++ b/src/main/resources/fxml/MainWindow.fxml
@@ -118,10 +118,16 @@
-
+
+
+
+
+
+
+
@@ -205,13 +211,17 @@
-
-
-
-
+
+
+
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/locals/cemu_UI-Local_de_DE.properties b/src/main/resources/locals/cemu_UI-Local_de_DE.properties
new file mode 100644
index 0000000..598d579
--- /dev/null
+++ b/src/main/resources/locals/cemu_UI-Local_de_DE.properties
@@ -0,0 +1,87 @@
+#HomeFlix-Local_de_DE.properties geramn Local
+
+# Buttons
+aboutBtn = \u00dcber
+settingsBtn = Einstellungen
+addBtn = Spiel hinzuf\u00fcgen
+reloadRomsBtn = ROMs neu laden
+smmdbBtn = smmdb
+cemuTFBtn = Ordner \u00F6ffnen
+romTFBtn = Ordner \u00F6ffnen
+smmdbDownloadBtn = Download
+playBtn = spielen
+cloudSyncToggleBtn = Spielst\u00e4nde \u00fcber die Cloud syncronisieren (Google Drive)
+autoUpdateToggleBtn = beim Start nach Updates suchen
+fullscreenToggleBtn = Spiel im Vollbildmodus starten
+
+# Labels
+cemu_UISettingsLbl = cemu_UI Einstellungen
+cemuDirectoryLbl = cemu directory
+romDirectoryLbl = ROM directory
+mainColorLbl = Hauptfarbe
+languageLbl = Sprache
+updateLbl = updates
+branchLbl = Updatezweig
+cemuSettingsLbl = cemu Einstellungen
+licensesLbl = Lizenzen
+
+# Columns
+titleColumn = Titel
+idColumn = ID
+starsColumn = Sterne
+timeColumn = Zeit
+
+# Strings
+editHeadingText = bearbeiten
+editBodyText = Du kannst den Title und den ROM-/Coverpfad bearbeiten.
+removeHeadingText = löschen
+removeBodyText = Bist du sicher dass du flgendes Spiel l\u00f6schen m\u00f6chtest
+addUpdateHeadingText = update
+addUpdateBodyText = Bitte w\u00e4hle das Update-Verzeichniss aus.
+addDLCHeadingText = ein DLC hinzufügen
+addDLCBodyText = Bitte w\u00e4hle das DLC-Verzeichniss aus.
+
+licensesLblHeadingText = cemu_UI
+licensesLblBodyText = cemu_UI ist lizensiert unter der GNU GPL 3.\n\nJFoenix, Apache License 2.0\nminimal-json, MIT License\nsqlite-jdbc, Apache License 2.0\nApache Commons IO, Apache License 2.0\nApache Commons Logging, Apache License 2.0\nApache Commons Codec, Apache License 2.0\nApache Log4j 2, Apache License 2.0\n
+showLicenses = Lizenzen \u00f6ffnen
+
+aboutBtnHeadingText = cemu_UI
+aboutBtnBodyText = Diese Programm wurde mit freier Software erstellt\nund ist lizensiert unter der GNU GPL 3.\n\nwww.kellerkinder.xyz
+
+cloudSyncWaringHeadingText = Spielst\u00e4nde über die Cloud syncronisieren (beta)
+cloudSyncWaringBodyText = WARNING this is a completly WIP cloud save integration,\nit's NOT recomended to use this!!\n\nUse it on your own risk and backup everthing before!
+
+cloudSyncErrorHeadingText = Fehler beim initialisieren der Cloud-Verbindung!
+cloudSyncErrorBodyText = Fehler beim initialisieren der Cloud-Verbindung.\nBitte lade die app.log (welceh du im cemu_UI Verzeichniss findest)\nauf \"https://github.com/Seil0/cemu_UI/issues\" hoch.
+
+addGameBtnHeadingText = eine neues Spiel zu cemu_Ui hinzuf\u00fcgen
+addGameBtnBodyText =
+addBtnReturnErrorHeadingText = Fehler beim hinzuf\u00fcgen des Spiels!
+addBtnReturnErrorBodyText = Fehler beim hinzuf\u00fcgen des Spiels.\nEiner der benötigten Werte war leer, bitte versuche es erneut.
+lastPlayed = zuletzt gespielt,
+today = heute
+yesterday = gestern
+never = nie
+
+# button strings
+playBtnPlay = spieles
+playBtnUpdating = updating...
+playBtnCopyingFiles = kopiere Dateien...
+smmdbDownloadBtnLoading = laden
+smmdbDownloadBtnDownload = Download
+okayBtnText = okay
+cancelBtnText = abbruch
+updateBtnCheckNow = Auf Update pr\u00FCfen
+updateBtnChecking = Es wird nach Updates gesucht...
+updateBtnNoUpdateAvailable = Kein Update verf\u00FCgbar
+updateBtnUpdateAvailable = Update verf\u00FCgbar
+
+#EditGameDialog
+gameTitle = Spiel Titel
+titleID = Titel ID
+romPath = ROM Pfad
+coverPath = Cover-Pfad
+editGameDialogHeadingTextError = Fehler beim hinzuf\u00fcgen des Spiels!
+editGameDialogBodyTextError = Fehler beim hinzuf\u00fcgen des Spiels.\nEiner der benötigten Werte war leer, bitte versuche es erneut.
+editGameDialogSelectPathBtn = .rpx Datei ausw\u00E4hlen
+editGameDialogSelectCoverBtn = cover Datei ausw\u00E4hlen
diff --git a/src/main/resources/locals/cemu_UI-Local_en_US.properties b/src/main/resources/locals/cemu_UI-Local_en_US.properties
new file mode 100644
index 0000000..f93fce9
--- /dev/null
+++ b/src/main/resources/locals/cemu_UI-Local_en_US.properties
@@ -0,0 +1,87 @@
+#HomeFlix-Local_en_US.properties US-English Local and default
+
+# Buttons
+aboutBtn = About
+settingsBtn = Setting
+addBtn = Add new Game
+reloadRomsBtn = reload ROMs
+smmdbBtn = smmdb
+cemuTFBtn = choose directory
+romTFBtn = choose directory
+smmdbDownloadBtn = Download
+playBtn = play
+cloudSyncToggleBtn = cloud savegames (Google Drive)
+autoUpdateToggleBtn = check for updates on startup
+fullscreenToggleBtn = start game in fullscreen
+
+# Labels
+cemu_UISettingsLbl = cemu_UI Settings
+cemuDirectoryLbl = cemu directory
+romDirectoryLbl = ROM directory
+mainColorLbl = main color
+languageLbl = language
+updateLbl = updates
+branchLbl = branch
+cemuSettingsLbl = cemu Settings
+licensesLbl = Licenses
+
+# Columns
+titleColumn = title
+idColumn = ID
+starsColumn = stars
+timeColumn = time
+
+# Strings
+editHeadingText = edit
+editBodyText = You can edit the tile and rom/cover path.
+removeHeadingText = remove
+removeBodyText = Are you sure you want to delete
+addUpdateHeadingText = update
+addUpdateBodyText = Please select the update root directory.
+addDLCHeadingText = add a DLC to
+addDLCBodyText = Please select the DLC root directory.
+
+licensesLblHeadingText = cemu_UI
+licensesLblBodyText = cemu_UI is licensed under the terms of GNU GPL 3.\n\nJFoenix, Apache License 2.0\nminimal-json, MIT License\nsqlite-jdbc, Apache License 2.0\nApache Commons IO, Apache License 2.0\nApache Commons Logging, Apache License 2.0\nApache Commons Codec, Apache License 2.0\nApache Log4j 2, Apache License 2.0\n
+showLicenses = show licenses
+
+aboutBtnHeadingText = cemu_UI
+aboutBtnBodyText = This Application is made with free Software\nand licensed under the terms of GNU GPL 3.\n\nwww.kellerkinder.xyz
+
+cloudSyncWaringHeadingText = activate cloud savegame sync (beta)
+cloudSyncWaringBodyText = WARNING this is a completly WIP cloud save integration,\nit's NOT recomended to use this!!\n\nUse it on your own risk and backup everthing before!
+
+cloudSyncErrorHeadingText = Error while initializing cloud sync!
+cloudSyncErrorBodyText = There was some truble while initializing cloud sync.\nPlease upload the app.log (which can be found in the cemu_UI directory)\nto \"https://github.com/Seil0/cemu_UI/issues\" so we can fix this.
+
+addGameBtnHeadingText = add a new game to cemu_UI
+addGameBtnBodyText =
+addBtnReturnErrorHeadingText = Error while adding a new Game!
+addBtnReturnErrorBodyText = There was some truble adding your game.\nOne of the needed values was empty, please try again to add your game.
+lastPlayed = Last played,
+today = today
+yesterday = yesterday
+never = never
+
+# button strings
+playBtnPlay = play
+playBtnUpdating = updating...
+playBtnCopyingFiles = copying files...
+smmdbDownloadBtnLoading = loading
+smmdbDownloadBtnDownload = Download
+okayBtnText = okay
+cancelBtnText = cancel
+updateBtnCheckNow = check now!
+updateBtnChecking = checking for updates ...
+updateBtnNoUpdateAvailable = no update available
+updateBtnUpdateAvailable = update available
+
+#EditGameDialog
+gameTitle = game title
+titleID = title ID
+romPath = ROM path
+coverPath = cover path
+editGameDialogHeadingTextError = Error while adding a new Game!
+editGameDialogBodyTextError = There was some truble adding your game.\nOne of the needed values was empty, please try again to add your game.
+editGameDialogSelectPathBtn = select .rpx file
+editGameDialogSelectCoverBtn = select cover file