Compare commits
29 Commits
visual-ind
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
3bf33b0d4c | ||
da947e1f51 | |||
21a7ec98dd | |||
992f2fb20c | |||
26872ec8fb | |||
452e78b1ed | |||
cce8bbe513 | |||
5043ffefff | |||
032a85600f | |||
4a8ecd32ac | |||
6afa33db75 | |||
7c5329fd54 | |||
b7ec6a62a3 | |||
bd70c814b9 | |||
272b1d0833 | |||
1fdf90da8a | |||
79bda2b1fd | |||
7d9514abae | |||
8c23ae27e8 | |||
308f20cb81 | |||
d71d8ed789 | |||
dd99292c65 | |||
36a05fcd8e | |||
fe71a8acc2 | |||
6f7d1b5695 | |||
5b912a0991 | |||
30551bccda | |||
c2254856da | |||
4eda79211e |
40
.drone.yml
Normal file
40
.drone.yml
Normal file
@ -0,0 +1,40 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: maven:3-amazoncorretto-8
|
||||
commands:
|
||||
- mvn install
|
||||
- name: gitea_release
|
||||
image: plugins/gitea-release
|
||||
settings:
|
||||
api_key:
|
||||
from_secret: gitea_token
|
||||
base_url: https://git.jeddunk.xyz
|
||||
files:
|
||||
- auto-cream-api-*.zip
|
||||
checksum:
|
||||
- md5
|
||||
- sha1
|
||||
- sha256
|
||||
- sha512
|
||||
- adler32
|
||||
- crc32
|
||||
when:
|
||||
event:
|
||||
- tag
|
||||
- name: discord_webhook
|
||||
image: appleboy/drone-discord
|
||||
settings:
|
||||
webhook_id:
|
||||
from_secret: discord_webhook_id
|
||||
webhook_token:
|
||||
from_secret: discord_webhook_token
|
||||
message: >
|
||||
{{#success build.status}}
|
||||
build {{build.number}} succeeded.
|
||||
{{else}}
|
||||
build {{build.number}} failed.
|
||||
{{/success}}
|
5
.gitignore
vendored
5
.gitignore
vendored
@ -159,5 +159,6 @@ $RECYCLE.BIN/
|
||||
/steamapps.json
|
||||
/test.json
|
||||
/steam_api.md5
|
||||
/src/main/java/util/env/Default.java
|
||||
/src/main/java/GetListOfDlc.java
|
||||
/src/main/java/xyz/jeddunk/autocreamapi/util/env/Default.java
|
||||
/src/main/java/xyz/jeddunk/autocreamapi/GetListOfDlc.java
|
||||
dist/
|
||||
|
6
.idea/checkstyleidea-libs/readme.txt
Normal file
6
.idea/checkstyleidea-libs/readme.txt
Normal file
@ -0,0 +1,6 @@
|
||||
This folder contains libraries copied from the "auto-cream-api" project.
|
||||
It is managed by the CheckStyle-IDEA IDE plugin.
|
||||
Do not modify this folder while the IDE is running.
|
||||
When the IDE is stopped, you may delete this folder at any time. It will be recreated as needed.
|
||||
In order to prevent the CheckStyle-IDEA IDE plugin from creating this folder,
|
||||
uncheck the "Copy libraries from project directory" option in the CheckStyle-IDEA settings dialog.
|
@ -13,7 +13,7 @@
|
||||
<component name="ProjectKey">
|
||||
<option name="state" value="project://e79810c8-c5c8-43b1-b19c-90c1f4095425" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8 (amazon)" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
18
README.md
18
README.md
@ -1,9 +1,17 @@
|
||||
# Auto-CreamAPI
|
||||
|
||||
## Development is continuing [here](https://git.jeddunk.xyz/jeddunk/auto-creamapi-2)! However you're still welcome to use this version.
|
||||
|
||||
[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/H2H4330U3)
|
||||
[![Build Status](https://ci.jeddunk.xyz/api/badges/jeddunk/auto-cream-api/status.svg)](https://ci.jeddunk.xyz/jeddunk/auto-cream-api)
|
||||
|
||||
Set your game automatically up for use with CreamAPI.
|
||||
|
||||
![](https://jeddunk.xyz/javaw_nLB130vOCY.png)
|
||||
|
||||
[![](https://jeddunk.xyz/jetbrains-small.png)](https://www.jetbrains.com/?from=Auto-CreamAPI)
|
||||
[Made with software provided by JetBrains s.r.o.](https://www.jetbrains.com/?from=Auto-CreamAPI)
|
||||
|
||||
## Features
|
||||
* Setup CreamAPI’s DLLs and configuration file automatically.
|
||||
* Find the AppID by providing the game’s name without having to look it up manually.
|
||||
@ -35,7 +43,7 @@ Download the latest release and extract it into any folder (e.g. `%USERPROFILE%\
|
||||
* Select a language and tick the options if needed.
|
||||
* Click on *"Save"*.
|
||||
|
||||
### Java 11
|
||||
### Java 11/Java 14
|
||||
|
||||
*WIP*
|
||||
|
||||
@ -51,7 +59,15 @@ The following dependencies are licensed under the Apache License 2.0:
|
||||
* gson
|
||||
* Apache Commons BeanUtils
|
||||
* Apache Commons Configuration
|
||||
* The Roboto font family
|
||||
|
||||
The following dependencies are licensed under the MIT License:
|
||||
* jsoup
|
||||
* Unirest-Java
|
||||
* slf4j
|
||||
* Copy Rename Maven Plugin
|
||||
|
||||
The following dependencies are licensed under the GPL2 License:
|
||||
* fuzzywuzzy
|
||||
|
||||
Logback is dual-licensed under the EPL v1.0 and the LGPL 2.1.
|
||||
|
@ -12,6 +12,7 @@
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
@ -34,5 +35,68 @@
|
||||
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpmime:4.5.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpasyncclient:4.1.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore-nio:4.4.10" level="project" />
|
||||
<orderEntry type="library" name="Maven: me.xdrop:fuzzywuzzy:1.3.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.coderplus.maven.plugins:copy-rename-maven-plugin:1.0.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-model:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-project:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-settings:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-profile:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-artifact-manager:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-plugin-registry:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.codehaus.plexus:plexus-container-default:1.0-alpha-9-stable-1" level="project" />
|
||||
<orderEntry type="library" name="Maven: junit:junit:3.8.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-core:2.0.9" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.maven.wagon:wagon-file:1.0-beta-2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-plugin-parameter-documenter:2.0.9" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.maven.wagon:wagon-webdav:1.0-beta-2" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: slide:slide-webdavlib:2.1" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: commons-httpclient:commons-httpclient:2.0.2" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: jdom:jdom:1.0" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: de.zeigermann.xml:xml-im-exporter:1.1" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.maven.wagon:wagon-http-lightweight:1.0-beta-2" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.maven.wagon:wagon-http-shared:1.0-beta-2" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: jtidy:jtidy:4aug2000r7-dev" level="project" />
|
||||
<orderEntry type="library" name="Maven: xml-apis:xml-apis:1.0.b2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven.reporting:maven-reporting-api:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven.doxia:doxia-sink-api:1.0-alpha-10" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven.wagon:wagon-provider-api:1.0-beta-2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-repository-metadata:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-error-diagnostics:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-cli:commons-cli:1.0" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.maven.wagon:wagon-ssh-external:1.0-beta-2" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.maven.wagon:wagon-ssh-common:1.0-beta-2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-plugin-descriptor:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.codehaus.plexus:plexus-interactivity-api:1.0-alpha-4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-monitor:2.0.9" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.maven.wagon:wagon-ssh:1.0-beta-2" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: com.jcraft:jsch:0.1.27" level="project" />
|
||||
<orderEntry type="library" name="Maven: classworlds:classworlds:1.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-plugin-api:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.maven:maven-artifact:2.0.9" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.codehaus.plexus:plexus-utils:1.5.8" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.sonatype.plexus:plexus-build-api:0.0.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.fusesource.jansi:jansi:1.18" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.sourceforge.htmlunit:htmlunit:2.44.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: xalan:xalan:2.7.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: xalan:serializer:2.7.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.sourceforge.htmlunit:htmlunit-core-js:2.44.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.sourceforge.htmlunit:neko-htmlunit:2.44.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: xerces:xercesImpl:2.12.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: net.sourceforge.htmlunit:htmlunit-cssparser:1.6.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-io:commons-io:2.8.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-net:commons-net:3.7.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.brotli:dec:0.1.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.shapesecurity:salvation2:3.0.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.32.v20200930" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.32.v20200930" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.32.v20200930" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.32.v20200930" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.32.v20200930" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.32.v20200930" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.32.v20200930" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.32.v20200930" level="project" />
|
||||
</component>
|
||||
</module>
|
@ -1,16 +0,0 @@
|
||||
# List of languages
|
||||
# https://partner.steamgames.com/doc/store/localization#supported_languages
|
||||
|
||||
english
|
||||
latam
|
||||
brazilian
|
||||
german
|
||||
french
|
||||
italian
|
||||
portuguese
|
||||
spanish
|
||||
russian
|
||||
schinese
|
||||
tchinese
|
||||
japanese
|
||||
koreana
|
113
pom.xml
113
pom.xml
@ -21,16 +21,28 @@
|
||||
|
||||
<groupId>xyz.jeddunk</groupId>
|
||||
<artifactId>auto-cream-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<version>1.2.2</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<dist>${project.basedir}/dist</dist>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>dist</directory>
|
||||
</fileset>
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
@ -42,11 +54,11 @@
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.2-beta-5</version>
|
||||
<version>2.2.2</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>Main</mainClass>
|
||||
<mainClass>xyz.jeddunk.autocreamapi.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
@ -63,6 +75,72 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-install-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.coderplus.maven.plugins</groupId>
|
||||
<artifactId>copy-rename-maven-plugin</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install-copy</id>
|
||||
<phase>install</phase>
|
||||
<goals>
|
||||
<goal>copy</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<overWrite>true</overWrite>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<sourceFile>${project.build.directory}/${project.artifactId}-${project.version}-jar-with-dependencies.jar</sourceFile>
|
||||
<destinationFile>${dist}/${project.artifactId}.jar</destinationFile>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<sourceFile>${project.basedir}/README.md</sourceFile>
|
||||
<destinationFile>${dist}/README.md</destinationFile>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<sourceFile>${project.basedir}/steam_api.dll</sourceFile>
|
||||
<destinationFile>${dist}/steam_api.dll</destinationFile>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<sourceFile>${project.basedir}/steam_api64.dll</sourceFile>
|
||||
<destinationFile>${dist}/steam_api64.dll</destinationFile>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
<sourceFile>${project.basedir}/version.txt</sourceFile>
|
||||
<destinationFile>${dist}/version.txt</destinationFile>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.8</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>install-zip</id>
|
||||
<phase>install</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<target>
|
||||
<zip destfile="${project.basedir}/${project.artifactId}-${project.version}.zip" basedir="${dist}"/>
|
||||
</target>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@ -72,7 +150,7 @@
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>bintray-jerady-maven</id>
|
||||
<name>bintray</name>
|
||||
<name>bintray-jerady</name>
|
||||
<url>https://dl.bintray.com/jerady/maven</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
@ -82,7 +160,7 @@
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>bintray-jerady-maven</id>
|
||||
<name>bintray-plugins</name>
|
||||
<name>bintray-jerady-plugins</name>
|
||||
<url>https://dl.bintray.com/jerady/maven</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
@ -131,5 +209,30 @@
|
||||
<artifactId>unirest-java</artifactId>
|
||||
<version>3.1.02</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.xdrop</groupId>
|
||||
<artifactId>fuzzywuzzy</artifactId>
|
||||
<version>1.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.coderplus.maven.plugins</groupId>
|
||||
<artifactId>copy-rename-maven-plugin</artifactId>
|
||||
<version>1.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.fusesource.jansi</groupId>
|
||||
<artifactId>jansi</artifactId>
|
||||
<version>1.18</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<version>2.44.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -1,193 +0,0 @@
|
||||
/*
|
||||
* Auto-CreamAPI
|
||||
* Copyright (C) 2020 Jeddunk
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package util;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import kong.unirest.HttpResponse;
|
||||
import kong.unirest.Unirest;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
import pojo.App;
|
||||
import pojo.SteamAppsList;
|
||||
import util.env.MainEnv;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Type;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SteamAppsListCache {
|
||||
|
||||
private SteamAppsList list = new SteamAppsList();
|
||||
private final File cacheFile = new File("steamapps.json");
|
||||
private MainEnv env;
|
||||
//private String key;
|
||||
|
||||
public SteamAppsListCache() {
|
||||
try {
|
||||
Class<?> envDefault = Class.forName("util.env.Default");
|
||||
env = (MainEnv) envDefault.newInstance();
|
||||
// System.out.println(env.getKey());
|
||||
} catch (ClassNotFoundException e) {
|
||||
env = new MainEnv();
|
||||
} catch (IllegalAccessException | InstantiationException e) {
|
||||
// Only thrown by newInstance()
|
||||
e.printStackTrace();
|
||||
}
|
||||
//boolean fileFound = true;
|
||||
try {
|
||||
getListFromFile();
|
||||
} catch (FileNotFoundException e) {
|
||||
System.err.println("File does not exist, trying to create steamapps.json for the first time...");
|
||||
//fileFound = false;
|
||||
sync();
|
||||
} catch (JsonSyntaxException e) {
|
||||
System.err.println("File seems to be corrupt, trying to recreate steamapps.json...");
|
||||
//fileFound = false;
|
||||
sync();
|
||||
}
|
||||
if (Instant.now().isAfter(list.getTimestamp().plus(Duration.ofDays(3)))) {
|
||||
System.err.println("List in file is not recent!");
|
||||
sync();
|
||||
}
|
||||
}
|
||||
|
||||
private void sync() {
|
||||
getListFromApi();
|
||||
try {
|
||||
saveListToFile();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public App getGame(int appId) {
|
||||
return list.getSteamAppsList().stream().filter(app -> app.getAppId() == appId).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public App getGame(String name) {
|
||||
return list.getSteamAppsList().stream()
|
||||
.filter(app -> app.getName().equalsIgnoreCase(name)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public App findGame(String name) {
|
||||
for (App app : list.getSteamAppsList()) {
|
||||
if (app.getName().toLowerCase().replaceAll("[^a-zA-Z0-9\\s+]", "")
|
||||
.startsWith(name.toLowerCase().replaceAll("[^a-zA-Z0-9\\s+]", ""))) {
|
||||
return app;
|
||||
}
|
||||
}
|
||||
for (App app : list.getSteamAppsList()) {
|
||||
if (app.getName().toLowerCase().replaceAll("[^a-zA-Z0-9\\s+]", "")
|
||||
.contains(name.toLowerCase().replaceAll("[^a-zA-Z0-9\\s+]", ""))) {
|
||||
return app;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void getListFromApi() {
|
||||
System.out.println("Trying to get SteamAppList from API...");
|
||||
List<App> apps = getApps();
|
||||
list.setTimestamp(Instant.now());
|
||||
list.setSteamAppsList(apps);
|
||||
}
|
||||
|
||||
private List<App> getApps() {
|
||||
HttpResponse<String> httpResponse =
|
||||
Unirest.get("https://api.steampowered.com/IStoreService/GetAppList/v1/" +
|
||||
"?key=" + env.getKey() + "&include_games=1&max_results=50000").asString();
|
||||
return new Gson()
|
||||
.fromJson(httpResponse.getBody(), App.Rezponze.Download.class)
|
||||
.getResponse().getApps();
|
||||
}
|
||||
|
||||
private void saveListToFile() throws IOException {
|
||||
System.out.println("Trying to save SteamAppList to file (" + cacheFile.getAbsolutePath() + ")...");
|
||||
Gson gson = new Gson();
|
||||
String jsonString = gson.toJson(list);
|
||||
BufferedWriter fOut = new BufferedWriter(new FileWriter(cacheFile));
|
||||
fOut.write(jsonString);
|
||||
fOut.close();
|
||||
System.out.println("Successfully saved SteamAppList to file (" + cacheFile.getAbsolutePath() + ")...");
|
||||
}
|
||||
|
||||
private void getListFromFile() throws FileNotFoundException, JsonSyntaxException {
|
||||
System.out.println("Trying to get SteamAppList from file (" + cacheFile.getAbsolutePath() + ")...");
|
||||
BufferedReader fIn = new BufferedReader(new FileReader(cacheFile));
|
||||
String json = fIn.lines().collect(Collectors.joining());
|
||||
final Type type = new TypeToken<SteamAppsList>() {
|
||||
}.getType();
|
||||
Gson gson = new Gson();
|
||||
list = gson.fromJson(json, type);
|
||||
System.out.println("Successfully got SteamAppList from file (" + cacheFile.getAbsolutePath() + ")...");
|
||||
}
|
||||
|
||||
public LinkedHashMap<Number, String> getDlcMap(String appId) throws IOException{
|
||||
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 + "/")
|
||||
.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 + "/dlc/")
|
||||
.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0")
|
||||
.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 (NullPointerException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
Map<Integer, String> allDLCs = new HashMap<>(steamStoreDLCs);
|
||||
steamDbDLCs.forEach(allDLCs::putIfAbsent);
|
||||
return allDLCs.entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
|
||||
(oldValue, newValue) -> oldValue, LinkedHashMap::new));
|
||||
}
|
||||
}
|
@ -13,108 +13,156 @@
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import com.jfoenix.controls.*;
|
||||
package xyz.jeddunk.autocreamapi;
|
||||
|
||||
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.concurrent.Service;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.event.Event;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.stage.*;
|
||||
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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import xyz.jeddunk.autocreamapi.pojo.App;
|
||||
import xyz.jeddunk.autocreamapi.util.CreamApiConfig;
|
||||
import xyz.jeddunk.autocreamapi.util.CreamApiDllHandler;
|
||||
import xyz.jeddunk.autocreamapi.util.SteamAppsListCache;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Controller {
|
||||
public class Controller implements Initializable {
|
||||
|
||||
final Logger logger = LoggerFactory.getLogger(Controller.class);
|
||||
|
||||
private static final String GLYPH_FAILURE = "TIMES";
|
||||
private static final String GLYPH_SUCCESS = "CHECK";
|
||||
private static final Color COLOR_FAILURE = Color.web("#E53935");
|
||||
private static final Color COLOR_SUCCESS = Color.web("#43A047");
|
||||
private static final String REGEX = "(?<steamApiDll>steam_api(?:64)?.dll)$";
|
||||
public Label creamApiDllApplied;
|
||||
public Label creamApiConfigExists;
|
||||
public FontAwesomeIconView creamApiDllAppliedIcon;
|
||||
public FontAwesomeIconView creamApiConfigExistsIcon;
|
||||
|
||||
private CreamApiDllHandler handler = null;
|
||||
private final CreamApiConfig config = CreamApiConfig.getInstance();
|
||||
private final SteamAppsListCache cache = new SteamAppsListCache();
|
||||
private boolean is64Bit;
|
||||
private boolean isSameFile;
|
||||
|
||||
|
||||
@FXML
|
||||
public Label creamApiDllApplied;
|
||||
@FXML
|
||||
public Label creamApiConfigExists;
|
||||
@FXML
|
||||
public FontAwesomeIconView creamApiDllAppliedIcon;
|
||||
@FXML
|
||||
public FontAwesomeIconView creamApiConfigExistsIcon;
|
||||
@FXML
|
||||
public Label state_label;
|
||||
@FXML
|
||||
public TextField path_textfield;
|
||||
@FXML
|
||||
public TextField appId_textfield;
|
||||
@FXML
|
||||
public TextField game_name_textfield;
|
||||
@FXML
|
||||
public ComboBox<String> language_combobox;
|
||||
@FXML
|
||||
public TextArea dlc_textarea;
|
||||
@FXML
|
||||
public CheckBox extra_protection_checkbox;
|
||||
@FXML
|
||||
public CheckBox offline_checkbox;
|
||||
@FXML
|
||||
public CheckBox unlock_all_checkbox;
|
||||
@FXML
|
||||
public CheckBox steamdb_dlc_checkbox;
|
||||
@FXML
|
||||
public Button reset_button;
|
||||
@FXML
|
||||
public Button save_button;
|
||||
@FXML
|
||||
public Button getAppId_button;
|
||||
@FXML
|
||||
public Button path_button;
|
||||
@FXML
|
||||
public Button getDlcList_button;
|
||||
private String steamApiPathString;
|
||||
|
||||
{
|
||||
try {
|
||||
handler = CreamApiDllHandler.getInstance();
|
||||
} catch (IOException e) {
|
||||
} catch (FileNotFoundException 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);
|
||||
System.exit(2);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
steamdb_dlc_checkbox.setSelected(true);
|
||||
appId_textfield.textProperty().addListener(appIdChangesGameName());
|
||||
//retrieveDlcList_button.setDisable(true); // WIP
|
||||
game_name_textfield.setOnKeyReleased(event -> {
|
||||
KeyCode code = event.getCode();
|
||||
if (code.equals(KeyCode.ENTER)) {
|
||||
getAppId();
|
||||
}
|
||||
});
|
||||
language_combobox.setItems(FXCollections.observableArrayList(config.getLanguages()));
|
||||
language_combobox.setTooltip(new Tooltip());
|
||||
language_combobox.setEditable(false);
|
||||
new ComboBoxAutoComplete<>(language_combobox);
|
||||
dlc_textarea.setPromptText("List of DLC...\r0000 = DLC Name");
|
||||
generate_tooltips();
|
||||
fix_dlc_textarea_prompt_text();
|
||||
reset(true);
|
||||
state_label.setText("Ready.");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Tooltip steamdb_dlc_tooltip = new Tooltip("Additionally get DLC data from SteamDB.\n" +
|
||||
"Especially useful for DLC that is not listed on the Steam Store.\n" +
|
||||
"This sometimes doesn't work because SteamDB may block access for scrapers.");
|
||||
steamdb_dlc_checkbox.setTooltip(steamdb_dlc_tooltip);
|
||||
Tooltip.install(steamdb_dlc_checkbox, steamdb_dlc_tooltip);
|
||||
}
|
||||
|
||||
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());
|
||||
@ -126,8 +174,8 @@ public class Controller {
|
||||
}
|
||||
|
||||
private void emptyFields() {
|
||||
creamApiDllAppliedIcon.setGlyphName("TIMES");
|
||||
creamApiConfigExistsIcon.setGlyphName("TIMES");
|
||||
/*setIndicator(creamApiDllApplied, creamApiDllAppliedIcon, COLOR_FAILURE, GLYPH_FAILURE);
|
||||
setIndicator(creamApiConfigExists, creamApiConfigExistsIcon, COLOR_FAILURE, GLYPH_FAILURE);*/
|
||||
appId_textfield.setText("");
|
||||
dlc_textarea.setText("");
|
||||
game_name_textfield.setText("");
|
||||
@ -137,16 +185,6 @@ public class Controller {
|
||||
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;
|
||||
@ -177,10 +215,10 @@ public class Controller {
|
||||
state_label.setText("Successfully reset all fields!");
|
||||
}
|
||||
} catch (NoSuchElementException e) {
|
||||
System.err.println("Error reading cream_api.ini! " +
|
||||
logger.warn("Error reading cream_api.ini! " +
|
||||
"This can be ignored if setting up CreamAPI for the first time.");
|
||||
} catch (NullPointerException e) {
|
||||
System.err.println("Can't fill out fields, no configuration file set!");
|
||||
logger.warn("Can't fill out fields, no configuration file set!");
|
||||
if (!silent) {
|
||||
state_label.setText("Could not reset fields, no configuration file set!");
|
||||
}
|
||||
@ -189,8 +227,6 @@ public class Controller {
|
||||
}
|
||||
|
||||
private void updateIndicators() {
|
||||
Color colorSuccess = Color.web("#43A047");
|
||||
Color colorFailure = Color.web("#E53935");
|
||||
try {
|
||||
is64Bit = false;
|
||||
if (!steamApiPathString.isEmpty()) {
|
||||
@ -202,37 +238,169 @@ public class Controller {
|
||||
String md5 = DigestUtils.md5Hex(is);
|
||||
isSameFile = Objects.equals(md5, handler.getDllMd5(is64Bit));
|
||||
if (isSameFile) {
|
||||
creamApiDllApplied.setTextFill(colorSuccess);
|
||||
creamApiDllAppliedIcon.setFill(colorSuccess);
|
||||
creamApiDllAppliedIcon.setGlyphName("CHECK");
|
||||
setIndicator(creamApiDllApplied, creamApiDllAppliedIcon, COLOR_SUCCESS, GLYPH_SUCCESS);
|
||||
} else {
|
||||
creamApiDllApplied.setTextFill(colorFailure);
|
||||
creamApiDllAppliedIcon.setFill(colorFailure);
|
||||
creamApiDllAppliedIcon.setGlyphName("TIMES");
|
||||
setIndicator(creamApiDllApplied, creamApiDllAppliedIcon, COLOR_FAILURE, GLYPH_FAILURE);
|
||||
}
|
||||
Path configPath = Paths.get(config.getPath());
|
||||
if (Files.exists(configPath) && Files.size(configPath) > 0L) {
|
||||
creamApiConfigExists.setTextFill(colorSuccess);
|
||||
creamApiConfigExistsIcon.setFill(colorSuccess);
|
||||
creamApiConfigExistsIcon.setGlyphName("CHECK");
|
||||
setIndicator(creamApiConfigExists, creamApiConfigExistsIcon, COLOR_SUCCESS, GLYPH_SUCCESS);
|
||||
} else {
|
||||
creamApiConfigExists.setTextFill(colorFailure);
|
||||
creamApiConfigExistsIcon.setFill(colorFailure);
|
||||
creamApiConfigExistsIcon.setGlyphName("TIMES");
|
||||
setIndicator(creamApiConfigExists, creamApiConfigExistsIcon, COLOR_FAILURE, GLYPH_FAILURE);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error! Resetting visual indicators!");
|
||||
creamApiDllApplied.setTextFill(colorFailure);
|
||||
creamApiDllAppliedIcon.setFill(colorFailure);
|
||||
creamApiDllAppliedIcon.setGlyphName("TIMES");
|
||||
creamApiConfigExists.setTextFill(colorFailure);
|
||||
creamApiConfigExistsIcon.setFill(colorFailure);
|
||||
creamApiConfigExistsIcon.setGlyphName("TIMES");
|
||||
logger.warn("Resetting visual indicators!");
|
||||
setIndicator(creamApiDllApplied, creamApiDllAppliedIcon, COLOR_FAILURE, GLYPH_FAILURE);
|
||||
setIndicator(creamApiConfigExists, creamApiConfigExistsIcon, COLOR_FAILURE, GLYPH_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setIndicator(Label label, FontAwesomeIconView icon, Color color, String glyphName) {
|
||||
label.setTextFill(color);
|
||||
icon.setFill(color);
|
||||
icon.setGlyphName(glyphName);
|
||||
}
|
||||
|
||||
public void save() {
|
||||
saveService().start();
|
||||
}
|
||||
|
||||
public void getAppId() {
|
||||
final List<App> games = cache.findListOfGames(game_name_textfield.getText());
|
||||
if (games.isEmpty()) {
|
||||
logger.info("No game name was given, setting AppID to \"-1\"!");
|
||||
appId_textfield.setText("-1");
|
||||
} else if (games.size() == 1) {
|
||||
App game = games.get(0);
|
||||
game_name_textfield.setText(game.getName());
|
||||
appId_textfield.setText(String.valueOf(game.getAppId()));
|
||||
} else {
|
||||
logger.info("Multiple results found, opening search result window!");
|
||||
try {
|
||||
URL resource = ClassLoader.getSystemResource("xyz/jeddunk/autocreamapi/searchResultWindow.fxml");
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(resource);
|
||||
Parent root1 = fxmlLoader.load();
|
||||
|
||||
SearchResultWindowController c = fxmlLoader.getController();
|
||||
c.initMe(games);
|
||||
c.setParentController(this);
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.initModality(Modality.APPLICATION_MODAL);
|
||||
stage.setResizable(false);
|
||||
stage.setTitle("Choose game...");
|
||||
stage.setScene(new Scene(root1));
|
||||
stage.show();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void unlockAll_disableDlcTextArea() {
|
||||
dlc_textarea.setDisable(unlock_all_checkbox.isSelected());
|
||||
getDlcList_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() {
|
||||
getDlcListService().start();
|
||||
}
|
||||
|
||||
public void openFileChooser() {
|
||||
FileChooser chooser = new FileChooser();
|
||||
chooser.setTitle("Choose steam_api(64).dll...");
|
||||
FileChooser.ExtensionFilter filter =
|
||||
new FileChooser.ExtensionFilter("Steam API DLL",
|
||||
"steam_api.dll", "steam_api64.dll");
|
||||
chooser.getExtensionFilters().add(filter);
|
||||
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();
|
||||
} catch (NullPointerException e) {
|
||||
logger.warn("Could not set config file location! Did you cancel the file chooser?");
|
||||
}
|
||||
emptyFields();
|
||||
reset(true);
|
||||
logger.info("File chosen: " + steamApiPathString);
|
||||
logger.info("Ready.");
|
||||
state_label.setText("Ready.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if CreamAPI version of DLL is there, if not, rename original to steam_api(64)_o.dll and copy
|
||||
* CreamAPI DLL to the path. Also looks for alternative Steam DLL (which means it patches both 64 and 32 bit
|
||||
* DLLs at once if found)
|
||||
*
|
||||
* @throws IOException If file is missing or not accessible/modifiable.
|
||||
*/
|
||||
private void setUpCreamApi() throws IOException {
|
||||
logger.info("Setting up DLL...");
|
||||
Path path = Paths.get(steamApiPathString);
|
||||
copyDllFile(path, isSameFile);
|
||||
findAdditionalDll(path);
|
||||
logger.info("Set up DLL successfully!");
|
||||
}
|
||||
|
||||
private void findAdditionalDll(Path path) throws IOException {
|
||||
String aDllString = is64Bit ? "\\steam_api.dll" : "\\steam_api64.dll";
|
||||
Path dir = path.getParent();
|
||||
Path aDll = Paths.get(dir.toString() + aDllString);
|
||||
if (Files.exists(aDll)) {
|
||||
logger.info("Additional DLL found: (" + aDll.toString() + ")!");
|
||||
InputStream is = Files.newInputStream(aDll);
|
||||
String md5 = DigestUtils.md5Hex(is);
|
||||
boolean aIsSameFile = Objects.equals(md5, handler.getDllMd5(!is64Bit));
|
||||
copyDllFile(aDll, aIsSameFile);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyDllFile(Path path, boolean isSameFile) throws IOException {
|
||||
if (!isSameFile) {
|
||||
String pathOrigString = steamApiPathString;
|
||||
String replacement = is64Bit ? "steam_api64_o.dll" : "steam_api_o.dll";
|
||||
pathOrigString =
|
||||
pathOrigString
|
||||
.replaceFirst(REGEX, replacement);
|
||||
Path pathOrig = Paths.get(pathOrigString);
|
||||
if (!Files.exists(pathOrig)) {
|
||||
logger.info("Renaming " + path.toString() + " to " + replacement + "...");
|
||||
Files.move(path, pathOrig);
|
||||
} else {
|
||||
logger.info(pathOrigString + " already exists!");
|
||||
String pathBakString = steamApiPathString;
|
||||
pathBakString =
|
||||
pathBakString
|
||||
.replaceFirst(REGEX, is64Bit ? "steam_api64.dll.backup" : "steam_api.dll.backup");
|
||||
Path pathBak = Paths.get(pathBakString);
|
||||
Files.move(path, pathBak, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
logger.info("Copying CreamAPI DLL to " + path.toString() + " ...");
|
||||
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);
|
||||
getDlcList_button.setDisable(b);
|
||||
}
|
||||
|
||||
public void resetFromButton() {
|
||||
reset(false);
|
||||
}
|
||||
|
||||
private Service<Void> saveService() {
|
||||
Service<Void> s = new Service<Void>() {
|
||||
@Override
|
||||
protected Task<Void> createTask() {
|
||||
@ -252,7 +420,7 @@ public class Controller {
|
||||
e.printStackTrace();
|
||||
cancel();
|
||||
} catch (NullPointerException e) {
|
||||
System.err.println("No configuration file set!");
|
||||
logger.warn("No configuration file set!");
|
||||
cancel();
|
||||
}
|
||||
updateIndicators();
|
||||
@ -273,51 +441,21 @@ public class Controller {
|
||||
setDisableAllButtons(false);
|
||||
state_label.setText("Could not save configuration file!");
|
||||
});
|
||||
s.start();
|
||||
return s;
|
||||
}
|
||||
|
||||
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() {
|
||||
private Service<Void> getDlcListService() {
|
||||
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();
|
||||
}
|
||||
Map<Integer, String> collect =
|
||||
cache.getDlcMap(appId_textfield.getText(), steamdb_dlc_checkbox.isSelected());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
collect.forEach((k, v) -> sb.append(k).append("=").append(v).append("\n"));
|
||||
dlc_textarea.setText(sb.toString());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@ -335,88 +473,64 @@ public class Controller {
|
||||
setDisableAllButtons(false);
|
||||
state_label.setText("Could not get list of DLCs!");
|
||||
});
|
||||
s.start();
|
||||
return s;
|
||||
}
|
||||
|
||||
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");
|
||||
} catch (ConfigurationException | IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NullPointerException e) {
|
||||
System.err.println("Could not set config file location! Did you cancel the file chooser?");
|
||||
static class ComboBoxAutoComplete<T> {
|
||||
|
||||
private ComboBox<T> cmb;
|
||||
String filter = "";
|
||||
private ObservableList<T> originalItems;
|
||||
|
||||
public ComboBoxAutoComplete(ComboBox<T> cmb) {
|
||||
this.cmb = cmb;
|
||||
originalItems = FXCollections.observableArrayList(cmb.getItems());
|
||||
cmb.setTooltip(new Tooltip());
|
||||
cmb.setOnKeyPressed(this::handleOnKeyPressed);
|
||||
cmb.setOnHidden(this::handleOnHiding);
|
||||
}
|
||||
path_textfield.setText(file.getParent());
|
||||
steamApiPathString = file.getAbsolutePath();
|
||||
emptyFields();
|
||||
reset(true);
|
||||
state_label.setText("Ready.");
|
||||
}
|
||||
|
||||
/**
|
||||
* check if creamapi version of dll is there, if not, rename original to steam_api(64)_o.dll and copy
|
||||
* creamapi dll to the path. also looks for alternative steam dll (which means it patches both 64 and 32 bit
|
||||
* dlls at once if found)
|
||||
*
|
||||
* @throws IOException If file is missing or not accessible/modifiable.
|
||||
*/
|
||||
private void setUpCreamApi() throws IOException {
|
||||
Path path = Paths.get(steamApiPathString);
|
||||
copyDllFile(path, isSameFile);
|
||||
findAdditionalDll(path);
|
||||
}
|
||||
public void handleOnKeyPressed(KeyEvent e) {
|
||||
SingleSelectionModel<T> sm = this.cmb.getSelectionModel();
|
||||
ObservableList<T> filteredList = FXCollections.observableArrayList();
|
||||
KeyCode code = e.getCode();
|
||||
|
||||
private void findAdditionalDll(Path path) throws IOException {
|
||||
String secondDllString = is64Bit ? "\\steam_api.dll" : "\\steam_api64.dll";
|
||||
Path dir = path.getParent();
|
||||
Path secondDll = Paths.get(dir.toString() + secondDllString);
|
||||
if (Files.exists(secondDll)) {
|
||||
System.out.println("Alternative DLL found!");
|
||||
InputStream is = Files.newInputStream(secondDll);
|
||||
String md5 = DigestUtils.md5Hex(is);
|
||||
boolean isSameFile1 = Objects.equals(md5, handler.getDllMd5(!is64Bit));
|
||||
copyDllFile(secondDll, isSameFile1);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyDllFile(Path path, boolean isSameFile) throws IOException {
|
||||
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);
|
||||
} else {
|
||||
String pathBakString = steamApiPathString;
|
||||
pathBakString =
|
||||
pathBakString
|
||||
.replaceFirst(REGEX, is64Bit ? "steam_api64.dll.backup" : "steam_api.dll.backup");
|
||||
Path pathBak = Paths.get(pathBakString);
|
||||
Files.move(path, pathBak, StandardCopyOption.REPLACE_EXISTING);
|
||||
if (code.isLetterKey()) {
|
||||
filter += e.getText();
|
||||
}
|
||||
//Files.deleteIfExists(path);
|
||||
Files.copy(handler.getDllPath(is64Bit), path);
|
||||
if (code == KeyCode.BACK_SPACE && filter.length() > 0) {
|
||||
filter = filter.substring(0, filter.length() - 1);
|
||||
cmb.getItems().setAll(originalItems);
|
||||
}
|
||||
if (code == KeyCode.ESCAPE) {
|
||||
filter = "";
|
||||
}
|
||||
if (filter.length() == 0) {
|
||||
filteredList = originalItems;
|
||||
cmb.getTooltip().hide();
|
||||
} else {
|
||||
Stream<T> items = cmb.getItems().stream();
|
||||
String txtUsr = filter.toLowerCase();
|
||||
items.filter(el -> el.toString().toLowerCase().contains(txtUsr)).forEach(filteredList::add);
|
||||
cmb.getTooltip().setText(txtUsr);
|
||||
Window stage = cmb.getScene().getWindow();
|
||||
double posX = stage.getX() + cmb.getBoundsInParent().getMinX();
|
||||
double posY = stage.getY() + cmb.getBoundsInParent().getMinY();
|
||||
cmb.getTooltip().show(stage, posX, posY);
|
||||
cmb.show();
|
||||
}
|
||||
cmb.getItems().setAll(filteredList);
|
||||
sm.selectFirst();
|
||||
}
|
||||
|
||||
public void handleOnHiding(Event e) {
|
||||
filter = "";
|
||||
cmb.getTooltip().hide();
|
||||
T s = cmb.getSelectionModel().getSelectedItem();
|
||||
cmb.getItems().setAll(originalItems);
|
||||
cmb.getSelectionModel().select(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@ -13,6 +13,8 @@
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package xyz.jeddunk.autocreamapi;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
@ -21,13 +23,18 @@ import javafx.stage.Stage;
|
||||
|
||||
public class Main extends Application {
|
||||
|
||||
private static final int MIN_WIDTH = 905;
|
||||
private static final int MIN_HEIGHT = 450;
|
||||
private static final int PREF_WIDTH = 1200;
|
||||
private static final int PREF_HEIGHT = 600;
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
Parent root = FXMLLoader.load(ClassLoader.getSystemResource("mainWindow.fxml"));
|
||||
Parent root = FXMLLoader.load(ClassLoader.getSystemResource("xyz/jeddunk/autocreamapi/mainWindow.fxml"));
|
||||
primaryStage.setTitle("Auto CreamAPI");
|
||||
primaryStage.setMinWidth(655 + 25);
|
||||
primaryStage.setMinHeight(400 + 50);
|
||||
primaryStage.setScene(new Scene(root, 1200, 600));
|
||||
primaryStage.setMinWidth(MIN_WIDTH + 25);
|
||||
primaryStage.setMinHeight(MIN_HEIGHT + 50);
|
||||
primaryStage.setScene(new Scene(root, PREF_WIDTH, PREF_HEIGHT));
|
||||
primaryStage.show();
|
||||
}
|
||||
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Auto-CreamAPI
|
||||
* Copyright (C) 2020 Jeddunk
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package xyz.jeddunk.autocreamapi;import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
|
||||
import javafx.scene.input.MouseButton;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
import javafx.stage.Stage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import xyz.jeddunk.autocreamapi.pojo.App;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static java.text.MessageFormat.format;
|
||||
|
||||
public class SearchResultWindowController implements Initializable {
|
||||
|
||||
final Logger logger = LoggerFactory.getLogger(SearchResultWindowController.class);
|
||||
|
||||
@FXML
|
||||
public Button okButton;
|
||||
@FXML
|
||||
public Button cancelButton;
|
||||
@FXML
|
||||
public TreeTableView<App> gameTable;
|
||||
@FXML
|
||||
public TreeTableColumn<App, Integer> appIdCol;
|
||||
@FXML
|
||||
public TreeTableColumn<App, String> nameCol;
|
||||
|
||||
public Controller parent;
|
||||
|
||||
private long lastTime;
|
||||
private boolean isDblClicked;
|
||||
|
||||
public SearchResultWindowController() {
|
||||
}
|
||||
|
||||
@FXML
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
}
|
||||
|
||||
public void initMe(List<App> games) {
|
||||
TreeItem<App> root = new TreeItem<>();
|
||||
appIdCol.setCellValueFactory(new TreeItemPropertyValueFactory<>("appId"));
|
||||
nameCol.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));
|
||||
games.forEach(game -> root.getChildren().add(new TreeItem<>(game)));
|
||||
gameTable.setRoot(root);
|
||||
}
|
||||
|
||||
public void confirm() {
|
||||
App app = gameTable.getSelectionModel().getSelectedItem().getValue();
|
||||
logger.info(format("Game selected: {0} ({1})!", app.getName(), app.getAppId()));
|
||||
parent.game_name_textfield.setText(app.getName());
|
||||
parent.appId_textfield.setText(String.valueOf(app.getAppId()));
|
||||
Stage current = (Stage) okButton.getScene().getWindow();
|
||||
current.close();
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
logger.info("Closing window without setting game!");
|
||||
/*parent.game_name_textfield.setText("");
|
||||
parent.appId_textfield.setText("-1");*/
|
||||
Stage current = (Stage) cancelButton.getScene().getWindow();
|
||||
current.close();
|
||||
}
|
||||
|
||||
public void setParentController(Controller controller) {
|
||||
parent = controller;
|
||||
}
|
||||
|
||||
public void doubleclickConfirm(MouseEvent mouseEvent) {
|
||||
if (mouseEvent.getButton() == MouseButton.PRIMARY) {
|
||||
long diff;
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (lastTime != 0 && currentTime != 0) {
|
||||
diff = currentTime - lastTime;
|
||||
isDblClicked = (diff <= 215);
|
||||
}
|
||||
lastTime = currentTime;
|
||||
if (isDblClicked) {
|
||||
/*App app = gameTable.getSelectionModel().getSelectedItem().getValue();
|
||||
parent.game_name_textfield.setText(app.getName());
|
||||
parent.appId_textfield.setText(String.valueOf(app.getAppId()));
|
||||
Stage current = (Stage) gameTable.getScene().getWindow();
|
||||
current.close();*/
|
||||
confirm();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package pojo;
|
||||
package xyz.jeddunk.autocreamapi.pojo;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
@ -13,7 +13,7 @@
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package pojo;
|
||||
package xyz.jeddunk.autocreamapi.pojo;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
@ -13,18 +13,24 @@
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package util;
|
||||
package xyz.jeddunk.autocreamapi.util;
|
||||
|
||||
import org.apache.commons.configuration2.*;
|
||||
import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
|
||||
import org.apache.commons.configuration2.builder.fluent.Configurations;
|
||||
import org.apache.commons.configuration2.ex.ConfigurationException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
|
||||
import static java.text.MessageFormat.format;
|
||||
|
||||
public class CreamApiConfig {
|
||||
|
||||
final Logger logger = LoggerFactory.getLogger(CreamApiConfig.class);
|
||||
|
||||
private static CreamApiConfig configInstance;
|
||||
private static final Configurations CONFIGS = new Configurations();
|
||||
|
||||
@ -48,25 +54,50 @@ public class CreamApiConfig {
|
||||
config = CONFIGS.ini(path);
|
||||
config.setCommentLeadingCharsUsedInInput(";");
|
||||
} catch (ConfigurationException e) {
|
||||
System.err.println("No config file found in default location!");
|
||||
logger.warn("No config file found!");
|
||||
//e.printStackTrace();
|
||||
}
|
||||
|
||||
File langFile = new File("languages.txt");
|
||||
try {
|
||||
BufferedReader fIn = new BufferedReader(new FileReader(langFile));
|
||||
fIn.lines().filter(line -> !line.isEmpty() && !line.startsWith("#")).forEach(languages::add);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// https://partner.steamgames.com/doc/store/localization#supported_languages
|
||||
languages.addAll(Arrays.asList(
|
||||
"english",
|
||||
"latam",
|
||||
"brazilian",
|
||||
"german",
|
||||
"french",
|
||||
"italian",
|
||||
"portuguese",
|
||||
"spanish",
|
||||
"russian",
|
||||
"schinese",
|
||||
"tchinese",
|
||||
"japanese",
|
||||
"koreana",
|
||||
"arabic",
|
||||
"bulgarian",
|
||||
"czech",
|
||||
"danish",
|
||||
"dutch",
|
||||
"finnish",
|
||||
"greek",
|
||||
"hungarian",
|
||||
"norwegian",
|
||||
"polish",
|
||||
"romanian",
|
||||
"swedish",
|
||||
"thai",
|
||||
"turkish",
|
||||
"ukrainian",
|
||||
"vietnamese"
|
||||
));
|
||||
|
||||
try {
|
||||
read();
|
||||
} catch (NoSuchElementException e) {
|
||||
System.err.println("Error reading cream_api.ini! " +
|
||||
logger.warn("Error reading cream_api.ini! " +
|
||||
"This can be ignored if setting up CreamAPI for the first time.");
|
||||
} catch (NullPointerException e) {
|
||||
System.err.println("Can't fill out fields, no configuration file set!");
|
||||
logger.warn("Can't fill out fields, no configuration file set!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +109,7 @@ public class CreamApiConfig {
|
||||
}
|
||||
|
||||
public void read() throws NullPointerException, NoSuchElementException {
|
||||
logger.info("Reading config file...");
|
||||
appId = config.getInt("steam.appid");
|
||||
language = config.getString("steam.language");
|
||||
if (language == null) {
|
||||
@ -88,9 +120,11 @@ public class CreamApiConfig {
|
||||
forceOffline = config.getBoolean("steam.forceoffline");
|
||||
final SubnodeConfiguration dlc_section = config.getSection("dlc");
|
||||
dlc_section.getKeys().forEachRemaining(k -> dlc.put(Integer.parseInt(k), dlc_section.getString(k)));
|
||||
logger.info("Successfully read config file!");
|
||||
}
|
||||
|
||||
public void sync() throws ConfigurationException {
|
||||
logger.info("Saving config file...");
|
||||
FileBasedConfigurationBuilder<INIConfiguration> builder = CONFIGS.iniBuilder(path);
|
||||
config = builder.getConfiguration();
|
||||
config.setCommentLeadingCharsUsedInInput(";");
|
||||
@ -111,6 +145,7 @@ public class CreamApiConfig {
|
||||
config.setProperty("steam_misc.disableuserinterface", false);
|
||||
|
||||
builder.save();
|
||||
logger.info("Saved successfully!");
|
||||
}
|
||||
|
||||
// DLC list parsing
|
||||
@ -126,7 +161,7 @@ public class CreamApiConfig {
|
||||
Arrays.stream(str.split("\\R+")).forEach(line -> {
|
||||
final String[] split = line.split("\\s*=\\s*", 2);
|
||||
if (split.length == 2) dlc.put(Integer.parseInt(split[0]), split[1]);
|
||||
else System.err.println(MessageFormat.format("Error while splitting line: \"{0}\"", line));
|
||||
else logger.error(format("Error while splitting line: \"{0}\"", line));
|
||||
});
|
||||
}
|
||||
|
||||
@ -179,9 +214,9 @@ public class CreamApiConfig {
|
||||
public void setConfig(String path) throws ConfigurationException, IOException {
|
||||
File file = new File(path);
|
||||
if (file.createNewFile()) {
|
||||
System.out.println("New config file created!");
|
||||
logger.info("New config file created!");
|
||||
} else {
|
||||
System.out.println("Using existing config file!");
|
||||
logger.info("Using existing config file!");
|
||||
}
|
||||
this.config = CONFIGS.ini(path);
|
||||
this.config.setCommentLeadingCharsUsedInInput(";");
|
@ -13,7 +13,7 @@
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package util;
|
||||
package xyz.jeddunk.autocreamapi.util;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
@ -31,10 +31,8 @@ public class CreamApiDllHandler {
|
||||
private final String steamApi64DllMd5;
|
||||
|
||||
private CreamApiDllHandler() throws IOException {
|
||||
String steamApiDllMd5 = DigestUtils.md5Hex(Files.newInputStream(steamApiDllPath));
|
||||
String steamApi64DllMd5 = DigestUtils.md5Hex(Files.newInputStream(steamApi64DllPath));
|
||||
this.steamApiDllMd5 = steamApiDllMd5;
|
||||
this.steamApi64DllMd5 = steamApi64DllMd5;
|
||||
this.steamApiDllMd5 = DigestUtils.md5Hex(Files.newInputStream(steamApiDllPath));
|
||||
this.steamApi64DllMd5 = DigestUtils.md5Hex(Files.newInputStream(steamApi64DllPath));
|
||||
}
|
||||
|
||||
public static synchronized CreamApiDllHandler getInstance() throws IOException {
|
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Auto-CreamAPI
|
||||
* Copyright (C) 2020 Jeddunk
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package xyz.jeddunk.autocreamapi.util;
|
||||
|
||||
import com.gargoylesoftware.htmlunit.BrowserVersion;
|
||||
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
|
||||
import com.gargoylesoftware.htmlunit.WebClient;
|
||||
import com.gargoylesoftware.htmlunit.html.HtmlPage;
|
||||
import com.gargoylesoftware.htmlunit.util.Cookie;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import kong.unirest.HttpResponse;
|
||||
import kong.unirest.Unirest;
|
||||
import me.xdrop.fuzzywuzzy.FuzzySearch;
|
||||
import me.xdrop.fuzzywuzzy.model.BoundExtractedResult;
|
||||
import org.jsoup.HttpStatusException;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import xyz.jeddunk.autocreamapi.pojo.App;
|
||||
import xyz.jeddunk.autocreamapi.pojo.SteamAppsList;
|
||||
import xyz.jeddunk.autocreamapi.util.env.MainEnv;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URL;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SteamAppsListCache {
|
||||
|
||||
final Logger logger = LoggerFactory.getLogger(SteamAppsListCache.class);
|
||||
|
||||
private SteamAppsList list = new SteamAppsList();
|
||||
private final File cacheFile = new File("steamapps.json");
|
||||
private MainEnv env;
|
||||
private String cfduid = "";
|
||||
|
||||
public SteamAppsListCache() {
|
||||
try {
|
||||
Class<?> envDefault = Class.forName("xyz.jeddunk.autocreamapi.util.env.Default");
|
||||
env = (MainEnv) envDefault.newInstance();
|
||||
// System.out.println(env.getKey());
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.debug("Default environment missing, using main environemnt...");
|
||||
env = new MainEnv();
|
||||
} catch (IllegalAccessException | InstantiationException e) {
|
||||
// Only thrown by newInstance()
|
||||
e.printStackTrace();
|
||||
}
|
||||
//boolean fileFound = true;
|
||||
try {
|
||||
getListFromFile();
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.info("File does not exist, trying to create steamapps.json for the first time...");
|
||||
//fileFound = false;
|
||||
sync();
|
||||
} catch (JsonSyntaxException e) {
|
||||
logger.warn("File seems to be corrupt, trying to recreate steamapps.json...");
|
||||
//fileFound = false;
|
||||
sync();
|
||||
}
|
||||
if (Instant.now().isAfter(list.getTimestamp().plus(Duration.ofDays(3)))) {
|
||||
logger.info("List in file is not recent!");
|
||||
sync();
|
||||
}
|
||||
}
|
||||
|
||||
private void sync() {
|
||||
getListFromApi();
|
||||
try {
|
||||
saveListToFile();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public App getGame(int appId) {
|
||||
return list.getSteamAppsList().stream().filter(app -> app.getAppId() == appId).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public App getGame(String name) {
|
||||
return list.getSteamAppsList().stream()
|
||||
.filter(app -> app.getName().equalsIgnoreCase(name)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public List<App> findListOfGames(String name) {
|
||||
List<BoundExtractedResult<App>> match = FuzzySearch.extractSorted(name, list.getSteamAppsList(), app ->
|
||||
app.getName().toLowerCase().replaceAll("[^a-zA-Z0-9\\s+]", ""), 80);
|
||||
List<App> collect = match.stream().map(BoundExtractedResult::getReferent).collect(Collectors.toList());
|
||||
for (App app : collect) {
|
||||
if (app.getName().replaceAll("[^a-zA-Z0-9\\s+]", "")
|
||||
.equalsIgnoreCase(name.replaceAll("[^a-zA-Z0-9\\s+]", ""))) {
|
||||
collect = new ArrayList<>();
|
||||
collect.add(app);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return collect;
|
||||
}
|
||||
|
||||
private void getListFromApi() {
|
||||
logger.info("Trying to get SteamAppList from API...");
|
||||
List<App> apps = getApps();
|
||||
list.setTimestamp(Instant.now());
|
||||
list.setSteamAppsList(apps);
|
||||
}
|
||||
|
||||
private List<App> getApps() {
|
||||
HttpResponse<String> httpResponse =
|
||||
Unirest.get("https://api.steampowered.com/IStoreService/GetAppList/v1/" +
|
||||
"?key=" + env.getKey() + "&include_games=1&max_results=50000").asString();
|
||||
return new Gson()
|
||||
.fromJson(httpResponse.getBody(), App.Rezponze.Download.class)
|
||||
.getResponse().getApps();
|
||||
}
|
||||
|
||||
private void saveListToFile() throws IOException {
|
||||
logger.info("Trying to save SteamAppList to file \"" + cacheFile.getAbsolutePath() + "\"...");
|
||||
Gson gson = new Gson();
|
||||
String jsonString = gson.toJson(list);
|
||||
BufferedWriter fOut = new BufferedWriter(new FileWriter(cacheFile));
|
||||
fOut.write(jsonString);
|
||||
fOut.close();
|
||||
logger.info("Successfully saved SteamAppList to file \"" + cacheFile.getAbsolutePath() + "\"...");
|
||||
}
|
||||
|
||||
private void getListFromFile() throws FileNotFoundException, JsonSyntaxException {
|
||||
logger.info("Trying to get SteamAppList from file \"" + cacheFile.getAbsolutePath() + "\"...");
|
||||
BufferedReader fIn = new BufferedReader(new FileReader(cacheFile));
|
||||
String json = fIn.lines().collect(Collectors.joining());
|
||||
final Type type = new TypeToken<SteamAppsList>() {
|
||||
}.getType();
|
||||
Gson gson = new Gson();
|
||||
list = gson.fromJson(json, type);
|
||||
logger.info("Successfully got SteamAppList from file \"" + cacheFile.getAbsolutePath() + "\"...");
|
||||
}
|
||||
|
||||
public Map<Integer, String> getDlcMap(String appId, boolean use_steamdb) {
|
||||
logger.info("Getting list of DLC for AppID: " + appId + "...");
|
||||
Map<Integer, String> steamStoreDLCs = new HashMap<>();
|
||||
Map<Integer, String> steamDbDLCs = new HashMap<>();
|
||||
|
||||
// Steam Store
|
||||
try {
|
||||
logger.info("Trying to get DLC from Steam store page...");
|
||||
Document steamDoc = Jsoup
|
||||
.connect("https://store.steampowered.com/app/" + appId + "/")
|
||||
.cookie("birthtime", "470703601")
|
||||
.cookie("wants_mature_content", "1")
|
||||
.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);
|
||||
}
|
||||
logger.info("Got DLC from Steam store page successfully.");
|
||||
} catch (HttpStatusException e) {
|
||||
logger.error(e.getUrl());
|
||||
if (e.getStatusCode() == 404) {
|
||||
logger.error("App ID empty or not found! (HTTP Status Code: 404)");
|
||||
} else {
|
||||
logger.error("Error occurred while trying to get list of DLCs " +
|
||||
"(HTTP Status Code: " + e.getStatusCode() + ")");
|
||||
}
|
||||
} catch (NullPointerException | IOException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// SteamDB
|
||||
if (use_steamdb) {
|
||||
|
||||
logger.info("Trying to get DLC from SteamDB...");
|
||||
if (cfduid.equals("")) {
|
||||
logger.info("Missing CF cookie, trying to get it...");
|
||||
WebClient client = new WebClient(BrowserVersion.CHROME);
|
||||
|
||||
client.getOptions().setCssEnabled(false);
|
||||
client.getOptions().setJavaScriptEnabled(false);
|
||||
client.getOptions().setThrowExceptionOnFailingStatusCode(false);
|
||||
client.getOptions().setRedirectEnabled(true);
|
||||
client.getCache().setMaxSize(0);
|
||||
/*client.waitForBackgroundJavaScript(10000);
|
||||
client.setJavaScriptTimeout(10000);
|
||||
client.waitForBackgroundJavaScriptStartingBefore(10000);*/
|
||||
|
||||
try {
|
||||
|
||||
String urlString = "https://steamdb.info/";
|
||||
|
||||
HtmlPage page = client.getPage(urlString);
|
||||
//noinspection SynchronizationOnLocalVariableOrMethodParameter
|
||||
synchronized (page) {
|
||||
page.wait(8000);
|
||||
}
|
||||
//Print cookies for test purposes. Comment out in production.
|
||||
URL url = new URL(urlString);
|
||||
for (Cookie c : client.getCookies(url)) {
|
||||
//System.out.println(c.getName() +"="+c.getValue());
|
||||
if (c.getName().equals("__cfduid")) {
|
||||
cfduid = c.getValue();
|
||||
logger.info("Got CF cookie successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
//This prints the content after bypassing Cloudflare.
|
||||
// System.out.println(client.getPage(url).getWebResponse().getContentAsString());
|
||||
} catch (FailingHttpStatusCodeException | IOException | InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
logger.error("Could not get CF cookie, skipping SteamDB DLC list...");
|
||||
}
|
||||
}
|
||||
|
||||
if ((!(cfduid.equals(""))) && (!(cfduid.equals("N/A")))) {
|
||||
try {
|
||||
Document steamDbDoc = Jsoup
|
||||
.connect("https://steamdb.info/app/" + appId + "/dlc/")
|
||||
.cookie("__cfduid", cfduid)
|
||||
.userAgent(BrowserVersion.CHROME.getUserAgent())
|
||||
.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);
|
||||
}
|
||||
logger.info("Got DLC from SteamDB successfully.");
|
||||
} catch (HttpStatusException e) {
|
||||
logger.error(e.getUrl());
|
||||
if (e.getStatusCode() == 404) {
|
||||
logger.error("App ID empty or not found! (HTTP Status Code: 404)");
|
||||
} else {
|
||||
logger.error("Error occurred while trying to get list of DLCs " +
|
||||
"(HTTP Status Code: " + e.getStatusCode() + ")");
|
||||
}
|
||||
} catch (NullPointerException | IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Merging both DLC lists...");
|
||||
Map<Integer, String> allDLCs = new HashMap<>(steamStoreDLCs);
|
||||
steamDbDLCs.forEach(allDLCs::putIfAbsent);
|
||||
logger.info("DLC list is done!");
|
||||
return allDLCs.entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByKey())
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
|
||||
(oldValue, newValue) -> oldValue, LinkedHashMap::new));
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package util.env;
|
||||
package xyz.jeddunk.autocreamapi.util.env;
|
||||
|
||||
public class MainEnv {
|
||||
String key = "";
|
@ -1 +1 @@
|
||||
Main-Class: Main
|
||||
Main-Class: xyz.jeddunk.autocreamapi.Main
|
||||
|
50
src/main/resources/logback.xml
Normal file
50
src/main/resources/logback.xml
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Auto-CreamAPI
|
||||
~ Copyright (C) 2020 Jeddunk
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
~ License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
~ version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
~ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along with this program. If not, see
|
||||
~ <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<configuration>
|
||||
|
||||
<property name="PATTERN" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} - %msg%n"/>
|
||||
|
||||
<!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
|
||||
the key "bySecond" into the logger context. This value will be
|
||||
available to all subsequent configuration elements. -->
|
||||
<timestamp key="bySecond" datePattern="yyyy'_'MM'_'dd'-'HH'_'mm'_'ss"/>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!--withJansi>true</withJansi-->
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<pattern>${PATTERN}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||
<!-- use the previously created timestamp to create a uniquely
|
||||
named log file -->
|
||||
<file>autocreamapi_${bySecond}.log</file>
|
||||
<encoder>
|
||||
<pattern>${PATTERN}</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
|
||||
<logger name="com.base22" level="TRACE"/>
|
||||
|
||||
|
||||
<root level="debug">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="FILE" />
|
||||
</root>
|
||||
</configuration>
|
@ -1,122 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXCheckBox?>
|
||||
<?import com.jfoenix.controls.JFXComboBox?>
|
||||
<?import com.jfoenix.controls.JFXTextArea?>
|
||||
<?import com.jfoenix.controls.JFXTextField?>
|
||||
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<!--
|
||||
~ Auto-CreamAPI
|
||||
~ Copyright (C) 2020 Jeddunk
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
~ License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
~ version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
~ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along with this program. If not, see
|
||||
~ <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<BorderPane prefHeight="361.0" prefWidth="693.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
|
||||
<center>
|
||||
<GridPane hgap="10.0" minHeight="360.0" minWidth="655.0" vgap="10.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="-Infinity" prefWidth="375.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="120.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="120.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<JFXTextField fx:id="path_textfield" promptText="Path to game's steam_api(64).dll..." GridPane.columnSpan="2" />
|
||||
<JFXButton fx:id="path_button" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" onAction="#openFileChooser" ripplerFill="BLACK" style="-fx-background-color: #ddd;" GridPane.columnIndex="2">
|
||||
<graphic>
|
||||
<FontAwesomeIconView glyphName="FOLDER_OPEN" glyphSize="24" />
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXTextField fx:id="game_name_textfield" promptText="Game..." GridPane.rowIndex="1" />
|
||||
<JFXButton fx:id="getAppId_button" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" onAction="#getAppId" ripplerFill="BLACK" style="-fx-background-color: #ddd;" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<graphic>
|
||||
<FontAwesomeIconView glyphName="SEARCH" glyphSize="24" />
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXTextField fx:id="appId_textfield" prefWidth="299.0" promptText="Steam AppID..." GridPane.columnIndex="2" GridPane.rowIndex="1" />
|
||||
<JFXComboBox fx:id="language_combobox" editable="true" promptText="Language" GridPane.columnSpan="2147483647" GridPane.rowIndex="2" />
|
||||
<JFXCheckBox fx:id="offline_checkbox" text="Force offline mode" GridPane.columnSpan="2147483647" GridPane.rowIndex="3" />
|
||||
<JFXCheckBox fx:id="extra_protection_checkbox" text="Try to bypass game-specific protection" GridPane.columnSpan="2147483647" GridPane.rowIndex="4" />
|
||||
<JFXCheckBox fx:id="unlock_all_checkbox" onAction="#unlockAll_disableDlcTextArea" text="Unlock all DLC (if possible)" GridPane.columnSpan="2147483647" GridPane.rowIndex="5" />
|
||||
<JFXTextArea fx:id="dlc_textarea" promptText="List of DLC..." GridPane.columnSpan="2147483647" GridPane.rowIndex="6" />
|
||||
<JFXButton fx:id="retrieveDlcList_button" maxHeight="1.7976931348623157E308" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onAction="#getDlcList" ripplerFill="BLACK" style="-fx-background-color: #ddd;" text="Get DLCs for AppID" GridPane.rowIndex="7" />
|
||||
<JFXButton fx:id="save_button" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" onAction="#save" ripplerFill="BLACK" style="-fx-background-color: #ddd;" text="Save" GridPane.columnIndex="1" GridPane.rowIndex="7" />
|
||||
<JFXButton fx:id="reset_button" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" onAction="#resetFromButton" ripplerFill="BLACK" style="-fx-background-color: #ddd;" text="Reset" GridPane.columnIndex="2" GridPane.rowIndex="7" />
|
||||
<BorderPane.margin>
|
||||
<Insets />
|
||||
</BorderPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</padding>
|
||||
</GridPane>
|
||||
</center>
|
||||
<bottom>
|
||||
<Label fx:id="state_label" maxWidth="1.7976931348623157E308" minHeight="25.0" minWidth="-Infinity" style="-fx-background-color: #ddd; -fx-border-color: #aaa;" text="Ready." textFill="#555555" BorderPane.alignment="CENTER">
|
||||
<BorderPane.margin>
|
||||
<Insets />
|
||||
</BorderPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</padding></Label>
|
||||
</bottom>
|
||||
<right>
|
||||
<GridPane maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="250.0"
|
||||
BorderPane.alignment="CENTER">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
|
||||
</rowConstraints>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
||||
</padding>
|
||||
<Label maxHeight="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity"
|
||||
text="CreamAPI DLL applied" fx:id="creamApiDllApplied">
|
||||
<font>
|
||||
<Font size="14.0"/>
|
||||
</font>
|
||||
<graphic>
|
||||
<FontAwesomeIconView fx:id="creamApiDllAppliedIcon" glyphName="TIMES" size="20"/>
|
||||
</graphic>
|
||||
</Label>
|
||||
<Label layoutX="20.0" layoutY="20.0" maxHeight="1.7976931348623157E308" minHeight="-Infinity"
|
||||
minWidth="-Infinity" text="CreamAPI configuration file exists" GridPane.rowIndex="1"
|
||||
fx:id="creamApiConfigExists">
|
||||
<font>
|
||||
<Font size="14.0"/>
|
||||
</font>
|
||||
<graphic>
|
||||
<FontAwesomeIconView fx:id="creamApiConfigExistsIcon" glyphName="TIMES" size="20"/>
|
||||
</graphic>
|
||||
</Label>
|
||||
</GridPane>
|
||||
</right>
|
||||
</BorderPane>
|
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
144
src/main/resources/xyz/jeddunk/autocreamapi/mainWindow.fxml
Normal file
144
src/main/resources/xyz/jeddunk/autocreamapi/mainWindow.fxml
Normal file
@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXCheckBox?>
|
||||
<?import com.jfoenix.controls.JFXComboBox?>
|
||||
<?import com.jfoenix.controls.JFXTextArea?>
|
||||
<?import com.jfoenix.controls.JFXTextField?>
|
||||
<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView?>
|
||||
<?import java.net.URL?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TitledPane?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<!--
|
||||
~ Auto-CreamAPI
|
||||
~ Copyright (C) 2020 Jeddunk
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
~ License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
~ version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
~ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along with this program. If not, see
|
||||
~ <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<BorderPane prefHeight="450.0" prefWidth="705.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="xyz.jeddunk.autocreamapi.Controller">
|
||||
<center>
|
||||
<GridPane hgap="10.0" minHeight="410.0" minWidth="655.0" vgap="10.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="-Infinity" prefWidth="375.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="120.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="120.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="-Infinity" prefHeight="60.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</padding>
|
||||
<TitledPane animated="false" collapsible="false" maxHeight="1.7976931348623157E308" styleClass="dlcSettings"
|
||||
text="DLC Settings" GridPane.columnSpan="2147483647" GridPane.rowIndex="5">
|
||||
<GridPane hgap="10.0" maxHeight="1.7976931348623157E308" vgap="10.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0"/>
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints/>
|
||||
<RowConstraints/>
|
||||
<RowConstraints maxHeight="1.7976931348623157E308"/>
|
||||
</rowConstraints>
|
||||
<JFXCheckBox fx:id="unlock_all_checkbox" onAction="#unlockAll_disableDlcTextArea"
|
||||
text="Unlock all DLC (if possible)" GridPane.columnSpan="2147483647"/>
|
||||
<JFXTextArea fx:id="dlc_textarea" maxHeight="1.7976931348623157E308" prefHeight="999999.0"
|
||||
promptText="List of DLC..." GridPane.columnSpan="2147483647" GridPane.rowIndex="2"
|
||||
GridPane.rowSpan="2147483647"/>
|
||||
<JFXCheckBox fx:id="steamdb_dlc_checkbox" text="Additionally use SteamDB for DLCs"
|
||||
GridPane.rowIndex="1"/>
|
||||
</GridPane>
|
||||
</TitledPane>
|
||||
<JFXTextField fx:id="path_textfield" promptText="Path to game's steam_api(64).dll..." GridPane.columnSpan="2" />
|
||||
<JFXButton fx:id="path_button" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" onAction="#openFileChooser" ripplerFill="BLACK" GridPane.columnIndex="2">
|
||||
<graphic>
|
||||
<FontAwesomeIconView glyphName="FOLDER_OPEN" glyphSize="24" />
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXTextField fx:id="game_name_textfield" promptText="Game..." GridPane.rowIndex="1" />
|
||||
<JFXButton fx:id="getAppId_button" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" onAction="#getAppId" ripplerFill="BLACK" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<graphic>
|
||||
<FontAwesomeIconView glyphName="SEARCH" glyphSize="24" />
|
||||
</graphic>
|
||||
</JFXButton>
|
||||
<JFXTextField fx:id="appId_textfield" prefWidth="299.0" promptText="Steam AppID..." GridPane.columnIndex="2" GridPane.rowIndex="1" />
|
||||
<JFXComboBox fx:id="language_combobox" editable="true" promptText="Language" GridPane.columnSpan="2147483647" GridPane.rowIndex="2" />
|
||||
<JFXCheckBox fx:id="offline_checkbox" text="Force offline mode" GridPane.columnSpan="2147483647" GridPane.rowIndex="3" />
|
||||
<JFXCheckBox fx:id="extra_protection_checkbox" text="Try to bypass game-specific protection" GridPane.columnSpan="2147483647" GridPane.rowIndex="4" />
|
||||
<JFXButton fx:id="getDlcList_button" maxHeight="1.7976931348623157E308" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onAction="#getDlcList" ripplerFill="BLACK" text="Get DLCs for AppID" GridPane.rowIndex="6" />
|
||||
<JFXButton fx:id="save_button" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" onAction="#save" ripplerFill="BLACK" text="Save" GridPane.columnIndex="1" GridPane.rowIndex="6" />
|
||||
<JFXButton fx:id="reset_button" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" onAction="#resetFromButton" ripplerFill="BLACK" text="Reset" GridPane.columnIndex="2" GridPane.rowIndex="6" />
|
||||
<BorderPane.margin>
|
||||
<Insets />
|
||||
</BorderPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</padding>
|
||||
</GridPane>
|
||||
</center>
|
||||
<bottom>
|
||||
<Label fx:id="state_label" maxWidth="1.7976931348623157E308" minHeight="25.0" minWidth="-Infinity" prefWidth="905.0" text="Ready." textFill="#555555" BorderPane.alignment="CENTER">
|
||||
<BorderPane.margin>
|
||||
<Insets />
|
||||
</BorderPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</bottom>
|
||||
<right>
|
||||
<GridPane maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="250.0" BorderPane.alignment="CENTER">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</padding>
|
||||
<Label fx:id="creamApiDllApplied" maxHeight="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" text="CreamAPI DLL applied">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<graphic>
|
||||
<FontAwesomeIconView fx:id="creamApiDllAppliedIcon" glyphName="TIMES" size="20" />
|
||||
</graphic>
|
||||
</Label>
|
||||
<Label fx:id="creamApiConfigExists" layoutX="20.0" layoutY="20.0" maxHeight="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" text="CreamAPI configuration file exists" GridPane.rowIndex="1">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<graphic>
|
||||
<FontAwesomeIconView fx:id="creamApiConfigExistsIcon" glyphName="TIMES" size="20" />
|
||||
</graphic>
|
||||
</Label>
|
||||
</GridPane>
|
||||
</right>
|
||||
<stylesheets>
|
||||
<URL value="@stylesheet.css" />
|
||||
</stylesheets>
|
||||
</BorderPane>
|
@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import com.jfoenix.controls.JFXButton?>
|
||||
<?import com.jfoenix.controls.JFXTreeTableView?>
|
||||
<?import java.net.URL?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.ButtonBar?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TreeTableColumn?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<!--
|
||||
~ Auto-CreamAPI
|
||||
~ Copyright (C) 2020 Jeddunk
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
~ License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
~ version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
~ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License along with this program. If not, see
|
||||
~ <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="655.0" prefWidth="420.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="xyz.jeddunk.autocreamapi.SearchResultWindowController">
|
||||
<opaqueInsets>
|
||||
<Insets />
|
||||
</opaqueInsets>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</padding>
|
||||
<Label maxWidth="1.7976931348623157E308" text="Choose a game from the list below:" />
|
||||
<JFXTreeTableView fx:id="gameTable" fixedCellSize="28.0" maxHeight="1.7976931348623157E308" onMouseClicked="#doubleclickConfirm" prefHeight="570.0" prefWidth="400.0" showRoot="false">
|
||||
<columns>
|
||||
<TreeTableColumn fx:id="appIdCol" editable="false" maxWidth="100.0" minWidth="100.0" prefWidth="100.0" resizable="false" text="AppID" />
|
||||
<TreeTableColumn fx:id="nameCol" editable="false" maxWidth="285.0" minWidth="285.0" prefWidth="285.0" resizable="false" text="Name" />
|
||||
</columns>
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" top="10.0" />
|
||||
</VBox.margin>
|
||||
</JFXTreeTableView>
|
||||
<ButtonBar prefHeight="40.0" prefWidth="200.0">
|
||||
<buttons>
|
||||
<JFXButton fx:id="okButton" mnemonicParsing="false" onAction="#confirm" text="OK" ripplerFill="BLACK" />
|
||||
<JFXButton fx:id="cancelButton" mnemonicParsing="false" onAction="#cancel" text="Cancel" ripplerFill="BLACK" />
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
<stylesheets>
|
||||
<URL value="@stylesheet.css" />
|
||||
</stylesheets>
|
||||
</VBox>
|
71
src/main/resources/xyz/jeddunk/autocreamapi/stylesheet.css
Normal file
71
src/main/resources/xyz/jeddunk/autocreamapi/stylesheet.css
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Auto-CreamAPI
|
||||
* Copyright (C) 2020 Jeddunk
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto Condensed', sans-serif;
|
||||
src: url("fonts/roboto-condensed/RobotoCondensed-Regular.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto Condensed', sans-serif;
|
||||
font-weight: bold;
|
||||
src: url("fonts/roboto-condensed/RobotoCondensed-Bold.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto Condensed', sans-serif;
|
||||
font-weight: italic;
|
||||
src: url("fonts/roboto-condensed/RobotoCondensed-Italic.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
src: url("fonts/roboto-mono/RobotoMono-Regular.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
font-weight: bold;
|
||||
src: url("fonts/roboto-mono/RobotoMono-Bold.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
font-weight: italic;
|
||||
src: url("fonts/roboto-mono/RobotoMono-Italic.ttf");
|
||||
}
|
||||
|
||||
* {
|
||||
-fx-font-size: 14;
|
||||
-fx-font-family: 'Roboto Condensed', sans-serif;
|
||||
}
|
||||
|
||||
JFXButton {
|
||||
-fx-background-color: #ddd;
|
||||
}
|
||||
|
||||
#state_label {
|
||||
-fx-background-color: #ddd;
|
||||
-fx-border-color: #aaa;
|
||||
}
|
||||
|
||||
#dlc_textarea {
|
||||
-fx-font-family: 'Roboto Mono', sans-serif;
|
||||
}
|
||||
|
||||
.dlcSettings > .title {
|
||||
-fx-background-color: #ddd;
|
||||
}
|
BIN
steam_api.dll
BIN
steam_api.dll
Binary file not shown.
BIN
steam_api64.dll
BIN
steam_api64.dll
Binary file not shown.
@ -1 +1 @@
|
||||
4.4.0.0
|
||||
4.5.0.0
|
Loading…
Reference in New Issue
Block a user