9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-28 19:39:11 +00:00

添加advancement包替换

This commit is contained in:
XiaoMoMi
2025-07-11 22:51:47 +08:00
parent d3bbacbe84
commit aa4ef03255
21 changed files with 410 additions and 7 deletions

View File

@@ -0,0 +1,23 @@
package net.momirealms.craftengine.core.advancement;
public enum AdvancementType {
TASK("task"),
CHALLENGE("challenge"),
GOAL("goal"),;
private final String id;
AdvancementType(String id) {
this.id = id;
}
public String id() {
return id;
}
public static final AdvancementType[] VALUES = values();
public static AdvancementType byId(int id) {
return VALUES[id];
}
}

View File

@@ -0,0 +1,67 @@
package net.momirealms.craftengine.core.advancement.network;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.jetbrains.annotations.ApiStatus;
import java.util.Map;
import java.util.Optional;
public class Advancement {
private final Optional<Key> parent;
private final Optional<AdvancementDisplay> displayInfo;
// 1.20-1.20.1
private final Map<String, Void> criteria;
private final AdvancementRequirements requirements;
private final boolean sendsTelemetryEvent;
public Advancement(Optional<Key> parent, Optional<AdvancementDisplay> displayInfo, AdvancementRequirements requirements, boolean sendsTelemetryEvent) {
this.criteria = null;
this.displayInfo = displayInfo;
this.parent = parent;
this.requirements = requirements;
this.sendsTelemetryEvent = sendsTelemetryEvent;
}
@ApiStatus.Obsolete
public Advancement(Optional<Key> parent, Optional<AdvancementDisplay> displayInfo, Map<String, Void> criteria, AdvancementRequirements requirements, boolean sendsTelemetryEvent) {
this.criteria = criteria;
this.displayInfo = displayInfo;
this.parent = parent;
this.requirements = requirements;
this.sendsTelemetryEvent = sendsTelemetryEvent;
}
public static Advancement read(FriendlyByteBuf buf) {
Optional<Key> parent = buf.readOptional(FriendlyByteBuf::readKey);
Optional<AdvancementDisplay> displayInfo = buf.readOptional(byteBuf -> AdvancementDisplay.read(buf));
if (VersionHelper.isOrAbove1_20_2()) {
AdvancementRequirements requirements = AdvancementRequirements.read(buf);
boolean sendsTelemetryEvent = buf.readBoolean();
return new Advancement(parent, displayInfo, requirements, sendsTelemetryEvent);
} else {
Map<String, Void> criteria = buf.readMap(FriendlyByteBuf::readUtf, (byteBuf -> null));
AdvancementRequirements requirements = AdvancementRequirements.read(buf);
boolean sendsTelemetryEvent = buf.readBoolean();
return new Advancement(parent, displayInfo, criteria, requirements, sendsTelemetryEvent);
}
}
public void write(FriendlyByteBuf buf) {
buf.writeOptional(this.parent, FriendlyByteBuf::writeKey);
buf.writeOptional(this.displayInfo, (byteBuf, info) -> info.write(buf));
if (!VersionHelper.isOrAbove1_20_2()) {
buf.writeMap(this.criteria, FriendlyByteBuf::writeUtf, ((byteBuf, unused) -> {}));
}
this.requirements.write(buf);
buf.writeBoolean(this.sendsTelemetryEvent);
}
public void applyClientboundData(Player player) {
this.displayInfo.ifPresent(info -> info.applyClientboundData(player));
}
}

View File

@@ -0,0 +1,115 @@
package net.momirealms.craftengine.core.advancement.network;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.core.advancement.AdvancementType;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.util.AdventureHelper;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.sparrow.nbt.Tag;
import java.util.Map;
import java.util.Optional;
public class AdvancementDisplay {
public static final int FLAG_BACKGROUND = 0b001;
public static final int FLAG_SHOW_TOAST = 0b010;
public static final int FLAG_HIDDEN = 0b100;
private Component title;
private Component description;
private Item<Object> icon;
private Optional<Key> background;
private final AdvancementType type;
private final boolean showToast;
private final boolean hidden;
private float x;
private float y;
public AdvancementDisplay(Component title,
Component description,
Item<Object> icon,
Optional<Key> background,
AdvancementType type,
boolean showToast,
boolean hidden,
float x,
float y) {
this.type = type;
this.showToast = showToast;
this.hidden = hidden;
this.background = background;
this.description = description;
this.icon = icon;
this.title = title;
this.x = x;
this.y = y;
}
public void applyClientboundData(Player player) {
this.icon = CraftEngine.instance().itemManager().s2c(this.icon, player);
}
public void write(FriendlyByteBuf buf) {
buf.writeComponent(this.title);
buf.writeComponent(this.description);
CraftEngine.instance().itemManager().encode(buf, this.icon);
buf.writeVarInt(this.type.ordinal());
int flags = 0;
if (this.background.isPresent()) {
flags |= FLAG_BACKGROUND;
}
if (this.showToast) {
flags |= FLAG_SHOW_TOAST;
}
if (this.hidden) {
flags |= FLAG_HIDDEN;
}
buf.writeInt(flags);
this.background.ifPresent(buf::writeKey);
buf.writeFloat(this.x);
buf.writeFloat(this.y);
}
public static AdvancementDisplay read(FriendlyByteBuf buf) {
Component title = readComponent(buf);
Component description = readComponent(buf);
Item<Object> icon = CraftEngine.instance().itemManager().decode(buf);
AdvancementType type = AdvancementType.byId(buf.readVarInt());
int flags = buf.readInt();
boolean hasBackground = (flags & 1) != 0;
Optional<Key> background = hasBackground ? Optional.of(buf.readKey()) : Optional.empty();
boolean showToast = (flags & 2) != 0;
boolean hidden = (flags & 4) != 0;
float x = buf.readFloat();
float y = buf.readFloat();
return new AdvancementDisplay(title, description, icon, background, type, showToast, hidden, x, y);
}
private static Component readComponent(FriendlyByteBuf buf) {
if (Config.interceptAdvancement()) {
if (VersionHelper.isOrAbove1_20_3()) {
Tag nbt = buf.readNbt(false);
Map<String, Component> tokens = CraftEngine.instance().fontManager().matchTags(nbt.getAsString());
Component component = AdventureHelper.nbtToComponent(nbt);
if (!tokens.isEmpty()) {
component = AdventureHelper.replaceText(component, tokens);
}
return component;
} else {
String json = buf.readUtf();
Component component = AdventureHelper.jsonToComponent(json);
Map<String, Component> tokens = CraftEngine.instance().fontManager().matchTags(json);
if (!tokens.isEmpty()) {
component = AdventureHelper.replaceText(component, tokens);
}
return component;
}
} else {
return buf.readComponent();
}
}
}

View File

@@ -0,0 +1,23 @@
package net.momirealms.craftengine.core.advancement.network;
import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
import net.momirealms.craftengine.core.util.Key;
public record AdvancementHolder(Key id, Advancement advancement) {
public static AdvancementHolder read(FriendlyByteBuf buf) {
Key key = buf.readKey();
Advancement ad = Advancement.read(buf);
return new AdvancementHolder(key, ad);
}
public void write(FriendlyByteBuf buf) {
buf.writeKey(this.id);
this.advancement.write(buf);
}
public void applyClientboundData(Player player) {
this.advancement.applyClientboundData(player);
}
}

View File

@@ -0,0 +1,27 @@
package net.momirealms.craftengine.core.advancement.network;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
import java.util.HashMap;
import java.util.Map;
public class AdvancementProgress {
private final Map<String, CriterionProgress> progress;
public AdvancementProgress(Map<String, CriterionProgress> progress) {
this.progress = progress;
}
public AdvancementProgress() {
this.progress = new HashMap<>();
}
public void write(FriendlyByteBuf buf) {
buf.writeMap(this.progress, FriendlyByteBuf::writeUtf, ((byteBuf, criterionProgress) -> criterionProgress.write(buf)));
}
public static AdvancementProgress read(FriendlyByteBuf buf) {
Map<String, CriterionProgress> progress = buf.readMap(FriendlyByteBuf::readUtf, CriterionProgress::read);
return new AdvancementProgress(progress);
}
}

View File

