253 lines
9.5 KiB
Java
253 lines
9.5 KiB
Java
import com.jfoenix.controls.*;
|
|
import javafx.beans.value.ChangeListener;
|
|
import javafx.collections.FXCollections;
|
|
import javafx.fxml.FXML;
|
|
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.Jsoup;
|
|
import org.jsoup.nodes.Document;
|
|
import org.jsoup.nodes.Element;
|
|
import org.jsoup.select.Elements;
|
|
import pojo.App;
|
|
import util.CreamApiConfig;
|
|
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.HashMap;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.Map;
|
|
import java.util.Objects;
|
|
import java.util.stream.Collectors;
|
|
|
|
public class Controller {
|
|
private static final String X86_MD5_HASH = "c6f267a2d10b891ed352ed849a28d69b";
|
|
private static final String X64_MD5_HASH = "645c728a6117946294130d07cf6c0cae";
|
|
private CreamApiConfig config = CreamApiConfig.getInstance();
|
|
private SteamAppsListCache cache = new SteamAppsListCache();
|
|
@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();
|
|
read();
|
|
}
|
|
|
|
private void read() {
|
|
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());
|
|
language_combobox.setItems(FXCollections.observableArrayList(config.getLanguages()));
|
|
language_combobox.getSelectionModel().select(config.getLanguage());
|
|
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("");
|
|
}
|
|
};
|
|
}
|
|
|
|
public void reset() {
|
|
config.read();
|
|
read();
|
|
}
|
|
|
|
public void save() {
|
|
try {
|
|
setUpCreamApi();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
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());
|
|
try {
|
|
config.sync();
|
|
} catch (ConfigurationException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
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() {
|
|
Map<Integer, String> steamStoreDLCs = new HashMap<>();
|
|
Map<Integer, String> steamDbDLCs = new HashMap<>();
|
|
//StringBuilder sb = new StringBuilder();
|
|
try {
|
|
// Steam Store
|
|
Document steamDoc = Jsoup
|
|
.connect("https://store.steampowered.com/app/" + appId_textfield.getText() + "/")
|
|
.get();
|
|
Elements steamDLCs = steamDoc.getElementsByClass("game_area_dlc_row");
|
|
for (Element dlc : steamDLCs) {
|
|
String dlc_id = dlc.attr("data-ds-appid");
|
|
String dlc_name = dlc
|
|
.getElementsByClass("game_area_dlc_name")
|
|
.text().replace("\n", "").trim();
|
|
steamStoreDLCs.put(Integer.parseInt(dlc_id), dlc_name);
|
|
}
|
|
// SteamDB
|
|
Document steamDbDoc = Jsoup
|
|
.connect("https://steamdb.info/app/" + appId_textfield.getText() + "/dlc/")
|
|
.get();
|
|
Element steamDbDlcSection = steamDbDoc.getElementById("dlc");
|
|
Elements steamDbDLCElements = steamDbDlcSection.getElementsByClass("app");
|
|
for (Element dlc : steamDbDLCElements) {
|
|
String dlc_id = dlc.attr("data-appid");
|
|
String dlc_name = "Unknown DLC " + dlc_id;
|
|
Elements td = dlc.getElementsByTag("td");
|
|
if (!td.isEmpty()) {
|
|
dlc_name = td.get(1).text().replace("\n", "").trim();
|
|
}
|
|
steamDbDLCs.put(Integer.parseInt(dlc_id), dlc_name);
|
|
}
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
} catch (NullPointerException e) {
|
|
// ignore
|
|
}
|
|
|
|
Map<Integer, String> allDLCs = new HashMap<>(steamStoreDLCs);
|
|
steamDbDLCs.forEach(allDLCs::putIfAbsent);
|
|
StringBuilder sb = new StringBuilder();
|
|
LinkedHashMap<Number, String> collect = allDLCs.entrySet().stream()
|
|
.sorted(Map.Entry.comparingByKey())
|
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
|
|
(oldValue, newValue) -> oldValue, LinkedHashMap::new));
|
|
collect.forEach((k, v) -> sb.append(k).append("=").append(v).append("\n"));
|
|
dlc_textarea.setText(sb.toString());
|
|
}
|
|
|
|
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();
|
|
} 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, is64Bit ? X64_MD5_HASH : X86_MD5_HASH);
|
|
if (!isSameFile) {
|
|
String pathOrigString = steamApiPathString;
|
|
pathOrigString =
|
|
pathOrigString
|
|
.replaceFirst("(?<steamApiDll>steam_api(?:64)?.dll)$",
|
|
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(Paths.get(is64Bit ? "steam_api64.dll" : "steam_api.dll"), path);
|
|
}
|
|
}
|
|
}
|
|
}
|