Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to 1.20.5 #58

Merged
merged 2 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,46 +1,14 @@
package xyz.nucleoid.server.translations.api;

import xyz.nucleoid.server.translations.api.language.ServerLanguage;
import xyz.nucleoid.server.translations.impl.LocalizableText;
import xyz.nucleoid.server.translations.impl.nbt.StackNbtLocalizer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import org.jetbrains.annotations.Nullable;
import xyz.nucleoid.server.translations.api.language.ServerLanguage;
import xyz.nucleoid.server.translations.impl.LocalizableText;

public final class Localization {
private Localization() {}

@Nullable
public static NbtCompound itemStackNbt(ItemStack stack, ServerPlayerEntity target) {
return itemStackNbt(stack, LocalizationTarget.of(target));
}

@Nullable
public static NbtCompound itemStackNbt(ItemStack stack, LocalizationTarget target) {
return itemStackNbt(stack, target.getLanguage());
}

@Nullable
public static NbtCompound itemStackNbt(ItemStack stack, ServerLanguage language) {
return StackNbtLocalizer.localize(stack, stack.getNbt(), language);
}

public static ItemStack itemStack(ItemStack stack, ServerPlayerEntity target) {
return itemStack(stack, LocalizationTarget.of(target));
}

public static ItemStack itemStack(ItemStack stack, LocalizationTarget target) {
return itemStack(stack, target.getLanguage());
}

public static ItemStack itemStack(ItemStack stack, ServerLanguage language) {
var copy = stack.copy();
copy.setNbt(StackNbtLocalizer.localize(copy, copy.getNbt(), language));
return copy;
}

public static Text text(Text text, ServerPlayerEntity target) {
return text(text, LocalizationTarget.of(target));
}
Expand All @@ -50,19 +18,7 @@ public static Text text(Text text, LocalizationTarget target) {
}

public static Text text(Text text, ServerLanguage language) {
return text(text, language, true);
}

public static Text text(Text text, ServerPlayerEntity target, boolean deep) {
return text(text, LocalizationTarget.of(target), deep);
}

public static Text text(Text text, LocalizationTarget target, boolean deep) {
return text(text, target.getLanguage(), deep);
}

public static Text text(Text text, ServerLanguage language, boolean deep) {
return LocalizableText.asLocalizedFor(text, language, deep);
return LocalizableText.asLocalizedFor(text, language);
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,92 +1,30 @@
package xyz.nucleoid.server.translations.impl;

import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtOps;
import net.minecraft.text.*;
import xyz.nucleoid.server.translations.api.language.ServerLanguage;
import xyz.nucleoid.server.translations.impl.nbt.StackNbtLocalizer;
import net.minecraft.text.HoverEvent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableTextContent;

import java.util.Optional;

public interface LocalizableText extends Text {
boolean stapi$isLocalized();

void stapi$setLocalized(boolean value);
public interface LocalizableText {

static Text asLocalizedFor(final Text text, final ServerLanguage language, final boolean translateDeeply) {
if (isTranslatable(text, translateDeeply)) {
var content = text.getContent();

if (content instanceof TranslatableTextContent translatableContent) {
var args = translatableContent.getArgs();

if (translateDeeply) {
args = new Object[translatableContent.getArgs().length];
for (int i = 0; i < args.length; i++) {
var arg = translatableContent.getArgs()[i];
if (arg instanceof Text argText) {
args[i] = asLocalizedFor(argText, language, true);
} else {
args[i] = arg;
}
}
}

content = new TranslatableTextContent(translatableContent.getKey(),
translatableContent.getFallback() == null && language.serverTranslations().contains(translatableContent.getKey())
? language.serverTranslations().get(translatableContent.getKey()) : translatableContent.getFallback(), args
);
}

var out = MutableText.of(content);
if (translateDeeply) {
for (var sibling : text.getSiblings()) {
out.append(asLocalizedFor(sibling, language, true));
}
} else {
out.getSiblings().addAll(text.getSiblings());
}

var style = text.getStyle();

if (style.getHoverEvent() != null) {
if (translateDeeply && style.getHoverEvent().getAction() == HoverEvent.Action.SHOW_TEXT) {
style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, asLocalizedFor(style.getHoverEvent().getValue(HoverEvent.Action.SHOW_TEXT), language, true)));
} else if (style.getHoverEvent().getAction() == HoverEvent.Action.SHOW_ITEM) {
var value = style.getHoverEvent().getValue(HoverEvent.Action.SHOW_ITEM);
var stack = value.asStack();
stack.setNbt(StackNbtLocalizer.localize(stack, stack.getNbt(), language));
style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new HoverEvent.ItemStackContent(stack)));
} else if (translateDeeply && style.getHoverEvent().getAction() == HoverEvent.Action.SHOW_ENTITY) {
var value = style.getHoverEvent().getValue(HoverEvent.Action.SHOW_ENTITY);
if (value.name.isPresent()) {
style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ENTITY, new HoverEvent.EntityContent(value.entityType, value.uuid, asLocalizedFor(value.name.get(), language, true))));
}
}
}

((LocalizableText) out).stapi$setLocalized(true);
return out.setStyle(style);
static Text asLocalizedFor(final Text text, final ServerLanguage language) {
// TODO 1.20.5 Not tested
// Encode to *any* intermediary format to apply the translation steps from TranslatableTextContentMixin to all translation text codecs
var dynamicOps = NbtOps.INSTANCE;
Optional<NbtElement> optionalNbt = TextCodecs.CODEC.encodeStart(dynamicOps, text).result();
if (optionalNbt.isEmpty()) {
// Failed to encode text, shouldn't happen
return text;
}

return text;
// Decode back
ServerTranslations.TRANSLATION_CONTEXT.set(language);
Optional<Text> optionalText = TextCodecs.CODEC.parse(dynamicOps, optionalNbt.get()).result();
ServerTranslations.TRANSLATION_CONTEXT.remove();
// Failed to decode text, shouldn't happen
return optionalText.orElse(text);
}

static boolean isTranslatable(Text text, boolean deepLocalization) {
if (deepLocalization) {
for (var x : text.getSiblings()) {
if (isTranslatable(x, true)) {
return true;
}
}

if (text.getStyle().getHoverEvent() != null) {
return true;
}
}

return (text instanceof LocalizableText localizableText && !localizableText.stapi$isLocalized())
&& (text.getContent() instanceof TranslatableTextContent
|| (text.getStyle().getHoverEvent() != null && text.getStyle().getHoverEvent().getAction() == HoverEvent.Action.SHOW_ITEM));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public final class ServerTranslations implements IdentifiableResourceReloadListe
public static final Logger LOGGER = LogUtils.getLogger();

public static final ServerTranslations INSTANCE = new ServerTranslations();
public static final ThreadLocal<ServerLanguage> TRANSLATION_CONTEXT = ThreadLocal.withInitial(() -> null);

private final SortedMap<String, ServerLanguageDefinition> supportedLanguages = new Object2ObjectRBTreeMap<>();

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtList;
import net.minecraft.nbt.NbtString;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.text.Text;
import xyz.nucleoid.server.translations.api.Localization;
import xyz.nucleoid.server.translations.api.LocalizationTarget;
Expand Down Expand Up @@ -35,7 +36,7 @@ private static void updateSide(NbtCompound nbt, LocalizationTarget target) {

private static void updateLines(NbtList messages, LocalizationTarget target) {
for (int i = 0; i < messages.size(); i++) {
messages.set(i, NbtString.of(Text.Serialization.toJsonString(Localization.text(Text.Serialization.fromLenientJson(messages.getString(i)), target))));
messages.set(i, NbtString.of(Text.Serialization.toJsonString(Localization.text(Text.Serialization.fromLenientJson(messages.getString(i), DynamicRegistryManager.EMPTY), target), DynamicRegistryManager.EMPTY)));
}
}
}
Loading