修复之前为了处理多世界被传送到多世界出生点从而带来出生区块不刷新的问题

This commit is contained in:
tanyaofei 2023-07-26 23:32:51 +08:00
parent 61c0381326
commit f4418f8b67
8 changed files with 78 additions and 45 deletions

View File

@ -6,7 +6,7 @@
<groupId>io.github.hello09x</groupId>
<artifactId>fakeplayer</artifactId>
<version>1_20_R1-0.1.2</version>
<version>1_20_R1-0.1.3</version>
<packaging>jar</packaging>
<name>fakeplayer</name>

View File

@ -21,7 +21,7 @@ public class SpawnCommand extends AbstractCommand {
public final static SpawnCommand instance = new SpawnCommand();
public void create(@NotNull Player sender, CommandArguments args) {
var fakePlayer = fakeplayerManager.spawn(sender, sender.getLocation());
var fakePlayer = fakeplayerManager.spawn(sender, sender.getLocation().clone());
if (fakePlayer != null) {
sender.sendMessage(textOfChildren(
text("你创建了假人 ", GRAY),

View File

@ -18,7 +18,11 @@ public class EmptyConnection extends Connection {
}
@Override
public void send(Packet packet, PacketSendListener listener) {
public void send(Packet<?> packet, PacketSendListener listener) {
}
@Override
public void send(Packet<?> packet) {
}
@Override

View File

@ -0,0 +1,30 @@
package io.github.hello09x.fakeplayer.entity;
import com.mojang.authlib.GameProfile;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
public class DebugServerPlayer extends ServerPlayer {
public DebugServerPlayer(MinecraftServer minecraftserver, ServerLevel worldserver, GameProfile gameprofile) {
super(minecraftserver, worldserver, gameprofile);
}
@Override
public void tick() {
System.out.println("tick");
super.tick();
}
@Override
public void doTick() {
System.out.println("dotick");
super.doTick();
}
@Override
public void baseTick() {
System.out.println("baseTick");
super.baseTick();
}
}

View File

@ -17,6 +17,7 @@ import net.minecraft.server.PlayerAdvancements;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
@ -54,7 +55,8 @@ public class FakePlayer {
@NotNull String creator,
@NotNull MinecraftServer server,
@NotNull UUID uniqueId,
@NotNull String name
@NotNull String name,
@NotNull Location spawnAt
) {
this.creator = creator;
this.handle = new ServerPlayer(server, Objects.requireNonNull(server.getLevel(ServerLevel.OVERWORLD), "缺少 overworld 世界"), new GameProfile(uniqueId, name));
@ -86,7 +88,6 @@ public class FakePlayer {
boolean pickupItems
) {
if (properties.isSimulateLogin()) {
preLogin:
new BukkitRunnable() {
@Override
public void run() {
@ -102,7 +103,6 @@ public class FakePlayer {
}
}.runTaskAsynchronously(Main.getInstance());
login:
{
Bukkit.getPluginManager().callEvent(new PlayerLoginEvent(
this.bukkitPlayer,
@ -112,7 +112,6 @@ public class FakePlayer {
}
}
gaming:
{
var connection = new EmptyConnection(PacketFlow.CLIENTBOUND);
var listener = new EmptyServerGamePacketListener(this.server, connection, this.handle);
@ -120,7 +119,6 @@ public class FakePlayer {
connection.setListener(listener);
}
spawn:
{
var connection = new EmptyConnection(PacketFlow.CLIENTBOUND);
var listener = new EmptyLoginPacketListener(server, connection);

View File

@ -4,7 +4,6 @@ import io.github.hello09x.fakeplayer.Main;
import io.github.hello09x.fakeplayer.entity.FakePlayer;
import io.github.hello09x.fakeplayer.entity.FakeplayerMetadata;
import io.github.hello09x.fakeplayer.entity.action.Action;
import io.github.hello09x.fakeplayer.entity.action.PlayerActionManager;
import io.github.hello09x.fakeplayer.optional.BungeeCordServer;
import io.github.hello09x.fakeplayer.properties.FakeplayerProperties;
import io.github.hello09x.fakeplayer.repository.UsedIdRepository;
@ -54,8 +53,6 @@ public class FakeplayerManager {
private final BungeeCordServer bungee = BungeeCordServer.instance;
private final PlayerActionManager playerActionManager = PlayerActionManager.instance;
private FakeplayerManager() {
var timer = new Timer();
@ -80,7 +77,7 @@ public class FakeplayerManager {
timer.schedule(new TimerTask() {
@Override
public void run() {
if (!properties.isFollowQuiting() || !properties.isBungee()) {
if (!properties.isFollowQuiting() || !properties.isBungeecord()) {
return;
}
@ -88,12 +85,12 @@ public class FakeplayerManager {
.stream()
.collect(Collectors.groupingBy(FakeplayerManager.this::getCreator));
for(var entry: group.entrySet()) {
for (var entry : group.entrySet()) {
if (bungee.isPlayerOnline(entry.getKey())) {
continue;
}
for(var fakePlayer: entry.getValue()) {
for (var fakePlayer : entry.getValue()) {
remove(fakePlayer.getName());
}
@ -143,47 +140,51 @@ public class FakeplayerManager {
pickupItems = userConfigRepository.selectOrDefault(creatorId, Configs.pickup_items);
}
var serverPlayer = new FakePlayer(
var player = new FakePlayer(
creator.getName(),
((CraftServer) Bukkit.getServer()).getServer(),
generateId(name.name()),
name.name()
name.name(),
spawnAt
);
var player = serverPlayer.getBukkitPlayer();
player.setMetadata(FakeplayerMetadata.CREATOR.key, new FixedMetadataValue(Main.getInstance(), creator.getName()));
player.setMetadata(FakeplayerMetadata.CREATOR_IP.key, new FixedMetadataValue(Main.getInstance(), AddressUtils.getAddress(creator)));
player.setMetadata(FakeplayerMetadata.NAME_SOURCE.key, new FixedMetadataValue(Main.getInstance(), name.source()));
player.setMetadata(FakeplayerMetadata.NAME_SEQUENCE.key, new FixedMetadataValue(Main.getInstance(), name.sequence()));
player.playerListName(text(creator.getName() + "的假人").style(Style.style(GRAY, ITALIC)));
var bukkitPlayer = player.getBukkitPlayer();
bukkitPlayer.setMetadata(FakeplayerMetadata.CREATOR.key, new FixedMetadataValue(Main.getInstance(), creator.getName()));
bukkitPlayer.setMetadata(FakeplayerMetadata.CREATOR_IP.key, new FixedMetadataValue(Main.getInstance(), AddressUtils.getAddress(creator)));
bukkitPlayer.setMetadata(FakeplayerMetadata.NAME_SOURCE.key, new FixedMetadataValue(Main.getInstance(), name.source()));
bukkitPlayer.setMetadata(FakeplayerMetadata.NAME_SEQUENCE.key, new FixedMetadataValue(Main.getInstance(), name.sequence()));
bukkitPlayer.playerListName(text(creator.getName() + "的假人").style(Style.style(GRAY, ITALIC)));
serverPlayer.spawn(invulnerable, collidable, lookAtEntity, pickupItems);
player.spawn(invulnerable, collidable, lookAtEntity, pickupItems);
usedIdRepository.add(player.getUniqueId());
usedIdRepository.add(bukkitPlayer.getUniqueId());
dispatchCommands(player, properties.getPreparingCommands());
performCommands(player);
dispatchCommands(bukkitPlayer, properties.getPreparingCommands());
performCommands(bukkitPlayer);
// 先等待玩家 spawn 之后再 tp, 否则 tp 不生效
// 可能会被别的插件干预, 因此 tp 两次
var spawnpoint = spawnAt.getWorld().getSpawnLocation().clone();
bukkitPlayer.teleport(spawnAt); // 当前 tick 必须传到出生点否则无法触发区块刷新
spawnAt.getWorld().playSound(spawnAt, Sound.ENTITY_ENDERMAN_TELEPORT, 1.0F, 1.0F);
// 可能被别的插件干预
// 在下一 tick 里探测
new BukkitRunnable() {
@Override
public void run() {
player.teleport(spawnpoint);
}
}.runTaskLater(Main.getInstance(), 5);
if (spawnAt.distance(bukkitPlayer.getLocation()) < 16) {
return;
}
var moveTo = spawnAt.clone();
new BukkitRunnable() {
@Override
public void run() {
player.teleport(moveTo);
moveTo.getWorld().playSound(moveTo, Sound.ENTITY_ENDERMAN_TELEPORT, 1.0F, 1.0F);
bukkitPlayer.teleport(spawnAt.getWorld().getSpawnLocation());
new BukkitRunnable() {
@Override
public void run() {
bukkitPlayer.teleport(spawnAt);
}
}.runTaskLater(Main.getInstance(), 1);
}
}.runTaskLater(Main.getInstance(), 20);
}.runTaskLater(Main.getInstance(), 1);
return player;
return bukkitPlayer;
}
public @Nullable Player get(@NotNull CommandSender creator, @NotNull String name) {
@ -361,7 +362,7 @@ public class FakeplayerManager {
}
public void performCommands(@NotNull Player player) {
if (!isFake(player)) {
if (!isFake(player)) {
return;
}

View File

@ -50,7 +50,7 @@ public class FakeplayerProperties extends AbstractProperties<FakeplayerPropertie
/**
* 是否允许玩家切换 bungeeCord 服务器时不跟随下线
*/
private boolean bungee;
private boolean bungeecord;
/**
* 是否探测 IP
@ -102,10 +102,10 @@ public class FakeplayerProperties extends AbstractProperties<FakeplayerPropertie
this.destroyCommands = file.getStringList("destroy-commands");
this.nameTemplate = file.getString("name-template", "");
this.simulateLogin = file.getBoolean("simulate-login", false);
this.bungee = file.getBoolean("bungee", true);
this.bungeecord = file.getBoolean("bungeecord", true);
if (this.nameTemplate.startsWith("-")) {
log.warning("假人名称模版不能以 - 开头, 该配置不会生效");
log.warning("假人名称模版不能以 - 开头, 该配置不会生效: " + this.nameTemplate);
this.nameTemplate = "";
}
}

View File

@ -27,7 +27,7 @@ follow-quiting: true
# 是否开启 bungeeCord 跟随下线
# 如果开启则玩家在切换服务器时不会因为在当前服务器下线而导致跟随下线
# 此配置仅在 `follow-quiting` 为 `true` 时生效
bungee: true
bungeecord: true
# 是否检测 IP
# 如果启用, 则一个 IP 只能创建 `maximum` 个假人