few updates

This commit is contained in:
2025-03-17 16:05:29 +01:00
parent 6e7acb2716
commit 8e53ed7292
11 changed files with 186 additions and 125 deletions
@@ -5,7 +5,7 @@ import net.minecraft.util.math.ColorHelper;
import org.saturnclient.saturnclient.cloaks.Cloaks; import org.saturnclient.saturnclient.cloaks.Cloaks;
import org.saturnclient.saturnclient.event.KeyInputHandler; import org.saturnclient.saturnclient.event.KeyInputHandler;
import org.saturnclient.saturnclient.auth.SaturnApi; import org.saturnclient.saturnclient.auth.SaturnSocket;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -23,7 +23,7 @@ public class SaturnClient implements ModInitializer {
LOGGER.info("Initializing " + MOD_ID); LOGGER.info("Initializing " + MOD_ID);
KeyInputHandler.register(); KeyInputHandler.register();
if (SaturnApi.authenticate()) { if (SaturnSocket.authenticate()) {
Cloaks.initialize(); Cloaks.initialize();
LOGGER.info(MOD_ID + " initialization complete"); LOGGER.info(MOD_ID + " initialization complete");
} else { } else {
@@ -1,97 +0,0 @@
package org.saturnclient.saturnclient.auth;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.minecraft.client.MinecraftClient;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.cloaks.Cloaks;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
public class SaturnApi {
private static final String server = "127.0.0.1";
private static final int port = 8080;
public static Map<String, SaturnPlayer> players = new HashMap<>();
public static Map<String, String> playerNames = new HashMap<>();
private static Socket socket;
private static BufferedReader reader;
private static PrintWriter writer;
public static boolean authenticate() {
// Register shutdown hook ONCE
ClientLifecycleEvents.CLIENT_STOPPING.register(c -> close());
try {
MinecraftClient client = MinecraftClient.getInstance();
if (client.getSession() == null) {
SaturnClient.LOGGER.error("No active Minecraft session found");
return false;
}
String accessToken = client.getSession().getAccessToken();
SaturnClient.LOGGER.info("Authenticating");
// Use try-with-resources to ensure proper cleanup
try (Socket tempSocket = new Socket(server, port);
BufferedReader tempReader = new BufferedReader(new InputStreamReader(tempSocket.getInputStream()));
PrintWriter tempWriter = new PrintWriter(tempSocket.getOutputStream(), true)) {
// Assign to class fields
socket = tempSocket;
reader = tempReader;
writer = tempWriter;
writer.println(accessToken);
String response = reader.readLine();
SaturnParser parser = new SaturnParser(response);
String uuid = parser.getString("uuid");
String cloak = parser.getString("cloak");
if (cloak != null) {
SaturnClient.LOGGER.info("Setting cloak to " + cloak + " for " + uuid);
MinecraftClient.getInstance().execute(() -> Cloaks.setCloak(uuid, cloak));
}
return true;
}
} catch (IOException e) {
SaturnClient.LOGGER.error("Authentication failed", e);
return false;
}
}
public static void close() {
try {
if (writer != null) {
writer.close();
}
if (reader != null) {
reader.close();
}
if (socket != null) {
socket.close();
}
SaturnClient.LOGGER.info("SaturnApi connection closed.");
} catch (IOException e) {
SaturnClient.LOGGER.error("Failed to close resources", e);
}
}
public static void setCloak(String cloakName) {
try {
writer.println("set_cloak@cloak=" + cloakName);
String response = reader.readLine();
new SaturnParser(response);
} catch (IOException e) {
SaturnClient.LOGGER.error("Request failed", e);
}
}
}
@@ -22,6 +22,8 @@ public class SaturnParser {
String[] keyValue = parts[i].split("="); String[] keyValue = parts[i].split("=");
if (keyValue.length == 2) { if (keyValue.length == 2) {
params.put(keyValue[0].trim(), keyValue[1].trim()); params.put(keyValue[0].trim(), keyValue[1].trim());
} else if (keyValue.length == 1) {
params.put(keyValue[0].trim(), "");
} else { } else {
throw new IOException("Invalid parameter format: " + parts[i]); throw new IOException("Invalid parameter format: " + parts[i]);
} }
@@ -36,4 +38,16 @@ public class SaturnParser {
throw new IOException("Parameter not found " + i); 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);
}
}
} }
@@ -2,4 +2,8 @@ package org.saturnclient.saturnclient.auth;
public class SaturnPlayer { public class SaturnPlayer {
public String cloak = ""; public String cloak = "";
public SaturnPlayer(String cloak) {
this.cloak = cloak;
}
} }
@@ -0,0 +1,134 @@
package org.saturnclient.saturnclient.auth;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.minecraft.client.MinecraftClient;
import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.cloaks.Cloaks;
import java.io.*;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
public class SaturnSocket {
private static final String server = "127.0.0.1";
private static final int port = 8080;
public static Map<String, SaturnPlayer> players = new HashMap<>();
public static Map<String, String> playerNames = new HashMap<>();
public static String uuid;
private static Socket socket;
private static BufferedReader reader;
private static PrintWriter writer;
private static Thread listenerThread;
private static volatile boolean running = false;
@SuppressWarnings("resource")
public static boolean authenticate() {
// Register shutdown hook ONCE
ClientLifecycleEvents.CLIENT_STOPPING.register(c -> close());
try {
MinecraftClient client = MinecraftClient.getInstance();
if (client.getSession() == null) {
SaturnClient.LOGGER.error("No active Minecraft session found");
return false;
}
String accessToken = client.getSession().getAccessToken();
SaturnClient.LOGGER.info("Authenticating");
// Establish a persistent connection
socket = new Socket(server, port);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);
// Send authentication request
writer.println(accessToken);
String response = reader.readLine();
SaturnClient.LOGGER.info(response);
SaturnParser parser = new SaturnParser(response);
uuid = parser.getString("uuid");
String cloak = parser.getString("cloak");
for (String availableCloak : parser.getArray("cloaks")) {
SaturnClient.LOGGER.info("Available cloak: " + availableCloak);
Cloaks.availableCloaks.add(availableCloak);
}
players.put(uuid, new SaturnPlayer(cloak));
if (cloak != null) {
SaturnClient.LOGGER.info("Setting cloak to " + cloak + " for " + uuid);
MinecraftClient.getInstance().execute(() -> Cloaks.setCloak(uuid, cloak));
}
playerNames.put(client.getSession().getUsername(), uuid);
// Start listening for server messages
startListenerThread();
return true;
} catch (IOException e) {
SaturnClient.LOGGER.error("Authentication failed", e);
return false;
}
}
private static void startListenerThread() {
running = true;
listenerThread = new Thread(() -> {
try {
while (running) {
String message = reader.readLine();
if (message == null) {
running = false;
break;
}
SaturnClient.LOGGER.info("Received: " + message);
// TODO: make a server response/request handler
}
} catch (IOException e) {
SaturnClient.LOGGER.error("Error reading from server", e);
} finally {
close();
}
});
listenerThread.setDaemon(true);
listenerThread.start();
}
public static void close() {
running = false;
try {
if (writer != null) {
writer.close();
}
if (reader != null) {
reader.close();
}
if (socket != null) {
socket.close();
}
SaturnClient.LOGGER.info("SaturnApi connection closed.");
} catch (IOException e) {
SaturnClient.LOGGER.error("Failed to close resources", e);
}
}
public static void setCloak(String cloakName) {
try {
writer.println("set_cloak@cloak=" + cloakName);
} catch (Exception e) {
SaturnClient.LOGGER.error("Request failed", e);
}
}
}
@@ -2,7 +2,7 @@ package org.saturnclient.saturnclient.cloaks;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.saturnclient.SaturnClient;
import org.saturnclient.saturnclient.auth.SaturnApi; import org.saturnclient.saturnclient.auth.SaturnSocket;
import org.saturnclient.saturnclient.auth.SaturnPlayer; import org.saturnclient.saturnclient.auth.SaturnPlayer;
import org.saturnclient.saturnclient.cloaks.utils.AnimatedCloakData; import org.saturnclient.saturnclient.cloaks.utils.AnimatedCloakData;
import org.saturnclient.saturnclient.cloaks.utils.IdentifierUtils; import org.saturnclient.saturnclient.cloaks.utils.IdentifierUtils;
@@ -41,13 +41,20 @@ public class Cloaks {
* @param cloakName Name of the cloak file to load * @param cloakName Name of the cloak file to load
*/ */
public static void setCloak(String uuid, String cloakName) { public static void setCloak(String uuid, String cloakName) {
SaturnApi.setCloak(cloakName); SaturnSocket.setCloak(cloakName);
setCloakSilent(uuid, cloakName);
}
SaturnPlayer player = SaturnApi.players.get(uuid); /**
* Handles loading and caching of a new cloak texture, without connecting to the
* server.
*
* @param cloakName Name of the cloak file to load
*/
public static void setCloakSilent(String uuid, String cloakName) {
SaturnPlayer player = SaturnSocket.players.get(uuid);
if (player == null) { if (player == null) {
SaturnPlayer newPlayer = new SaturnPlayer(); SaturnSocket.players.put(uuid, new SaturnPlayer(cloakName));
newPlayer.cloak = cloakName;
SaturnApi.players.put(uuid, newPlayer);
} else { } else {
player.cloak = cloakName; player.cloak = cloakName;
} }
@@ -59,7 +66,6 @@ public class Cloaks {
loadStaticCloak(cloakName + ".png"); loadStaticCloak(cloakName + ".png");
} }
} }
} }
/** /**
@@ -128,11 +134,11 @@ public class Cloaks {
} }
public static Identifier getCurrentCloakTexture(String uuid) { public static Identifier getCurrentCloakTexture(String uuid) {
if (!SaturnApi.players.containsKey(uuid)) { if (!SaturnSocket.players.containsKey(uuid)) {
return null; return null;
} }
String cloakName = SaturnApi.players.get(uuid).cloak; String cloakName = SaturnSocket.players.get(uuid).cloak;
if (cloakName.isEmpty()) { if (cloakName.isEmpty()) {
return null; return null;
@@ -1,6 +1,6 @@
package org.saturnclient.saturnclient.menus; package org.saturnclient.saturnclient.menus;
import org.saturnclient.saturnclient.auth.SaturnApi; import org.saturnclient.saturnclient.auth.SaturnSocket;
import org.saturnclient.saturnclient.cloaks.Cloaks; import org.saturnclient.saturnclient.cloaks.Cloaks;
import org.saturnclient.ui.SaturnUi; import org.saturnclient.ui.SaturnUi;
import org.saturnclient.ui.Textures; import org.saturnclient.ui.Textures;
@@ -55,7 +55,7 @@ public class CloaksMenu extends SaturnUi {
.setHeight(cloakHeight)); .setHeight(cloakHeight));
draw(new SaturnClickableSprite(Textures.BUTTON_BORDER, () -> { draw(new SaturnClickableSprite(Textures.BUTTON_BORDER, () -> {
SaturnApi.setCloak(cloak); Cloaks.setCloak(SaturnSocket.uuid, cloak);
}) })
.setColor(10526880) .setColor(10526880)
.setX(modX - 3) .setX(modX - 3)
@@ -26,7 +26,7 @@ public class MainMenu extends SaturnUi {
}).setX((width - buttonWidth) / 2).setY((height - buttonHeight) / }).setX((width - buttonWidth) / 2).setY((height - buttonHeight) /
2).setWidth(buttonWidth) 2).setWidth(buttonWidth)
.setHeight(buttonHeight) .setHeight(buttonHeight)
.setAnimations(new FadeIn(3))); .setAnimations(new FadeIn(1)));
draw( draw(
new SaturnImageButton(Textures.EMOTE, 14, 14, new SaturnImageButton(Textures.EMOTE, 14, 14,
@@ -37,7 +37,7 @@ public class MainMenu extends SaturnUi {
.setY((height - buttonHeight) / 2) .setY((height - buttonHeight) / 2)
.setWidth(buttonHeight) .setWidth(buttonHeight)
.setHeight(buttonHeight) .setHeight(buttonHeight)
.setAnimations(new FadeIn(3))); .setAnimations(new FadeIn(1)));
draw( draw(
new SaturnImageButton(Textures.COSMETICS, 14, 14, new SaturnImageButton(Textures.COSMETICS, 14, 14,
@@ -48,7 +48,7 @@ public class MainMenu extends SaturnUi {
.setY((height - buttonHeight) / 2) .setY((height - buttonHeight) / 2)
.setWidth(buttonHeight) .setWidth(buttonHeight)
.setHeight(buttonHeight) .setHeight(buttonHeight)
.setAnimations(new FadeIn(3))); .setAnimations(new FadeIn(1)));
int logoSize = 49; int logoSize = 49;
@@ -58,7 +58,7 @@ public class MainMenu extends SaturnUi {
.setY((height - 8) / 2 - 23) .setY((height - 8) / 2 - 23)
.setWidth(logoSize) .setWidth(logoSize)
.setHeight(8) .setHeight(8)
.setAnimations(new FadeIn(3))); .setAnimations(new FadeIn(1)));
draw( draw(
new SaturnImage(Textures.LOGO) new SaturnImage(Textures.LOGO)
@@ -66,6 +66,6 @@ public class MainMenu extends SaturnUi {
.setY(height / 2 - logoSize - 24) .setY(height / 2 - logoSize - 24)
.setWidth(logoSize) .setWidth(logoSize)
.setHeight(logoSize) .setHeight(logoSize)
.setAnimations(new Slide(2, 14))); .setAnimations(new Slide(1, 14)));
} }
} }
@@ -13,7 +13,7 @@ import net.minecraft.text.Text;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.client.render.LightmapTextureManager; import net.minecraft.client.render.LightmapTextureManager;
import org.saturnclient.saturnclient.auth.SaturnApi; import org.saturnclient.saturnclient.auth.SaturnSocket;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
@@ -60,7 +60,7 @@ public abstract class NameTagMixin<S extends EntityRenderState> {
private boolean isSaturn(S state) { private boolean isSaturn(S state) {
if (state instanceof PlayerEntityRenderState) { if (state instanceof PlayerEntityRenderState) {
String name = ((PlayerEntityRenderState) state).name; String name = ((PlayerEntityRenderState) state).name;
return SaturnApi.playerNames.containsKey(name); return SaturnSocket.playerNames.containsKey(name);
} }
return false; return false;
} }
@@ -1,6 +1,6 @@
package org.saturnclient.saturnclient.mixin; package org.saturnclient.saturnclient.mixin;
import org.saturnclient.saturnclient.auth.SaturnApi; import org.saturnclient.saturnclient.auth.SaturnSocket;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
@@ -22,6 +22,6 @@ public abstract class TabListMixin {
@Nullable @Nullable
public Text getDisplayName() { public Text getDisplayName() {
String name = displayName.getString(); String name = displayName.getString();
return Text.literal(SaturnApi.playerNames.containsKey(name) ? "" + name : name); return Text.literal(SaturnSocket.playerNames.containsKey(name) ? "" + name : name);
} }
} }
@@ -12,26 +12,26 @@ import net.minecraft.util.math.ColorHelper;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
public class SaturnClickableImage extends SaturnWidget { public class SaturnClickableImage extends SaturnWidget {
public Identifier sprite; public Identifier texture;
public boolean selected = false; public boolean selected = false;
public Consumer<SaturnClickableImage> onPress; public Consumer<SaturnClickableImage> onPress;
public int color = ColorHelper.getWhite(1.0f); public int color = ColorHelper.getWhite(1.0f);
public int hoverColor = SaturnClient.COLOR; public int hoverColor = SaturnClient.COLOR;
public SaturnClickableImage(Identifier sprite, Consumer<SaturnClickableImage> onPress) { public SaturnClickableImage(Identifier texture, Consumer<SaturnClickableImage> onPress) {
this.sprite = sprite; this.texture = texture;
this.onPress = onPress; this.onPress = onPress;
} }
public SaturnClickableImage(Identifier sprite, Runnable onPress) { public SaturnClickableImage(Identifier texture, Runnable onPress) {
this(sprite, (m) -> { this(texture, (m) -> {
onPress.run(); onPress.run();
}); });
} }
@Override @Override
public void render(DrawContext context, boolean hovering, int mouseX, int mouseY) { public void render(DrawContext context, boolean hovering, int mouseX, int mouseY) {
context.drawTexture(RenderLayer::getGuiTextured, sprite, x, y, 0, 0, width, height, width, context.drawTexture(RenderLayer::getGuiTextured, texture, x, y, 0, 0, width, height, width,
height, (hovering || selected ? hoverColor : color) | MathHelper.ceil(this.alpha * 255.0F) << 24); height, (hovering || selected ? hoverColor : color) | MathHelper.ceil(this.alpha * 255.0F) << 24);
} }