package ru.nevetime.clientirc; import com.mojang.blaze3d.platform.InputConstants; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Supplier; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import org.lwjgl.glfw.GLFW; public final class MiddleClickHandler { private static final ExecutorService IO_EXECUTOR = Executors.newSingleThreadExecutor(runnable -> { Thread t = new Thread(runnable, "clientirc-marker-io"); t.setDaemon(true); return t; }); private static KeyMapping markerKey; private MiddleClickHandler() {} public static void init(Supplier serviceSupplier, Supplier playerNameSupplier) { markerKey = new KeyMapping( "key.clientirc.marker", InputConstants.Type.MOUSE, GLFW.GLFW_MOUSE_BUTTON_MIDDLE, "category.clientirc" ); KeyBindingHelper.registerKeyBinding(markerKey); ClientTickEvents.END_CLIENT_TICK.register(client -> { while (markerKey.consumeClick()) { if (client.player == null || client.level == null) break; Vec3 target; if (client.hitResult instanceof BlockHitResult br && br.getType() != HitResult.Type.MISS) { target = br.getBlockPos().getCenter(); } else { Vec3 eye = client.player.getEyePosition(); Vec3 look = client.player.getViewVector(1.0f); target = eye.add(look.scale(20.0)); } String dimId = client.level.dimension().location().toString(); String playerName = playerNameSupplier.get(); double tx = target.x, ty = target.y, tz = target.z; MarkerManager.set(new MarkerManager.Marker(playerName, dimId, tx, ty, tz, System.currentTimeMillis())); IO_EXECUTOR.execute(() -> { IrcService service = serviceSupplier.get(); if (service != null) service.sendMarkerSet(playerName, dimId, tx, ty, tz); }); } }); } public static void removeOwnMarker(Supplier serviceSupplier, Supplier playerNameSupplier) { String name = playerNameSupplier.get(); MarkerManager.remove(name); IO_EXECUTOR.execute(() -> { IrcService service = serviceSupplier.get(); if (service != null) service.sendMarkerRemove(name); }); } }