PrepareSpawnTask.java
net.minecraft.server.network.config.PrepareSpawnTask
信息
- 全限定名:net.minecraft.server.network.config.PrepareSpawnTask
- 类型:public class
- 包:net.minecraft.server.network.config
- 源码路径:src/main/java/net/minecraft/server/network/config/PrepareSpawnTask.java
- 起始行号:L31
- 实现:ConfigurationTask
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L32 - 说明:
TODO
- 类型:
-
TYPE- 类型:
ConfigurationTask.Type - 修饰符:
public static final - 源码定位:
L33 - 说明:
TODO
- 类型:
-
PREPARE_CHUNK_RADIUS- 类型:
int - 修饰符:
public static final - 源码定位:
L34 - 说明:
TODO
- 类型:
-
server- 类型:
MinecraftServer - 修饰符:
private final - 源码定位:
L35 - 说明:
TODO
- 类型:
-
nameAndId- 类型:
NameAndId - 修饰符:
private final - 源码定位:
L36 - 说明:
TODO
- 类型:
-
loadListener- 类型:
LevelLoadListener - 修饰符:
private final - 源码定位:
L37 - 说明:
TODO
- 类型:
-
state- 类型:
PrepareSpawnTask.State - 修饰符:
private - 源码定位:
L38 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.server.network.config.PrepareSpawnTask.Preparing- 类型:
class - 修饰符:
private final - 源码定位:
L113 - 说明:
TODO
- 类型:
-
net.minecraft.server.network.config.PrepareSpawnTask.Ready- 类型:
class - 修饰符:
private final - 源码定位:
L161 - 说明:
TODO
- 类型:
-
net.minecraft.server.network.config.PrepareSpawnTask.State- 类型:
interface - 修饰符:
private sealed - 源码定位:
L203 - 说明:
TODO
- 类型:
构造器
public PrepareSpawnTask(MinecraftServer server, NameAndId nameAndId) @ L40
- 构造器名:PrepareSpawnTask
- 源码定位:L40
- 修饰符:public
参数:
- server: MinecraftServer
- nameAndId: NameAndId
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void start(Consumer<Packet<?>> connection) @ L46
- 方法名:start
- 源码定位:L46
- 返回类型:void
- 修饰符:public
参数:
- connection: Consumer<Packet<?>>
说明:
TODO
public boolean tick() @ L68
- 方法名:tick
- 源码定位:L68
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public ServerPlayer spawnPlayer(Connection connection, CommonListenerCookie cookie) @ L86
- 方法名:spawnPlayer
- 源码定位:L86
- 返回类型:ServerPlayer
- 修饰符:public
参数:
- connection: Connection
- cookie: CommonListenerCookie
说明:
TODO
public void keepAlive() @ L94
- 方法名:keepAlive
- 源码定位:L94
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void close() @ L100
- 方法名:close
- 源码定位:L100
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public ConfigurationTask.Type type() @ L108
- 方法名:type
- 源码定位:L108
- 返回类型:ConfigurationTask.Type
- 修饰符:public
参数:
- 无
说明:
TODO
代码
public class PrepareSpawnTask implements ConfigurationTask {
private static final Logger LOGGER = LogUtils.getLogger();
public static final ConfigurationTask.Type TYPE = new ConfigurationTask.Type("prepare_spawn");
public static final int PREPARE_CHUNK_RADIUS = 3;
private final MinecraftServer server;
private final NameAndId nameAndId;
private final LevelLoadListener loadListener;
private PrepareSpawnTask.@Nullable State state;
public PrepareSpawnTask(MinecraftServer server, NameAndId nameAndId) {
this.server = server;
this.nameAndId = nameAndId;
this.loadListener = server.getLevelLoadListener();
}
@Override
public void start(Consumer<Packet<?>> connection) {
try (ProblemReporter.ScopedCollector reporter = new ProblemReporter.ScopedCollector(LOGGER)) {
Optional<ValueInput> loadedData = this.server
.getPlayerList()
.loadPlayerData(this.nameAndId)
.map(tag -> TagValueInput.create(reporter, this.server.registryAccess(), tag));
ServerPlayer.SavedPosition loadedPosition = loadedData.<ServerPlayer.SavedPosition>flatMap(tag -> tag.read(ServerPlayer.SavedPosition.MAP_CODEC))
.orElse(ServerPlayer.SavedPosition.EMPTY);
LevelData.RespawnData respawnData = this.server.getWorldData().overworldData().getRespawnData();
ServerLevel spawnLevel = loadedPosition.dimension().map(this.server::getLevel).orElseGet(() -> {
ServerLevel spawnDataLevel = this.server.getLevel(respawnData.dimension());
return spawnDataLevel != null ? spawnDataLevel : this.server.overworld();
});
CompletableFuture<Vec3> spawnPosition = loadedPosition.position()
.map(CompletableFuture::completedFuture)
.orElseGet(() -> PlayerSpawnFinder.findSpawn(spawnLevel, respawnData.pos()));
Vec2 spawnAngle = loadedPosition.rotation().orElse(new Vec2(respawnData.yaw(), respawnData.pitch()));
this.state = new PrepareSpawnTask.Preparing(spawnLevel, spawnPosition, spawnAngle);
}
}
@Override
public boolean tick() {
return switch (this.state) {
case null -> false;
case PrepareSpawnTask.Preparing preparing -> {
PrepareSpawnTask.Ready ready = preparing.tick();
if (ready != null) {
this.state = ready;
yield true;
} else {
yield false;
}
}
case PrepareSpawnTask.Ready ignored -> true;
default -> throw new MatchException(null, null);
};
}
public ServerPlayer spawnPlayer(Connection connection, CommonListenerCookie cookie) {
if (this.state instanceof PrepareSpawnTask.Ready ready) {
return ready.spawn(connection, cookie);
} else {
throw new IllegalStateException("Player spawn was not ready");
}
}
public void keepAlive() {
if (this.state instanceof PrepareSpawnTask.Ready ready) {
ready.keepAlive();
}
}
public void close() {
if (this.state instanceof PrepareSpawnTask.Preparing preparing) {
preparing.cancel();
}
this.state = null;
}
@Override
public ConfigurationTask.Type type() {
return TYPE;
}
private final class Preparing implements PrepareSpawnTask.State {
private final ServerLevel spawnLevel;
private final CompletableFuture<Vec3> spawnPosition;
private final Vec2 spawnAngle;
private @Nullable CompletableFuture<?> chunkLoadFuture;
private final ChunkLoadCounter chunkLoadCounter;
private Preparing(ServerLevel spawnLevel, CompletableFuture<Vec3> spawnPosition, Vec2 spawnAngle) {
Objects.requireNonNull(PrepareSpawnTask.this);
super();
this.chunkLoadCounter = new ChunkLoadCounter();
this.spawnLevel = spawnLevel;
this.spawnPosition = spawnPosition;
this.spawnAngle = spawnAngle;
}
public void cancel() {
this.spawnPosition.cancel(false);
}
public PrepareSpawnTask.@Nullable Ready tick() {
if (!this.spawnPosition.isDone()) {
return null;
} else {
Vec3 spawnPosition = this.spawnPosition.join();
if (this.chunkLoadFuture == null) {
ChunkPos spawnChunk = ChunkPos.containing(BlockPos.containing(spawnPosition));
this.chunkLoadCounter
.track(
this.spawnLevel,
() -> this.chunkLoadFuture = this.spawnLevel.getChunkSource().addTicketAndLoadWithRadius(TicketType.PLAYER_SPAWN, spawnChunk, 3)
);
PrepareSpawnTask.this.loadListener.start(LevelLoadListener.Stage.LOAD_PLAYER_CHUNKS, this.chunkLoadCounter.totalChunks());
PrepareSpawnTask.this.loadListener.updateFocus(this.spawnLevel.dimension(), spawnChunk);
}
PrepareSpawnTask.this.loadListener
.update(LevelLoadListener.Stage.LOAD_PLAYER_CHUNKS, this.chunkLoadCounter.readyChunks(), this.chunkLoadCounter.totalChunks());
if (!this.chunkLoadFuture.isDone()) {
return null;
} else {
PrepareSpawnTask.this.loadListener.finish(LevelLoadListener.Stage.LOAD_PLAYER_CHUNKS);
return PrepareSpawnTask.this.new Ready(this.spawnLevel, spawnPosition, this.spawnAngle);
}
}
}
}
private final class Ready implements PrepareSpawnTask.State {
private final ServerLevel spawnLevel;
private final Vec3 spawnPosition;
private final Vec2 spawnAngle;
private Ready(ServerLevel spawnLevel, Vec3 spawnPosition, Vec2 spawnAngle) {
Objects.requireNonNull(PrepareSpawnTask.this);
super();
this.spawnLevel = spawnLevel;
this.spawnPosition = spawnPosition;
this.spawnAngle = spawnAngle;
}
public void keepAlive() {
this.spawnLevel.getChunkSource().addTicketWithRadius(TicketType.PLAYER_SPAWN, ChunkPos.containing(BlockPos.containing(this.spawnPosition)), 3);
}
public ServerPlayer spawn(Connection connection, CommonListenerCookie cookie) {
ChunkPos spawnChunk = ChunkPos.containing(BlockPos.containing(this.spawnPosition));
this.spawnLevel.waitForEntities(spawnChunk, 3);
ServerPlayer player = new ServerPlayer(PrepareSpawnTask.this.server, this.spawnLevel, cookie.gameProfile(), cookie.clientInformation());
ServerPlayer var7;
try (ProblemReporter.ScopedCollector reporter = new ProblemReporter.ScopedCollector(player.problemPath(), PrepareSpawnTask.LOGGER)) {
Optional<ValueInput> input = PrepareSpawnTask.this.server
.getPlayerList()
.loadPlayerData(PrepareSpawnTask.this.nameAndId)
.map(tag -> TagValueInput.create(reporter, PrepareSpawnTask.this.server.registryAccess(), tag));
input.ifPresent(player::load);
player.snapTo(this.spawnPosition, this.spawnAngle.x, this.spawnAngle.y);
PrepareSpawnTask.this.server.getPlayerList().placeNewPlayer(connection, player, cookie);
input.ifPresent(tag -> {
player.loadAndSpawnEnderPearls(tag);
player.loadAndSpawnParentVehicle(tag);
});
var7 = player;
}
return var7;
}
}
private sealed interface State permits PrepareSpawnTask.Preparing, PrepareSpawnTask.Ready {
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
BlockPos.containing()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
ChunkLoadCounter()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
PlayerSpawnFinder.findSpawn()
- 引用位置:
-
- 引用位置:
构造调用/返回值 - 关联成员:
ServerPlayer()
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/实现/方法调用/构造调用/返回值 - 关联成员:
ConfigurationTask.Type(), Type()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用/构造调用 - 关联成员:
ProblemReporter.ScopedCollector(), ScopedCollector()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ChunkPos.containing()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
TagValueInput.create()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
Vec2()
- 引用位置: