Merge branch '1.20.5' into eye_tracking_range_combat

This commit is contained in:
Martin Prokoph
2024-04-29 20:05:05 +02:00
committed by GitHub
17 changed files with 220 additions and 117 deletions

View File

@@ -1,5 +1,5 @@
plugins { plugins {
id 'fabric-loom' version '1.1-SNAPSHOT' id 'fabric-loom' version '1.6-SNAPSHOT'
id 'java-library' id 'java-library'
id 'maven-publish' id 'maven-publish'
id 'com.github.johnrengelman.shadow' version '7.0.0' id 'com.github.johnrengelman.shadow' version '7.0.0'
@@ -13,7 +13,7 @@ group = project.maven_group
version = "${project.mod_version}+${getMCVersionString()}" version = "${project.mod_version}+${getMCVersionString()}"
// This field defines the Java version your mod target. // This field defines the Java version your mod target.
def targetJavaVersion = 17 def targetJavaVersion = 21
boolean isMCVersionNonRelease() { boolean isMCVersionNonRelease() {
return project.minecraft_version.matches('^\\d\\dw\\d\\d[a-z]$') return project.minecraft_version.matches('^\\d\\dw\\d\\d[a-z]$')

View File

@@ -3,9 +3,9 @@ org.gradle.jvmargs=-Xmx1G
# Fabric Properties # Fabric Properties
# check these on https://fabricmc.net/use # check these on https://fabricmc.net/use
minecraft_version=1.20.4 minecraft_version=1.20.5
yarn_mappings=1.20.4+build.3 yarn_mappings=1.20.5+build.1
loader_version=0.15.3 loader_version=0.15.10
# Mod Properties # Mod Properties
mod_version = 1.9.4 mod_version = 1.9.4
@@ -17,11 +17,11 @@ changelog = See changes at: https://github.com/TeamMidnightDust/MidnightControls
# Dependencies # Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_version=0.91.3+1.20.4 fabric_version=0.97.7+1.20.5
sodium_version=mc1.19.2-0.4.4 sodium_version=mc1.19.2-0.4.4
spruceui_version=5.0.3+1.20.4 spruceui_version=5.0.3+1.20.4
midnightlib_version=1.5.3-fabric midnightlib_version=1.5.4-fabric
modmenu_version=7.0.0 modmenu_version=10.0.0-beta.1
emotecraft_version=2.1.3-SNAPSHOT-build.29-MC1.19-fabric emotecraft_version=2.1.3-SNAPSHOT-build.29-MC1.19-fabric
bendylib_version=2.0.+ bendylib_version=2.0.+
emi_version=1.1.1+1.20.4+fabric emi_version=1.1.1+1.20.4+fabric

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@@ -9,15 +9,18 @@
package eu.midnightdust.midnightcontrols; package eu.midnightdust.midnightcontrols;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import eu.midnightdust.midnightcontrols.event.PlayerChangeControlsModeCallback; import eu.midnightdust.midnightcontrols.event.PlayerChangeControlsModeCallback;
import eu.midnightdust.midnightcontrols.packet.ControlsModePacket;
import eu.midnightdust.midnightcontrols.packet.FeaturePacket;
import eu.midnightdust.midnightcontrols.packet.HelloPacket;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.ModContainer;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Identifier; import net.minecraft.network.packet.CustomPayload;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -34,9 +37,9 @@ import java.util.Optional;
*/ */
public class MidnightControls implements ModInitializer { public class MidnightControls implements ModInitializer {
private static MidnightControls INSTANCE; private static MidnightControls INSTANCE;
public static final Identifier CONTROLS_MODE_CHANNEL = new Identifier(MidnightControlsConstants.CONTROLS_MODE_CHANNEL.toString()); public static final CustomPayload.Id<CustomPayload> CONTROLS_MODE_CHANNEL = CustomPayload.id(MidnightControlsConstants.CONTROLS_MODE_CHANNEL.toString());
public static final Identifier FEATURE_CHANNEL = new Identifier(MidnightControlsConstants.FEATURE_CHANNEL.toString()); public static final CustomPayload.Id<CustomPayload> FEATURE_CHANNEL = CustomPayload.id(MidnightControlsConstants.FEATURE_CHANNEL.toString());
public static final Identifier HELLO_CHANNEL = new Identifier(MidnightControlsConstants.HELLO_CHANNEL.toString()); public static final CustomPayload.Id<CustomPayload> HELLO_CHANNEL = CustomPayload.id(MidnightControlsConstants.HELLO_CHANNEL.toString());
public static boolean isExtrasLoaded; public static boolean isExtrasLoaded;
public final Logger logger = LogManager.getLogger("MidnightControls"); public final Logger logger = LogManager.getLogger("MidnightControls");
@@ -47,19 +50,19 @@ public class MidnightControls implements ModInitializer {
isExtrasLoaded = FabricLoader.getInstance().isModLoaded("midnightcontrols-extra"); isExtrasLoaded = FabricLoader.getInstance().isModLoaded("midnightcontrols-extra");
this.log("Initializing MidnightControls..."); this.log("Initializing MidnightControls...");
ServerPlayNetworking.registerGlobalReceiver(HELLO_CHANNEL, (server, player, handler, buf, responseSender) -> { PayloadTypeRegistry.playC2S().register(HelloPacket.PACKET_ID, HelloPacket.codec);
String version = buf.readString(32); PayloadTypeRegistry.playC2S().register(ControlsModePacket.PACKET_ID, ControlsModePacket.codec);
ControlsMode.byId(buf.readString(32)) PayloadTypeRegistry.playS2C().register(ControlsModePacket.PACKET_ID, ControlsModePacket.codec);
.ifPresent(controlsMode -> server PayloadTypeRegistry.playS2C().register(FeaturePacket.PACKET_ID, FeaturePacket.codec);
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(player, controlsMode)));
server.execute(() -> { ServerPlayNetworking.registerGlobalReceiver(HelloPacket.PACKET_ID, (payload, context) -> {
ServerPlayNetworking.send(player, FEATURE_CHANNEL, this.makeFeatureBuffer(MidnightControlsFeature.HORIZONTAL_REACHAROUND)); ControlsMode.byId(payload.controlsMode())
.ifPresent(controlsMode -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.player(), controlsMode));
context.responseSender().sendPacket(new FeaturePacket(MidnightControlsFeature.HORIZONTAL_REACHAROUND));
}); });
}); ServerPlayNetworking.registerGlobalReceiver(ControlsModePacket.PACKET_ID,
ServerPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (payload, context) -> ControlsMode.byId(payload.controlsMode())
(server, player, handler, buf, responseSender) -> ControlsMode.byId(buf.readString(32)) .ifPresent(controlsMode -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(context.player(), controlsMode)));
.ifPresent(controlsMode -> server
.execute(() -> PlayerChangeControlsModeCallback.EVENT.invoker().apply(player, controlsMode))));
} }
/** /**
@@ -80,44 +83,6 @@ public class MidnightControls implements ModInitializer {
this.logger.info("[MidnightControls] " + warning); this.logger.info("[MidnightControls] " + warning);
} }
/**
* Returns a packet byte buffer made for the midnightcontrols:controls_mode plugin message.
*
* @param controlsMode the controls mode to send
* @return the packet byte buffer
*/
public PacketByteBuf makeControlsModeBuffer(@NotNull ControlsMode controlsMode) {
Objects.requireNonNull(controlsMode, "Controls mode cannot be null.");
return new PacketByteBuf(Unpooled.buffer()).writeString(controlsMode.getName(), 32);
}
/**
* Returns a packet byte buffer made for the midnightcontrols:feature plugin message.
*
* @param features the features data to send
* @return the packet byte buffer
*/
public PacketByteBuf makeFeatureBuffer(MidnightControlsFeature... features) {
if (features.length == 0)
throw new IllegalArgumentException("At least one feature must be provided.");
var buffer = new PacketByteBuf(Unpooled.buffer());
buffer.writeVarInt(features.length);
for (var feature : features) {
buffer.writeString(feature.getName(), 64);
buffer.writeBoolean(feature.isAllowed());
}
return buffer;
}
public PacketByteBuf makeHello(@NotNull ControlsMode controlsMode) {
var version = "";
Optional<ModContainer> container;
if ((container = FabricLoader.getInstance().getModContainer(MidnightControlsConstants.NAMESPACE)).isPresent()) {
version = container.get().getMetadata().getVersion().getFriendlyString();
}
return new PacketByteBuf(Unpooled.buffer()).writeString(version, 32).writeString(controlsMode.getName(), 32);
}
/** /**
* Gets the MidnightControls instance. * Gets the MidnightControls instance.
* *

View File

@@ -29,6 +29,9 @@ import eu.midnightdust.midnightcontrols.client.ring.MidnightRing;
import dev.lambdaurora.spruceui.hud.HudManager; import dev.lambdaurora.spruceui.hud.HudManager;
import eu.midnightdust.midnightcontrols.client.touch.TouchInput; import eu.midnightdust.midnightcontrols.client.touch.TouchInput;
import eu.midnightdust.midnightcontrols.client.util.RainbowColor; import eu.midnightdust.midnightcontrols.client.util.RainbowColor;
import eu.midnightdust.midnightcontrols.packet.ControlsModePacket;
import eu.midnightdust.midnightcontrols.packet.FeaturePacket;
import eu.midnightdust.midnightcontrols.packet.HelloPacket;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
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.keybinding.v1.KeyBindingHelper;
@@ -37,6 +40,7 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.ResourcePackActivationType; import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.option.KeyBinding; import net.minecraft.client.option.KeyBinding;
@@ -48,9 +52,7 @@ import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import java.io.File; import java.io.File;
import java.util.Objects; import java.util.*;
import java.util.Timer;
import java.util.TimerTask;
/** /**
* Represents the midnightcontrols client mod. * Represents the midnightcontrols client mod.
@@ -94,19 +96,19 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
this.ring.registerAction("buttonbinding", ButtonBindingRingAction.FACTORY); this.ring.registerAction("buttonbinding", ButtonBindingRingAction.FACTORY);
ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (client, handler, buf, responseSender) -> ClientPlayNetworking.registerGlobalReceiver(CONTROLS_MODE_CHANNEL, (payload, context) ->
responseSender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode))); context.responseSender().sendPacket(new ControlsModePacket(MidnightControlsConfig.controlsMode.getName())));
ClientPlayNetworking.registerGlobalReceiver(FEATURE_CHANNEL, (client, handler, buf, responseSender) -> { ClientPlayNetworking.registerGlobalReceiver(FeaturePacket.PACKET_ID, ((payload, context) -> {}));
int features = buf.readVarInt();
for (int i = 0; i < features; i++) {
var name = buf.readString(64);
boolean allowed = buf.readBoolean();
MidnightControlsFeature.fromName(name).ifPresent(feature -> client.execute(() -> feature.setAllowed(allowed)));
}
});
ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> { ClientPlayConnectionEvents.JOIN.register((handler, sender, client) -> {
sender.sendPacket(HELLO_CHANNEL, this.makeHello(MidnightControlsConfig.controlsMode)); var version = "";
sender.sendPacket(CONTROLS_MODE_CHANNEL, this.makeControlsModeBuffer(MidnightControlsConfig.controlsMode)); Optional<ModContainer> container;
if ((container = FabricLoader.getInstance().getModContainer(MidnightControlsConstants.NAMESPACE)).isPresent()) {
version = container.get().getMetadata().getVersion().getFriendlyString();
}
var controlsMode = MidnightControlsConfig.controlsMode.getName();
sender.sendPacket(new HelloPacket(version, controlsMode));
sender.sendPacket(new ControlsModePacket(controlsMode));
}); });
ClientPlayConnectionEvents.DISCONNECT.register(this::onLeave); ClientPlayConnectionEvents.DISCONNECT.register(this::onLeave);
@@ -255,6 +257,7 @@ public class MidnightControlsClient extends MidnightControls implements ClientMo
MidnightControlsConfig.controlsMode = this.previousControlsMode; MidnightControlsConfig.controlsMode = this.previousControlsMode;
} }
ClientPlayNetworking.getSender().sendPacket(new ControlsModePacket(MidnightControlsConfig.controlsMode.getName()));
} }
} }

View File

@@ -489,7 +489,7 @@ public class MidnightInput {
state = 1; state = 1;
asButtonState = 1; asButtonState = 1;
} }
if (MidnightControlsConfig.debug) System.out.println(axis + " "+ value + " " + absValue + " " + state); //if (MidnightControlsConfig.debug) System.out.println(axis + " "+ value + " " + absValue + " " + state);
} }
} }

View File

@@ -15,6 +15,7 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.FluidBlock; import net.minecraft.block.FluidBlock;
import net.minecraft.block.SlabBlock; import net.minecraft.block.SlabBlock;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
@@ -74,7 +75,7 @@ public class MidnightReacharound {
} }
public static float getPlayerRange(@NotNull MinecraftClient client) { public static float getPlayerRange(@NotNull MinecraftClient client) {
return client.interactionManager != null ? client.interactionManager.getReachDistance() : 0.f; return client.player != null ? Double.valueOf(client.player.getAttributeValue(EntityAttributes.PLAYER_BLOCK_INTERACTION_RANGE)).floatValue() : 0.f;
} }
/** /**

View File

@@ -151,25 +151,17 @@ public record Controller(int id) implements Nameable {
private static boolean updateMappingsSync() { private static boolean updateMappingsSync() {
try { try {
MidnightControlsClient.get().log("Updating controller mappings..."); MidnightControlsClient.get().log("Updating controller mappings...");
File databaseFile = new File("config/gamecontrollerdatabase.txt"); Optional<File> databaseFile = getDatabaseFile();
try { if (databaseFile.isPresent()) {
BufferedInputStream in = new BufferedInputStream(new URL("https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt").openStream()); var database = ioResourceToBuffer(databaseFile.get().getPath(), 1024);
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(databaseFile));
byte[] dataBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
out.write(dataBuffer, 0, bytesRead);
}
out.close();
} catch (Exception ignored) {/* Just continue when internet connection is not available */}
var database = ioResourceToBuffer(databaseFile.getPath(), 1024);
if (database != null) GLFW.glfwUpdateGamepadMappings(database); if (database != null) GLFW.glfwUpdateGamepadMappings(database);
}
if (!MidnightControlsClient.MAPPINGS_FILE.exists()) if (!MidnightControlsClient.MAPPINGS_FILE.exists())
return false; return false;
var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024); var buffer = ioResourceToBuffer(MidnightControlsClient.MAPPINGS_FILE.getPath(), 1024);
if (buffer != null) GLFW.glfwUpdateGamepadMappings(buffer); if (buffer != null) GLFW.glfwUpdateGamepadMappings(buffer);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.fillInStackTrace();
} }
try (var memoryStack = MemoryStack.stackPush()) { try (var memoryStack = MemoryStack.stackPush()) {
@@ -182,8 +174,8 @@ public record Controller(int id) implements Nameable {
if (client != null) { if (client != null) {
client.getToastManager().add(SystemToast.create(client, SystemToast.Type.PERIODIC_NOTIFICATION, client.getToastManager().add(SystemToast.create(client, SystemToast.Type.PERIODIC_NOTIFICATION,
Text.translatable("midnightcontrols.controller.mappings.error"), Text.literal(string))); Text.translatable("midnightcontrols.controller.mappings.error"), Text.literal(string)));
MidnightControls.get().log(I18n.translate("midnightcontrols.controller.mappings.error")+string);
} }
MidnightControls.get().log(I18n.translate("midnightcontrols.controller.mappings.error")+string);
} }
} catch (Throwable e) { } catch (Throwable e) {
/* Ignored :concern: */ /* Ignored :concern: */
@@ -205,4 +197,19 @@ public record Controller(int id) implements Nameable {
} }
return true; return true;
} }
private static Optional<File> getDatabaseFile() {
File databaseFile = new File("config/gamecontrollerdatabase.txt");
try {
BufferedInputStream in = new BufferedInputStream(new URL("https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt").openStream());
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(databaseFile));
byte[] dataBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
out.write(dataBuffer, 0, bytesRead);
}
out.close();
} catch (Exception e) {return Optional.empty();}
return Optional.of(databaseFile);
}
} }

