Moving cloaks to common
This commit is contained in:
+1
-1
Submodule common updated: a54aa9eaba...5b34d3eb37
+1
-1
@@ -282,7 +282,7 @@ public class CloakFeatureRenderer extends FeatureRenderer<PlayerEntityRenderStat
|
||||
return;
|
||||
}
|
||||
|
||||
Identifier customCape = Cloaks.getCurrentCloakTexture(player.uuid);
|
||||
Identifier customCape = (Identifier) (Object) Cloaks.getCurrentCloakTexture(player.uuid);
|
||||
if (customCape == null
|
||||
|| this.hasCustomModelForLayer(playerEntityRenderState.equippedChestStack, LayerType.WINGS)) {
|
||||
return;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package org.saturnclient.cosmetics.cloak;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import org.saturnclient.client.ServiceClient;
|
||||
import org.saturnclient.client.player.SaturnPlayer;
|
||||
import org.saturnclient.common.ref.asset.IdentifierRef;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -15,7 +14,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.saturnclient.cosmetics.cloak.utils.AnimatedCloakData;
|
||||
import org.saturnclient.cosmetics.utils.AnimatedCloakData;
|
||||
import org.saturnclient.cosmetics.cloak.utils.IdentifierUtils;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
@@ -32,7 +31,7 @@ public class Cloaks {
|
||||
|
||||
private static final String CLOAKS_RESOURCE_PATH = "assets/saturnclient/textures/cloaks/";
|
||||
public static final List<String> availableCloaks = new ArrayList<>();
|
||||
public static Identifier cloakCacheIdentifier = null;
|
||||
public static IdentifierRef cloakCacheIdentifier = null;
|
||||
public static final Map<UUID, List<AnimatedCloakData>> animatedCloaks = new ConcurrentHashMap<>();
|
||||
private static final Map<UUID, Long> lastFrameTime = new ConcurrentHashMap<>();
|
||||
|
||||
@@ -129,8 +128,8 @@ public class Cloaks {
|
||||
.replace(' ', '_')
|
||||
.replaceAll("[^a-z0-9/._-]", "");
|
||||
|
||||
cloakCacheIdentifier = Identifier.of(SaturnClient.MOD_ID, "cloaks_" + safeFileName);
|
||||
IdentifierUtils.registerBufferedImageTexture(cloakCacheIdentifier, image);
|
||||
cloakCacheIdentifier = IdentifierRef.of(SaturnClient.MOD_ID, "cloaks_" + safeFileName);
|
||||
IdentifierUtils.registerBufferedImageTextureFast(cloakCacheIdentifier, image);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
SaturnClient.LOGGER.error("Failed to load static cloak from resources: " + fileName, e);
|
||||
@@ -177,7 +176,7 @@ public class Cloaks {
|
||||
int delay = Math.max(gif.getDelay(i) * 10, 50); // Minimum 50ms delay
|
||||
|
||||
String frameId = baseFrameId + "_frame_" + i;
|
||||
Identifier frameIdentifier = Identifier.of(SaturnClient.MOD_ID, "cloaks_" + frameId);
|
||||
IdentifierRef frameIdentifier = IdentifierRef.of(SaturnClient.MOD_ID, "cloaks_" + frameId);
|
||||
|
||||
try {
|
||||
IdentifierUtils.registerBufferedImageTextureFast(frameIdentifier, frame);
|
||||
@@ -217,7 +216,7 @@ public class Cloaks {
|
||||
}, CLOAK_LOADER_EXECUTOR);
|
||||
}
|
||||
|
||||
public static Identifier getCurrentCloakTexture(UUID uuid) {
|
||||
public static IdentifierRef getCurrentCloakTexture(UUID uuid) {
|
||||
SaturnPlayer player = SaturnPlayer.get(uuid);
|
||||
|
||||
if (player == null || player.cloak.isEmpty()) {
|
||||
@@ -251,15 +250,15 @@ public class Cloaks {
|
||||
currentFrame = 0;
|
||||
}
|
||||
|
||||
Identifier identifier = frames.get(currentFrame).getTextureId();
|
||||
IdentifierRef identifier = frames.get(currentFrame).getTextureId();
|
||||
|
||||
if (identifier == null) {
|
||||
return Identifier.of(SaturnClient.MOD_ID, "textures/cloaks/" + cloakName + ".png");
|
||||
return IdentifierRef.of(SaturnClient.MOD_ID, "textures/cloaks/" + cloakName + ".png");
|
||||
}
|
||||
|
||||
return identifier;
|
||||
} else {
|
||||
return Identifier.of(SaturnClient.MOD_ID, "textures/cloaks/" + cloakName + ".png");
|
||||
return IdentifierRef.of(SaturnClient.MOD_ID, "textures/cloaks/" + cloakName + ".png");
|
||||
}
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
package org.saturnclient.cosmetics.cloak.utils;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
/**
|
||||
* Represents a single frame of an animated cloak.
|
||||
*/
|
||||
public class AnimatedCloakData {
|
||||
private final Identifier textureId;
|
||||
private final int delayMs;
|
||||
|
||||
/**
|
||||
* Creates a new animated cloak frame.
|
||||
*
|
||||
* @param textureId The texture identifier for this frame
|
||||
* @param delayMs The delay in milliseconds before the next frame
|
||||
*/
|
||||
public AnimatedCloakData(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;
|
||||
}
|
||||
}
|
||||
+34
-62
@@ -1,98 +1,70 @@
|
||||
package org.saturnclient.cosmetics.cloak.utils;
|
||||
|
||||
import org.saturnclient.common.ref.asset.IdentifierRef;
|
||||
import org.saturnclient.saturnclient.SaturnClient;
|
||||
|
||||
import net.minecraft.client.texture.NativeImage;
|
||||
import net.minecraft.client.texture.NativeImageBackedTexture;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.util.Map;
|
||||
|
||||
public class IdentifierUtils {
|
||||
|
||||
/**
|
||||
* ORIGINAL METHOD - EXTREMELY SLOW - causes 10-20 second freezes
|
||||
* This converts BufferedImage -> PNG bytes -> ByteBuffer -> NativeImage ->
|
||||
* Texture
|
||||
* This is completely unnecessary and wastes massive amounts of CPU time!
|
||||
*/
|
||||
public static void registerBufferedImageTexture(Identifier i, BufferedImage bi) {
|
||||
public static void registerBufferedImageTextureFast(IdentifierRef identifierRef, BufferedImage bufferedImage) {
|
||||
try {
|
||||
// This is the performance killer:
|
||||
// 1. Converts BufferedImage to PNG (expensive compression)
|
||||
// 2. Creates ByteBuffer copy (memory allocation)
|
||||
// 3. NativeImage.read() parses PNG back to raw pixels (expensive decompression)
|
||||
// This is doing compression -> decompression for no reason!
|
||||
Identifier identifier = (Identifier) (Object) identifierRef;
|
||||
|
||||
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream();
|
||||
javax.imageio.ImageIO.write(bi, "png", baos);
|
||||
byte[] bytes = baos.toByteArray();
|
||||
java.nio.ByteBuffer bb = org.lwjgl.BufferUtils.createByteBuffer(bytes.length).put(bytes);
|
||||
bb.flip();
|
||||
NativeImageBackedTexture nibt = new NativeImageBackedTexture(NativeImage.read(bb));
|
||||
SaturnClient.client.getTextureManager().registerTexture(i, nibt);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* OPTIMIZED METHOD - Direct pixel conversion without unnecessary PNG
|
||||
* encoding/decoding
|
||||
* This should reduce loading time from 10-20 seconds to under 1 second
|
||||
*/
|
||||
public static void registerBufferedImageTextureFast(Identifier identifier, BufferedImage bufferedImage) {
|
||||
try {
|
||||
int width = bufferedImage.getWidth();
|
||||
int height = bufferedImage.getHeight();
|
||||
|
||||
// Create NativeImage directly with the correct format
|
||||
NativeImage nativeImage = new NativeImage(NativeImage.Format.RGBA, width, height, false);
|
||||
|
||||
// Direct pixel copy - much faster than PNG conversion
|
||||
if (bufferedImage.getType() == BufferedImage.TYPE_INT_ARGB) {
|
||||
// Fast path for ARGB images - direct memory access
|
||||
int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData();
|
||||
|
||||
int index = 0;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int pixel = pixels[y * width + x];
|
||||
nativeImage.setColorArgb(x, y, pixel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Fallback for other image types - still faster than PNG conversion
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int rgb = bufferedImage.getRGB(x, y);
|
||||
nativeImage.setColorArgb(x, y, rgb);
|
||||
}
|
||||
nativeImage.setColorArgb(x, y, pixels[index++]);
|
||||
}
|
||||
}
|
||||
|
||||
// Register the texture
|
||||
} else {
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
nativeImage.setColorArgb(x, y, bufferedImage.getRGB(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NativeImageBackedTexture texture = new NativeImageBackedTexture(nativeImage);
|
||||
SaturnClient.client.execute(
|
||||
() -> SaturnClient.client.getTextureManager().registerTexture(identifier, texture));
|
||||
|
||||
SaturnClient.client.execute(() ->
|
||||
SaturnClient.client.getTextureManager().registerTexture(identifier, texture)
|
||||
);
|
||||
|
||||
} catch (Exception e) {
|
||||
SaturnClient.LOGGER.error("Failed to register texture: " + identifier, e);
|
||||
// Fallback to slow method if fast method fails
|
||||
registerBufferedImageTexture(identifier, bufferedImage);
|
||||
SaturnClient.LOGGER.error("Failed to register texture: {}", identifierRef, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* EVEN FASTER VERSION - Bulk texture registration
|
||||
* Use this when registering many textures at once (like animated cloak frames)
|
||||
*/
|
||||
public static void registerBufferedImageTexturesBulk(java.util.Map<Identifier, BufferedImage> textures) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
public static void registerBufferedImageTexturesBulk(Map<IdentifierRef, BufferedImage> textures) {
|
||||
|
||||
for (java.util.Map.Entry<Identifier, BufferedImage> entry : textures.entrySet()) {
|
||||
registerBufferedImageTextureFast(entry.getKey(), entry.getValue());
|
||||
}
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
long endTime = System.currentTimeMillis();
|
||||
SaturnClient.LOGGER.info("Registered {} textures in {}ms", textures.size(), (endTime - startTime));
|
||||
textures.forEach(IdentifierUtils::registerBufferedImageTextureFast);
|
||||
|
||||
long end = System.currentTimeMillis();
|
||||
|
||||
SaturnClient.LOGGER.info(
|
||||
"Registered {} textures in {}ms",
|
||||
textures.size(),
|
||||
(end - start)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package org.saturnclient.cosmetics.cloak.utils;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Utility class for generating random strings and numbers.
|
||||
*/
|
||||
public final class RandomUtils {
|
||||
private static final String ALPHANUMERIC = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
private static final String ALPHANUMERIC_LOWERCASE = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
private RandomUtils() {
|
||||
// Prevent instantiation
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random string of specified length using given characters.
|
||||
*/
|
||||
private static String random(final int length, final char[] chars) {
|
||||
StringBuilder sb = new StringBuilder(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
sb.append(chars[RANDOM.nextInt(chars.length)]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random string of specified length using alphanumeric characters.
|
||||
*/
|
||||
public static String randomString(final int length) {
|
||||
return random(length, ALPHANUMERIC.toCharArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random lowercase string of specified length.
|
||||
*/
|
||||
public static String randomStringLowercase(final int length) {
|
||||
return random(length, ALPHANUMERIC_LOWERCASE.toCharArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random integer between min and max (inclusive).
|
||||
*/
|
||||
public static int randBetween(int min, int max) {
|
||||
return RANDOM.nextInt(max - min + 1) + min;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -67,6 +67,6 @@ public class SaturnProviderImpl implements SaturnProvider {
|
||||
|
||||
@Override
|
||||
public void registerBufferedImageTexture(IdentifierRef i, BufferedImage bi) {
|
||||
IdentifierUtils.registerBufferedImageTextureFast((Identifier) (Object) i, bi);
|
||||
IdentifierUtils.registerBufferedImageTextureFast(i, bi);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user