From 4941a14d89a742e89b544ac165c7d61387e97522 Mon Sep 17 00:00:00 2001 From: kurrycat Date: Thu, 27 Jun 2024 21:19:54 +0200 Subject: [PATCH] add fabric 1.21 --- README.md | 1 + fabric-1.21/.gitignore | 40 ++ fabric-1.21/build.gradle | 21 + fabric-1.21/gradle.properties | 14 + .../fabric_1_21/EventHandler.java | 122 +++++ .../fabric_1_21/FunctionCompatibility.java | 415 ++++++++++++++++++ .../fabric_1_21/MPKGuiScreen.java | 86 ++++ .../compatibility/fabric_1_21/MPKMod.java | 80 ++++ .../fabric_1_21/mixin/GameRendererMixin.java | 32 ++ .../fabric_1_21/mixin/KeyBindingAccessor.java | 12 + .../fabric_1_21/mixin/KeyboardMixin.java | 18 + .../mixin/MinecraftClientMixin.java | 16 + .../fabric_1_21/mixin/MouseMixin.java | 55 +++ .../src/main/resources/assets/mpkmod/icon.png | Bin 0 -> 11576 bytes .../resources/assets/mpkmod/lang/en_US.lang | 6 + .../resources/assets/mpkmod/lang/en_us.json | 8 + .../resources/assets/mpkmod/lang/pl_pl.json | 8 + .../resources/assets/mpkmod/lang/pl_pl.lang | 6 + .../src/main/resources/fabric.mod.json | 36 ++ .../src/main/resources/mpkmod.mixins.json | 18 + settings.gradle.kts | 1 + 21 files changed, 995 insertions(+) create mode 100644 fabric-1.21/.gitignore create mode 100644 fabric-1.21/build.gradle create mode 100644 fabric-1.21/gradle.properties create mode 100644 fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/EventHandler.java create mode 100644 fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java create mode 100644 fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/MPKGuiScreen.java create mode 100644 fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/MPKMod.java create mode 100644 fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/GameRendererMixin.java create mode 100644 fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/KeyBindingAccessor.java create mode 100644 fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/KeyboardMixin.java create mode 100644 fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/MinecraftClientMixin.java create mode 100644 fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/MouseMixin.java create mode 100644 fabric-1.21/src/main/resources/assets/mpkmod/icon.png create mode 100644 fabric-1.21/src/main/resources/assets/mpkmod/lang/en_US.lang create mode 100644 fabric-1.21/src/main/resources/assets/mpkmod/lang/en_us.json create mode 100644 fabric-1.21/src/main/resources/assets/mpkmod/lang/pl_pl.json create mode 100644 fabric-1.21/src/main/resources/assets/mpkmod/lang/pl_pl.lang create mode 100644 fabric-1.21/src/main/resources/fabric.mod.json create mode 100644 fabric-1.21/src/main/resources/mpkmod.mixins.json diff --git a/README.md b/README.md index adbfd022..26c8463b 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ If you think that mpkmod should have a specific feature, encounter any bugs or i - 1.19.4 - 1.20.4 - 1.20.6 + - 1.21 --- diff --git a/fabric-1.21/.gitignore b/fabric-1.21/.gitignore new file mode 100644 index 00000000..c476faf2 --- /dev/null +++ b/fabric-1.21/.gitignore @@ -0,0 +1,40 @@ +# gradle + +.gradle/ +build/ +out/ +classes/ + +# eclipse + +*.launch + +# idea + +.idea/ +*.iml +*.ipr +*.iws + +# vscode + +.settings/ +.vscode/ +bin/ +.classpath +.project + +# macos + +*.DS_Store + +# fabric + +run/ + +# java + +hs_err_*.log +replay_*.log +*.hprof +*.jfr diff --git a/fabric-1.21/build.gradle b/fabric-1.21/build.gradle new file mode 100644 index 00000000..b54ca866 --- /dev/null +++ b/fabric-1.21/build.gradle @@ -0,0 +1,21 @@ +plugins { + id 'fabric-loom' version '1.6-SNAPSHOT' +} + +loom.runs.client.runDir = "../runs/run" + +dependencies { + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" + modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} \ No newline at end of file diff --git a/fabric-1.21/gradle.properties b/fabric-1.21/gradle.properties new file mode 100644 index 00000000..9af5b9fd --- /dev/null +++ b/fabric-1.21/gradle.properties @@ -0,0 +1,14 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G +org.gradle.parallel=true + +# Fabric Properties +# check these on https://fabricmc.net/develop +minecraft_version=1.21 +yarn_mappings=1.21+build.4 +loader_version=0.15.11 + +# Fabric API +fabric_version=0.100.4+1.21 + +jdkVersion=21 diff --git a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/EventHandler.java b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/EventHandler.java new file mode 100644 index 00000000..87bd1f65 --- /dev/null +++ b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/EventHandler.java @@ -0,0 +1,122 @@ +package io.github.kurrycat.mpkmod.compatibility.fabric_1_21; + + +import io.github.kurrycat.mpkmod.compatibility.API; +import io.github.kurrycat.mpkmod.compatibility.MCClasses.Player; +import io.github.kurrycat.mpkmod.compatibility.fabric_1_21.mixin.KeyBindingAccessor; +import io.github.kurrycat.mpkmod.ticks.ButtonMS; +import io.github.kurrycat.mpkmod.ticks.ButtonMSList; +import io.github.kurrycat.mpkmod.util.BoundingBox3D; +import io.github.kurrycat.mpkmod.util.Vector3D; +import net.fabricmc.fabric.api.networking.v1.PacketSender; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.option.GameOptions; +import net.minecraft.client.render.RenderTickCounter; +import net.minecraft.client.util.InputUtil; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.Util; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Vec3d; + +public class EventHandler { + private static final ButtonMSList timeQueue = new ButtonMSList(); + + /** + * @param key The GLFW key code. See {@link net.minecraft.client.util.InputUtil}. + * @param scanCode + * @param action The action, where 0 = unpressed, 1 = pressed, 2 = held. + */ + public void onKey(int key, int scanCode, int action) { + GameOptions options = MinecraftClient.getInstance().options; + long eventNanos = Util.getMeasuringTimeNano(); + + InputUtil.Key inputKey = InputUtil.fromKeyCode(key, scanCode); + + int[] keys = { + ((KeyBindingAccessor) options.forwardKey).getBoundKey().getCode(), + ((KeyBindingAccessor) options.leftKey).getBoundKey().getCode(), + ((KeyBindingAccessor) options.backKey).getBoundKey().getCode(), + ((KeyBindingAccessor) options.rightKey).getBoundKey().getCode(), + ((KeyBindingAccessor) options.sprintKey).getBoundKey().getCode(), + ((KeyBindingAccessor) options.sneakKey).getBoundKey().getCode(), + ((KeyBindingAccessor) options.jumpKey).getBoundKey().getCode() + }; + + for (int i = 0; i < keys.length; i++) { + if (key == keys[i]) { + timeQueue.add(ButtonMS.of(ButtonMS.Button.values()[i], eventNanos, action == 1)); + } + } + + if (action == 1) { + FunctionCompatibility.pressedButtons.add(inputKey.getCode()); + } else if (action == 0) { + FunctionCompatibility.pressedButtons.remove(inputKey.getCode()); + } + + API.Events.onKeyInput(key, inputKey.getLocalizedText().getString(), action == 1); + + MPKMod.keyBindingMap.forEach((id, keyBinding) -> { + if (keyBinding.isPressed()) { + API.Events.onKeybind(id); + } + }); + } + + public void onInGameOverlayRender(DrawContext drawContext, RenderTickCounter renderTickCounter) { + drawContext.getMatrices().push(); + API.getFunctionHolder().drawContext = drawContext; + API.Events.onRenderOverlay(); + drawContext.getMatrices().pop(); + } + + public void onRenderWorldOverlay(MatrixStack matrixStack, float tickDelta) { + MPKMod.INSTANCE.matrixStack = matrixStack; + matrixStack.push(); + Vec3d pos = MinecraftClient.getInstance().gameRenderer.getCamera().getPos(); + MPKMod.INSTANCE.matrixStack.translate(-pos.x, -pos.y, -pos.z); + API.Events.onRenderWorldOverlay(tickDelta); + matrixStack.pop(); + } + + public void onClientTickStart(MinecraftClient mc) { + API.Events.onTickStart(); + } + + public void onClientTickEnd(MinecraftClient mc) { + ClientPlayerEntity mcPlayer = mc.player; + + if (mcPlayer != null) { + Box playerBB = mcPlayer.getBoundingBox(); + new Player() + .setPos(new Vector3D(mcPlayer.getX(), mcPlayer.getY(), mcPlayer.getZ())) + .setLastPos(new Vector3D(mcPlayer.prevX, mcPlayer.prevY, mcPlayer.prevZ)) + .setMotion(new Vector3D(mcPlayer.getVelocity().x, mcPlayer.getVelocity().y, mcPlayer.getVelocity().z)) + .setRotation(mcPlayer.getRotationClient().y, mcPlayer.getRotationClient().x) + .setOnGround(mcPlayer.isOnGround()) + .setSprinting(mcPlayer.isSprinting()) + .setBoundingBox(new BoundingBox3D( + new Vector3D(playerBB.minX, playerBB.minY, playerBB.minZ), + new Vector3D(playerBB.maxX, playerBB.maxY, playerBB.maxZ) + )) + .constructKeyInput() + .setKeyMSList(timeQueue) + .buildAndSave(); + timeQueue.clear(); + } + + API.Events.onTickEnd(); + } + + + public void onServerConnect(ClientPlayNetworkHandler clientPlayNetworkHandler, PacketSender packetSender, MinecraftClient minecraftClient) { + API.Events.onServerConnect(clientPlayNetworkHandler.getConnection().isLocal()); + } + + public void onServerDisconnect(ClientPlayNetworkHandler clientPlayNetworkHandler, MinecraftClient minecraftClient) { + API.Events.onServerDisconnect(); + } +} diff --git a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java new file mode 100644 index 00000000..d7b9bab6 --- /dev/null +++ b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/FunctionCompatibility.java @@ -0,0 +1,415 @@ +package io.github.kurrycat.mpkmod.compatibility.fabric_1_21; + +import com.mojang.blaze3d.systems.RenderSystem; +import io.github.kurrycat.mpkmod.compatibility.MCClasses.*; +import io.github.kurrycat.mpkmod.compatibility.fabric_1_21.mixin.KeyBindingAccessor; +import io.github.kurrycat.mpkmod.gui.MPKGuiScreen; +import io.github.kurrycat.mpkmod.util.BoundingBox3D; +import io.github.kurrycat.mpkmod.util.Debug; +import io.github.kurrycat.mpkmod.util.Vector2D; +import io.github.kurrycat.mpkmod.util.Vector3D; +import net.minecraft.block.BlockState; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.network.ServerInfo; +import net.minecraft.client.option.GameOptions; +import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.render.*; +import net.minecraft.client.sound.PositionedSoundInstance; +import net.minecraft.client.util.Window; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.registry.Registries; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Util; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import org.joml.Matrix4f; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.util.List; +import java.util.*; + +public class FunctionCompatibility implements FunctionHolder, + SoundManager.Interface, + WorldInteraction.Interface, + Renderer3D.Interface, + Renderer2D.Interface, + FontRenderer.Interface, + io.github.kurrycat.mpkmod.compatibility.MCClasses.Minecraft.Interface, + io.github.kurrycat.mpkmod.compatibility.MCClasses.Keyboard.Interface, + Profiler.Interface { + public static final Set pressedButtons = new HashSet<>(); + public DrawContext drawContext = null; + + public void playButtonSound() { + MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F)); + } + + public List getCollisionBoundingBoxes(Vector3D blockPosVector) { + final Vector3D blockPosVec = blockPosVector.copy(); + BlockPos blockPos = new BlockPos(blockPosVec.getXI(), blockPosVec.getYI(), blockPosVec.getZI()); + if (MinecraftClient.getInstance().world == null) return null; + ArrayList boundingBoxes = new ArrayList<>(); + BlockState blockState = MinecraftClient.getInstance().world.getBlockState(blockPos); + + blockState.getCollisionShape(MinecraftClient.getInstance().world, blockPos).simplify().forEachBox( + ((minX, minY, minZ, maxX, maxY, maxZ) -> boundingBoxes.add( + new BoundingBox3D(new Vector3D(minX, minY, minZ), new Vector3D(maxX, maxY, maxZ)).move(blockPosVec) + )) + ); + + return boundingBoxes; + } + + public Vector3D getLookingAt() { + if (MinecraftClient.getInstance().getCameraEntity() == null) + return null; + + HitResult hitResult = MinecraftClient.getInstance().getCameraEntity().raycast(20, 0, false); + if (hitResult instanceof BlockHitResult) { + BlockPos blockPos = ((BlockHitResult) hitResult).getBlockPos(); + return new Vector3D(blockPos.getX(), blockPos.getY(), blockPos.getZ()); + } + + return null; + } + + @Override + public String getBlockName(Vector3D blockPos) { + BlockPos blockpos = new BlockPos(blockPos.getXI(), blockPos.getYI(), blockPos.getZI()); + if (MinecraftClient.getInstance().world == null) + return null; + + return Registries.BLOCK.getKey( + MinecraftClient.getInstance().world.getBlockState(blockpos).getBlock() + ).toString(); + } + + @Override + public HashMap getBlockProperties(Vector3D blockPos) { + HashMap properties = new HashMap<>(); + if (MinecraftClient.getInstance().world == null) + return properties; + + BlockPos blockpos = new BlockPos(blockPos.getXI(), blockPos.getYI(), blockPos.getZI()); + BlockState blockState = MinecraftClient.getInstance().world.getBlockState(blockpos); + blockState.getEntries().forEach((key, value) -> + properties.put(key.getName(), Util.getValueAsString(key, value)) + ); + return null; + } + + /** + * Is called in {@link io.github.kurrycat.mpkmod.compatibility.MCClasses.WorldInteraction.Interface WorldInteraction.Interface} + */ + public String getLookingAtBlock() { + if (MinecraftClient.getInstance().getCameraEntity() == null) + return null; + + HitResult hitResult = MinecraftClient.getInstance().getCameraEntity().raycast(20, 0, false); + if (hitResult.getType() == HitResult.Type.BLOCK && MinecraftClient.getInstance().world != null) { + return Registries.BLOCK.getKey( + MinecraftClient.getInstance().world.getBlockState(((BlockHitResult) hitResult).getBlockPos()).getBlock() + ).toString(); + } + return null; + } + + public void drawBox(BoundingBox3D bb, Color color, float partialTicks) { + int r = color.getRed(), g = color.getGreen(), b = color.getBlue(), a = color.getAlpha(); + + RenderSystem.applyModelViewMatrix(); + + RenderSystem.enableBlend(); + RenderSystem.enableDepthTest(); + RenderSystem.setShader(GameRenderer::getPositionColorProgram); + + Tessellator tessellator = Tessellator.getInstance(); + + RenderSystem.lineWidth(1.0F); + + Matrix4f posMat = MPKMod.INSTANCE.matrixStack.peek().getPositionMatrix(); + + float minX = (float) bb.minX(); + float minY = (float) bb.minY(); + float minZ = (float) bb.minZ(); + float maxX = (float) bb.maxX(); + float maxY = (float) bb.maxY(); + float maxZ = (float) bb.maxZ(); + + BufferBuilder builder = tessellator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR); + + builder.vertex(posMat, minX, maxY, minZ).color(r, g, b, a); + builder.vertex(posMat, maxX, maxY, minZ).color(r, g, b, a); + builder.vertex(posMat, maxX, minY, minZ).color(r, g, b, a); + builder.vertex(posMat, minX, minY, minZ).color(r, g, b, a); + + builder.vertex(posMat, minX, minY, maxZ).color(r, g, b, a); + builder.vertex(posMat, maxX, minY, maxZ).color(r, g, b, a); + builder.vertex(posMat, maxX, maxY, maxZ).color(r, g, b, a); + builder.vertex(posMat, minX, maxY, maxZ).color(r, g, b, a); + + builder.vertex(posMat, minX, minY, minZ).color(r, g, b, a); + builder.vertex(posMat, maxX, minY, minZ).color(r, g, b, a); + builder.vertex(posMat, maxX, minY, maxZ).color(r, g, b, a); + builder.vertex(posMat, minX, minY, maxZ).color(r, g, b, a); + + builder.vertex(posMat, minX, maxY, maxZ).color(r, g, b, a); + builder.vertex(posMat, maxX, maxY, maxZ).color(r, g, b, a); + builder.vertex(posMat, maxX, maxY, minZ).color(r, g, b, a); + builder.vertex(posMat, minX, maxY, minZ).color(r, g, b, a); + + builder.vertex(posMat, minX, minY, maxZ).color(r, g, b, a); + builder.vertex(posMat, minX, maxY, maxZ).color(r, g, b, a); + builder.vertex(posMat, minX, maxY, minZ).color(r, g, b, a); + builder.vertex(posMat, minX, minY, minZ).color(r, g, b, a); + + builder.vertex(posMat, maxX, minY, minZ).color(r, g, b, a); + builder.vertex(posMat, maxX, maxY, minZ).color(r, g, b, a); + builder.vertex(posMat, maxX, maxY, maxZ).color(r, g, b, a); + builder.vertex(posMat, maxX, minY, maxZ).color(r, g, b, a); + + BufferRenderer.drawWithGlobalProgram(builder.end()); + + RenderSystem.enableBlend(); + } + + /** + * Is called in {@link Renderer2D.Interface} + */ + public void drawRect(Vector2D pos, Vector2D size, Color color) { + if (drawContext == null) return; + //0.04 because drawString SHADOW_OFFSET is 0.03 + drawContext.getMatrices().translate(0, 0, 0.04); + Matrix4f posMat = drawContext.getMatrices().peek().getPositionMatrix(); + int r = color.getRed(), g = color.getGreen(), b = color.getBlue(), a = color.getAlpha(); + double x = pos.getX(), y = pos.getY(), w = size.getX(), h = size.getY(); + + Tessellator tessellator = Tessellator.getInstance(); + RenderSystem.enableBlend(); + RenderSystem.setShader(GameRenderer::getPositionColorProgram); + BufferBuilder bb = tessellator.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR); + bb.vertex(posMat, (float) x, (float) (y + h), 0).color(r, g, b, a); + bb.vertex(posMat, (float) (x + w), (float) (y + h), 0).color(r, g, b, a); + bb.vertex(posMat, (float) (x + w), (float) y, 0).color(r, g, b, a); + bb.vertex(posMat, (float) x, (float) y, 0).color(r, g, b, a); + BufferRenderer.drawWithGlobalProgram(bb.end()); + + RenderSystem.disableBlend(); + } + + /** + * Is called in {@link Renderer2D.Interface} + */ + public void drawLines(Collection points, Color color) { + if (points.size() < 2) { + Debug.stacktrace("At least two points expected, got: " + points.size()); + return; + } + int r = color.getRed(), g = color.getGreen(), b = color.getBlue(), a = color.getAlpha(); + + drawContext.getMatrices().translate(0, 0, 0.04); + Matrix4f posMat = drawContext.getMatrices().peek().getPositionMatrix(); + + RenderSystem.enableBlend(); + RenderSystem.enableDepthTest(); + RenderSystem.setShader(GameRenderer::getPositionColorProgram); + + Tessellator tessellator = Tessellator.getInstance(); + + RenderSystem.lineWidth(1.0f); + + BufferBuilder builder = tessellator.begin(VertexFormat.DrawMode.DEBUG_LINE_STRIP, VertexFormats.POSITION_COLOR); + + for (Vector2D p : points) { + builder.vertex(posMat, (float) p.getX(), (float) p.getY(), 0).color(r, g, b, a); + } + + BufferRenderer.drawWithGlobalProgram(builder.end()); + + RenderSystem.enableBlend(); + } + + public Vector2D getScaledSize() { + return new Vector2D( + MinecraftClient.getInstance().getWindow().getScaledWidth(), + MinecraftClient.getInstance().getWindow().getScaledHeight() + ); + } + + public Vector2D getScreenSize() { + return new Vector2D(MinecraftClient.getInstance().getWindow().getWidth(), MinecraftClient.getInstance().getWindow().getHeight()); + } + + public void enableScissor(double x, double y, double w, double h) { + GL11.glEnable(GL11.GL_SCISSOR_TEST); + Window r = MinecraftClient.getInstance().getWindow(); + + double scaleFactor = r.getScaleFactor(); + double posX = x * scaleFactor; + double posY = r.getFramebufferHeight() - (y + h) * scaleFactor; + double width = w * scaleFactor; + double height = h * scaleFactor; + GL11.glScissor((int) posX, (int) posY, Math.max(0, (int) width), Math.max(0, (int) height)); + } + + public void disableScissor() { + GL11.glDisable(GL11.GL_SCISSOR_TEST); + } + + + public void drawString(String text, double x, double y, Color color, double fontSize, boolean shadow) { + if (drawContext == null) return; + MatrixStack matrixStack = drawContext.getMatrices(); + matrixStack.translate(0, 0, 0.04); + matrixStack.push(); + matrixStack.translate(x, y, 0); + double scale = fontSize / MinecraftClient.getInstance().textRenderer.fontHeight; + matrixStack.scale((float) scale, (float) scale, 1); + drawContext.drawText( + MinecraftClient.getInstance().textRenderer, text, + 0, 0, color.getRGB(), shadow + ); + matrixStack.pop(); + } + + public Vector2D getStringSize(String text, double fontSize) { + return new Vector2D( + MinecraftClient.getInstance().textRenderer.getWidth(text) * + (float) (fontSize / MinecraftClient.getInstance().textRenderer.fontHeight), + (float) fontSize + ); + } + + public String getIP() { + ServerInfo d = MinecraftClient.getInstance().getCurrentServerEntry(); + + if (d == null) + return "Multiplayer"; + else + return d.address; + } + + public String getFPS() { + String[] split = MinecraftClient.getInstance().fpsDebugString.split(" "); + if (split.length == 0) + return "Error"; + return split[0]; + } + + public void displayGuiScreen(MPKGuiScreen screen) { + MinecraftClient.getInstance().setScreen( + screen == null + ? null + : new io.github.kurrycat.mpkmod.compatibility.fabric_1_21.MPKGuiScreen(screen)); + } + + public String getCurrentGuiScreen() { + Screen curr = MinecraftClient.getInstance().currentScreen; + + if (curr == null) + return null; + else if (curr instanceof io.github.kurrycat.mpkmod.compatibility.fabric_1_21.MPKGuiScreen) { + String id = ((io.github.kurrycat.mpkmod.compatibility.fabric_1_21.MPKGuiScreen) curr).eventReceiver.getID(); + if (id == null) + id = "unknown"; + + return id; + } + + return curr.getClass().getSimpleName(); + } + + /** + * Is called in {@link io.github.kurrycat.mpkmod.compatibility.MCClasses.Minecraft.Interface Minecraft.Interface} + */ + public String getUserName() { + if (MinecraftClient.getInstance().player == null) return null; + return MinecraftClient.getInstance().player.getName().getString(); + } + + public void copyToClipboard(String content) { + MinecraftClient.getInstance().keyboard.setClipboard(content); + } + + public boolean setInputs(Float yaw, boolean relYaw, Float pitch, boolean relPitch, int pressedInputs, int releasedInputs, int L, int R) { + if (!io.github.kurrycat.mpkmod.compatibility.MCClasses.Minecraft.isSingleplayer()) return false; + ClientPlayerEntity player = MinecraftClient.getInstance().player; + if (player == null) return false; + GameOptions op = MinecraftClient.getInstance().options; + + float prevYaw = player.getYaw(); + float prevPitch = player.getPitch(); + + if (yaw != null) { + player.setYaw(relYaw ? (player.getYaw() + yaw) : yaw); + player.prevYaw += player.getYaw() - prevYaw; + } + if (pitch != null) { + player.setPitch(relPitch ? (player.getPitch() + pitch) : pitch); + player.setPitch(MathHelper.clamp(player.getPitch(), -90.0F, 90.0F)); + + player.prevPitch += player.getPitch() - prevPitch; + player.prevPitch = MathHelper.clamp(player.prevPitch, -90.0F, 90.0F); + } + + if (player.getVehicle() != null) { + player.getVehicle().onPassengerLookAround(player); + } + + KeyBinding[] keys = new KeyBinding[]{ + op.forwardKey, + op.leftKey, + op.backKey, + op.rightKey, + op.sprintKey, + op.sneakKey, + op.jumpKey + }; + + for (int i = 0; i < keys.length; i++) { + if ((releasedInputs & 1 << i) != 0) { + KeyBinding.setKeyPressed(((KeyBindingAccessor) keys[i]).getBoundKey(), false); + } + if ((pressedInputs & 1 << i) != 0) { + KeyBinding.setKeyPressed(((KeyBindingAccessor) keys[i]).getBoundKey(), true); + KeyBinding.onKeyPressed(((KeyBindingAccessor) keys[i]).getBoundKey()); + } + } + + KeyBinding.setKeyPressed(((KeyBindingAccessor) op.attackKey).getBoundKey(), L > 0); + for (int i = 0; i < L; i++) + KeyBinding.onKeyPressed(((KeyBindingAccessor) op.attackKey).getBoundKey()); + + KeyBinding.setKeyPressed(((KeyBindingAccessor) op.useKey).getBoundKey(), R > 0); + for (int i = 0; i < R; i++) + KeyBinding.onKeyPressed(((KeyBindingAccessor) op.useKey).getBoundKey()); + + return true; + } + + public boolean isF3Enabled() { + return MinecraftClient.getInstance().getDebugHud().shouldShowDebugHud(); + } + + public List getPressedButtons() { + return new ArrayList<>(pressedButtons); + } + + public void startSection(String name) { + MinecraftClient.getInstance().getProfiler().push(name); + } + + public void endStartSection(String name) { + MinecraftClient.getInstance().getProfiler().swap(name); + } + + public void endSection() { + MinecraftClient.getInstance().getProfiler().pop(); + } +} diff --git a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/MPKGuiScreen.java b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/MPKGuiScreen.java new file mode 100644 index 00000000..7dbb4b3c --- /dev/null +++ b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/MPKGuiScreen.java @@ -0,0 +1,86 @@ +package io.github.kurrycat.mpkmod.compatibility.fabric_1_21; + +import io.github.kurrycat.mpkmod.compatibility.API; +import io.github.kurrycat.mpkmod.compatibility.MCClasses.Profiler; +import io.github.kurrycat.mpkmod.util.MathUtil; +import io.github.kurrycat.mpkmod.util.Vector2D; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.text.Text; + +public class MPKGuiScreen extends Screen { + public io.github.kurrycat.mpkmod.gui.MPKGuiScreen eventReceiver; + + public MPKGuiScreen(io.github.kurrycat.mpkmod.gui.MPKGuiScreen screen) { + super(Text.translatable(API.MODID + ".gui.title")); + eventReceiver = screen; + } + + public void init() { + eventReceiver.onInit(); + } + + @Override + public void resize(MinecraftClient client, int width, int height) { + super.resize(client, width, height); + eventReceiver.onResize(width, height); + } + + public void render(DrawContext drawContext, int mouseX, int mouseY, float delta) { + drawContext.getMatrices().push(); + API.getFunctionHolder().drawContext = drawContext; + Profiler.startSection(eventReceiver.getID() == null ? "mpk_gui" : eventReceiver.getID()); + try { + eventReceiver.drawScreen(new Vector2D(mouseX, mouseY), delta); + } catch (Exception e) { + API.LOGGER.warn("Error in drawScreen with id: " + eventReceiver.getID(), e); + } + Profiler.endSection(); + drawContext.getMatrices().pop(); + } + + public void close() { + super.close(); + eventReceiver.onGuiClosed(); + } + + public boolean shouldPause() { + return false; + } + + public boolean mouseClicked(double mouseX, double mouseY, int state) { + eventReceiver.onMouseClicked(new Vector2D(mouseX, mouseY), state); + return super.mouseClicked(mouseX, mouseY, state); + } + + public boolean mouseReleased(double mouseX, double mouseY, int state) { + eventReceiver.onMouseReleased(new Vector2D(mouseX, mouseY), state); + return super.mouseReleased(mouseX, mouseY, state); + } + + public boolean mouseDragged(double mouseX, double mouseY, int clickedMouseButton, double moveX, double moveY) { + eventReceiver.onMouseClickMove(new Vector2D(mouseX, mouseY), clickedMouseButton, 0); + return super.mouseDragged(mouseX, mouseY, clickedMouseButton, moveX, moveY); + } + + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + eventReceiver.onKeyEvent(keyCode, scanCode, modifiers, false); + return super.keyPressed(keyCode, scanCode, modifiers); + } + + @Override + public boolean charTyped(char c, int modifiers) { + eventReceiver.onKeyEvent(c, 0, modifiers, true); + return super.charTyped(c, modifiers); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { + eventReceiver.onMouseScroll( + new Vector2D(mouseX, mouseY), + (int) (MathUtil.constrain(verticalAmount, -1, 1) * 7) + ); + return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); + } +} diff --git a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/MPKMod.java b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/MPKMod.java new file mode 100644 index 00000000..995b913d --- /dev/null +++ b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/MPKMod.java @@ -0,0 +1,80 @@ +package io.github.kurrycat.mpkmod.compatibility.fabric_1_21; + +import io.github.kurrycat.mpkmod.compatibility.API; +import io.github.kurrycat.mpkmod.compatibility.MCClasses.KeyBinding; +import net.fabricmc.api.ModInitializer; +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.networking.v1.ClientPlayConnectionEvents; +import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; +import net.minecraft.SharedConstants; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.util.math.MatrixStack; + +import java.util.HashMap; +import java.util.Map; + +public class MPKMod implements ModInitializer { + public static final MPKMod INSTANCE = new MPKMod(); + public static Map keyBindingMap = new HashMap<>(); + public final EventHandler eventHandler = new EventHandler(); + public MatrixStack matrixStack; + + @Override + public void onInitialize() { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + API.LOGGER.info("Loading " + API.NAME + " " + API.VERSION); + API.preInit(getClass()); + registerKeybindingsFromGUIs(); + + HudRenderCallback.EVENT.register(eventHandler::onInGameOverlayRender); + ClientTickEvents.START_CLIENT_TICK.register(eventHandler::onClientTickStart); + ClientTickEvents.END_CLIENT_TICK.register(eventHandler::onClientTickEnd); + ClientPlayConnectionEvents.JOIN.register(eventHandler::onServerConnect); + ClientPlayConnectionEvents.DISCONNECT.register(eventHandler::onServerDisconnect); + } + + private void registerKeybindingsFromGUIs() { + API.guiScreenMap.forEach((id, guiScreen) -> { + if (guiScreen.shouldCreateKeyBind()) + registerKeyBinding(id); + }); + + API.keyBindingMap.forEach((id, consumer) -> registerKeyBinding(id)); + keyBindingMap.forEach((id, key) -> KeyBindingHelper.registerKeyBinding(key)); + } + + public void registerKeyBinding(String id) { + net.minecraft.client.option.KeyBinding keyBinding = new net.minecraft.client.option.KeyBinding( + API.MODID + ".key." + id + ".desc", + -1, + API.KEYBINDING_CATEGORY + ); + + keyBindingMap.put(id, keyBinding); + } + + public void init() { + API.LOGGER.info(API.COMPATIBILITY_MARKER, "Registering compatibility functions..."); + API.registerFunctionHolder(new FunctionCompatibility()); + API.LOGGER.info(API.COMPATIBILITY_MARKER, "Registered compatibility functions."); + + registerKeyBindings(); + API.init(SharedConstants.getGameVersion().getName()); + + API.Events.onLoadComplete(); + } + + private void registerKeyBindings() { + for (net.minecraft.client.option.KeyBinding k : MinecraftClient.getInstance().options.allKeys) { + new io.github.kurrycat.mpkmod.compatibility.MCClasses.KeyBinding( + () -> k.getBoundKeyLocalizedText().getString(), + k.getTranslationKey(), + k::isPressed + ); + } + + API.LOGGER.info(API.COMPATIBILITY_MARKER, "Registered {} Keybindings", KeyBinding.getKeyMap().size()); + } +} diff --git a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/GameRendererMixin.java b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/GameRendererMixin.java new file mode 100644 index 00000000..13073a89 --- /dev/null +++ b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/GameRendererMixin.java @@ -0,0 +1,32 @@ +package io.github.kurrycat.mpkmod.compatibility.fabric_1_21.mixin; + +import com.mojang.blaze3d.systems.RenderSystem; +import io.github.kurrycat.mpkmod.compatibility.fabric_1_21.MPKMod; +import net.minecraft.client.render.Camera; +import net.minecraft.client.render.GameRenderer; +import net.minecraft.client.render.RenderTickCounter; +import net.minecraft.client.util.math.MatrixStack; +import org.joml.Matrix4fStack; +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(value = GameRenderer.class) +public class GameRendererMixin { + @Inject(at = @At(value = "INVOKE_STRING", + target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V", + args = "ldc=hand"), + method = "renderWorld") + public void render(RenderTickCounter tickCounter, CallbackInfo ci) { + GameRenderer gameRenderer = (GameRenderer) (Object) this; + Camera camera = gameRenderer.getCamera(); + Matrix4fStack matrixStack = RenderSystem.getModelViewStack(); + matrixStack.pushMatrix(); + matrixStack.rotateXYZ(camera.getPitch() * ((float) Math.PI / 180), camera.getYaw() * ((float) Math.PI / 180) + (float) Math.PI, 0.0f); + + MPKMod.INSTANCE.eventHandler.onRenderWorldOverlay(new MatrixStack(), tickCounter.getTickDelta(false)); + + matrixStack.popMatrix(); + } +} diff --git a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/KeyBindingAccessor.java b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/KeyBindingAccessor.java new file mode 100644 index 00000000..ad96efba --- /dev/null +++ b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/KeyBindingAccessor.java @@ -0,0 +1,12 @@ +package io.github.kurrycat.mpkmod.compatibility.fabric_1_21.mixin; + +import net.minecraft.client.option.KeyBinding; +import net.minecraft.client.util.InputUtil; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(KeyBinding.class) +public interface KeyBindingAccessor { + @Accessor + InputUtil.Key getBoundKey(); +} diff --git a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/KeyboardMixin.java b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/KeyboardMixin.java new file mode 100644 index 00000000..6da0fe93 --- /dev/null +++ b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/KeyboardMixin.java @@ -0,0 +1,18 @@ +package io.github.kurrycat.mpkmod.compatibility.fabric_1_21.mixin; + +import io.github.kurrycat.mpkmod.compatibility.fabric_1_21.MPKMod; +import net.minecraft.client.Keyboard; +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(Keyboard.class) +public class KeyboardMixin { + @Inject(method = "onKey", at = @At(value = "RETURN")) + private void onKey(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) { + if(key != -1) { + MPKMod.INSTANCE.eventHandler.onKey(key, scancode, action); + } + } +} diff --git a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/MinecraftClientMixin.java b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/MinecraftClientMixin.java new file mode 100644 index 00000000..3ed4083a --- /dev/null +++ b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/MinecraftClientMixin.java @@ -0,0 +1,16 @@ +package io.github.kurrycat.mpkmod.compatibility.fabric_1_21.mixin; + +import io.github.kurrycat.mpkmod.compatibility.fabric_1_21.MPKMod; +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; + +@Mixin(MinecraftClient.class) +public class MinecraftClientMixin { + @Inject(at = @At("TAIL"), method = "") + private void init(CallbackInfo info) { + MPKMod.INSTANCE.init(); + } +} diff --git a/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/MouseMixin.java b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/MouseMixin.java new file mode 100644 index 00000000..8cf1033f --- /dev/null +++ b/fabric-1.21/src/main/java/io/github/kurrycat/mpkmod/compatibility/fabric_1_21/mixin/MouseMixin.java @@ -0,0 +1,55 @@ +package io.github.kurrycat.mpkmod.compatibility.fabric_1_21.mixin; + +import io.github.kurrycat.mpkmod.compatibility.API; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.Mouse; +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; + +@Mixin(Mouse.class) +public class MouseMixin { + @Shadow + private double cursorDeltaX; + @Shadow + private double cursorDeltaY; + @Shadow + private double x; + @Shadow + private double y; + + @Inject(method = "onCursorPos", at = @At(value = "TAIL")) + private void onCursorPos(long window, double x, double y, CallbackInfo ci) { + if (window == MinecraftClient.getInstance().getWindow().getHandle()) { + API.Events.onMouseInput( + io.github.kurrycat.mpkmod.util.Mouse.Button.NONE, + io.github.kurrycat.mpkmod.util.Mouse.State.NONE, + (int) x, (int) y, (int) cursorDeltaX, (int) -cursorDeltaY, + 0, System.nanoTime() + ); + } + } + + @Inject(method = "onMouseScroll", at = @At(value = "TAIL")) + private void onMouseScroll(long window, double horizontal, double vertical, CallbackInfo ci) { + API.Events.onMouseInput( + io.github.kurrycat.mpkmod.util.Mouse.Button.NONE, + io.github.kurrycat.mpkmod.util.Mouse.State.NONE, + (int) x, (int) y, 0, 0, + (int) vertical, System.nanoTime() + ); + } + + @Inject(method = "onMouseButton", at = @At(value = "TAIL")) + private void onMouseButton(long window, int button, int action, int mods, CallbackInfo ci) { + API.Events.onMouseInput( + io.github.kurrycat.mpkmod.util.Mouse.Button.fromInt(button), + button == -1 ? io.github.kurrycat.mpkmod.util.Mouse.State.NONE : + (action == 1 ? io.github.kurrycat.mpkmod.util.Mouse.State.DOWN : io.github.kurrycat.mpkmod.util.Mouse.State.UP), + (int) x, (int) y, 0, 0, + 0, System.nanoTime() + ); + } +} diff --git a/fabric-1.21/src/main/resources/assets/mpkmod/icon.png b/fabric-1.21/src/main/resources/assets/mpkmod/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..48bcd55b0c041883e83c5cf2cabb942b2ad92f14 GIT binary patch literal 11576 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.15.11", + "fabric-api": "*", + "minecraft": "~1.21", + "java": ">=21" + }, + "suggests": {} +} diff --git a/fabric-1.21/src/main/resources/mpkmod.mixins.json b/fabric-1.21/src/main/resources/mpkmod.mixins.json new file mode 100644 index 00000000..77fe20b1 --- /dev/null +++ b/fabric-1.21/src/main/resources/mpkmod.mixins.json @@ -0,0 +1,18 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "io.github.kurrycat.mpkmod.compatibility.fabric_1_21.mixin", + "compatibilityLevel": "JAVA_21", + "mixins": [ + ], + "client": [ + "GameRendererMixin", + "KeyBindingAccessor", + "KeyboardMixin", + "MinecraftClientMixin", + "MouseMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index c653d102..499cdb92 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -28,4 +28,5 @@ if (System.getenv("JITPACK") == null) { include("fabric-1.19.4") include("fabric-1.20.4") include("fabric-1.20.6") + include("fabric-1.21") } \ No newline at end of file