base mod created
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
public enum ChatType
|
||||
{
|
||||
CHAT((byte)0),
|
||||
SYSTEM((byte)1),
|
||||
GAME_INFO((byte)2);
|
||||
|
||||
private final byte id;
|
||||
|
||||
private ChatType(byte id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public byte getId()
|
||||
{
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public static ChatType byId(byte idIn)
|
||||
{
|
||||
for (ChatType chattype : values())
|
||||
{
|
||||
if (idIn == chattype.id)
|
||||
{
|
||||
return chattype;
|
||||
}
|
||||
}
|
||||
|
||||
return CHAT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.util.EnumTypeAdapterFactory;
|
||||
import net.minecraft.util.JsonUtils;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
public interface ITextComponent extends Iterable<ITextComponent>
|
||||
{
|
||||
/**
|
||||
* Sets the style of this component and updates the parent style of all of the sibling components.
|
||||
*/
|
||||
ITextComponent setStyle(Style style);
|
||||
|
||||
/**
|
||||
* Gets the style of this component. Returns a direct reference; changes to this style will modify the style of this
|
||||
* component (IE, there is no need to call {@link #setStyle(Style)} again after modifying it).
|
||||
*
|
||||
* If this component's style is currently <code>null</code>, it will be initialized to the default style, and the
|
||||
* parent style of all sibling components will be set to that style. (IE, changes to this style will also be
|
||||
* reflected in sibling components.)
|
||||
*
|
||||
* This method never returns <code>null</code>.
|
||||
*/
|
||||
Style getStyle();
|
||||
|
||||
/**
|
||||
* Adds a new component to the end of the sibling list, with the specified text. Same as calling {@link
|
||||
* #appendSibling(ITextComponent)} with a new {@link TextComponentString}.
|
||||
*
|
||||
* @return This component, for chaining (and not the newly added component)
|
||||
*/
|
||||
ITextComponent appendText(String text);
|
||||
|
||||
/**
|
||||
* Adds a new component to the end of the sibling list, setting that component's style's parent style to this
|
||||
* component's style.
|
||||
*
|
||||
* @return This component, for chaining (and not the newly added component)
|
||||
*/
|
||||
ITextComponent appendSibling(ITextComponent component);
|
||||
|
||||
/**
|
||||
* Gets the raw content of this component (but not its sibling components), without any formatting codes. For
|
||||
* example, this is the raw text in a {@link TextComponentString}, but it's the translated text for a {@link
|
||||
* TextComponentTranslation} and it's the score value for a {@link TextComponentScore}.
|
||||
*/
|
||||
String getUnformattedComponentText();
|
||||
|
||||
/**
|
||||
* Gets the text of this component <em>and all sibling components</em>, without any formatting codes.
|
||||
*/
|
||||
String getUnformattedText();
|
||||
|
||||
/**
|
||||
* Gets the text of this component <em>and all sibling components</em>, with formatting codes added for rendering.
|
||||
*/
|
||||
String getFormattedText();
|
||||
|
||||
/**
|
||||
* Gets the sibling components of this one.
|
||||
*/
|
||||
List<ITextComponent> getSiblings();
|
||||
|
||||
/**
|
||||
* Creates a copy of this component. Almost a deep copy, except the style is shallow-copied.
|
||||
*/
|
||||
ITextComponent createCopy();
|
||||
|
||||
public static class Serializer implements JsonDeserializer<ITextComponent>, JsonSerializer<ITextComponent>
|
||||
{
|
||||
private static final Gson GSON;
|
||||
|
||||
public ITextComponent deserialize(JsonElement p_deserialize_1_, Type p_deserialize_2_, JsonDeserializationContext p_deserialize_3_) throws JsonParseException
|
||||
{
|
||||
if (p_deserialize_1_.isJsonPrimitive())
|
||||
{
|
||||
return new TextComponentString(p_deserialize_1_.getAsString());
|
||||
}
|
||||
else if (!p_deserialize_1_.isJsonObject())
|
||||
{
|
||||
if (p_deserialize_1_.isJsonArray())
|
||||
{
|
||||
JsonArray jsonarray1 = p_deserialize_1_.getAsJsonArray();
|
||||
ITextComponent itextcomponent1 = null;
|
||||
|
||||
for (JsonElement jsonelement : jsonarray1)
|
||||
{
|
||||
ITextComponent itextcomponent2 = this.deserialize(jsonelement, jsonelement.getClass(), p_deserialize_3_);
|
||||
|
||||
if (itextcomponent1 == null)
|
||||
{
|
||||
itextcomponent1 = itextcomponent2;
|
||||
}
|
||||
else
|
||||
{
|
||||
itextcomponent1.appendSibling(itextcomponent2);
|
||||
}
|
||||
}
|
||||
|
||||
return itextcomponent1;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonParseException("Don't know how to turn " + p_deserialize_1_ + " into a Component");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonObject jsonobject = p_deserialize_1_.getAsJsonObject();
|
||||
ITextComponent itextcomponent;
|
||||
|
||||
if (jsonobject.has("text"))
|
||||
{
|
||||
itextcomponent = new TextComponentString(jsonobject.get("text").getAsString());
|
||||
}
|
||||
else if (jsonobject.has("translate"))
|
||||
{
|
||||
String s = jsonobject.get("translate").getAsString();
|
||||
|
||||
if (jsonobject.has("with"))
|
||||
{
|
||||
JsonArray jsonarray = jsonobject.getAsJsonArray("with");
|
||||
Object[] aobject = new Object[jsonarray.size()];
|
||||
|
||||
for (int i = 0; i < aobject.length; ++i)
|
||||
{
|
||||
aobject[i] = this.deserialize(jsonarray.get(i), p_deserialize_2_, p_deserialize_3_);
|
||||
|
||||
if (aobject[i] instanceof TextComponentString)
|
||||
{
|
||||
TextComponentString textcomponentstring = (TextComponentString)aobject[i];
|
||||
|
||||
if (textcomponentstring.getStyle().isEmpty() && textcomponentstring.getSiblings().isEmpty())
|
||||
{
|
||||
aobject[i] = textcomponentstring.getText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
itextcomponent = new TextComponentTranslation(s, aobject);
|
||||
}
|
||||
else
|
||||
{
|
||||
itextcomponent = new TextComponentTranslation(s, new Object[0]);
|
||||
}
|
||||
}
|
||||
else if (jsonobject.has("score"))
|
||||
{
|
||||
JsonObject jsonobject1 = jsonobject.getAsJsonObject("score");
|
||||
|
||||
if (!jsonobject1.has("name") || !jsonobject1.has("objective"))
|
||||
{
|
||||
throw new JsonParseException("A score component needs a least a name and an objective");
|
||||
}
|
||||
|
||||
itextcomponent = new TextComponentScore(JsonUtils.getString(jsonobject1, "name"), JsonUtils.getString(jsonobject1, "objective"));
|
||||
|
||||
if (jsonobject1.has("value"))
|
||||
{
|
||||
((TextComponentScore)itextcomponent).setValue(JsonUtils.getString(jsonobject1, "value"));
|
||||
}
|
||||
}
|
||||
else if (jsonobject.has("selector"))
|
||||
{
|
||||
itextcomponent = new TextComponentSelector(JsonUtils.getString(jsonobject, "selector"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!jsonobject.has("keybind"))
|
||||
{
|
||||
throw new JsonParseException("Don't know how to turn " + p_deserialize_1_ + " into a Component");
|
||||
}
|
||||
|
||||
itextcomponent = new TextComponentKeybind(JsonUtils.getString(jsonobject, "keybind"));
|
||||
}
|
||||
|
||||
if (jsonobject.has("extra"))
|
||||
{
|
||||
JsonArray jsonarray2 = jsonobject.getAsJsonArray("extra");
|
||||
|
||||
if (jsonarray2.size() <= 0)
|
||||
{
|
||||
throw new JsonParseException("Unexpected empty array of components");
|
||||
}
|
||||
|
||||
for (int j = 0; j < jsonarray2.size(); ++j)
|
||||
{
|
||||
itextcomponent.appendSibling(this.deserialize(jsonarray2.get(j), p_deserialize_2_, p_deserialize_3_));
|
||||
}
|
||||
}
|
||||
|
||||
itextcomponent.setStyle((Style)p_deserialize_3_.deserialize(p_deserialize_1_, Style.class));
|
||||
return itextcomponent;
|
||||
}
|
||||
}
|
||||
|
||||
private void serializeChatStyle(Style style, JsonObject object, JsonSerializationContext ctx)
|
||||
{
|
||||
JsonElement jsonelement = ctx.serialize(style);
|
||||
|
||||
if (jsonelement.isJsonObject())
|
||||
{
|
||||
JsonObject jsonobject = (JsonObject)jsonelement;
|
||||
|
||||
for (Entry<String, JsonElement> entry : jsonobject.entrySet())
|
||||
{
|
||||
object.add(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JsonElement serialize(ITextComponent p_serialize_1_, Type p_serialize_2_, JsonSerializationContext p_serialize_3_)
|
||||
{
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
|
||||
if (!p_serialize_1_.getStyle().isEmpty())
|
||||
{
|
||||
this.serializeChatStyle(p_serialize_1_.getStyle(), jsonobject, p_serialize_3_);
|
||||
}
|
||||
|
||||
if (!p_serialize_1_.getSiblings().isEmpty())
|
||||
{
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
|
||||
for (ITextComponent itextcomponent : p_serialize_1_.getSiblings())
|
||||
{
|
||||
jsonarray.add(this.serialize(itextcomponent, itextcomponent.getClass(), p_serialize_3_));
|
||||
}
|
||||
|
||||
jsonobject.add("extra", jsonarray);
|
||||
}
|
||||
|
||||
if (p_serialize_1_ instanceof TextComponentString)
|
||||
{
|
||||
jsonobject.addProperty("text", ((TextComponentString)p_serialize_1_).getText());
|
||||
}
|
||||
else if (p_serialize_1_ instanceof TextComponentTranslation)
|
||||
{
|
||||
TextComponentTranslation textcomponenttranslation = (TextComponentTranslation)p_serialize_1_;
|
||||
jsonobject.addProperty("translate", textcomponenttranslation.getKey());
|
||||
|
||||
if (textcomponenttranslation.getFormatArgs() != null && textcomponenttranslation.getFormatArgs().length > 0)
|
||||
{
|
||||
JsonArray jsonarray1 = new JsonArray();
|
||||
|
||||
for (Object object : textcomponenttranslation.getFormatArgs())
|
||||
{
|
||||
if (object instanceof ITextComponent)
|
||||
{
|
||||
jsonarray1.add(this.serialize((ITextComponent)object, object.getClass(), p_serialize_3_));
|
||||
}
|
||||
else
|
||||
{
|
||||
jsonarray1.add(new JsonPrimitive(String.valueOf(object)));
|
||||
}
|
||||
}
|
||||
|
||||
jsonobject.add("with", jsonarray1);
|
||||
}
|
||||
}
|
||||
else if (p_serialize_1_ instanceof TextComponentScore)
|
||||
{
|
||||
TextComponentScore textcomponentscore = (TextComponentScore)p_serialize_1_;
|
||||
JsonObject jsonobject1 = new JsonObject();
|
||||
jsonobject1.addProperty("name", textcomponentscore.getName());
|
||||
jsonobject1.addProperty("objective", textcomponentscore.getObjective());
|
||||
jsonobject1.addProperty("value", textcomponentscore.getUnformattedComponentText());
|
||||
jsonobject.add("score", jsonobject1);
|
||||
}
|
||||
else if (p_serialize_1_ instanceof TextComponentSelector)
|
||||
{
|
||||
TextComponentSelector textcomponentselector = (TextComponentSelector)p_serialize_1_;
|
||||
jsonobject.addProperty("selector", textcomponentselector.getSelector());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(p_serialize_1_ instanceof TextComponentKeybind))
|
||||
{
|
||||
throw new IllegalArgumentException("Don't know how to serialize " + p_serialize_1_ + " as a Component");
|
||||
}
|
||||
|
||||
TextComponentKeybind textcomponentkeybind = (TextComponentKeybind)p_serialize_1_;
|
||||
jsonobject.addProperty("keybind", textcomponentkeybind.getKeybind());
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a component into JSON.
|
||||
*/
|
||||
public static String componentToJson(ITextComponent component)
|
||||
{
|
||||
return GSON.toJson(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a JSON string into a {@link ITextComponent}, with strict parsing.
|
||||
*
|
||||
* @see #fromJsonLenient(String)
|
||||
* @see {@link com.google.gson.stream.JsonReader#setLenient(boolean)}
|
||||
*/
|
||||
@Nullable
|
||||
public static ITextComponent jsonToComponent(String json)
|
||||
{
|
||||
return (ITextComponent)JsonUtils.gsonDeserialize(GSON, json, ITextComponent.class, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a JSON string into a {@link ITextComponent}, being lenient upon parse errors.
|
||||
*
|
||||
* @see #jsonToComponent(String)
|
||||
* @see {@link com.google.gson.stream.JsonReader#setLenient(boolean)}
|
||||
*/
|
||||
@Nullable
|
||||
public static ITextComponent fromJsonLenient(String json)
|
||||
{
|
||||
return (ITextComponent)JsonUtils.gsonDeserialize(GSON, json, ITextComponent.class, true);
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
GsonBuilder gsonbuilder = new GsonBuilder();
|
||||
gsonbuilder.registerTypeHierarchyAdapter(ITextComponent.class, new ITextComponent.Serializer());
|
||||
gsonbuilder.registerTypeHierarchyAdapter(Style.class, new Style.Serializer());
|
||||
gsonbuilder.registerTypeAdapterFactory(new EnumTypeAdapterFactory());
|
||||
GSON = gsonbuilder.create();
|
||||
}
|
||||
}
|
||||
}
|
||||
729
build/tmp/recompileMc/sources/net/minecraft/util/text/Style.java
Normal file
729
build/tmp/recompileMc/sources/net/minecraft/util/text/Style.java
Normal file
@@ -0,0 +1,729 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.util.text.event.ClickEvent;
|
||||
import net.minecraft.util.text.event.HoverEvent;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
public class Style
|
||||
{
|
||||
/** The parent of this ChatStyle. Used for looking up values that this instance does not override. */
|
||||
private Style parentStyle;
|
||||
private TextFormatting color;
|
||||
private Boolean bold;
|
||||
private Boolean italic;
|
||||
private Boolean underlined;
|
||||
private Boolean strikethrough;
|
||||
private Boolean obfuscated;
|
||||
private ClickEvent clickEvent;
|
||||
private HoverEvent hoverEvent;
|
||||
private String insertion;
|
||||
/** The base of the ChatStyle hierarchy. All ChatStyle instances are implicitly children of this. */
|
||||
private static final Style ROOT = new Style()
|
||||
{
|
||||
/**
|
||||
* Gets the effective color of this ChatStyle.
|
||||
*/
|
||||
@Nullable
|
||||
public TextFormatting getColor()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Whether or not text of this ChatStyle should be in bold.
|
||||
*/
|
||||
public boolean getBold()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Whether or not text of this ChatStyle should be italicized.
|
||||
*/
|
||||
public boolean getItalic()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Whether or not to format text of this ChatStyle using strikethrough.
|
||||
*/
|
||||
public boolean getStrikethrough()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Whether or not text of this ChatStyle should be underlined.
|
||||
*/
|
||||
public boolean getUnderlined()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Whether or not text of this ChatStyle should be obfuscated.
|
||||
*/
|
||||
public boolean getObfuscated()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* The effective chat click event.
|
||||
*/
|
||||
@Nullable
|
||||
public ClickEvent getClickEvent()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* The effective chat hover event.
|
||||
*/
|
||||
@Nullable
|
||||
public HoverEvent getHoverEvent()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Get the text to be inserted into Chat when the component is shift-clicked
|
||||
*/
|
||||
@Nullable
|
||||
public String getInsertion()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Sets the color for this ChatStyle to the given value. Only use color values for this; set other values using
|
||||
* the specific methods.
|
||||
*/
|
||||
public Style setColor(TextFormatting color)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
/**
|
||||
* Sets whether or not text of this ChatStyle should be in bold. Set to false if, e.g., the parent style is
|
||||
* bold and you want text of this style to be unbolded.
|
||||
*/
|
||||
public Style setBold(Boolean boldIn)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
/**
|
||||
* Sets whether or not text of this ChatStyle should be italicized. Set to false if, e.g., the parent style is
|
||||
* italicized and you want to override that for this style.
|
||||
*/
|
||||
public Style setItalic(Boolean italic)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
/**
|
||||
* Sets whether or not to format text of this ChatStyle using strikethrough. Set to false if, e.g., the parent
|
||||
* style uses strikethrough and you want to override that for this style.
|
||||
*/
|
||||
public Style setStrikethrough(Boolean strikethrough)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
/**
|
||||
* Sets whether or not text of this ChatStyle should be underlined. Set to false if, e.g., the parent style is
|
||||
* underlined and you want to override that for this style.
|
||||
*/
|
||||
public Style setUnderlined(Boolean underlined)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
/**
|
||||
* Sets whether or not text of this ChatStyle should be obfuscated. Set to false if, e.g., the parent style is
|
||||
* obfuscated and you want to override that for this style.
|
||||
*/
|
||||
public Style setObfuscated(Boolean obfuscated)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
/**
|
||||
* Sets the event that should be run when text of this ChatStyle is clicked on.
|
||||
*/
|
||||
public Style setClickEvent(ClickEvent event)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
/**
|
||||
* Sets the event that should be run when text of this ChatStyle is hovered over.
|
||||
*/
|
||||
public Style setHoverEvent(HoverEvent event)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
/**
|
||||
* Sets the fallback ChatStyle to use if this ChatStyle does not override some value. Without a parent, obvious
|
||||
* defaults are used (bold: false, underlined: false, etc).
|
||||
*/
|
||||
public Style setParentStyle(Style parent)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public String toString()
|
||||
{
|
||||
return "Style.ROOT";
|
||||
}
|
||||
/**
|
||||
* Creates a shallow copy of this style. Changes to this instance's values will not be reflected in the copy,
|
||||
* but changes to the parent style's values WILL be reflected in both this instance and the copy, wherever
|
||||
* either does not override a value.
|
||||
*/
|
||||
public Style createShallowCopy()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Creates a deep copy of this style. No changes to this instance or its parent style will be reflected in the
|
||||
* copy.
|
||||
*/
|
||||
public Style createDeepCopy()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Gets the equivilent text formatting code(s) for this style, including all needed section sign characters.
|
||||
*
|
||||
* @return A formatted string that can be combined with text to produce this style.
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
public String getFormattingCode()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the effective color of this ChatStyle.
|
||||
*/
|
||||
@Nullable
|
||||
public TextFormatting getColor()
|
||||
{
|
||||
return this.color == null ? this.getParent().getColor() : this.color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not text of this ChatStyle should be in bold.
|
||||
*/
|
||||
public boolean getBold()
|
||||
{
|
||||
return this.bold == null ? this.getParent().getBold() : this.bold.booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not text of this ChatStyle should be italicized.
|
||||
*/
|
||||
public boolean getItalic()
|
||||
{
|
||||
return this.italic == null ? this.getParent().getItalic() : this.italic.booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not to format text of this ChatStyle using strikethrough.
|
||||
*/
|
||||
public boolean getStrikethrough()
|
||||
{
|
||||
return this.strikethrough == null ? this.getParent().getStrikethrough() : this.strikethrough.booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not text of this ChatStyle should be underlined.
|
||||
*/
|
||||
public boolean getUnderlined()
|
||||
{
|
||||
return this.underlined == null ? this.getParent().getUnderlined() : this.underlined.booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not text of this ChatStyle should be obfuscated.
|
||||
*/
|
||||
public boolean getObfuscated()
|
||||
{
|
||||
return this.obfuscated == null ? this.getParent().getObfuscated() : this.obfuscated.booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this style is empty (inherits everything from the parent).
|
||||
*/
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return this.bold == null && this.italic == null && this.strikethrough == null && this.underlined == null && this.obfuscated == null && this.color == null && this.clickEvent == null && this.hoverEvent == null && this.insertion == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The effective chat click event.
|
||||
*/
|
||||
@Nullable
|
||||
public ClickEvent getClickEvent()
|
||||
{
|
||||
return this.clickEvent == null ? this.getParent().getClickEvent() : this.clickEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* The effective chat hover event.
|
||||
*/
|
||||
@Nullable
|
||||
public HoverEvent getHoverEvent()
|
||||
{
|
||||
return this.hoverEvent == null ? this.getParent().getHoverEvent() : this.hoverEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text to be inserted into Chat when the component is shift-clicked
|
||||
*/
|
||||
@Nullable
|
||||
public String getInsertion()
|
||||
{
|
||||
return this.insertion == null ? this.getParent().getInsertion() : this.insertion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color for this ChatStyle to the given value. Only use color values for this; set other values using the
|
||||
* specific methods.
|
||||
*/
|
||||
public Style setColor(TextFormatting color)
|
||||
{
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not text of this ChatStyle should be in bold. Set to false if, e.g., the parent style is bold
|
||||
* and you want text of this style to be unbolded.
|
||||
*/
|
||||
public Style setBold(Boolean boldIn)
|
||||
{
|
||||
this.bold = boldIn;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not text of this ChatStyle should be italicized. Set to false if, e.g., the parent style is
|
||||
* italicized and you want to override that for this style.
|
||||
*/
|
||||
public Style setItalic(Boolean italic)
|
||||
{
|
||||
this.italic = italic;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not to format text of this ChatStyle using strikethrough. Set to false if, e.g., the parent
|
||||
* style uses strikethrough and you want to override that for this style.
|
||||
*/
|
||||
public Style setStrikethrough(Boolean strikethrough)
|
||||
{
|
||||
this.strikethrough = strikethrough;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not text of this ChatStyle should be underlined. Set to false if, e.g., the parent style is
|
||||
* underlined and you want to override that for this style.
|
||||
*/
|
||||
public Style setUnderlined(Boolean underlined)
|
||||
{
|
||||
this.underlined = underlined;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not text of this ChatStyle should be obfuscated. Set to false if, e.g., the parent style is
|
||||
* obfuscated and you want to override that for this style.
|
||||
*/
|
||||
public Style setObfuscated(Boolean obfuscated)
|
||||
{
|
||||
this.obfuscated = obfuscated;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event that should be run when text of this ChatStyle is clicked on.
|
||||
*/
|
||||
public Style setClickEvent(ClickEvent event)
|
||||
{
|
||||
this.clickEvent = event;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event that should be run when text of this ChatStyle is hovered over.
|
||||
*/
|
||||
public Style setHoverEvent(HoverEvent event)
|
||||
{
|
||||
this.hoverEvent = event;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a text to be inserted into Chat when the component is shift-clicked
|
||||
*/
|
||||
public Style setInsertion(String insertion)
|
||||
{
|
||||
this.insertion = insertion;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fallback ChatStyle to use if this ChatStyle does not override some value. Without a parent, obvious
|
||||
* defaults are used (bold: false, underlined: false, etc).
|
||||
*/
|
||||
public Style setParentStyle(Style parent)
|
||||
{
|
||||
this.parentStyle = parent;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the equivilent text formatting code(s) for this style, including all needed section sign characters.
|
||||
*
|
||||
* @return A formatted string that can be combined with text to produce this style.
|
||||
*/
|
||||
public String getFormattingCode()
|
||||
{
|
||||
if (this.isEmpty())
|
||||
{
|
||||
return this.parentStyle != null ? this.parentStyle.getFormattingCode() : "";
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
|
||||
if (this.getColor() != null)
|
||||
{
|
||||
stringbuilder.append((Object)this.getColor());
|
||||
}
|
||||
|
||||
if (this.getBold())
|
||||
{
|
||||
stringbuilder.append((Object)TextFormatting.BOLD);
|
||||
}
|
||||
|
||||
if (this.getItalic())
|
||||
{
|
||||
stringbuilder.append((Object)TextFormatting.ITALIC);
|
||||
}
|
||||
|
||||
if (this.getUnderlined())
|
||||
{
|
||||
stringbuilder.append((Object)TextFormatting.UNDERLINE);
|
||||
}
|
||||
|
||||
if (this.getObfuscated())
|
||||
{
|
||||
stringbuilder.append((Object)TextFormatting.OBFUSCATED);
|
||||
}
|
||||
|
||||
if (this.getStrikethrough())
|
||||
{
|
||||
stringbuilder.append((Object)TextFormatting.STRIKETHROUGH);
|
||||
}
|
||||
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the immediate parent of this ChatStyle.
|
||||
*/
|
||||
private Style getParent()
|
||||
{
|
||||
return this.parentStyle == null ? ROOT : this.parentStyle;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Style{hasParent=" + (this.parentStyle != null) + ", color=" + this.color + ", bold=" + this.bold + ", italic=" + this.italic + ", underlined=" + this.underlined + ", obfuscated=" + this.obfuscated + ", clickEvent=" + this.getClickEvent() + ", hoverEvent=" + this.getHoverEvent() + ", insertion=" + this.getInsertion() + '}';
|
||||
}
|
||||
|
||||
public boolean equals(Object p_equals_1_)
|
||||
{
|
||||
if (this == p_equals_1_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(p_equals_1_ instanceof Style))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean flag;
|
||||
label77:
|
||||
{
|
||||
Style style = (Style)p_equals_1_;
|
||||
|
||||
if (this.getBold() == style.getBold() && this.getColor() == style.getColor() && this.getItalic() == style.getItalic() && this.getObfuscated() == style.getObfuscated() && this.getStrikethrough() == style.getStrikethrough() && this.getUnderlined() == style.getUnderlined())
|
||||
{
|
||||
label71:
|
||||
{
|
||||
if (this.getClickEvent() != null)
|
||||
{
|
||||
if (!this.getClickEvent().equals(style.getClickEvent()))
|
||||
{
|
||||
break label71;
|
||||
}
|
||||
}
|
||||
else if (style.getClickEvent() != null)
|
||||
{
|
||||
break label71;
|
||||
}
|
||||
|
||||
if (this.getHoverEvent() != null)
|
||||
{
|
||||
if (!this.getHoverEvent().equals(style.getHoverEvent()))
|
||||
{
|
||||
break label71;
|
||||
}
|
||||
}
|
||||
else if (style.getHoverEvent() != null)
|
||||
{
|
||||
break label71;
|
||||
}
|
||||
|
||||
if (this.getInsertion() != null)
|
||||
{
|
||||
if (this.getInsertion().equals(style.getInsertion()))
|
||||
{
|
||||
break label77;
|
||||
}
|
||||
}
|
||||
else if (style.getInsertion() == null)
|
||||
{
|
||||
break label77;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flag = false;
|
||||
return flag;
|
||||
}
|
||||
flag = true;
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
int i = this.color.hashCode();
|
||||
i = 31 * i + this.bold.hashCode();
|
||||
i = 31 * i + this.italic.hashCode();
|
||||
i = 31 * i + this.underlined.hashCode();
|
||||
i = 31 * i + this.strikethrough.hashCode();
|
||||
i = 31 * i + this.obfuscated.hashCode();
|
||||
i = 31 * i + this.clickEvent.hashCode();
|
||||
i = 31 * i + this.hoverEvent.hashCode();
|
||||
i = 31 * i + this.insertion.hashCode();
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a shallow copy of this style. Changes to this instance's values will not be reflected in the copy, but
|
||||
* changes to the parent style's values WILL be reflected in both this instance and the copy, wherever either does
|
||||
* not override a value.
|
||||
*/
|
||||
public Style createShallowCopy()
|
||||
{
|
||||
Style style = new Style();
|
||||
style.bold = this.bold;
|
||||
style.italic = this.italic;
|
||||
style.strikethrough = this.strikethrough;
|
||||
style.underlined = this.underlined;
|
||||
style.obfuscated = this.obfuscated;
|
||||
style.color = this.color;
|
||||
style.clickEvent = this.clickEvent;
|
||||
style.hoverEvent = this.hoverEvent;
|
||||
style.parentStyle = this.parentStyle;
|
||||
style.insertion = this.insertion;
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of this style. No changes to this instance or its parent style will be reflected in the
|
||||
* copy.
|
||||
*/
|
||||
public Style createDeepCopy()
|
||||
{
|
||||
Style style = new Style();
|
||||
style.setBold(Boolean.valueOf(this.getBold()));
|
||||
style.setItalic(Boolean.valueOf(this.getItalic()));
|
||||
style.setStrikethrough(Boolean.valueOf(this.getStrikethrough()));
|
||||
style.setUnderlined(Boolean.valueOf(this.getUnderlined()));
|
||||
style.setObfuscated(Boolean.valueOf(this.getObfuscated()));
|
||||
style.setColor(this.getColor());
|
||||
style.setClickEvent(this.getClickEvent());
|
||||
style.setHoverEvent(this.getHoverEvent());
|
||||
style.setInsertion(this.getInsertion());
|
||||
return style;
|
||||
}
|
||||
|
||||
public static class Serializer implements JsonDeserializer<Style>, JsonSerializer<Style>
|
||||
{
|
||||
@Nullable
|
||||
public Style deserialize(JsonElement p_deserialize_1_, Type p_deserialize_2_, JsonDeserializationContext p_deserialize_3_) throws JsonParseException
|
||||
{
|
||||
if (p_deserialize_1_.isJsonObject())
|
||||
{
|
||||
Style style = new Style();
|
||||
JsonObject jsonobject = p_deserialize_1_.getAsJsonObject();
|
||||
|
||||
if (jsonobject == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (jsonobject.has("bold"))
|
||||
{
|
||||
style.bold = jsonobject.get("bold").getAsBoolean();
|
||||
}
|
||||
|
||||
if (jsonobject.has("italic"))
|
||||
{
|
||||
style.italic = jsonobject.get("italic").getAsBoolean();
|
||||
}
|
||||
|
||||
if (jsonobject.has("underlined"))
|
||||
{
|
||||
style.underlined = jsonobject.get("underlined").getAsBoolean();
|
||||
}
|
||||
|
||||
if (jsonobject.has("strikethrough"))
|
||||
{
|
||||
style.strikethrough = jsonobject.get("strikethrough").getAsBoolean();
|
||||
}
|
||||
|
||||
if (jsonobject.has("obfuscated"))
|
||||
{
|
||||
style.obfuscated = jsonobject.get("obfuscated").getAsBoolean();
|
||||
}
|
||||
|
||||
if (jsonobject.has("color"))
|
||||
{
|
||||
style.color = (TextFormatting)p_deserialize_3_.deserialize(jsonobject.get("color"), TextFormatting.class);
|
||||
}
|
||||
|
||||
if (jsonobject.has("insertion"))
|
||||
{
|
||||
style.insertion = jsonobject.get("insertion").getAsString();
|
||||
}
|
||||
|
||||
if (jsonobject.has("clickEvent"))
|
||||
{
|
||||
JsonObject jsonobject1 = jsonobject.getAsJsonObject("clickEvent");
|
||||
|
||||
if (jsonobject1 != null)
|
||||
{
|
||||
JsonPrimitive jsonprimitive = jsonobject1.getAsJsonPrimitive("action");
|
||||
ClickEvent.Action clickevent$action = jsonprimitive == null ? null : ClickEvent.Action.getValueByCanonicalName(jsonprimitive.getAsString());
|
||||
JsonPrimitive jsonprimitive1 = jsonobject1.getAsJsonPrimitive("value");
|
||||
String s = jsonprimitive1 == null ? null : jsonprimitive1.getAsString();
|
||||
|
||||
if (clickevent$action != null && s != null && clickevent$action.shouldAllowInChat())
|
||||
{
|
||||
style.clickEvent = new ClickEvent(clickevent$action, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (jsonobject.has("hoverEvent"))
|
||||
{
|
||||
JsonObject jsonobject2 = jsonobject.getAsJsonObject("hoverEvent");
|
||||
|
||||
if (jsonobject2 != null)
|
||||
{
|
||||
JsonPrimitive jsonprimitive2 = jsonobject2.getAsJsonPrimitive("action");
|
||||
HoverEvent.Action hoverevent$action = jsonprimitive2 == null ? null : HoverEvent.Action.getValueByCanonicalName(jsonprimitive2.getAsString());
|
||||
ITextComponent itextcomponent = (ITextComponent)p_deserialize_3_.deserialize(jsonobject2.get("value"), ITextComponent.class);
|
||||
|
||||
if (hoverevent$action != null && itextcomponent != null && hoverevent$action.shouldAllowInChat())
|
||||
{
|
||||
style.hoverEvent = new HoverEvent(hoverevent$action, itextcomponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JsonElement serialize(Style p_serialize_1_, Type p_serialize_2_, JsonSerializationContext p_serialize_3_)
|
||||
{
|
||||
if (p_serialize_1_.isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
JsonObject jsonobject = new JsonObject();
|
||||
|
||||
if (p_serialize_1_.bold != null)
|
||||
{
|
||||
jsonobject.addProperty("bold", p_serialize_1_.bold);
|
||||
}
|
||||
|
||||
if (p_serialize_1_.italic != null)
|
||||
{
|
||||
jsonobject.addProperty("italic", p_serialize_1_.italic);
|
||||
}
|
||||
|
||||
if (p_serialize_1_.underlined != null)
|
||||
{
|
||||
jsonobject.addProperty("underlined", p_serialize_1_.underlined);
|
||||
}
|
||||
|
||||
if (p_serialize_1_.strikethrough != null)
|
||||
{
|
||||
jsonobject.addProperty("strikethrough", p_serialize_1_.strikethrough);
|
||||
}
|
||||
|
||||
if (p_serialize_1_.obfuscated != null)
|
||||
{
|
||||
jsonobject.addProperty("obfuscated", p_serialize_1_.obfuscated);
|
||||
}
|
||||
|
||||
if (p_serialize_1_.color != null)
|
||||
{
|
||||
jsonobject.add("color", p_serialize_3_.serialize(p_serialize_1_.color));
|
||||
}
|
||||
|
||||
if (p_serialize_1_.insertion != null)
|
||||
{
|
||||
jsonobject.add("insertion", p_serialize_3_.serialize(p_serialize_1_.insertion));
|
||||
}
|
||||
|
||||
if (p_serialize_1_.clickEvent != null)
|
||||
{
|
||||
JsonObject jsonobject1 = new JsonObject();
|
||||
jsonobject1.addProperty("action", p_serialize_1_.clickEvent.getAction().getCanonicalName());
|
||||
jsonobject1.addProperty("value", p_serialize_1_.clickEvent.getValue());
|
||||
jsonobject.add("clickEvent", jsonobject1);
|
||||
}
|
||||
|
||||
if (p_serialize_1_.hoverEvent != null)
|
||||
{
|
||||
JsonObject jsonobject2 = new JsonObject();
|
||||
jsonobject2.addProperty("action", p_serialize_1_.hoverEvent.getAction().getCanonicalName());
|
||||
jsonobject2.add("value", p_serialize_3_.serialize(p_serialize_1_.hoverEvent.getValue()));
|
||||
jsonobject.add("hoverEvent", jsonobject2);
|
||||
}
|
||||
|
||||
return jsonobject;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
public abstract class TextComponentBase implements ITextComponent
|
||||
{
|
||||
/**
|
||||
* The later siblings of this component. If this component turns the text bold, that will apply to all the siblings
|
||||
* until a later sibling turns the text something else.
|
||||
*/
|
||||
protected List<ITextComponent> siblings = Lists.<ITextComponent>newArrayList();
|
||||
private Style style;
|
||||
|
||||
/**
|
||||
* Adds a new component to the end of the sibling list, setting that component's style's parent style to this
|
||||
* component's style.
|
||||
*
|
||||
* @return This component, for chaining (and not the newly added component)
|
||||
*/
|
||||
public ITextComponent appendSibling(ITextComponent component)
|
||||
{
|
||||
component.getStyle().setParentStyle(this.getStyle());
|
||||
this.siblings.add(component);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sibling components of this one.
|
||||
*/
|
||||
public List<ITextComponent> getSiblings()
|
||||
{
|
||||
return this.siblings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new component to the end of the sibling list, with the specified text. Same as calling {@link
|
||||
* #appendSibling(ITextComponent)} with a new {@link TextComponentString}.
|
||||
*
|
||||
* @return This component, for chaining (and not the newly added component)
|
||||
*/
|
||||
public ITextComponent appendText(String text)
|
||||
{
|
||||
return this.appendSibling(new TextComponentString(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the style of this component and updates the parent style of all of the sibling components.
|
||||
*/
|
||||
public ITextComponent setStyle(Style style)
|
||||
{
|
||||
this.style = style;
|
||||
|
||||
for (ITextComponent itextcomponent : this.siblings)
|
||||
{
|
||||
itextcomponent.getStyle().setParentStyle(this.getStyle());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the style of this component. Returns a direct reference; changes to this style will modify the style of this
|
||||
* component (IE, there is no need to call {@link #setStyle(Style)} again after modifying it).
|
||||
*
|
||||
* If this component's style is currently <code>null</code>, it will be initialized to the default style, and the
|
||||
* parent style of all sibling components will be set to that style. (IE, changes to this style will also be
|
||||
* reflected in sibling components.)
|
||||
*
|
||||
* This method never returns <code>null</code>.
|
||||
*/
|
||||
public Style getStyle()
|
||||
{
|
||||
if (this.style == null)
|
||||
{
|
||||
this.style = new Style();
|
||||
|
||||
for (ITextComponent itextcomponent : this.siblings)
|
||||
{
|
||||
itextcomponent.getStyle().setParentStyle(this.style);
|
||||
}
|
||||
}
|
||||
|
||||
return this.style;
|
||||
}
|
||||
|
||||
public Iterator<ITextComponent> iterator()
|
||||
{
|
||||
return Iterators.<ITextComponent>concat(Iterators.forArray(this), createDeepCopyIterator(this.siblings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text of this component <em>and all sibling components</em>, without any formatting codes.
|
||||
*/
|
||||
public final String getUnformattedText()
|
||||
{
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
|
||||
for (ITextComponent itextcomponent : this)
|
||||
{
|
||||
stringbuilder.append(itextcomponent.getUnformattedComponentText());
|
||||
}
|
||||
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text of this component <em>and all sibling components</em>, with formatting codes added for rendering.
|
||||
*/
|
||||
public final String getFormattedText()
|
||||
{
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
|
||||
for (ITextComponent itextcomponent : this)
|
||||
{
|
||||
String s = itextcomponent.getUnformattedComponentText();
|
||||
|
||||
if (!s.isEmpty())
|
||||
{
|
||||
stringbuilder.append(itextcomponent.getStyle().getFormattingCode());
|
||||
stringbuilder.append(s);
|
||||
stringbuilder.append((Object)TextFormatting.RESET);
|
||||
}
|
||||
}
|
||||
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an iterator that iterates over the given components, returning deep copies of each component in turn so
|
||||
* that the properties of the returned objects will remain externally consistent after being returned.
|
||||
*/
|
||||
public static Iterator<ITextComponent> createDeepCopyIterator(Iterable<ITextComponent> components)
|
||||
{
|
||||
Iterator<ITextComponent> iterator = Iterators.concat(Iterators.transform(components.iterator(), new Function<ITextComponent, Iterator<ITextComponent>>()
|
||||
{
|
||||
public Iterator<ITextComponent> apply(@Nullable ITextComponent p_apply_1_)
|
||||
{
|
||||
return p_apply_1_.iterator();
|
||||
}
|
||||
}));
|
||||
iterator = Iterators.transform(iterator, new Function<ITextComponent, ITextComponent>()
|
||||
{
|
||||
public ITextComponent apply(@Nullable ITextComponent p_apply_1_)
|
||||
{
|
||||
ITextComponent itextcomponent = p_apply_1_.createCopy();
|
||||
itextcomponent.setStyle(itextcomponent.getStyle().createDeepCopy());
|
||||
return itextcomponent;
|
||||
}
|
||||
});
|
||||
return iterator;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_equals_1_)
|
||||
{
|
||||
if (this == p_equals_1_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(p_equals_1_ instanceof TextComponentBase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextComponentBase textcomponentbase = (TextComponentBase)p_equals_1_;
|
||||
return this.siblings.equals(textcomponentbase.siblings) && this.getStyle().equals(textcomponentbase.getStyle());
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return 31 * this.style.hashCode() + this.siblings.hashCode();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "BaseComponent{style=" + this.style + ", siblings=" + this.siblings + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class TextComponentKeybind extends TextComponentBase
|
||||
{
|
||||
public static Function<String, Supplier<String>> displaySupplierFunction = (p_193635_0_) ->
|
||||
{
|
||||
return () -> {
|
||||
return p_193635_0_;
|
||||
};
|
||||
};
|
||||
private final String keybind;
|
||||
private Supplier<String> displaySupplier;
|
||||
|
||||
public TextComponentKeybind(String keybind)
|
||||
{
|
||||
this.keybind = keybind;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw content of this component (but not its sibling components), without any formatting codes. For
|
||||
* example, this is the raw text in a {@link TextComponentString}, but it's the translated text for a {@link
|
||||
* TextComponentTranslation} and it's the score value for a {@link TextComponentScore}.
|
||||
*/
|
||||
public String getUnformattedComponentText()
|
||||
{
|
||||
if (this.displaySupplier == null)
|
||||
{
|
||||
this.displaySupplier = (Supplier)displaySupplierFunction.apply(this.keybind);
|
||||
}
|
||||
|
||||
return this.displaySupplier.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this component. Almost a deep copy, except the style is shallow-copied.
|
||||
*/
|
||||
public TextComponentKeybind createCopy()
|
||||
{
|
||||
TextComponentKeybind textcomponentkeybind = new TextComponentKeybind(this.keybind);
|
||||
textcomponentkeybind.setStyle(this.getStyle().createShallowCopy());
|
||||
|
||||
for (ITextComponent itextcomponent : this.getSiblings())
|
||||
{
|
||||
textcomponentkeybind.appendSibling(itextcomponent.createCopy());
|
||||
}
|
||||
|
||||
return textcomponentkeybind;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_equals_1_)
|
||||
{
|
||||
if (this == p_equals_1_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(p_equals_1_ instanceof TextComponentKeybind))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextComponentKeybind textcomponentkeybind = (TextComponentKeybind)p_equals_1_;
|
||||
return this.keybind.equals(textcomponentkeybind.keybind) && super.equals(p_equals_1_);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "KeybindComponent{keybind='" + this.keybind + '\'' + ", siblings=" + this.siblings + ", style=" + this.getStyle() + '}';
|
||||
}
|
||||
|
||||
public String getKeybind()
|
||||
{
|
||||
return this.keybind;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.scoreboard.Score;
|
||||
import net.minecraft.scoreboard.ScoreObjective;
|
||||
import net.minecraft.scoreboard.Scoreboard;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.StringUtils;
|
||||
|
||||
public class TextComponentScore extends TextComponentBase
|
||||
{
|
||||
private final String name;
|
||||
private final String objective;
|
||||
/** The value displayed instead of the real score (may be null) */
|
||||
private String value = "";
|
||||
|
||||
public TextComponentScore(String nameIn, String objectiveIn)
|
||||
{
|
||||
this.name = nameIn;
|
||||
this.objective = objectiveIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the entity who owns this score.
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the objective for this score.
|
||||
*/
|
||||
public String getObjective()
|
||||
{
|
||||
return this.objective;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value that is displayed for the score. Generally, you do not want to call this as the score is resolved
|
||||
* automatically. (If you want to manually set text, use a {@link TextComponentString})
|
||||
*/
|
||||
public void setValue(String valueIn)
|
||||
{
|
||||
this.value = valueIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw content of this component (but not its sibling components), without any formatting codes. For
|
||||
* example, this is the raw text in a {@link TextComponentString}, but it's the translated text for a {@link
|
||||
* TextComponentTranslation} and it's the score value for a {@link TextComponentScore}.
|
||||
*/
|
||||
public String getUnformattedComponentText()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the value of the score on this component.
|
||||
*/
|
||||
public void resolve(ICommandSender sender)
|
||||
{
|
||||
MinecraftServer minecraftserver = sender.getServer();
|
||||
|
||||
if (minecraftserver != null && minecraftserver.isAnvilFileSet() && StringUtils.isNullOrEmpty(this.value))
|
||||
{
|
||||
Scoreboard scoreboard = minecraftserver.getWorld(0).getScoreboard();
|
||||
ScoreObjective scoreobjective = scoreboard.getObjective(this.objective);
|
||||
|
||||
if (scoreboard.entityHasObjective(this.name, scoreobjective))
|
||||
{
|
||||
Score score = scoreboard.getOrCreateScore(this.name, scoreobjective);
|
||||
this.setValue(String.format("%d", score.getScorePoints()));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.value = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this component. Almost a deep copy, except the style is shallow-copied.
|
||||
*/
|
||||
public TextComponentScore createCopy()
|
||||
{
|
||||
TextComponentScore textcomponentscore = new TextComponentScore(this.name, this.objective);
|
||||
textcomponentscore.setValue(this.value);
|
||||
textcomponentscore.setStyle(this.getStyle().createShallowCopy());
|
||||
|
||||
for (ITextComponent itextcomponent : this.getSiblings())
|
||||
{
|
||||
textcomponentscore.appendSibling(itextcomponent.createCopy());
|
||||
}
|
||||
|
||||
return textcomponentscore;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_equals_1_)
|
||||
{
|
||||
if (this == p_equals_1_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(p_equals_1_ instanceof TextComponentScore))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextComponentScore textcomponentscore = (TextComponentScore)p_equals_1_;
|
||||
return this.name.equals(textcomponentscore.name) && this.objective.equals(textcomponentscore.objective) && super.equals(p_equals_1_);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "ScoreComponent{name='" + this.name + '\'' + "objective='" + this.objective + '\'' + ", siblings=" + this.siblings + ", style=" + this.getStyle() + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
public class TextComponentSelector extends TextComponentBase
|
||||
{
|
||||
/** The selector used to find the matching entities of this text component */
|
||||
private final String selector;
|
||||
|
||||
public TextComponentSelector(String selectorIn)
|
||||
{
|
||||
this.selector = selectorIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the selector of this component, in plain text.
|
||||
*/
|
||||
public String getSelector()
|
||||
{
|
||||
return this.selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw content of this component (but not its sibling components), without any formatting codes. For
|
||||
* example, this is the raw text in a {@link TextComponentString}, but it's the translated text for a {@link
|
||||
* TextComponentTranslation} and it's the score value for a {@link TextComponentScore}.
|
||||
*/
|
||||
public String getUnformattedComponentText()
|
||||
{
|
||||
return this.selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this component. Almost a deep copy, except the style is shallow-copied.
|
||||
*/
|
||||
public TextComponentSelector createCopy()
|
||||
{
|
||||
TextComponentSelector textcomponentselector = new TextComponentSelector(this.selector);
|
||||
textcomponentselector.setStyle(this.getStyle().createShallowCopy());
|
||||
|
||||
for (ITextComponent itextcomponent : this.getSiblings())
|
||||
{
|
||||
textcomponentselector.appendSibling(itextcomponent.createCopy());
|
||||
}
|
||||
|
||||
return textcomponentselector;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_equals_1_)
|
||||
{
|
||||
if (this == p_equals_1_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(p_equals_1_ instanceof TextComponentSelector))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextComponentSelector textcomponentselector = (TextComponentSelector)p_equals_1_;
|
||||
return this.selector.equals(textcomponentselector.selector) && super.equals(p_equals_1_);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "SelectorComponent{pattern='" + this.selector + '\'' + ", siblings=" + this.siblings + ", style=" + this.getStyle() + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
public class TextComponentString extends TextComponentBase
|
||||
{
|
||||
private final String text;
|
||||
|
||||
public TextComponentString(String msg)
|
||||
{
|
||||
this.text = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text value of this component. This is used to access the {@link #text} property, and only should be used
|
||||
* when dealing specifically with instances of {@link TextComponentString} - for other purposes, use {@link
|
||||
* #getUnformattedComponentText()}.
|
||||
*/
|
||||
public String getText()
|
||||
{
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw content of this component (but not its sibling components), without any formatting codes. For
|
||||
* example, this is the raw text in a {@link TextComponentString}, but it's the translated text for a {@link
|
||||
* TextComponentTranslation} and it's the score value for a {@link TextComponentScore}.
|
||||
*/
|
||||
public String getUnformattedComponentText()
|
||||
{
|
||||
return this.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this component. Almost a deep copy, except the style is shallow-copied.
|
||||
*/
|
||||
public TextComponentString createCopy()
|
||||
{
|
||||
TextComponentString textcomponentstring = new TextComponentString(this.text);
|
||||
textcomponentstring.setStyle(this.getStyle().createShallowCopy());
|
||||
|
||||
for (ITextComponent itextcomponent : this.getSiblings())
|
||||
{
|
||||
textcomponentstring.appendSibling(itextcomponent.createCopy());
|
||||
}
|
||||
|
||||
return textcomponentstring;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_equals_1_)
|
||||
{
|
||||
if (this == p_equals_1_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(p_equals_1_ instanceof TextComponentString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextComponentString textcomponentstring = (TextComponentString)p_equals_1_;
|
||||
return this.text.equals(textcomponentstring.getText()) && super.equals(p_equals_1_);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "TextComponent{text='" + this.text + '\'' + ", siblings=" + this.siblings + ", style=" + this.getStyle() + '}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.Arrays;
|
||||
import java.util.IllegalFormatException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import net.minecraft.util.text.translation.I18n;
|
||||
|
||||
public class TextComponentTranslation extends TextComponentBase
|
||||
{
|
||||
private final String key;
|
||||
private final Object[] formatArgs;
|
||||
private final Object syncLock = new Object();
|
||||
private long lastTranslationUpdateTimeInMilliseconds = -1L;
|
||||
/**
|
||||
* The discrete elements that make up this component. For example, this would be ["Prefix, ", "FirstArg",
|
||||
* "SecondArg", " again ", "SecondArg", " and ", "FirstArg", " lastly ", "ThirdArg", " and also ", "FirstArg", "
|
||||
* again!"] for "translation.test.complex" (see en-US.lang)
|
||||
*/
|
||||
@VisibleForTesting
|
||||
List<ITextComponent> children = Lists.<ITextComponent>newArrayList();
|
||||
public static final Pattern STRING_VARIABLE_PATTERN = Pattern.compile("%(?:(\\d+)\\$)?([A-Za-z%]|$)");
|
||||
|
||||
public TextComponentTranslation(String translationKey, Object... args)
|
||||
{
|
||||
this.key = translationKey;
|
||||
this.formatArgs = args;
|
||||
|
||||
for (Object object : args)
|
||||
{
|
||||
if (object instanceof ITextComponent)
|
||||
{
|
||||
((ITextComponent)object).getStyle().setParentStyle(this.getStyle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
/**
|
||||
* Ensures that all of the children are up to date with the most recent translation mapping.
|
||||
*/
|
||||
synchronized void ensureInitialized()
|
||||
{
|
||||
synchronized (this.syncLock)
|
||||
{
|
||||
long i = I18n.getLastTranslationUpdateTimeInMilliseconds();
|
||||
|
||||
if (i == this.lastTranslationUpdateTimeInMilliseconds)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.lastTranslationUpdateTimeInMilliseconds = i;
|
||||
this.children.clear();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.initializeFromFormat(I18n.translateToLocal(this.key));
|
||||
}
|
||||
catch (TextComponentTranslationFormatException textcomponenttranslationformatexception)
|
||||
{
|
||||
this.children.clear();
|
||||
|
||||
try
|
||||
{
|
||||
this.initializeFromFormat(I18n.translateToFallback(this.key));
|
||||
}
|
||||
catch (TextComponentTranslationFormatException var5)
|
||||
{
|
||||
throw textcomponenttranslationformatexception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the content of this component, substituting in variables.
|
||||
*/
|
||||
protected void initializeFromFormat(String format)
|
||||
{
|
||||
boolean flag = false;
|
||||
Matcher matcher = STRING_VARIABLE_PATTERN.matcher(format);
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
try
|
||||
{
|
||||
int l;
|
||||
|
||||
for (; matcher.find(j); j = l)
|
||||
{
|
||||
int k = matcher.start();
|
||||
l = matcher.end();
|
||||
|
||||
if (k > j)
|
||||
{
|
||||
TextComponentString textcomponentstring = new TextComponentString(String.format(format.substring(j, k)));
|
||||
textcomponentstring.getStyle().setParentStyle(this.getStyle());
|
||||
this.children.add(textcomponentstring);
|
||||
}
|
||||
|
||||
String s2 = matcher.group(2);
|
||||
String s = format.substring(k, l);
|
||||
|
||||
if ("%".equals(s2) && "%%".equals(s))
|
||||
{
|
||||
TextComponentString textcomponentstring2 = new TextComponentString("%");
|
||||
textcomponentstring2.getStyle().setParentStyle(this.getStyle());
|
||||
this.children.add(textcomponentstring2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!"s".equals(s2))
|
||||
{
|
||||
throw new TextComponentTranslationFormatException(this, "Unsupported format: '" + s + "'");
|
||||
}
|
||||
|
||||
String s1 = matcher.group(1);
|
||||
int i1 = s1 != null ? Integer.parseInt(s1) - 1 : i++;
|
||||
|
||||
if (i1 < this.formatArgs.length)
|
||||
{
|
||||
this.children.add(this.getFormatArgumentAsComponent(i1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j < format.length())
|
||||
{
|
||||
TextComponentString textcomponentstring1 = new TextComponentString(String.format(format.substring(j)));
|
||||
textcomponentstring1.getStyle().setParentStyle(this.getStyle());
|
||||
this.children.add(textcomponentstring1);
|
||||
}
|
||||
}
|
||||
catch (IllegalFormatException illegalformatexception)
|
||||
{
|
||||
throw new TextComponentTranslationFormatException(this, illegalformatexception);
|
||||
}
|
||||
}
|
||||
|
||||
private ITextComponent getFormatArgumentAsComponent(int index)
|
||||
{
|
||||
if (index >= this.formatArgs.length)
|
||||
{
|
||||
throw new TextComponentTranslationFormatException(this, index);
|
||||
}
|
||||
else
|
||||
{
|
||||
Object object = this.formatArgs[index];
|
||||
ITextComponent itextcomponent;
|
||||
|
||||
if (object instanceof ITextComponent)
|
||||
{
|
||||
itextcomponent = (ITextComponent)object;
|
||||
}
|
||||
else
|
||||
{
|
||||
itextcomponent = new TextComponentString(object == null ? "null" : object.toString());
|
||||
itextcomponent.getStyle().setParentStyle(this.getStyle());
|
||||
}
|
||||
|
||||
return itextcomponent;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the style of this component and updates the parent style of all of the sibling components.
|
||||
*/
|
||||
public ITextComponent setStyle(Style style)
|
||||
{
|
||||
super.setStyle(style);
|
||||
|
||||
for (Object object : this.formatArgs)
|
||||
{
|
||||
if (object instanceof ITextComponent)
|
||||
{
|
||||
((ITextComponent)object).getStyle().setParentStyle(this.getStyle());
|
||||
}
|
||||
}
|
||||
|
||||
if (this.lastTranslationUpdateTimeInMilliseconds > -1L)
|
||||
{
|
||||
for (ITextComponent itextcomponent : this.children)
|
||||
{
|
||||
itextcomponent.getStyle().setParentStyle(style);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Iterator<ITextComponent> iterator()
|
||||
{
|
||||
this.ensureInitialized();
|
||||
return Iterators.<ITextComponent>concat(createDeepCopyIterator(this.children), createDeepCopyIterator(this.siblings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw content of this component (but not its sibling components), without any formatting codes. For
|
||||
* example, this is the raw text in a {@link TextComponentString}, but it's the translated text for a {@link
|
||||
* TextComponentTranslation} and it's the score value for a {@link TextComponentScore}.
|
||||
*/
|
||||
public String getUnformattedComponentText()
|
||||
{
|
||||
this.ensureInitialized();
|
||||
StringBuilder stringbuilder = new StringBuilder();
|
||||
|
||||
for (ITextComponent itextcomponent : this.children)
|
||||
{
|
||||
stringbuilder.append(itextcomponent.getUnformattedComponentText());
|
||||
}
|
||||
|
||||
return stringbuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this component. Almost a deep copy, except the style is shallow-copied.
|
||||
*/
|
||||
public TextComponentTranslation createCopy()
|
||||
{
|
||||
Object[] aobject = new Object[this.formatArgs.length];
|
||||
|
||||
for (int i = 0; i < this.formatArgs.length; ++i)
|
||||
{
|
||||
if (this.formatArgs[i] instanceof ITextComponent)
|
||||
{
|
||||
aobject[i] = ((ITextComponent)this.formatArgs[i]).createCopy();
|
||||
}
|
||||
else
|
||||
{
|
||||
aobject[i] = this.formatArgs[i];
|
||||
}
|
||||
}
|
||||
|
||||
TextComponentTranslation textcomponenttranslation = new TextComponentTranslation(this.key, aobject);
|
||||
textcomponenttranslation.setStyle(this.getStyle().createShallowCopy());
|
||||
|
||||
for (ITextComponent itextcomponent : this.getSiblings())
|
||||
{
|
||||
textcomponenttranslation.appendSibling(itextcomponent.createCopy());
|
||||
}
|
||||
|
||||
return textcomponenttranslation;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_equals_1_)
|
||||
{
|
||||
if (this == p_equals_1_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (!(p_equals_1_ instanceof TextComponentTranslation))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TextComponentTranslation textcomponenttranslation = (TextComponentTranslation)p_equals_1_;
|
||||
return Arrays.equals(this.formatArgs, textcomponenttranslation.formatArgs) && this.key.equals(textcomponenttranslation.key) && super.equals(p_equals_1_);
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
int i = super.hashCode();
|
||||
i = 31 * i + this.key.hashCode();
|
||||
i = 31 * i + Arrays.hashCode(this.formatArgs);
|
||||
return i;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "TranslatableComponent{key='" + this.key + '\'' + ", args=" + Arrays.toString(this.formatArgs) + ", siblings=" + this.siblings + ", style=" + this.getStyle() + '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key used to translate this component.
|
||||
*/
|
||||
public String getKey()
|
||||
{
|
||||
return this.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the object array that is used to translate the key.
|
||||
*/
|
||||
public Object[] getFormatArgs()
|
||||
{
|
||||
return this.formatArgs;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
public class TextComponentTranslationFormatException extends IllegalArgumentException
|
||||
{
|
||||
public TextComponentTranslationFormatException(TextComponentTranslation component, String message)
|
||||
{
|
||||
super(String.format("Error parsing: %s: %s", component, message));
|
||||
}
|
||||
|
||||
public TextComponentTranslationFormatException(TextComponentTranslation component, int index)
|
||||
{
|
||||
super(String.format("Invalid index %d requested for %s", index, component));
|
||||
}
|
||||
|
||||
public TextComponentTranslationFormatException(TextComponentTranslation component, Throwable cause)
|
||||
{
|
||||
super(String.format("Error while parsing: %s", component), cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
import java.util.List;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.EntityNotFoundException;
|
||||
import net.minecraft.command.EntitySelector;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
public class TextComponentUtils
|
||||
{
|
||||
public static ITextComponent processComponent(ICommandSender commandSender, ITextComponent component, Entity entityIn) throws CommandException
|
||||
{
|
||||
ITextComponent itextcomponent;
|
||||
|
||||
if (component instanceof TextComponentScore)
|
||||
{
|
||||
TextComponentScore textcomponentscore = (TextComponentScore)component;
|
||||
String s = textcomponentscore.getName();
|
||||
|
||||
if (EntitySelector.isSelector(s))
|
||||
{
|
||||
List<Entity> list = EntitySelector.<Entity>matchEntities(commandSender, s, Entity.class);
|
||||
|
||||
if (list.size() != 1)
|
||||
{
|
||||
throw new EntityNotFoundException("commands.generic.selector.notFound", new Object[] {s});
|
||||
}
|
||||
|
||||
Entity entity = list.get(0);
|
||||
|
||||
if (entity instanceof EntityPlayer)
|
||||
{
|
||||
s = entity.getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
s = entity.getCachedUniqueIdString();
|
||||
}
|
||||
}
|
||||
|
||||
String s2 = entityIn != null && s.equals("*") ? entityIn.getName() : s;
|
||||
itextcomponent = new TextComponentScore(s2, textcomponentscore.getObjective());
|
||||
((TextComponentScore)itextcomponent).setValue(textcomponentscore.getUnformattedComponentText());
|
||||
((TextComponentScore)itextcomponent).resolve(commandSender);
|
||||
}
|
||||
else if (component instanceof TextComponentSelector)
|
||||
{
|
||||
String s1 = ((TextComponentSelector)component).getSelector();
|
||||
itextcomponent = EntitySelector.matchEntitiesToTextComponent(commandSender, s1);
|
||||
|
||||
if (itextcomponent == null)
|
||||
{
|
||||
itextcomponent = new TextComponentString("");
|
||||
}
|
||||
}
|
||||
else if (component instanceof TextComponentString)
|
||||
{
|
||||
itextcomponent = new TextComponentString(((TextComponentString)component).getText());
|
||||
}
|
||||
else if (component instanceof TextComponentKeybind)
|
||||
{
|
||||
itextcomponent = new TextComponentKeybind(((TextComponentKeybind)component).getKeybind());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(component instanceof TextComponentTranslation))
|
||||
{
|
||||
return component;
|
||||
}
|
||||
|
||||
Object[] aobject = ((TextComponentTranslation)component).getFormatArgs();
|
||||
|
||||
for (int i = 0; i < aobject.length; ++i)
|
||||
{
|
||||
Object object = aobject[i];
|
||||
|
||||
if (object instanceof ITextComponent)
|
||||
{
|
||||
aobject[i] = processComponent(commandSender, (ITextComponent)object, entityIn);
|
||||
}
|
||||
}
|
||||
|
||||
itextcomponent = new TextComponentTranslation(((TextComponentTranslation)component).getKey(), aobject);
|
||||
}
|
||||
|
||||
Style style = component.getStyle();
|
||||
|
||||
if (style != null)
|
||||
{
|
||||
itextcomponent.setStyle(style.createShallowCopy());
|
||||
}
|
||||
|
||||
for (ITextComponent itextcomponent1 : component.getSiblings())
|
||||
{
|
||||
itextcomponent.appendSibling(processComponent(commandSender, itextcomponent1, entityIn));
|
||||
}
|
||||
|
||||
return itextcomponent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
package net.minecraft.util.text;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public enum TextFormatting
|
||||
{
|
||||
BLACK("BLACK", '0', 0),
|
||||
DARK_BLUE("DARK_BLUE", '1', 1),
|
||||
DARK_GREEN("DARK_GREEN", '2', 2),
|
||||
DARK_AQUA("DARK_AQUA", '3', 3),
|
||||
DARK_RED("DARK_RED", '4', 4),
|
||||
DARK_PURPLE("DARK_PURPLE", '5', 5),
|
||||
GOLD("GOLD", '6', 6),
|
||||
GRAY("GRAY", '7', 7),
|
||||
DARK_GRAY("DARK_GRAY", '8', 8),
|
||||
BLUE("BLUE", '9', 9),
|
||||
GREEN("GREEN", 'a', 10),
|
||||
AQUA("AQUA", 'b', 11),
|
||||
RED("RED", 'c', 12),
|
||||
LIGHT_PURPLE("LIGHT_PURPLE", 'd', 13),
|
||||
YELLOW("YELLOW", 'e', 14),
|
||||
WHITE("WHITE", 'f', 15),
|
||||
OBFUSCATED("OBFUSCATED", 'k', true),
|
||||
BOLD("BOLD", 'l', true),
|
||||
STRIKETHROUGH("STRIKETHROUGH", 'm', true),
|
||||
UNDERLINE("UNDERLINE", 'n', true),
|
||||
ITALIC("ITALIC", 'o', true),
|
||||
RESET("RESET", 'r', -1);
|
||||
|
||||
/** Maps a name (e.g., 'underline') to its corresponding enum value (e.g., UNDERLINE). */
|
||||
private static final Map<String, TextFormatting> NAME_MAPPING = Maps.<String, TextFormatting>newHashMap();
|
||||
/**
|
||||
* Matches formatting codes that indicate that the client should treat the following text as bold, recolored,
|
||||
* obfuscated, etc.
|
||||
*/
|
||||
private static final Pattern FORMATTING_CODE_PATTERN = Pattern.compile("(?i)\u00a7[0-9A-FK-OR]");
|
||||
/** The name of this color/formatting */
|
||||
private final String name;
|
||||
/** The formatting code that produces this format. */
|
||||
private final char formattingCode;
|
||||
private final boolean fancyStyling;
|
||||
/**
|
||||
* The control string (section sign + formatting code) that can be inserted into client-side text to display
|
||||
* subsequent text in this format.
|
||||
*/
|
||||
private final String controlString;
|
||||
/** The numerical index that represents this color */
|
||||
private final int colorIndex;
|
||||
|
||||
private static String lowercaseAlpha(String p_175745_0_)
|
||||
{
|
||||
return p_175745_0_.toLowerCase(Locale.ROOT).replaceAll("[^a-z]", "");
|
||||
}
|
||||
|
||||
private TextFormatting(String formattingName, char formattingCodeIn, int colorIndex)
|
||||
{
|
||||
this(formattingName, formattingCodeIn, false, colorIndex);
|
||||
}
|
||||
|
||||
private TextFormatting(String formattingName, char formattingCodeIn, boolean fancyStylingIn)
|
||||
{
|
||||
this(formattingName, formattingCodeIn, fancyStylingIn, -1);
|
||||
}
|
||||
|
||||
private TextFormatting(String formattingName, char formattingCodeIn, boolean fancyStylingIn, int colorIndex)
|
||||
{
|
||||
this.name = formattingName;
|
||||
this.formattingCode = formattingCodeIn;
|
||||
this.fancyStyling = fancyStylingIn;
|
||||
this.colorIndex = colorIndex;
|
||||
this.controlString = "\u00a7" + formattingCodeIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numerical color index that represents this formatting
|
||||
*/
|
||||
public int getColorIndex()
|
||||
{
|
||||
return this.colorIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* False if this is just changing the color or resetting; true otherwise.
|
||||
*/
|
||||
public boolean isFancyStyling()
|
||||
{
|
||||
return this.fancyStyling;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this is a color code.
|
||||
*/
|
||||
public boolean isColor()
|
||||
{
|
||||
return !this.fancyStyling && this != RESET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the friendly name of this value.
|
||||
*/
|
||||
public String getFriendlyName()
|
||||
{
|
||||
return this.name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return this.controlString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the given string, with formatting codes stripped away.
|
||||
*/
|
||||
@Nullable
|
||||
public static String getTextWithoutFormattingCodes(@Nullable String text)
|
||||
{
|
||||
return text == null ? null : FORMATTING_CODE_PATTERN.matcher(text).replaceAll("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value by its friendly name; null if the given name does not map to a defined value.
|
||||
*/
|
||||
@Nullable
|
||||
public static TextFormatting getValueByName(@Nullable String friendlyName)
|
||||
{
|
||||
return friendlyName == null ? null : (TextFormatting)NAME_MAPPING.get(lowercaseAlpha(friendlyName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a TextFormatting from it's color index
|
||||
*/
|
||||
@Nullable
|
||||
public static TextFormatting fromColorIndex(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
return RESET;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (TextFormatting textformatting : values())
|
||||
{
|
||||
if (textformatting.getColorIndex() == index)
|
||||
{
|
||||
return textformatting;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the valid values.
|
||||
*/
|
||||
public static Collection<String> getValidValues(boolean p_96296_0_, boolean p_96296_1_)
|
||||
{
|
||||
List<String> list = Lists.<String>newArrayList();
|
||||
|
||||
for (TextFormatting textformatting : values())
|
||||
{
|
||||
if ((!textformatting.isColor() || p_96296_0_) && (!textformatting.isFancyStyling() || p_96296_1_))
|
||||
{
|
||||
list.add(textformatting.getFriendlyName());
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
for (TextFormatting textformatting : values())
|
||||
{
|
||||
NAME_MAPPING.put(lowercaseAlpha(textformatting.name), textformatting);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package net.minecraft.util.text.event;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.Map;
|
||||
|
||||
public class ClickEvent
|
||||
{
|
||||
private final ClickEvent.Action action;
|
||||
private final String value;
|
||||
|
||||
public ClickEvent(ClickEvent.Action theAction, String theValue)
|
||||
{
|
||||
this.action = theAction;
|
||||
this.value = theValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the action to perform when this event is raised.
|
||||
*/
|
||||
public ClickEvent.Action getAction()
|
||||
{
|
||||
return this.action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value to perform the action on when this event is raised. For example, if the action is "open URL",
|
||||
* this would be the URL to open.
|
||||
*/
|
||||
public String getValue()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_equals_1_)
|
||||
{
|
||||
if (this == p_equals_1_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (p_equals_1_ != null && this.getClass() == p_equals_1_.getClass())
|
||||
{
|
||||
ClickEvent clickevent = (ClickEvent)p_equals_1_;
|
||||
|
||||
if (this.action != clickevent.action)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.value != null)
|
||||
{
|
||||
if (!this.value.equals(clickevent.value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (clickevent.value != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "ClickEvent{action=" + this.action + ", value='" + this.value + '\'' + '}';
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
int i = this.action.hashCode();
|
||||
i = 31 * i + (this.value != null ? this.value.hashCode() : 0);
|
||||
return i;
|
||||
}
|
||||
|
||||
public static enum Action
|
||||
{
|
||||
OPEN_URL("open_url", true),
|
||||
OPEN_FILE("open_file", false),
|
||||
RUN_COMMAND("run_command", true),
|
||||
SUGGEST_COMMAND("suggest_command", true),
|
||||
CHANGE_PAGE("change_page", true);
|
||||
|
||||
private static final Map<String, ClickEvent.Action> NAME_MAPPING = Maps.<String, ClickEvent.Action>newHashMap();
|
||||
private final boolean allowedInChat;
|
||||
/** The canonical name used to refer to this action. */
|
||||
private final String canonicalName;
|
||||
|
||||
private Action(String canonicalNameIn, boolean allowedInChatIn)
|
||||
{
|
||||
this.canonicalName = canonicalNameIn;
|
||||
this.allowedInChat = allowedInChatIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this event can be run from chat text.
|
||||
*/
|
||||
public boolean shouldAllowInChat()
|
||||
{
|
||||
return this.allowedInChat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the canonical name for this action (e.g., "run_command")
|
||||
*/
|
||||
public String getCanonicalName()
|
||||
{
|
||||
return this.canonicalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value by its canonical name.
|
||||
*/
|
||||
public static ClickEvent.Action getValueByCanonicalName(String canonicalNameIn)
|
||||
{
|
||||
return NAME_MAPPING.get(canonicalNameIn);
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
for (ClickEvent.Action clickevent$action : values())
|
||||
{
|
||||
NAME_MAPPING.put(clickevent$action.getCanonicalName(), clickevent$action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package net.minecraft.util.text.event;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import java.util.Map;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
public class HoverEvent
|
||||
{
|
||||
private final HoverEvent.Action action;
|
||||
private final ITextComponent value;
|
||||
|
||||
public HoverEvent(HoverEvent.Action actionIn, ITextComponent valueIn)
|
||||
{
|
||||
this.action = actionIn;
|
||||
this.value = valueIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the action to perform when this event is raised.
|
||||
*/
|
||||
public HoverEvent.Action getAction()
|
||||
{
|
||||
return this.action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value to perform the action on when this event is raised. For example, if the action is "show item",
|
||||
* this would be the item to show.
|
||||
*/
|
||||
public ITextComponent getValue()
|
||||
{
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_equals_1_)
|
||||
{
|
||||
if (this == p_equals_1_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (p_equals_1_ != null && this.getClass() == p_equals_1_.getClass())
|
||||
{
|
||||
HoverEvent hoverevent = (HoverEvent)p_equals_1_;
|
||||
|
||||
if (this.action != hoverevent.action)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.value != null)
|
||||
{
|
||||
if (!this.value.equals(hoverevent.value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (hoverevent.value != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "HoverEvent{action=" + this.action + ", value='" + this.value + '\'' + '}';
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
int i = this.action.hashCode();
|
||||
i = 31 * i + (this.value != null ? this.value.hashCode() : 0);
|
||||
return i;
|
||||
}
|
||||
|
||||
public static enum Action
|
||||
{
|
||||
SHOW_TEXT("show_text", true),
|
||||
SHOW_ITEM("show_item", true),
|
||||
SHOW_ENTITY("show_entity", true);
|
||||
|
||||
private static final Map<String, HoverEvent.Action> NAME_MAPPING = Maps.<String, HoverEvent.Action>newHashMap();
|
||||
private final boolean allowedInChat;
|
||||
private final String canonicalName;
|
||||
|
||||
private Action(String canonicalNameIn, boolean allowedInChatIn)
|
||||
{
|
||||
this.canonicalName = canonicalNameIn;
|
||||
this.allowedInChat = allowedInChatIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this event can be run from chat text.
|
||||
*/
|
||||
public boolean shouldAllowInChat()
|
||||
{
|
||||
return this.allowedInChat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the canonical name for this action (e.g., "show_achievement")
|
||||
*/
|
||||
public String getCanonicalName()
|
||||
{
|
||||
return this.canonicalName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value by its canonical name.
|
||||
*/
|
||||
public static HoverEvent.Action getValueByCanonicalName(String canonicalNameIn)
|
||||
{
|
||||
return NAME_MAPPING.get(canonicalNameIn);
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
for (HoverEvent.Action hoverevent$action : values())
|
||||
{
|
||||
NAME_MAPPING.put(hoverevent$action.getCanonicalName(), hoverevent$action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Auto generated package-info by MCP
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
package net.minecraft.util.text.event;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
@@ -0,0 +1,7 @@
|
||||
// Auto generated package-info by MCP
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
package net.minecraft.util.text;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
@@ -0,0 +1,57 @@
|
||||
package net.minecraft.util.text.translation;
|
||||
|
||||
@Deprecated
|
||||
public class I18n
|
||||
{
|
||||
public static final LanguageMap localizedName = LanguageMap.getInstance();
|
||||
/**
|
||||
* A StringTranslate instance using the hardcoded default locale (en_US). Used as a fallback in case the shared
|
||||
* StringTranslate singleton instance fails to translate a key.
|
||||
*/
|
||||
private static final LanguageMap fallbackTranslator = new LanguageMap();
|
||||
|
||||
/**
|
||||
* Translates a Stat name
|
||||
*/
|
||||
@Deprecated
|
||||
public static String translateToLocal(String key)
|
||||
{
|
||||
return localizedName.translateKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a Stat name with format args
|
||||
*/
|
||||
@Deprecated
|
||||
public static String translateToLocalFormatted(String key, Object... format)
|
||||
{
|
||||
return localizedName.translateKeyFormat(key, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates a Stat name using the fallback (hardcoded en_US) locale. Looks like it's only intended to be used if
|
||||
* translateToLocal fails.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String translateToFallback(String key)
|
||||
{
|
||||
return fallbackTranslator.translateKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not translateToLocal will find a translation for the given key.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean canTranslate(String key)
|
||||
{
|
||||
return localizedName.isKeyTranslated(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time, in milliseconds since epoch, that the translation mapping was last updated
|
||||
*/
|
||||
public static long getLastTranslationUpdateTimeInMilliseconds()
|
||||
{
|
||||
return localizedName.getLastUpdateTimeInMilliseconds();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package net.minecraft.util.text.translation;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.IllegalFormatException;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
public class LanguageMap
|
||||
{
|
||||
/** Pattern that matches numeric variable placeholders in a resource string, such as "%d", "%3$d", "%.2f" */
|
||||
private static final Pattern NUMERIC_VARIABLE_PATTERN = Pattern.compile("%(\\d+\\$)?[\\d\\.]*[df]");
|
||||
/** A Splitter that splits a string on the first "=". For example, "a=b=c" would split into ["a", "b=c"]. */
|
||||
private static final Splitter EQUAL_SIGN_SPLITTER = Splitter.on('=').limit(2);
|
||||
/** Is the private singleton instance of StringTranslate. */
|
||||
public static final LanguageMap instance = new LanguageMap();
|
||||
public final Map<String, String> languageList = Maps.<String, String>newHashMap();
|
||||
/** The time, in milliseconds since epoch, that this instance was last updated */
|
||||
private long lastUpdateTimeInMilliseconds;
|
||||
|
||||
public LanguageMap()
|
||||
{
|
||||
InputStream inputstream = LanguageMap.class.getResourceAsStream("/assets/minecraft/lang/en_us.lang");
|
||||
inject(this, inputstream);
|
||||
}
|
||||
|
||||
public static void inject(InputStream inputstream)
|
||||
{
|
||||
inject(instance, inputstream);
|
||||
}
|
||||
|
||||
private static void inject(LanguageMap inst, InputStream inputstream)
|
||||
{
|
||||
Map<String, String> map = parseLangFile(inputstream);
|
||||
inst.languageList.putAll(map);
|
||||
inst.lastUpdateTimeInMilliseconds = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static Map<String, String> parseLangFile(InputStream inputstream)
|
||||
{
|
||||
Map<String, String> table = Maps.newHashMap();
|
||||
try
|
||||
{
|
||||
inputstream = net.minecraftforge.fml.common.FMLCommonHandler.instance().loadLanguage(table, inputstream);
|
||||
if (inputstream == null) return table;
|
||||
|
||||
for (String s : IOUtils.readLines(inputstream, StandardCharsets.UTF_8))
|
||||
{
|
||||
if (!s.isEmpty() && s.charAt(0) != '#')
|
||||
{
|
||||
String[] astring = (String[])Iterables.toArray(EQUAL_SIGN_SPLITTER.split(s), String.class);
|
||||
|
||||
if (astring != null && astring.length == 2)
|
||||
{
|
||||
String s1 = astring[0];
|
||||
String s2 = NUMERIC_VARIABLE_PATTERN.matcher(astring[1]).replaceAll("%$1s");
|
||||
table.put(s1, s2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (IOException var7)
|
||||
{
|
||||
;
|
||||
}
|
||||
catch (Exception ex) {}
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the StringTranslate singleton instance
|
||||
*/
|
||||
static LanguageMap getInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
|
||||
/**
|
||||
* Replaces all the current instance's translations with the ones that are passed in.
|
||||
*/
|
||||
public static synchronized void replaceWith(Map<String, String> p_135063_0_)
|
||||
{
|
||||
instance.languageList.clear();
|
||||
instance.languageList.putAll(p_135063_0_);
|
||||
instance.lastUpdateTimeInMilliseconds = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a key to current language.
|
||||
*/
|
||||
public synchronized String translateKey(String key)
|
||||
{
|
||||
return this.tryTranslateKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a key to current language applying String.format()
|
||||
*/
|
||||
public synchronized String translateKeyFormat(String key, Object... format)
|
||||
{
|
||||
String s = this.tryTranslateKey(key);
|
||||
|
||||
try
|
||||
{
|
||||
return String.format(s, format);
|
||||
}
|
||||
catch (IllegalFormatException var5)
|
||||
{
|
||||
return "Format error: " + s;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to look up a translation for the given key; spits back the key if no result was found.
|
||||
*/
|
||||
private String tryTranslateKey(String key)
|
||||
{
|
||||
String s = this.languageList.get(key);
|
||||
return s == null ? key : s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the passed key is in the translation table.
|
||||
*/
|
||||
public synchronized boolean isKeyTranslated(String key)
|
||||
{
|
||||
return this.languageList.containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time, in milliseconds since epoch, that this instance was last updated
|
||||
*/
|
||||
public long getLastUpdateTimeInMilliseconds()
|
||||
{
|
||||
return this.lastUpdateTimeInMilliseconds;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Auto generated package-info by MCP
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
package net.minecraft.util.text.translation;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
Reference in New Issue
Block a user