TranslatableContents.java

net.minecraft.network.chat.contents.TranslatableContents

信息

  • 全限定名:net.minecraft.network.chat.contents.TranslatableContents
  • 类型:public class
  • 包:net.minecraft.network.chat.contents
  • 源码路径:src/main/java/net/minecraft/network/chat/contents/TranslatableContents.java
  • 起始行号:L30
  • 实现:ComponentContents
  • 职责:

    TODO

字段/常量

  • NO_ARGS

    • 类型: Object[]
    • 修饰符: public static final
    • 源码定位: L31
    • 说明:

      TODO

  • PRIMITIVE_ARG_CODEC

    • 类型: Codec<Object>
    • 修饰符: private static final
    • 源码定位: L32
    • 说明:

      TODO

  • ARG_CODEC

    • 类型: Codec<Object>
    • 修饰符: private static final
    • 源码定位: L33
    • 说明:

      TODO

  • MAP_CODEC

    • 类型: MapCodec<TranslatableContents>
    • 修饰符: public static final
    • 源码定位: L38
    • 说明:

      TODO

  • TEXT_PERCENT

    • 类型: FormattedText
    • 修饰符: private static final
    • 源码定位: L46
    • 说明:

      TODO

  • TEXT_NULL

    • 类型: FormattedText
    • 修饰符: private static final
    • 源码定位: L47
    • 说明:

      TODO

  • key

    • 类型: String
    • 修饰符: private final
    • 源码定位: L48
    • 说明:

      TODO

  • fallback

    • 类型: String
    • 修饰符: private final
    • 源码定位: L49
    • 说明:

      TODO

  • args

    • 类型: Object[]
    • 修饰符: private final
    • 源码定位: L50
    • 说明:

      TODO

  • decomposedWith

    • 类型: Language
    • 修饰符: private
    • 源码定位: L51
    • 说明:

      TODO

  • decomposedParts

    • 类型: List<FormattedText>
    • 修饰符: private
    • 源码定位: L52
    • 说明:

      TODO

  • FORMAT_PATTERN

    • 类型: Pattern
    • 修饰符: private static final
    • 源码定位: L53
    • 说明:

      TODO

内部类/嵌套类型

构造器

public TranslatableContents(String key, String fallback, Object[] args) @ L75

  • 构造器名:TranslatableContents
  • 源码定位:L75
  • 修饰符:public

参数:

  • key: String
  • fallback: String
  • args: Object[]

说明:

TODO

方法

下面的方法块按源码顺序生成。

