import com.jfoenix.controls.*; import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; import javafx.concurrent.Service; import javafx.concurrent.Task; import javafx.fxml.FXML; import javafx.scene.control.Alert; import javafx.scene.control.Label; import javafx.scene.control.Tooltip; import javafx.stage.FileChooser; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.configuration2.ex.ConfigurationException; import org.jsoup.HttpStatusException; import pojo.App; import util.CreamApiConfig; import util.CreamApiDllHandler; import util.SteamAppsListCache; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Map; import java.util.Objects; public class Controller { private static final String REGEX = "(?steam_api(?:64)?.dll)$"; private CreamApiDllHandler handler = null; { try { handler = CreamApiDllHandler.getInstance(); } catch (IOException e) { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle("CreamAPI DLLs missing!"); alert.setHeaderText("CreamAPI DLL files can't be found!"); alert.setContentText("Please download CreamAPI and extract the non-log " + "version in the same folder as Auto-CreamAPI!\nThe program will now close."); alert.showAndWait(); System.exit(10); } } private final CreamApiConfig config = CreamApiConfig.getInstance(); private final SteamAppsListCache cache = new SteamAppsListCache(); @FXML public Label state_label; @FXML public JFXTextField path_textfield; @FXML public JFXTextField appId_textfield; @FXML public JFXTextField game_name_textfield; @FXML public JFXComboBox language_combobox; @FXML public JFXTextArea dlc_textarea; @FXML public JFXCheckBox extra_protection_checkbox; @FXML public JFXCheckBox offline_checkbox; @FXML public JFXCheckBox unlock_all_checkbox; @FXML public JFXButton reset_button; @FXML public JFXButton save_button; @FXML public JFXButton getAppId_button; @FXML public JFXButton path_button; @FXML public JFXButton retrieveDlcList_button; private String steamApiPathString; public Controller() { } @FXML public void initialize() { appId_textfield.textProperty().addListener(appIdChangesGameName()); //retrieveDlcList_button.setDisable(true); // WIP generate_tooltips(); fix_dlc_textarea_prompt_text(); reset(true); state_label.setText("Ready."); } private void read() { language_combobox.setItems(FXCollections.observableArrayList(config.getLanguages())); language_combobox.getSelectionModel().select(config.getLanguage()); appId_textfield.setText(config.getAppId().toString()); dlc_textarea.setText(config.getDlcListAsString()); game_name_textfield.setText(cache.getGame(config.getAppId()).getName()); extra_protection_checkbox.setSelected(config.getExtraProtection()); offline_checkbox.setSelected(config.getForceOffline()); unlock_all_checkbox.setSelected(config.getUnlockAll()); unlockAll_disableDlcTextArea(); } private void fix_dlc_textarea_prompt_text() { dlc_textarea.setPromptText("List of DLC...\r0000 = DLC Name"); } private void generate_tooltips() { Tooltip extra_protection_tooltip = new Tooltip("\"extra protection\""); extra_protection_checkbox.setTooltip(extra_protection_tooltip); Tooltip.install(extra_protection_checkbox, extra_protection_tooltip); } private ChangeListener appIdChangesGameName() { return (observable, oldValue, newValue) -> { int appId; try { appId = Integer.parseInt(newValue); final App game = cache.getGame(appId); if (game != null) { game_name_textfield.setText(game.getName()); } else { game_name_textfield.setText(""); } } catch (NumberFormatException e) { game_name_textfield.setText(""); } }; } private void reset(boolean silent) { if (silent) { state_label.setText(""); } else { state_label.setText("Resetting fields..."); } try { config.read(); read(); if (!silent) { state_label.setText("Successfully reset all fields!"); } } catch (NullPointerException e) { System.err.println("Can't fill out fields, no configuration file set!"); if (!silent) { state_label.setText("Could not reset fields, no configuration file set!"); } } } public void save() { Service s = new Service() { @Override protected Task createTask() { return new Task() { @Override protected Void call() { try { setUpCreamApi(); config.setDlcListFromString(dlc_textarea.getText()); config.setAppId(Integer.parseInt(appId_textfield.getText())); config.setExtraProtection(extra_protection_checkbox.isSelected()); config.setForceOffline(offline_checkbox.isSelected()); config.setUnlockAll(unlock_all_checkbox.isSelected()); config.setLanguage(language_combobox.getValue()); config.sync(); } catch (IOException | ConfigurationException e) { e.printStackTrace(); cancel(); } catch (NullPointerException e) { System.err.println("No configuration file set!"); cancel(); } return null; } }; } }; s.setOnRunning(event -> { setDisableAllButtons(true); state_label.setText("Saving..."); }); s.setOnSucceeded(event -> { setDisableAllButtons(false); state_label.setText("Saved successfully!"); }); s.setOnCancelled(event -> { setDisableAllButtons(false); state_label.setText("Could not save configuration file!"); }); s.start(); } public void getAppId() { final App game = cache.findGame(game_name_textfield.getText()); if (game == null) { appId_textfield.setText("-1"); } else { appId_textfield.setText(String.valueOf(game.getAppId())); } } public void unlockAll_disableDlcTextArea() { dlc_textarea.setDisable(unlock_all_checkbox.isSelected()); retrieveDlcList_button.setDisable(unlock_all_checkbox.isSelected()); } /** * Gets DLC from both the Steam Store and SteamDB, since the latter has a (weird) limit of 64(?) DLCs. SteamDB * also lists DLC not available for purchase. */ public void getDlcList() { Service s = new Service() { @Override protected Task createTask() { return new Task() { @Override protected Void call() { try { Map collect = cache.getDlcMap(appId_textfield.getText()); StringBuilder sb = new StringBuilder(); collect.forEach((k, v) -> sb.append(k).append("=").append(v).append("\n")); dlc_textarea.setText(sb.toString()); } catch (HttpStatusException e) { if (e.getStatusCode() == 404) { System.err.println("App ID empty or not found! (HTTP Status Code: 404)"); } else { // e.printStackTrace(); System.err.println("STATUS CODE: " + e.getStatusCode()); } cancel(); } catch (IOException e) { e.printStackTrace(); cancel(); } return null; } }; } }; s.setOnRunning(event -> { setDisableAllButtons(true); state_label.setText("Getting list of DLCs..."); }); s.setOnSucceeded(event -> { setDisableAllButtons(false); state_label.setText("Got list of DLCs successfully!"); }); s.setOnCancelled(event -> { setDisableAllButtons(false); state_label.setText("Could not get list of DLCs!"); }); s.start(); } public void openFileChooser() { FileChooser chooser = new FileChooser(); chooser.setTitle("Choose steam_api(64).dll..."); FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter("steam_api(64).dll", "steam_api.dll", "steam_api64.dll"); chooser.getExtensionFilters().add(filter); final File file = chooser.showOpenDialog(path_button.getScene().getWindow()); try { config.setConfig(file.getParent() + "\\cream_api.ini"); path_textfield.setText(file.getParent()); steamApiPathString = file.getAbsolutePath(); reset(true); state_label.setText("Ready."); } catch (ConfigurationException | IOException e) { e.printStackTrace(); } } /** * check if creamapi version of dll is there, if not, rename original to steam_api(64)_o.dll and copy * creamapi one to the path. * * @throws IOException If file is missing or not accessible/modifiable. */ private void setUpCreamApi() throws IOException { boolean is64Bit = false; if (!steamApiPathString.isEmpty()) { Path path = Paths.get(steamApiPathString); if (path.endsWith("steam_api64.dll")) { is64Bit = true; } InputStream is = Files.newInputStream(path); String md5 = DigestUtils.md5Hex(is); boolean isSameFile = Objects.equals(md5, handler.getDllMd5(is64Bit)); if (!isSameFile) { String pathOrigString = steamApiPathString; pathOrigString = pathOrigString .replaceFirst(REGEX, is64Bit ? "steam_api64_o.dll" : "steam_api_o.dll"); Path pathOrig = Paths.get(pathOrigString); if (!Files.exists(pathOrig)) { Files.move(path, pathOrig); } Files.deleteIfExists(path); Files.copy(handler.getDllPath(is64Bit), path); } } } private void setDisableAllButtons(boolean b) { reset_button.setDisable(b); save_button.setDisable(b); getAppId_button.setDisable(b); path_button.setDisable(b); retrieveDlcList_button.setDisable(b); } public void resetFromButton() { reset(false); } }