@@ -0,0 +1,23 @@
package net.momirealms.craftengine.core.advancement.network;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
import java.util.ArrayList;
import java.util.List;
public class AdvancementRequirements {
public static final AdvancementRequirements EMPTY = new AdvancementRequirements(List.of());
private final List<List<String>> requirements;
public AdvancementRequirements(List<List<String>> requirements) {
this.requirements = requirements;
}
public void write(FriendlyByteBuf byteBuf) {
byteBuf.writeCollection(this.requirements, ((buf, strings) -> buf.writeCollection(strings, FriendlyByteBuf::writeUtf)));
}
public static AdvancementRequirements read(FriendlyByteBuf byteBuf) {
return new AdvancementRequirements(byteBuf.readCollection(ArrayList::new, buf -> buf.readCollection(ArrayList::new, FriendlyByteBuf::readUtf)));
}
}

View File

@@ -0,0 +1,42 @@
package net.momirealms.craftengine.core.advancement.network;
import net.momirealms.craftengine.core.util.FriendlyByteBuf;
import org.jetbrains.annotations.Nullable;
import java.time.Instant;
public class CriterionProgress {
@Nullable
private Instant obtainedTimestamp;
public CriterionProgress() {
}
public CriterionProgress(@Nullable Instant obtainedTimestamp) {
this.obtainedTimestamp = obtainedTimestamp;
}
public boolean isDone() {
return this.obtainedTimestamp != null;
}
public void grant() {
this.obtainedTimestamp = Instant.now();
}
public void revoke() {
this.obtainedTimestamp = null;
}
public @Nullable Instant obtainedTimestamp() {
return obtainedTimestamp;
}
public void write(FriendlyByteBuf buf) {
buf.writeNullable(this.obtainedTimestamp, FriendlyByteBuf::writeInstant);
}
public static CriterionProgress read(FriendlyByteBuf buf) {
return new CriterionProgress(buf.readNullable(FriendlyByteBuf::readInstant));
}
}

View File

@@ -150,6 +150,7 @@ public class Config {
protected boolean image$intercept_packets$player_info;
protected boolean image$intercept_packets$set_score;
protected boolean image$intercept_packets$item;
protected boolean image$intercept_packets$advancement;
protected boolean item$client_bound_model;
protected boolean item$non_italic_tag;
@@ -393,6 +394,7 @@ public class Config {
image$intercept_packets$player_info = config.getBoolean("image.intercept-packets.player-info", true);
image$intercept_packets$set_score = config.getBoolean("image.intercept-packets.set-score", true);
image$intercept_packets$item = config.getBoolean("image.intercept-packets.item", true);
image$intercept_packets$advancement = config.getBoolean("image.intercept-packets.advancement", true);
// emoji
emoji$chat = config.getBoolean("emoji.chat", true);
@@ -742,6 +744,10 @@ public class Config {
return instance.image$intercept_packets$item;
}
public static boolean interceptAdvancement() {
return instance.image$intercept_packets$advancement;
}
public static boolean predictBreaking() {
return instance.block$predict_breaking;
}

View File

@@ -11,6 +11,7 @@ import io.netty.handler.codec.EncoderException;
import io.netty.util.ByteProcessor;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.core.registry.Registry;
import net.momirealms.craftengine.core.world.BlockPos;
import net.momirealms.sparrow.nbt.NBT;
@@ -29,6 +30,7 @@ import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@@ -47,6 +49,30 @@ public class FriendlyByteBuf extends ByteBuf {
return source;
}
public Component readComponent() {
if (VersionHelper.isOrAbove1_20_3()) {
return AdventureHelper.nbtToComponent(this.readNbt(false));
} else {
return AdventureHelper.jsonToComponent(this.readUtf());
}
}
public void writeComponent(Component component) {
if (VersionHelper.isOrAbove1_20_3()) {
this.writeNbt(AdventureHelper.componentToNbt(component), false);
} else {
this.writeUtf(AdventureHelper.componentToJson(component));
}
}
public Instant readInstant() {
return Instant.ofEpochMilli(this.readLong());
}
public void writeInstant(Instant instant) {
this.writeLong(instant.toEpochMilli());
}
public <T, C extends Collection<T>> C readCollection(IntFunction<C> collectionFactory, Reader<T> reader) {
int i = this.readVarInt();
C collection = collectionFactory.apply(i);