diff --git a/build.gradle b/build.gradle index d99ed5d..3fcc938 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,8 @@ dependencies { modApi "dev.felnull:special-model-loader:1.4.0+pre.1" include "dev.felnull:special-model-loader:1.4.0+pre.1" + implementation 'com.github.selimaj-dev:session-java:0.1.4' + include modImplementation("dev.kosmx.player-anim:player-animation-lib-fabric:${project.player_anim}") //You might want bendy-lib. playerAnimator will wrap it. // include modRuntimeOnly("io.github.kosmx.bendy-lib:bendy-lib-fabric:${project.bendylib_version}") @@ -27,16 +29,11 @@ dependencies { repositories { - maven { url "https://maven.parchmentmc.org" } - maven { - name = "FelNull Maven" - url = "https://maven.felnull.dev" - } - - maven { - name "KosmX's maven" - url 'https://maven.kosmx.dev/' - } + maven { url 'https://maven.fabricmc.net/' } // Fabric's official repo + maven { url 'https://jitpack.io' } + maven { url "https://maven.parchmentmc.org" } + maven { name = "FelNull Maven"; url = "https://maven.felnull.dev" } + maven { name = "KosmX maven"; url = 'https://maven.kosmx.dev/' } } processResources { diff --git a/src/main/java/org/saturnclient/saturnclient/SaturnClient.java b/src/main/java/org/saturnclient/saturnclient/SaturnClient.java index 0b9d836..e922ee9 100644 --- a/src/main/java/org/saturnclient/saturnclient/SaturnClient.java +++ b/src/main/java/org/saturnclient/saturnclient/SaturnClient.java @@ -7,7 +7,7 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.util.math.MatrixStack; import org.saturnclient.modules.ModManager; -import org.saturnclient.saturnclient.auth.Auth; +import org.saturnclient.saturnclient.client.ServiceClient; import org.saturnclient.saturnclient.config.ConfigManager; import org.saturnclient.saturnclient.cosmetics.Emotes; import org.saturnclient.saturnclient.cosmetics.Hats; @@ -75,7 +75,7 @@ public class SaturnClient implements ModInitializer { KeyInputHandler.register(); Emotes.initialize(); - if (Auth.authenticate()) { + if (ServiceClient.authenticate()) { Cloaks.initialize(); Hats.initialize(); LOGGER.info(MOD_ID + " initialization complete"); diff --git a/src/main/java/org/saturnclient/saturnclient/SaturnClientConfig.java b/src/main/java/org/saturnclient/saturnclient/SaturnClientConfig.java index db45255..de13281 100644 --- a/src/main/java/org/saturnclient/saturnclient/SaturnClientConfig.java +++ b/src/main/java/org/saturnclient/saturnclient/SaturnClientConfig.java @@ -1,6 +1,10 @@ package org.saturnclient.saturnclient; import org.saturnclient.saturnclient.config.Property; + +import java.util.Map; +import java.util.UUID; + import org.lwjgl.glfw.GLFW; import org.saturnclient.saturnclient.config.ConfigManager; import org.saturnclient.ui2.resources.Textures; @@ -16,6 +20,17 @@ public class SaturnClientConfig { public static Property bendyCloaks = Property.bool(true); public static Property openEmoteWheel = Property.keybinding(GLFW.GLFW_KEY_B); + static enum Role { + OWNER, + ADMIN, + PARTNER, + CONTRIBUTOR + } + + private static final Map ROLES = Map.of( + UUID.fromString("d362a042-28bd-49e1-a807-ae74dbe8aba9"), + Role.OWNER); + public static Identifier getLogo() { return realisticLogo.value ? Textures.REALISTIC_LOGO : Textures.LOGO; } @@ -33,12 +48,25 @@ public class SaturnClientConfig { * - Contributor: Aqua * - Other/player: White */ - public static Formatting getIconColor(String uuid) { - if (uuid.equals("d362a04228bd49e1a807ae74dbe8aba9")) { - return Formatting.DARK_RED; // Owner - } + public static Formatting getIconColor(UUID uuid) { + Role role = ROLES.get(uuid); - return Formatting.WHITE; + switch (role) { + case OWNER: + return Formatting.DARK_RED; + + case ADMIN: + return Formatting.RED; + + case PARTNER: + return Formatting.GOLD; + + case CONTRIBUTOR: + return Formatting.AQUA; + + default: + return Formatting.WHITE; + } } public static void init() { diff --git a/src/main/java/org/saturnclient/saturnclient/auth/Auth.java b/src/main/java/org/saturnclient/saturnclient/auth/Auth.java deleted file mode 100644 index 3bcd7af..0000000 --- a/src/main/java/org/saturnclient/saturnclient/auth/Auth.java +++ /dev/null @@ -1,283 +0,0 @@ -package org.saturnclient.saturnclient.auth; - -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Collectors; - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.util.Identifier; - -import org.saturnclient.saturnclient.cosmetics.Hats; -import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks; -import org.saturnclient.ui2.Utils; -import org.saturnclient.ui2.elements.Notification.NotificationKind; - -import dev.kosmx.playerAnim.api.layered.AnimationStack; -import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationAccess; -import dev.kosmx.playerAnim.minecraftApi.PlayerAnimationRegistry; - -import org.saturnclient.saturnclient.SaturnClient; - -public class Auth { - public static Map players = new HashMap<>(); - public static Map playerNames = new HashMap<>(); - public static String uuid; - private static Thread listenerThread; - private static Thread pingThread; - private static volatile boolean running = false; - - public static boolean authenticate() { - // Register shutdown hook ONCE - ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> close()); - - try { - if (SaturnClient.client.getSession() == null) { - SaturnClient.LOGGER.error("No active Minecraft session found"); - return false; - } - - String accessToken = SaturnClient.client.getSession().getAccessToken(); - SaturnClient.LOGGER.info("Authenticating"); - - Network.init(); - - Network.write(accessToken); - - String response = Network.read(); - - SaturnParser parser = new SaturnParser(response); - - uuid = parser.getString("uuid"); - String cloak = parser.getString("cloak"); - String hat = parser.getString("hat"); - - for (String availableCloak : parser.getArray("cloaks")) { - Cloaks.availableCloaks.add(availableCloak); - } - - for (String availableHat : parser.getArray("hats")) { - Hats.availableHats.add(availableHat); - } - - players.put(uuid, new SaturnPlayer(cloak, hat)); - - Cloaks.loadCloak(uuid); - - playerNames.put(SaturnClient.client.getSession().getUsername(), uuid); - - afterAuth(); - - startListenerThread(); - startPingThread(); - - return true; - } catch (Exception e) { - SaturnClient.LOGGER.error("Authentication failed", e); - return false; - } - } - - private static void startListenerThread() { - running = true; - listenerThread = new Thread(() -> { - try { - while (running) { - String message = Network.read(); - if (message == null) { - SaturnClient.LOGGER.error("Connection closed"); - running = false; - break; - } - - SaturnClient.LOGGER.info("Received: " + message); - - SaturnParser parser = new SaturnParser(message); - - switch (parser.method) { - case "player": - String uuid = parser.getString("uuid"); - if (parser.getBool("saturn")) { - String cloak = parser.getString("cloak"); - String hat = parser.getString("hat"); - players.put(uuid, new SaturnPlayer(cloak, hat)); - Cloaks.loadCloak(uuid); - } else { - playerNames.entrySet().removeIf(entry -> entry.getValue().equals(uuid)); - } - break; - - case "successful_transaction": - String cloak = parser.getStringOrNull("cloak"); - String hat = parser.getStringOrNull("hat"); - if (cloak != null) { - Cloaks.availableCloaks.add(cloak); - - } - if (hat != null) { - Hats.availableHats.add(hat); - } - - case "update_cloak": - String targetUuid = parser.getStringOrNull("uuid"); - String targetCloak = parser.getStringOrNull("cloak"); - if (targetUuid != null && targetCloak != null) { - SaturnPlayer player = players.get(targetUuid); - if (player != null) { - player.cloak = targetCloak; - } - } - break; - - case "update_hat": - targetUuid = parser.getStringOrNull("uuid"); - String targetHat = parser.getStringOrNull("hat"); - if (targetUuid != null && targetHat != null) { - SaturnPlayer player = players.get(targetUuid); - if (player != null) { - player.hat = targetHat; - } - } - break; - - case "emote": - targetUuid = parser.getStringOrNull("uuid"); - String emote = parser.getStringOrNull("name"); - - for (AbstractClientPlayerEntity player : SaturnClient.client.world.getPlayers()) { - if (player.getUuidAsString().replace("-", "").equals(targetUuid)) { - AnimationStack animationStack = PlayerAnimationAccess.getPlayerAnimLayer(player); - if (emote != null && !emote.isEmpty()) { - if (animationStack.isActive() && animationStack.getPriority() == 1000) { - animationStack.removeLayer(1000); - } - animationStack.addAnimLayer(1000, - PlayerAnimationRegistry - .getAnimation(Identifier.of("saturnclient", emote)) - .playAnimation()); - } else { - animationStack.removeLayer(1000); - } - } - } - break; - - default: - if (parser.error != null) { - String[] a = parser.error.replace("!", "").split(": "); - Utils.notify(NotificationKind.Error, a[0], a[1]); - } - break; - } - } - } catch (Exception e) { - SaturnClient.LOGGER.error("Error reading from server", e); - } finally { - close(); - } - }); - - listenerThread.setDaemon(true); - listenerThread.start(); - } - - private static void startPingThread() { - pingThread = new Thread(() -> { - try { - while (running && !Thread.currentThread().isInterrupted()) { - try { - Thread.sleep(25000); // 25 seconds - if (running) { - Network.write("ping"); - } - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); // Restore interrupt status - break; // Exit the loop on interruption - } - } - } catch (Exception e) { - if (!(e instanceof InterruptedException)) { - SaturnClient.LOGGER.error("Error in ping thread", e); - } - } - }); - - pingThread.setDaemon(true); - pingThread.start(); - } - - public static void close() { - running = false; - if (pingThread != null) { - pingThread.interrupt(); - } - if (listenerThread != null) { - listenerThread.interrupt(); - } - try { - close(); - SaturnClient.LOGGER.info("SaturnApi connection closed."); - } catch (Exception e) { - SaturnClient.LOGGER.error("Failed to close resources", e); - } - } - - public static void afterAuth() { - PlayerTracker.initialize(); - } - - public static void setCloak(String cloakName) { - try { - Network.write("set_cloak@cloak=" + cloakName + "@notify=" + stringifyPlayers()); - } catch (Exception e) { - SaturnClient.LOGGER.error("Request failed", e); - } - } - - public static void setHat(String hatName) { - try { - Network.write("set_hat@hat=" + hatName + "@notify=" + stringifyPlayers()); - } catch (Exception e) { - SaturnClient.LOGGER.error("Request failed", e); - } - } - - public static void emote(String name) { - try { - Network.write("emote@name=" + name + "@notify=" + stringifyPlayers()); - } catch (Exception e) { - SaturnClient.LOGGER.error("Request failed", e); - } - } - - public static String stringifyPlayers() { - return players.keySet().stream() - .filter(key -> key != uuid) - .collect(Collectors.joining("$")); - } - - public static void player(String name, String uuid) { - try { - playerNames.put(name, uuid.replaceAll("-", "")); - Network.write("player@uuid=" + uuid.replaceAll("-", "")); - } catch (Exception e) { - SaturnClient.LOGGER.error("Request failed", e); - } - } - - public static void buyCloak(String name) { - try { - Network.write("buy_cloak@cloak=" + name); - } catch (Exception e) { - SaturnClient.LOGGER.error("Request failed", e); - } - } - - public static void buyHat(String name) { - try { - Network.write("buy_hat@hat=" + name); - } catch (Exception e) { - SaturnClient.LOGGER.error("Request failed", e); - } - } -} diff --git a/src/main/java/org/saturnclient/saturnclient/auth/Network.java b/src/main/java/org/saturnclient/saturnclient/auth/Network.java deleted file mode 100644 index 507f857..0000000 --- a/src/main/java/org/saturnclient/saturnclient/auth/Network.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.saturnclient.saturnclient.auth; - -import java.io.*; -import java.net.*; -import java.security.*; -import java.util.Base64; -import javax.crypto.*; -import javax.crypto.spec.*; -import java.security.interfaces.*; -import java.security.spec.X509EncodedKeySpec; - -public class Network { - static Socket socket; - static PrintWriter out; - static BufferedReader in; - static byte[] key = new byte[32]; - - private static final int CONNECTION_TIMEOUT = 5000; - private static final int READ_TIMEOUT = 5000; - - public static class AES { - public static byte[] encryptAES256(String message, byte[] key) throws Exception { - Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); - SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); - cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); - byte[] encryptedMessage = cipher.doFinal(message.getBytes()); - return encryptedMessage; - } - - public static String decryptAES256(byte[] encryptedMessage, byte[] key) throws Exception { - Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); - SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); - cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); - byte[] decryptedMessage = cipher.doFinal(encryptedMessage); - return new String(decryptedMessage); - } - } - - public static void init() throws Exception { - // Generate AES key - new SecureRandom().nextBytes(key); - - socket = new Socket(); - socket.connect(new InetSocketAddress("77.247.92.168", 8080), CONNECTION_TIMEOUT); - - socket.setSoTimeout(READ_TIMEOUT); - - // out = new DataOutputStream(socket.getOutputStream()); - out = new PrintWriter(socket.getOutputStream(), true); - in = new BufferedReader(new InputStreamReader(socket.getInputStream())); - - StringBuilder publicKeyBuilder = new StringBuilder(); - String line; - while (!(line = in.readLine()).contains("-----END PUBLIC KEY-----")) { - publicKeyBuilder.append(line).append("\n"); - } - publicKeyBuilder.append(line); - - String publicKeyPem = publicKeyBuilder.toString(); - - String publicKeyBase64 = publicKeyPem.replace("-----BEGIN PUBLIC KEY-----", "") - .replace("-----END PUBLIC KEY-----", "").replace("\n", "").replace("\r", ""); - byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyBase64); - - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes); - KeyFactory keyFactory = KeyFactory.getInstance("RSA"); - RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec); - - Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); - rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey); - byte[] encryptedKey = rsaCipher.doFinal(key); - - out.println(Base64.getEncoder().encodeToString(encryptedKey)); - } - - public static void write(String message) { - try { - out.println(Base64.getEncoder().encodeToString(AES.encryptAES256(message, key))); - } catch (Exception e) { - throw new RuntimeException("Failed to write to server: " + e.getMessage()); - } - } - - public static String read() { - try { - String msg = in.readLine(); - if (msg != null) { - return AES.decryptAES256(Base64.getDecoder().decode(msg), key); - } else { - return ""; - } - } catch (Exception e) { - return ""; - } - } - - public static void close() { - try { - socket.close(); - out.close(); - in.close(); - } catch (Exception e) { - } - } -} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/saturnclient/auth/SaturnParser.java b/src/main/java/org/saturnclient/saturnclient/auth/SaturnParser.java deleted file mode 100644 index 60d1c31..0000000 --- a/src/main/java/org/saturnclient/saturnclient/auth/SaturnParser.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.saturnclient.saturnclient.auth; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -public class SaturnParser { - public String method = ""; - public String error; - private Map params = new HashMap<>(); - - public SaturnParser(String input) throws IOException { - String[] parts = input.split("@"); - - if (parts.length == 0) { - throw new IOException("Invalid input string"); - } - - if (parts[0].startsWith("!")) { - error = input; - } - - method = parts[0]; - - for (int i = 1; i < parts.length; i++) { - String[] keyValue = parts[i].split("="); - if (keyValue.length == 2) { - params.put(keyValue[0].trim(), keyValue[1].trim()); - } else if (keyValue.length == 1) { - params.put(keyValue[0].trim(), ""); - } else { - throw new IOException("Invalid parameter format: " + parts[i]); - } - } - } - - public String getString(String i) throws IOException { - String val = params.get(i); - if (val != null) { - return val; - } else { - throw new IOException("Parameter not found " + i); - } - } - - public String getStringOrNull(String i) throws IOException { - String val = params.get(i); - return val; - } - - public boolean getBool(String i) throws IOException { - String val = params.get(i); - if (val != null) { - return val.equals("true"); - } else { - throw new IOException("Parameter not found " + i); - } - } - - public String[] getArray(String i) throws IOException { - String val = params.get(i); - if (val != null) { - if (val.isEmpty()) { - return new String[] {}; - } - return val.split("\\$"); - } else { - throw new IOException("Parameter not found " + i); - } - } -} diff --git a/src/main/java/org/saturnclient/saturnclient/auth/SaturnPlayer.java b/src/main/java/org/saturnclient/saturnclient/auth/SaturnPlayer.java deleted file mode 100644 index 8ffe19e..0000000 --- a/src/main/java/org/saturnclient/saturnclient/auth/SaturnPlayer.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.saturnclient.saturnclient.auth; - -public class SaturnPlayer { - public String cloak = ""; - public String hat = ""; - - public SaturnPlayer(String cloak, String hat) { - this.cloak = cloak; - this.hat = hat; - } -} diff --git a/src/main/java/org/saturnclient/saturnclient/client/ServiceClient.java b/src/main/java/org/saturnclient/saturnclient/client/ServiceClient.java new file mode 100644 index 0000000..8876664 --- /dev/null +++ b/src/main/java/org/saturnclient/saturnclient/client/ServiceClient.java @@ -0,0 +1,116 @@ +package org.saturnclient.saturnclient.client; + +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.client.player.SaturnPlayer; +import org.saturnclient.saturnclient.cosmetics.Hats; +import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks; + +import dev.selimaj.session.Session; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; + +public class ServiceClient { + private static Session session; + public static UUID uuid; + + public static boolean connectTimeout() { + try { + session = Session.connect("ws://127.0.0.1:8080", 10, TimeUnit.SECONDS); + return true; + } catch (Exception e) { + return false; + } + } + + public static boolean authenticate() { + ClientLifecycleEvents.CLIENT_STOPPING.register(_o -> { + if (session != null) + try { + session.close(); + } catch (Exception e) { + SaturnClient.LOGGER.error("Unable to close Saturn session"); + + } + }); + + try { + var mcSession = SaturnClient.client.getSession(); + if (mcSession == null) { + SaturnClient.LOGGER.error("No active Minecraft session found"); + return false; + } + + String accessToken = mcSession.getAccessToken(); + uuid = mcSession.getUuidOrNull(); + String username = mcSession.getUsername(); + + SaturnClient.LOGGER.info("Authenticating with UUID: " + accessToken); + + if (!connectTimeout()) { + SaturnClient.LOGGER.error("Unable to authenticate: Session Server Timeout"); + return false; + } + + ServiceMethods.AuthResponse response = session.request(ServiceMethods.Authenticate, accessToken).get(); + + for (String availableCloak : response.cloaks()) { + Cloaks.availableCloaks.add(availableCloak); + } + + for (String availableHat : response.hats()) { + Hats.availableHats.add(availableHat); + } + + SaturnPlayer.set(uuid, username, new SaturnPlayer(uuid, username, response.cloak(), response.hat())); + + Cloaks.loadCloak(uuid); + + return true; + } catch (Exception e) { + SaturnClient.LOGGER.error("Authentication failed", e); + return false; + } + } + + public static void setCloak(String cloak) { + try { + session.request(ServiceMethods.SetCloak, cloak).get(); + } catch (Exception e) { + SaturnClient.LOGGER.error("Failed to set cloak (service): ", e); + } + } + + public static void setHat(String hat) { + try { + session.request(ServiceMethods.SetHat, hat).get(); + } catch (Exception e) { + SaturnClient.LOGGER.error("Failed to set hat (service): ", e); + } + } + + public static void buyCloak(String cloak) { + try { + session.request(ServiceMethods.BuyCloak, cloak).get(); + } catch (Exception e) { + SaturnClient.LOGGER.error("Failed to buy cloak (service): ", e); + } + } + + public static void buyHat(String hat) { + try { + session.request(ServiceMethods.BuyHat, hat).get(); + } catch (Exception e) { + SaturnClient.LOGGER.error("Failed to buy hat (service): ", e); + } + } + + public static void emote(String emote) { + try { + session.request(ServiceMethods.Emote, emote).get(); + } catch (Exception e) { + SaturnClient.LOGGER.error("Failed to emote (service): ", e); + } + } +} diff --git a/src/main/java/org/saturnclient/saturnclient/client/ServiceMethods.java b/src/main/java/org/saturnclient/saturnclient/client/ServiceMethods.java new file mode 100644 index 0000000..7eb9dea --- /dev/null +++ b/src/main/java/org/saturnclient/saturnclient/client/ServiceMethods.java @@ -0,0 +1,27 @@ +package org.saturnclient.saturnclient.client; + +import dev.selimaj.session.types.Method; + +public class ServiceMethods { + public record AuthResponse(String cloak, String hat, String[] cloaks, String[] hats) { + } + + public static final Method Authenticate = new Method<>("auth", + String.class, AuthResponse.class, String.class); + + // Equip + public static final Method SetCloak = new Method<>("set_cloak", + String.class, String.class, String.class); + public static final Method SetHat = new Method<>("set_hat", + String.class, String.class, String.class); + + // Buy + public static final Method BuyCloak = new Method<>("buy_cloak", + String.class, String.class, String.class); + public static final Method BuyHat = new Method<>("buy_hat", + String.class, String.class, String.class); + + // Emote + public static final Method Emote = new Method<>("emote", + String.class, String.class, String.class); +} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/saturnclient/auth/PlayerTracker.java b/src/main/java/org/saturnclient/saturnclient/client/player/PlayerTracker.java similarity index 90% rename from src/main/java/org/saturnclient/saturnclient/auth/PlayerTracker.java rename to src/main/java/org/saturnclient/saturnclient/client/player/PlayerTracker.java index a6aff97..2a27c6b 100644 --- a/src/main/java/org/saturnclient/saturnclient/auth/PlayerTracker.java +++ b/src/main/java/org/saturnclient/saturnclient/client/player/PlayerTracker.java @@ -1,8 +1,9 @@ -package org.saturnclient.saturnclient.auth; +package org.saturnclient.saturnclient.client.player; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import org.saturnclient.saturnclient.SaturnClient; + import net.minecraft.client.network.PlayerListEntry; import net.minecraft.client.MinecraftClient; @@ -45,8 +46,7 @@ public class PlayerTracker { private static void onPlayerJoin(MinecraftClient client, PlayerListEntry player) { GameProfile profile = player.getProfile(); - String uuid = profile.getId().toString(); - if (uuid != Auth.uuid) - Auth.player(profile.getName(), uuid); + UUID uuid = profile.getId(); + SaturnPlayer.player(uuid); } } diff --git a/src/main/java/org/saturnclient/saturnclient/client/player/SaturnPlayer.java b/src/main/java/org/saturnclient/saturnclient/client/player/SaturnPlayer.java new file mode 100644 index 0000000..5f18c51 --- /dev/null +++ b/src/main/java/org/saturnclient/saturnclient/client/player/SaturnPlayer.java @@ -0,0 +1,54 @@ +package org.saturnclient.saturnclient.client.player; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.saturnclient.saturnclient.client.ServiceClient; + +public class SaturnPlayer { + private static Map PLAYERS = new HashMap<>(); + private static Map PLAYER_NAMES = new HashMap<>(); + + public String cloak = ""; + public String hat = ""; + public final UUID uuid; + public final String name; + + public SaturnPlayer(UUID uuid, String name, String cloak, String hat) { + this.cloak = cloak; + this.hat = hat; + this.uuid = uuid; + this.name = name; + } + + public static SaturnPlayer get() { + return PLAYERS.get(ServiceClient.uuid); + } + + public static SaturnPlayer get(UUID uuid) { + return PLAYERS.get(uuid); + } + + public static SaturnPlayer get(String name) { + UUID uuid = PLAYER_NAMES.get(name); + if (uuid == null) + return null; + return PLAYERS.get(uuid); + } + + public static void set(UUID uuid, String name, SaturnPlayer player) { + PLAYER_NAMES.put(name, uuid); + PLAYERS.put(uuid, player); + } + + public static void player(UUID uuid) { + if (PLAYERS.containsKey(uuid)) { + return; + } + + // If offline then leave + + PLAYERS.put(uuid, null); + } +} diff --git a/src/main/java/org/saturnclient/saturnclient/cosmetics/CloakFeatureRenderer.java b/src/main/java/org/saturnclient/saturnclient/cosmetics/CloakFeatureRenderer.java index 6ce1401..7f869a3 100644 --- a/src/main/java/org/saturnclient/saturnclient/cosmetics/CloakFeatureRenderer.java +++ b/src/main/java/org/saturnclient/saturnclient/cosmetics/CloakFeatureRenderer.java @@ -1,7 +1,7 @@ package org.saturnclient.saturnclient.cosmetics; import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.auth.Auth; +import org.saturnclient.saturnclient.client.player.SaturnPlayer; import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks; import net.minecraft.client.render.OverlayTexture; @@ -290,13 +290,9 @@ public class CloakFeatureRenderer extends FeatureRenderer availableCloaks = new ArrayList<>(); public static Identifier cloakCacheIdentifier = null; - public static final Map> animatedCloaks = new ConcurrentHashMap<>(); - private static final Map lastFrameTime = new ConcurrentHashMap<>(); + public static final Map> animatedCloaks = new ConcurrentHashMap<>(); + private static final Map lastFrameTime = new ConcurrentHashMap<>(); private static final ExecutorService CLOAK_LOADER_EXECUTOR = Executors.newFixedThreadPool( Math.min(4, Runtime.getRuntime().availableProcessors()), @@ -54,17 +55,6 @@ public class Cloaks { availableCloaks.add(0, ""); } - /** - * Handles loading and caching of a new cloak texture. - * - * @param cloakName Name of the cloak file to load - */ - public static void setCloak(String uuid, String cloakName) { - Auth.setCloak(cloakName); - setCloakSilent(uuid, cloakName); - SaturnClient.LOGGER.info("Cloak set to " + cloakName); - } - /** * Sets cloak of the current player * @@ -72,7 +62,8 @@ public class Cloaks { */ public static void setCloak(String cloakName) { if (availableCloaks.contains(cloakName)) { - setCloak(Auth.uuid, cloakName); + setCloak(ServiceClient.uuid, cloakName); + ServiceClient.setCloak(cloakName); } } @@ -82,10 +73,12 @@ public class Cloaks { * * @param cloakName Name of the cloak file to load */ - public static void setCloakSilent(String uuid, String cloakName) { - SaturnPlayer player = Auth.players.get(uuid); + public static void setCloak(UUID uuid, String cloakName) { + SaturnPlayer player = SaturnPlayer.get(uuid); + if (player == null) { - Auth.players.put(uuid, new SaturnPlayer(cloakName, null)); + // Auth.players.put(uuid, new SaturnPlayer(cloakName, null)); + // TODO: Address this functionality } else { player.cloak = cloakName; } @@ -99,8 +92,9 @@ public class Cloaks { * * @param cloakName Name of the cloak file to load */ - public static void loadCloak(String uuid) { - SaturnPlayer player = Auth.players.get(uuid); + public static void loadCloak(UUID uuid) { + SaturnPlayer player = SaturnPlayer.get(uuid); + if (player != null && player.cloak != null) { if (!player.cloak.isEmpty()) { if (Arrays.asList(ANIMATED_CLOAKS).contains(player.cloak)) { @@ -146,7 +140,7 @@ public class Cloaks { } } - public static CompletableFuture loadAnimatedCloakAsync(String uuid, String cloakName) { + public static CompletableFuture loadAnimatedCloakAsync(UUID uuid, String cloakName) { return CompletableFuture.runAsync(() -> { String fileName = cloakName + ".gif"; @@ -196,7 +190,7 @@ public class Cloaks { } else { // Queue for main thread execution // SaturnClient.client.execute( - // () -> IdentifierUtils.registerBufferedImageTexture(frameIdentifier, frame)); + // () -> IdentifierUtils.registerBufferedImageTexture(frameIdentifier, frame)); } animatedFrames.add(new AnimatedCloakData(frameIdentifier, delay)); @@ -226,16 +220,14 @@ public class Cloaks { }, CLOAK_LOADER_EXECUTOR); } - public static Identifier getCurrentCloakTexture(String uuid) { - if (!Auth.players.containsKey(uuid)) { + public static Identifier getCurrentCloakTexture(UUID uuid) { + SaturnPlayer player = SaturnPlayer.get(uuid); + + if (player == null || player.cloak.isEmpty()) { return null; } - String cloakName = Auth.players.get(uuid).cloak; - - if (cloakName.isEmpty()) { - return null; - } + String cloakName = player.cloak; if (Arrays.asList(ANIMATED_CLOAKS).contains(cloakName)) { List frames = animatedCloaks.get(uuid); diff --git a/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java index 7f6ad17..1504913 100644 --- a/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ b/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java @@ -7,7 +7,7 @@ import net.minecraft.client.util.InputUtil; import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.auth.Auth; +import org.saturnclient.saturnclient.client.ServiceClient; import org.saturnclient.ui2.screens.EmoteWheel; import org.saturnclient.ui2.screens.ShiftMenu; @@ -47,7 +47,7 @@ public class KeyInputHandler { AnimationStack animationStack = PlayerAnimationAccess.getPlayerAnimLayer(SaturnClient.client.player); if (animationStack.isActive() && animationStack.getPriority() == 1000) { animationStack.removeLayer(1000); - Auth.emote(""); + ServiceClient.emote(""); } } }); diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java index defa7f5..b0e9d34 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/NameTagMixin.java @@ -15,7 +15,10 @@ import net.minecraft.util.Formatting; import net.minecraft.util.math.Vec3d; import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.auth.Auth; +import org.saturnclient.saturnclient.client.player.SaturnPlayer; + +import java.util.UUID; + import org.joml.Matrix4f; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.Inject; @@ -37,12 +40,12 @@ public abstract class NameTagMixin { private void onRenderLabelIfPresent(S state, Text text, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) { - String uuid = isSaturn(state); + UUID uuid = isSaturn(state); if (uuid != null) { MutableText iconText = Text.literal(SaturnClientConfig.getSaturnIndicator()) - .styled(style -> style.withColor(SaturnClientConfig.getIconColor(uuid))); - + .styled(style -> style.withColor(SaturnClientConfig.getIconColor(uuid))); + Text nameText = text.copy().styled(style -> style.withColor(Formatting.WHITE)); renderLabel(state, iconText.append(nameText), matrices, @@ -52,13 +55,11 @@ public abstract class NameTagMixin { } } - private String isSaturn(S state) { + private UUID isSaturn(S state) { if (state instanceof PlayerEntityRenderState) { String name = ((PlayerEntityRenderState) state).name; - String uuid = Auth.playerNames.get(name); - if (Auth.players.containsKey(uuid)) { - return uuid; - } + SaturnPlayer player = SaturnPlayer.get(name); + return player.uuid; } return null; diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java new file mode 100644 index 0000000..7e4e0af --- /dev/null +++ b/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java @@ -0,0 +1,26 @@ +package org.saturnclient.saturnclient.mixin; + +import org.saturnclient.saturnclient.SaturnClientConfig; +import org.saturnclient.ui2.screens.TitleMenu; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.TitleScreen; + +@Mixin(MinecraftClient.class) +public class SetScreenMixin { + @ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true) + private Screen replaceTitleScreen(Screen screen) { + if (SaturnClientConfig.saturnTitleScreen.value) { + if (screen instanceof TitleScreen) + return new TitleMenu(); + if (screen == null && ((MinecraftClient) (Object) this).world == null) + return new TitleMenu(); + } + + return screen; + } +} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java new file mode 100644 index 0000000..846b1cc --- /dev/null +++ b/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java @@ -0,0 +1,162 @@ +package org.saturnclient.saturnclient.mixin; + +import java.util.Optional; +import java.util.function.Consumer; + +import org.saturnclient.ui2.RenderScope; +import org.saturnclient.ui2.resources.Textures; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.SplashOverlay; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.resource.ResourceReload; +import net.minecraft.util.Util; +import net.minecraft.util.math.MathHelper; + +@Mixin(SplashOverlay.class) +public abstract class SplashOverlayMixin { + + @Shadow + private MinecraftClient client; + @Shadow + private ResourceReload reload; + + @Shadow(remap = false) + private long reloadCompleteTime; + + @Shadow(remap = false) + private long reloadStartTime; + + @Shadow(remap = false) + private boolean reloading; + + @Shadow(remap = false) + private Consumer> exceptionHandler; + + @Shadow(remap = false) + private float progress; + + private static int withAlpha(int color, int alpha) { + return color & 0xFFFFFF | alpha << 24; + } + + /** + * @reason Replace vanilla splash rendering completely but keep exit logic + */ + @Overwrite + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + int screenWidth = context.getScaledWindowWidth(); + int screenHeight = context.getScaledWindowHeight(); + long currentTime = Util.getMeasuringTimeMs(); + + // Initialize reload start time if not set + if (reloadStartTime == -1L) { + reloadStartTime = currentTime; + } + + // Compute fade-out progress after reload completes + float fadeOutProgress = reloadCompleteTime > -1L + ? (float) (currentTime - reloadCompleteTime) / 1000f + : -1f; + + int alpha = fadeOutProgress >= 0f + ? MathHelper.ceil((1.0f - MathHelper.clamp(fadeOutProgress - 1f, 0f, 1f)) * 255f) + : 255; + + // Compute fade-in progress while reloading + float reloadProgress = reloadStartTime > -1L + ? (float) (currentTime - reloadStartTime) / 500f + : -1f; + + // Get render scope for better UI + RenderScope scope = new RenderScope(context); + scope.setRenderLayer(RenderLayer::getGuiTextured); + + // Draw background overlay + if (fadeOutProgress >= 1.0F) { + renderCurrentScreen(context, mouseX, mouseY, delta); + int overlayAlpha = computeOverlayAlpha(fadeOutProgress - 1f); + // context.fill(0, 0, screenWidth, screenHeight, + // withAlpha(0x53389E, overlayAlpha)); + scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, + withAlpha(0xFFFFFF, overlayAlpha)); + } else if (reloading) { + if (reloadProgress < 1.0F) { + renderCurrentScreen(context, mouseX, mouseY, delta); + } + scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, + withAlpha(0xFFFFFF, alpha)); + } else { + scope.drawTexture(Textures.SPLASH, 0, 0, 0, 0, screenWidth, screenHeight, + withAlpha(0xFFFFFF, alpha)); + } + + float u = this.reload.getProgress(); + this.progress = MathHelper.clamp(this.progress * 0.95F + u * 0.050000012F, 0.0F, 1.0F); + + // Draw central logo + drawLogo(scope, screenWidth, screenHeight, alpha); + renderProgressBar(scope, context, screenWidth, screenHeight, alpha); + + // Remove overlay after fade-out completes + if (fadeOutProgress >= 2.0F) { + client.setOverlay(null); + } + + // Handle reload completion and exceptions + handleReloadCompletion(context); + } + + private void renderCurrentScreen(DrawContext context, int mouseX, int mouseY, float delta) { + if (client.currentScreen != null) { + client.currentScreen.render(context, mouseX, mouseY, delta); + } + } + + /** Draw the main logo centered */ + private void drawLogo(RenderScope scope, int screenWidth, int screenHeight, int alpha) { + scope.drawTexture(Textures.LOGO, (screenWidth - 60) / 2, ((screenHeight - 60) / 2) - 20, 0, 0, 60, 60, + withAlpha(0xFFFFFF, alpha)); + } + + private void renderProgressBar(RenderScope scope, DrawContext context, int screenWidth, int screenHeight, + int alpha) { + int progressY = ((screenHeight - 5) / 2) + 25; + context.drawBorder((screenWidth - 120) / 2, progressY, 120, 5, withAlpha(0xFFFFFF, alpha)); + + int progressWidth = Math.min((int) (progress * 120), 120); + int progressX = (screenWidth - 120) / 2; + + context.fill(progressX, progressY, progressX + progressWidth, progressY + 5, withAlpha(0xFFFFFF, alpha)); + } + + /** Compute overlay alpha from fade progress */ + private int computeOverlayAlpha(float progress) { + return MathHelper.ceil((1.0F - MathHelper.clamp(progress, 0.0F, 1.0F)) * 255.0F); + } + + /** Handle reload completion logic */ + private void handleReloadCompletion(DrawContext context) { + float reloadProgress = reloadStartTime > -1L ? (float) (Util.getMeasuringTimeMs() - reloadStartTime) / 500f + : -1f; + + if (reloadCompleteTime == -1L && reload.isComplete() && (!reloading || reloadProgress >= 2.0F)) { + try { + reload.throwException(); + exceptionHandler.accept(Optional.empty()); + } catch (Throwable ex) { + exceptionHandler.accept(Optional.of(ex)); + } + + reloadCompleteTime = Util.getMeasuringTimeMs(); + + if (client.currentScreen != null) { + client.currentScreen.init(client, context.getScaledWindowWidth(), context.getScaledWindowHeight()); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java index 058ec46..a1f4f37 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/TabListMixin.java @@ -1,13 +1,14 @@ package org.saturnclient.saturnclient.mixin; import net.minecraft.client.network.PlayerListEntry; -import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import java.util.UUID; + import org.jetbrains.annotations.Nullable; import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.auth.Auth; +import org.saturnclient.saturnclient.client.player.SaturnPlayer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; @@ -30,13 +31,13 @@ public abstract class TabListMixin { public Text getDisplayName() { GameProfile profile = ((PlayerListEntry) (Object) this).getProfile(); String name = profile.getName(); - String uuid = profile.getId().toString().replaceAll("-", ""); + UUID uuid = profile.getId(); - MutableText iconText = Text.literal(SaturnClientConfig.getSaturnIndicator()) - .styled(style -> style.withColor(SaturnClientConfig.getIconColor(uuid))); - - Text nameText = Text.literal(name).styled(style -> style.withColor(Formatting.WHITE)); - - return Auth.players.containsKey(uuid) ? iconText.append(nameText) : Text.literal(name); + if (SaturnPlayer.get(uuid) != null) { + return Text.literal(SaturnClientConfig.getSaturnIndicator()) + .styled(style -> style.withColor(SaturnClientConfig.getIconColor(uuid))) + .append(Text.literal(name).styled(style -> style.withColor(Formatting.WHITE))); + } + return Text.literal(name); } } diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/TitleScreenMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/TitleScreenMixin.java deleted file mode 100644 index 44151c1..0000000 --- a/src/main/java/org/saturnclient/saturnclient/mixin/TitleScreenMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.saturnclient.saturnclient.mixin; - -import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.ui2.screens.TitleMenu; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import net.minecraft.client.gui.screen.TitleScreen; - -@Mixin(TitleScreen.class) -public class TitleScreenMixin { - @Inject(method = "init", at = @At("HEAD"), cancellable = true) - private void onInit(CallbackInfo ci) { - if (SaturnClientConfig.saturnTitleScreen.value) { - SaturnClient.client.setScreen(new TitleMenu()); - ci.cancel(); - } - } -} diff --git a/src/main/java/org/saturnclient/ui2/RenderScope.java b/src/main/java/org/saturnclient/ui2/RenderScope.java index 8954e05..231428c 100644 --- a/src/main/java/org/saturnclient/ui2/RenderScope.java +++ b/src/main/java/org/saturnclient/ui2/RenderScope.java @@ -12,8 +12,11 @@ import org.saturnclient.ui2.resources.Fonts; import com.mojang.blaze3d.systems.RenderSystem; import org.saturnclient.saturnclient.SaturnClient; +import org.saturnclient.saturnclient.mixin.DrawContextAccessor; + import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer.TextLayerType; +import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.ScreenRect; import net.minecraft.client.render.DiffuseLighting; import net.minecraft.client.render.OverlayTexture; @@ -42,6 +45,10 @@ public class RenderScope { private int opacity = 255 << 24; private final ItemRenderState itemRenderState; + public RenderScope(DrawContext context) { + this(context.getMatrices(), ((DrawContextAccessor) context).getVertexConsumers()); + } + public RenderScope(MatrixStack matrices, VertexConsumerProvider.Immediate vertexConsumers) { this.matrices = matrices; this.vertexConsumers = vertexConsumers; diff --git a/src/main/java/org/saturnclient/ui2/SaturnScreen.java b/src/main/java/org/saturnclient/ui2/SaturnScreen.java index d69b579..05bde40 100644 --- a/src/main/java/org/saturnclient/ui2/SaturnScreen.java +++ b/src/main/java/org/saturnclient/ui2/SaturnScreen.java @@ -22,6 +22,7 @@ import net.minecraft.util.Identifier; public abstract class SaturnScreen extends Screen { private final Pool pool = new Pool(3); protected List elements = new ArrayList<>(); + protected float backgroundOpacity = 1.0f; public int blurDuration = 700; public float blurProgress = 0.0f; public int backgroundBlur = 10; @@ -43,7 +44,7 @@ public abstract class SaturnScreen extends Screen { synchronized (elements) { elements.add(element); } - + if (element.animation != null) { element.animation.init(element); @@ -93,16 +94,16 @@ public abstract class SaturnScreen extends Screen { mouseY *= 2; if (client.world == null && client.getCurrentServerEntry() == null) { - ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, 1.0F, delta); + ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, backgroundOpacity, delta); } PostEffectProcessor postEffectProcessor = this.client.getShaderLoader().loadPostEffect( - Identifier.ofVanilla("blur"), - DefaultFramebufferSet.MAIN_ONLY); - if (postEffectProcessor != null) { - postEffectProcessor.setUniforms("Radius", backgroundBlur * blurProgress); - postEffectProcessor.render(this.client.getFramebuffer(), this.pool); - } + Identifier.ofVanilla("blur"), + DefaultFramebufferSet.MAIN_ONLY); + if (postEffectProcessor != null) { + postEffectProcessor.setUniforms("Radius", backgroundBlur * blurProgress); + postEffectProcessor.render(this.client.getFramebuffer(), this.pool); + } // We are using a Abstracted RenderScope because older minecraft versions don't // use DrawContext diff --git a/src/main/java/org/saturnclient/ui2/resources/Textures.java b/src/main/java/org/saturnclient/ui2/resources/Textures.java index 1e29bdd..cdaac79 100644 --- a/src/main/java/org/saturnclient/ui2/resources/Textures.java +++ b/src/main/java/org/saturnclient/ui2/resources/Textures.java @@ -28,6 +28,7 @@ public class Textures { public static final Identifier REALISTIC_LOGO = Identifier.of("saturnclient", "textures/logo/realistic.png"); public static final Identifier LOGO_TEXT = Identifier.of("saturnclient", "textures/logo/text.png"); public static final Identifier LOGO_TEXT_BIG = Identifier.of("saturnclient", "textures/logo/text_big.png"); + public static final Identifier SPLASH = Identifier.of("saturnclient", "textures/gui/splash.png"); // Widgets public static final Identifier BUTTON_BORDER = Identifier.of("saturnclient", "button_border"); diff --git a/src/main/java/org/saturnclient/ui2/screens/EmoteWheel.java b/src/main/java/org/saturnclient/ui2/screens/EmoteWheel.java index 73ba8d4..6e4ad52 100644 --- a/src/main/java/org/saturnclient/ui2/screens/EmoteWheel.java +++ b/src/main/java/org/saturnclient/ui2/screens/EmoteWheel.java @@ -2,8 +2,7 @@ package org.saturnclient.ui2.screens; import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.saturnclient.SaturnClientConfig; -import org.saturnclient.saturnclient.auth.Auth; -// import org.saturnclient.saturnclient.auth.Auth; +import org.saturnclient.saturnclient.client.ServiceClient; import org.saturnclient.saturnclient.cosmetics.Emotes; import org.saturnclient.ui2.SaturnScreen; import org.saturnclient.ui2.Utils; @@ -71,7 +70,7 @@ public class EmoteWheel extends SaturnScreen { animationStack.addAnimLayer(1000, PlayerAnimationRegistry.getAnimation(Identifier.of("saturnclient", emote)).playAnimation()); - Auth.emote(emote); + ServiceClient.emote(emote); close(); }).dimensions(70, 70).centerOffset(width, height, -80 + (col * 80), -35 + (row * 80)) .animation(new Fade(700))); diff --git a/src/main/java/org/saturnclient/ui2/screens/TitleMenu.java b/src/main/java/org/saturnclient/ui2/screens/TitleMenu.java index 8bcde8e..a97a6c4 100644 --- a/src/main/java/org/saturnclient/ui2/screens/TitleMenu.java +++ b/src/main/java/org/saturnclient/ui2/screens/TitleMenu.java @@ -26,8 +26,10 @@ public class TitleMenu extends SaturnScreen { public void ui() { backgroundBlur = 0; - draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(98, 10).centerOffset(width, height, 0, -36).animation(new Fade(700))); - draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -82).animation(new SlideY(700, -20))); + draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(98, 10).centerOffset(width, height, 0, -36) + .animation(new Fade(700))); + draw(new ImageTexture(SaturnClientConfig.getLogo()).dimensions(98, 98).centerOffset(width, height, 0, -82) + .animation(new SlideY(700, -20))); draw(new Button("SINGLEPLAYER", () -> { client.setScreen(new SelectWorldScreen(new TitleMenu())); diff --git a/src/main/java/org/saturnclient/ui2/screens/cosmetics/CloakMenu.java b/src/main/java/org/saturnclient/ui2/screens/cosmetics/CloakMenu.java index aae0b06..2abb28d 100644 --- a/src/main/java/org/saturnclient/ui2/screens/cosmetics/CloakMenu.java +++ b/src/main/java/org/saturnclient/ui2/screens/cosmetics/CloakMenu.java @@ -1,8 +1,7 @@ package org.saturnclient.ui2.screens.cosmetics; import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.auth.Auth; -import org.saturnclient.saturnclient.auth.SaturnPlayer; +import org.saturnclient.saturnclient.client.player.SaturnPlayer; import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks; import org.saturnclient.ui2.resources.Textures; import org.saturnclient.ui2.SaturnScreen; @@ -27,15 +26,15 @@ public class CloakMenu extends SaturnScreen { int row = 0; int col = 0; - - SaturnPlayer player = Auth.players.get(Auth.uuid); + + SaturnPlayer player = SaturnPlayer.get(); if (player != null) { for (String cloak : Cloaks.availableCloaks) { scroll.draw(new CosmeticPreview(cloak == player.cloak, Textures.getCloakPreview(cloak), () -> { Cloaks.setCloak(cloak); }).position((50 + g) * col, (111 + g) * row)); - + if (col == 5) { col = 0; row++; @@ -46,18 +45,18 @@ public class CloakMenu extends SaturnScreen { } int scrollWidth = 480 + 10 + (g * 2) + (p * 2); - + draw(scroll.dimensions(scrollWidth, 350).center(width, height)); - draw(new SkinPreview(-30.0f, false).scale(3.5f).position(scroll.x + (scrollWidth - 220), scroll.y+40)); + draw(new SkinPreview(-30.0f, false).scale(3.5f).position(scroll.x + (scrollWidth - 220), scroll.y + 40)); draw(new Sidebar(2, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0)); draw(new TabMenu(0, - new TabMenuComponent(Textures.CLOAK, () -> {}), - new TabMenuComponent(Textures.HAT, () -> { - SaturnClient.client.setScreen(new HatMenu()); - }) - ).centerOffset(width, height, 0, -195)); + new TabMenuComponent(Textures.CLOAK, () -> { + }), + new TabMenuComponent(Textures.HAT, () -> { + SaturnClient.client.setScreen(new HatMenu()); + })).centerOffset(width, height, 0, -195)); } } diff --git a/src/main/java/org/saturnclient/ui2/screens/cosmetics/HatMenu.java b/src/main/java/org/saturnclient/ui2/screens/cosmetics/HatMenu.java index d81a9cb..06deb3c 100644 --- a/src/main/java/org/saturnclient/ui2/screens/cosmetics/HatMenu.java +++ b/src/main/java/org/saturnclient/ui2/screens/cosmetics/HatMenu.java @@ -1,8 +1,7 @@ package org.saturnclient.ui2.screens.cosmetics; import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.auth.Auth; -import org.saturnclient.saturnclient.auth.SaturnPlayer; +import org.saturnclient.saturnclient.client.player.SaturnPlayer; import org.saturnclient.saturnclient.cosmetics.Hats; import org.saturnclient.ui2.resources.Textures; import org.saturnclient.ui2.SaturnScreen; @@ -27,15 +26,15 @@ public class HatMenu extends SaturnScreen { int row = 0; int col = 0; - - SaturnPlayer player = Auth.players.get(Auth.uuid); + + SaturnPlayer player = SaturnPlayer.get(); if (player != null) { for (String hat : Hats.availableHats) { scroll.draw(new CosmeticPreview(hat == player.hat, Textures.getHatPreview(hat), () -> { - Hats.setHat(Auth.uuid, hat); + Hats.setHat(hat); }).dimensions(50, 50).position((50 + g) * col, (50 + g) * row)); - + if (col == 5) { col = 0; row++; @@ -46,18 +45,18 @@ public class HatMenu extends SaturnScreen { } int scrollWidth = 480 + 10 + (g * 2) + (p * 2); - + draw(scroll.dimensions(scrollWidth, 350).center(width, height)); - draw(new SkinPreview(170f, true).scale(3.5f).position(scroll.x + (scrollWidth - 220), scroll.y+40)); + draw(new SkinPreview(170f, true).scale(3.5f).position(scroll.x + (scrollWidth - 220), scroll.y + 40)); draw(new Sidebar(2, this::close).centerOffset(width, height, -(scrollWidth / 2 + 20), 0)); draw(new TabMenu(1, - new TabMenuComponent(Textures.CLOAK, () -> { - SaturnClient.client.setScreen(new CloakMenu()); - }), - new TabMenuComponent(Textures.HAT, () -> {}) - ).centerOffset(width, height, 0, -195)); + new TabMenuComponent(Textures.CLOAK, () -> { + SaturnClient.client.setScreen(new CloakMenu()); + }), + new TabMenuComponent(Textures.HAT, () -> { + })).centerOffset(width, height, 0, -195)); } } diff --git a/src/main/java/org/saturnclient/ui2/screens/store/CloakStore.java b/src/main/java/org/saturnclient/ui2/screens/store/CloakStore.java index e400320..1f0a056 100644 --- a/src/main/java/org/saturnclient/ui2/screens/store/CloakStore.java +++ b/src/main/java/org/saturnclient/ui2/screens/store/CloakStore.java @@ -1,8 +1,8 @@ package org.saturnclient.ui2.screens.store; import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.auth.Auth; -import org.saturnclient.saturnclient.auth.SaturnPlayer; +import org.saturnclient.saturnclient.client.ServiceClient; +import org.saturnclient.saturnclient.client.player.SaturnPlayer; import org.saturnclient.saturnclient.cosmetics.cloaks.Cloaks; import org.saturnclient.ui2.SaturnScreen; import org.saturnclient.ui2.Utils; @@ -42,7 +42,7 @@ public class CloakStore extends SaturnScreen { int row = 0; int col = 0; - SaturnPlayer player = Auth.players.get(Auth.uuid); + SaturnPlayer player = SaturnPlayer.get(); if (player != null) { for (String cloak : Cloaks.ALL_CLOAKS) { @@ -54,7 +54,7 @@ public class CloakStore extends SaturnScreen { long now = System.currentTimeMillis(); if (now - lastPurchaseTime >= 3000) { Utils.notify(NotificationKind.Info, "Purchase processing", "Please wait"); - Auth.buyCloak(cloak); + ServiceClient.buyCloak(cloak); lastPurchaseTime = now; new Thread(() -> { try { diff --git a/src/main/java/org/saturnclient/ui2/screens/store/HatStore.java b/src/main/java/org/saturnclient/ui2/screens/store/HatStore.java index 579ffa5..15f87b8 100644 --- a/src/main/java/org/saturnclient/ui2/screens/store/HatStore.java +++ b/src/main/java/org/saturnclient/ui2/screens/store/HatStore.java @@ -1,8 +1,8 @@ package org.saturnclient.ui2.screens.store; import org.saturnclient.saturnclient.SaturnClient; -import org.saturnclient.saturnclient.auth.Auth; -import org.saturnclient.saturnclient.auth.SaturnPlayer; +import org.saturnclient.saturnclient.client.ServiceClient; +import org.saturnclient.saturnclient.client.player.SaturnPlayer; import org.saturnclient.saturnclient.cosmetics.Hats; import org.saturnclient.ui2.SaturnScreen; import org.saturnclient.ui2.Utils; @@ -42,7 +42,7 @@ public class HatStore extends SaturnScreen { int row = 0; int col = 0; - SaturnPlayer player = Auth.players.get(Auth.uuid); + SaturnPlayer player = SaturnPlayer.get(); if (player != null) { for (String hat : Hats.ALL_HATS) { @@ -54,7 +54,7 @@ public class HatStore extends SaturnScreen { long now = System.currentTimeMillis(); if (now - lastPurchaseTime >= 3000) { Utils.notify(NotificationKind.Info, "Purchase processing", "Please wait"); - Auth.buyHat(hat); + ServiceClient.buyHat(hat); lastPurchaseTime = now; new Thread(() -> { try { diff --git a/src/main/resources/assets/saturnclient/textures/gui/splash.png b/src/main/resources/assets/saturnclient/textures/gui/splash.png new file mode 100644 index 0000000..84f2988 Binary files /dev/null and b/src/main/resources/assets/saturnclient/textures/gui/splash.png differ diff --git a/src/main/resources/saturnclient.mixins.json b/src/main/resources/saturnclient.mixins.json index 8327a69..3bc9ccc 100644 --- a/src/main/resources/saturnclient.mixins.json +++ b/src/main/resources/saturnclient.mixins.json @@ -9,7 +9,8 @@ "PlayerEntityRendererMixin", "WhoAmI", "DrawContextAccessor", - "TitleScreenMixin" + "SplashOverlayMixin", + "SetScreenMixin" ], "injectors": { "defaultRequire": 1