View File

@@ -27,6 +27,7 @@ import dev.lambdaurora.spruceui.widget.SpruceLabelWidget;
import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget; import dev.lambdaurora.spruceui.widget.container.SpruceContainerWidget;
import dev.lambdaurora.spruceui.widget.container.SpruceOptionListWidget; import dev.lambdaurora.spruceui.widget.container.SpruceOptionListWidget;
import dev.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget; import dev.lambdaurora.spruceui.widget.container.tabbed.SpruceTabbedWidget;
import eu.midnightdust.midnightcontrols.packet.ControlsModePacket;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
@@ -92,6 +93,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
id = GLFW.GLFW_JOYSTICK_1; id = GLFW.GLFW_JOYSTICK_1;
id = searchNextAvailableController(id, false); id = searchNextAvailableController(id, false);
MidnightControlsConfig.setController(Controller.byId(id)); MidnightControlsConfig.setController(Controller.byId(id));
if (MidnightControlsConfig.debug) System.out.println(Controller.byId(id).getName() + "'s Controller GUID: " + Controller.byId(id).getGuid());
}, },
option -> { option -> {
var controller = MidnightControlsConfig.getController(); var controller = MidnightControlsConfig.getController();
@@ -182,7 +184,7 @@ public class MidnightControlsSettingsScreen extends SpruceScreen {
MidnightControlsConfig.save(); MidnightControlsConfig.save();
if (this.client != null && this.client.player != null) { if (this.client != null && this.client.player != null) {
ClientPlayNetworking.getSender().sendPacket(MidnightControls.CONTROLS_MODE_CHANNEL, this.mod.makeControlsModeBuffer(next)); ClientPlayNetworking.getSender().sendPacket(new ControlsModePacket(next.getName()));
} }
}, option -> option.getDisplayText(Text.translatable(MidnightControlsConfig.controlsMode.getTranslationKey())), }, option -> option.getDisplayText(Text.translatable(MidnightControlsConfig.controlsMode.getTranslationKey())),
Text.translatable("midnightcontrols.menu.controls_mode.tooltip")); Text.translatable("midnightcontrols.menu.controls_mode.tooltip"));

