* Clean up code in PlayerCommand.spawn and EntityPlayerMPFake.createFake. * Update src/main/java/carpet/CarpetSettings.java * Update src/main/java/carpet/commands/PlayerCommand.java * Update src/main/java/carpet/patches/EntityPlayerMPFake.java Co-authored-by: gnembon <41132274+gnembon@users.noreply.github.com>
164 lines
6.9 KiB
Java
164 lines
6.9 KiB
Java
package carpet.patches;
|
|
|
|
import carpet.CarpetSettings;
|
|
import com.mojang.authlib.GameProfile;
|
|
import net.minecraft.block.entity.SkullBlockEntity;
|
|
import net.minecraft.entity.Entity;
|
|
import net.minecraft.entity.player.PlayerEntity;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.network.packet.s2c.play.EntityPositionS2CPacket;
|
|
import net.minecraft.network.packet.s2c.play.EntitySetHeadYawS2CPacket;
|
|
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
|
|
import net.minecraft.entity.damage.DamageSource;
|
|
import net.minecraft.entity.player.HungerManager;
|
|
import net.minecraft.network.NetworkSide;
|
|
import net.minecraft.text.Text;
|
|
import net.minecraft.text.TranslatableText;
|
|
import net.minecraft.server.MinecraftServer;
|
|
import net.minecraft.server.ServerTask;
|
|
import net.minecraft.server.network.ServerPlayerEntity;
|
|
import net.minecraft.server.network.ServerPlayerInteractionManager;
|
|
import net.minecraft.server.world.ServerWorld;
|
|
import net.minecraft.util.UserCache;
|
|
import net.minecraft.util.registry.RegistryKey;
|
|
import net.minecraft.world.GameMode;
|
|
import net.minecraft.world.World;
|
|
import carpet.fakes.ServerPlayerEntityInterface;
|
|
import carpet.utils.Messenger;
|
|
|
|
@SuppressWarnings("EntityConstructor")
|
|
public class EntityPlayerMPFake extends ServerPlayerEntity
|
|
{
|
|
public Runnable fixStartingPosition = () -> {};
|
|
public boolean isAShadow;
|
|
|
|
public static EntityPlayerMPFake createFake(String username, MinecraftServer server, double d0, double d1, double d2, double yaw, double pitch, RegistryKey<World> dimensionId, GameMode gamemode)
|
|
{
|
|
//prolly half of that crap is not necessary, but it works
|
|
ServerWorld worldIn = server.getWorld(dimensionId);
|
|
ServerPlayerInteractionManager interactionManagerIn = new ServerPlayerInteractionManager(worldIn);
|
|
UserCache.setUseRemote(false);
|
|
GameProfile gameprofile;
|
|
try {
|
|
gameprofile = server.getUserCache().findByName(username);
|
|
}
|
|
finally {
|
|
UserCache.setUseRemote(server.isDedicated() && server.isOnlineMode());
|
|
}
|
|
if (gameprofile == null)
|
|
{
|
|
if (!CarpetSettings.allowSpawningOfflinePlayers)
|
|
{
|
|
return null;
|
|
} else {
|
|
gameprofile = new GameProfile(PlayerEntity.getOfflinePlayerUuid(username), username);
|
|
}
|
|
}
|
|
if (gameprofile.getProperties().containsKey("textures"))
|
|
{
|
|
gameprofile = SkullBlockEntity.loadProperties(gameprofile);
|
|
}
|
|
EntityPlayerMPFake instance = new EntityPlayerMPFake(server, worldIn, gameprofile, interactionManagerIn, false);
|
|
instance.fixStartingPosition = () -> instance.refreshPositionAndAngles(d0, d1, d2, (float) yaw, (float) pitch);
|
|
server.getPlayerManager().onPlayerConnect(new NetworkManagerFake(NetworkSide.SERVERBOUND), instance);
|
|
instance.teleport(worldIn, d0, d1, d2, (float)yaw, (float)pitch);
|
|
instance.setHealth(20.0F);
|
|
instance.removed = false;
|
|
instance.stepHeight = 0.6F;
|
|
interactionManagerIn.setGameMode(gamemode);
|
|
server.getPlayerManager().sendToDimension(new EntitySetHeadYawS2CPacket(instance, (byte) (instance.headYaw * 256 / 360)), dimensionId);//instance.dimension);
|
|
server.getPlayerManager().sendToDimension(new EntityPositionS2CPacket(instance), dimensionId);//instance.dimension);
|
|
instance.getServerWorld().getChunkManager().updateCameraPosition(instance);
|
|
instance.dataTracker.set(PLAYER_MODEL_PARTS, (byte) 0x7f); // show all model layers (incl. capes)
|
|
return instance;
|
|
}
|
|
|
|
public static EntityPlayerMPFake createShadow(MinecraftServer server, ServerPlayerEntity player)
|
|
{
|
|
player.getServer().getPlayerManager().remove(player);
|
|
player.networkHandler.disconnect(new TranslatableText("multiplayer.disconnect.duplicate_login"));
|
|
ServerWorld worldIn = player.getServerWorld();//.getWorld(player.dimension);
|
|
ServerPlayerInteractionManager interactionManagerIn = new ServerPlayerInteractionManager(worldIn);
|
|
GameProfile gameprofile = player.getGameProfile();
|
|
EntityPlayerMPFake playerShadow = new EntityPlayerMPFake(server, worldIn, gameprofile, interactionManagerIn, true);
|
|
server.getPlayerManager().onPlayerConnect(new NetworkManagerFake(NetworkSide.SERVERBOUND), playerShadow);
|
|
|
|
playerShadow.setHealth(player.getHealth());
|
|
playerShadow.networkHandler.requestTeleport(player.getX(), player.getY(), player.getZ(), player.yaw, player.pitch);
|
|
interactionManagerIn.setGameMode(player.interactionManager.getGameMode());
|
|
((ServerPlayerEntityInterface) playerShadow).getActionPack().copyFrom(((ServerPlayerEntityInterface) player).getActionPack());
|
|
playerShadow.stepHeight = 0.6F;
|
|
playerShadow.dataTracker.set(PLAYER_MODEL_PARTS, player.getDataTracker().get(PLAYER_MODEL_PARTS));
|
|
|
|
|
|
server.getPlayerManager().sendToDimension(new EntitySetHeadYawS2CPacket(playerShadow, (byte) (player.headYaw * 256 / 360)), playerShadow.world.getRegistryKey());
|
|
server.getPlayerManager().sendToAll(new PlayerListS2CPacket(PlayerListS2CPacket.Action.ADD_PLAYER, playerShadow));
|
|
player.getServerWorld().getChunkManager().updateCameraPosition(playerShadow);
|
|
return playerShadow;
|
|
}
|
|
|
|
private EntityPlayerMPFake(MinecraftServer server, ServerWorld worldIn, GameProfile profile, ServerPlayerInteractionManager interactionManagerIn, boolean shadow)
|
|
{
|
|
super(server, worldIn, profile, interactionManagerIn);
|
|
isAShadow = shadow;
|
|
}
|
|
|
|
@Override
|
|
protected void onEquipStack(ItemStack stack)
|
|
{
|
|
if (!isUsingItem()) super.onEquipStack(stack);
|
|
}
|
|
|
|
@Override
|
|
public void kill()
|
|
{
|
|
kill(Messenger.s("Killed"));
|
|
}
|
|
|
|
public void kill(Text reason)
|
|
{
|
|
shakeOff();
|
|
this.server.send(new ServerTask(this.server.getTicks(), () -> {
|
|
this.networkHandler.onDisconnected(reason);
|
|
}));
|
|
}
|
|
|
|
@Override
|
|
public void tick()
|
|
{
|
|
if (this.getServer().getTicks() % 10 == 0)
|
|
{
|
|
this.networkHandler.syncWithPlayerPosition();
|
|
this.getServerWorld().getChunkManager().updateCameraPosition(this);
|
|
//if (netherPortalCooldown==10) onTeleportationDone(); <- causes hard crash but would need to be done to enable portals
|
|
}
|
|
super.tick();
|
|
this.playerTick();
|
|
}
|
|
|
|
private void shakeOff()
|
|
{
|
|
if (getVehicle() instanceof PlayerEntity) stopRiding();
|
|
for (Entity passenger : getPassengersDeep())
|
|
{
|
|
if (passenger instanceof PlayerEntity) passenger.stopRiding();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onDeath(DamageSource cause)
|
|
{
|
|
shakeOff();
|
|
super.onDeath(cause);
|
|
setHealth(20);
|
|
this.hungerManager = new HungerManager();
|
|
kill(this.getDamageTracker().getDeathMessage());
|
|
}
|
|
|
|
@Override
|
|
public String getIp()
|
|
{
|
|
return "127.0.0.1";
|
|
}
|
|
}
|