Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Гайд Своя иконка в окне + Изменение названия окна Fabric 1.21.11

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
19 Май 2025
Сообщения
283
Реакции
3
Привет всем!
Решил сделать гайд как сменить название окна и поставить свою иконку в окне
Своя иконка в окне
Class: WindowMixin
Прочитал=пастер:
Expand Collapse Copy
package wtf.client.api.mixins;

import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.util.Icons;
import net.minecraft.client.util.Window;
import net.minecraft.resource.ResourcePack;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWImage;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.io.IOException;
import java.nio.ByteBuffer;

@Mixin(Window.class)
public class WindowMixin {
    @Shadow
    @Final
    private long handle;

    @Inject(method = "setIcon", at = @At("HEAD"), cancellable = true)
    private void onSetIcon(CallbackInfo ci) {
        ci.cancel();

        try (MemoryStack memoryStack = MemoryStack.stackPush()) {
            GLFWImage.Buffer buffer = GLFWImage.malloc(1, memoryStack);
            try (NativeImage nativeImage = NativeImage.read(WindowMixin.class.getResourceAsStream("/assets/modid/images/ui/logo64x.png"))) {
                ByteBuffer byteBuffer = MemoryUtil.memAlloc(nativeImage.getWidth() * nativeImage.getHeight() * 4);
                byteBuffer.asIntBuffer().put(nativeImage.copyPixelsAbgr());
                buffer.position(0);
                buffer.width(nativeImage.getWidth());
                buffer.height(nativeImage.getHeight());
                buffer.pixels(byteBuffer);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            GLFW.glfwSetWindowIcon(this.handle, buffer.position(0));
        }
    }
}
Изменения названия окна
Class: MinecraftClientMixin
Pastaaa:
Expand Collapse Copy
package wtf.client.api.mixins;

import net.minecraft.client.MinecraftClient;
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;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(MinecraftClient.class)
public class MinecraftClientMixin {
    @Inject(method = "getWindowTitle", at = @At("RETURN"), cancellable = true)
    private void getWindowTitle(CallbackInfoReturnable<String> cir) {

        cir.setReturnValue(String.format("Pasta bro"));
    }
}

ScreenShots:
1776182523510.png
1776182534954.png
 
Привет всем!
Решил сделать гайд как сменить название окна и поставить свою иконку в окне
Своя иконка в окне
Class: WindowMixin
Прочитал=пастер:
Expand Collapse Copy
package wtf.client.api.mixins;

import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.util.Icons;
import net.minecraft.client.util.Window;
import net.minecraft.resource.ResourcePack;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWImage;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.io.IOException;
import java.nio.ByteBuffer;

@Mixin(Window.class)
public class WindowMixin {
    @Shadow
    @Final
    private long handle;

    @Inject(method = "setIcon", at = @At("HEAD"), cancellable = true)
    private void onSetIcon(CallbackInfo ci) {
        ci.cancel();

        try (MemoryStack memoryStack = MemoryStack.stackPush()) {
            GLFWImage.Buffer buffer = GLFWImage.malloc(1, memoryStack);
            try (NativeImage nativeImage = NativeImage.read(WindowMixin.class.getResourceAsStream("/assets/modid/images/ui/logo64x.png"))) {
                ByteBuffer byteBuffer = MemoryUtil.memAlloc(nativeImage.getWidth() * nativeImage.getHeight() * 4);
                byteBuffer.asIntBuffer().put(nativeImage.copyPixelsAbgr());
                buffer.position(0);
                buffer.width(nativeImage.getWidth());
                buffer.height(nativeImage.getHeight());
                buffer.pixels(byteBuffer);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            GLFW.glfwSetWindowIcon(this.handle, buffer.position(0));
        }
    }
}
Изменения названия окна
Class: MinecraftClientMixin
Pastaaa:
Expand Collapse Copy
package wtf.client.api.mixins;

import net.minecraft.client.MinecraftClient;
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;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(MinecraftClient.class)
public class MinecraftClientMixin {
    @Inject(method = "getWindowTitle", at = @At("RETURN"), cancellable = true)
    private void getWindowTitle(CallbackInfoReturnable<String> cir) {

        cir.setReturnValue(String.format("Pasta bro"));
    }
}

ScreenShots:
Посмотреть вложение 333249Посмотреть вложение 333250
С тайтлом ещё нормально, но отдельный миксин на иконку - кринж, вот тебе метод, в MinecraftClientMixin инжектишься в
@Inject(at = @At("TAIL"), method = "<init>") и вызываешь метод (DWMApi.setWindowIcon(mc.getWindow().getHandle(), "ассет до картинки");)

Java:
Expand Collapse Copy
public static void setWindowIcon(long windowHandle, Identifier id) {
        try (MemoryStack stack = MemoryStack.stackPush()) {
            InputStream stream = WinAPI.class.getResourceAsStream("/assets/" + id.getNamespace() + "/" + id.getPath());
            if (stream == null) {
                System.err.println("Иконки не найдена: " + id);
                return;
            }

            BufferedImage img = ImageIO.read(stream);
            int width = img.getWidth();
            int height = img.getHeight();

            ByteBuffer buffer = ByteBuffer.allocateDirect(width * height * 4);
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    int pixel = img.getRGB(x, y);
                    buffer.put((byte) ((pixel >> 16) & 0xFF));
                    buffer.put((byte) ((pixel >> 8) & 0xFF));
                    buffer.put((byte) (pixel & 0xFF));
                    buffer.put((byte) ((pixel >> 24) & 0xFF));
                }
            }
            buffer.flip();

            GLFWImage icon = GLFWImage.malloc(stack);
            icon.set(width, height, buffer);

            GLFWImage.Buffer icons = GLFWImage.malloc(1, stack);
            icons.put(0, icon);

            GLFW.glfwSetWindowIcon(windowHandle, icons);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

@ponkarpon НЕ УБИВАЙ ЗА СВОЙ СЕЛФКОД
 
Назад
Сверху Снизу