diff --git a/gradle.properties b/gradle.properties
index 36e0fa8..792d814 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -3,17 +3,17 @@ org.gradle.jvmargs=-Xmx2G
# Fabric Properties
# check these on https://fabricmc.net/use
-minecraft_version=1.21
-yarn_mappings=1.21+build.9
-loader_version=0.15.11
-fabric_version=0.100.7+1.21
+minecraft_version=1.21.4
+yarn_mappings=1.21.4+build.2
+loader_version=0.16.9
+fabric_version=0.112.2+1.21.4
# Other Dependencies
jb_annotations_version = 23.0.0
apiguardian_version = 1.1.2
# Mod Properties
-mod_version = 3.2.1
+mod_version = 3.3.0
maven_group = org.ladysnake
archives_base_name = impersonate
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 09206a3..b1d008c 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,5 +1,5 @@
[versions]
-cca = "6.1.1"
+cca = "6.1.2"
fpa = "0.2-SNAPSHOT"
elmendorf = "0.13.0"
diff --git a/src/main/java/org/ladysnake/impersonate/impl/ImpersonateCommandOutput.java b/src/main/java/org/ladysnake/impersonate/impl/ImpersonateCommandOutput.java
new file mode 100644
index 0000000..b9b162e
--- /dev/null
+++ b/src/main/java/org/ladysnake/impersonate/impl/ImpersonateCommandOutput.java
@@ -0,0 +1,7 @@
+package org.ladysnake.impersonate.impl;
+
+import net.minecraft.server.command.CommandOutput;
+
+public interface ImpersonateCommandOutput extends CommandOutput {
+ boolean impersonate$shouldRevealName();
+}
diff --git a/src/main/java/org/ladysnake/impersonate/impl/ImpersonateTextContent.java b/src/main/java/org/ladysnake/impersonate/impl/ImpersonateTextContent.java
index 4e4e7cd..24a7bc5 100644
--- a/src/main/java/org/ladysnake/impersonate/impl/ImpersonateTextContent.java
+++ b/src/main/java/org/ladysnake/impersonate/impl/ImpersonateTextContent.java
@@ -26,11 +26,7 @@
import net.minecraft.server.command.CommandOutput;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
-import net.minecraft.text.MutableText;
-import net.minecraft.text.StringVisitable;
-import net.minecraft.text.Style;
-import net.minecraft.text.Text;
-import net.minecraft.text.TextContent;
+import net.minecraft.text.*;
import org.jetbrains.annotations.Nullable;
import org.ladysnake.impersonate.Impersonator;
@@ -66,7 +62,7 @@ private ImpersonateTextContent(String trueText, String fakedText, boolean reveal
@Override
public void impersonateResolve(CommandOutput recipient) {
- revealed = !(recipient instanceof PlayerEntity player) || shouldBeRevealedBy(player);
+ revealed = !(recipient instanceof ImpersonateCommandOutput impersonateOutput) || impersonateOutput.impersonate$shouldRevealName();
}
public boolean isRevealed() {
@@ -74,9 +70,9 @@ public boolean isRevealed() {
}
public static boolean shouldBeRevealedBy(PlayerEntity player) {
- return player instanceof ServerPlayerEntity
- && player.getWorld().getGameRules().getBoolean(ImpersonateGamerules.OP_REVEAL_IMPERSONATIONS)
- && ((ServerPlayerEntity) player).server.getPlayerManager().isOperator(player.getGameProfile());
+ return player instanceof ServerPlayerEntity serverPlayer
+ && serverPlayer.getServerWorld().getGameRules().getBoolean(ImpersonateGamerules.OP_REVEAL_IMPERSONATIONS)
+ && serverPlayer.server.getPlayerManager().isOperator(player.getGameProfile());
}
@Override
diff --git a/src/main/java/org/ladysnake/impersonate/impl/PacketMeddling.java b/src/main/java/org/ladysnake/impersonate/impl/PacketMeddling.java
index c466413..4620542 100644
--- a/src/main/java/org/ladysnake/impersonate/impl/PacketMeddling.java
+++ b/src/main/java/org/ladysnake/impersonate/impl/PacketMeddling.java
@@ -17,28 +17,24 @@
*/
package org.ladysnake.impersonate.impl;
-import io.netty.buffer.ByteBuf;
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs;
import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.network.codec.PacketCodec;
-import net.minecraft.network.codec.PacketCodecs;
import net.minecraft.network.message.MessageType;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.s2c.play.ChatMessageS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
import net.minecraft.registry.DynamicRegistryManager;
+import net.minecraft.server.command.CommandOutput;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;
-import org.ladysnake.impersonate.Impersonate;
import org.ladysnake.impersonate.Impersonator;
import org.ladysnake.impersonate.impl.mixin.PlayerListS2CPacketEntryAccessor;
import java.util.Optional;
-import java.util.function.Function;
public final class PacketMeddling {
@@ -72,12 +68,14 @@ public static
> P copyPacket(P packet, PacketCodec super R
}
public static ChatMessageS2CPacket resolveChatMessage(ChatMessageS2CPacket chatPacket, ServerPlayerEntity player) {
- @Nullable Text unsignedContent = Optional.ofNullable(chatPacket.unsignedContent()).map(t -> ((RecipientAwareText) t).impersonateResolveAll(player)).orElse(null);
- Text name = ((RecipientAwareText) chatPacket.serializedParameters().name()).impersonateResolveAll(player);
+ CommandOutput commandOutput = player.getCommandOutput();
+ @Nullable Text unsignedContent = Optional.ofNullable(chatPacket.unsignedContent()).map(t -> ((RecipientAwareText) t).impersonateResolveAll(commandOutput)).orElse(null);
+ Text name = ((RecipientAwareText) chatPacket.serializedParameters().name()).impersonateResolveAll(commandOutput);
Optional targetName = chatPacket.serializedParameters().targetName().map(text -> text instanceof RecipientAwareText t
- ? t.impersonateResolveAll(player)
+ ? t.impersonateResolveAll(commandOutput)
: null);
+
// God, I wish we had a Record#copy method in this language
// And yes we need to do a deep copy at the end, to avoid sharing text references
return copyPacket(new ChatMessageS2CPacket(
diff --git a/src/main/java/org/ladysnake/impersonate/impl/PlayerImpersonator.java b/src/main/java/org/ladysnake/impersonate/impl/PlayerImpersonator.java
index 44d831b..edcf25e 100644
--- a/src/main/java/org/ladysnake/impersonate/impl/PlayerImpersonator.java
+++ b/src/main/java/org/ladysnake/impersonate/impl/PlayerImpersonator.java
@@ -120,7 +120,7 @@ public void syncChanges(@Nullable GameProfile profile) {
}
private void applyCapeGamerule(ServerPlayerEntity player, GameProfile impersonatedProfile) {
- if (!player.getWorld().getGameRules().getBoolean(ImpersonateGamerules.FAKE_CAPES)) {
+ if (!player.getServerWorld().getGameRules().getBoolean(ImpersonateGamerules.FAKE_CAPES)) {
if (impersonatedProfile == null) {
((PlayerEntityExtensions) player).impersonate_resetCape();
} else {
diff --git a/src/main/java/org/ladysnake/impersonate/impl/ServerPlayerSkins.java b/src/main/java/org/ladysnake/impersonate/impl/ServerPlayerSkins.java
index b360e0d..4513544 100644
--- a/src/main/java/org/ladysnake/impersonate/impl/ServerPlayerSkins.java
+++ b/src/main/java/org/ladysnake/impersonate/impl/ServerPlayerSkins.java
@@ -28,14 +28,7 @@
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.entity.Entity;
import net.minecraft.entity.effect.StatusEffectInstance;
-import net.minecraft.network.packet.s2c.play.CommonPlayerSpawnInfo;
-import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket;
-import net.minecraft.network.packet.s2c.play.EntityStatusEffectS2CPacket;
-import net.minecraft.network.packet.s2c.play.ExperienceBarUpdateS2CPacket;
-import net.minecraft.network.packet.s2c.play.HealthUpdateS2CPacket;
-import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
-import net.minecraft.network.packet.s2c.play.PlayerRemoveS2CPacket;
-import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket;
+import net.minecraft.network.packet.s2c.play.*;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerChunkLoadingManager;
import net.minecraft.server.world.ServerChunkManager;
@@ -172,7 +165,8 @@ private static void reloadSkinVanilla(ServerPlayerEntity player) {
targetWorld.isDebugWorld(),
targetWorld.isFlat(),
player.getLastDeathPos(),
- player.getPortalCooldown()
+ player.getPortalCooldown(),
+ targetWorld.getSeaLevel()
),
PlayerRespawnS2CPacket.KEEP_ATTRIBUTES
));
diff --git a/src/main/java/org/ladysnake/impersonate/impl/mixin/ServerCommonNetworkHandlerMixin.java b/src/main/java/org/ladysnake/impersonate/impl/mixin/ServerCommonNetworkHandlerMixin.java
index 7542744..3ad17f9 100644
--- a/src/main/java/org/ladysnake/impersonate/impl/mixin/ServerCommonNetworkHandlerMixin.java
+++ b/src/main/java/org/ladysnake/impersonate/impl/mixin/ServerCommonNetworkHandlerMixin.java
@@ -52,7 +52,7 @@ private Packet> resolveFakeTextsInPackets(Packet> packet) {
}
} else if (packet instanceof GameMessageS2CPacket gamePacket) {
if (this.existsImpersonator()) {
- Text resolvedText = ((RecipientAwareText) gamePacket.content()).impersonateResolveAll(player);
+ Text resolvedText = ((RecipientAwareText) gamePacket.content()).impersonateResolveAll(player.getCommandOutput());
return new GameMessageS2CPacket(resolvedText, gamePacket.overlay());
}
} else if (packet instanceof PlayerListS2CPacket listPacket) {
diff --git a/src/main/java/org/ladysnake/impersonate/impl/mixin/ServerPlayerEntity$CommandOutput.java b/src/main/java/org/ladysnake/impersonate/impl/mixin/ServerPlayerEntity$CommandOutput.java
new file mode 100644
index 0000000..48a70a5
--- /dev/null
+++ b/src/main/java/org/ladysnake/impersonate/impl/mixin/ServerPlayerEntity$CommandOutput.java
@@ -0,0 +1,20 @@
+package org.ladysnake.impersonate.impl.mixin;
+
+import net.minecraft.server.network.ServerPlayerEntity;
+import org.ladysnake.impersonate.impl.ImpersonateCommandOutput;
+import org.ladysnake.impersonate.impl.ImpersonateTextContent;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+
+@Mixin(targets = "net.minecraft.server.network.ServerPlayerEntity$3")
+public abstract class ServerPlayerEntity$CommandOutput implements ImpersonateCommandOutput {
+ @Shadow
+ @Final
+ ServerPlayerEntity field_54403;
+
+ @Override
+ public boolean impersonate$shouldRevealName() {
+ return ImpersonateTextContent.shouldBeRevealedBy(this.field_54403);
+ }
+}
diff --git a/src/main/java/org/ladysnake/impersonate/impl/mixin/ServerPlayerEntityMixin.java b/src/main/java/org/ladysnake/impersonate/impl/mixin/ServerPlayerEntityMixin.java
index 8752004..98a7054 100644
--- a/src/main/java/org/ladysnake/impersonate/impl/mixin/ServerPlayerEntityMixin.java
+++ b/src/main/java/org/ladysnake/impersonate/impl/mixin/ServerPlayerEntityMixin.java
@@ -21,12 +21,14 @@
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.packet.c2s.common.SyncedClientOptions;
import net.minecraft.server.network.ServerPlayerEntity;
+import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.ladysnake.impersonate.Impersonator;
import org.ladysnake.impersonate.impl.ImpersonateGamerules;
import org.ladysnake.impersonate.impl.PlayerEntityExtensions;
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;
@@ -34,13 +36,16 @@
@Mixin(ServerPlayerEntity.class)
public abstract class ServerPlayerEntityMixin extends PlayerEntity implements PlayerEntityExtensions {
+ @Shadow
+ public abstract ServerWorld getServerWorld();
+
public ServerPlayerEntityMixin(World world, BlockPos pos, float yaw, GameProfile profile) {
super(world, pos, yaw, profile);
}
@Inject(method = "setClientOptions", at = @At("RETURN"))
private void removeCapeIfDisallowed(SyncedClientOptions clientOptions, CallbackInfo ci) {
- if (Impersonator.get(this).isImpersonating() && !this.getWorld().getGameRules().getBoolean(ImpersonateGamerules.FAKE_CAPES)) {
+ if (Impersonator.get(this).isImpersonating() && !this.getServerWorld().getGameRules().getBoolean(ImpersonateGamerules.FAKE_CAPES)) {
this.impersonate_disableCape();
}
}
diff --git a/src/main/resources/mixins.impersonate.common.json b/src/main/resources/mixins.impersonate.common.json
index 187e5d8..49f5135 100644
--- a/src/main/resources/mixins.impersonate.common.json
+++ b/src/main/resources/mixins.impersonate.common.json
@@ -13,10 +13,11 @@
"PlayerListS2CPacketEntryAccessor",
"PlayerListS2CPacketEntryMixin",
"PlayerManagerMixin",
+ "ServerChunkLoadingManagerAccessor",
"ServerCommonNetworkHandlerMixin",
+ "ServerPlayerEntity$CommandOutput",
"ServerPlayerEntityMixin",
"TextMixin",
- "ServerChunkLoadingManagerAccessor",
"TranslatableTextContentMixin"
],
"injectors": {
diff --git a/src/testmod/java/org/ladysnake/impersonatest/ImpersonItem.java b/src/testmod/java/org/ladysnake/impersonatest/ImpersonItem.java
index 4989cde..b1c90ff 100644
--- a/src/testmod/java/org/ladysnake/impersonatest/ImpersonItem.java
+++ b/src/testmod/java/org/ladysnake/impersonatest/ImpersonItem.java
@@ -25,7 +25,6 @@
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
-import net.minecraft.util.TypedActionResult;
import net.minecraft.world.World;
import org.ladysnake.impersonate.Impersonator;
@@ -37,9 +36,9 @@ public ImpersonItem(Settings settings) {
}
@Override
- public TypedActionResult use(World world, PlayerEntity user, Hand hand) {
+ public ActionResult use(World world, PlayerEntity user, Hand hand) {
if (Impersonator.get(user).stopImpersonation(IMPERSONATION_KEY) != null) {
- return TypedActionResult.success(user.getStackInHand(hand));
+ return ActionResult.SUCCESS;
}
return super.use(world, user, hand);
}
diff --git a/src/testmod/java/org/ladysnake/impersonatest/Impersonatest.java b/src/testmod/java/org/ladysnake/impersonatest/Impersonatest.java
index 624abb7..33c521e 100644
--- a/src/testmod/java/org/ladysnake/impersonatest/Impersonatest.java
+++ b/src/testmod/java/org/ladysnake/impersonatest/Impersonatest.java
@@ -21,6 +21,8 @@
import net.minecraft.item.Item;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
+import net.minecraft.registry.RegistryKey;
+import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
public final class Impersonatest implements ModInitializer {
@@ -31,7 +33,8 @@ public static Identifier id(String path) {
@Override
public void onInitialize() {
- Registry.register(Registries.ITEM, id("impersonitem"), new ImpersonItem(new Item.Settings()));
+ Identifier impersonitemId = id("impersonitem");
+ Registry.register(Registries.ITEM, impersonitemId, new ImpersonItem(new Item.Settings().registryKey(RegistryKey.of(RegistryKeys.ITEM, impersonitemId))));
}
}