private static DataResult<Object> filterAllowedArguments(Object result) @ L55

  • 方法名:filterAllowedArguments
  • 源码定位:L55
  • 返回类型:DataResult
  • 修饰符:private static
  • 参数:

    • result: Object

    说明:

    TODO

    public static boolean isAllowedPrimitiveArgument(Object object) @ L59

    • 方法名:isAllowedPrimitiveArgument
    • 源码定位:L59
    • 返回类型:boolean
    • 修饰符:public static

    参数:

    • object: Object

    说明:

    TODO

    private static Optional<List<Object>> adjustArgs(Object[] args) @ L63

    • 方法名:adjustArgs
    • 源码定位:L63
    • 返回类型:Optional<List>
    • 修饰符:private static
    • 参数:

      • args: Object[]

      说明:

      TODO

      private static Object[] adjustArgs(Optional<List<Object>> args) @ L67

      • 方法名:adjustArgs
      • 源码定位:L67
      • 返回类型:Object[]
      • 修饰符:private static

      参数:

      • args: Optional<List>

        说明:

        TODO

        private static TranslatableContents create(String key, Optional<String> fallback, Optional<List<Object>> args) @ L71

        • 方法名:create
        • 源码定位:L71
        • 返回类型:TranslatableContents
        • 修饰符:private static

        参数:

        • key: String
        • fallback: Optional
        • args: Optional<List>

          说明:

          TODO

          public MapCodec<TranslatableContents> codec() @ L81

          • 方法名:codec
          • 源码定位:L81
          • 返回类型:MapCodec
          • 修饰符:public

          参数:

          说明:

          TODO

          private void decompose() @ L86

          • 方法名:decompose
          • 源码定位:L86
          • 返回类型:void
          • 修饰符:private

          参数:

          说明:

          TODO

          private void decomposeTemplate(String template, Consumer<FormattedText> decomposedParts) @ L102

          • 方法名:decomposeTemplate
          • 源码定位:L102
          • 返回类型:void
          • 修饰符:private

          参数:

          • template: String
          • decomposedParts: Consumer

          说明:

          TODO

          private FormattedText getArgument(int index) @ L151

          • 方法名:getArgument
          • 源码定位:L151
          • 返回类型:FormattedText
          • 修饰符:private

          参数:

          • index: int

          说明:

          TODO

          public <T> Optional<T> visit(FormattedText.StyledContentConsumer<T> output, Style currentStyle) @ L164

          • 方法名:visit
          • 源码定位:L164
          • 返回类型: Optional
          • 修饰符:public

          参数:

          • output: FormattedText.StyledContentConsumer
          • currentStyle: Style

          说明:

          TODO

          public <T> Optional<T> visit(FormattedText.ContentConsumer<T> output) @ L178

          • 方法名:visit
          • 源码定位:L178
          • 返回类型: Optional
          • 修饰符:public

          参数:

          • output: FormattedText.ContentConsumer

          说明:

          TODO

          public MutableComponent resolve(ResolutionContext context, int recursionDepth) @ L192

          • 方法名:resolve
          • 源码定位:L192
          • 返回类型:MutableComponent
          • 修饰符:public

          参数:

          • context: ResolutionContext
          • recursionDepth: int

          说明:

          TODO

          public boolean equals(Object o) @ L208

          • 方法名:equals
          • 源码定位:L208
          • 返回类型:boolean
          • 修饰符:public

          参数:

          • o: Object

          说明:

          TODO

          public int hashCode() @ L218

          • 方法名:hashCode
          • 源码定位:L218
          • 返回类型:int
          • 修饰符:public

          参数:

          说明:

          TODO

          public String toString() @ L225

          • 方法名:toString
          • 源码定位:L225
          • 返回类型:String
          • 修饰符:public

          参数:

          说明:

          TODO

          public String getKey() @ L236

          • 方法名:getKey
          • 源码定位:L236
          • 返回类型:String
          • 修饰符:public

          参数:

          说明:

          TODO

          public String getFallback() @ L240

          • 方法名:getFallback
          • 源码定位:L240
          • 返回类型:String
          • 修饰符:public

          参数:

          说明:

          TODO

          public Object[] getArgs() @ L244

          • 方法名:getArgs
          • 源码定位:L244
          • 返回类型:Object[]
          • 修饰符:public

          参数:

          说明:

          TODO

          代码

          public class TranslatableContents implements ComponentContents {
              public static final Object[] NO_ARGS = new Object[0];
              private static final Codec<Object> PRIMITIVE_ARG_CODEC = ExtraCodecs.JAVA.validate(TranslatableContents::filterAllowedArguments);
              private static final Codec<Object> ARG_CODEC = Codec.either(PRIMITIVE_ARG_CODEC, ComponentSerialization.CODEC)
                  .xmap(
                      e -> e.map(o -> o, component -> Objects.requireNonNullElse(component.tryCollapseToString(), component)),
                      o -> o instanceof Component c ? Either.right(c) : Either.left(o)
                  );
              public static final MapCodec<TranslatableContents> MAP_CODEC = RecordCodecBuilder.mapCodec(
                  i -> i.group(
                          Codec.STRING.fieldOf("translate").forGetter(o -> o.key),
                          Codec.STRING.lenientOptionalFieldOf("fallback").forGetter(o -> Optional.ofNullable(o.fallback)),
                          ARG_CODEC.listOf().optionalFieldOf("with").forGetter(o -> adjustArgs(o.args))
                      )
                      .apply(i, TranslatableContents::create)
              );
              private static final FormattedText TEXT_PERCENT = FormattedText.of("%");
              private static final FormattedText TEXT_NULL = FormattedText.of("null");
              private final String key;
              private final @Nullable String fallback;
              private final Object[] args;
              private @Nullable Language decomposedWith;
              private List<FormattedText> decomposedParts = ImmutableList.of();
              private static final Pattern FORMAT_PATTERN = Pattern.compile("%(?:(\\d+)\\$)?([A-Za-z%]|$)");
           
              private static DataResult<Object> filterAllowedArguments(@Nullable Object result) {
                  return !isAllowedPrimitiveArgument(result) ? DataResult.error(() -> "This value needs to be parsed as component") : DataResult.success(result);
              }
           
              public static boolean isAllowedPrimitiveArgument(@Nullable Object object) {
                  return object instanceof Number || object instanceof Boolean || object instanceof String;
              }
           
              private static Optional<List<Object>> adjustArgs(Object[] args) {
                  return args.length == 0 ? Optional.empty() : Optional.of(Arrays.asList(args));
              }
           
              private static Object[] adjustArgs(Optional<List<Object>> args) {
                  return args.<Object[]>map(a -> a.isEmpty() ? NO_ARGS : a.toArray()).orElse(NO_ARGS);
              }
           
              private static TranslatableContents create(String key, Optional<String> fallback, Optional<List<Object>> args) {
                  return new TranslatableContents(key, fallback.orElse(null), adjustArgs(args));
              }
           
              public TranslatableContents(String key, @Nullable String fallback, Object[] args) {
                  this.key = key;
                  this.fallback = fallback;
                  this.args = args;
              }
           
              @Override
              public MapCodec<TranslatableContents> codec() {
                  return MAP_CODEC;
              }
           
              private void decompose() {
                  Language currentLanguage = Language.getInstance();
                  if (currentLanguage != this.decomposedWith) {
                      this.decomposedWith = currentLanguage;
                      String format = this.fallback != null ? currentLanguage.getOrDefault(this.key, this.fallback) : currentLanguage.getOrDefault(this.key);
           
                      try {
                          Builder<FormattedText> parts = ImmutableList.builder();
                          this.decomposeTemplate(format, parts::add);
                          this.decomposedParts = parts.build();
                      } catch (TranslatableFormatException var4) {
                          this.decomposedParts = ImmutableList.of(FormattedText.of(format));
                      }
                  }
              }
           
              private void decomposeTemplate(String template, Consumer<FormattedText> decomposedParts) {
                  Matcher matcher = FORMAT_PATTERN.matcher(template);
           
                  try {
                      int replacementIndex = 0;
                      int current = 0;
           
                      while (matcher.find(current)) {
                          int start = matcher.start();
                          int end = matcher.end();
                          if (start > current) {
                              String prefix = template.substring(current, start);
                              if (prefix.indexOf(37) != -1) {
                                  throw new IllegalArgumentException();
                              }
           
                              decomposedParts.accept(FormattedText.of(prefix));
                          }
           
                          String formatType = matcher.group(2);
                          String formatString = template.substring(start, end);
                          if ("%".equals(formatType) && "%%".equals(formatString)) {
                              decomposedParts.accept(TEXT_PERCENT);
                          } else {
                              if (!"s".equals(formatType)) {
                                  throw new TranslatableFormatException(this, "Unsupported format: '" + formatString + "'");
                              }
           
                              String possiblePositionIndex = matcher.group(1);
                              int index = possiblePositionIndex != null ? Integer.parseInt(possiblePositionIndex) - 1 : replacementIndex++;
                              decomposedParts.accept(this.getArgument(index));
                          }
           
                          current = end;
                      }
           
                      if (current < template.length()) {
                          String tail = template.substring(current);
                          if (tail.indexOf(37) != -1) {
                              throw new IllegalArgumentException();
                          }
           
                          decomposedParts.accept(FormattedText.of(tail));
                      }
                  } catch (IllegalArgumentException var12) {
                      throw new TranslatableFormatException(this, var12);
                  }
              }
           
              private FormattedText getArgument(int index) {
                  if (index >= 0 && index < this.args.length) {
                      Object arg = this.args[index];
                      if (arg instanceof Component componentArg) {
                          return componentArg;
                      } else {
                          return arg == null ? TEXT_NULL : FormattedText.of(arg.toString());
                      }
                  } else {
                      throw new TranslatableFormatException(this, index);
                  }
              }
           
              @Override
              public <T> Optional<T> visit(FormattedText.StyledContentConsumer<T> output, Style currentStyle) {
                  this.decompose();
           
                  for (FormattedText part : this.decomposedParts) {
                      Optional<T> result = part.visit(output, currentStyle);
                      if (result.isPresent()) {
                          return result;
                      }
                  }
           
                  return Optional.empty();
              }
           
              @Override
              public <T> Optional<T> visit(FormattedText.ContentConsumer<T> output) {
                  this.decompose();
           
                  for (FormattedText part : this.decomposedParts) {
                      Optional<T> result = part.visit(output);
                      if (result.isPresent()) {
                          return result;
                      }
                  }
           
                  return Optional.empty();
              }
           
              @Override
              public MutableComponent resolve(ResolutionContext context, int recursionDepth) throws CommandSyntaxException {
                  Object[] argsCopy = new Object[this.args.length];
           
                  for (int i = 0; i < argsCopy.length; i++) {
                      Object param = this.args[i];
                      if (param instanceof Component component) {
                          argsCopy[i] = ComponentUtils.resolve(context, component, recursionDepth);
                      } else {
                          argsCopy[i] = param;
                      }
                  }
           
                  return MutableComponent.create(new TranslatableContents(this.key, this.fallback, argsCopy));
              }
           
              @Override
              public boolean equals(Object o) {
                  return this == o
                      ? true
                      : o instanceof TranslatableContents that
                          && Objects.equals(this.key, that.key)
                          && Objects.equals(this.fallback, that.fallback)
                          && Arrays.equals(this.args, that.args);
              }
           
              @Override
              public int hashCode() {
                  int result = Objects.hashCode(this.key);
                  result = 31 * result + Objects.hashCode(this.fallback);
                  return 31 * result + Arrays.hashCode(this.args);
              }
           
              @Override
              public String toString() {
                  return "translation{key='"
                      + this.key
                      + "'"
                      + (this.fallback != null ? ", fallback='" + this.fallback + "'" : "")
                      + ", args="
                      + Arrays.toString(this.args)
                      + "}";
              }
           
              public String getKey() {
                  return this.key;
              }
           
              public @Nullable String getFallback() {
                  return this.fallback;
              }
           
              public Object[] getArgs() {
                  return this.args;
              }
          }

          引用的其他类