auto-creamapi/src/main/java/Controller.java

317 lines
12 KiB
Java

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 = "(?<steamApiDll>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<String> 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<String> 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<Void> s = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@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<Void> s = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() {
try {
Map<Number, String> 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);
}
}