lots of code
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
package io.github.skippyall.minions.fakeplayer;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.yggdrasil.ProfileResult;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.UUIDUtil;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.contents.TranslatableContents;
|
||||
import net.minecraft.network.protocol.PacketFlow;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundClientCommandPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.TickTask;
|
||||
import net.minecraft.server.level.ClientInformation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.CommonListenerCookie;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.food.FoodData;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class MinionFakePlayer extends ServerPlayer {
|
||||
public Runnable fixStartingPosition = () -> {};
|
||||
public boolean isAShadow;
|
||||
public static void createMinion(String username, ServerLevel level, ServerPlayer owner, Vec3 pos, double yaw, double pitch) {
|
||||
MinecraftServer server = level.getServer();
|
||||
server.getProfileCache().getAsync(username).thenAcceptAsync((optional) -> {
|
||||
GameProfile profile = null;
|
||||
if(optional.isPresent()){
|
||||
UUID uuid = optional.get().getId();
|
||||
ProfileResult result = server.getSessionService().fetchProfile(uuid, true);
|
||||
if(result != null) {
|
||||
profile = result.profile();
|
||||
}
|
||||
}
|
||||
if(profile == null) {
|
||||
profile = new GameProfile(UUIDUtil.createOfflinePlayerUUID(username), username);
|
||||
}
|
||||
MinionFakePlayer instance = new MinionFakePlayer(server, level, profile, ClientInformation.createDefault(), false);
|
||||
instance.fixStartingPosition = () -> instance.moveTo(pos.x, pos.y, pos.z, (float) yaw, (float) pitch);
|
||||
server.getPlayerList().placeNewPlayer(new FakeClientConnection(PacketFlow.SERVERBOUND), instance, new CommonListenerCookie(profile, 0, instance.clientInformation()));
|
||||
instance.teleportTo(level, pos.x, pos.y, pos.z, (float) yaw, (float) pitch);
|
||||
instance.setHealth(20.0F);
|
||||
instance.unsetRemoved();
|
||||
instance.gameMode.changeGameModeForPlayer(GameType.SURVIVAL);
|
||||
server.getPlayerList().broadcastAll(new ClientboundRotateHeadPacket(instance, (byte) (instance.yHeadRot * 256 / 360)), level.dimension());//instance.dimension);
|
||||
server.getPlayerList().broadcastAll(new ClientboundTeleportEntityPacket(instance), level.dimension());//instance.dimension);
|
||||
//instance.world.getChunkManager(). updatePosition(instance);
|
||||
instance.entityData.set(DATA_PLAYER_MODE_CUSTOMISATION, (byte) 0x7f); // show all model layers (incl. capes)
|
||||
instance.getAbilities().flying = false;
|
||||
instance.setMaxUpStep(0.6F);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused") //Don't know if I'll need this
|
||||
public static MinionFakePlayer createShadow(MinecraftServer server, ServerPlayer player)
|
||||
{
|
||||
player.getServer().getPlayerList().remove(player);
|
||||
player.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login"));
|
||||
ServerLevel worldIn = player.serverLevel();//.getWorld(player.dimension);
|
||||
GameProfile gameprofile = player.getGameProfile();
|
||||
MinionFakePlayer playerShadow = new MinionFakePlayer(server, worldIn, gameprofile, player.clientInformation(), true);
|
||||
playerShadow.setChatSession(player.getChatSession());
|
||||
server.getPlayerList().placeNewPlayer(new FakeClientConnection(PacketFlow.SERVERBOUND), playerShadow, new CommonListenerCookie(gameprofile, 0, player.clientInformation()));
|
||||
|
||||
playerShadow.setHealth(player.getHealth());
|
||||
playerShadow.connection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
|
||||
playerShadow.gameMode.changeGameModeForPlayer(player.gameMode.getGameModeForPlayer());
|
||||
((ServerPlayerInterface) playerShadow).getActionPack().copyFrom(((ServerPlayerInterface) player).getActionPack());
|
||||
playerShadow.entityData.set(DATA_PLAYER_MODE_CUSTOMISATION, player.getEntityData().get(DATA_PLAYER_MODE_CUSTOMISATION));
|
||||
|
||||
|
||||
server.getPlayerList().broadcastAll(new ClientboundRotateHeadPacket(playerShadow, (byte) (player.yHeadRot * 256 / 360)), playerShadow.level().dimension());
|
||||
server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, playerShadow));
|
||||
//player.world.getChunkManager().updatePosition(playerShadow);
|
||||
playerShadow.getAbilities().flying = player.getAbilities().flying;
|
||||
return playerShadow;
|
||||
}
|
||||
|
||||
public static MinionFakePlayer respawnFake(MinecraftServer server, ServerLevel level, GameProfile profile, ClientInformation cli)
|
||||
{
|
||||
return new MinionFakePlayer(server, level, profile, cli, false);
|
||||
}
|
||||
|
||||
private MinionFakePlayer(MinecraftServer server, ServerLevel worldIn, GameProfile profile, ClientInformation cli, boolean shadow)
|
||||
{
|
||||
super(server, worldIn, profile, cli);
|
||||
isAShadow = shadow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEquipItem(final EquipmentSlot slot, final ItemStack previous, final ItemStack stack)
|
||||
{
|
||||
if (!isUsingItem()) super.onEquipItem(slot, previous, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kill()
|
||||
{
|
||||
kill(Component.literal("Killed"));
|
||||
}
|
||||
|
||||
public void kill(Component reason)
|
||||
{
|
||||
shakeOff();
|
||||
|
||||
if (reason.getContents() instanceof TranslatableContents text && text.getKey().equals("multiplayer.disconnect.duplicate_login")) {
|
||||
this.connection.onDisconnect(reason);
|
||||
} else {
|
||||
this.server.tell(new TickTask(this.server.getTickCount(), () -> {
|
||||
this.connection.onDisconnect(reason);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (this.getServer().getTickCount() % 10 == 0)
|
||||
{
|
||||
this.connection.resetPosition();
|
||||
this.serverLevel().getChunkSource().move(this);
|
||||
}
|
||||
try
|
||||
{
|
||||
super.tick();
|
||||
this.doTick();
|
||||
}
|
||||
catch (NullPointerException ignored)
|
||||
{
|
||||
// happens with that paper port thingy - not sure what that would fix, but hey
|
||||
// the game not gonna crash violently.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void shakeOff()
|
||||
{
|
||||
if (getVehicle() instanceof Player) stopRiding();
|
||||
for (Entity passenger : getIndirectPassengers())
|
||||
{
|
||||
if (passenger instanceof Player) passenger.stopRiding();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die(DamageSource cause)
|
||||
{
|
||||
shakeOff();
|
||||
super.die(cause);
|
||||
setHealth(20);
|
||||
this.foodData = new FoodData();
|
||||
kill(this.getCombatTracker().getDeathMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIpAddress()
|
||||
{
|
||||
return "127.0.0.1";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsListing() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkFallDamage(double y, boolean onGround, BlockState state, BlockPos pos) {
|
||||
doCheckFallDamage(0.0, y, 0.0, onGround);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity changeDimension(ServerLevel serverLevel)
|
||||
{
|
||||
super.changeDimension(serverLevel);
|
||||
if (wonGame) {
|
||||
ServerboundClientCommandPacket p = new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.PERFORM_RESPAWN);
|
||||
connection.handleClientCommand(p);
|
||||
}
|
||||
|
||||
// If above branch was taken, *this* has been removed and replaced, the new instance has been set
|
||||
// on 'our' connection (which is now theirs, but we still have a ref).
|
||||
if (connection.player.isChangingDimension()) {
|
||||
connection.player.hasChangedDimension();
|
||||
}
|
||||
return connection.player;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user