View File

@@ -86,6 +86,9 @@ public class TouchscreenOverlay extends Screen {
@Override @Override
public void renderInGameBackground(DrawContext context) {} public void renderInGameBackground(DrawContext context) {}
@Override
protected void applyBlur(float delta) {}
private void pauseGame() { private void pauseGame() {
assert this.client != null; assert this.client != null;
this.client.setScreen(new GameMenuScreen(true)); this.client.setScreen(new GameMenuScreen(true));

View File

@@ -10,14 +10,19 @@
package eu.midnightdust.midnightcontrols.client.mixin; package eu.midnightdust.midnightcontrols.client.mixin;
import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen; import eu.midnightdust.midnightcontrols.client.gui.MidnightControlsSettingsScreen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.option.ControlsOptionsScreen; import net.minecraft.client.gui.screen.option.ControlsOptionsScreen;
import net.minecraft.client.gui.screen.option.GameOptionsScreen; import net.minecraft.client.gui.screen.option.GameOptionsScreen;
import net.minecraft.client.gui.widget.OptionListWidget;
import net.minecraft.client.gui.widget.TextIconButtonWidget; import net.minecraft.client.gui.widget.TextIconButtonWidget;
import net.minecraft.client.option.GameOptions; import net.minecraft.client.option.GameOptions;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@@ -27,14 +32,29 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
*/ */
@Mixin(ControlsOptionsScreen.class) @Mixin(ControlsOptionsScreen.class)
public abstract class ControlsOptionsScreenMixin extends GameOptionsScreen { public abstract class ControlsOptionsScreenMixin extends GameOptionsScreen {
public ControlsOptionsScreenMixin(Screen parent, GameOptions gameOptions, Text text) {
super(parent, gameOptions, text); @Shadow @Nullable private OptionListWidget optionListWidget;
public ControlsOptionsScreenMixin(Screen parent, GameOptions gameOptions, Text title) {
super(parent, gameOptions, title);
} }
@Inject(method = "init", at = @At(value = "INVOKE", ordinal = 1, shift = At.Shift.AFTER, target = "Lnet/minecraft/client/gui/screen/option/ControlsOptionsScreen;addDrawableChild(Lnet/minecraft/client/gui/Element;)Lnet/minecraft/client/gui/Element;")) @Unique TextIconButtonWidget button = TextIconButtonWidget.builder(Text.translatable("midnightcontrols.menu.title.controller"), (button -> this.client.setScreen(new MidnightControlsSettingsScreen(this, false))), true)
private void addControllerButton(CallbackInfo ci) {
TextIconButtonWidget iconWidget = TextIconButtonWidget.builder(Text.translatable("midnightcontrols.menu.title.controller"), (button -> this.client.setScreen(new MidnightControlsSettingsScreen(this, false))), true)
.dimension(20,20).texture(new Identifier("midnightcontrols", "icon/controller"), 20, 20).build(); .dimension(20,20).texture(new Identifier("midnightcontrols", "icon/controller"), 20, 20).build();
iconWidget.setPosition(this.width / 2 + 158, this.height / 6 - 12);
this.addDrawableChild(iconWidget); @Inject(at = @At("TAIL"), method = "init")
public void midnightcontrols$onInit(CallbackInfo ci) {
this.midnightcontrols$setupButton();
this.addDrawableChild(button);
}
@Override
public void resize(MinecraftClient client, int width, int height) {
super.resize(client, width, height);
this.midnightcontrols$setupButton();
}
@Unique
public void midnightcontrols$setupButton() {
assert optionListWidget != null;
button.setPosition(optionListWidget.getWidth() / 2 + 158, optionListWidget.getY() + 4);
} }
} }

View File

@@ -9,6 +9,7 @@
package eu.midnightdust.midnightcontrols.client.mixin; package eu.midnightdust.midnightcontrols.client.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import eu.midnightdust.midnightcontrols.ControlsMode; import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
@@ -18,14 +19,13 @@ import eu.midnightdust.midnightcontrols.client.touch.TouchUtils;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.util.math.MatrixStack; import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(GameRenderer.class) @Mixin(GameRenderer.class)
public abstract class GameRendererMixin { public abstract class GameRendererMixin {
@@ -38,15 +38,16 @@ public abstract class GameRendererMixin {
if (this.client.currentScreen != null && MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) if (this.client.currentScreen != null && MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER)
MidnightControlsClient.get().input.onPreRenderScreen(this.client, this.client.currentScreen); MidnightControlsClient.get().input.onPreRenderScreen(this.client, this.client.currentScreen);
} }
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;draw()V", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILSOFT) @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;draw()V", shift = At.Shift.BEFORE))
private void renderVirtualCursor(float tickDelta, long startTime, boolean tick, CallbackInfo ci, boolean bl, MatrixStack matrixStack, DrawContext drawContext) { private void renderVirtualCursor(float tickDelta, long startTime, boolean tick, CallbackInfo ci, @Local DrawContext drawContext) {
MidnightControlsRenderer.renderVirtualCursor(drawContext, client); MidnightControlsRenderer.renderVirtualCursor(drawContext, client);
drawContext.draw(); drawContext.draw();
} }
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/GameRenderer;renderHand:Z", ordinal = 0), method = "renderWorld") @Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/GameRenderer;renderHand:Z"), method = "renderWorld")
private void postWorldRender(float tickDelta, long limitTime, MatrixStack matrix, CallbackInfo ci) { private void captureProjAndModMatrix(float tickDelta, long limitTime, CallbackInfo ci, @Local(ordinal = 1) Matrix4f matrices) {
TouchUtils.lastProjMat.set(RenderSystem.getProjectionMatrix()); TouchUtils.lastProjMat.set(RenderSystem.getProjectionMatrix());
TouchUtils.lastModMat.set(RenderSystem.getModelViewMatrix()); TouchUtils.lastModMat.set(RenderSystem.getModelViewMatrix());
TouchUtils.lastWorldSpaceMatrix.set(matrix.peek().getPositionMatrix()); TouchUtils.lastWorldSpaceMatrix.set(matrices);
} }
} }

