implement connect to Elite Dangerous Companion
This commit is contained in:
@@ -65,6 +65,11 @@
|
||||
<artifactId>opencsv</artifactId>
|
||||
<version>2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
261
utils/src/main/java/ru/trader/edce/EDSession.java
Normal file
261
utils/src/main/java/ru/trader/edce/EDSession.java
Normal file
@@ -0,0 +1,261 @@
|
||||
package ru.trader.edce;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.CookieStore;
|
||||
import org.apache.http.client.ResponseHandler;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.client.methods.RequestBuilder;
|
||||
import org.apache.http.cookie.Cookie;
|
||||
import org.apache.http.impl.client.BasicCookieStore;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.client.LaxRedirectStrategy;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/* Connect to Elite Dangerous Companion
|
||||
* Thanks Andargor(https://github.com/Andargor) for source on Python
|
||||
*/
|
||||
public class EDSession {
|
||||
private final static Logger LOG = LoggerFactory.getLogger(EDSession.class);
|
||||
private final static String COMPANION_DOMAIN = "companion.orerve.net";
|
||||
private final static String LOGIN_URL = "https://" + COMPANION_DOMAIN + "/user/login";
|
||||
private final static String CONFIRM_URL = "https://" + COMPANION_DOMAIN + "/user/confirm";
|
||||
private final static String PROFILE_URL = "https://" + COMPANION_DOMAIN + "/profile";
|
||||
private final static String USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Mobile/11D257";
|
||||
private final static String COOKIE_FILE = "edce.tmp";
|
||||
|
||||
private final String login;
|
||||
private final String password;
|
||||
private CookieStore cookieStore;
|
||||
private CloseableHttpClient httpClient;
|
||||
private ED_SESSION_STATUS lastStatus;
|
||||
|
||||
public EDSession(String login, String password) throws IOException, ClassNotFoundException {
|
||||
this.login = login;
|
||||
this.password = password;
|
||||
this.lastStatus = ED_SESSION_STATUS.LOGIN_REQUIRED;
|
||||
initClient();
|
||||
}
|
||||
|
||||
private void initClient() throws IOException, ClassNotFoundException {
|
||||
cookieStore = readCookieStore();
|
||||
checkCookie();
|
||||
httpClient = HttpClients.custom()
|
||||
.setDefaultCookieStore(cookieStore)
|
||||
.setUserAgent(USER_AGENT)
|
||||
.setRedirectStrategy(new LaxRedirectStrategy())
|
||||
.build();
|
||||
}
|
||||
|
||||
public void login(){
|
||||
LOG.info("Login to {}, email {}", COMPANION_DOMAIN, login);
|
||||
HttpUriRequest loginRequest = RequestBuilder.post(LOGIN_URL)
|
||||
.addParameter("email", login)
|
||||
.addParameter("password", password)
|
||||
.build();
|
||||
EDResponseHandler handler = new EDResponseHandler(content -> {
|
||||
if (content.contains("verification code")){
|
||||
LOG.info("Verification code required");
|
||||
lastStatus = ED_SESSION_STATUS.VERIFICATION_REQUIRED;
|
||||
} else {
|
||||
if (content.contains("Password")){
|
||||
LOG.info("Wrong password or email");
|
||||
lastStatus = ED_SESSION_STATUS.LOGIN_FAILED;
|
||||
} else {
|
||||
lastStatus = ED_SESSION_STATUS.OK;
|
||||
}
|
||||
}
|
||||
});
|
||||
try {
|
||||
if (!httpClient.execute(loginRequest, handler)){
|
||||
lastStatus = ED_SESSION_STATUS.ERROR;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error on connect to {}", LOGIN_URL);
|
||||
LOG.error("", e);
|
||||
lastStatus = ED_SESSION_STATUS.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
public void submitVerifyCode(String code){
|
||||
LOG.info("Submit verify code to {}", COMPANION_DOMAIN);
|
||||
HttpUriRequest submitRequest = RequestBuilder.post(CONFIRM_URL)
|
||||
.addParameter("code", code)
|
||||
.build();
|
||||
EDResponseHandler handler = new EDResponseHandler(content -> {
|
||||
if (content.contains("verification code")){
|
||||
LOG.info("Wrong verify code");
|
||||
lastStatus = ED_SESSION_STATUS.VERIFICATION_REQUIRED;
|
||||
} else {
|
||||
lastStatus = ED_SESSION_STATUS.OK;
|
||||
}
|
||||
});
|
||||
try {
|
||||
if (!httpClient.execute(submitRequest, handler)){
|
||||
lastStatus = ED_SESSION_STATUS.ERROR;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error on connect to {}", CONFIRM_URL);
|
||||
LOG.error("", e);
|
||||
lastStatus = ED_SESSION_STATUS.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
public void readProfile(Consumer<String> contentConsumer){
|
||||
LOG.info("Submit profile request to {}", COMPANION_DOMAIN);
|
||||
HttpUriRequest submitRequest = RequestBuilder.get(PROFILE_URL).build();
|
||||
EDResponseHandler handler = new EDResponseHandler(content -> {
|
||||
if (lastStatus != ED_SESSION_STATUS.OK){
|
||||
if (content.contains("verification code")){
|
||||
LOG.info("Verification code required");
|
||||
lastStatus = ED_SESSION_STATUS.VERIFICATION_REQUIRED;
|
||||
} else if (content.contains("Password")) {
|
||||
LOG.info("Login required");
|
||||
lastStatus = ED_SESSION_STATUS.LOGIN_REQUIRED;
|
||||
} else {
|
||||
contentConsumer.accept(content);
|
||||
lastStatus = ED_SESSION_STATUS.OK;
|
||||
}
|
||||
} else {
|
||||
contentConsumer.accept(content);
|
||||
}
|
||||
});
|
||||
try {
|
||||
if (!httpClient.execute(submitRequest, handler)){
|
||||
lastStatus = ED_SESSION_STATUS.ERROR;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("Error on connect to {}", CONFIRM_URL);
|
||||
LOG.error("", e);
|
||||
lastStatus = ED_SESSION_STATUS.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
public ED_SESSION_STATUS getLastStatus() {
|
||||
return lastStatus;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
writeCookieStore(cookieStore);
|
||||
httpClient.close();
|
||||
}
|
||||
|
||||
private void checkCookie(){
|
||||
boolean appFound = false, mtkFound = false, midFound = false;
|
||||
for (Cookie cookie : cookieStore.getCookies()) {
|
||||
if (COMPANION_DOMAIN.equals(cookie.getDomain())) {
|
||||
if ("CompanionApp".equals(cookie.getName())) {
|
||||
appFound = true;
|
||||
} else if ("mid".equals(cookie.getName())){
|
||||
midFound = true;
|
||||
} else if ("mtk".equals(cookie.getName())){
|
||||
mtkFound = true;
|
||||
}
|
||||
if (appFound && mtkFound && midFound){
|
||||
LOG.debug("Old cookie found, login not required");
|
||||
lastStatus = ED_SESSION_STATUS.OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clearCookies(){
|
||||
cookieStore.clear();
|
||||
}
|
||||
|
||||
public void clearExpiredCookies(){
|
||||
cookieStore.clearExpired(new Date());
|
||||
}
|
||||
|
||||
private static CookieStore readCookieStore() {
|
||||
LOG.debug("Read cookie store from {}", COOKIE_FILE);
|
||||
File file = new File(COOKIE_FILE);
|
||||
BasicCookieStore cookieStore = null;
|
||||
if (file.exists()) {
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))){
|
||||
cookieStore = (BasicCookieStore) ois.readObject();
|
||||
cookieStore.clearExpired(new Date());
|
||||
} catch (ClassNotFoundException | IOException e) {
|
||||
LOG.warn("Error on read cookie from {}", COOKIE_FILE);
|
||||
LOG.warn("", e);
|
||||
}
|
||||
}
|
||||
if (cookieStore == null) {
|
||||
LOG.debug("Not found cookie store, create new");
|
||||
cookieStore = new BasicCookieStore();
|
||||
}
|
||||
return cookieStore;
|
||||
}
|
||||
|
||||
private static void writeCookieStore(CookieStore cookieStore) {
|
||||
LOG.debug("Write cookie store to {}", COOKIE_FILE);
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(COOKIE_FILE))){
|
||||
oos.writeObject(cookieStore);
|
||||
oos.flush();
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Error on write cookie to {}", COOKIE_FILE);
|
||||
LOG.warn("", e);
|
||||
}
|
||||
}
|
||||
|
||||
private class EDResponseHandler implements ResponseHandler<Boolean> {
|
||||
|
||||
private final Consumer<String> contentReader;
|
||||
|
||||
public EDResponseHandler() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public EDResponseHandler(Consumer<String> contentReader) {
|
||||
this.contentReader = contentReader;
|
||||
}
|
||||
|
||||
private void readContent(HttpEntity entity) throws IOException {
|
||||
if (contentReader != null) {
|
||||
String content = EntityUtils.toString(entity);
|
||||
LOG.debug("Content: {}", content);
|
||||
contentReader.accept(content);
|
||||
} else {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Content: {}", EntityUtils.toString(entity));
|
||||
} else {
|
||||
EntityUtils.consume(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean handleResponse(HttpResponse response) throws IOException {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Response: {}", response.getStatusLine());
|
||||
LOG.debug("Headers: {}", Arrays.toString(response.getAllHeaders()));
|
||||
}
|
||||
int status = response.getStatusLine().getStatusCode();
|
||||
if (status >= 200 && status < 300){
|
||||
HttpEntity entity = response.getEntity();
|
||||
if (entity != null){
|
||||
if ("application/json".equals(entity.getContentType().getValue())){
|
||||
lastStatus = ED_SESSION_STATUS.OK;
|
||||
}
|
||||
readContent(entity);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
LOG.warn("Don't connect, status: {}", response.getStatusLine());
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Content: {}", EntityUtils.toString(response.getEntity()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package ru.trader.edce;
|
||||
|
||||
public enum ED_SESSION_STATUS {
|
||||
OK, VERIFICATION_REQUIRED, LOGIN_FAILED, ERROR, LOGIN_REQUIRED
|
||||
}
|
||||
45
utils/src/test/java/ru/trader/edce/EDSessionDemo.java
Normal file
45
utils/src/test/java/ru/trader/edce/EDSessionDemo.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package ru.trader.edce;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class EDSessionDemo {
|
||||
private final static Logger LOG = LoggerFactory.getLogger(EDSessionDemo.class);
|
||||
|
||||
private static String readLine(String format, Object... args) throws IOException {
|
||||
if (System.console() != null) {
|
||||
return System.console().readLine(format, args);
|
||||
}
|
||||
System.out.print(String.format(format, args));
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||
System.in));
|
||||
return reader.readLine();
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
LOG.info("Test ED Companion connect");
|
||||
EDSession edSession = new EDSession("frontier@mail.ru","elite");
|
||||
if (edSession.getLastStatus() == ED_SESSION_STATUS.OK){
|
||||
LOG.info("Check get profile");
|
||||
edSession.readProfile(s ->{});
|
||||
}
|
||||
if (edSession.getLastStatus() == ED_SESSION_STATUS.LOGIN_REQUIRED) {
|
||||
edSession.login();
|
||||
if (edSession.getLastStatus() == ED_SESSION_STATUS.VERIFICATION_REQUIRED) {
|
||||
LOG.info("Check verification");
|
||||
String code = readLine("Verify code:");
|
||||
edSession.submitVerifyCode(code);
|
||||
edSession.login();
|
||||
}
|
||||
if (edSession.getLastStatus() == ED_SESSION_STATUS.OK) {
|
||||
LOG.info("Check get profile");
|
||||
edSession.readProfile(s -> {});
|
||||
}
|
||||
}
|
||||
edSession.close();
|
||||
}
|
||||
}
|
||||
6753
utils/src/test/resources/edce/edce.json
Normal file
6753
utils/src/test/resources/edce/edce.json
Normal file
File diff suppressed because it is too large
Load Diff
2479
utils/src/test/resources/edce/edce2.json
Normal file
2479
utils/src/test/resources/edce/edce2.json
Normal file
File diff suppressed because it is too large
Load Diff
4548
utils/src/test/resources/edce/edce3.json
Normal file
4548
utils/src/test/resources/edce/edce3.json
Normal file
File diff suppressed because it is too large
Load Diff
4280
utils/src/test/resources/edce/edce4.json
Normal file
4280
utils/src/test/resources/edce/edce4.json
Normal file
File diff suppressed because it is too large
Load Diff
9041
utils/src/test/resources/edce/edce5.json
Normal file
9041
utils/src/test/resources/edce/edce5.json
Normal file
File diff suppressed because it is too large
Load Diff
2503
utils/src/test/resources/edce/edce6.json
Normal file
2503
utils/src/test/resources/edce/edce6.json
Normal file
File diff suppressed because it is too large
Load Diff
9797
utils/src/test/resources/edce/edce7.json
Normal file
9797
utils/src/test/resources/edce/edce7.json
Normal file
File diff suppressed because it is too large
Load Diff
6753
utils/src/test/resources/edce/edce_cruise.json
Normal file
6753
utils/src/test/resources/edce/edce_cruise.json
Normal file
File diff suppressed because it is too large
Load Diff
6798
utils/src/test/resources/edce/edce_deep_space.json
Normal file
6798
utils/src/test/resources/edce/edce_deep_space.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,4 +5,4 @@ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern=%p: %d{dd.MM.yyyy HH:mm:ss} (%F:%L) - %m%n
|
||||
|
||||
|
||||
|
||||
log4j.logger.ru.trader.edce = DEBUG
|
||||
Reference in New Issue
Block a user