PlayerAdvancements.java
net.minecraft.server.PlayerAdvancements
信息
- 全限定名:net.minecraft.server.PlayerAdvancements
- 类型:public class
- 包:net.minecraft.server
- 源码路径:src/main/java/net/minecraft/server/PlayerAdvancements.java
- 起始行号:L48
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L49 - 说明:
TODO
- 类型:
-
GSON- 类型:
Gson - 修饰符:
private static final - 源码定位:
L50 - 说明:
TODO
- 类型:
-
playerList- 类型:
PlayerList - 修饰符:
private final - 源码定位:
L51 - 说明:
TODO
- 类型:
-
playerSavePath- 类型:
Path - 修饰符:
private final - 源码定位:
L52 - 说明:
TODO
- 类型:
-
tree- 类型:
AdvancementTree - 修饰符:
private - 源码定位:
L53 - 说明:
TODO
- 类型:
-
progress- 类型:
Map<AdvancementHolder,AdvancementProgress> - 修饰符:
private final - 源码定位:
L54 - 说明:
TODO
- 类型:
-
visible- 类型:
Set<AdvancementHolder> - 修饰符:
private final - 源码定位:
L55 - 说明:
TODO
- 类型:
-
progressChanged- 类型:
Set<AdvancementHolder> - 修饰符:
private final - 源码定位:
L56 - 说明:
TODO
- 类型:
-
rootsToUpdate- 类型:
Set<AdvancementNode> - 修饰符:
private final - 源码定位:
L57 - 说明:
TODO
- 类型:
-
player- 类型:
ServerPlayer - 修饰符:
private - 源码定位:
L58 - 说明:
TODO
- 类型:
-
lastSelectedTab- 类型:
AdvancementHolder - 修饰符:
private - 源码定位:
L59 - 说明:
TODO
- 类型:
-
isFirstPacket- 类型:
boolean - 修饰符:
private - 源码定位:
L60 - 说明:
TODO
- 类型:
-
codec- 类型:
Codec<PlayerAdvancements.Data> - 修饰符:
private final - 源码定位:
L61 - 说明:
TODO
- 类型:
内部类/嵌套类型
net.minecraft.server.PlayerAdvancements.Data- 类型:
record - 修饰符:
private - 源码定位:
L316 - 说明:
TODO
- 类型:
构造器
public PlayerAdvancements(DataFixer dataFixer, PlayerList playerList, ServerAdvancementManager manager, Path playerSavePath, ServerPlayer player) @ L63
- 构造器名:PlayerAdvancements
- 源码定位:L63
- 修饰符:public
参数:
- dataFixer: DataFixer
- playerList: PlayerList
- manager: ServerAdvancementManager
- playerSavePath: Path
- player: ServerPlayer
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void setPlayer(ServerPlayer player) @ L73
- 方法名:setPlayer
- 源码定位:L73
- 返回类型:void
- 修饰符:public
参数:
- player: ServerPlayer
说明:
TODO
public void stopListening() @ L77
- 方法名:stopListening
- 源码定位:L77
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void reload(ServerAdvancementManager manager) @ L83
- 方法名:reload
- 源码定位:L83
- 返回类型:void
- 修饰符:public
参数:
- manager: ServerAdvancementManager
说明:
TODO
private void registerListeners(ServerAdvancementManager manager) @ L95
- 方法名:registerListeners
- 源码定位:L95
- 返回类型:void
- 修饰符:private
参数:
- manager: ServerAdvancementManager
说明:
TODO
private void checkForAutomaticTriggers(ServerAdvancementManager manager) @ L101
- 方法名:checkForAutomaticTriggers
- 源码定位:L101
- 返回类型:void
- 修饰符:private
参数:
- manager: ServerAdvancementManager
说明:
TODO
private void load(ServerAdvancementManager manager) @ L111
- 方法名:load
- 源码定位:L111
- 返回类型:void
- 修饰符:private
参数:
- manager: ServerAdvancementManager
说明:
TODO
public void save() @ L128
- 方法名:save
- 源码定位:L128
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private void applyFrom(ServerAdvancementManager manager, PlayerAdvancements.Data data) @ L142
- 方法名:applyFrom
- 源码定位:L142
- 返回类型:void
- 修饰符:private
参数:
- manager: ServerAdvancementManager
- data: PlayerAdvancements.Data
说明:
TODO
private PlayerAdvancements.Data asData() @ L155
- 方法名:asData
- 源码定位:L155
- 返回类型:PlayerAdvancements.Data
- 修饰符:private
参数:
- 无
说明:
TODO
public boolean award(AdvancementHolder holder, String criterion) @ L165
- 方法名:award
- 源码定位:L165
- 返回类型:boolean
- 修饰符:public
参数:
- holder: AdvancementHolder
- criterion: String
说明:
TODO
public boolean revoke(AdvancementHolder advancement, String criterion) @ L190
- 方法名:revoke
- 源码定位:L190
- 返回类型:boolean
- 修饰符:public
参数:
- advancement: AdvancementHolder
- criterion: String
说明:
TODO
private void markForVisibilityUpdate(AdvancementHolder advancement) @ L207
- 方法名:markForVisibilityUpdate
- 源码定位:L207
- 返回类型:void
- 修饰符:private
参数:
- advancement: AdvancementHolder
说明:
TODO
private void registerListeners(AdvancementHolder holder) @ L214
- 方法名:registerListeners
- 源码定位:L214
- 返回类型:void
- 修饰符:private
参数:
- holder: AdvancementHolder
说明:
TODO
private <T extends CriterionTriggerInstance> void registerListener(AdvancementHolder holder, String key, Criterion<T> criterion) @ L226
- 方法名:registerListener
- 源码定位:L226
- 返回类型:
void - 修饰符:private
参数:
- holder: AdvancementHolder
- key: String
- criterion: Criterion
说明:
TODO
private void unregisterListeners(AdvancementHolder holder) @ L230
- 方法名:unregisterListeners
- 源码定位:L230
- 返回类型:void
- 修饰符:private
参数:
- holder: AdvancementHolder
说明:
TODO
private <T extends CriterionTriggerInstance> void removeListener(AdvancementHolder holder, String key, Criterion<T> criterion) @ L241
- 方法名:removeListener
- 源码定位:L241
- 返回类型:
void - 修饰符:private
参数:
- holder: AdvancementHolder
- key: String
- criterion: Criterion
说明:
TODO
public void flushDirty(ServerPlayer player, boolean showAdvancements) @ L245
- 方法名:flushDirty
- 源码定位:L245
- 返回类型:void
- 修饰符:public
参数:
- player: ServerPlayer
- showAdvancements: boolean
说明:
TODO
public void setSelectedTab(AdvancementHolder holder) @ L272
- 方法名:setSelectedTab
- 源码定位:L272
- 返回类型:void
- 修饰符:public
参数:
- holder: AdvancementHolder
说明:
TODO
public AdvancementProgress getOrStartProgress(AdvancementHolder advancement) @ L285
- 方法名:getOrStartProgress
- 源码定位:L285
- 返回类型:AdvancementProgress
- 修饰符:public
参数:
- advancement: AdvancementHolder
说明:
TODO
private void startProgress(AdvancementHolder holder, AdvancementProgress progress) @ L295
- 方法名:startProgress
- 源码定位:L295
- 返回类型:void
- 修饰符:private
参数:
- holder: AdvancementHolder
- progress: AdvancementProgress
说明:
TODO
private void updateTreeVisibility(AdvancementNode root, Set<AdvancementHolder> added, Set<Identifier> removed) @ L300
- 方法名:updateTreeVisibility
- 源码定位:L300
- 返回类型:void
- 修饰符:private
参数:
- root: AdvancementNode
- added: Set
- removed: Set
说明:
TODO
代码
public class PlayerAdvancements {
private static final Logger LOGGER = LogUtils.getLogger();
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private final PlayerList playerList;
private final Path playerSavePath;
private AdvancementTree tree;
private final Map<AdvancementHolder, AdvancementProgress> progress = new LinkedHashMap<>();
private final Set<AdvancementHolder> visible = new HashSet<>();
private final Set<AdvancementHolder> progressChanged = new HashSet<>();
private final Set<AdvancementNode> rootsToUpdate = new HashSet<>();
private ServerPlayer player;
private @Nullable AdvancementHolder lastSelectedTab;
private boolean isFirstPacket = true;
private final Codec<PlayerAdvancements.Data> codec;
public PlayerAdvancements(DataFixer dataFixer, PlayerList playerList, ServerAdvancementManager manager, Path playerSavePath, ServerPlayer player) {
this.playerList = playerList;
this.playerSavePath = playerSavePath;
this.player = player;
this.tree = manager.tree();
int defaultVersion = 1343;
this.codec = DataFixTypes.ADVANCEMENTS.wrapCodec(PlayerAdvancements.Data.CODEC, dataFixer, 1343);
this.load(manager);
}
public void setPlayer(ServerPlayer player) {
this.player = player;
}
public void stopListening() {
for (CriterionTrigger<?> trigger : BuiltInRegistries.TRIGGER_TYPES) {
trigger.removePlayerListeners(this);
}
}
public void reload(ServerAdvancementManager manager) {
this.stopListening();
this.progress.clear();
this.visible.clear();
this.rootsToUpdate.clear();
this.progressChanged.clear();
this.isFirstPacket = true;
this.lastSelectedTab = null;
this.tree = manager.tree();
this.load(manager);
}
private void registerListeners(ServerAdvancementManager manager) {
for (AdvancementHolder advancement : manager.getAllAdvancements()) {
this.registerListeners(advancement);
}
}
private void checkForAutomaticTriggers(ServerAdvancementManager manager) {
for (AdvancementHolder holder : manager.getAllAdvancements()) {
Advancement advancement = holder.value();
if (advancement.criteria().isEmpty()) {
this.award(holder, "");
advancement.rewards().grant(this.player);
}
}
}
private void load(ServerAdvancementManager manager) {
if (Files.isRegularFile(this.playerSavePath)) {
try (Reader reader = Files.newBufferedReader(this.playerSavePath, StandardCharsets.UTF_8)) {
JsonElement json = StrictJsonParser.parse(reader);
PlayerAdvancements.Data data = this.codec.parse(JsonOps.INSTANCE, json).getOrThrow(JsonParseException::new);
this.applyFrom(manager, data);
} catch (JsonIOException | IOException var7) {
LOGGER.error("Couldn't access player advancements in {}", this.playerSavePath, var7);
} catch (JsonParseException var8) {
LOGGER.error("Couldn't parse player advancements in {}", this.playerSavePath, var8);
}
}
this.checkForAutomaticTriggers(manager);
this.registerListeners(manager);
}
public void save() {
JsonElement json = this.codec.encodeStart(JsonOps.INSTANCE, this.asData()).getOrThrow();
try {
FileUtil.createDirectoriesSafe(this.playerSavePath.getParent());
try (Writer outputWriter = Files.newBufferedWriter(this.playerSavePath, StandardCharsets.UTF_8)) {
GSON.toJson(json, GSON.newJsonWriter(outputWriter));
}
} catch (JsonIOException | IOException var7) {
LOGGER.error("Couldn't save player advancements to {}", this.playerSavePath, var7);
}
}
private void applyFrom(ServerAdvancementManager manager, PlayerAdvancements.Data data) {
data.forEach((id, progress) -> {
AdvancementHolder advancement = manager.get(id);
if (advancement == null) {
LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", id, this.playerSavePath);
} else {
this.startProgress(advancement, progress);
this.progressChanged.add(advancement);
this.markForVisibilityUpdate(advancement);
}
});
}
private PlayerAdvancements.Data asData() {
Map<Identifier, AdvancementProgress> map = new LinkedHashMap<>();
this.progress.forEach((advancement, progress) -> {
if (progress.hasProgress()) {
map.put(advancement.id(), progress);
}
});
return new PlayerAdvancements.Data(map);
}
public boolean award(AdvancementHolder holder, String criterion) {
boolean result = false;
AdvancementProgress progress = this.getOrStartProgress(holder);
boolean wasDone = progress.isDone();
if (progress.grantProgress(criterion)) {
this.unregisterListeners(holder);
this.progressChanged.add(holder);
result = true;
if (!wasDone && progress.isDone()) {
holder.value().rewards().grant(this.player);
holder.value().display().ifPresent(display -> {
if (display.shouldAnnounceChat() && this.player.level().getGameRules().get(GameRules.SHOW_ADVANCEMENT_MESSAGES)) {
this.playerList.broadcastSystemMessage(display.getType().createAnnouncement(holder, this.player), false);
}
});
}
}
if (!wasDone && progress.isDone()) {
this.markForVisibilityUpdate(holder);
}
return result;
}
public boolean revoke(AdvancementHolder advancement, String criterion) {
boolean result = false;
AdvancementProgress progress = this.getOrStartProgress(advancement);
boolean wasDone = progress.isDone();
if (progress.revokeProgress(criterion)) {
this.registerListeners(advancement);
this.progressChanged.add(advancement);
result = true;
}
if (wasDone && !progress.isDone()) {
this.markForVisibilityUpdate(advancement);
}
return result;
}
private void markForVisibilityUpdate(AdvancementHolder advancement) {
AdvancementNode node = this.tree.get(advancement);
if (node != null) {
this.rootsToUpdate.add(node.root());
}
}
private void registerListeners(AdvancementHolder holder) {
AdvancementProgress advancementProgress = this.getOrStartProgress(holder);
if (!advancementProgress.isDone()) {
for (Entry<String, Criterion<?>> entry : holder.value().criteria().entrySet()) {
CriterionProgress criterionProgress = advancementProgress.getCriterion(entry.getKey());
if (criterionProgress != null && !criterionProgress.isDone()) {
this.registerListener(holder, entry.getKey(), entry.getValue());
}
}
}
}
private <T extends CriterionTriggerInstance> void registerListener(AdvancementHolder holder, String key, Criterion<T> criterion) {
criterion.trigger().addPlayerListener(this, new CriterionTrigger.Listener<>(criterion.triggerInstance(), holder, key));
}
private void unregisterListeners(AdvancementHolder holder) {
AdvancementProgress advancementProgress = this.getOrStartProgress(holder);
for (Entry<String, Criterion<?>> entry : holder.value().criteria().entrySet()) {
CriterionProgress criterionProgress = advancementProgress.getCriterion(entry.getKey());
if (criterionProgress != null && (criterionProgress.isDone() || advancementProgress.isDone())) {
this.removeListener(holder, entry.getKey(), entry.getValue());
}
}
}
private <T extends CriterionTriggerInstance> void removeListener(AdvancementHolder holder, String key, Criterion<T> criterion) {
criterion.trigger().removePlayerListener(this, new CriterionTrigger.Listener<>(criterion.triggerInstance(), holder, key));
}
public void flushDirty(ServerPlayer player, boolean showAdvancements) {
if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) {
Map<Identifier, AdvancementProgress> progress = new HashMap<>();
Set<AdvancementHolder> added = new HashSet<>();
Set<Identifier> removed = new HashSet<>();
for (AdvancementNode root : this.rootsToUpdate) {
this.updateTreeVisibility(root, added, removed);
}
this.rootsToUpdate.clear();
for (AdvancementHolder holder : this.progressChanged) {
if (this.visible.contains(holder)) {
progress.put(holder.id(), this.progress.get(holder));
}
}
this.progressChanged.clear();
if (!progress.isEmpty() || !added.isEmpty() || !removed.isEmpty()) {
player.connection.send(new ClientboundUpdateAdvancementsPacket(this.isFirstPacket, added, removed, progress, showAdvancements));
}
}
this.isFirstPacket = false;
}
public void setSelectedTab(@Nullable AdvancementHolder holder) {
AdvancementHolder old = this.lastSelectedTab;
if (holder != null && holder.value().isRoot() && holder.value().display().isPresent()) {
this.lastSelectedTab = holder;
} else {
this.lastSelectedTab = null;
}
if (old != this.lastSelectedTab) {
this.player.connection.send(new ClientboundSelectAdvancementsTabPacket(this.lastSelectedTab == null ? null : this.lastSelectedTab.id()));
}
}
public AdvancementProgress getOrStartProgress(AdvancementHolder advancement) {
AdvancementProgress progress = this.progress.get(advancement);
if (progress == null) {
progress = new AdvancementProgress();
this.startProgress(advancement, progress);
}
return progress;
}
private void startProgress(AdvancementHolder holder, AdvancementProgress progress) {
progress.update(holder.value().requirements());
this.progress.put(holder, progress);
}
private void updateTreeVisibility(AdvancementNode root, Set<AdvancementHolder> added, Set<Identifier> removed) {
AdvancementVisibilityEvaluator.evaluateVisibility(root, node -> this.getOrStartProgress(node.holder()).isDone(), (node, shouldBeVisible) -> {
AdvancementHolder advancement = node.holder();
if (shouldBeVisible) {
if (this.visible.add(advancement)) {
added.add(advancement);
if (this.progress.containsKey(advancement)) {
this.progressChanged.add(advancement);
}
}
} else if (this.visible.remove(advancement)) {
removed.add(advancement.id());
}
});
}
private record Data(Map<Identifier, AdvancementProgress> map) {
public static final Codec<PlayerAdvancements.Data> CODEC = Codec.unboundedMap(Identifier.CODEC, AdvancementProgress.CODEC)
.xmap(PlayerAdvancements.Data::new, PlayerAdvancements.Data::map);
public void forEach(BiConsumer<Identifier, AdvancementProgress> consumer) {
this.map.entrySet().stream().sorted(Entry.comparingByValue()).forEach(entry -> consumer.accept(entry.getKey(), entry.getValue()));
}
}
}引用的其他类
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段/构造调用/返回值 - 关联成员:
AdvancementProgress()
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
ClientboundSelectAdvancementsTabPacket
- 引用位置:
构造调用 - 关联成员:
ClientboundSelectAdvancementsTabPacket()
- 引用位置:
-
ClientboundUpdateAdvancementsPacket
- 引用位置:
构造调用 - 关联成员:
ClientboundUpdateAdvancementsPacket()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
AdvancementVisibilityEvaluator
- 引用位置:
方法调用 - 关联成员:
AdvancementVisibilityEvaluator.evaluateVisibility()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
FileUtil.createDirectoriesSafe()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
StrictJsonParser.parse()
- 引用位置: