small changes

This commit is contained in:
2025-03-01 03:33:20 +01:00
parent fd831b707f
commit 4412d071d5
7 changed files with 65 additions and 112 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ org.gradle.jvmargs=-Xmx1G
# Mod Properties # Mod Properties
mod_version = 1.0.0 mod_version = 1.0.0
maven_group = me.iipho3nix maven_group = me.iipho3nix
archives_base_name = capes archives_base_name = auraclient
# Dependencies # Dependencies
# check this on https://modmuss50.me/fabric.html # check this on https://modmuss50.me/fabric.html
@@ -64,11 +64,10 @@ public class AuraApi {
String cloak = jsonResponse.get("cloak").getAsString(); String cloak = jsonResponse.get("cloak").getAsString();
if (cloak != null) { if (cloak != null) {
AuraClient.LOGGER.info("Setting cloak to " + cloak + " for " + uuid); AuraClient.LOGGER.info("Setting cloak to " + cloak + " for " + uuid);
MinecraftClient.getInstance().execute(() -> Cloaks.setCape(uuid, cloak)); MinecraftClient.getInstance().execute(() -> Cloaks.setCloak(uuid, cloak));
} }
return success; return success;
} catch (Exception e) { } catch (Exception e) {
AuraClient.LOGGER.error("Authentication failed", e); AuraClient.LOGGER.error("Authentication failed", e);
return false; return false;
@@ -3,7 +3,7 @@ package org.auraclient.auraclient.cloaks;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.auraclient.auraclient.AuraClient; import org.auraclient.auraclient.AuraClient;
import org.auraclient.auraclient.auth.AuraApi; import org.auraclient.auraclient.auth.AuraApi;
import org.auraclient.auraclient.cloaks.utils.AnimatedCapeData; import org.auraclient.auraclient.cloaks.utils.AnimatedCloakData;
import org.auraclient.auraclient.cloaks.utils.IdentifierUtils; import org.auraclient.auraclient.cloaks.utils.IdentifierUtils;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
@@ -14,76 +14,78 @@ import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
* Manages the cloak/cape system for Aura Client. * Manages the cloak system for Aura Client.
* Handles loading and caching of player capes. * Handles loading and caching of player cloaks.
*/ */
public class Cloaks { public class Cloaks {
private static final String[] ANIMATED_CLOAKS = { "glitch" }; private static final String[] ANIMATED_CLOAKS = { "glitch" };
private static final String CAPES_RESOURCE_PATH = "assets/auraclient/textures/capes/"; private static final String CLOAKS_RESOURCE_PATH = "assets/auraclient/textures/cloaks/";
public static final List<String> availableCloaks = new ArrayList<>(); public static final List<String> availableCloaks = new ArrayList<>();
public static Identifier capeCacheIdentifier = null; public static Identifier cloakCacheIdentifier = null;
public static final Map<String, String> playerCapes = new HashMap<>(); public static final Map<String, String> playerCloaks = new HashMap<>();
public static final Map<String, List<AnimatedCapeData>> animatedCapes = new ConcurrentHashMap<>(); public static final Map<String, List<AnimatedCloakData>> animatedCloaks = new ConcurrentHashMap<>();
private static final Map<String, Long> lastFrameTime = new ConcurrentHashMap<>(); private static final Map<String, Long> lastFrameTime = new ConcurrentHashMap<>();
/** /**
* Initializes the cloak system. * Initializes the cloak system.
* Loads cape textures from resources. * Loads cloak textures from resources.
*/ */
public static void initialize() { public static void initialize() {
availableCloaks.add(0, ""); availableCloaks.add(0, "");
} }
/** /**
* Handles loading and caching of a new cape texture. * Handles loading and caching of a new cloak texture.
* *
* @param capeName Name of the cape file to load * @param cloakName Name of the cloak file to load
*/ */
public static void setCape(String uuid, String capeName) { public static void setCloak(String uuid, String cloakName) {
AuraApi.setCloak(capeName); AuraApi.setCloak(cloakName);
if (!capeName.isEmpty()) { if (!cloakName.isEmpty()) {
Cloaks.playerCapes.put(uuid, capeName); Cloaks.playerCloaks.put(uuid, cloakName);
if (Arrays.asList(ANIMATED_CLOAKS).contains(capeName)) { if (Arrays.asList(ANIMATED_CLOAKS).contains(cloakName)) {
loadAnimatedCape(uuid, capeName + ".gif"); loadAnimatedCloak(uuid, cloakName + ".gif");
} else { } else {
loadStaticCape(capeName + ".png"); loadStaticCloak(cloakName + ".png");
} }
} else {
Cloaks.playerCloaks.remove(uuid);
} }
} }
/** /**
* Loads and processes a static cape from a PNG file in resources. * Loads and processes a static cloak from a PNG file in resources.
* *
* @param fileName Name of the PNG file to load * @param fileName Name of the PNG file to load
*/ */
private static void loadStaticCape(String fileName) { private static void loadStaticCloak(String fileName) {
try { try {
String resourcePath = CAPES_RESOURCE_PATH + fileName; String resourcePath = CLOAKS_RESOURCE_PATH + fileName;
InputStream inputStream = Cloaks.class.getClassLoader().getResourceAsStream(resourcePath); InputStream inputStream = Cloaks.class.getClassLoader().getResourceAsStream(resourcePath);
if (inputStream != null) { if (inputStream != null) {
BufferedImage image = ImageIO.read(inputStream); BufferedImage image = ImageIO.read(inputStream);
// Add debug logging for static cape // Add debug logging for static cloak
AuraClient.LOGGER.info("Static cape dimensions: " + image.getWidth() + "x" + image.getHeight()); AuraClient.LOGGER.info("Static cloak dimensions: " + image.getWidth() + "x" + image.getHeight());
String safeFileName = fileName.toLowerCase(Locale.ROOT) String safeFileName = fileName.toLowerCase(Locale.ROOT)
.replace(' ', '_') .replace(' ', '_')
.replaceAll("[^a-z0-9/._-]", ""); .replaceAll("[^a-z0-9/._-]", "");
capeCacheIdentifier = Identifier.of(AuraClient.MOD_ID, "capes_" + safeFileName); cloakCacheIdentifier = Identifier.of(AuraClient.MOD_ID, "cloaks_" + safeFileName);
IdentifierUtils.registerBufferedImageTexture(capeCacheIdentifier, image); IdentifierUtils.registerBufferedImageTexture(cloakCacheIdentifier, image);
} }
} catch (IOException e) { } catch (IOException e) {
AuraClient.LOGGER.error("Failed to load static cape from resources: " + fileName, e); AuraClient.LOGGER.error("Failed to load static cloak from resources: " + fileName, e);
} }
} }
private static void loadAnimatedCape(String uuid, String fileName) { private static void loadAnimatedCloak(String uuid, String fileName) {
try { try {
String resourcePath = CAPES_RESOURCE_PATH + fileName; String resourcePath = CLOAKS_RESOURCE_PATH + fileName;
InputStream inputStream = Cloaks.class.getClassLoader().getResourceAsStream(resourcePath); InputStream inputStream = Cloaks.class.getClassLoader().getResourceAsStream(resourcePath);
if (inputStream != null) { if (inputStream != null) {
@@ -93,7 +95,7 @@ public class Cloaks {
// Use our custom GifDecoder // Use our custom GifDecoder
GifDecoder.GifImage gif = GifDecoder.read(data); GifDecoder.GifImage gif = GifDecoder.read(data);
List<AnimatedCapeData> frames = new ArrayList<>(); List<AnimatedCloakData> frames = new ArrayList<>();
int frameCount = gif.getFrameCount(); int frameCount = gif.getFrameCount();
for (int i = 0; i < frameCount; i++) { for (int i = 0; i < frameCount; i++) {
@@ -102,30 +104,30 @@ public class Cloaks {
int delay = gif.getDelay(i) * 10; int delay = gif.getDelay(i) * 10;
String frameId = fileName.replace(".gif", "") + "_frame_" + i; String frameId = fileName.replace(".gif", "") + "_frame_" + i;
Identifier frameIdentifier = Identifier.of(AuraClient.MOD_ID, "capes_" + frameId); Identifier frameIdentifier = Identifier.of(AuraClient.MOD_ID, "cloaks_" + frameId);
IdentifierUtils.registerBufferedImageTexture(frameIdentifier, frame); IdentifierUtils.registerBufferedImageTexture(frameIdentifier, frame);
frames.add(new AnimatedCapeData(frameIdentifier, delay)); frames.add(new AnimatedCloakData(frameIdentifier, delay));
} }
animatedCapes.put(uuid, frames); animatedCloaks.put(uuid, frames);
lastFrameTime.put(uuid, System.currentTimeMillis()); lastFrameTime.put(uuid, System.currentTimeMillis());
AuraClient.LOGGER.info("Loaded " + frames.size() + " frames for animated cape: " + fileName); AuraClient.LOGGER.info("Loaded " + frames.size() + " frames for animated cloak: " + fileName);
} }
} catch (IOException e) { } catch (IOException e) {
AuraClient.LOGGER.error("Failed to load animated cape from resources: " + fileName, e); AuraClient.LOGGER.error("Failed to load animated cloak from resources: " + fileName, e);
} }
} }
public static Identifier getCurrentCapeTexture(String uuid) { public static Identifier getCurrentCloakTexture(String uuid) {
if (!playerCapes.containsKey(uuid)) { if (!playerCloaks.containsKey(uuid)) {
return null; return null;
} }
String capeName = playerCapes.get(uuid); String cloakName = playerCloaks.get(uuid);
if (Arrays.asList(ANIMATED_CLOAKS).contains(capeName)) { if (Arrays.asList(ANIMATED_CLOAKS).contains(cloakName)) {
List<AnimatedCapeData> frames = animatedCapes.get(uuid); List<AnimatedCloakData> frames = animatedCloaks.get(uuid);
if (frames == null || frames.isEmpty()) { if (frames == null || frames.isEmpty()) {
return null; return null;
} }
@@ -151,7 +153,7 @@ public class Cloaks {
return frames.get(currentFrame).getTextureId(); return frames.get(currentFrame).getTextureId();
} else { } else {
return Identifier.of(AuraClient.MOD_ID, "textures/capes/" + capeName + ".png"); return Identifier.of(AuraClient.MOD_ID, "textures/cloaks/" + cloakName + ".png");
} }
} }
} }
@@ -1,35 +0,0 @@
package org.auraclient.auraclient.cloaks.utils;
import net.minecraft.util.Identifier;
/**
* Represents a single frame of an animated cape.
*/
public class AnimatedCapeData {
private final Identifier textureId;
private final int delayMs;
/**
* Creates a new animated cape frame.
* @param textureId The texture identifier for this frame
* @param delayMs The delay in milliseconds before the next frame
*/
public AnimatedCapeData(Identifier textureId, int delayMs) {
this.textureId = textureId;
this.delayMs = delayMs;
}
/**
* @return The texture identifier for this frame
*/
public Identifier getTextureId() {
return textureId;
}
/**
* @return The delay in milliseconds before the next frame
*/
public int getDelayMs() {
return delayMs;
}
}
@@ -18,9 +18,7 @@ public class CloakSelector extends Screen {
for (String cloak : Cloaks.availableCloaks) { for (String cloak : Cloaks.availableCloaks) {
addDrawableChild(ButtonWidget.builder(Text.literal(cloak), (__) -> { addDrawableChild(ButtonWidget.builder(Text.literal(cloak), (__) -> {
String uuid = client.player.getUuidAsString().replace("-", ""); String uuid = client.player.getUuidAsString().replace("-", "");
Cloaks.setCape(uuid, cloak); Cloaks.setCloak(uuid, cloak);
// Cloaks.playerCapes.put(uuid, cloak);
// AuraApi.setCloak(cloak);
}).dimensions((this.width - 50) / 2, y, 50, 30).build()); }).dimensions((this.width - 50) / 2, y, 50, 30).build());
y += 35; y += 35;
@@ -13,33 +13,29 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/** /**
* Mixin for handling custom cloaks in the AbstractClientPlayerEntity class. * Mixin for handling custom cloaks in the AbstractClientPlayerEntity class.
* Injects custom cape textures for players who have them assigned. * Injects custom cloak textures for players who have them assigned.
*/ */
@Mixin(AbstractClientPlayerEntity.class) @Mixin(AbstractClientPlayerEntity.class)
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class AbstractClientPlayerEntityMixin { public abstract class AbstractClientPlayerEntityMixin {
/** /**
* Injects custom cape textures into the player's skin textures. * Injects custom cloak textures into the player's skin textures.
*
* @param cir Callback containing the original skin textures
*/ */
@Inject(method = "getSkinTextures", at = @At("RETURN"), cancellable = true) @Inject(method = "getSkinTextures", at = @At("RETURN"), cancellable = true)
private void getSkinTextures(CallbackInfoReturnable<SkinTextures> cir) { private void injectCustomTextures(CallbackInfoReturnable<SkinTextures> cir) {
AbstractClientPlayerEntity player = (AbstractClientPlayerEntity) (Object) this; AbstractClientPlayerEntity player = (AbstractClientPlayerEntity) (Object) this;
String uuid = player.getUuidAsString().replace("-", ""); String uuid = player.getUuid().toString();
if (Cloaks.playerCapes.containsKey(uuid)) { Identifier cloakTexture = Cloaks.getCurrentCloakTexture(uuid);
Identifier capeTexture = Cloaks.getCurrentCapeTexture(uuid); if (cloakTexture != null) {
if (capeTexture != null) {
SkinTextures textures = cir.getReturnValue(); SkinTextures textures = cir.getReturnValue();
cir.setReturnValue(new SkinTextures( cir.setReturnValue(new SkinTextures(
textures.texture(), textures.texture(),
textures.textureUrl(), textures.textureUrl(),
capeTexture, cloakTexture,
textures.elytraTexture(), textures.elytraTexture(),
textures.model(), textures.model(),
textures.secure())); textures.secure()));
} }
} }
}
} }
+6 -13
View File
@@ -3,26 +3,19 @@
"id": "auraclient", "id": "auraclient",
"version": "${version}", "version": "${version}",
"name": "auraclient", "name": "auraclient",
"description": "A local cape mod for fabric with support for animated capes", "description": "A Minecraft client mod",
"authors": [ "authors": ["IIpho3nix", "kleo-dev"],
"IIpho3nix",
"kleo-dev"
],
"contact": { "contact": {
"website": "https://iipho3nix.me", "website": "https://kleo-dev.netlify.app",
"sources": "https://github.com/IIpho3nix/IIpho3nix-s-Capes-Mod" "sources": "https://github.com/kleo-dev/auraclient"
}, },
"license": "GPL-3.0", "license": "GPL-3.0",
"icon": "assets/auraclient/icon.png", "icon": "assets/auraclient/icon.png",
"environment": "client", "environment": "client",
"entrypoints": { "entrypoints": {
"main": [ "main": ["org.auraclient.auraclient.AuraClient"]
"org.auraclient.auraclient.AuraClient"
]
}, },
"mixins": [ "mixins": ["auraclient.mixins.json"],
"auraclient.mixins.json"
],
"depends": { "depends": {
"fabricloader": ">=${loader_version}", "fabricloader": ">=${loader_version}",
"fabric": "*", "fabric": "*",