View File

@@ -51,7 +51,7 @@ public abstract class MouseMixin implements MouseAccessor {
@Shadow private boolean hasResolutionChanged; @Shadow private boolean hasResolutionChanged;
@Shadow private double lastMouseUpdateTime; @Shadow private double glfwTime;
@Shadow @Final private SmoothUtil cursorXSmoother; @Shadow @Final private SmoothUtil cursorXSmoother;
@@ -123,8 +123,8 @@ public abstract class MouseMixin implements MouseAccessor {
|| ||
items.getItem() instanceof net.minecraft.item.ThrowablePotionItem; items.getItem() instanceof net.minecraft.item.ThrowablePotionItem;
EyeTrackerHandler.updateMouseWithEyeTracking(x + cursorDeltaX, y + cursorDeltaY, client, EyeTrackerHandler.updateMouseWithEyeTracking(x + cursorDeltaX, y + cursorDeltaY, client,
lastMouseUpdateTime, leftButtonClicked, isUsingLongRangedTool, cursorXSmoother, cursorYSmoother); glfwTime, leftButtonClicked, isUsingLongRangedTool, cursorXSmoother, cursorYSmoother);
lastMouseUpdateTime = GlfwUtil.getTime(); glfwTime = GlfwUtil.getTime();
cursorDeltaX = 0.0; cursorDeltaX = 0.0;
cursorDeltaY = 0.0; cursorDeltaY = 0.0;
ci.cancel(); ci.cancel();

View File

@@ -9,6 +9,7 @@
package eu.midnightdust.midnightcontrols.client.mixin; package eu.midnightdust.midnightcontrols.client.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import eu.midnightdust.lib.util.MidnightColorUtil; import eu.midnightdust.lib.util.MidnightColorUtil;
import eu.midnightdust.midnightcontrols.ControlsMode; import eu.midnightdust.midnightcontrols.ControlsMode;
import eu.midnightdust.midnightcontrols.client.MidnightControlsClient; import eu.midnightdust.midnightcontrols.client.MidnightControlsClient;
@@ -61,6 +62,7 @@ public abstract class WorldRendererMixin {
@Shadow @Shadow
private static void drawCuboidShapeOutline(MatrixStack matrices, VertexConsumer vertexConsumer, VoxelShape shape, double offsetX, double offsetY, double offsetZ, float red, float green, float blue, float alpha) { private static void drawCuboidShapeOutline(MatrixStack matrices, VertexConsumer vertexConsumer, VoxelShape shape, double offsetX, double offsetY, double offsetZ, float red, float green, float blue, float alpha) {
} }
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/hit/HitResult;getType()Lnet/minecraft/util/hit/HitResult$Type;")) @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/hit/HitResult;getType()Lnet/minecraft/util/hit/HitResult$Type;"))
private HitResult.Type dontRenderOutline(HitResult instance) { private HitResult.Type dontRenderOutline(HitResult instance) {
if (MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) { if (MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) {
@@ -78,8 +80,7 @@ public abstract class WorldRendererMixin {
shift = At.Shift.AFTER shift = At.Shift.AFTER
) )
) )
private void onOutlineRender(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, private void onOutlineRender(float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, Matrix4f matrix4f2, CallbackInfo ci, @Local MatrixStack matrices) {
LightmapTextureManager lightmapTextureManager, Matrix4f matrix4f, CallbackInfo ci) {
if (((MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.touchInControllerMode) || MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN) if (((MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && MidnightControlsConfig.touchInControllerMode) || MidnightControlsConfig.controlsMode == ControlsMode.TOUCHSCREEN)
&& MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) { && MidnightControlsConfig.touchMode == TouchMode.FINGER_POS) {
this.renderFingerOutline(matrices, camera); this.renderFingerOutline(matrices, camera);

View File

@@ -0,0 +1,33 @@
package eu.midnightdust.midnightcontrols.packet;
import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.client.MidnightControlsConfig;
import io.netty.buffer.Unpooled;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.CustomPayload;
import java.util.Objects;
import java.util.Optional;
public record ControlsModePacket(String controlsMode) implements CustomPayload {
public static final Id<ControlsModePacket> PACKET_ID = new Id<>(MidnightControlsConstants.CONTROLS_MODE_CHANNEL);
public static final PacketCodec<RegistryByteBuf, ControlsModePacket> codec = PacketCodec.of(ControlsModePacket::write, ControlsModePacket::read);
public static ControlsModePacket read(RegistryByteBuf buf) {
return new ControlsModePacket(buf.readString(32));
}
public void write(RegistryByteBuf buf) {
Objects.requireNonNull(controlsMode, "Controls mode cannot be null.");
buf.writeString(controlsMode, 32);
}
@Override
public Id<? extends CustomPayload> getId() {
return PACKET_ID;
}
}

View File

@@ -0,0 +1,43 @@
package eu.midnightdust.midnightcontrols.packet;
import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import eu.midnightdust.midnightcontrols.MidnightControlsFeature;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.CustomPayload;
public record FeaturePacket(MidnightControlsFeature... features) implements CustomPayload {
public static final Id<FeaturePacket> PACKET_ID = new Id<>(MidnightControlsConstants.FEATURE_CHANNEL);
public static final PacketCodec<RegistryByteBuf, FeaturePacket> codec = PacketCodec.of(FeaturePacket::write, FeaturePacket::read);
public static FeaturePacket read(RegistryByteBuf buf) {
int featureLength = buf.readVarInt();
MidnightControlsFeature[] receivedFeatures = new MidnightControlsFeature[featureLength];
for (int i = 0; i < featureLength; i++) {
var name = buf.readString(64);
boolean allowed = buf.readBoolean();
var feature = MidnightControlsFeature.fromName(name);
if (feature.isPresent()) {
feature.get().setAllowed(allowed);
receivedFeatures[i] = feature.get();
}
}
return new FeaturePacket(receivedFeatures);
}
public void write(RegistryByteBuf buf) {
if (features.length == 0)
throw new IllegalArgumentException("At least one feature must be provided.");
buf.writeVarInt(features.length);
for (var feature : features) {
buf.writeString(feature.getName(), 64);
buf.writeBoolean(feature.isAllowed());
}
}
@Override
public Id<? extends CustomPayload> getId() {
return PACKET_ID;
}
}

View File

@@ -0,0 +1,24 @@
package eu.midnightdust.midnightcontrols.packet;
import eu.midnightdust.midnightcontrols.MidnightControlsConstants;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.CustomPayload;
public record HelloPacket(String version, String controlsMode) implements CustomPayload {
public static final CustomPayload.Id<HelloPacket> PACKET_ID = new CustomPayload.Id<>(MidnightControlsConstants.HELLO_CHANNEL);
public static final PacketCodec<RegistryByteBuf, HelloPacket> codec = PacketCodec.of(HelloPacket::write, HelloPacket::read);
public static HelloPacket read(RegistryByteBuf buf) {
return new HelloPacket(buf.readString(32), buf.readString(32));
}
public void write(RegistryByteBuf buf) {
buf.writeString(version, 32).writeString(controlsMode, 32);
}
@Override
public Id<? extends CustomPayload> getId() {
return PACKET_ID;
}
}