Make fake players compatible with adventure platform lib and minor refactor around them (#1235)

* Make fake players compatible with adventure platform and minor refactor around them

Cleaner approach

* Remove no longer needed enderpearl mixin for fake players

Their ClientConnection now has an open channel so isOpen returns true
This commit is contained in:
altrisi authored and GitHub committed 2022-01-19 21:28:36 +01:00
1 parent c0bba54799
commit ec47dea267
9 files changed
+49 -93

No files matched your search

@@ -0,0 +1,7 @@
package carpet.fakes;
import io.netty.channel.Channel;
public interface ClientConnectionInterface {
void setChannel(Channel channel);
}
@@ -1,18 +1,21 @@
package carpet.mixins;
import carpet.fakes.ClientConnectionInterface;
import carpet.logging.logHelpers.PacketCounter;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.Packet;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientConnection.class)
public abstract class ClientConnectionMixin
public abstract class ClientConnectionMixin implements ClientConnectionInterface
{
// Add to the packet counter whenever a packet is received.
@Inject(method = "channelRead0", at = @At("HEAD"))
@@ -28,4 +31,8 @@ public abstract class ClientConnectionMixin
{
PacketCounter.totalOut++;
}
@Override
@Accessor //Compat with adventure-platform-fabric
public abstract void setChannel(Channel channel);
}
@@ -1,9 +1,7 @@
package carpet.mixins;
import com.mojang.authlib.GameProfile;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.ClientConnection;
import net.minecraft.text.TranslatableText;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.network.ServerPlayNetworkHandler;
@@ -15,14 +13,9 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import carpet.patches.NetHandlerPlayServerFake;
import carpet.patches.EntityPlayerMPFake;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
@Mixin(PlayerManager.class)
public abstract class PlayerManager_fakePlayersMixin
{
@@ -42,38 +35,13 @@ public abstract class PlayerManager_fakePlayersMixin
@Redirect(method = "onPlayerConnect", at = @At(value = "NEW", target = "net/minecraft/server/network/ServerPlayNetworkHandler"))
private ServerPlayNetworkHandler replaceNetworkHandler(MinecraftServer server, ClientConnection clientConnection, ServerPlayerEntity playerIn)
{
boolean isServerPlayerEntity = playerIn instanceof EntityPlayerMPFake;
if (isServerPlayerEntity)
if (playerIn instanceof EntityPlayerMPFake fake)
{
return new NetHandlerPlayServerFake(this.server, clientConnection, playerIn);
return new NetHandlerPlayServerFake(this.server, clientConnection, fake);
}
else
{
return new ServerPlayNetworkHandler(this.server, clientConnection, playerIn);
}
}
@Redirect(method = "createPlayer", at = @At(value = "INVOKE", target = "Ljava/util/Iterator;hasNext()Z"))
private boolean cancelWhileLoop(Iterator iterator)
{
return false;
}
@Inject(method = "createPlayer", at = @At(value = "INVOKE", shift = At.Shift.BEFORE,
target = "Ljava/util/Iterator;hasNext()Z"), locals = LocalCapture.CAPTURE_FAILHARD)
private void newWhileLoop(GameProfile gameProfile_1, CallbackInfoReturnable<ServerPlayerEntity> cir, UUID uUID_1,
List list_1, ServerPlayerEntity serverPlayerEntity, Iterator var5)
{
while (var5.hasNext())
{
ServerPlayerEntity serverPlayerEntity_3 = (ServerPlayerEntity) var5.next();
if(serverPlayerEntity_3 instanceof EntityPlayerMPFake)
{
((EntityPlayerMPFake)serverPlayerEntity_3).kill(new TranslatableText("multiplayer.disconnect.duplicate_login"));
continue;
}
serverPlayerEntity_3.networkHandler.disconnect(new TranslatableText("multiplayer.disconnect.duplicate_login"));
}
}
}
@@ -1,29 +0,0 @@
package carpet.mixins;
import carpet.patches.EntityPlayerMPFake;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.projectile.thrown.EnderPearlEntity;
import net.minecraft.entity.projectile.thrown.ThrownItemEntity;
import net.minecraft.network.ClientConnection;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(EnderPearlEntity.class)
public abstract class ThrownEnderpearlEntity_fakePlayersMixin extends ThrownItemEntity
{
public ThrownEnderpearlEntity_fakePlayersMixin(EntityType<? extends ThrownItemEntity> entityType_1, World world_1)
{
super(entityType_1, world_1);
}
@Redirect(method = "onCollision", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/network/ClientConnection;isOpen()Z"
))
private boolean isConnectionGood(ClientConnection clientConnection)
{
return clientConnection.isOpen() || getOwner() instanceof EntityPlayerMPFake;
}
}
@@ -62,7 +62,7 @@ public class EntityPlayerMPFake extends ServerPlayerEntity
}
EntityPlayerMPFake instance = new EntityPlayerMPFake(server, worldIn, gameprofile, false);
instance.fixStartingPosition = () -> instance.refreshPositionAndAngles(d0, d1, d2, (float) yaw, (float) pitch);
server.getPlayerManager().onPlayerConnect(new NetworkManagerFake(NetworkSide.SERVERBOUND), instance);
server.getPlayerManager().onPlayerConnect(new FakeClientConnection(NetworkSide.SERVERBOUND), instance);
instance.teleport(worldIn, d0, d1, d2, (float)yaw, (float)pitch);
instance.setHealth(20.0F);
instance.unsetRemoved();
@@ -83,7 +83,7 @@ public class EntityPlayerMPFake extends ServerPlayerEntity
ServerWorld worldIn = player.getServerWorld();//.getWorld(player.dimension);
GameProfile gameprofile = player.getGameProfile();
EntityPlayerMPFake playerShadow = new EntityPlayerMPFake(server, worldIn, gameprofile, true);
server.getPlayerManager().onPlayerConnect(new NetworkManagerFake(NetworkSide.SERVERBOUND), playerShadow);
server.getPlayerManager().onPlayerConnect(new FakeClientConnection(NetworkSide.SERVERBOUND), playerShadow);
playerShadow.setHealth(player.getHealth());
playerShadow.networkHandler.requestTeleport(player.getX(), player.getY(), player.getZ(), player.getYaw(), player.getPitch());
@@ -0,0 +1,27 @@
package carpet.patches;
import carpet.fakes.ClientConnectionInterface;
import io.netty.channel.embedded.EmbeddedChannel;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.NetworkSide;
public class FakeClientConnection extends ClientConnection
{
public FakeClientConnection(NetworkSide p)
{
super(p);
// compat with adventure-platform-fabric. This does NOT trigger other vanilla handlers for establishing a channel
// also makes #isOpen return true, allowing enderpearls to teleport fake players
((ClientConnectionInterface)this).setChannel(new EmbeddedChannel());
}
@Override
public void disableAutoRead()
{
}
@Override
public void handleDisconnection()
{
}
}
@@ -4,13 +4,12 @@ import net.minecraft.network.ClientConnection;
import net.minecraft.network.Packet;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
public class NetHandlerPlayServerFake extends ServerPlayNetworkHandler
{
public NetHandlerPlayServerFake(MinecraftServer server, ClientConnection cc, ServerPlayerEntity playerIn)
public NetHandlerPlayServerFake(MinecraftServer server, ClientConnection cc, EntityPlayerMPFake playerIn)
{
super(server, cc, playerIn);
}
@@ -23,9 +22,9 @@ public class NetHandlerPlayServerFake extends ServerPlayNetworkHandler
@Override
public void disconnect(Text message)
{
if (player instanceof EntityPlayerMPFake && message instanceof TranslatableText && ((TranslatableText) message).getKey().equals("multiplayer.disconnect.idling"))
if (message instanceof TranslatableText text && (text.getKey().equals("multiplayer.disconnect.idling") || text.getKey().equals("multiplayer.disconnect.duplicate_login")))
{
((EntityPlayerMPFake) player).kill(new TranslatableText(((TranslatableText) message).getKey()));
((EntityPlayerMPFake) player).kill(message);
}
}
}
@@ -1,22 +0,0 @@
package carpet.patches;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.NetworkSide;
public class NetworkManagerFake extends ClientConnection
{
public NetworkManagerFake(NetworkSide p)
{
super(p);
}
@Override
public void disableAutoRead()
{
}
@Override
public void handleDisconnection()
{
}
}
-1
View File
@@ -68,7 +68,6 @@
"VillagerEntity_aiMixin",
"PlayerEntity_fakePlayersMixin",
"ThrownEnderpearlEntity_fakePlayersMixin",
"ServerPlayNetworkHandler_coreMixin",