diff --git a/mod/src/main/java/zsawyer/mods/mumblelink/mumble/UpdateData.java b/mod/src/main/java/zsawyer/mods/mumblelink/mumble/UpdateData.java index d5c422b..0d1f3cb 100644 --- a/mod/src/main/java/zsawyer/mods/mumblelink/mumble/UpdateData.java +++ b/mod/src/main/java/zsawyer/mods/mumblelink/mumble/UpdateData.java @@ -22,6 +22,8 @@ package zsawyer.mods.mumblelink.mumble; import net.minecraft.client.Minecraft; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import zsawyer.mods.mumblelink.MumbleLinkImpl; import zsawyer.mods.mumblelink.api.IdentityManipulator; @@ -36,6 +38,8 @@ * @author zsawyer */ public class UpdateData { + private static final int HEIGHT_INDEX = 1; + float[] fAvatarPosition = {0, 0, 0}; // [3] float[] fAvatarFront = {0, 0, 0}; // [3] @@ -135,6 +139,7 @@ public void set(Minecraft game) { (float) game.player.getPosition(1f).y() * fAvatarPositionY, (float) game.player.getPosition(1f).z() * fAvatarPositionZ }; + applyDimensionalOffset(game, fAvatarPosition); // Unit vector pointing out of the avatar's eyes (here Front looks // into scene). @@ -159,6 +164,7 @@ public void set(Minecraft game) { (float) game.player.getPosition(1f).y() * fCameraPositionY, (float) game.player.getPosition(1f).z() * fCameraPositionZ }; + applyDimensionalOffset(game, fCameraPosition); fCameraFront = new float[]{ (float) lookDirection.x * fCameraFrontX, @@ -211,4 +217,27 @@ protected String generateContext(Minecraft game, int maxLength) { private Vec3 getTopVec(Minecraft game) { return game.player.getUpVector(1f); } + + + /** + * Make people in other dimensions far away so that they're muted. + *

+ * reimplementation of https://github.com/magneticflux-/fabric-mumblelink-mod/blob/12727324ae9ecfc9c6b0ab5b604e824d43cfffa1/src/main/kotlin/com/skaggsm/mumblelinkmod/client/ClientMumbleLinkMod.kt#L136 + * + * @param game the source to get live data from + * @param originalPosition the original position to be offset + */ + public static void applyDimensionalOffset(Minecraft game, float[] originalPosition) { + ResourceKey dimension = game.player.level.dimension(); + if (dimension == null) { + // silently ignoring because it would become too spammy + return; + } + + int configuredOffset = MumbleLinkImpl.dimensionalHeight(); + int hash = LinkAPIHelper.stableHash(dimension.toString()); + float heightOffset = (hash % 2048) * configuredOffset; + + originalPosition[HEIGHT_INDEX] += heightOffset; + } } diff --git a/mod/src/main/java/zsawyer/mods/mumblelink/mumble/jna/LinkAPIHelper.java b/mod/src/main/java/zsawyer/mods/mumblelink/mumble/jna/LinkAPIHelper.java index 716e976..7162653 100644 --- a/mod/src/main/java/zsawyer/mods/mumblelink/mumble/jna/LinkAPIHelper.java +++ b/mod/src/main/java/zsawyer/mods/mumblelink/mumble/jna/LinkAPIHelper.java @@ -27,6 +27,7 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; +import java.util.PrimitiveIterator; /** * @author zsawyer @@ -54,6 +55,28 @@ public static ByteBuffer parseToByteBuffer(int capacity, String value) { return buffer; } + /** + * A stable hash function designed for world IDs. + * Different clients should be able to run this on the same world ID and get the same result. + *

+ * Based on the `djb2` hash function: [Hash Functions](http://www.cse.yorku.ca/~oz/hash.html) + *

+ * reimplementation of https://github.com/magneticflux-/fabric-mumblelink-mod/blob/3866317c64f9b7f5b9b4f17e88cd51c0a717b993/src/main/kotlin/com/skaggsm/mumblelinkmod/client/Utils.kt#L21 + * + * @param hashingTarget the strings whose character sequence should be hashed + * @return the stable hash built for the given input + */ + public static int stableHash(String hashingTarget) { + int hash = 5381; + PrimitiveIterator.OfInt characterIterator = hashingTarget.chars().iterator(); + + while (characterIterator.hasNext()) { + hash += (hash << 5) + characterIterator.nextInt(); + } + + return hash; + } + public synchronized LinkAPILibrary getLibraryInstance() { return libraryInstance; }