Code/net/minecraft/util/datafix/fixes/TextComponentHoverAndClickE...

166 lines
7.0 KiB
Java
Raw Permalink Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.util.datafix.fixes;
import com.mojang.datafixers.DSL;
import com.mojang.datafixers.DataFix;
import com.mojang.datafixers.TypeRewriteRule;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.datafixers.types.Type;
import com.mojang.datafixers.util.Either;
import com.mojang.datafixers.util.Pair;
import com.mojang.datafixers.util.Unit;
import com.mojang.serialization.Dynamic;
import com.mojang.serialization.DynamicOps;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import javax.annotation.Nullable;
import net.minecraft.Util;
import net.minecraft.util.datafix.ExtraDataFixUtils;
public class TextComponentHoverAndClickEventFix extends DataFix {
public TextComponentHoverAndClickEventFix(Schema p_392221_) {
super(p_392221_, true);
}
@Override
protected TypeRewriteRule makeRule() {
Type<? extends Pair<String, ?>> type = (Type<? extends Pair<String, ?>>)this.getInputSchema().getType(References.TEXT_COMPONENT).findFieldType("hoverEvent");
return this.createFixer(this.getInputSchema().getTypeRaw(References.TEXT_COMPONENT), this.getOutputSchema().getType(References.TEXT_COMPONENT), type);
}
private <C1, C2, H extends Pair<String, ?>> TypeRewriteRule createFixer(Type<C1> p_394191_, Type<C2> p_396398_, Type<H> p_393938_) {
Type<Pair<String, Either<Either<String, List<C1>>, Pair<Either<List<C1>, Unit>, Pair<Either<C1, Unit>, Pair<Either<H, Unit>, Dynamic<?>>>>>>> type = DSL.named(
References.TEXT_COMPONENT.typeName(),
DSL.or(
DSL.or(DSL.string(), DSL.list(p_394191_)),
DSL.and(
DSL.optional(DSL.field("extra", DSL.list(p_394191_))),
DSL.optional(DSL.field("separator", p_394191_)),
DSL.optional(DSL.field("hoverEvent", p_393938_)),
DSL.remainderType()
)
)
);
if (!type.equals(this.getInputSchema().getType(References.TEXT_COMPONENT))) {
throw new IllegalStateException(
"Text component type did not match, expected " + type + " but got " + this.getInputSchema().getType(References.TEXT_COMPONENT)
);
} else {
Type<?> type1 = ExtraDataFixUtils.patchSubType(type, type, p_396398_);
return this.fixTypeEverywhere(
"TextComponentHoverAndClickEventFix",
type,
p_396398_,
p_392390_ -> p_396871_ -> {
boolean flag = p_396871_.getSecond().map(p_396868_ -> false, p_392755_ -> {
Pair<Either<H, Unit>, Dynamic<?>> pair = p_392755_.getSecond().getSecond();
boolean flag1 = pair.getFirst().left().isPresent();
boolean flag2 = pair.getSecond().get("clickEvent").result().isPresent();
return flag1 || flag2;
});
return (C2)(!flag
? p_396871_
: Util.writeAndReadTypedOrThrow(ExtraDataFixUtils.cast(type1, p_396871_, p_392390_), p_396398_, TextComponentHoverAndClickEventFix::fixTextComponent)
.getValue());
}
);
}
}
private static Dynamic<?> fixTextComponent(Dynamic<?> p_393778_) {
return p_393778_.renameAndFixField("hoverEvent", "hover_event", TextComponentHoverAndClickEventFix::fixHoverEvent)
.renameAndFixField("clickEvent", "click_event", TextComponentHoverAndClickEventFix::fixClickEvent);
}
private static Dynamic<?> copyFields(Dynamic<?> p_394161_, Dynamic<?> p_393015_, String... p_396190_) {
for (String s : p_396190_) {
p_394161_ = Dynamic.copyField(p_393015_, s, p_394161_, s);
}
return p_394161_;
}
private static Dynamic<?> fixHoverEvent(Dynamic<?> p_393225_) {
String s = p_393225_.get("action").asString("");
return switch (s) {
case "show_text" -> p_393225_.renameField("contents", "value");
case "show_item" -> {
Dynamic<?> dynamic1 = p_393225_.get("contents").orElseEmptyMap();
Optional<String> optional = dynamic1.asString().result();
yield optional.isPresent()
? p_393225_.renameField("contents", "id")
: copyFields(p_393225_.remove("contents"), dynamic1, "id", "count", "components");
}
case "show_entity" -> {
Dynamic<?> dynamic = p_393225_.get("contents").orElseEmptyMap();
yield copyFields(p_393225_.remove("contents"), dynamic, "id", "type", "name").renameField("id", "uuid").renameField("type", "id");
}
default -> p_393225_;
};
}
@Nullable
private static <T> Dynamic<T> fixClickEvent(Dynamic<T> p_397814_) {
String s = p_397814_.get("action").asString("");
String s1 = p_397814_.get("value").asString("");
return switch (s) {
case "open_url" -> !validateUri(s1) ? null : p_397814_.renameField("value", "url");
case "open_file" -> p_397814_.renameField("value", "path");
case "run_command", "suggest_command" -> !validateChat(s1) ? null : p_397814_.renameField("value", "command");
case "change_page" -> {
Integer integer = p_397814_.get("value").result().map(TextComponentHoverAndClickEventFix::parseOldPage).orElse(null);
if (integer == null) {
yield null;
} else {
int i = Math.max(integer, 1);
yield p_397814_.remove("value").set("page", p_397814_.createInt(i));
}
}
default -> p_397814_;
};
}
@Nullable
private static Integer parseOldPage(Dynamic<?> p_396464_) {
Optional<Number> optional = p_396464_.asNumber().result();
if (optional.isPresent()) {
return optional.get().intValue();
} else {
try {
return Integer.parseInt(p_396464_.asString(""));
} catch (Exception exception) {
return null;
}
}
}
private static boolean validateUri(String p_395339_) {
try {
URI uri = new URI(p_395339_);
String s = uri.getScheme();
if (s == null) {
return false;
} else {
String s1 = s.toLowerCase(Locale.ROOT);
return "http".equals(s1) || "https".equals(s1);
}
} catch (URISyntaxException urisyntaxexception) {
return false;
}
}
private static boolean validateChat(String p_394600_) {
for (int i = 0; i < p_394600_.length(); i++) {
char c0 = p_394600_.charAt(i);
if (c0 == 167 || c0 < ' ' || c0 == 127) {
return false;
}
}
return true;
}
}