structure and player-dependent capes
This commit is contained in:
@@ -1,20 +1,24 @@
|
||||
package org.auraclient.auraclient;
|
||||
|
||||
import org.auraclient.auraclient.cloaks.Cloaks;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import org.auraclient.auraclient.cloaks.Cloaks;
|
||||
import org.auraclient.auraclient.event.KeyInputHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/*
|
||||
* Massive thank you to IIpho3nix for making this mod, i (leo) have modified it to fit Aura Client
|
||||
*/
|
||||
|
||||
/**
|
||||
* Main class for the Aura Client mod.
|
||||
* Originally created by IIpho3nix and modified for Aura Client by leo.
|
||||
*/
|
||||
public class AuraClient implements ModInitializer {
|
||||
public static final String MOD_ID = "auraclient";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
LOGGER.info("Initializing " + MOD_ID);
|
||||
KeyInputHandler.register();
|
||||
Cloaks.initialize();
|
||||
LOGGER.info(MOD_ID + " initialization complete");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,25 +5,49 @@ import net.minecraft.client.gui.Drawable;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
/**
|
||||
* Represents a drawable texture in the Aura Client UI.
|
||||
* Uses the builder pattern for flexible texture creation and configuration.
|
||||
*/
|
||||
public class AuraClientTexture implements Drawable {
|
||||
// Textures
|
||||
public static Identifier BOX_1_1 = Identifier.of("auraclient", "textures/gui/box_1_1.png");
|
||||
// Predefined textures
|
||||
public static final Identifier BOX_1_1 = Identifier.of("auraclient", "textures/gui/box_1_1.png");
|
||||
|
||||
Identifier sprite;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
boolean focused = false;
|
||||
private final Identifier sprite;
|
||||
private int x;
|
||||
private int y;
|
||||
private int width;
|
||||
private int height;
|
||||
|
||||
public AuraClientTexture(Identifier sprite) {
|
||||
/**
|
||||
* Creates a new texture with the specified sprite.
|
||||
* @param sprite The identifier for the texture sprite
|
||||
*/
|
||||
private AuraClientTexture(Identifier sprite) {
|
||||
this.sprite = sprite;
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new builder instance for the texture.
|
||||
* @param sprite The identifier for the texture sprite
|
||||
* @return A new AuraClientTexture instance
|
||||
*/
|
||||
public static AuraClientTexture builder(Identifier sprite) {
|
||||
return new AuraClientTexture(sprite);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dimensions and position of the texture.
|
||||
* @param x The x coordinate
|
||||
* @param y The y coordinate
|
||||
* @param width The width of the texture
|
||||
* @param height The height of the texture
|
||||
* @return This instance for method chaining
|
||||
*/
|
||||
public AuraClientTexture dimensions(int x, int y, int width, int height) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
@@ -32,6 +56,15 @@ public class AuraClientTexture implements Drawable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the focused state of the texture.
|
||||
* @param focused The focused state
|
||||
* @return This instance for method chaining
|
||||
*/
|
||||
public AuraClientTexture setFocused(boolean focused) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
|
||||
context.drawTexture(RenderLayer::getGuiTextured, sprite, x, y, 0, 0, width, height, width, height);
|
||||
|
||||
@@ -1,118 +1,154 @@
|
||||
package org.auraclient.auraclient.cloaks;
|
||||
|
||||
import at.dhyan.open_imaging.GifDecoder;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.auraclient.auraclient.AuraClient;
|
||||
import org.auraclient.auraclient.cloaks.utils.AnimatedCapeData;
|
||||
import org.auraclient.auraclient.cloaks.utils.IdentifierUtils;
|
||||
import org.auraclient.auraclient.cloaks.utils.RandomUtils;
|
||||
import org.auraclient.auraclient.event.KeyInputHandler;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Manages the cloak/cape system for Aura Client.
|
||||
* Handles loading, caching, and animating player capes.
|
||||
*/
|
||||
public class Cloaks {
|
||||
private static final File capesFolder = new File(MinecraftClient.getInstance().runDirectory, "Capes");
|
||||
public static final List<String> list = new ArrayList<>();
|
||||
private static final List<AnimatedCapeData> anicape = new ArrayList<>();
|
||||
private static int capeindex = 0;
|
||||
private static long mili = System.currentTimeMillis();
|
||||
private static String lastCache = "NotCached";
|
||||
private static final String CAPES_RESOURCE_PATH = "assets/auraclient/textures/capes/";
|
||||
private static final List<AnimatedCapeData> animatedCapeFrames = new ArrayList<>();
|
||||
private static int currentFrameIndex = 0;
|
||||
private static long lastFrameTime = System.currentTimeMillis();
|
||||
private static String lastCachedCape = "NoCache";
|
||||
|
||||
public static final List<String> availableCapes = new ArrayList<>();
|
||||
public static Identifier capeCacheIdentifier = null;
|
||||
public static String cape = "";
|
||||
public static final Map<String, String> playerCapes = new HashMap<>();
|
||||
|
||||
public static void initialize() {
|
||||
list.clear();
|
||||
list.add("");
|
||||
if (capesFolder.mkdir()) {
|
||||
AuraClient.LOGGER.info("New Cape Folder Created");
|
||||
downloadCloakTextures();
|
||||
/**
|
||||
* Initializes the cloak system.
|
||||
* Loads cape textures from resources.
|
||||
*/
|
||||
public static void initialize() {
|
||||
availableCapes.clear();
|
||||
availableCapes.add("");
|
||||
loadCloakTextures();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads cloak textures from the resources.
|
||||
* Supports both static (.png) and animated (.gif) capes.
|
||||
*/
|
||||
private static void loadCloakTextures() {
|
||||
// In a resource-based system, we would need to manually list available capes
|
||||
// For now, we can add default capes that we know exist in resources
|
||||
// This would need to be updated when adding new capes to resources
|
||||
availableCapes.add("glitch.png");
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the cape animation state.
|
||||
* Called every tick to handle animated capes.
|
||||
*/
|
||||
public static void tick() {
|
||||
String currentCape = playerCapes.values().stream().findFirst().orElse("");
|
||||
|
||||
if (!lastCachedCape.equals(currentCape)) {
|
||||
handleCapeChange(currentCape);
|
||||
} else if (currentCape.endsWith(".gif")) {
|
||||
updateAnimatedCape();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles loading and caching of a new cape texture.
|
||||
* @param capeName Name of the cape file to load
|
||||
*/
|
||||
private static void handleCapeChange(String capeName) {
|
||||
if (!capeName.isEmpty()) {
|
||||
if (capeName.endsWith(".gif")) {
|
||||
loadAnimatedCape(capeName);
|
||||
} else {
|
||||
AuraClient.LOGGER.info("Cape Folder Already Exists");
|
||||
loadStaticCape(capeName);
|
||||
}
|
||||
loadCloakTextures();
|
||||
lastCachedCape = capeName;
|
||||
}
|
||||
}
|
||||
|
||||
KeyInputHandler.register();
|
||||
/**
|
||||
* Loads and processes an animated cape from a GIF file in resources.
|
||||
* @param fileName Name of the GIF file to load
|
||||
*/
|
||||
private static void loadAnimatedCape(String fileName) {
|
||||
try {
|
||||
animatedCapeFrames.clear();
|
||||
String resourcePath = CAPES_RESOURCE_PATH + fileName;
|
||||
InputStream inputStream = Cloaks.class.getClassLoader().getResourceAsStream(resourcePath);
|
||||
|
||||
if (inputStream != null) {
|
||||
GifDecoder.GifImage gif = GifDecoder.read(inputStream);
|
||||
int frameCount = gif.getFrameCount();
|
||||
|
||||
for (int i = 0; i < frameCount; i++) {
|
||||
BufferedImage frame = gif.getFrame(i);
|
||||
int delay = gif.getDelay(i);
|
||||
Identifier frameId = Identifier.of(AuraClient.MOD_ID,
|
||||
"capes_" + RandomUtils.randomStringLowercase(10));
|
||||
|
||||
IdentifierUtils.registerBufferedImageTexture(frameId, frame);
|
||||
animatedCapeFrames.add(new AnimatedCapeData(frameId, delay));
|
||||
}
|
||||
|
||||
currentFrameIndex = 0;
|
||||
capeCacheIdentifier = animatedCapeFrames.get(0).getTextureId();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
AuraClient.LOGGER.error("Failed to load animated cape from resources: " + fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and processes a static cape from a PNG file in resources.
|
||||
* @param fileName Name of the PNG file to load
|
||||
*/
|
||||
private static void loadStaticCape(String fileName) {
|
||||
try {
|
||||
String resourcePath = CAPES_RESOURCE_PATH + fileName;
|
||||
InputStream inputStream = Cloaks.class.getClassLoader().getResourceAsStream(resourcePath);
|
||||
|
||||
if (inputStream != null) {
|
||||
BufferedImage image = ImageIO.read(inputStream);
|
||||
|
||||
String safeFileName = fileName.toLowerCase(Locale.ROOT)
|
||||
.replace(' ', '_')
|
||||
.replaceAll("[^a-z0-9/._-]", "");
|
||||
|
||||
capeCacheIdentifier = Identifier.of(AuraClient.MOD_ID, "capes_" + safeFileName);
|
||||
IdentifierUtils.registerBufferedImageTexture(capeCacheIdentifier, image);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
AuraClient.LOGGER.error("Failed to load static cape from resources: " + fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current frame of an animated cape.
|
||||
*/
|
||||
private static void updateAnimatedCape() {
|
||||
if (currentFrameIndex >= animatedCapeFrames.size()) {
|
||||
currentFrameIndex = 0;
|
||||
}
|
||||
|
||||
public static void downloadCloakTextures() {
|
||||
// Todo: Download the cloak textures and put them in the Capes folder
|
||||
}
|
||||
|
||||
private static void loadCloakTextures() {
|
||||
if (capesFolder.isDirectory()) {
|
||||
for (final File fileEntry : Objects.requireNonNull(capesFolder.listFiles())) {
|
||||
if (
|
||||
fileEntry.getName().endsWith(".png") || fileEntry.getName().endsWith(".gif")
|
||||
) {
|
||||
list.add(fileEntry.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void tick() {
|
||||
if (!lastCache.equals(cape)) {
|
||||
if (!cape.isEmpty()) {
|
||||
if (cape.endsWith(".gif")) {
|
||||
try {
|
||||
anicape.clear();
|
||||
Identifier frameIdentifier;
|
||||
File file = new File(capesFolder, cape);
|
||||
final FileInputStream data = new FileInputStream(file);
|
||||
final GifDecoder.GifImage gif = GifDecoder.read(data);
|
||||
final int frameCount = gif.getFrameCount();
|
||||
for (int i = 0; i < frameCount; i++) {
|
||||
final BufferedImage img = gif.getFrame(i);
|
||||
final int delay = gif.getDelay(i);
|
||||
frameIdentifier = Identifier.of(AuraClient.MOD_ID, "capes_" + RandomUtils.randomStringLowercase(10));
|
||||
IdentifierUtils.registerBufferedImageTexture(frameIdentifier, img);
|
||||
anicape.add(new AnimatedCapeData(frameIdentifier, delay));
|
||||
}
|
||||
capeindex = 0;
|
||||
capeCacheIdentifier = anicape.get(0).getId();
|
||||
lastCache = cape;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
BufferedImage img = null;
|
||||
File file = new File(capesFolder, cape);
|
||||
try {
|
||||
img = ImageIO.read(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
capeCacheIdentifier = Identifier.of(AuraClient.MOD_ID, "capes_" + cape.toLowerCase(Locale.ROOT).replace(' ', '_').replaceAll("[^a-z0-9/._-]", ""));
|
||||
IdentifierUtils.registerBufferedImageTexture(capeCacheIdentifier, img);
|
||||
lastCache = cape;
|
||||
}
|
||||
} else {
|
||||
capeCacheIdentifier = null;
|
||||
lastCache = cape;
|
||||
}
|
||||
} else {
|
||||
if (cape.endsWith(".gif")) {
|
||||
if (capeindex > (anicape.size() - 1)) {
|
||||
capeindex = 0;
|
||||
}
|
||||
if (System.currentTimeMillis() > mili + anicape.get(capeindex).getDelay()) {
|
||||
mili = System.currentTimeMillis();
|
||||
capeCacheIdentifier = anicape.get(capeindex).getId();
|
||||
capeindex++;
|
||||
}
|
||||
}
|
||||
AnimatedCapeData currentFrame = animatedCapeFrames.get(currentFrameIndex);
|
||||
if (System.currentTimeMillis() > lastFrameTime + currentFrame.getDelayMs()) {
|
||||
lastFrameTime = System.currentTimeMillis();
|
||||
capeCacheIdentifier = currentFrame.getTextureId();
|
||||
currentFrameIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,20 +2,34 @@ 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 id;
|
||||
private final int delay;
|
||||
private final Identifier textureId;
|
||||
private final int delayMs;
|
||||
|
||||
public AnimatedCapeData(Identifier id, int delay) {
|
||||
this.id = id;
|
||||
this.delay = delay;
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
public Identifier getId() {
|
||||
return id;
|
||||
/**
|
||||
* @return The texture identifier for this frame
|
||||
*/
|
||||
public Identifier getTextureId() {
|
||||
return textureId;
|
||||
}
|
||||
|
||||
public int getDelay() {
|
||||
return delay;
|
||||
/**
|
||||
* @return The delay in milliseconds before the next frame
|
||||
*/
|
||||
public int getDelayMs() {
|
||||
return delayMs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,28 +2,47 @@ package org.auraclient.auraclient.cloaks.utils;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class RandomUtils {
|
||||
/**
|
||||
* 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) {
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < length; i++)
|
||||
stringBuilder.append(chars[new Random().nextInt(chars.length)]);
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
private static String random(final int length, final String chars) {
|
||||
return random(length, chars.toCharArray());
|
||||
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, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
|
||||
return random(length, ALPHANUMERIC.toCharArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random lowercase string of specified length.
|
||||
*/
|
||||
public static String randomStringLowercase(final int length) {
|
||||
return random(length, "0123456789abcdefghijklmnopqrstuvwxyz");
|
||||
return random(length, ALPHANUMERIC_LOWERCASE.toCharArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random integer between min and max (inclusive).
|
||||
*/
|
||||
public static int randBetween(int min, int max) {
|
||||
Random r = new Random();
|
||||
return r.nextInt(max - min) + min;
|
||||
return RANDOM.nextInt(max - min + 1) + min;
|
||||
}
|
||||
}
|
||||
@@ -7,18 +7,33 @@ import net.minecraft.client.util.InputUtil;
|
||||
import org.auraclient.auraclient.menus.MainMenu;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
/**
|
||||
* Handles keyboard input events for the Aura Client.
|
||||
* Manages keybindings and their associated actions.
|
||||
*/
|
||||
public class KeyInputHandler {
|
||||
public static final String KEY_CATEGORY_CAPES = "key.category.auraclient";
|
||||
public static final String KEY_MAIN_MENU = "key.auraclient.main_menu";
|
||||
public static KeyBinding mainMenuKey;
|
||||
private static final String KEY_CATEGORY = "key.category.auraclient";
|
||||
private static final String MAIN_MENU_KEY_ID = "key.auraclient.main_menu";
|
||||
private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT;
|
||||
|
||||
private static KeyBinding mainMenuKeyBinding;
|
||||
|
||||
/**
|
||||
* Registers all keybindings and their associated event handlers.
|
||||
* Should be called during mod initialization.
|
||||
*/
|
||||
public static void register() {
|
||||
mainMenuKey = KeyBindingHelper.registerKeyBinding(new KeyBinding(
|
||||
KEY_MAIN_MENU, InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_RIGHT_SHIFT, KEY_CATEGORY_CAPES
|
||||
// Register the main menu key binding
|
||||
mainMenuKeyBinding = KeyBindingHelper.registerKeyBinding(new KeyBinding(
|
||||
MAIN_MENU_KEY_ID,
|
||||
InputUtil.Type.KEYSYM,
|
||||
DEFAULT_MENU_KEY,
|
||||
KEY_CATEGORY
|
||||
));
|
||||
|
||||
// Register the event handler for the main menu key
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||
if (mainMenuKey.wasPressed()) {
|
||||
if (mainMenuKeyBinding.wasPressed()) {
|
||||
client.setScreen(new MainMenu());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,23 +1,43 @@
|
||||
package org.auraclient.auraclient.menus;
|
||||
|
||||
import org.auraclient.auraclient.AuraClient;
|
||||
import org.auraclient.auraclient.cloaks.Cloaks;
|
||||
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class CloakSelector extends Screen {
|
||||
private TextFieldWidget playerNameField;
|
||||
|
||||
public CloakSelector() {
|
||||
super(Text.literal("Cloaks"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
int y = ((this.height - (35 * (Cloaks.list.size()))) / 2);
|
||||
// Add player name text field at the top
|
||||
this.playerNameField = new TextFieldWidget(this.textRenderer,
|
||||
(this.width - 200) / 2, 20, 200, 20, Text.literal("Player Name"));
|
||||
this.playerNameField.setMaxLength(16);
|
||||
addDrawableChild(this.playerNameField);
|
||||
|
||||
for (String cloak : Cloaks.list) {
|
||||
// Calculate starting Y position for cloak buttons, accounting for text field
|
||||
int y = ((this.height - (35 * (Cloaks.availableCapes.size()))) / 2) + 30;
|
||||
|
||||
for (String cloak : Cloaks.availableCapes) {
|
||||
addDrawableChild(ButtonWidget.builder(Text.literal(cloak), (__) -> {
|
||||
Cloaks.cape = cloak;
|
||||
String playerName = this.playerNameField.getText();
|
||||
if (!playerName.isEmpty() && !playerName.equals("Player Name")) {
|
||||
if (cloak.isEmpty()) {
|
||||
Cloaks.playerCapes.remove(playerName);
|
||||
AuraClient.LOGGER.info("Cape removed for player: " + playerName);
|
||||
} else {
|
||||
Cloaks.playerCapes.put(playerName, cloak);
|
||||
AuraClient.LOGGER.info("Cape set for player: " + playerName + " to " + cloak);
|
||||
}
|
||||
}
|
||||
}).dimensions((this.width - 50) / 2, y, 50, 30).build());
|
||||
|
||||
y += 35;
|
||||
|
||||
@@ -12,7 +12,9 @@ public class MainMenu extends Screen {
|
||||
@Override
|
||||
protected void init() {
|
||||
addDrawableChild(ButtonWidget.builder(Text.literal("Cloaks"), (_button) -> {
|
||||
client.setScreen(new CloakSelector());
|
||||
if (client.player != null) {
|
||||
client.setScreen(new CloakSelector());
|
||||
}
|
||||
}).dimensions((this.width - 50) / 2, (this.height - 30) / 2, 50, 30).build());
|
||||
}
|
||||
}
|
||||
+26
-15
@@ -1,35 +1,46 @@
|
||||
package org.auraclient.auraclient.mixin;
|
||||
|
||||
import org.auraclient.auraclient.AuraClient;
|
||||
import org.auraclient.auraclient.cloaks.Cloaks;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.util.SkinTextures;
|
||||
import org.auraclient.auraclient.cloaks.Cloaks;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
/**
|
||||
* Mixin for handling custom cloaks in the AbstractClientPlayerEntity class.
|
||||
* Injects custom cape textures for players who have them assigned.
|
||||
*/
|
||||
@Mixin(AbstractClientPlayerEntity.class)
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class AbstractClientPlayerEntityMixin {
|
||||
@Inject(at = @At("RETURN"), method = "getSkinTextures", cancellable = true)
|
||||
private void getSkinTextures(CallbackInfoReturnable<SkinTextures> cir) {
|
||||
// AbstractClientPlayerEntity player = (AbstractClientPlayerEntity) (Object) this;
|
||||
|
||||
if (((AbstractClientPlayerEntity) (Object) this) instanceof ClientPlayerEntity && Cloaks.capeCacheIdentifier != null) {
|
||||
// AuraClient.LOGGER.info("Rendering skin for: " + player.getUuid());
|
||||
/**
|
||||
* Injects custom cape textures into the player's skin textures.
|
||||
* @param cir Callback containing the original skin textures
|
||||
*/
|
||||
@Inject(
|
||||
method = "getSkinTextures",
|
||||
at = @At("RETURN"),
|
||||
cancellable = true
|
||||
)
|
||||
private void getSkinTextures(CallbackInfoReturnable<SkinTextures> cir) {
|
||||
AbstractClientPlayerEntity player = (AbstractClientPlayerEntity) (Object) this;
|
||||
|
||||
if (Cloaks.playerCapes.containsKey(player.getName().getString()) &&
|
||||
Cloaks.capeCacheIdentifier != null) {
|
||||
|
||||
SkinTextures textures = cir.getReturnValue();
|
||||
cir.setReturnValue(new SkinTextures(
|
||||
textures.texture(),
|
||||
textures.textureUrl(),
|
||||
Cloaks.capeCacheIdentifier,
|
||||
textures.elytraTexture(),
|
||||
textures.model(),
|
||||
textures.secure()
|
||||
textures.texture(),
|
||||
textures.textureUrl(),
|
||||
Cloaks.capeCacheIdentifier,
|
||||
textures.elytraTexture(),
|
||||
textures.model(),
|
||||
textures.secure()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,30 @@
|
||||
package org.auraclient.auraclient.mixin;
|
||||
|
||||
import org.auraclient.auraclient.cloaks.Cloaks;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import org.auraclient.auraclient.cloaks.Cloaks;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* Mixin for the MinecraftClient class.
|
||||
* Handles the periodic updating of cloaks system.
|
||||
*/
|
||||
@Mixin(MinecraftClient.class)
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class MinecraftClientMixin {
|
||||
@Inject(at = @At("HEAD"), method = "tick")
|
||||
|
||||
/**
|
||||
* Injects into the client tick to update cloaks.
|
||||
* @param ci Callback info
|
||||
*/
|
||||
@Inject(
|
||||
method = "tick",
|
||||
at = @At("HEAD")
|
||||
)
|
||||
private void tick(CallbackInfo ci) {
|
||||
Cloaks.tick();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user