minecraft-src/net/minecraft/network/chat/HoverEvent.java
2025-07-04 03:45:38 +03:00

159 lines
5.5 KiB
Java

package net.minecraft.network.chat;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.mojang.serialization.Lifecycle;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import net.minecraft.core.UUIDUtil;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
public interface HoverEvent {
Codec<HoverEvent> CODEC = HoverEvent.Action.CODEC.dispatch("action", HoverEvent::action, action -> action.codec);
HoverEvent.Action action();
public static enum Action implements StringRepresentable {
SHOW_TEXT("show_text", true, HoverEvent.ShowText.CODEC),
SHOW_ITEM("show_item", true, HoverEvent.ShowItem.CODEC),
SHOW_ENTITY("show_entity", true, HoverEvent.ShowEntity.CODEC);
public static final Codec<HoverEvent.Action> UNSAFE_CODEC = StringRepresentable.fromValues(HoverEvent.Action::values);
public static final Codec<HoverEvent.Action> CODEC = UNSAFE_CODEC.validate(HoverEvent.Action::filterForSerialization);
private final String name;
private final boolean allowFromServer;
final MapCodec<? extends HoverEvent> codec;
private Action(final String name, final boolean allowFromServer, final MapCodec<? extends HoverEvent> codec) {
this.name = name;
this.allowFromServer = allowFromServer;
this.codec = codec;
}
/**
* Indicates whether this event can be run from chat text.
*/
public boolean isAllowedFromServer() {
return this.allowFromServer;
}
@Override
public String getSerializedName() {
return this.name;
}
public String toString() {
return "<action " + this.name + ">";
}
private static DataResult<HoverEvent.Action> filterForSerialization(HoverEvent.Action action) {
return !action.isAllowedFromServer() ? DataResult.error(() -> "Action not allowed: " + action) : DataResult.success(action, Lifecycle.stable());
}
}
public static class EntityTooltipInfo {
public static final MapCodec<HoverEvent.EntityTooltipInfo> CODEC = RecordCodecBuilder.mapCodec(
instance -> instance.group(
BuiltInRegistries.ENTITY_TYPE.byNameCodec().fieldOf("id").forGetter(entityTooltipInfo -> entityTooltipInfo.type),
UUIDUtil.LENIENT_CODEC.fieldOf("uuid").forGetter(entityTooltipInfo -> entityTooltipInfo.uuid),
ComponentSerialization.CODEC.optionalFieldOf("name").forGetter(entityTooltipInfo -> entityTooltipInfo.name)
)
.apply(instance, HoverEvent.EntityTooltipInfo::new)
);
public final EntityType<?> type;
public final UUID uuid;
public final Optional<Component> name;
@Nullable
private List<Component> linesCache;
public EntityTooltipInfo(EntityType<?> type, UUID id, @Nullable Component name) {
this(type, id, Optional.ofNullable(name));
}
public EntityTooltipInfo(EntityType<?> type, UUID id, Optional<Component> name) {
this.type = type;
this.uuid = id;
this.name = name;
}
public List<Component> getTooltipLines() {
if (this.linesCache == null) {
this.linesCache = new ArrayList();
this.name.ifPresent(this.linesCache::add);
this.linesCache.add(Component.translatable("gui.entity_tooltip.type", this.type.getDescription()));
this.linesCache.add(Component.literal(this.uuid.toString()));
}
return this.linesCache;
}
public boolean equals(Object object) {
if (this == object) {
return true;
} else if (object != null && this.getClass() == object.getClass()) {
HoverEvent.EntityTooltipInfo entityTooltipInfo = (HoverEvent.EntityTooltipInfo)object;
return this.type.equals(entityTooltipInfo.type) && this.uuid.equals(entityTooltipInfo.uuid) && this.name.equals(entityTooltipInfo.name);
} else {
return false;
}
}
public int hashCode() {
int i = this.type.hashCode();
i = 31 * i + this.uuid.hashCode();
return 31 * i + this.name.hashCode();
}
}
public record ShowEntity(HoverEvent.EntityTooltipInfo entity) implements HoverEvent {
public static final MapCodec<HoverEvent.ShowEntity> CODEC = RecordCodecBuilder.mapCodec(
instance -> instance.group(HoverEvent.EntityTooltipInfo.CODEC.forGetter(HoverEvent.ShowEntity::entity)).apply(instance, HoverEvent.ShowEntity::new)
);
@Override
public HoverEvent.Action action() {
return HoverEvent.Action.SHOW_ENTITY;
}
}
public record ShowItem(ItemStack item) implements HoverEvent {
public static final MapCodec<HoverEvent.ShowItem> CODEC = ItemStack.MAP_CODEC.xmap(HoverEvent.ShowItem::new, HoverEvent.ShowItem::item);
public ShowItem(ItemStack item) {
item = item.copy();
this.item = item;
}
@Override
public HoverEvent.Action action() {
return HoverEvent.Action.SHOW_ITEM;
}
public boolean equals(Object object) {
return object instanceof HoverEvent.ShowItem showItem && ItemStack.matches(this.item, showItem.item);
}
public int hashCode() {
return ItemStack.hashItemAndComponents(this.item);
}
}
public record ShowText(Component value) implements HoverEvent {
public static final MapCodec<HoverEvent.ShowText> CODEC = RecordCodecBuilder.mapCodec(
instance -> instance.group(ComponentSerialization.CODEC.fieldOf("value").forGetter(HoverEvent.ShowText::value)).apply(instance, HoverEvent.ShowText::new)
);
@Override
public HoverEvent.Action action() {
return HoverEvent.Action.SHOW_TEXT;
}
}
}