working ish
This commit is contained in:
@@ -3,13 +3,17 @@ 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.IdentifierUtils;
|
import org.auraclient.auraclient.cloaks.utils.IdentifierUtils;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.imageio.ImageReader;
|
||||||
|
import javax.imageio.stream.ImageInputStream;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the cloak/cape system for Aura Client.
|
* Manages the cloak/cape system for Aura Client.
|
||||||
@@ -20,6 +24,8 @@ public class 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 capeCacheIdentifier = null;
|
||||||
public static final Map<String, String> playerCapes = new HashMap<>();
|
public static final Map<String, String> playerCapes = new HashMap<>();
|
||||||
|
public static final Map<String, List<AnimatedCapeData>> animatedCapes = new ConcurrentHashMap<>();
|
||||||
|
private static final Map<String, Long> lastFrameTime = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the cloak system.
|
* Initializes the cloak system.
|
||||||
@@ -39,7 +45,11 @@ public class Cloaks {
|
|||||||
Cloaks.playerCapes.put(uuid, capeName);
|
Cloaks.playerCapes.put(uuid, capeName);
|
||||||
|
|
||||||
if (!capeName.isEmpty()) {
|
if (!capeName.isEmpty()) {
|
||||||
loadStaticCape(capeName);
|
if (capeName.endsWith(".gif")) {
|
||||||
|
loadAnimatedCape(uuid, capeName);
|
||||||
|
} else {
|
||||||
|
loadStaticCape(capeName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,4 +78,97 @@ public class Cloaks {
|
|||||||
AuraClient.LOGGER.error("Failed to load static cape from resources: " + fileName, e);
|
AuraClient.LOGGER.error("Failed to load static cape from resources: " + fileName, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void loadAnimatedCape(String uuid, String fileName) {
|
||||||
|
try {
|
||||||
|
String resourcePath = CAPES_RESOURCE_PATH + fileName;
|
||||||
|
InputStream inputStream = Cloaks.class.getClassLoader().getResourceAsStream(resourcePath);
|
||||||
|
|
||||||
|
if (inputStream != null) {
|
||||||
|
ImageInputStream stream = ImageIO.createImageInputStream(inputStream);
|
||||||
|
ImageReader reader = ImageIO.getImageReadersByFormatName("gif").next();
|
||||||
|
reader.setInput(stream);
|
||||||
|
|
||||||
|
List<AnimatedCapeData> frames = new ArrayList<>();
|
||||||
|
int frameCount = reader.getNumImages(true);
|
||||||
|
|
||||||
|
for (int i = 0; i < frameCount; i++) {
|
||||||
|
BufferedImage frame = reader.read(i);
|
||||||
|
String frameId = fileName.replace(".gif", "") + "_frame_" + i;
|
||||||
|
Identifier frameIdentifier = Identifier.of(AuraClient.MOD_ID, "capes_" + frameId);
|
||||||
|
IdentifierUtils.registerBufferedImageTexture(frameIdentifier, frame);
|
||||||
|
|
||||||
|
// Get frame delay in milliseconds (default to 100ms if not specified)
|
||||||
|
int delay = 100;
|
||||||
|
try {
|
||||||
|
javax.imageio.metadata.IIOMetadata metadata = reader.getImageMetadata(i);
|
||||||
|
String metaFormatName = metadata.getNativeMetadataFormatName();
|
||||||
|
org.w3c.dom.Node root = metadata.getAsTree(metaFormatName);
|
||||||
|
org.w3c.dom.NodeList children = root.getChildNodes();
|
||||||
|
|
||||||
|
for (int j = 0; j < children.getLength(); j++) {
|
||||||
|
org.w3c.dom.Node node = children.item(j);
|
||||||
|
if (node.getNodeName().equals("GraphicControlExtension")) {
|
||||||
|
org.w3c.dom.NamedNodeMap attrs = node.getAttributes();
|
||||||
|
org.w3c.dom.Node delayNode = attrs.getNamedItem("delayTime");
|
||||||
|
if (delayNode != null) {
|
||||||
|
delay = Integer.parseInt(delayNode.getNodeValue()) * 10; // Convert centiseconds to
|
||||||
|
// milliseconds
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
AuraClient.LOGGER.warn("Could not read frame delay for " + fileName + " frame " + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
frames.add(new AnimatedCapeData(frameIdentifier, delay));
|
||||||
|
}
|
||||||
|
|
||||||
|
animatedCapes.put(uuid, frames);
|
||||||
|
lastFrameTime.put(uuid, System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
AuraClient.LOGGER.error("Failed to load animated cape from resources: " + fileName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Identifier getCurrentCapeTexture(String uuid) {
|
||||||
|
if (!playerCapes.containsKey(uuid)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String capeName = playerCapes.get(uuid);
|
||||||
|
if (capeName.endsWith(".gif")) {
|
||||||
|
List<AnimatedCapeData> frames = animatedCapes.get(uuid);
|
||||||
|
if (frames == null || frames.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
long lastTime = lastFrameTime.getOrDefault(uuid, currentTime);
|
||||||
|
int currentFrame = 0;
|
||||||
|
|
||||||
|
// Find the current frame based on elapsed time
|
||||||
|
long elapsedTime = currentTime - lastTime;
|
||||||
|
long totalTime = 0;
|
||||||
|
for (int i = 0; i < frames.size(); i++) {
|
||||||
|
totalTime += frames.get(i).getDelayMs();
|
||||||
|
if (elapsedTime < totalTime) {
|
||||||
|
currentFrame = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset animation if we've gone through all frames
|
||||||
|
if (elapsedTime >= totalTime) {
|
||||||
|
lastFrameTime.put(uuid, currentTime);
|
||||||
|
currentFrame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return frames.get(currentFrame).getTextureId();
|
||||||
|
} else {
|
||||||
|
return Identifier.of(AuraClient.MOD_ID, "textures/capes/" + capeName + ".png");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -27,18 +27,16 @@ public class AbstractClientPlayerEntityMixin {
|
|||||||
@Inject(method = "getSkinTextures", at = @At("RETURN"), cancellable = true)
|
@Inject(method = "getSkinTextures", at = @At("RETURN"), cancellable = true)
|
||||||
private void getSkinTextures(CallbackInfoReturnable<SkinTextures> cir) {
|
private void getSkinTextures(CallbackInfoReturnable<SkinTextures> cir) {
|
||||||
AbstractClientPlayerEntity player = (AbstractClientPlayerEntity) (Object) this;
|
AbstractClientPlayerEntity player = (AbstractClientPlayerEntity) (Object) this;
|
||||||
|
|
||||||
String uuid = player.getUuidAsString().replace("-", "");
|
String uuid = player.getUuidAsString().replace("-", "");
|
||||||
|
|
||||||
if (Cloaks.playerCapes.containsKey(uuid)) {
|
if (Cloaks.playerCapes.containsKey(uuid)) {
|
||||||
String cloak = Cloaks.playerCapes.get(uuid);
|
Identifier capeTexture = Cloaks.getCurrentCapeTexture(uuid);
|
||||||
|
if (capeTexture != null) {
|
||||||
if (!cloak.isEmpty()) {
|
|
||||||
SkinTextures textures = cir.getReturnValue();
|
SkinTextures textures = cir.getReturnValue();
|
||||||
cir.setReturnValue(new SkinTextures(
|
cir.setReturnValue(new SkinTextures(
|
||||||
textures.texture(),
|
textures.texture(),
|
||||||
textures.textureUrl(),
|
textures.textureUrl(),
|
||||||
Identifier.of("auraclient", "textures/capes/" + cloak + ".png"),
|
capeTexture,
|
||||||
textures.elytraTexture(),
|
textures.elytraTexture(),
|
||||||
textures.model(),
|
textures.model(),
|
||||||
textures.secure()));
|
textures.secure()));
|
||||||
|
|||||||
Reference in New Issue
Block a user