update loads of shit
18
pom.xml
@ -22,12 +22,30 @@
|
|||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||||
|
<artifactId>javax-websocket-server-impl</artifactId>
|
||||||
|
<version>9.4.43.v20210629</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-servlet</artifactId>
|
||||||
|
<version>9.4.43.v20210629</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.minecraft</groupId>
|
<groupId>net.minecraft</groupId>
|
||||||
<artifactId>minecraft</artifactId>
|
<artifactId>minecraft</artifactId>
|
||||||
<version>1.8.8</version>
|
<version>1.8.8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.java-websocket</groupId>
|
||||||
|
<artifactId>Java-WebSocket</artifactId>
|
||||||
|
<version>1.5.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>co.gongzh.procbridge</groupId>
|
<groupId>co.gongzh.procbridge</groupId>
|
||||||
<artifactId>procbridge</artifactId>
|
<artifactId>procbridge</artifactId>
|
||||||
|
@ -20,12 +20,14 @@ package fr.litarvan.openauth;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import fr.litarvan.openauth.model.AuthAgent;
|
import fr.litarvan.openauth.model.AuthAgent;
|
||||||
import fr.litarvan.openauth.model.request.*;
|
|
||||||
import fr.litarvan.openauth.model.response.*;
|
|
||||||
import fr.litarvan.openauth.model.AuthError;
|
import fr.litarvan.openauth.model.AuthError;
|
||||||
|
import fr.litarvan.openauth.model.request.*;
|
||||||
|
import fr.litarvan.openauth.model.response.AuthResponse;
|
||||||
|
import fr.litarvan.openauth.model.response.RefreshResponse;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.Proxy;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
@ -43,18 +45,20 @@ public class Authenticator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The Mojang official auth server
|
* The Mojang official auth server
|
||||||
|
* @deprecated Should not be used since it doesn't work anymore.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static final String MOJANG_AUTH_URL = "https://authserver.mojang.com/";
|
public static final String MOJANG_AUTH_URL = "https://authserver.mojang.com/";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The auth server URL
|
* The auth server URL
|
||||||
*/
|
*/
|
||||||
private String authURL;
|
private final String authURL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The server auth points
|
* The server auth points
|
||||||
*/
|
*/
|
||||||
private AuthPoints authPoints;
|
private final AuthPoints authPoints;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an authenticator
|
* Create an authenticator
|
||||||
@ -71,14 +75,14 @@ public class Authenticator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticates an user using his password.
|
* Authenticates a user using his password.
|
||||||
*
|
*
|
||||||
* @param agent
|
* @param agent
|
||||||
* The auth agent (optional)
|
* The auth agent (optional)
|
||||||
* @param username
|
* @param username
|
||||||
* User mojang account name
|
* User account name
|
||||||
* @param password
|
* @param password
|
||||||
* User mojang account password
|
* User account password
|
||||||
* @param clientToken
|
* @param clientToken
|
||||||
* The client token (optional, like a key for the access token)
|
* The client token (optional, like a key for the access token)
|
||||||
*
|
*
|
||||||
@ -87,8 +91,30 @@ public class Authenticator {
|
|||||||
* @return The response sent by the server (parsed from a JSON)
|
* @return The response sent by the server (parsed from a JSON)
|
||||||
*/
|
*/
|
||||||
public AuthResponse authenticate(AuthAgent agent, String username, String password, String clientToken) throws AuthenticationException {
|
public AuthResponse authenticate(AuthAgent agent, String username, String password, String clientToken) throws AuthenticationException {
|
||||||
|
return authenticate(agent, username, password, clientToken, Proxy.NO_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticates a user using his password.
|
||||||
|
*
|
||||||
|
* @param agent
|
||||||
|
* The auth agent (optional)
|
||||||
|
* @param username
|
||||||
|
* User account name
|
||||||
|
* @param password
|
||||||
|
* User account password
|
||||||
|
* @param clientToken
|
||||||
|
* The client token (optional, like a key for the access token)
|
||||||
|
* @param proxy
|
||||||
|
* The proxy to use (optional)
|
||||||
|
*
|
||||||
|
* @throws AuthenticationException If the server returned an error as a JSON
|
||||||
|
*
|
||||||
|
* @return The response sent by the server (parsed from a JSON)
|
||||||
|
*/
|
||||||
|
public AuthResponse authenticate(AuthAgent agent, String username, String password, String clientToken, Proxy proxy) throws AuthenticationException {
|
||||||
AuthRequest request = new AuthRequest(agent, username, password, clientToken);
|
AuthRequest request = new AuthRequest(agent, username, password, clientToken);
|
||||||
return (AuthResponse) sendRequest(request, AuthResponse.class, authPoints.getAuthenticatePoint());
|
return (AuthResponse) sendRequest(request, AuthResponse.class, authPoints.getAuthenticatePoint(), proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,15 +124,34 @@ public class Authenticator {
|
|||||||
* @param accessToken
|
* @param accessToken
|
||||||
* The saved access token
|
* The saved access token
|
||||||
* @param clientToken
|
* @param clientToken
|
||||||
* The saved client token (need to be the same used when authenticated to get the acces token)
|
* The saved client token (need to be the same used when authenticated to get the access token)
|
||||||
*
|
*
|
||||||
* @throws AuthenticationException If the server returned an error as a JSON
|
* @throws AuthenticationException If the server returned an error as a JSON
|
||||||
*
|
*
|
||||||
* @return The response sent by the server (parsed from a JSON)
|
* @return The response sent by the server (parsed from a JSON)
|
||||||
*/
|
*/
|
||||||
public RefreshResponse refresh(String accessToken, String clientToken) throws AuthenticationException {
|
public RefreshResponse refresh(String accessToken, String clientToken) throws AuthenticationException {
|
||||||
|
return refresh(accessToken, clientToken, Proxy.NO_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh a valid access token. It can be uses to keep a user logged in between gaming sessions
|
||||||
|
* and is preferred over storing the user's password in a file.
|
||||||
|
*
|
||||||
|
* @param accessToken
|
||||||
|
* The saved access token
|
||||||
|
* @param clientToken
|
||||||
|
* The saved client token (need to be the same used when authenticated to get the access token)
|
||||||
|
* @param proxy
|
||||||
|
* The proxy to use (optional)
|
||||||
|
*
|
||||||
|
* @throws AuthenticationException If the server returned an error as a JSON
|
||||||
|
*
|
||||||
|
* @return The response sent by the server (parsed from a JSON)
|
||||||
|
*/
|
||||||
|
public RefreshResponse refresh(String accessToken, String clientToken, Proxy proxy) throws AuthenticationException {
|
||||||
RefreshRequest request = new RefreshRequest(accessToken, clientToken);
|
RefreshRequest request = new RefreshRequest(accessToken, clientToken);
|
||||||
return (RefreshResponse) sendRequest(request, RefreshResponse.class, authPoints.getRefreshPoint());
|
return (RefreshResponse) sendRequest(request, RefreshResponse.class, authPoints.getRefreshPoint(), proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -123,23 +168,58 @@ public class Authenticator {
|
|||||||
* @throws AuthenticationException If the server returned an error as a JSON
|
* @throws AuthenticationException If the server returned an error as a JSON
|
||||||
*/
|
*/
|
||||||
public void validate(String accessToken) throws AuthenticationException {
|
public void validate(String accessToken) throws AuthenticationException {
|
||||||
|
validate(accessToken, Proxy.NO_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an access token is a valid session token with a currently-active session.
|
||||||
|
* Note: this method will not respond successfully to all currently-logged-in sessions,
|
||||||
|
* just the most recently-logged-in for each user. It is intended to be used by servers to validate
|
||||||
|
* that a user should be connecting (and reject users who have logged in elsewhere since starting Minecraft),
|
||||||
|
* NOT to auth that a particular session token is valid for authentication purposes.
|
||||||
|
* To authenticate a user by session token, use the refresh verb and catch resulting errors.
|
||||||
|
*
|
||||||
|
* @param accessToken
|
||||||
|
* The access token to check
|
||||||
|
* @param proxy
|
||||||
|
* The proxy to use (optional)
|
||||||
|
*
|
||||||
|
* @throws AuthenticationException If the server returned an error as a JSON
|
||||||
|
*/
|
||||||
|
public void validate(String accessToken, Proxy proxy) throws AuthenticationException {
|
||||||
ValidateRequest request = new ValidateRequest(accessToken);
|
ValidateRequest request = new ValidateRequest(accessToken);
|
||||||
sendRequest(request, null, authPoints.getValidatePoint());
|
sendRequest(request, null, authPoints.getValidatePoint(), proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidates accessTokens using an account's username and password
|
* Invalidates accessTokens using an account's username and password
|
||||||
*
|
*
|
||||||
* @param username
|
* @param username
|
||||||
* User mojang account name
|
* User account name
|
||||||
* @param password
|
* @param password
|
||||||
* User mojang account password
|
* User account password
|
||||||
*
|
*
|
||||||
* @throws AuthenticationException If the server returned an error as a JSON
|
* @throws AuthenticationException If the server returned an error as a JSON
|
||||||
*/
|
*/
|
||||||
public void signout(String username, String password) throws AuthenticationException {
|
public void signout(String username, String password) throws AuthenticationException {
|
||||||
|
signout(username, password, Proxy.NO_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates accessTokens using an account's username and password
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* User account name
|
||||||
|
* @param password
|
||||||
|
* User account password
|
||||||
|
* @param proxy
|
||||||
|
* The proxy to use (optional)
|
||||||
|
*
|
||||||
|
* @throws AuthenticationException If the server returned an error as a JSON
|
||||||
|
*/
|
||||||
|
public void signout(String username, String password, Proxy proxy) throws AuthenticationException {
|
||||||
SignoutRequest request = new SignoutRequest(username, password);
|
SignoutRequest request = new SignoutRequest(username, password);
|
||||||
sendRequest(request, null, authPoints.getSignoutPoint());
|
sendRequest(request, null, authPoints.getSignoutPoint(), proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -153,8 +233,24 @@ public class Authenticator {
|
|||||||
* @throws AuthenticationException If the server returned an error as a JSON
|
* @throws AuthenticationException If the server returned an error as a JSON
|
||||||
*/
|
*/
|
||||||
public void invalidate(String accessToken, String clientToken) throws AuthenticationException {
|
public void invalidate(String accessToken, String clientToken) throws AuthenticationException {
|
||||||
|
invalidate(accessToken, clientToken, Proxy.NO_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates accessTokens using a client/access token pair
|
||||||
|
*
|
||||||
|
* @param accessToken
|
||||||
|
* Valid access token to invalidate
|
||||||
|
* @param clientToken
|
||||||
|
* Client token used when authenticated to get the access token
|
||||||
|
* @param proxy
|
||||||
|
* The proxy to use (optional)
|
||||||
|
*
|
||||||
|
* @throws AuthenticationException If the server returned an error as a JSON
|
||||||
|
*/
|
||||||
|
public void invalidate(String accessToken, String clientToken, Proxy proxy) throws AuthenticationException {
|
||||||
InvalidateRequest request = new InvalidateRequest(accessToken, clientToken);
|
InvalidateRequest request = new InvalidateRequest(accessToken, clientToken);
|
||||||
sendRequest(request, null, authPoints.getInvalidatePoint());
|
sendRequest(request, null, authPoints.getInvalidatePoint(), proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,7 +259,7 @@ public class Authenticator {
|
|||||||
* @param request
|
* @param request
|
||||||
* The auth request to send
|
* The auth request to send
|
||||||
* @param model
|
* @param model
|
||||||
* The model of the reponse
|
* The model of the response
|
||||||
* @param authPoint
|
* @param authPoint
|
||||||
* The auth point of the request
|
* The auth point of the request
|
||||||
* @throws AuthenticationException
|
* @throws AuthenticationException
|
||||||
@ -171,14 +267,36 @@ public class Authenticator {
|
|||||||
*
|
*
|
||||||
* @throws AuthenticationException If the server returned an error as a JSON
|
* @throws AuthenticationException If the server returned an error as a JSON
|
||||||
*
|
*
|
||||||
* @return Instance of the given reponse model if it not null
|
* @return Instance of the given response model if it not null
|
||||||
*/
|
*/
|
||||||
private Object sendRequest(Object request, Class<?> model, String authPoint) throws AuthenticationException {
|
private Object sendRequest(Object request, Class<?> model, String authPoint) throws AuthenticationException {
|
||||||
|
return sendRequest(request, model, authPoint, Proxy.NO_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a request to the auth server
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* The auth request to send
|
||||||
|
* @param model
|
||||||
|
* The model of the response
|
||||||
|
* @param authPoint
|
||||||
|
* The auth point of the request
|
||||||
|
* @param proxy
|
||||||
|
* The proxy to use (optional)
|
||||||
|
* @throws AuthenticationException
|
||||||
|
* If it returned an error or the request failed
|
||||||
|
*
|
||||||
|
* @throws AuthenticationException If the server returned an error as a JSON
|
||||||
|
*
|
||||||
|
* @return Instance of the given response model if it not null
|
||||||
|
*/
|
||||||
|
private Object sendRequest(Object request, Class<?> model, String authPoint, Proxy proxy) throws AuthenticationException {
|
||||||
Gson gson = new Gson();
|
Gson gson = new Gson();
|
||||||
String response;
|
String response;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
response = sendPostRequest(this.authURL + authPoint, gson.toJson(request));
|
response = sendPostRequest(this.authURL + authPoint, gson.toJson(request), proxy);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new AuthenticationException(new AuthError("Can't send the request : " + e.getClass().getName(), e.getMessage(), "Unknown"));
|
throw new AuthenticationException(new AuthError("Can't send the request : " + e.getClass().getName(), e.getMessage(), "Unknown"));
|
||||||
}
|
}
|
||||||
@ -204,9 +322,29 @@ public class Authenticator {
|
|||||||
* @return The request response
|
* @return The request response
|
||||||
*/
|
*/
|
||||||
private String sendPostRequest(String url, String json) throws AuthenticationException, IOException {
|
private String sendPostRequest(String url, String json) throws AuthenticationException, IOException {
|
||||||
|
return sendPostRequest(url, json, Proxy.NO_PROXY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a post request of a json
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* The url to send the request
|
||||||
|
* @param json
|
||||||
|
* The json to send
|
||||||
|
* @param proxy
|
||||||
|
* The proxy to use (optional)
|
||||||
|
* @throws IOException
|
||||||
|
* If it failed
|
||||||
|
*
|
||||||
|
* @throws AuthenticationException If the request returned an error JSON or not a JSON
|
||||||
|
*
|
||||||
|
* @return The request response
|
||||||
|
*/
|
||||||
|
private String sendPostRequest(String url, String json, Proxy proxy) throws AuthenticationException, IOException {
|
||||||
byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8);
|
byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8);
|
||||||
URL serverURL = new URL(url);
|
URL serverURL = new URL(url);
|
||||||
HttpURLConnection connection = (HttpURLConnection) serverURL.openConnection();
|
HttpURLConnection connection = (HttpURLConnection) serverURL.openConnection(proxy != null ? proxy : Proxy.NO_PROXY);
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
|
|
||||||
// Sending post request
|
// Sending post request
|
||||||
|
@ -20,28 +20,30 @@ package fr.litarvan.openauth.microsoft;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.io.BufferedReader;
|
import java.net.Proxy;
|
||||||
import java.io.IOException;
|
import java.net.URL;
|
||||||
import java.io.InputStreamReader;
|
import java.net.URLEncoder;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.*;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
public class HttpClient
|
public class HttpClient
|
||||||
{
|
{
|
||||||
public static final String MIME_TYPE_JSON = "application/json";
|
public static final String MIME_TYPE_JSON = "application/json";
|
||||||
public static final String MIME_TYPE_URLENCODED_FORM = "application/x-www-form-urlencoded";
|
public static final String MIME_TYPE_URLENCODED_FORM = "application/x-www-form-urlencoded";
|
||||||
|
|
||||||
|
|
||||||
private final Gson gson;
|
private final Gson gson;
|
||||||
|
private final Proxy proxy;
|
||||||
|
|
||||||
public HttpClient()
|
public HttpClient()
|
||||||
|
{
|
||||||
|
this(Proxy.NO_PROXY);
|
||||||
|
}
|
||||||
|
public HttpClient(Proxy proxy)
|
||||||
{
|
{
|
||||||
this.gson = new Gson();
|
this.gson = new Gson();
|
||||||
|
this.proxy = proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -52,21 +54,21 @@ public class HttpClient
|
|||||||
|
|
||||||
public <T> T getJson(String url, String token, Class<T> responseClass) throws MicrosoftAuthenticationException
|
public <T> T getJson(String url, String token, Class<T> responseClass) throws MicrosoftAuthenticationException
|
||||||
{
|
{
|
||||||
HttpsURLConnection connection = createConnection(url);
|
HttpURLConnection connection = createConnection(url);
|
||||||
connection.addRequestProperty("Authorization", "Bearer " + token);
|
connection.addRequestProperty("Authorization", "Bearer " + token);
|
||||||
connection.addRequestProperty("Accept", MIME_TYPE_JSON);
|
connection.addRequestProperty("Accept", MIME_TYPE_JSON);
|
||||||
|
|
||||||
return readJson(connection, responseClass);
|
return readJson(connection, responseClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpsURLConnection postForm(String url, Map<String, String> params) throws MicrosoftAuthenticationException
|
public HttpURLConnection postForm(String url, Map<String, String> params) throws MicrosoftAuthenticationException
|
||||||
{
|
{
|
||||||
return post(url, MIME_TYPE_URLENCODED_FORM, "*/*", buildParams(params));
|
return post(url, MIME_TYPE_URLENCODED_FORM, "*/*", buildParams(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T postJson(String url, Object request, Class<T> responseClass) throws MicrosoftAuthenticationException
|
public <T> T postJson(String url, Object request, Class<T> responseClass) throws MicrosoftAuthenticationException
|
||||||
{
|
{
|
||||||
HttpsURLConnection connection = post(url, MIME_TYPE_JSON, MIME_TYPE_JSON, gson.toJson(request));
|
HttpURLConnection connection = post(url, MIME_TYPE_JSON, MIME_TYPE_JSON, gson.toJson(request));
|
||||||
return readJson(connection, responseClass);
|
return readJson(connection, responseClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,9 +78,9 @@ public class HttpClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected HttpsURLConnection post(String url, String contentType, String accept, String data) throws MicrosoftAuthenticationException
|
protected HttpURLConnection post(String url, String contentType, String accept, String data) throws MicrosoftAuthenticationException
|
||||||
{
|
{
|
||||||
HttpsURLConnection connection = createConnection(url);
|
HttpURLConnection connection = createConnection(url);
|
||||||
connection.setDoOutput(true);
|
connection.setDoOutput(true);
|
||||||
connection.addRequestProperty("Content-Type", contentType);
|
connection.addRequestProperty("Content-Type", contentType);
|
||||||
connection.addRequestProperty("Accept", accept);
|
connection.addRequestProperty("Accept", accept);
|
||||||
@ -93,12 +95,12 @@ public class HttpClient
|
|||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T> T readJson(HttpsURLConnection connection, Class<T> responseType) throws MicrosoftAuthenticationException
|
protected <T> T readJson(HttpURLConnection connection, Class<T> responseType) throws MicrosoftAuthenticationException
|
||||||
{
|
{
|
||||||
return gson.fromJson(readResponse(connection), responseType);
|
return gson.fromJson(readResponse(connection), responseType);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String readResponse(HttpsURLConnection connection) throws MicrosoftAuthenticationException
|
protected String readResponse(HttpURLConnection connection) throws MicrosoftAuthenticationException
|
||||||
{
|
{
|
||||||
String redirection = connection.getHeaderField("Location");
|
String redirection = connection.getHeaderField("Location");
|
||||||
if (redirection != null) {
|
if (redirection != null) {
|
||||||
@ -106,19 +108,61 @@ public class HttpClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder response = new StringBuilder();
|
StringBuilder response = new StringBuilder();
|
||||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
|
|
||||||
String line;
|
try
|
||||||
while ((line = br.readLine()) != null) {
|
{
|
||||||
response.append(line).append('\n');
|
InputStream inputStream = connection.getInputStream();
|
||||||
|
|
||||||
|
// check if the url corresponds to a related authentication url
|
||||||
|
if(this.checkUrl(connection.getURL()))
|
||||||
|
{
|
||||||
|
// then patch the input stream like in the old MicrosoftPatchedHttpURLConnection class.
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
int n;
|
||||||
|
byte[] data = new byte[8192];
|
||||||
|
|
||||||
|
while ((n = inputStream.read(data, 0, data.length)) != -1) {
|
||||||
|
buffer.write(data, 0, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] patched = buffer
|
||||||
|
.toString("UTF-8")
|
||||||
|
.replaceAll("integrity ?=", "integrity.disabled=")
|
||||||
|
.replaceAll("setAttribute\\(\"integrity\"", "setAttribute(\"integrity.disabled\"")
|
||||||
|
.getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
inputStream = new ByteArrayInputStream(patched);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
throw new MicrosoftAuthenticationException(e);
|
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||||
|
String line;
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
response.append(line).append('\n');
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new MicrosoftAuthenticationException(e);
|
||||||
|
}
|
||||||
|
} catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.toString();
|
return response.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpsURLConnection followRedirects(HttpsURLConnection connection) throws MicrosoftAuthenticationException
|
private boolean checkUrl(URL url)
|
||||||
|
{
|
||||||
|
return (("login.microsoftonline.com".equals(url.getHost()) && url.getPath().endsWith("/oauth2/authorize"))
|
||||||
|
|| ("login.live.com".equals(url.getHost()) && "/oauth20_authorize.srf".equals(url.getPath()))
|
||||||
|
|| ("login.live.com".equals(url.getHost()) && "/ppsecure/post.srf".equals(url.getPath()))
|
||||||
|
|| ("login.microsoftonline.com".equals(url.getHost()) && "/login.srf".equals(url.getPath()))
|
||||||
|
|| ("login.microsoftonline.com".equals(url.getHost()) && url.getPath().endsWith("/login"))
|
||||||
|
|| ("login.microsoftonline.com".equals(url.getHost()) && url.getPath().endsWith("/SAS/ProcessAuth"))
|
||||||
|
|| ("login.microsoftonline.com".equals(url.getHost()) && url.getPath().endsWith("/federation/oauth2"))
|
||||||
|
|| ("login.microsoftonline.com".equals(url.getHost()) && url.getPath().endsWith("/oauth2/v2.0/authorize")));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected HttpURLConnection followRedirects(HttpURLConnection connection) throws MicrosoftAuthenticationException
|
||||||
{
|
{
|
||||||
String redirection = connection.getHeaderField("Location");
|
String redirection = connection.getHeaderField("Location");
|
||||||
if (redirection != null) {
|
if (redirection != null) {
|
||||||
@ -137,7 +181,7 @@ public class HttpClient
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
query.append(key).append('=').append(URLEncoder.encode(value, "UTF-8"));
|
query.append(key).append('=').append(URLEncoder.encode(value, StandardCharsets.UTF_8.name()));
|
||||||
} catch (UnsupportedEncodingException ignored) {
|
} catch (UnsupportedEncodingException ignored) {
|
||||||
// Can't happen
|
// Can't happen
|
||||||
}
|
}
|
||||||
@ -146,17 +190,22 @@ public class HttpClient
|
|||||||
return query.toString();
|
return query.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HttpsURLConnection createConnection(String url) throws MicrosoftAuthenticationException
|
protected HttpURLConnection createConnection(String url) throws MicrosoftAuthenticationException
|
||||||
{
|
{
|
||||||
HttpsURLConnection connection;
|
HttpURLConnection connection;
|
||||||
try {
|
try {
|
||||||
connection = (HttpsURLConnection) new URL(url).openConnection();
|
connection = (HttpURLConnection) new URL(url).openConnection(proxy);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new MicrosoftAuthenticationException(e);
|
throw new MicrosoftAuthenticationException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
String userAgent = "Mozilla/5.0 (XboxReplay; XboxLiveAuth/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36";
|
String userAgent = "Mozilla/5.0 (XboxReplay; XboxLiveAuth/3.0) " +
|
||||||
|
"AppleWebKit/537.36 (KHTML, like Gecko) " +
|
||||||
|
"Chrome/71.0.3578.98 " +
|
||||||
|
"Safari/537.36";
|
||||||
|
|
||||||
|
connection.setConnectTimeout(30 * 1000); // 30s
|
||||||
|
connection.setReadTimeout(60 * 1000); // 60s
|
||||||
connection.setRequestProperty("Accept-Language", "en-US");
|
connection.setRequestProperty("Accept-Language", "en-US");
|
||||||
connection.setRequestProperty("Accept-Charset", "UTF-8");
|
connection.setRequestProperty("Accept-Charset", "UTF-8");
|
||||||
connection.setRequestProperty("User-Agent", userAgent);
|
connection.setRequestProperty("User-Agent", userAgent);
|
||||||
|
92
src/main/java/fr/litarvan/openauth/microsoft/LoginFrame.java
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015-2021 Adrien 'Litarvan' Navratil
|
||||||
|
*
|
||||||
|
* This file is part of OpenAuth.
|
||||||
|
|
||||||
|
* OpenAuth is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* OpenAuth 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with OpenAuth. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package fr.litarvan.openauth.microsoft;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.embed.swing.JFXPanel;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.web.WebView;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Had to use Swing here, JavaFX is meant to have an 'Application' but only one can exist.
|
||||||
|
* Creating one would break compatibility with JavaFX apps (which already have their own
|
||||||
|
* class), and letting the user do so would break compatibility with Swing apps.
|
||||||
|
*
|
||||||
|
* This method makes the frame compatible with pretty much everything.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class LoginFrame extends JFrame
|
||||||
|
{
|
||||||
|
private CompletableFuture<String> future;
|
||||||
|
private boolean completed;
|
||||||
|
|
||||||
|
public LoginFrame()
|
||||||
|
{
|
||||||
|
this.setTitle("Microsoft Authentication");
|
||||||
|
this.setSize(750, 750);
|
||||||
|
this.setLocationRelativeTo(null);
|
||||||
|
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||||
|
|
||||||
|
this.setContentPane(new JFXPanel());
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<String> start(String url)
|
||||||
|
{
|
||||||
|
if (this.future != null) {
|
||||||
|
return this.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.future = new CompletableFuture<>();
|
||||||
|
this.addWindowListener(new WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
if(!completed)
|
||||||
|
future.complete(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Platform.runLater(() -> this.init(url));
|
||||||
|
return this.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void init(String url)
|
||||||
|
{
|
||||||
|
WebView webView = new WebView();
|
||||||
|
JFXPanel content = (JFXPanel) this.getContentPane();
|
||||||
|
|
||||||
|
content.setScene(new Scene(webView, this.getWidth(), this.getHeight()));
|
||||||
|
|
||||||
|
webView.getEngine().locationProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
|
if (newValue.contains("access_token")) {
|
||||||
|
this.future.complete(newValue);
|
||||||
|
completed = true;
|
||||||
|
this.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
webView.getEngine().setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36");
|
||||||
|
webView.getEngine().load(url);
|
||||||
|
|
||||||
|
this.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
@ -29,19 +29,23 @@ import fr.litarvan.openauth.microsoft.model.response.MinecraftProfile;
|
|||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Litarvan
|
* @author Litarvan
|
||||||
* @version 1.1.0
|
* @version 1.1.5
|
||||||
*/
|
*/
|
||||||
public class MicrosoftAuthResult
|
public class MicrosoftAuthResult
|
||||||
{
|
{
|
||||||
private final MinecraftProfile profile;
|
private final MinecraftProfile profile;
|
||||||
private final String accessToken;
|
private final String accessToken;
|
||||||
private final String refreshToken;
|
private final String refreshToken;
|
||||||
|
private final String xuid;
|
||||||
|
private final String clientId;
|
||||||
|
|
||||||
public MicrosoftAuthResult(MinecraftProfile profile, String accessToken, String refreshToken)
|
public MicrosoftAuthResult(MinecraftProfile profile, String accessToken, String refreshToken, String xuid, String clientId)
|
||||||
{
|
{
|
||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
this.accessToken = accessToken;
|
this.accessToken = accessToken;
|
||||||
this.refreshToken = refreshToken;
|
this.refreshToken = refreshToken;
|
||||||
|
this.xuid = xuid;
|
||||||
|
this.clientId = clientId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,4 +72,20 @@ public class MicrosoftAuthResult
|
|||||||
{
|
{
|
||||||
return refreshToken;
|
return refreshToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The XUID of the player
|
||||||
|
*/
|
||||||
|
public String getXuid()
|
||||||
|
{
|
||||||
|
return this.xuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The client ID of the player
|
||||||
|
*/
|
||||||
|
public String getClientId()
|
||||||
|
{
|
||||||
|
return this.clientId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,10 @@ import fr.litarvan.openauth.microsoft.model.request.XboxLiveLoginProperties;
|
|||||||
import fr.litarvan.openauth.microsoft.model.request.XboxLoginRequest;
|
import fr.litarvan.openauth.microsoft.model.request.XboxLoginRequest;
|
||||||
import fr.litarvan.openauth.microsoft.model.response.*;
|
import fr.litarvan.openauth.microsoft.model.response.*;
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
@ -47,17 +47,16 @@ import java.util.regex.Pattern;
|
|||||||
* Microsoft authenticator
|
* Microsoft authenticator
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* This class can be used to authenticate a player using its Microsoft account.
|
* This class can be used to authenticate a player using its Microsoft account.
|
||||||
* Use {@link #loginWithCredentials} to retrieve a player profile from his Microsoft credentials,
|
* Use {@link #loginWithCredentials} to retrieve a player profile from his Microsoft credentials,
|
||||||
* or loginWithWebview to use a webview with Microsoft login form.
|
* or {@link #loginWithWebview} to use a webview with Microsoft login form.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @version 1.1.0
|
|
||||||
* @author Litarvan
|
* @author Litarvan
|
||||||
|
* @version 1.1.0
|
||||||
*/
|
*/
|
||||||
public class MicrosoftAuthenticator
|
public class MicrosoftAuthenticator {
|
||||||
{
|
public static final String MICROSOFT_AUTHORIZATION_ENDPOINT = "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize";
|
||||||
public static final String MICROSOFT_AUTHORIZATION_ENDPOINT = "https://login.live.com/oauth20_authorize.srf";
|
|
||||||
public static final String MICROSOFT_TOKEN_ENDPOINT = "https://login.live.com/oauth20_token.srf";
|
public static final String MICROSOFT_TOKEN_ENDPOINT = "https://login.live.com/oauth20_token.srf";
|
||||||
public static final String MICROSOFT_REDIRECTION_ENDPOINT = "https://login.live.com/oauth20_desktop.srf";
|
public static final String MICROSOFT_REDIRECTION_ENDPOINT = "https://login.live.com/oauth20_desktop.srf";
|
||||||
|
|
||||||
@ -80,24 +79,19 @@ public class MicrosoftAuthenticator
|
|||||||
|
|
||||||
private final HttpClient http;
|
private final HttpClient http;
|
||||||
|
|
||||||
public MicrosoftAuthenticator()
|
public MicrosoftAuthenticator() {
|
||||||
{
|
|
||||||
this.http = new HttpClient();
|
this.http = new HttpClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs in a player using its Microsoft account credentials, and retrieve its Minecraft profile
|
* Logs in a player using its Microsoft account credentials, and retrieve its Minecraft profile
|
||||||
*
|
*
|
||||||
* @param email Player Microsoft account e-mail
|
* @param email Player Microsoft account e-mail
|
||||||
* @param password Player Microsoft account password
|
* @param password Player Microsoft account password
|
||||||
*
|
|
||||||
* @return The player Minecraft profile
|
* @return The player Minecraft profile
|
||||||
*
|
|
||||||
* @throws MicrosoftAuthenticationException Thrown if one of the several HTTP requests failed at some point
|
* @throws MicrosoftAuthenticationException Thrown if one of the several HTTP requests failed at some point
|
||||||
*/
|
*/
|
||||||
public MicrosoftAuthResult loginWithCredentials(String email, String password) throws MicrosoftAuthenticationException
|
public MicrosoftAuthResult loginWithCredentials(String email, String password) throws MicrosoftAuthenticationException {
|
||||||
{
|
|
||||||
CookieHandler currentHandler = CookieHandler.getDefault();
|
CookieHandler currentHandler = CookieHandler.getDefault();
|
||||||
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
|
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
|
||||||
|
|
||||||
@ -106,7 +100,7 @@ public class MicrosoftAuthenticator
|
|||||||
params.put("loginfmt", email);
|
params.put("loginfmt", email);
|
||||||
params.put("passwd", password);
|
params.put("passwd", password);
|
||||||
|
|
||||||
HttpsURLConnection result;
|
HttpURLConnection result;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PreAuthData authData = preAuthRequest();
|
PreAuthData authData = preAuthRequest();
|
||||||
@ -118,9 +112,9 @@ public class MicrosoftAuthenticator
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return loginWithTokens(extractTokens(result.getURL().toString()));
|
return loginWithTokens(extractTokens(result.getURL().toString()),true);
|
||||||
} catch (MicrosoftAuthenticationException e) {
|
} catch (MicrosoftAuthenticationException e) {
|
||||||
if (match("identity/confirm", http.readResponse(result)) != null) {
|
if (match("(identity/confirm)", http.readResponse(result)) != null) {
|
||||||
throw new MicrosoftAuthenticationException(
|
throw new MicrosoftAuthenticationException(
|
||||||
"User has enabled double-authentication or must allow sign-in on https://account.live.com/activity"
|
"User has enabled double-authentication or must allow sign-in on https://account.live.com/activity"
|
||||||
);
|
);
|
||||||
@ -130,77 +124,54 @@ public class MicrosoftAuthenticator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * Logs in a player using a webview to display Microsoft login page.
|
* Logs in a player using a webview to display Microsoft login page.
|
||||||
// * <b>This function blocks the current thread until the process is finished; this can cause your application to
|
* <b>This function blocks the current thread until the process is finished; this can cause your application to
|
||||||
// * freeze. When calling from the JavaFX thread or any thread which must not be blocked, use
|
* freeze. When calling from the JavaFX thread or any thread which must not be blocked, use
|
||||||
// * {@link #loginWithAsyncWebview()}</b>
|
* {@link #loginWithAsyncWebview()}</b>
|
||||||
// *
|
*
|
||||||
// * @return The player Minecraft profile
|
* @return The player Minecraft profile
|
||||||
// *
|
* @throws MicrosoftAuthenticationException Thrown if one of the several HTTP requests failed at some point
|
||||||
// * @throws MicrosoftAuthenticationException Thrown if one of the several HTTP requests failed at some point
|
*/
|
||||||
// */
|
public MicrosoftAuthResult loginWithWebview() throws MicrosoftAuthenticationException {
|
||||||
// public MicrosoftAuthResult loginWithWebview() throws MicrosoftAuthenticationException
|
|
||||||
// {
|
|
||||||
// try {
|
|
||||||
// return loginWithAsyncWebview().get();
|
|
||||||
// } catch (InterruptedException | ExecutionException e) {
|
|
||||||
// throw new MicrosoftAuthenticationException(e);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Logs in a player using a webview to display Microsoft login page. This function does not block the current thread.
|
|
||||||
// *
|
|
||||||
// * @return A future resolved by the player Minecraft profile
|
|
||||||
// */
|
|
||||||
// public CompletableFuture<MicrosoftAuthResult> loginWithAsyncWebview()
|
|
||||||
// {
|
|
||||||
// String url = String.format("%s?%s", MICROSOFT_AUTHORIZATION_ENDPOINT, http.buildParams(getLoginParams()));
|
|
||||||
// LoginFrame frame = new LoginFrame();
|
|
||||||
//
|
|
||||||
// return frame.start(url).thenApplyAsync(result -> {
|
|
||||||
// try {
|
|
||||||
// return loginWithTokens(extractTokens(result));
|
|
||||||
// } catch (MicrosoftAuthenticationException e) {
|
|
||||||
// throw new CompletionException(e);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
/*public MicrosoftAuthResult loginWithWebview() throws MicrosoftAuthenticationException
|
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
return loginWithAsyncWebview().get();
|
return loginWithAsyncWebview().get();
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
throw new MicrosoftAuthenticationException(e);
|
throw new MicrosoftAuthenticationException(e);
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs in a player using a webview to display Microsoft login page. This function does not block the current thread.
|
||||||
|
*
|
||||||
|
* @return A future resolved by the player Minecraft profile
|
||||||
|
*/
|
||||||
|
public CompletableFuture<MicrosoftAuthResult> loginWithAsyncWebview() {
|
||||||
|
if(!System.getProperty("java.version").startsWith("1."))
|
||||||
|
CookieHandler.setDefault(new CookieManager());
|
||||||
|
|
||||||
/*public CompletableFuture<MicrosoftAuthResult> loginWithAsyncWebview()
|
|
||||||
{
|
|
||||||
String url = String.format("%s?%s", MICROSOFT_AUTHORIZATION_ENDPOINT, http.buildParams(getLoginParams()));
|
String url = String.format("%s?%s", MICROSOFT_AUTHORIZATION_ENDPOINT, http.buildParams(getLoginParams()));
|
||||||
LoginFrame frame = new LoginFrame();
|
LoginFrame frame = new LoginFrame();
|
||||||
|
|
||||||
return frame.start(url).thenApplyAsync(result -> {
|
return frame.start(url).thenApplyAsync(result -> {
|
||||||
try {
|
try {
|
||||||
return loginWithTokens(extractTokens(result));
|
if(result != null)
|
||||||
|
return loginWithTokens(extractTokens(result),true);
|
||||||
|
else return null;
|
||||||
} catch (MicrosoftAuthenticationException e) {
|
} catch (MicrosoftAuthenticationException e) {
|
||||||
throw new CompletionException(e);
|
throw new CompletionException(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}*/
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs in a player using a Microsoft account refresh token retrieved earlier.
|
* Logs in a player using a Microsoft account refresh token retrieved earlier.
|
||||||
*
|
*
|
||||||
* @param refreshToken Player Microsoft account refresh token
|
* @param refreshToken Player Microsoft account refresh token
|
||||||
*
|
|
||||||
* @return The player Minecraft profile
|
* @return The player Minecraft profile
|
||||||
*
|
|
||||||
* @throws MicrosoftAuthenticationException Thrown if one of the several HTTP requests failed at some point
|
* @throws MicrosoftAuthenticationException Thrown if one of the several HTTP requests failed at some point
|
||||||
*/
|
*/
|
||||||
public MicrosoftAuthResult loginWithRefreshToken(String refreshToken) throws MicrosoftAuthenticationException
|
public MicrosoftAuthResult loginWithRefreshToken(String refreshToken) throws MicrosoftAuthenticationException {
|
||||||
{
|
|
||||||
Map<String, String> params = getLoginParams();
|
Map<String, String> params = getLoginParams();
|
||||||
params.put("refresh_token", refreshToken);
|
params.put("refresh_token", refreshToken);
|
||||||
params.put("grant_type", "refresh_token");
|
params.put("grant_type", "refresh_token");
|
||||||
@ -210,7 +181,7 @@ public class MicrosoftAuthenticator
|
|||||||
params, MicrosoftRefreshResponse.class
|
params, MicrosoftRefreshResponse.class
|
||||||
);
|
);
|
||||||
|
|
||||||
return loginWithTokens(new AuthTokens(response.getAccessToken() , response.getRefreshToken()));
|
return loginWithTokens(new AuthTokens(response.getAccessToken(), response.getRefreshToken()),true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -218,13 +189,23 @@ public class MicrosoftAuthenticator
|
|||||||
* <b>If the token was retrieved using Azure AAD/MSAL, it should be prefixed with d=</b>
|
* <b>If the token was retrieved using Azure AAD/MSAL, it should be prefixed with d=</b>
|
||||||
*
|
*
|
||||||
* @param tokens Player Microsoft account tokens pair
|
* @param tokens Player Microsoft account tokens pair
|
||||||
*
|
|
||||||
* @return The player Minecraft profile
|
* @return The player Minecraft profile
|
||||||
*
|
|
||||||
* @throws MicrosoftAuthenticationException Thrown if one of the several HTTP requests failed at some point
|
* @throws MicrosoftAuthenticationException Thrown if one of the several HTTP requests failed at some point
|
||||||
*/
|
*/
|
||||||
public MicrosoftAuthResult loginWithTokens(AuthTokens tokens) throws MicrosoftAuthenticationException
|
public MicrosoftAuthResult loginWithTokens(AuthTokens tokens) throws MicrosoftAuthenticationException {
|
||||||
{
|
return loginWithTokens(tokens,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs in a player using a Microsoft account tokens retrieved earlier.
|
||||||
|
* <b>If the token was retrieved using Azure AAD/MSAL, it should be prefixed with d=</b>
|
||||||
|
*
|
||||||
|
* @param tokens Player Microsoft account tokens pair
|
||||||
|
* @param retrieveProfile Whether to retrieve the player profile
|
||||||
|
* @return The player Minecraft profile
|
||||||
|
* @throws MicrosoftAuthenticationException Thrown if one of the several HTTP requests failed at some point
|
||||||
|
*/
|
||||||
|
public MicrosoftAuthResult loginWithTokens(AuthTokens tokens, boolean retrieveProfile) throws MicrosoftAuthenticationException {
|
||||||
XboxLoginResponse xboxLiveResponse = xboxLiveLogin(tokens.getAccessToken());
|
XboxLoginResponse xboxLiveResponse = xboxLiveLogin(tokens.getAccessToken());
|
||||||
XboxLoginResponse xstsResponse = xstsLogin(xboxLiveResponse.getToken());
|
XboxLoginResponse xstsResponse = xstsLogin(xboxLiveResponse.getToken());
|
||||||
|
|
||||||
@ -239,19 +220,26 @@ public class MicrosoftAuthenticator
|
|||||||
if (Arrays.stream(storeResponse.getItems()).noneMatch(item -> item.getName().equals(MINECRAFT_STORE_IDENTIFIER))) {
|
if (Arrays.stream(storeResponse.getItems()).noneMatch(item -> item.getName().equals(MINECRAFT_STORE_IDENTIFIER))) {
|
||||||
throw new MicrosoftAuthenticationException("Player didn't buy Minecraft Java Edition or did not migrate its account");
|
throw new MicrosoftAuthenticationException("Player didn't buy Minecraft Java Edition or did not migrate its account");
|
||||||
}
|
}
|
||||||
|
MinecraftProfile profile = null;
|
||||||
|
if (retrieveProfile) {
|
||||||
|
profile = http.getJson(
|
||||||
|
MINECRAFT_PROFILE_ENDPOINT,
|
||||||
|
minecraftResponse.getAccessToken(),
|
||||||
|
MinecraftProfile.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
MinecraftProfile profile = http.getJson(
|
return new MicrosoftAuthResult(
|
||||||
MINECRAFT_PROFILE_ENDPOINT,
|
profile,
|
||||||
minecraftResponse.getAccessToken(),
|
minecraftResponse.getAccessToken(),
|
||||||
MinecraftProfile.class
|
tokens.getRefreshToken(),
|
||||||
|
xboxLiveResponse.getDisplayClaims().getUsers()[0].getUserHash(),
|
||||||
|
Base64.getEncoder().encodeToString(minecraftResponse.getUsername().getBytes())
|
||||||
);
|
);
|
||||||
|
|
||||||
return new MicrosoftAuthResult(profile, minecraftResponse.getAccessToken(), tokens.getRefreshToken());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected PreAuthData preAuthRequest() throws MicrosoftAuthenticationException
|
protected PreAuthData preAuthRequest() throws MicrosoftAuthenticationException {
|
||||||
{
|
|
||||||
Map<String, String> params = getLoginParams();
|
Map<String, String> params = getLoginParams();
|
||||||
params.put("display", "touch");
|
params.put("display", "touch");
|
||||||
params.put("locale", "en");
|
params.put("locale", "en");
|
||||||
@ -264,8 +252,7 @@ public class MicrosoftAuthenticator
|
|||||||
return new PreAuthData(ppft, urlPost);
|
return new PreAuthData(ppft, urlPost);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected XboxLoginResponse xboxLiveLogin(String accessToken) throws MicrosoftAuthenticationException
|
protected XboxLoginResponse xboxLiveLogin(String accessToken) throws MicrosoftAuthenticationException {
|
||||||
{
|
|
||||||
XboxLiveLoginProperties properties = new XboxLiveLoginProperties("RPS", XBOX_LIVE_AUTH_HOST, accessToken);
|
XboxLiveLoginProperties properties = new XboxLiveLoginProperties("RPS", XBOX_LIVE_AUTH_HOST, accessToken);
|
||||||
XboxLoginRequest<XboxLiveLoginProperties> request = new XboxLoginRequest<>(
|
XboxLoginRequest<XboxLiveLoginProperties> request = new XboxLoginRequest<>(
|
||||||
properties, XBOX_LIVE_AUTH_RELAY, "JWT"
|
properties, XBOX_LIVE_AUTH_RELAY, "JWT"
|
||||||
@ -274,9 +261,8 @@ public class MicrosoftAuthenticator
|
|||||||
return http.postJson(XBOX_LIVE_AUTHORIZATION_ENDPOINT, request, XboxLoginResponse.class);
|
return http.postJson(XBOX_LIVE_AUTHORIZATION_ENDPOINT, request, XboxLoginResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected XboxLoginResponse xstsLogin(String xboxLiveToken) throws MicrosoftAuthenticationException
|
protected XboxLoginResponse xstsLogin(String xboxLiveToken) throws MicrosoftAuthenticationException {
|
||||||
{
|
XSTSAuthorizationProperties properties = new XSTSAuthorizationProperties("RETAIL", new String[]{xboxLiveToken});
|
||||||
XSTSAuthorizationProperties properties = new XSTSAuthorizationProperties("RETAIL", new String[] { xboxLiveToken });
|
|
||||||
XboxLoginRequest<XSTSAuthorizationProperties> request = new XboxLoginRequest<>(
|
XboxLoginRequest<XSTSAuthorizationProperties> request = new XboxLoginRequest<>(
|
||||||
properties, MINECRAFT_AUTH_RELAY, "JWT"
|
properties, MINECRAFT_AUTH_RELAY, "JWT"
|
||||||
);
|
);
|
||||||
@ -284,15 +270,13 @@ public class MicrosoftAuthenticator
|
|||||||
return http.postJson(XSTS_AUTHORIZATION_ENDPOINT, request, XboxLoginResponse.class);
|
return http.postJson(XSTS_AUTHORIZATION_ENDPOINT, request, XboxLoginResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MinecraftLoginResponse minecraftLogin(String userHash, String xstsToken) throws MicrosoftAuthenticationException
|
protected MinecraftLoginResponse minecraftLogin(String userHash, String xstsToken) throws MicrosoftAuthenticationException {
|
||||||
{
|
|
||||||
MinecraftLoginRequest request = new MinecraftLoginRequest(String.format("XBL3.0 x=%s;%s", userHash, xstsToken));
|
MinecraftLoginRequest request = new MinecraftLoginRequest(String.format("XBL3.0 x=%s;%s", userHash, xstsToken));
|
||||||
return http.postJson(MINECRAFT_AUTH_ENDPOINT, request, MinecraftLoginResponse.class);
|
return http.postJson(MINECRAFT_AUTH_ENDPOINT, request, MinecraftLoginResponse.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected Map<String, String> getLoginParams()
|
protected Map<String, String> getLoginParams() {
|
||||||
{
|
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
params.put("client_id", XBOX_LIVE_CLIENT_ID);
|
params.put("client_id", XBOX_LIVE_CLIENT_ID);
|
||||||
params.put("redirect_uri", MICROSOFT_REDIRECTION_ENDPOINT);
|
params.put("redirect_uri", MICROSOFT_REDIRECTION_ENDPOINT);
|
||||||
@ -302,13 +286,11 @@ public class MicrosoftAuthenticator
|
|||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AuthTokens extractTokens(String url) throws MicrosoftAuthenticationException
|
protected AuthTokens extractTokens(String url) throws MicrosoftAuthenticationException {
|
||||||
{
|
|
||||||
return new AuthTokens(extractValue(url, "access_token"), extractValue(url, "refresh_token"));
|
return new AuthTokens(extractValue(url, "access_token"), extractValue(url, "refresh_token"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String extractValue(String url, String key) throws MicrosoftAuthenticationException
|
protected String extractValue(String url, String key) throws MicrosoftAuthenticationException {
|
||||||
{
|
|
||||||
String matched = match(key + "=([^&]*)", url);
|
String matched = match(key + "=([^&]*)", url);
|
||||||
if (matched == null) {
|
if (matched == null) {
|
||||||
throw new MicrosoftAuthenticationException("Invalid credentials or tokens");
|
throw new MicrosoftAuthenticationException("Invalid credentials or tokens");
|
||||||
@ -321,8 +303,7 @@ public class MicrosoftAuthenticator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String match(String regex, String content)
|
protected String match(String regex, String content) {
|
||||||
{
|
|
||||||
Matcher matcher = Pattern.compile(regex).matcher(content);
|
Matcher matcher = Pattern.compile(regex).matcher(content);
|
||||||
if (!matcher.find()) {
|
if (!matcher.find()) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,150 +0,0 @@
|
|||||||
package fr.litarvan.openauth.microsoft;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Thanks a lot to Mickaël Guessant for this trick
|
|
||||||
*
|
|
||||||
* https://github.com/mguessan
|
|
||||||
* https://github.com/mguessan/davmail/blob/master/src/java/davmail/exchange/auth/O365InteractiveAuthenticatorFrame.java
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.net.*;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HttpURLConnection Microsoft-patched wrapped
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* This class serves as HttpURLConnection, but actually wraps a real one and
|
|
||||||
* patch its input to disable Microsoft meta integrity check, which can fail
|
|
||||||
* on Java >=11 on non-macOS platforms.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @version 1.1.1
|
|
||||||
* @author Litarvan
|
|
||||||
*/
|
|
||||||
public class MicrosoftPatchedHttpURLConnection extends HttpURLConnection
|
|
||||||
{
|
|
||||||
private final HttpURLConnection inner;
|
|
||||||
|
|
||||||
public MicrosoftPatchedHttpURLConnection(URL url, HttpURLConnection inner)
|
|
||||||
{
|
|
||||||
super(url);
|
|
||||||
|
|
||||||
this.inner = inner;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setRequestMethod(String method) throws ProtocolException
|
|
||||||
{
|
|
||||||
this.inner.setRequestMethod(method);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setInstanceFollowRedirects(boolean followRedirects)
|
|
||||||
{
|
|
||||||
this.inner.setInstanceFollowRedirects(followRedirects);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getInstanceFollowRedirects()
|
|
||||||
{
|
|
||||||
return this.inner.getInstanceFollowRedirects();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRequestMethod()
|
|
||||||
{
|
|
||||||
return this.inner.getRequestMethod();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getResponseCode() throws IOException
|
|
||||||
{
|
|
||||||
return this.inner.getResponseCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getResponseMessage() throws IOException
|
|
||||||
{
|
|
||||||
return this.inner.getResponseMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, List<String>> getHeaderFields()
|
|
||||||
{
|
|
||||||
return this.inner.getHeaderFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHeaderField(String name)
|
|
||||||
{
|
|
||||||
return this.inner.getHeaderField(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHeaderField(int n)
|
|
||||||
{
|
|
||||||
return this.inner.getHeaderField(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disconnect()
|
|
||||||
{
|
|
||||||
this.inner.disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDoOutput(boolean dooutput)
|
|
||||||
{
|
|
||||||
this.inner.setDoOutput(dooutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean usingProxy()
|
|
||||||
{
|
|
||||||
return this.inner.usingProxy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void connect() throws IOException
|
|
||||||
{
|
|
||||||
this.inner.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getInputStream() throws IOException
|
|
||||||
{
|
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
|
||||||
try (InputStream in = this.inner.getInputStream()) {
|
|
||||||
int n;
|
|
||||||
byte[] data = new byte[8192];
|
|
||||||
|
|
||||||
while ((n = in.read(data, 0, data.length)) != -1) {
|
|
||||||
buffer.write(data, 0, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] patched = buffer
|
|
||||||
.toString("UTF-8")
|
|
||||||
.replaceAll("integrity ?=", "integrity.disabled=")
|
|
||||||
.replaceAll("setAttribute\\(\"integrity\"", "setAttribute(\"integrity.disabled\"")
|
|
||||||
.getBytes(StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
return new ByteArrayInputStream(patched);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public OutputStream getOutputStream() throws IOException
|
|
||||||
{
|
|
||||||
return this.inner.getOutputStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getErrorStream()
|
|
||||||
{
|
|
||||||
return this.inner.getErrorStream();
|
|
||||||
}
|
|
||||||
}
|
|
@ -197,6 +197,7 @@ import rip.athena.client.events.types.render.RenderType;
|
|||||||
import rip.athena.client.gui.menu.AthenaMenu;
|
import rip.athena.client.gui.menu.AthenaMenu;
|
||||||
import rip.athena.client.modules.impl.fpssettings.OptimizerMod;
|
import rip.athena.client.modules.impl.fpssettings.OptimizerMod;
|
||||||
import rip.athena.client.modules.impl.mods.HitDelayFix;
|
import rip.athena.client.modules.impl.mods.HitDelayFix;
|
||||||
|
import rip.athena.client.modules.impl.render.MotionBlur;
|
||||||
|
|
||||||
public class Minecraft implements IThreadListener, IPlayerUsage
|
public class Minecraft implements IThreadListener, IPlayerUsage
|
||||||
{
|
{
|
||||||
@ -325,7 +326,7 @@ public class Minecraft implements IThreadListener, IPlayerUsage
|
|||||||
private IReloadableResourceManager mcResourceManager;
|
private IReloadableResourceManager mcResourceManager;
|
||||||
public final IMetadataSerializer metadataSerializer_ = new IMetadataSerializer();
|
public final IMetadataSerializer metadataSerializer_ = new IMetadataSerializer();
|
||||||
private final List<IResourcePack> defaultResourcePacks = Lists.<IResourcePack>newArrayList();
|
private final List<IResourcePack> defaultResourcePacks = Lists.<IResourcePack>newArrayList();
|
||||||
private final DefaultResourcePack mcDefaultResourcePack;
|
public final DefaultResourcePack mcDefaultResourcePack;
|
||||||
private ResourcePackRepository mcResourcePackRepository;
|
private ResourcePackRepository mcResourcePackRepository;
|
||||||
private LanguageManager mcLanguageManager;
|
private LanguageManager mcLanguageManager;
|
||||||
private IStream stream;
|
private IStream stream;
|
||||||
@ -1224,6 +1225,11 @@ public class Minecraft implements IThreadListener, IPlayerUsage
|
|||||||
|
|
||||||
public void updateDisplay()
|
public void updateDisplay()
|
||||||
{
|
{
|
||||||
|
if(Athena.INSTANCE.getModuleManager().get(MotionBlur.class).isToggled()) {
|
||||||
|
if(Minecraft.getMinecraft().thePlayer != null) {
|
||||||
|
MotionBlur.createAccumulation();
|
||||||
|
}
|
||||||
|
}
|
||||||
this.mcProfiler.startSection("display_update");
|
this.mcProfiler.startSection("display_update");
|
||||||
Display.update();
|
Display.update();
|
||||||
this.mcProfiler.endSection();
|
this.mcProfiler.endSection();
|
||||||
|
@ -23,16 +23,19 @@ import optifine.HttpResponse;
|
|||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import rip.athena.client.Athena;
|
||||||
|
import rip.athena.client.modules.impl.fpssettings.OptimizerMod;
|
||||||
|
import rip.athena.client.modules.impl.fpssettings.impl.ThreadDownloadImageDataHook;
|
||||||
|
|
||||||
public class ThreadDownloadImageData extends SimpleTexture
|
public class ThreadDownloadImageData extends SimpleTexture
|
||||||
{
|
{
|
||||||
private static final Logger logger = LogManager.getLogger();
|
public static final Logger logger = LogManager.getLogger();
|
||||||
private static final AtomicInteger threadDownloadCounter = new AtomicInteger(0);
|
private static final AtomicInteger threadDownloadCounter = new AtomicInteger(0);
|
||||||
private final File cacheFile;
|
public final File cacheFile;
|
||||||
private final String imageUrl;
|
private final String imageUrl;
|
||||||
private final IImageBuffer imageBuffer;
|
public final IImageBuffer imageBuffer;
|
||||||
private BufferedImage bufferedImage;
|
public BufferedImage bufferedImage;
|
||||||
private Thread imageThread;
|
public Thread imageThread;
|
||||||
private boolean textureUploaded;
|
private boolean textureUploaded;
|
||||||
private static final String __OBFID = "CL_00001049";
|
private static final String __OBFID = "CL_00001049";
|
||||||
public Boolean imageFound = null;
|
public Boolean imageFound = null;
|
||||||
@ -83,9 +86,21 @@ public class ThreadDownloadImageData extends SimpleTexture
|
|||||||
{
|
{
|
||||||
if (this.bufferedImage == null && this.textureLocation != null)
|
if (this.bufferedImage == null && this.textureLocation != null)
|
||||||
{
|
{
|
||||||
|
OptimizerMod mod = (OptimizerMod) Athena.INSTANCE.getModuleManager().get(OptimizerMod.class);
|
||||||
|
|
||||||
|
if(mod.BETTER_SKIN_LOADING) {
|
||||||
|
ThreadDownloadImageDataHook.getImprovedCacheLoading(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
super.loadTexture(resourceManager);
|
super.loadTexture(resourceManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*if (this.bufferedImage == null && this.textureLocation != null)
|
||||||
|
{
|
||||||
|
super.loadTexture(resourceManager);
|
||||||
|
}*/
|
||||||
|
|
||||||
if (this.imageThread == null)
|
if (this.imageThread == null)
|
||||||
{
|
{
|
||||||
if (this.cacheFile != null && this.cacheFile.isFile())
|
if (this.cacheFile != null && this.cacheFile.isFile())
|
||||||
@ -116,7 +131,7 @@ public class ThreadDownloadImageData extends SimpleTexture
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void loadTextureFromServer()
|
public void loadTextureFromServer()
|
||||||
{
|
{
|
||||||
this.imageThread = new Thread("Texture Downloader #" + threadDownloadCounter.incrementAndGet())
|
this.imageThread = new Thread("Texture Downloader #" + threadDownloadCounter.incrementAndGet())
|
||||||
{
|
{
|
||||||
|
@ -10,8 +10,10 @@ import net.minecraft.item.Item;
|
|||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.MathHelper;
|
import net.minecraft.util.MathHelper;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
import rip.athena.client.Athena;
|
import rip.athena.client.Athena;
|
||||||
import rip.athena.client.modules.impl.fpssettings.OptimizerMod;
|
import rip.athena.client.modules.impl.fpssettings.OptimizerMod;
|
||||||
|
import rip.athena.client.modules.impl.mods.ItemPhysics;
|
||||||
|
|
||||||
public class RenderEntityItem extends Render<EntityItem>
|
public class RenderEntityItem extends Render<EntityItem>
|
||||||
{
|
{
|
||||||
@ -115,6 +117,13 @@ public class RenderEntityItem extends Render<EntityItem>
|
|||||||
IBakedModel ibakedmodel = this.itemRenderer.getItemModelMesher().getItemModel(itemstack);
|
IBakedModel ibakedmodel = this.itemRenderer.getItemModelMesher().getItemModel(itemstack);
|
||||||
int i = this.func_177077_a(entity, x, y, z, partialTicks, ibakedmodel);
|
int i = this.func_177077_a(entity, x, y, z, partialTicks, ibakedmodel);
|
||||||
|
|
||||||
|
int rotation = (int) (((System.nanoTime() / 3000000) + entity.getEntityId() * 10000) % 360);
|
||||||
|
if(Athena.INSTANCE.getModuleManager().get(ItemPhysics.class).isToggled()) {
|
||||||
|
if (entity.onGround) rotation = 90;
|
||||||
|
GL11.glRotatef(rotation / 2, 0, 1, 0);
|
||||||
|
GL11.glRotatef(rotation, 1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < i; ++j)
|
for (int j = 0; j < i; ++j)
|
||||||
{
|
{
|
||||||
if (ibakedmodel.isGui3d())
|
if (ibakedmodel.isGui3d())
|
||||||
|
@ -35,6 +35,9 @@ import optifine.Config;
|
|||||||
import optifine.ConnectedTextures;
|
import optifine.ConnectedTextures;
|
||||||
import optifine.Reflector;
|
import optifine.Reflector;
|
||||||
import optifine.TextureUtils;
|
import optifine.TextureUtils;
|
||||||
|
import rip.athena.client.Athena;
|
||||||
|
import rip.athena.client.events.types.client.ClientTickEvent;
|
||||||
|
import rip.athena.client.events.types.client.SwitchTextureEvent;
|
||||||
import shadersmod.client.ShadersTex;
|
import shadersmod.client.ShadersTex;
|
||||||
|
|
||||||
public class TextureMap extends AbstractTexture implements ITickableTextureObject
|
public class TextureMap extends AbstractTexture implements ITickableTextureObject
|
||||||
@ -139,6 +142,10 @@ public class TextureMap extends AbstractTexture implements ITickableTextureObjec
|
|||||||
|
|
||||||
public void loadTextureAtlas(IResourceManager resourceManager)
|
public void loadTextureAtlas(IResourceManager resourceManager)
|
||||||
{
|
{
|
||||||
|
if(!Athena.INSTANCE.getEventBus().post(new SwitchTextureEvent())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Config.dbg("Multitexture: " + Config.isMultiTexture());
|
Config.dbg("Multitexture: " + Config.isMultiTexture());
|
||||||
|
|
||||||
if (Config.isMultiTexture())
|
if (Config.isMultiTexture())
|
||||||
|
@ -5,6 +5,8 @@ import net.minecraft.client.renderer.GlStateManager;
|
|||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.tileentity.MobSpawnerBaseLogic;
|
import net.minecraft.tileentity.MobSpawnerBaseLogic;
|
||||||
import net.minecraft.tileentity.TileEntityMobSpawner;
|
import net.minecraft.tileentity.TileEntityMobSpawner;
|
||||||
|
import rip.athena.client.Athena;
|
||||||
|
import rip.athena.client.modules.impl.fpssettings.OptimizerMod;
|
||||||
|
|
||||||
public class TileEntityMobSpawnerRenderer extends TileEntitySpecialRenderer<TileEntityMobSpawner>
|
public class TileEntityMobSpawnerRenderer extends TileEntitySpecialRenderer<TileEntityMobSpawner>
|
||||||
{
|
{
|
||||||
@ -21,6 +23,9 @@ public class TileEntityMobSpawnerRenderer extends TileEntitySpecialRenderer<Tile
|
|||||||
*/
|
*/
|
||||||
public static void renderMob(MobSpawnerBaseLogic mobSpawnerLogic, double posX, double posY, double posZ, float partialTicks)
|
public static void renderMob(MobSpawnerBaseLogic mobSpawnerLogic, double posX, double posY, double posZ, float partialTicks)
|
||||||
{
|
{
|
||||||
|
OptimizerMod mod = (OptimizerMod) Athena.INSTANCE.getModuleManager().get(OptimizerMod.class);
|
||||||
|
if(mod.REMOVE_ENTITY_SPAWNER) return;
|
||||||
|
|
||||||
Entity entity = mobSpawnerLogic.func_180612_a(mobSpawnerLogic.getSpawnerWorld());
|
Entity entity = mobSpawnerLogic.func_180612_a(mobSpawnerLogic.getSpawnerWorld());
|
||||||
|
|
||||||
if (entity != null)
|
if (entity != null)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package net.minecraft.world.storage;
|
package net.minecraft.world.storage;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import io.netty.handler.codec.http.multipart.AbstractHttpData;
|
||||||
import net.minecraft.crash.CrashReportCategory;
|
import net.minecraft.crash.CrashReportCategory;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
@ -9,6 +11,8 @@ import net.minecraft.world.EnumDifficulty;
|
|||||||
import net.minecraft.world.GameRules;
|
import net.minecraft.world.GameRules;
|
||||||
import net.minecraft.world.WorldSettings;
|
import net.minecraft.world.WorldSettings;
|
||||||
import net.minecraft.world.WorldType;
|
import net.minecraft.world.WorldType;
|
||||||
|
import rip.athena.client.Athena;
|
||||||
|
import rip.athena.client.modules.impl.render.TimeChanger;
|
||||||
|
|
||||||
public class WorldInfo
|
public class WorldInfo
|
||||||
{
|
{
|
||||||
@ -411,7 +415,9 @@ public class WorldInfo
|
|||||||
*/
|
*/
|
||||||
public long getWorldTime()
|
public long getWorldTime()
|
||||||
{
|
{
|
||||||
return this.worldTime;
|
TimeChanger mod = (TimeChanger) Athena.INSTANCE.getModuleManager().get(TimeChanger.class);
|
||||||
|
|
||||||
|
return mod.isToggled() ? mod.time : this.worldTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getSizeOnDisk()
|
public long getSizeOnDisk()
|
||||||
|
@ -18,6 +18,7 @@ import rip.athena.client.modules.impl.other.AimTrainer;
|
|||||||
import rip.athena.client.requests.ContentType;
|
import rip.athena.client.requests.ContentType;
|
||||||
import rip.athena.client.requests.WebRequest;
|
import rip.athena.client.requests.WebRequest;
|
||||||
import rip.athena.client.requests.WebRequestResult;
|
import rip.athena.client.requests.WebRequestResult;
|
||||||
|
import rip.athena.client.server.CosmeticsClient;
|
||||||
import rip.athena.client.socket.SocketClient;
|
import rip.athena.client.socket.SocketClient;
|
||||||
import rip.athena.client.theme.ThemeManager;
|
import rip.athena.client.theme.ThemeManager;
|
||||||
import rip.athena.client.utils.PrefixedLogger;
|
import rip.athena.client.utils.PrefixedLogger;
|
||||||
@ -28,6 +29,7 @@ import javax.swing.*;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
@ -78,8 +80,12 @@ public class Athena {
|
|||||||
* connections with servers or other systems.
|
* connections with servers or other systems.
|
||||||
*/
|
*/
|
||||||
public void initClient() {
|
public void initClient() {
|
||||||
this.discordRPC = new DiscordRPC();
|
String os = System.getProperty("os.name");
|
||||||
|
|
||||||
|
if (os.toLowerCase().contains("win")) {
|
||||||
|
this.discordRPC = new DiscordRPC();
|
||||||
|
}
|
||||||
|
|
||||||
if(!MAIN_DIR.exists()) {
|
if(!MAIN_DIR.exists()) {
|
||||||
MAIN_DIR.mkdir();
|
MAIN_DIR.mkdir();
|
||||||
}
|
}
|
||||||
@ -93,7 +99,7 @@ public class Athena {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(SocketClient.isClientRunning()) {
|
if(SocketClient.isClientRunning()) {
|
||||||
JOptionPane.showMessageDialog(null, "Port 1337 already in use.");
|
JOptionPane.showMessageDialog(null, "Port 45376 already in use.");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package rip.athena.client.cosmetics;/**
|
||||||
|
* @project Athena-Client
|
||||||
|
* @author Athena Development
|
||||||
|
* @date 6/12/2023
|
||||||
|
*/
|
||||||
|
public class CosmeticsController {
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package rip.athena.client.events.types.client;
|
||||||
|
|
||||||
|
import rip.athena.client.events.Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Athena Development
|
||||||
|
* @project Athena-Client
|
||||||
|
* @date 6/12/2023
|
||||||
|
*/
|
||||||
|
public class SwitchTextureEvent extends Event {
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package rip.athena.client.gui.clickgui.components.mods;
|
package rip.athena.client.gui.clickgui.components.mods;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import rip.athena.client.Athena;
|
import rip.athena.client.Athena;
|
||||||
import rip.athena.client.font.FontManager;
|
import rip.athena.client.font.FontManager;
|
||||||
@ -53,40 +54,25 @@ public class CategoryButton extends MenuButton {
|
|||||||
int y = this.getRenderY();
|
int y = this.getRenderY();
|
||||||
int width = (this.width == -1 && this.height == -1) ? (getStringWidth(text) + minOffset * 2) : this.width;
|
int width = (this.width == -1 && this.height == -1) ? (getStringWidth(text) + minOffset * 2) : this.width;
|
||||||
int height = (this.width == -1 && this.height == -1) ? (getStringHeight(text) + minOffset * 2) : this.height;
|
int height = (this.width == -1 && this.height == -1) ? (getStringHeight(text) + minOffset * 2) : this.height;
|
||||||
|
|
||||||
int backgroundColor = getColor(DrawType.BACKGROUND, lastState);
|
|
||||||
int textColor = getColor(DrawType.TEXT, lastState);
|
|
||||||
|
|
||||||
//RoundedUtils.drawRoundedRect(x + 9, y - 1, x + width - 19, y + height + 1, 12, new Color(50,50,50,255).getRGB());
|
|
||||||
if(isActive()) {
|
if(isActive()) {
|
||||||
RoundedUtils.drawGradientRound(x + 30, y, width - 40, height, 12, Athena.INSTANCE.getThemeManager().getTheme().getFirstColor(), Athena.INSTANCE.getThemeManager().getTheme().getFirstColor(), Athena.INSTANCE.getThemeManager().getTheme().getSecondColor(), Athena.INSTANCE.getThemeManager().getTheme().getSecondColor());
|
RoundedUtils.drawGradientRound(x + 30, y, width - 40, height, 12, Athena.INSTANCE.getThemeManager().getTheme().getFirstColor(), Athena.INSTANCE.getThemeManager().getTheme().getFirstColor(), Athena.INSTANCE.getThemeManager().getTheme().getSecondColor(), Athena.INSTANCE.getThemeManager().getTheme().getSecondColor());
|
||||||
//RoundedUtils.drawRoundedRect(x + 29, y - 1, x + width - 19, y + height + 1, 12, new Color(50, 50, 50, 255).getRGB());
|
|
||||||
//RoundedUtils.drawRoundedRect(x + 30, y, x + width - 20, y + height, 12, new Color(25,25,25,255).getRGB());
|
|
||||||
}
|
}
|
||||||
if(Settings.customGuiFont) {
|
if(Settings.customGuiFont) {
|
||||||
rip.athena.client.utils.font.FontManager.getNunitoBold(20).drawString(text, x + 70, y + height / 2 - (getStringHeight(text) / 2) + 2, Athena.INSTANCE.getThemeManager().getPrimaryTheme().getTextColor());
|
rip.athena.client.utils.font.FontManager.getNunitoBold(25).drawString(text, x + 70, y + height / 2 - (getStringHeight(text) / 2) + 2, Athena.INSTANCE.getThemeManager().getPrimaryTheme().getTextColor());
|
||||||
} else {
|
} else {
|
||||||
Minecraft.getMinecraft().fontRendererObj.drawString(text, x + (width / 2 - getStringWidth(text) / 2), y + height / 2 - (getStringHeight(text) / 2), Athena.INSTANCE.getThemeManager().getPrimaryTheme().getTextColor());
|
Minecraft.getMinecraft().fontRendererObj.drawString(text, x + (width / 2 - getStringWidth(text) / 2), y + height / 2 - (getStringHeight(text) / 2), Athena.INSTANCE.getThemeManager().getPrimaryTheme().getTextColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawUtils.drawImage(image, x + 35, y + 3, 25, 25);
|
DrawUtils.drawImage(image, x + 35, y + 3, 25, 25);
|
||||||
/*
|
|
||||||
if(Settings.customGuiFont) {
|
|
||||||
rip.athena.client.utils.font.FontManager.getProductSansRegular(30).drawString(text, x + (width / 2 - getStringWidth(text) / 2), y + height / 2 - (getStringHeight(text) / 2) - 3, textColor);
|
|
||||||
} else {
|
|
||||||
Minecraft.getMinecraft().fontRendererObj.drawString(text, x + (width / 2 - getStringWidth(text) / 2), y + height / 2 - (getStringHeight(text) / 2) - 3, textColor);
|
|
||||||
}
|
|
||||||
if(isActive()) {
|
|
||||||
drawHorizontalLine(x + (width / 2 - getStringWidth(text) / 2), y + 29, (int)Minecraft.getMinecraft().fontRendererObj.getStringWidth(text), 2, textColor);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
mouseDown = false;
|
mouseDown = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getStringWidth(String string) {
|
public int getStringWidth(String string) {
|
||||||
if(Settings.customGuiFont) {
|
if(Settings.customGuiFont) {
|
||||||
return (int) rip.athena.client.utils.font.FontManager.getNunitoBold(20).width(string);
|
return (int) rip.athena.client.utils.font.FontManager.getNunitoBold(25).width(string);
|
||||||
} else {
|
} else {
|
||||||
return Minecraft.getMinecraft().fontRendererObj.getStringWidth(string);
|
return Minecraft.getMinecraft().fontRendererObj.getStringWidth(string);
|
||||||
}
|
}
|
||||||
@ -95,7 +81,7 @@ public class CategoryButton extends MenuButton {
|
|||||||
@Override
|
@Override
|
||||||
public int getStringHeight(String string) {
|
public int getStringHeight(String string) {
|
||||||
if(Settings.customGuiFont) {
|
if(Settings.customGuiFont) {
|
||||||
return (int) rip.athena.client.utils.font.FontManager.getNunitoBold(20).height();
|
return (int) rip.athena.client.utils.font.FontManager.getNunitoBold(25).height();
|
||||||
} else {
|
} else {
|
||||||
return Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT;
|
return Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT;
|
||||||
}
|
}
|
||||||
|
@ -404,4 +404,4 @@ public class GuiAccountManager extends GuiScreen {
|
|||||||
|
|
||||||
return this.faceTexture;
|
return this.faceTexture;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -40,6 +40,7 @@ public class LoginPanel extends Panel {
|
|||||||
setHeight(200);
|
setHeight(200);
|
||||||
actionButtons.add(new AltButton("Cracked"));
|
actionButtons.add(new AltButton("Cracked"));
|
||||||
actionButtons.add(new AltButton("Session"));
|
actionButtons.add(new AltButton("Session"));
|
||||||
|
actionButtons.add(new AltButton("Login"));
|
||||||
textFields.add(new TextField());
|
textFields.add(new TextField());
|
||||||
textFields.add(new TextField());
|
textFields.add(new TextField());
|
||||||
}
|
}
|
||||||
@ -172,9 +173,7 @@ public class LoginPanel extends Panel {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
actionButton.drawScreen(mouseX, mouseY);
|
actionButton.drawScreen(mouseX, mouseY);
|
||||||
|
|
||||||
seperation += actionWidth + buttonSpacing;
|
seperation += actionWidth + buttonSpacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,18 +198,39 @@ public class LoginPanel extends Panel {
|
|||||||
actionButtons.forEach(actionButton -> actionButton.mouseClicked(mouseX, mouseY, button));
|
actionButtons.forEach(actionButton -> actionButton.mouseClicked(mouseX, mouseY, button));
|
||||||
|
|
||||||
if (hoveringMicrosoft && button == 0) {
|
if (hoveringMicrosoft && button == 0) {
|
||||||
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
MicrosoftAuthenticator authenticator = new MicrosoftAuthenticator();
|
MicrosoftAuthenticator authenticator = new MicrosoftAuthenticator();
|
||||||
/*try {
|
|
||||||
MicrosoftAuthResult acc = authenticator.loginWithWebview();
|
TextField username = textFields.get(0);
|
||||||
Athena.INSTANCE.getAccountManager().getAccounts().add(new Account(AccountType.MICROSOFT, acc.getProfile().getName(), acc.getProfile().getId(), acc.getRefreshToken()));
|
String email = username.getText();
|
||||||
|
String password = textFields.get(1).getText();
|
||||||
|
if (email.contains(":")) {
|
||||||
|
String[] split = email.split(":");
|
||||||
|
if (split.length != 2) return;
|
||||||
|
email = split[0];
|
||||||
|
password = split[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Athena.INSTANCE.getLog().info(email + password);
|
||||||
|
MicrosoftAuthResult acc = authenticator.loginWithCredentials(email, password);
|
||||||
|
|
||||||
Minecraft.getMinecraft().session = new Session(acc.getProfile().getName(), acc.getProfile().getId(), acc.getAccessToken(), "legacy");
|
Minecraft.getMinecraft().session = new Session(acc.getProfile().getName(), acc.getProfile().getId(), acc.getAccessToken(), "legacy");
|
||||||
|
|
||||||
|
status = "Logged into " + acc.getProfile().getName();
|
||||||
|
Athena.INSTANCE.getAccountManager().getAccounts().add(new Account(AccountType.MICROSOFT, acc.getProfile().getName(), acc.getProfile().getId(), acc.getRefreshToken()));
|
||||||
|
Athena.INSTANCE.getAccountManager().setCurrentAccount(Athena.INSTANCE.getAccountManager().getAccountByUsername(acc.getProfile().getName()));
|
||||||
Athena.INSTANCE.getAccountManager().isFirstLogin = false;
|
Athena.INSTANCE.getAccountManager().isFirstLogin = false;
|
||||||
|
Athena.INSTANCE.getAccountManager().save();
|
||||||
|
Athena.INSTANCE.getLog().info("Success: Logged into " + acc.getProfile().getName());
|
||||||
|
|
||||||
} catch (MicrosoftAuthenticationException e) {
|
} catch (MicrosoftAuthenticationException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
resetTextFields();
|
||||||
}).start();
|
}).start();
|
||||||
resetTextFields();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,16 +19,6 @@ public class OptimizerMod extends Module {
|
|||||||
public boolean DONT_CULL_PLAYER_NAMETAGS = true;
|
public boolean DONT_CULL_PLAYER_NAMETAGS = true;
|
||||||
public boolean DONT_CULL_ENTITY_NAMETAGS = true;
|
public boolean DONT_CULL_ENTITY_NAMETAGS = true;
|
||||||
public boolean DONT_CULL_ARMOR_STANDS_NAMETAGS = true;
|
public boolean DONT_CULL_ARMOR_STANDS_NAMETAGS = true;
|
||||||
public boolean PARTICLE_CULLING = true;
|
|
||||||
public boolean ITEM_SEARCHING = true;
|
|
||||||
public boolean OPTIMISED_ITEM_RENDERER = true;
|
|
||||||
public boolean OPTIMISED_FONT_RENDERER = true;
|
|
||||||
public boolean CACHED_FONT_DATA = true;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Low animation tick", description = "Renders animations slower for better performance.")
|
|
||||||
public boolean LOW_ANIMATION_TICK = true;
|
|
||||||
public boolean BATCH_MODEL_RENDERING = true;
|
|
||||||
public boolean DISABLE_GL_ERROR_CHECKING = true;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Static particle color", description = "Makes particles render at full brightness.")
|
@ConfigValue.Boolean(name = "Static particle color", description = "Makes particles render at full brightness.")
|
||||||
public boolean STATIC_PARTICLE_COLOR = true;
|
public boolean STATIC_PARTICLE_COLOR = true;
|
||||||
@ -45,12 +35,6 @@ public class OptimizerMod extends Module {
|
|||||||
@ConfigValue.Integer(name = "Chunk updates per second", description = "Lower value, better fps.", min = 1, max = 250)
|
@ConfigValue.Integer(name = "Chunk updates per second", description = "Lower value, better fps.", min = 1, max = 250)
|
||||||
public int CHUNK_UPDATE_LIMITER = 50;
|
public int CHUNK_UPDATE_LIMITER = 50;
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Remove text shadows", description = "Removes all text shadows.")
|
|
||||||
public boolean REMOVE_TEXT_SHADOWS= false;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Remove chat background", description = "Removes the chat background.")
|
|
||||||
public boolean REMOVE_CHAT_BACKGROUND = false;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Remove mob spawner entity", description = "Removes the spinning entity inside of mob spawners.")
|
@ConfigValue.Boolean(name = "Remove mob spawner entity", description = "Removes the spinning entity inside of mob spawners.")
|
||||||
public boolean REMOVE_ENTITY_SPAWNER = true;
|
public boolean REMOVE_ENTITY_SPAWNER = true;
|
||||||
|
|
||||||
@ -58,33 +42,9 @@ public class OptimizerMod extends Module {
|
|||||||
public boolean STATIC_DROPS = true;
|
public boolean STATIC_DROPS = true;
|
||||||
public boolean FAST_WORLD_LOADING = true;
|
public boolean FAST_WORLD_LOADING = true;
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Remove item glint", description = "Removes the enchantment glint from all items.")
|
|
||||||
public boolean REMOVE_ITEM_GLINT = true;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Remove Piston Extentions", description = "Removes Piston Extentions Animation.")
|
|
||||||
public static boolean REMOVE_PISTON_EXTENTION = false;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Disable TNT Flashing", description = "Disables Prime TNT Flashing to help FPS")
|
|
||||||
public boolean noLagTNTFlash = true;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Remove TNT", description = "Removes all primed tnt blocks.")
|
|
||||||
public boolean REMOVE_TNT = false;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Disable TNT Expand", description = "Disables Prime TNT Expanding to help FPS")
|
|
||||||
public boolean noLagTNTExpand = true;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Merge TNT", description = "If Prime TNT is in the same block, render it as 1 Prime TNT")
|
|
||||||
public boolean noLagStackTNT = true;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Holograms Render", description = "Disables the render of holograms")
|
|
||||||
public boolean noLagHolograms = true;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Custom Cane Renderer", description = "Only render cane in a certain radius to help FPS")
|
@ConfigValue.Boolean(name = "Custom Cane Renderer", description = "Only render cane in a certain radius to help FPS")
|
||||||
public boolean noLagCane = false;
|
public boolean noLagCane = false;
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Liquid Vision", description = "Makes it clear in water an lava")
|
|
||||||
public boolean noLagLiquidVision = false;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Remove Water", description = "Removes the render of water")
|
@ConfigValue.Boolean(name = "Remove Water", description = "Removes the render of water")
|
||||||
public static boolean noLagClearWater = false;
|
public static boolean noLagClearWater = false;
|
||||||
|
|
||||||
@ -94,9 +54,6 @@ public class OptimizerMod extends Module {
|
|||||||
@ConfigValue.Integer(name = "Entity Render Distance", min = 1, max = 64)
|
@ConfigValue.Integer(name = "Entity Render Distance", min = 1, max = 64)
|
||||||
public int noLagEntityDistance = 32;
|
public int noLagEntityDistance = 32;
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Disable fog", description = "Disables fog")
|
|
||||||
public boolean noFog = true;
|
|
||||||
|
|
||||||
@ConfigValue.Boolean(name = "Better Chests", description = "Disable render of knob/lid/reduce size of chests")
|
@ConfigValue.Boolean(name = "Better Chests", description = "Disable render of knob/lid/reduce size of chests")
|
||||||
public boolean noBetterChests = false;
|
public boolean noBetterChests = false;
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ public class EntityCulling {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void tick(ClientTickEvent event) {
|
public void onTick(ClientTickEvent event) {
|
||||||
WorldClient theWorld = Minecraft.getMinecraft().theWorld;
|
WorldClient theWorld = Minecraft.getMinecraft().theWorld;
|
||||||
if (theWorld == null)
|
if (theWorld == null)
|
||||||
return;
|
return;
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
package rip.athena.client.modules.impl.fpssettings.impl;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.ThreadDownloadImageData;
|
||||||
|
import net.minecraft.client.renderer.texture.SimpleTexture;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ThreadDownloadImageDataHook extends SimpleTexture {
|
||||||
|
public ThreadDownloadImageDataHook(ResourceLocation textureResourceLocation) {
|
||||||
|
super(textureResourceLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void getImprovedCacheLoading(ThreadDownloadImageData data) {
|
||||||
|
new Thread(() -> {
|
||||||
|
if (data.imageThread == null) {
|
||||||
|
if (data.cacheFile != null && data.cacheFile.isFile()) {
|
||||||
|
ThreadDownloadImageData.logger.debug("Loading http texture from local cache ({})",
|
||||||
|
new Object[] { data.cacheFile });
|
||||||
|
try {
|
||||||
|
data.bufferedImage = ImageIO.read(data.cacheFile);
|
||||||
|
if (data.imageBuffer != null) {
|
||||||
|
data.setBufferedImage(data.imageBuffer.parseUserSkin(data.bufferedImage));
|
||||||
|
}
|
||||||
|
} catch (IOException ioexception) {
|
||||||
|
ThreadDownloadImageData.logger.error("Couldn't load skin " + data.cacheFile, ioexception);
|
||||||
|
data.loadTextureFromServer();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data.loadTextureFromServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package rip.athena.client.modules.impl.mods;
|
||||||
|
|
||||||
|
import rip.athena.client.modules.Category;
|
||||||
|
import rip.athena.client.modules.Module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Athena Development
|
||||||
|
* @project Athena-Client
|
||||||
|
* @date 6/12/2023
|
||||||
|
*/
|
||||||
|
public class ItemPhysics extends Module {
|
||||||
|
|
||||||
|
public ItemPhysics() {
|
||||||
|
super("ItemPhysics", Category.MODS);
|
||||||
|
}
|
||||||
|
}
|
@ -71,7 +71,7 @@ public class FPSMod extends Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
if (this.mc.gameSettings.showDebugInfo) {
|
if (mc.gameSettings.showDebugInfo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,16 +43,49 @@ import static net.minecraft.client.resources.SimpleReloadableResourceManager.dom
|
|||||||
*/
|
*/
|
||||||
public class MotionBlur extends Module {
|
public class MotionBlur extends Module {
|
||||||
|
|
||||||
@ConfigValue.Double(name = "Blur Amount", min = 1.0, max = 10)
|
@ConfigValue.Integer(name = "Amount", min = 1, max = 10)
|
||||||
private double amount = 2.0D;
|
public static int amount = 1;
|
||||||
|
|
||||||
|
public static float f;
|
||||||
|
|
||||||
public MotionBlur() {
|
public MotionBlur() {
|
||||||
super("Motion Blur", Category.RENDER, "Athena/gui/mods/motionblur.png");
|
super("Motion Blur", Category.RENDER, "Athena/gui/mods/motionblur.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
public static void createAccumulation() {
|
||||||
public void onRender(RenderEvent event) {
|
float f = getAccumulationValue();
|
||||||
|
GL11.glAccum(GL11.GL_MULT, f);
|
||||||
|
GL11.glAccum(GL11.GL_ACCUM, 1.0F - f);
|
||||||
|
GL11.glAccum(GL11.GL_RETURN, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getMultiplier() {
|
||||||
|
return amount * 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getAccumulationValue() {
|
||||||
|
f = getMultiplier() * 10.0F;
|
||||||
|
long lastTimestampInGame = System.currentTimeMillis();
|
||||||
|
|
||||||
|
if (f > 996.0F) {
|
||||||
|
f = 996.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f > 990.0F) {
|
||||||
|
f = 990.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
long i = System.currentTimeMillis() - lastTimestampInGame;
|
||||||
|
|
||||||
|
if (i > 10000L) {
|
||||||
|
return 0.0F;
|
||||||
|
} else {
|
||||||
|
if (f < 0.0F) {
|
||||||
|
f = 0.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
return f / 1000.0F;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,190 @@
|
|||||||
|
package rip.athena.client.modules.impl.render;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureUtil;
|
||||||
|
import net.minecraft.client.resources.IResourcePack;
|
||||||
|
import net.minecraft.client.resources.ResourcePackRepository;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import rip.athena.client.Athena;
|
||||||
|
import rip.athena.client.config.ConfigValue;
|
||||||
|
import rip.athena.client.events.SubscribeEvent;
|
||||||
|
import rip.athena.client.events.types.client.SwitchTextureEvent;
|
||||||
|
import rip.athena.client.font.FontManager;
|
||||||
|
import rip.athena.client.gui.hud.HUDElement;
|
||||||
|
import rip.athena.client.modules.Category;
|
||||||
|
import rip.athena.client.modules.Module;
|
||||||
|
import rip.athena.client.utils.render.ColorUtil;
|
||||||
|
import rip.athena.client.utils.render.DrawUtils;
|
||||||
|
import rip.athena.client.utils.render.RoundedUtils;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Athena Development
|
||||||
|
* @project Athena-Client
|
||||||
|
* @date 6/12/2023
|
||||||
|
*/
|
||||||
|
public class PackDisplay extends Module {
|
||||||
|
|
||||||
|
@ConfigValue.List(name = "Display Mode", values = {"Circle", "Modern", "Fade", "Old"}, description = "Chose display of background")
|
||||||
|
private String backgroundMode = "Circle";
|
||||||
|
|
||||||
|
@ConfigValue.Boolean(name = "Background")
|
||||||
|
private boolean backGround = true;
|
||||||
|
|
||||||
|
@ConfigValue.Color(name = "Background Color")
|
||||||
|
private Color background = new Color(0, 0, 0, 150);
|
||||||
|
|
||||||
|
@ConfigValue.Color(name = "Color")
|
||||||
|
private Color color = Color.WHITE;
|
||||||
|
|
||||||
|
@ConfigValue.Boolean(name = "Custom Font")
|
||||||
|
private boolean customFont = false;
|
||||||
|
|
||||||
|
@ConfigValue.Boolean(name = "Static Chroma")
|
||||||
|
private boolean isUsingStaticChroma = false;
|
||||||
|
|
||||||
|
@ConfigValue.Boolean(name = "Wave Chroma")
|
||||||
|
private boolean isUsingWaveChroma = false;
|
||||||
|
|
||||||
|
private IResourcePack pack;
|
||||||
|
private ResourceLocation currentPack;
|
||||||
|
private List<ResourcePackRepository.Entry> packs;
|
||||||
|
ResourcePackRepository resourcePackRepository;
|
||||||
|
|
||||||
|
private HUDElement hud;
|
||||||
|
private int width = 66;
|
||||||
|
private int height = 48;
|
||||||
|
|
||||||
|
public PackDisplay() {
|
||||||
|
super("PackDisplay", Category.RENDER);
|
||||||
|
|
||||||
|
hud = new HUDElement("packdisplay", width, height) {
|
||||||
|
@Override
|
||||||
|
public void onRender() {
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
hud.setX(1);
|
||||||
|
hud.setY(175);
|
||||||
|
|
||||||
|
addHUD(hud);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render() {
|
||||||
|
if (mc.gameSettings.showDebugInfo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL11.glPushMatrix();
|
||||||
|
|
||||||
|
resourcePackRepository = mc.getResourcePackRepository();
|
||||||
|
packs = resourcePackRepository.getRepositoryEntries();
|
||||||
|
|
||||||
|
if(pack == null) {
|
||||||
|
pack = this.getCurrentPack();
|
||||||
|
loadTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = hud.getWidth();
|
||||||
|
int height = hud.getHeight();
|
||||||
|
|
||||||
|
if(backGround) {
|
||||||
|
if(backgroundMode.equalsIgnoreCase("Modern")) {
|
||||||
|
if(Athena.INSTANCE.getThemeManager().getTheme().isTriColor()) {
|
||||||
|
RoundedUtils.drawGradientRound(hud.getX() - 10, hud.getY(), hud.getWidth() + rip.athena.client.utils.font.FontManager.getProductSansRegular(25).width(this.convertNormalText(pack.getPackName())) / 2, hud.getHeight() + 20, 6, Athena.INSTANCE.getThemeManager().getTheme().getFirstColor(), Athena.INSTANCE.getThemeManager().getTheme().getSecondColor(), Athena.INSTANCE.getThemeManager().getTheme().getThirdColor(), Athena.INSTANCE.getThemeManager().getTheme().getFirstColor());
|
||||||
|
} else {
|
||||||
|
RoundedUtils.drawGradientRound(hud.getX() - 10, hud.getY(), hud.getWidth() + rip.athena.client.utils.font.FontManager.getProductSansRegular(25).width(this.convertNormalText(pack.getPackName())) / 2, hud.getHeight() + 20,6, Athena.INSTANCE.getThemeManager().getTheme().getFirstColor(), Athena.INSTANCE.getThemeManager().getTheme().getFirstColor(), Athena.INSTANCE.getThemeManager().getTheme().getSecondColor(), Athena.INSTANCE.getThemeManager().getTheme().getSecondColor());
|
||||||
|
}
|
||||||
|
} else if (backgroundMode.equalsIgnoreCase("Circle")) {
|
||||||
|
RoundedUtils.drawGradientRound(hud.getX() - 10, hud.getY(), hud.getWidth() + rip.athena.client.utils.font.FontManager.getProductSansRegular(25).width(this.convertNormalText(pack.getPackName())) / 2, hud.getHeight() + 20, 6, ColorUtil.getClientColor(0, 255), ColorUtil.getClientColor(90, 255), ColorUtil.getClientColor(180, 255), ColorUtil.getClientColor(270, 255));
|
||||||
|
} else if (backgroundMode.equalsIgnoreCase("Fade")) {
|
||||||
|
RoundedUtils.drawRoundedRect(hud.getX() - 10, hud.getY(), hud.getX() + width + rip.athena.client.utils.font.FontManager.getProductSansRegular(20).width(this.convertNormalText(pack.getPackName())) / 2, hud.getY() + height + 20, 12.0f, Athena.INSTANCE.getThemeManager().getTheme().getAccentColor().getRGB());
|
||||||
|
} else {
|
||||||
|
RoundedUtils.drawRoundedRect(hud.getX() - 10, hud.getY(), hud.getX() + width + rip.athena.client.utils.font.FontManager.getProductSansRegular(20).width(this.convertNormalText(pack.getPackName())) / 2, hud.getY() + height + 20, 12,background.getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hud.setHeight(hud.getWidth() + rip.athena.client.utils.font.FontManager.getProductSansRegular(25).width(this.convertNormalText(pack.getPackName())) / 2);
|
||||||
|
hud.setWidth(hud.getHeight() + 20);
|
||||||
|
|
||||||
|
mc.getTextureManager().bindTexture(this.currentPack);
|
||||||
|
RoundedUtils.drawRoundTextured(hud.getX(), hud.getY() + 4.5F, 29, 29, 2, 225);
|
||||||
|
|
||||||
|
float posY = hud.getY() + 10;
|
||||||
|
float posX = hud.getX() + 33;
|
||||||
|
|
||||||
|
if(customFont) {
|
||||||
|
hud.setWidth((int)rip.athena.client.utils.font.FontManager.getProductSansRegular(25).width(this.convertNormalText(pack.getPackName())) + 16);
|
||||||
|
hud.setHeight((int) FontManager.baloo17.getHeight(this.convertNormalText(pack.getPackName())) + 7);
|
||||||
|
|
||||||
|
if(isUsingStaticChroma) {
|
||||||
|
DrawUtils.drawCustomFontChromaString(rip.athena.client.utils.font.FontManager.getProductSansRegular(25), this.convertNormalText(pack.getPackName()), (int) (posX) + 1, (int)posY + 2,true, true);
|
||||||
|
} else if(isUsingWaveChroma) {
|
||||||
|
DrawUtils.drawCustomFontChromaString(rip.athena.client.utils.font.FontManager.getProductSansRegular(25), this.convertNormalText(pack.getPackName()), (int) (posX + 1), (int)posY + 2, false, true);
|
||||||
|
} else {
|
||||||
|
rip.athena.client.utils.font.FontManager.getProductSansRegular(25).drawString(this.convertNormalText(pack.getPackName()),(int) (posX) + 1, (int)posY + 2, color.getRGB());
|
||||||
|
|
||||||
|
//rip.athena.client.utils.font.FontManager.getPoppinsRegular(25).drawString(string,(int) (posX), (int)posY + 3, color.getRGB());
|
||||||
|
//rip.athena.client.utils.font.FontManager.getProductSansRegular(30).drawString(string,(int) (posX), (int)posY + 1, color.getRGB());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hud.setWidth(mc.fontRendererObj.getStringWidth(this.convertNormalText(pack.getPackName())) + 16);
|
||||||
|
hud.setHeight(mc.fontRendererObj.FONT_HEIGHT + 9);
|
||||||
|
|
||||||
|
if(isUsingStaticChroma) {
|
||||||
|
DrawUtils.drawChromaString(this.convertNormalText(pack.getPackName()), posX, posY + 3, true ,true);
|
||||||
|
} else if(isUsingWaveChroma) {
|
||||||
|
DrawUtils.drawChromaString(this.convertNormalText(pack.getPackName()), posX, posY + 3, false ,true);
|
||||||
|
} else {
|
||||||
|
mc.fontRendererObj.drawStringWithShadow(this.convertNormalText(pack.getPackName()), posX, posY + 3, color.getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GL11.glColor3f(1, 1, 1);
|
||||||
|
GL11.glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onSwitchTexture(SwitchTextureEvent event) {
|
||||||
|
packs = resourcePackRepository.getRepositoryEntries();
|
||||||
|
pack = this.getCurrentPack();
|
||||||
|
this.loadTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertNormalText(String text) {
|
||||||
|
return text.replaceAll("\\u00a7" + "1", "").replaceAll("\\u00a7" + "2", "").replaceAll("\\u00a7" + "3", "")
|
||||||
|
.replaceAll("\\u00a7" + "4", "").replaceAll("\\u00a7" + "5", "").replaceAll("\\u00a7" + "6", "")
|
||||||
|
.replaceAll("\\u00a7" + "7", "").replaceAll("\\u00a7" + "8", "").replaceAll("\\u00a7" + "9", "")
|
||||||
|
.replaceAll("\\u00a7" + "a", "").replaceAll("\\u00a7" + "b", "").replaceAll("\\u00a7" + "c", "")
|
||||||
|
.replaceAll("\\u00a7" + "d", "").replaceAll("\\u00a7" + "e", "").replaceAll("\\u00a7" + "f", "")
|
||||||
|
.replaceAll("\\u00a7" + "g", "").replaceAll("\\u00a7" + "k", "").replaceAll("\\u00a7" + "l", "")
|
||||||
|
.replaceAll("\\u00a7" + "m", "").replaceAll("\\u00a7" + "n", "").replaceAll("\\u00a7" + "o", "")
|
||||||
|
.replaceAll("\\u00a7" + "r", "").replace(".zip", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadTexture() {
|
||||||
|
DynamicTexture dynamicTexture;
|
||||||
|
try {
|
||||||
|
dynamicTexture = new DynamicTexture(getCurrentPack().getPackImage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
dynamicTexture = TextureUtil.missingTexture;
|
||||||
|
}
|
||||||
|
this.currentPack = mc.getTextureManager().getDynamicTextureLocation("texturepackicon", dynamicTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IResourcePack getCurrentPack() {
|
||||||
|
if (packs != null && !packs.isEmpty()) {
|
||||||
|
final IResourcePack last = packs.get(packs.size() - 1).getResourcePack();
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
return mc.mcDefaultResourcePack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
super.onEnable();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,153 @@
|
|||||||
|
package rip.athena.client.modules.impl.render;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.util.MovingObjectPosition;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import rip.athena.client.Athena;
|
||||||
|
import rip.athena.client.config.ConfigValue;
|
||||||
|
import rip.athena.client.events.SubscribeEvent;
|
||||||
|
import rip.athena.client.events.types.entity.AttackEntityEvent;
|
||||||
|
import rip.athena.client.font.FontManager;
|
||||||
|
import rip.athena.client.gui.hud.HUDElement;
|
||||||
|
import rip.athena.client.modules.Category;
|
||||||
|
import rip.athena.client.modules.Module;
|
||||||
|
import rip.athena.client.utils.NumberUtils;
|
||||||
|
import rip.athena.client.utils.render.ColorUtil;
|
||||||
|
import rip.athena.client.utils.render.DrawUtils;
|
||||||
|
import rip.athena.client.utils.render.RoundedUtils;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Athena Development
|
||||||
|
* @project Athena-Client
|
||||||
|
* @date 6/12/2023
|
||||||
|
*/
|
||||||
|
public class ReachDisplay extends Module {
|
||||||
|
|
||||||
|
@ConfigValue.List(name = "Display Mode", values = {"Circle", "Modern", "Fade", "Old"}, description = "Chose display of background")
|
||||||
|
private String backgroundMode = "Circle";
|
||||||
|
|
||||||
|
@ConfigValue.Boolean(name = "Background")
|
||||||
|
private boolean backGround = true;
|
||||||
|
|
||||||
|
@ConfigValue.Color(name = "Background Color")
|
||||||
|
private Color background = new Color(0, 0, 0, 150);
|
||||||
|
|
||||||
|
@ConfigValue.Color(name = "Color")
|
||||||
|
private Color color = Color.WHITE;
|
||||||
|
|
||||||
|
@ConfigValue.Boolean(name = "Custom Font")
|
||||||
|
private boolean customFont = false;
|
||||||
|
|
||||||
|
@ConfigValue.Boolean(name = "Static Chroma")
|
||||||
|
private boolean isUsingStaticChroma = false;
|
||||||
|
|
||||||
|
@ConfigValue.Boolean(name = "Wave Chroma")
|
||||||
|
private boolean isUsingWaveChroma = false;
|
||||||
|
|
||||||
|
private DecimalFormat format = new DecimalFormat("0.##");
|
||||||
|
|
||||||
|
private double distance = 0;
|
||||||
|
private long hitTime = -1;
|
||||||
|
private String reach;
|
||||||
|
|
||||||
|
HUDElement hud;
|
||||||
|
private int width = 56;
|
||||||
|
private int height = 18;
|
||||||
|
|
||||||
|
public ReachDisplay() {
|
||||||
|
super("Reach Display", Category.RENDER, "Athena/gui/mods/reach.png");
|
||||||
|
|
||||||
|
hud = new HUDElement("reachdisplay", width, height) {
|
||||||
|
@Override
|
||||||
|
public void onRender() {
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
hud.setX(1);
|
||||||
|
hud.setY(175);
|
||||||
|
|
||||||
|
addHUD(hud);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public void onDamageEntity(AttackEntityEvent e) {
|
||||||
|
if(mc.objectMouseOver != null && mc.objectMouseOver.hitVec != null && mc.objectMouseOver.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY) {
|
||||||
|
distance = mc.objectMouseOver.hitVec.distanceTo(mc.thePlayer.getPositionEyes(1.0F));
|
||||||
|
hitTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render() {
|
||||||
|
if (mc.gameSettings.showDebugInfo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL11.glPushMatrix();
|
||||||
|
|
||||||
|
if((System.currentTimeMillis() - hitTime) > 5000) {
|
||||||
|
distance = 0;
|
||||||
|
}
|
||||||
|
if(distance == 0) {
|
||||||
|
reach = "Hasn't attacked";
|
||||||
|
}else {
|
||||||
|
reach = format.format(distance) + " blocks";
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = hud.getWidth();
|
||||||
|
int height = hud.getHeight();
|
||||||
|
|
||||||
|
if(backGround) {
|
||||||
|
if(backgroundMode.equalsIgnoreCase("Modern")) {
|
||||||
|
if(Athena.INSTANCE.getThemeManager().getTheme().isTriColor()) {
|
||||||
|
RoundedUtils.drawGradientRound(hud.getX(), hud.getY(), hud.getWidth(), hud.getHeight(), 6, Athena.INSTANCE.getThemeManager().getTheme().getFirstColor(), Athena.INSTANCE.getThemeManager().getTheme().getSecondColor(), Athena.INSTANCE.getThemeManager().getTheme().getThirdColor(), Athena.INSTANCE.getThemeManager().getTheme().getFirstColor());
|
||||||
|
} else {
|
||||||
|
RoundedUtils.drawGradientRound(hud.getX(), hud.getY(), hud.getWidth(), hud.getHeight(), 6, Athena.INSTANCE.getThemeManager().getTheme().getFirstColor(), Athena.INSTANCE.getThemeManager().getTheme().getFirstColor(), Athena.INSTANCE.getThemeManager().getTheme().getSecondColor(), Athena.INSTANCE.getThemeManager().getTheme().getSecondColor());
|
||||||
|
}
|
||||||
|
} else if (backgroundMode.equalsIgnoreCase("Circle")) {
|
||||||
|
RoundedUtils.drawGradientRound(hud.getX(), hud.getY(), hud.getWidth(), hud.getHeight(), 6, ColorUtil.getClientColor(0, 255), ColorUtil.getClientColor(90, 255), ColorUtil.getClientColor(180, 255), ColorUtil.getClientColor(270, 255));
|
||||||
|
} else if (backgroundMode.equalsIgnoreCase("Fade")) {
|
||||||
|
RoundedUtils.drawRoundedRect(hud.getX(), hud.getY(), hud.getX() + width, hud.getY() + height, 8.0f, Athena.INSTANCE.getThemeManager().getTheme().getAccentColor().getRGB());
|
||||||
|
} else {
|
||||||
|
RoundedUtils.drawRoundedRect(hud.getX(), hud.getY(), hud.getX() + width, hud.getY() + height, 12,background.getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float posY = hud.getY() + 2;
|
||||||
|
float posX = hud.getX() + 9;
|
||||||
|
|
||||||
|
if(customFont) {
|
||||||
|
hud.setWidth((int)rip.athena.client.utils.font.FontManager.getProductSansRegular(25).width(String.valueOf(reach)) + 16);
|
||||||
|
hud.setHeight((int) FontManager.baloo17.getHeight(String.valueOf(reach)) + 7);
|
||||||
|
|
||||||
|
if(isUsingStaticChroma) {
|
||||||
|
DrawUtils.drawCustomFontChromaString(rip.athena.client.utils.font.FontManager.getProductSansRegular(25), String.valueOf(reach), (int) (posX), (int) posY + 1, true, true);
|
||||||
|
} else if(isUsingWaveChroma) {
|
||||||
|
DrawUtils.drawCustomFontChromaString(rip.athena.client.utils.font.FontManager.getProductSansRegular(25), String.valueOf(reach), (int) (posX), (int) posY + 1, false, true);
|
||||||
|
} else {
|
||||||
|
rip.athena.client.utils.font.FontManager.getProductSansRegular(25).drawString(String.valueOf(reach),(int) (posX) + 1, (int)posY + 2, color.getRGB());
|
||||||
|
|
||||||
|
//rip.athena.client.utils.font.FontManager.getPoppinsRegular(25).drawString(string,(int) (posX), (int)posY + 3, color.getRGB());
|
||||||
|
//rip.athena.client.utils.font.FontManager.getProductSansRegular(30).drawString(string,(int) (posX), (int)posY + 1, color.getRGB());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hud.setWidth(mc.fontRendererObj.getStringWidth(String.valueOf(reach)) + 16);
|
||||||
|
hud.setHeight(mc.fontRendererObj.FONT_HEIGHT + 9);
|
||||||
|
|
||||||
|
if(isUsingStaticChroma) {
|
||||||
|
DrawUtils.drawChromaString(String.valueOf(reach), posX, posY + 3, true ,true);
|
||||||
|
} else if(isUsingWaveChroma) {
|
||||||
|
DrawUtils.drawChromaString(String.valueOf(reach), posX, posY+ 3, false ,true);
|
||||||
|
} else {
|
||||||
|
mc.fontRendererObj.drawStringWithShadow(String.valueOf(reach), (float) (posX), (float) posY+ 3, color.getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GL11.glColor3f(1, 1, 1);
|
||||||
|
GL11.glPopMatrix();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package rip.athena.client.modules.impl.render;
|
||||||
|
|
||||||
|
import rip.athena.client.config.ConfigValue;
|
||||||
|
import rip.athena.client.modules.Category;
|
||||||
|
import rip.athena.client.modules.Module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Athena Development
|
||||||
|
* @project Athena-Client
|
||||||
|
* @date 6/12/2023
|
||||||
|
*/
|
||||||
|
public class TimeChanger extends Module {
|
||||||
|
|
||||||
|
@ConfigValue.Integer(name = "Time", min = 1, max = 24000)
|
||||||
|
public int time = 16000;
|
||||||
|
|
||||||
|
public TimeChanger() {
|
||||||
|
super("Time Changer", Category.RENDER, "Athena/gui/mods/timechanger.png");
|
||||||
|
}
|
||||||
|
}
|
60
src/main/java/rip/athena/client/server/CosmeticsClient.java
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package rip.athena.client.server;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import org.eclipse.jetty.websocket.api.Session;
|
||||||
|
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
|
||||||
|
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
|
||||||
|
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
|
||||||
|
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
|
||||||
|
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Athena Development
|
||||||
|
* @project Athena-Client
|
||||||
|
* @date 6/12/2023
|
||||||
|
*/
|
||||||
|
|
||||||
|
@WebSocket
|
||||||
|
public class CosmeticsClient {
|
||||||
|
|
||||||
|
private Session session;
|
||||||
|
|
||||||
|
public void connect(String serverUri) throws URISyntaxException {
|
||||||
|
WebSocketClient client = new WebSocketClient();
|
||||||
|
try {
|
||||||
|
client.start();
|
||||||
|
URI uri = new URI(serverUri);
|
||||||
|
client.connect(this, uri);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnWebSocketConnect
|
||||||
|
public void onConnect(Session session) {
|
||||||
|
System.out.println("Connected to server");
|
||||||
|
this.session = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnWebSocketMessage
|
||||||
|
public void onMessage(String message) {
|
||||||
|
System.out.println("Received message from server: " + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnWebSocketClose
|
||||||
|
public void onClose(int statusCode, String reason) {
|
||||||
|
System.out.println("Connection closed: " + reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessage(String message) {
|
||||||
|
try {
|
||||||
|
session.getRemote().sendString(message);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class SocketClient {
|
public class SocketClient {
|
||||||
|
|
||||||
public static final Client client = new Client("141.145.209.142", 1337);
|
public static final Client client = new Client("141.145.209.142", 45376);
|
||||||
private static final Map<String, Boolean> userCache = new HashMap<>();
|
private static final Map<String, Boolean> userCache = new HashMap<>();
|
||||||
|
|
||||||
private static Map<String, String> rankCache = new HashMap<>();
|
private static Map<String, String> rankCache = new HashMap<>();
|
||||||
@ -25,7 +25,7 @@ public class SocketClient {
|
|||||||
|
|
||||||
public static boolean isClientRunning() {
|
public static boolean isClientRunning() {
|
||||||
try {
|
try {
|
||||||
ServerSocket serverSocket = new ServerSocket(1337);
|
ServerSocket serverSocket = new ServerSocket(45376);
|
||||||
serverSocket.close();
|
serverSocket.close();
|
||||||
return false;
|
return false;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
BIN
src/main/resources/assets/minecraft/Athena/gui/mods/reach.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.5 KiB |
BIN
src/main/resources/assets/minecraft/pack.png
Normal file
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 848 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 571 B |
After Width: | Height: | Size: 765 B |
After Width: | Height: | Size: 732 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 780 B |
After Width: | Height: | Size: 864 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 956 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 933 B |
After Width: | Height: | Size: 1017 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 425 B |
After Width: | Height: | Size: 569 B |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 638 B |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 479 B |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 985 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 817 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1008 B |