update loads of shit
18
pom.xml
@ -22,12 +22,30 @@
|
||||
</repositories>
|
||||
|
||||
<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>
|
||||
<groupId>net.minecraft</groupId>
|
||||
<artifactId>minecraft</artifactId>
|
||||
<version>1.8.8</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.java-websocket</groupId>
|
||||
<artifactId>Java-WebSocket</artifactId>
|
||||
<version>1.5.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>co.gongzh.procbridge</groupId>
|
||||
<artifactId>procbridge</artifactId>
|
||||
|
@ -20,12 +20,14 @@ package fr.litarvan.openauth;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
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.request.*;
|
||||
import fr.litarvan.openauth.model.response.AuthResponse;
|
||||
import fr.litarvan.openauth.model.response.RefreshResponse;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@ -43,18 +45,20 @@ public class Authenticator {
|
||||
|
||||
/**
|
||||
* 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/";
|
||||
|
||||
/**
|
||||
* The auth server URL
|
||||
*/
|
||||
private String authURL;
|
||||
private final String authURL;
|
||||
|
||||
/**
|
||||
* The server auth points
|
||||
*/
|
||||
private AuthPoints authPoints;
|
||||
private final AuthPoints authPoints;
|
||||
|
||||
/**
|
||||
* Create an authenticator
|
||||
@ -71,14 +75,14 @@ public class Authenticator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticates an user using his password.
|
||||
* Authenticates a user using his password.
|
||||
*
|
||||
* @param agent
|
||||
* The auth agent (optional)
|
||||
* @param username
|
||||
* User mojang account name
|
||||
* User account name
|
||||
* @param password
|
||||
* User mojang account password
|
||||
* User account password
|
||||
* @param clientToken
|
||||
* 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)
|
||||
*/
|
||||
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);
|
||||
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
|
||||
* The saved access token
|
||||
* @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
|
||||
*
|
||||
* @return The response sent by the server (parsed from a JSON)
|
||||
*/
|
||||
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);
|
||||
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
|
||||
*/
|
||||
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);
|
||||
sendRequest(request, null, authPoints.getValidatePoint());
|
||||
sendRequest(request, null, authPoints.getValidatePoint(), proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates accessTokens using an account's username and password
|
||||
*
|
||||
* @param username
|
||||
* User mojang account name
|
||||
* User account name
|
||||
* @param password
|
||||
* User mojang account password
|
||||
* User account password
|
||||
*
|
||||
* @throws AuthenticationException If the server returned an error as a JSON
|
||||
*/
|
||||
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);
|
||||
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
|
||||
*/
|
||||
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);
|
||||
sendRequest(request, null, authPoints.getInvalidatePoint());
|
||||
sendRequest(request, null, authPoints.getInvalidatePoint(), proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,7 +259,7 @@ public class Authenticator {
|
||||
* @param request
|
||||
* The auth request to send
|
||||
* @param model
|
||||
* The model of the reponse
|
||||
* The model of the response
|
||||
* @param authPoint
|
||||
* The auth point of the request
|
||||
* @throws AuthenticationException
|
||||
@ -171,14 +267,36 @@ public class Authenticator {
|
||||
*
|
||||
* @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 {
|
||||
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();
|
||||
String response;
|
||||
|
||||
try {
|
||||
response = sendPostRequest(this.authURL + authPoint, gson.toJson(request));
|
||||
response = sendPostRequest(this.authURL + authPoint, gson.toJson(request), proxy);
|
||||
} catch (IOException e) {
|
||||
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
|
||||
*/
|
||||
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);
|
||||
URL serverURL = new URL(url);
|
||||
HttpURLConnection connection = (HttpURLConnection) serverURL.openConnection();
|
||||
HttpURLConnection connection = (HttpURLConnection) serverURL.openConnection(proxy != null ? proxy : Proxy.NO_PROXY);
|
||||
connection.setRequestMethod("POST");
|
||||
|
||||
// Sending post request
|
||||
|
@ -20,28 +20,30 @@ package fr.litarvan.openauth.microsoft;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class HttpClient
|
||||
{
|
||||
public static final String MIME_TYPE_JSON = "application/json";
|
||||
public static final String MIME_TYPE_URLENCODED_FORM = "application/x-www-form-urlencoded";
|
||||
|
||||
|
||||
private final Gson gson;
|
||||
private final Proxy proxy;
|
||||
|
||||
public HttpClient()
|
||||
{
|
||||
this(Proxy.NO_PROXY);
|
||||
}
|
||||
public HttpClient(Proxy proxy)
|
||||
{
|
||||
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
|
||||
{
|
||||
HttpsURLConnection connection = createConnection(url);
|
||||
HttpURLConnection connection = createConnection(url);
|
||||
connection.addRequestProperty("Authorization", "Bearer " + token);
|
||||
connection.addRequestProperty("Accept", MIME_TYPE_JSON);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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.addRequestProperty("Content-Type", contentType);
|
||||
connection.addRequestProperty("Accept", accept);
|
||||
@ -93,12 +95,12 @@ public class HttpClient
|
||||
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);
|
||||
}
|
||||
|
||||
protected String readResponse(HttpsURLConnection connection) throws MicrosoftAuthenticationException
|
||||
protected String readResponse(HttpURLConnection connection) throws MicrosoftAuthenticationException
|
||||
{
|
||||
String redirection = connection.getHeaderField("Location");
|
||||
if (redirection != null) {
|
||||
@ -106,7 +108,33 @@ public class HttpClient
|
||||
}
|
||||
|
||||
StringBuilder response = new StringBuilder();
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
|
||||
|
||||
try
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
response.append(line).append('\n');
|
||||
@ -114,11 +142,27 @@ public class HttpClient
|
||||
} catch (IOException e) {
|
||||
throw new MicrosoftAuthenticationException(e);
|
||||
}
|
||||
} catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
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");
|
||||
if (redirection != null) {
|
||||
@ -137,7 +181,7 @@ public class HttpClient
|
||||
}
|
||||
|
||||
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) {
|
||||
// Can't happen
|
||||
}
|
||||
@ -146,17 +190,22 @@ public class HttpClient
|
||||
return query.toString();
|
||||
}
|
||||
|
||||
protected HttpsURLConnection createConnection(String url) throws MicrosoftAuthenticationException
|
||||
protected HttpURLConnection createConnection(String url) throws MicrosoftAuthenticationException
|
||||
{
|
||||
HttpsURLConnection connection;
|
||||
HttpURLConnection connection;
|
||||
try {
|
||||
connection = (HttpsURLConnection) new URL(url).openConnection();
|
||||
connection = (HttpURLConnection) new URL(url).openConnection(proxy);
|
||||
} catch (IOException 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-Charset", "UTF-8");
|
||||
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>
|
||||
*
|
||||
* @author Litarvan
|
||||
* @version 1.1.0
|
||||
* @version 1.1.5
|
||||
*/
|
||||
public class MicrosoftAuthResult
|
||||
{
|
||||
private final MinecraftProfile profile;
|
||||
private final String accessToken;
|
||||
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.accessToken = accessToken;
|
||||
this.refreshToken = refreshToken;
|
||||
this.xuid = xuid;
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,4 +72,20 @@ public class MicrosoftAuthResult
|
||||
{
|
||||
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.response.*;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -49,15 +49,14 @@ import java.util.regex.Pattern;
|
||||
* <p>
|
||||
* 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,
|
||||
* or loginWithWebview to use a webview with Microsoft login form.
|
||||
* or {@link #loginWithWebview} to use a webview with Microsoft login form.
|
||||
* </p>
|
||||
*
|
||||
* @version 1.1.0
|
||||
* @author Litarvan
|
||||
* @version 1.1.0
|
||||
*/
|
||||
public class MicrosoftAuthenticator
|
||||
{
|
||||
public static final String MICROSOFT_AUTHORIZATION_ENDPOINT = "https://login.live.com/oauth20_authorize.srf";
|
||||
public class MicrosoftAuthenticator {
|
||||
public static final String MICROSOFT_AUTHORIZATION_ENDPOINT = "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize";
|
||||
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";
|
||||
|
||||
@ -80,24 +79,19 @@ public class MicrosoftAuthenticator
|
||||
|
||||
private final HttpClient http;
|
||||
|
||||
public MicrosoftAuthenticator()
|
||||
{
|
||||
public MicrosoftAuthenticator() {
|
||||
this.http = new HttpClient();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Logs in a player using its Microsoft account credentials, and retrieve its Minecraft profile
|
||||
*
|
||||
* @param email Player Microsoft account e-mail
|
||||
* @param password Player Microsoft account password
|
||||
*
|
||||
* @return The player Minecraft profile
|
||||
*
|
||||
* @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.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
|
||||
|
||||
@ -106,7 +100,7 @@ public class MicrosoftAuthenticator
|
||||
params.put("loginfmt", email);
|
||||
params.put("passwd", password);
|
||||
|
||||
HttpsURLConnection result;
|
||||
HttpURLConnection result;
|
||||
|
||||
try {
|
||||
PreAuthData authData = preAuthRequest();
|
||||
@ -118,9 +112,9 @@ public class MicrosoftAuthenticator
|
||||
}
|
||||
|
||||
try {
|
||||
return loginWithTokens(extractTokens(result.getURL().toString()));
|
||||
return loginWithTokens(extractTokens(result.getURL().toString()),true);
|
||||
} catch (MicrosoftAuthenticationException e) {
|
||||
if (match("identity/confirm", http.readResponse(result)) != null) {
|
||||
if (match("(identity/confirm)", http.readResponse(result)) != null) {
|
||||
throw new MicrosoftAuthenticationException(
|
||||
"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.
|
||||
// * <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
|
||||
// * {@link #loginWithAsyncWebview()}</b>
|
||||
// *
|
||||
// * @return The player Minecraft profile
|
||||
// *
|
||||
// * @throws MicrosoftAuthenticationException Thrown if one of the several HTTP requests failed at some point
|
||||
// */
|
||||
// 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
|
||||
{
|
||||
/**
|
||||
* 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
|
||||
* freeze. When calling from the JavaFX thread or any thread which must not be blocked, use
|
||||
* {@link #loginWithAsyncWebview()}</b>
|
||||
*
|
||||
* @return The player Minecraft profile
|
||||
* @throws MicrosoftAuthenticationException Thrown if one of the several HTTP requests failed at some point
|
||||
*/
|
||||
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() {
|
||||
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()));
|
||||
LoginFrame frame = new LoginFrame();
|
||||
|
||||
return frame.start(url).thenApplyAsync(result -> {
|
||||
try {
|
||||
return loginWithTokens(extractTokens(result));
|
||||
if(result != null)
|
||||
return loginWithTokens(extractTokens(result),true);
|
||||
else return null;
|
||||
} catch (MicrosoftAuthenticationException e) {
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
});
|
||||
}*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs in a player using a Microsoft account refresh token retrieved earlier.
|
||||
*
|
||||
* @param refreshToken Player Microsoft account refresh token
|
||||
*
|
||||
* @return The player Minecraft profile
|
||||
*
|
||||
* @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();
|
||||
params.put("refresh_token", refreshToken);
|
||||
params.put("grant_type", "refresh_token");
|
||||
@ -210,7 +181,7 @@ public class MicrosoftAuthenticator
|
||||
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>
|
||||
*
|
||||
* @param tokens Player Microsoft account tokens pair
|
||||
*
|
||||
* @return The player Minecraft profile
|
||||
*
|
||||
* @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 xstsResponse = xstsLogin(xboxLiveResponse.getToken());
|
||||
|
||||
@ -239,19 +220,26 @@ public class MicrosoftAuthenticator
|
||||
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");
|
||||
}
|
||||
|
||||
MinecraftProfile profile = http.getJson(
|
||||
MinecraftProfile profile = null;
|
||||
if (retrieveProfile) {
|
||||
profile = http.getJson(
|
||||
MINECRAFT_PROFILE_ENDPOINT,
|
||||
minecraftResponse.getAccessToken(),
|
||||
MinecraftProfile.class
|
||||
);
|
||||
}
|
||||
|
||||
return new MicrosoftAuthResult(profile, minecraftResponse.getAccessToken(), tokens.getRefreshToken());
|
||||
return new MicrosoftAuthResult(
|
||||
profile,
|
||||
minecraftResponse.getAccessToken(),
|
||||
tokens.getRefreshToken(),
|
||||
xboxLiveResponse.getDisplayClaims().getUsers()[0].getUserHash(),
|
||||
Base64.getEncoder().encodeToString(minecraftResponse.getUsername().getBytes())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
protected PreAuthData preAuthRequest() throws MicrosoftAuthenticationException
|
||||
{
|
||||
protected PreAuthData preAuthRequest() throws MicrosoftAuthenticationException {
|
||||
Map<String, String> params = getLoginParams();
|
||||
params.put("display", "touch");
|
||||
params.put("locale", "en");
|
||||
@ -264,8 +252,7 @@ public class MicrosoftAuthenticator
|
||||
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);
|
||||
XboxLoginRequest<XboxLiveLoginProperties> request = new XboxLoginRequest<>(
|
||||
properties, XBOX_LIVE_AUTH_RELAY, "JWT"
|
||||
@ -274,9 +261,8 @@ public class MicrosoftAuthenticator
|
||||
return http.postJson(XBOX_LIVE_AUTHORIZATION_ENDPOINT, request, XboxLoginResponse.class);
|
||||
}
|
||||
|
||||
protected XboxLoginResponse xstsLogin(String xboxLiveToken) throws MicrosoftAuthenticationException
|
||||
{
|
||||
XSTSAuthorizationProperties properties = new XSTSAuthorizationProperties("RETAIL", new String[] { xboxLiveToken });
|
||||
protected XboxLoginResponse xstsLogin(String xboxLiveToken) throws MicrosoftAuthenticationException {
|
||||
XSTSAuthorizationProperties properties = new XSTSAuthorizationProperties("RETAIL", new String[]{xboxLiveToken});
|
||||
XboxLoginRequest<XSTSAuthorizationProperties> request = new XboxLoginRequest<>(
|
||||
properties, MINECRAFT_AUTH_RELAY, "JWT"
|
||||
);
|
||||
@ -284,15 +270,13 @@ public class MicrosoftAuthenticator
|
||||
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));
|
||||
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<>();
|
||||
params.put("client_id", XBOX_LIVE_CLIENT_ID);
|
||||
params.put("redirect_uri", MICROSOFT_REDIRECTION_ENDPOINT);
|
||||
@ -302,13 +286,11 @@ public class MicrosoftAuthenticator
|
||||
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"));
|
||||
}
|
||||
|
||||
protected String extractValue(String url, String key) throws MicrosoftAuthenticationException
|
||||
{
|
||||
protected String extractValue(String url, String key) throws MicrosoftAuthenticationException {
|
||||
String matched = match(key + "=([^&]*)", url);
|
||||
if (matched == null) {
|
||||
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);
|
||||
if (!matcher.find()) {
|
||||
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.modules.impl.fpssettings.OptimizerMod;
|
||||
import rip.athena.client.modules.impl.mods.HitDelayFix;
|
||||
import rip.athena.client.modules.impl.render.MotionBlur;
|
||||
|
||||
public class Minecraft implements IThreadListener, IPlayerUsage
|
||||
{
|
||||
@ -325,7 +326,7 @@ public class Minecraft implements IThreadListener, IPlayerUsage
|
||||
private IReloadableResourceManager mcResourceManager;
|
||||
public final IMetadataSerializer metadataSerializer_ = new IMetadataSerializer();
|
||||
private final List<IResourcePack> defaultResourcePacks = Lists.<IResourcePack>newArrayList();
|
||||
private final DefaultResourcePack mcDefaultResourcePack;
|
||||
public final DefaultResourcePack mcDefaultResourcePack;
|
||||
private ResourcePackRepository mcResourcePackRepository;
|
||||
private LanguageManager mcLanguageManager;
|
||||
private IStream stream;
|
||||
@ -1224,6 +1225,11 @@ public class Minecraft implements IThreadListener, IPlayerUsage
|
||||
|
||||
public void updateDisplay()
|
||||
{
|
||||
if(Athena.INSTANCE.getModuleManager().get(MotionBlur.class).isToggled()) {
|
||||
if(Minecraft.getMinecraft().thePlayer != null) {
|
||||
MotionBlur.createAccumulation();
|
||||
}
|
||||
}
|
||||
this.mcProfiler.startSection("display_update");
|
||||
Display.update();
|
||||
this.mcProfiler.endSection();
|
||||
|
@ -23,16 +23,19 @@ import optifine.HttpResponse;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
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
|
||||
{
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
public static final Logger logger = LogManager.getLogger();
|
||||
private static final AtomicInteger threadDownloadCounter = new AtomicInteger(0);
|
||||
private final File cacheFile;
|
||||
public final File cacheFile;
|
||||
private final String imageUrl;
|
||||
private final IImageBuffer imageBuffer;
|
||||
private BufferedImage bufferedImage;
|
||||
private Thread imageThread;
|
||||
public final IImageBuffer imageBuffer;
|
||||
public BufferedImage bufferedImage;
|
||||
public Thread imageThread;
|
||||
private boolean textureUploaded;
|
||||
private static final String __OBFID = "CL_00001049";
|
||||
public Boolean imageFound = null;
|
||||
@ -83,9 +86,21 @@ public class ThreadDownloadImageData extends SimpleTexture
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/*if (this.bufferedImage == null && this.textureLocation != null)
|
||||
{
|
||||
super.loadTexture(resourceManager);
|
||||
}*/
|
||||
|
||||
if (this.imageThread == null)
|
||||
{
|
||||
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())
|
||||
{
|
||||
|
@ -10,8 +10,10 @@ import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import rip.athena.client.Athena;
|
||||
import rip.athena.client.modules.impl.fpssettings.OptimizerMod;
|
||||
import rip.athena.client.modules.impl.mods.ItemPhysics;
|
||||
|
||||
public class RenderEntityItem extends Render<EntityItem>
|
||||
{
|
||||
@ -115,6 +117,13 @@ public class RenderEntityItem extends Render<EntityItem>
|
||||
IBakedModel ibakedmodel = this.itemRenderer.getItemModelMesher().getItemModel(itemstack);
|
||||
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)
|
||||
{
|
||||
if (ibakedmodel.isGui3d())
|
||||
|
@ -35,6 +35,9 @@ import optifine.Config;
|
||||
import optifine.ConnectedTextures;
|
||||
import optifine.Reflector;
|
||||
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;
|
||||
|
||||
public class TextureMap extends AbstractTexture implements ITickableTextureObject
|
||||
@ -139,6 +142,10 @@ public class TextureMap extends AbstractTexture implements ITickableTextureObjec
|
||||
|
||||
public void loadTextureAtlas(IResourceManager resourceManager)
|
||||
{
|
||||
if(!Athena.INSTANCE.getEventBus().post(new SwitchTextureEvent())) {
|
||||
return;
|
||||
}
|
||||
|
||||
Config.dbg("Multitexture: " + Config.isMultiTexture());
|
||||
|
||||
if (Config.isMultiTexture())
|
||||
|
@ -5,6 +5,8 @@ import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.tileentity.MobSpawnerBaseLogic;
|
||||
import net.minecraft.tileentity.TileEntityMobSpawner;
|
||||
import rip.athena.client.Athena;
|
||||
import rip.athena.client.modules.impl.fpssettings.OptimizerMod;
|
||||
|
||||
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)
|
||||
{
|
||||
OptimizerMod mod = (OptimizerMod) Athena.INSTANCE.getModuleManager().get(OptimizerMod.class);
|
||||
if(mod.REMOVE_ENTITY_SPAWNER) return;
|
||||
|
||||
Entity entity = mobSpawnerLogic.func_180612_a(mobSpawnerLogic.getSpawnerWorld());
|
||||
|
||||
if (entity != null)
|
||||
|
@ -1,6 +1,8 @@
|
||||
package net.minecraft.world.storage;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import io.netty.handler.codec.http.multipart.AbstractHttpData;
|
||||
import net.minecraft.crash.CrashReportCategory;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
@ -9,6 +11,8 @@ import net.minecraft.world.EnumDifficulty;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.WorldSettings;
|
||||
import net.minecraft.world.WorldType;
|
||||
import rip.athena.client.Athena;
|
||||
import rip.athena.client.modules.impl.render.TimeChanger;
|
||||
|
||||
public class WorldInfo
|
||||
{
|
||||
@ -411,7 +415,9 @@ public class WorldInfo
|
||||
*/
|
||||
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()
|
||||
|
@ -18,6 +18,7 @@ import rip.athena.client.modules.impl.other.AimTrainer;
|
||||
import rip.athena.client.requests.ContentType;
|
||||
import rip.athena.client.requests.WebRequest;
|
||||
import rip.athena.client.requests.WebRequestResult;
|
||||
import rip.athena.client.server.CosmeticsClient;
|
||||
import rip.athena.client.socket.SocketClient;
|
||||
import rip.athena.client.theme.ThemeManager;
|
||||
import rip.athena.client.utils.PrefixedLogger;
|
||||
@ -28,6 +29,7 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.NoSuchElementException;
|
||||
@ -78,7 +80,11 @@ public class Athena {
|
||||
* connections with servers or other systems.
|
||||
*/
|
||||
public void initClient() {
|
||||
String os = System.getProperty("os.name");
|
||||
|
||||
if (os.toLowerCase().contains("win")) {
|
||||
this.discordRPC = new DiscordRPC();
|
||||
}
|
||||
|
||||
if(!MAIN_DIR.exists()) {
|
||||
MAIN_DIR.mkdir();
|
||||
@ -93,7 +99,7 @@ public class Athena {
|
||||
}
|
||||
|
||||
if(SocketClient.isClientRunning()) {
|
||||
JOptionPane.showMessageDialog(null, "Port 1337 already in use.");
|
||||
JOptionPane.showMessageDialog(null, "Port 45376 already in use.");
|
||||
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;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import rip.athena.client.Athena;
|
||||
import rip.athena.client.font.FontManager;
|
||||
@ -54,31 +55,16 @@ public class CategoryButton extends MenuButton {
|
||||
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 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()) {
|
||||
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) {
|
||||
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 {
|
||||
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);
|
||||
/*
|
||||
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;
|
||||
}
|
||||
@ -86,7 +72,7 @@ public class CategoryButton extends MenuButton {
|
||||
@Override
|
||||
public int getStringWidth(String string) {
|
||||
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 {
|
||||
return Minecraft.getMinecraft().fontRendererObj.getStringWidth(string);
|
||||
}
|
||||
@ -95,7 +81,7 @@ public class CategoryButton extends MenuButton {
|
||||
@Override
|
||||
public int getStringHeight(String string) {
|
||||
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 {
|
||||
return Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ public class LoginPanel extends Panel {
|
||||
setHeight(200);
|
||||
actionButtons.add(new AltButton("Cracked"));
|
||||
actionButtons.add(new AltButton("Session"));
|
||||
actionButtons.add(new AltButton("Login"));
|
||||
textFields.add(new TextField());
|
||||
textFields.add(new TextField());
|
||||
}
|
||||
@ -172,9 +173,7 @@ public class LoginPanel extends Panel {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
actionButton.drawScreen(mouseX, mouseY);
|
||||
|
||||
seperation += actionWidth + buttonSpacing;
|
||||
}
|
||||
|
||||
@ -199,18 +198,39 @@ public class LoginPanel extends Panel {
|
||||
actionButtons.forEach(actionButton -> actionButton.mouseClicked(mouseX, mouseY, button));
|
||||
|
||||
if (hoveringMicrosoft && button == 0) {
|
||||
|
||||
new Thread(() -> {
|
||||
MicrosoftAuthenticator authenticator = new MicrosoftAuthenticator();
|
||||
/*try {
|
||||
MicrosoftAuthResult acc = authenticator.loginWithWebview();
|
||||
Athena.INSTANCE.getAccountManager().getAccounts().add(new Account(AccountType.MICROSOFT, acc.getProfile().getName(), acc.getProfile().getId(), acc.getRefreshToken()));
|
||||
|
||||
TextField username = textFields.get(0);
|
||||
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");
|
||||
|
||||
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().save();
|
||||
Athena.INSTANCE.getLog().info("Success: Logged into " + acc.getProfile().getName());
|
||||
|
||||
} catch (MicrosoftAuthenticationException e) {
|
||||
e.printStackTrace();
|
||||
}*/
|
||||
}).start();
|
||||
}
|
||||
|
||||
resetTextFields();
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,16 +19,6 @@ public class OptimizerMod extends Module {
|
||||
public boolean DONT_CULL_PLAYER_NAMETAGS = true;
|
||||
public boolean DONT_CULL_ENTITY_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.")
|
||||
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)
|
||||
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.")
|
||||
public boolean REMOVE_ENTITY_SPAWNER = true;
|
||||
|
||||
@ -58,33 +42,9 @@ public class OptimizerMod extends Module {
|
||||
public boolean STATIC_DROPS = 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")
|
||||
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")
|
||||
public static boolean noLagClearWater = false;
|
||||
|
||||
@ -94,9 +54,6 @@ public class OptimizerMod extends Module {
|
||||
@ConfigValue.Integer(name = "Entity Render Distance", min = 1, max = 64)
|
||||
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")
|
||||
public boolean noBetterChests = false;
|
||||
|
||||
|
@ -196,7 +196,7 @@ public class EntityCulling {
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void tick(ClientTickEvent event) {
|
||||
public void onTick(ClientTickEvent event) {
|
||||
WorldClient theWorld = Minecraft.getMinecraft().theWorld;
|
||||
if (theWorld == null)
|
||||
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() {
|
||||
if (this.mc.gameSettings.showDebugInfo) {
|
||||
if (mc.gameSettings.showDebugInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -43,16 +43,49 @@ import static net.minecraft.client.resources.SimpleReloadableResourceManager.dom
|
||||
*/
|
||||
public class MotionBlur extends Module {
|
||||
|
||||
@ConfigValue.Double(name = "Blur Amount", min = 1.0, max = 10)
|
||||
private double amount = 2.0D;
|
||||
@ConfigValue.Integer(name = "Amount", min = 1, max = 10)
|
||||
public static int amount = 1;
|
||||
|
||||
public static float f;
|
||||
|
||||
public MotionBlur() {
|
||||
super("Motion Blur", Category.RENDER, "Athena/gui/mods/motionblur.png");
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRender(RenderEvent event) {
|
||||
public static void createAccumulation() {
|
||||
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
|
||||
|
@ -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 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 Map<String, String> rankCache = new HashMap<>();
|
||||
@ -25,7 +25,7 @@ public class SocketClient {
|
||||
|
||||
public static boolean isClientRunning() {
|
||||
try {
|
||||
ServerSocket serverSocket = new ServerSocket(1337);
|
||||
ServerSocket serverSocket = new ServerSocket(45376);
|
||||
serverSocket.close();
|
||||
return false;
|
||||
} 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 |
After Width: | Height: | Size: 405 B |