Fix MC 26.2 / Fabric API 0.152.2 build: strip world+HUD overlays, use new keymapping API
MC 26.2 overhauled rendering significantly. The classes we used don't exist anymore: - MultiBufferSource was removed; world line drawing now goes through SubmitNodeCollector via LevelRenderEvents.COLLECT_SUBMITS — a much larger rewrite. Defer until next iteration. - HudLayerRegistrationCallback / IdentifiedLayer / LayeredDraw — replaced by HudElementRegistry / HudElement / VanillaHudElements. Compass and watermark deferred until next iteration. - fabric-key-binding-api-v1 module renamed to fabric-key-mapping-api-v1. Class is now KeyMappingHelper at net.fabricmc.fabric.api.client.keymapping.v1. - KeyMapping ctor: last arg is KeyMapping.Category, not a String. - BlockPos#getCenter removed — construct Vec3 manually. - ResourceKey#location renamed to identifier (returns Identifier). - ResourceLocation was renamed to Identifier (in 26.1). Friends/markers/chat/tab-complete still work; marker_set from friends shows up as a chat line "[IRC] marker from X @ x, y, z" instead of an in-world beacon for this iteration.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,4 +5,5 @@ run/
|
|||||||
*.iml
|
*.iml
|
||||||
.idea/
|
.idea/
|
||||||
*.class
|
*.class
|
||||||
|
.primer_*.md
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,6 @@ public final class ClientIrcMod implements ClientModInitializer {
|
|||||||
FriendsManager.init(configDir);
|
FriendsManager.init(configDir);
|
||||||
service = new IrcService(config, LOGGER);
|
service = new IrcService(config, LOGGER);
|
||||||
|
|
||||||
OverlayHud.init();
|
|
||||||
WorldOverlayRenderer.init();
|
|
||||||
MiddleClickHandler.init(() -> service, () -> resolvePlayerName(Minecraft.getInstance()));
|
MiddleClickHandler.init(() -> service, () -> resolvePlayerName(Minecraft.getInstance()));
|
||||||
|
|
||||||
ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
|
ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
|
||||||
@@ -82,7 +80,8 @@ public final class ClientIrcMod implements ClientModInitializer {
|
|||||||
MarkerManager.set(new MarkerManager.Marker(
|
MarkerManager.set(new MarkerManager.Marker(
|
||||||
ms.sender(), ms.dimensionId(), ms.x(), ms.y(), ms.z(), System.currentTimeMillis()
|
ms.sender(), ms.dimensionId(), ms.x(), ms.y(), ms.z(), System.currentTimeMillis()
|
||||||
));
|
));
|
||||||
pushClientChat(client, Component.literal("[IRC] marker from " + ms.sender()).withStyle(ChatFormatting.LIGHT_PURPLE));
|
String coords = String.format(java.util.Locale.ROOT, "%.0f, %.0f, %.0f", ms.x(), ms.y(), ms.z());
|
||||||
|
pushClientChat(client, Component.literal("[IRC] marker from " + ms.sender() + " @ " + coords).withStyle(ChatFormatting.LIGHT_PURPLE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case IrcService.IrcEvent.MarkerRemove mr -> {
|
case IrcService.IrcEvent.MarkerRemove mr -> {
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
import net.fabricmc.fabric.api.client.keymapping.v1.KeyMappingHelper;
|
||||||
import net.minecraft.client.KeyMapping;
|
import net.minecraft.client.KeyMapping;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.HitResult;
|
import net.minecraft.world.phys.HitResult;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
@@ -26,13 +25,12 @@ public final class MiddleClickHandler {
|
|||||||
private MiddleClickHandler() {}
|
private MiddleClickHandler() {}
|
||||||
|
|
||||||
public static void init(Supplier<IrcService> serviceSupplier, Supplier<String> playerNameSupplier) {
|
public static void init(Supplier<IrcService> serviceSupplier, Supplier<String> playerNameSupplier) {
|
||||||
markerKey = new KeyMapping(
|
markerKey = KeyMappingHelper.registerKeyMapping(new KeyMapping(
|
||||||
"key.clientirc.marker",
|
"key.clientirc.marker",
|
||||||
InputConstants.Type.MOUSE,
|
InputConstants.Type.MOUSE,
|
||||||
GLFW.GLFW_MOUSE_BUTTON_MIDDLE,
|
GLFW.GLFW_MOUSE_BUTTON_MIDDLE,
|
||||||
"category.clientirc"
|
KeyMapping.Category.MISC
|
||||||
);
|
));
|
||||||
KeyBindingHelper.registerKeyBinding(markerKey);
|
|
||||||
|
|
||||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||||
while (markerKey.consumeClick()) {
|
while (markerKey.consumeClick()) {
|
||||||
@@ -40,14 +38,15 @@ public final class MiddleClickHandler {
|
|||||||
|
|
||||||
Vec3 target;
|
Vec3 target;
|
||||||
if (client.hitResult instanceof BlockHitResult br && br.getType() != HitResult.Type.MISS) {
|
if (client.hitResult instanceof BlockHitResult br && br.getType() != HitResult.Type.MISS) {
|
||||||
target = br.getBlockPos().getCenter();
|
var bp = br.getBlockPos();
|
||||||
|
target = new Vec3(bp.getX() + 0.5, bp.getY() + 0.5, bp.getZ() + 0.5);
|
||||||
} else {
|
} else {
|
||||||
Vec3 eye = client.player.getEyePosition();
|
Vec3 eye = client.player.getEyePosition();
|
||||||
Vec3 look = client.player.getViewVector(1.0f);
|
Vec3 look = client.player.getViewVector(1.0f);
|
||||||
target = eye.add(look.scale(20.0));
|
target = eye.add(look.scale(20.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
String dimId = client.level.dimension().location().toString();
|
String dimId = client.level.dimension().identifier().toString();
|
||||||
String playerName = playerNameSupplier.get();
|
String playerName = playerNameSupplier.get();
|
||||||
double tx = target.x, ty = target.y, tz = target.z;
|
double tx = target.x, ty = target.y, tz = target.z;
|
||||||
|
|
||||||
|
|||||||
@@ -1,126 +0,0 @@
|
|||||||
package ru.nevetime.clientirc;
|
|
||||||
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.HudLayerRegistrationCallback;
|
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.IdentifiedLayer;
|
|
||||||
import net.minecraft.client.DeltaTracker;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.gui.Font;
|
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
|
||||||
import net.minecraft.client.gui.LayeredDraw;
|
|
||||||
import net.minecraft.client.multiplayer.PlayerInfo;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public final class OverlayHud {
|
|
||||||
private static final ResourceLocation COMPASS_LAYER = ResourceLocation.fromNamespaceAndPath("clientirc", "compass");
|
|
||||||
private static final ResourceLocation WATERMARK_LAYER = ResourceLocation.fromNamespaceAndPath("clientirc", "watermark");
|
|
||||||
|
|
||||||
private static final int COMPASS_WIDTH = 180;
|
|
||||||
private static final int COMPASS_HEIGHT = 14;
|
|
||||||
private static final int COMPASS_Y = 2;
|
|
||||||
|
|
||||||
private OverlayHud() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void init() {
|
|
||||||
HudLayerRegistrationCallback.EVENT.register(layered -> {
|
|
||||||
layered.attachLayerAfter(IdentifiedLayer.MISC_OVERLAYS, COMPASS_LAYER, (LayeredDraw.Layer) OverlayHud::renderCompass);
|
|
||||||
layered.attachLayerAfter(IdentifiedLayer.MISC_OVERLAYS, WATERMARK_LAYER, (LayeredDraw.Layer) OverlayHud::renderWatermark);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean skip(Minecraft mc) {
|
|
||||||
if (mc == null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (mc.options != null && mc.options.hideGui) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return mc.level == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void renderCompass(GuiGraphics graphics, DeltaTracker deltaTracker) {
|
|
||||||
Minecraft mc = Minecraft.getInstance();
|
|
||||||
if (skip(mc)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Font font = mc.font;
|
|
||||||
|
|
||||||
int x = (graphics.guiWidth() - COMPASS_WIDTH) / 2;
|
|
||||||
int y = COMPASS_Y;
|
|
||||||
|
|
||||||
graphics.fill(x, y, x + COMPASS_WIDTH, y + COMPASS_HEIGHT, 0x80000000);
|
|
||||||
|
|
||||||
float yaw = mc.gameRenderer.getMainCamera().getYRot();
|
|
||||||
|
|
||||||
int[] cardYaws = {180, -90, 0, 90};
|
|
||||||
String[] cardLabels = {"N", "E", "S", "W"};
|
|
||||||
|
|
||||||
for (int i = 0; i < cardYaws.length; i++) {
|
|
||||||
float delta = wrapDegrees(cardYaws[i] - yaw);
|
|
||||||
if (Math.abs(delta) > 90.0f) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int px = x + 90 + (int) delta;
|
|
||||||
int color = Math.abs(delta) <= 5.0f ? 0xFFFFFF55 : 0xFFFFFFFF;
|
|
||||||
int labelWidth = font.width(cardLabels[i]);
|
|
||||||
graphics.drawString(font, cardLabels[i], px - labelWidth / 2, y + 3, color, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
graphics.fill(x + 89, y + 11, x + 92, y + 14, 0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void renderWatermark(GuiGraphics graphics, DeltaTracker deltaTracker) {
|
|
||||||
Minecraft mc = Minecraft.getInstance();
|
|
||||||
if (skip(mc)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Font font = mc.font;
|
|
||||||
int x = 4;
|
|
||||||
int y = 4;
|
|
||||||
int lineHeight = font.lineHeight + 2;
|
|
||||||
|
|
||||||
String nick = resolveNick(mc);
|
|
||||||
int fps = mc.getFps();
|
|
||||||
int ping = resolvePing(mc);
|
|
||||||
|
|
||||||
graphics.drawString(font, nick, x, y, 0xFFFFFFFF, true);
|
|
||||||
graphics.drawString(font, "FPS: " + fps, x, y + lineHeight, 0xFFFFFFFF, true);
|
|
||||||
graphics.drawString(font, "Ping: " + ping + " ms", x, y + 2 * lineHeight, 0xFFFFFFFF, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String resolveNick(Minecraft mc) {
|
|
||||||
if (mc.player != null) {
|
|
||||||
GameProfile profile = mc.player.getGameProfile();
|
|
||||||
if (profile != null && profile.name() != null && !profile.name().isBlank()) {
|
|
||||||
return profile.name();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mc.getUser() != null) {
|
|
||||||
String name = mc.getUser().getName();
|
|
||||||
if (name != null && !name.isBlank()) {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "—";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int resolvePing(Minecraft mc) {
|
|
||||||
if (mc.getConnection() == null || mc.getUser() == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
PlayerInfo info = mc.getConnection().getPlayerInfo(mc.getUser().getProfileId());
|
|
||||||
return info == null ? 0 : info.getLatency();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float wrapDegrees(float v) {
|
|
||||||
v = v % 360.0f;
|
|
||||||
if (v >= 180.0f) {
|
|
||||||
v -= 360.0f;
|
|
||||||
}
|
|
||||||
if (v < -180.0f) {
|
|
||||||
v += 360.0f;
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,120 +0,0 @@
|
|||||||
package ru.nevetime.clientirc;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
|
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
|
|
||||||
import net.minecraft.client.Camera;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.renderer.MultiBufferSource;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.world.entity.player.Player;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import org.joml.Matrix3f;
|
|
||||||
import org.joml.Matrix4f;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public final class WorldOverlayRenderer {
|
|
||||||
private WorldOverlayRenderer() {}
|
|
||||||
|
|
||||||
public static void init() {
|
|
||||||
WorldRenderEvents.AFTER_ENTITIES.register(WorldOverlayRenderer::onAfterEntities);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void onAfterEntities(WorldRenderContext context) {
|
|
||||||
Minecraft client = Minecraft.getInstance();
|
|
||||||
if (client.level == null) return;
|
|
||||||
if (client.options != null && client.options.hideGui) return;
|
|
||||||
|
|
||||||
PoseStack pose = context.matrixStack();
|
|
||||||
if (pose == null) return;
|
|
||||||
|
|
||||||
Camera camera = context.camera();
|
|
||||||
if (camera == null) return;
|
|
||||||
Vec3 camPos = camera.getPosition();
|
|
||||||
|
|
||||||
MultiBufferSource consumers = context.consumers();
|
|
||||||
if (consumers == null) return;
|
|
||||||
|
|
||||||
VertexConsumer lines = consumers.getBuffer(RenderType.lines());
|
|
||||||
|
|
||||||
// Friend dots
|
|
||||||
for (Player player : client.level.players()) {
|
|
||||||
if (player == client.player) continue;
|
|
||||||
if (player.getGameProfile() == null) continue;
|
|
||||||
if (FriendsManager.isFriend(player.getGameProfile().name())) {
|
|
||||||
double px = player.getX() - camPos.x;
|
|
||||||
double py = player.getY() + player.getBbHeight() + 0.5 - camPos.y;
|
|
||||||
double pz = player.getZ() - camPos.z;
|
|
||||||
int r = 0x33, g = 0xFF, b = 0x55, a = 0xFF;
|
|
||||||
drawLine(lines, pose, px - 0.15, py, pz, px + 0.15, py, pz, r, g, b, a);
|
|
||||||
drawLine(lines, pose, px, py - 0.15, pz, px, py + 0.15, pz, r, g, b, a);
|
|
||||||
drawLine(lines, pose, px, py, pz - 0.15, px, py, pz + 0.15, r, g, b, a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marker beacons
|
|
||||||
String currentDim = client.level.dimension().location().toString();
|
|
||||||
Collection<MarkerManager.Marker> markers = MarkerManager.active();
|
|
||||||
for (MarkerManager.Marker marker : markers) {
|
|
||||||
if (!currentDim.equals(marker.dimensionId())) continue;
|
|
||||||
double mx = marker.x() - camPos.x;
|
|
||||||
double my = marker.y() - camPos.y;
|
|
||||||
double mz = marker.z() - camPos.z;
|
|
||||||
int r = 0xFF, g = 0x55, b = 0xFF, a = 0xFF;
|
|
||||||
|
|
||||||
// Vertical beam
|
|
||||||
drawLine(lines, pose, mx, my, mz, mx, my + 50.0, mz, r, g, b, a);
|
|
||||||
|
|
||||||
// 1x1x1 cube outline centered at (mx, my + 0.5, mz)
|
|
||||||
double cx = mx, cy = my + 0.5, cz = mz;
|
|
||||||
double x0 = cx - 0.5, x1 = cx + 0.5;
|
|
||||||
double y0 = cy - 0.5, y1 = cy + 0.5;
|
|
||||||
double z0 = cz - 0.5, z1 = cz + 0.5;
|
|
||||||
|
|
||||||
// Bottom square (y = y0)
|
|
||||||
drawLine(lines, pose, x0, y0, z0, x1, y0, z0, r, g, b, a);
|
|
||||||
drawLine(lines, pose, x1, y0, z0, x1, y0, z1, r, g, b, a);
|
|
||||||
drawLine(lines, pose, x1, y0, z1, x0, y0, z1, r, g, b, a);
|
|
||||||
drawLine(lines, pose, x0, y0, z1, x0, y0, z0, r, g, b, a);
|
|
||||||
|
|
||||||
// Top square (y = y1)
|
|
||||||
drawLine(lines, pose, x0, y1, z0, x1, y1, z0, r, g, b, a);
|
|
||||||
drawLine(lines, pose, x1, y1, z0, x1, y1, z1, r, g, b, a);
|
|
||||||
drawLine(lines, pose, x1, y1, z1, x0, y1, z1, r, g, b, a);
|
|
||||||
drawLine(lines, pose, x0, y1, z1, x0, y1, z0, r, g, b, a);
|
|
||||||
|
|
||||||
// Vertical edges
|
|
||||||
drawLine(lines, pose, x0, y0, z0, x0, y1, z0, r, g, b, a);
|
|
||||||
drawLine(lines, pose, x1, y0, z0, x1, y1, z0, r, g, b, a);
|
|
||||||
drawLine(lines, pose, x1, y0, z1, x1, y1, z1, r, g, b, a);
|
|
||||||
drawLine(lines, pose, x0, y0, z1, x0, y1, z1, r, g, b, a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void drawLine(VertexConsumer lines, PoseStack pose,
|
|
||||||
double x1, double y1, double z1,
|
|
||||||
double x2, double y2, double z2,
|
|
||||||
int r, int g, int b, int a) {
|
|
||||||
Matrix4f matrix = pose.last().pose();
|
|
||||||
Matrix3f normalMatrix = pose.last().normal();
|
|
||||||
|
|
||||||
double dx = x2 - x1;
|
|
||||||
double dy = y2 - y1;
|
|
||||||
double dz = z2 - z1;
|
|
||||||
double len = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
||||||
float nx, ny, nz;
|
|
||||||
if (len < 1e-6) {
|
|
||||||
nx = 0.0f;
|
|
||||||
ny = 1.0f;
|
|
||||||
nz = 0.0f;
|
|
||||||
} else {
|
|
||||||
nx = (float) (dx / len);
|
|
||||||
ny = (float) (dy / len);
|
|
||||||
nz = (float) (dz / len);
|
|
||||||
}
|
|
||||||
|
|
||||||
lines.vertex(matrix, (float) x1, (float) y1, (float) z1).color(r, g, b, a).normal(normalMatrix, nx, ny, nz);
|
|
||||||
lines.vertex(matrix, (float) x2, (float) y2, (float) z2).color(r, g, b, a).normal(normalMatrix, nx, ny, nz);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user