diff --git a/src/com/massivecraft/massivecore/MassiveCore.java b/src/com/massivecraft/massivecore/MassiveCore.java index a6d0d736..3c52cc00 100644 --- a/src/com/massivecraft/massivecore/MassiveCore.java +++ b/src/com/massivecraft/massivecore/MassiveCore.java @@ -23,6 +23,8 @@ import com.massivecraft.massivecore.adapter.MassiveSetAdapter; import com.massivecraft.massivecore.adapter.MassiveTreeMapAdapter; import com.massivecraft.massivecore.adapter.MassiveTreeSetAdapter; import com.massivecraft.massivecore.adapter.ModdedEnumTypeAdapter; +import com.massivecraft.massivecore.adapter.MsonAdapter; +import com.massivecraft.massivecore.adapter.MsonEventAdapter; import com.massivecraft.massivecore.adapter.PlayerInventoryAdapter; import com.massivecraft.massivecore.adapter.UUIDAdapter; import com.massivecraft.massivecore.chestgui.EngineChestGui; @@ -44,6 +46,8 @@ import com.massivecraft.massivecore.collections.MassiveTreeSet; import com.massivecraft.massivecore.collections.MassiveTreeSetDef; import com.massivecraft.massivecore.integration.vault.IntegrationVault; import com.massivecraft.massivecore.mixin.EngineTeleportMixinCause; +import com.massivecraft.massivecore.mson.Mson; +import com.massivecraft.massivecore.mson.MsonEvent; import com.massivecraft.massivecore.ps.PS; import com.massivecraft.massivecore.ps.PSAdapter; import com.massivecraft.massivecore.store.ExamineThread; @@ -52,6 +56,7 @@ import com.massivecraft.massivecore.util.IdUtil; import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.PlayerUtil; import com.massivecraft.massivecore.util.TimeUnit; +import com.massivecraft.massivecore.util.Txt; import com.massivecraft.massivecore.xlib.gson.Gson; import com.massivecraft.massivecore.xlib.gson.GsonBuilder; import com.massivecraft.massivecore.xlib.gson.JsonArray; @@ -67,6 +72,7 @@ public class MassiveCore extends MassivePlugin public final static String INSTANCE = "instance"; public final static String DEFAULT = "default"; + public static final String NONE = Txt.parse("none"); public final static Set NOTHING = MUtil.treeset("", "none", "null", "nothing"); public final static Set REMOVE = MUtil.treeset("clear", "c", "delete", "del", "d", "erase", "e", "remove", "rem", "r", "reset", "res"); @@ -115,6 +121,9 @@ public class MassiveCore extends MassivePlugin .registerTypeAdapter(MassiveTreeSet.class, MassiveTreeSetAdapter.get()) .registerTypeAdapter(MassiveTreeSetDef.class, MassiveTreeSetAdapter.get()) + .registerTypeAdapter(Mson.class, MsonAdapter.get()) + .registerTypeAdapter(MsonEvent.class, MsonEventAdapter.get()) + .registerTypeAdapter(BackstringEnumSet.class, BackstringEnumSetAdapter.get()) .registerTypeAdapter(Entry.class, EntryAdapter.get()) diff --git a/src/com/massivecraft/massivecore/PriorityLines.java b/src/com/massivecraft/massivecore/PriorityLines.java index cd113c3a..56daba25 100644 --- a/src/com/massivecraft/massivecore/PriorityLines.java +++ b/src/com/massivecraft/massivecore/PriorityLines.java @@ -1,10 +1,10 @@ package com.massivecraft.massivecore; import java.util.Arrays; +import java.util.Collections; import java.util.LinkedList; import java.util.List; -import com.massivecraft.massivecore.Prioritized; import com.massivecraft.massivecore.util.MUtil; public class PriorityLines implements Prioritized, Comparable @@ -19,8 +19,9 @@ public class PriorityLines implements Prioritized, Comparable private List lines; public List getLines() { return this.lines; } - public void setLines(List lines) { this.lines = lines; } + public void setLines(List lines) { this.lines = lines; } public void setLines(String... lines) { this.setLines(Arrays.asList(lines)); } + public void setLines(String line) { this.setLines(Collections.singletonList(line)); } // -------------------------------------------- // // CONSTRUCT @@ -61,7 +62,7 @@ public class PriorityLines implements Prioritized, Comparable { int ret; - ret = Integer.valueOf(this.priority).compareTo(that.priority); + ret = Integer.compare(this.priority, that.priority); if (ret != 0) return ret; if (MUtil.equals(this.lines, that.lines)) return 0; @@ -89,15 +90,10 @@ public class PriorityLines implements Prioritized, Comparable public boolean equals(Object obj) { if (this == obj) return true; - if (obj == null) return false; if (!(obj instanceof PriorityLines)) return false; PriorityLines other = (PriorityLines) obj; - if (lines == null) - { - if (other.lines != null) return false; - } - else if (!lines.equals(other.lines)) return false; if (priority != other.priority) return false; + if ( ! MUtil.equals(this.lines, other.lines)) return false; return true; } diff --git a/src/com/massivecraft/massivecore/adapter/LowercaseEnumAdapter.java b/src/com/massivecraft/massivecore/adapter/LowercaseEnumAdapter.java index 89d7fc94..d7cf5bad 100644 --- a/src/com/massivecraft/massivecore/adapter/LowercaseEnumAdapter.java +++ b/src/com/massivecraft/massivecore/adapter/LowercaseEnumAdapter.java @@ -59,6 +59,16 @@ public class LowercaseEnumAdapter> implements JsonDeserializer // UTIL // -------------------------------------------- // + public T getEnumValueFrom(JsonElement json) + { + return getEnumValueFrom(json.toString()); + } + + public T getEnumValueFrom(String str) + { + return getEnumValueFrom(str, clazz); + } + public static T[] getEnumValues(Class clazz) { if (clazz == null) throw new IllegalArgumentException("passed clazz param is null"); @@ -82,14 +92,13 @@ public class LowercaseEnumAdapter> implements JsonDeserializer return string.toLowerCase(); } - public T getEnumValueFrom(JsonElement json) + public static> T getEnumValueFrom(String str, Class clazz) { - String jsonString = json.getAsString(); - jsonString = getComparable(jsonString); + str = getComparable(str); for (T value : getEnumValues(clazz)) { - if (getComparable(value).equals(jsonString)) return value; + if (getComparable(value).equals(str)) return value; } return null; diff --git a/src/com/massivecraft/massivecore/adapter/MsonAdapter.java b/src/com/massivecraft/massivecore/adapter/MsonAdapter.java new file mode 100644 index 00000000..82bacde0 --- /dev/null +++ b/src/com/massivecraft/massivecore/adapter/MsonAdapter.java @@ -0,0 +1,41 @@ +package com.massivecraft.massivecore.adapter; + +import java.lang.reflect.Type; + +import com.massivecraft.massivecore.mson.Mson; +import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext; +import com.massivecraft.massivecore.xlib.gson.JsonDeserializer; +import com.massivecraft.massivecore.xlib.gson.JsonElement; +import com.massivecraft.massivecore.xlib.gson.JsonNull; +import com.massivecraft.massivecore.xlib.gson.JsonParseException; +import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext; +import com.massivecraft.massivecore.xlib.gson.JsonSerializer; + +public class MsonAdapter implements JsonDeserializer, JsonSerializer +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + public static MsonAdapter i = new MsonAdapter(); + public static MsonAdapter get() { return i; } + public MsonAdapter() {} + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public JsonElement serialize(Mson src, Type typeOfSrc, JsonSerializationContext context) + { + if (src == null) return JsonNull.INSTANCE; + return src.toJson(); + } + + @Override + public Mson deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException + { + return Mson.fromJson(json.getAsJsonObject()); + } + +} diff --git a/src/com/massivecraft/massivecore/adapter/MsonEventAdapter.java b/src/com/massivecraft/massivecore/adapter/MsonEventAdapter.java new file mode 100644 index 00000000..02cff82c --- /dev/null +++ b/src/com/massivecraft/massivecore/adapter/MsonEventAdapter.java @@ -0,0 +1,40 @@ +package com.massivecraft.massivecore.adapter; + +import java.lang.reflect.Type; + +import com.massivecraft.massivecore.mson.Mson; +import com.massivecraft.massivecore.mson.MsonEvent; +import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext; +import com.massivecraft.massivecore.xlib.gson.JsonDeserializer; +import com.massivecraft.massivecore.xlib.gson.JsonElement; +import com.massivecraft.massivecore.xlib.gson.JsonParseException; +import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext; +import com.massivecraft.massivecore.xlib.gson.JsonSerializer; + +public class MsonEventAdapter implements JsonDeserializer, JsonSerializer +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + public static MsonEventAdapter i = new MsonEventAdapter(); + public static MsonEventAdapter get() { return i; } + public MsonEventAdapter() {} + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public JsonElement serialize(MsonEvent src, Type typeOfSrc, JsonSerializationContext context) + { + return Mson.GSON.toJsonTree(src); + } + + @Override + public MsonEvent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException + { + return Mson.GSON.fromJson(json, MsonEvent.class); + } + +} diff --git a/src/com/massivecraft/massivecore/cmd/MassiveCommand.java b/src/com/massivecraft/massivecore/cmd/MassiveCommand.java index a696dde9..dee98ccd 100644 --- a/src/com/massivecraft/massivecore/cmd/MassiveCommand.java +++ b/src/com/massivecraft/massivecore/cmd/MassiveCommand.java @@ -12,6 +12,7 @@ import java.util.Map.Entry; import java.util.Set; import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; @@ -970,6 +971,45 @@ public class MassiveCommand return getUseageTemplate(false); } + public String getCommandLine(String... args) + { + return getCommandLine(Arrays.asList(args)); + } + + public String getCommandLine(Iterable args) + { + // Initiate ret + StringBuilder ret = new StringBuilder(); + + // First a slash + ret.append('/'); + + // Then parent commands + for (MassiveCommand parent : this.getCommandChain()) + { + // Append parent + ret.append(parent.getAliases().get(0)); + + // Append space + ret.append(' '); + } + // Then ourself + ret.append(this.getAliases().get(0)); + + // Then args + for (String arg : args) + { + // First a space + ret.append(' '); + + // Then the arg + ret.append(arg); + } + + // Return ret + return ret.toString(); + } + // -------------------------------------------- // // TAB // -------------------------------------------- // diff --git a/src/com/massivecraft/massivecore/cmd/req/ReqIsPlayer.java b/src/com/massivecraft/massivecore/cmd/req/ReqIsPlayer.java index 54ebba08..bee1295f 100644 --- a/src/com/massivecraft/massivecore/cmd/req/ReqIsPlayer.java +++ b/src/com/massivecraft/massivecore/cmd/req/ReqIsPlayer.java @@ -5,6 +5,7 @@ import org.bukkit.entity.Player; import com.massivecraft.massivecore.Lang; import com.massivecraft.massivecore.cmd.MassiveCommand; +import com.massivecraft.massivecore.util.Txt; public class ReqIsPlayer extends ReqAbstract { @@ -30,7 +31,7 @@ public class ReqIsPlayer extends ReqAbstract @Override public String createErrorMessage(CommandSender sender, MassiveCommand command) { - return Lang.COMMAND_SENDER_MUST_BE_PLAYER; + return Txt.parse(Lang.COMMAND_SENDER_MUST_BE_PLAYER); } } diff --git a/src/com/massivecraft/massivecore/cmd/req/ReqIsntPlayer.java b/src/com/massivecraft/massivecore/cmd/req/ReqIsntPlayer.java index 5b17bfe5..f29e739d 100644 --- a/src/com/massivecraft/massivecore/cmd/req/ReqIsntPlayer.java +++ b/src/com/massivecraft/massivecore/cmd/req/ReqIsntPlayer.java @@ -5,6 +5,7 @@ import org.bukkit.entity.Player; import com.massivecraft.massivecore.Lang; import com.massivecraft.massivecore.cmd.MassiveCommand; +import com.massivecraft.massivecore.util.Txt; public class ReqIsntPlayer extends ReqAbstract { @@ -30,7 +31,7 @@ public class ReqIsntPlayer extends ReqAbstract @Override public String createErrorMessage(CommandSender sender, MassiveCommand command) { - return Lang.COMMAND_SENDER_MUSNT_BE_PLAYER; + return Txt.parse(Lang.COMMAND_SENDER_MUSNT_BE_PLAYER); } } diff --git a/src/com/massivecraft/massivecore/collections/WorldExceptionSet.java b/src/com/massivecraft/massivecore/collections/WorldExceptionSet.java index 7e3dd86b..7f70e1ef 100644 --- a/src/com/massivecraft/massivecore/collections/WorldExceptionSet.java +++ b/src/com/massivecraft/massivecore/collections/WorldExceptionSet.java @@ -1,9 +1,11 @@ package com.massivecraft.massivecore.collections; +import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Entity; import com.massivecraft.massivecore.CaseInsensitiveComparator; +import com.massivecraft.massivecore.ps.PS; public class WorldExceptionSet { @@ -39,11 +41,21 @@ public class WorldExceptionSet return this.standard; } + public boolean contains(PS ps) + { + return this.contains(ps.getWorld()); + } + public boolean contains(World world) { return this.contains(world.getName()); } + public boolean contains(Location loc) + { + return this.contains(loc.getWorld()); + } + public boolean contains(Entity entity) { return this.contains(entity.getWorld()); diff --git a/src/com/massivecraft/massivecore/mixin/CommandMixinDefault.java b/src/com/massivecraft/massivecore/mixin/CommandMixinDefault.java index 6957340f..6ecdf846 100644 --- a/src/com/massivecraft/massivecore/mixin/CommandMixinDefault.java +++ b/src/com/massivecraft/massivecore/mixin/CommandMixinDefault.java @@ -34,4 +34,4 @@ public class CommandMixinDefault extends CommandMixinAbstract return true; } -} \ No newline at end of file +} diff --git a/src/com/massivecraft/massivecore/mixin/DisplayNameMixin.java b/src/com/massivecraft/massivecore/mixin/DisplayNameMixin.java index 57470509..21c6f7aa 100644 --- a/src/com/massivecraft/massivecore/mixin/DisplayNameMixin.java +++ b/src/com/massivecraft/massivecore/mixin/DisplayNameMixin.java @@ -1,6 +1,9 @@ package com.massivecraft.massivecore.mixin; +import com.massivecraft.massivecore.mson.Mson; + public interface DisplayNameMixin { + public Mson getDisplayNameMson(Object senderObject, Object watcherObject); public String getDisplayName(Object senderObject, Object watcherObject); } diff --git a/src/com/massivecraft/massivecore/mixin/DisplayNameMixinAbstract.java b/src/com/massivecraft/massivecore/mixin/DisplayNameMixinAbstract.java index b2e51153..2e694f26 100644 --- a/src/com/massivecraft/massivecore/mixin/DisplayNameMixinAbstract.java +++ b/src/com/massivecraft/massivecore/mixin/DisplayNameMixinAbstract.java @@ -1,6 +1,11 @@ package com.massivecraft.massivecore.mixin; +import com.massivecraft.massivecore.mson.Mson; + public abstract class DisplayNameMixinAbstract implements DisplayNameMixin { - -} \ No newline at end of file + public Mson getDisplayNameMson(Object senderObject, Object watcherObject) + { + return Mson.fromParsedMessage(this.getDisplayName(senderObject, watcherObject)); + } +} diff --git a/src/com/massivecraft/massivecore/mixin/DisplayNameMixinDefault.java b/src/com/massivecraft/massivecore/mixin/DisplayNameMixinDefault.java index 71d09963..59cdce5c 100644 --- a/src/com/massivecraft/massivecore/mixin/DisplayNameMixinDefault.java +++ b/src/com/massivecraft/massivecore/mixin/DisplayNameMixinDefault.java @@ -3,6 +3,7 @@ package com.massivecraft.massivecore.mixin; import org.bukkit.ChatColor; import org.bukkit.entity.Player; +import com.massivecraft.massivecore.mson.Mson; import com.massivecraft.massivecore.util.IdUtil; public class DisplayNameMixinDefault extends DisplayNameMixinAbstract @@ -60,4 +61,4 @@ public class DisplayNameMixinDefault extends DisplayNameMixinAbstract return ret; } -} \ No newline at end of file +} diff --git a/src/com/massivecraft/massivecore/mixin/KickMixinDefault.java b/src/com/massivecraft/massivecore/mixin/KickMixinDefault.java index 62f7079e..20ad6f6a 100644 --- a/src/com/massivecraft/massivecore/mixin/KickMixinDefault.java +++ b/src/com/massivecraft/massivecore/mixin/KickMixinDefault.java @@ -26,4 +26,4 @@ public class KickMixinDefault extends KickMixinAbstract return true; } -} \ No newline at end of file +} diff --git a/src/com/massivecraft/massivecore/mixin/Mixin.java b/src/com/massivecraft/massivecore/mixin/Mixin.java index 9c4f127f..54aca4dd 100644 --- a/src/com/massivecraft/massivecore/mixin/Mixin.java +++ b/src/com/massivecraft/massivecore/mixin/Mixin.java @@ -141,6 +141,11 @@ public class Mixin return getDisplayNameMixin().getDisplayName(senderObject, watcherObject); } + public static Mson getDisplayNameMson(Object senderObject, Object watcherObject) + { + return getDisplayNameMixin().getDisplayNameMson(senderObject, watcherObject); + } + // -------------------------------------------- // // STATIC EXPOSE: INVENTORY // -------------------------------------------- // @@ -163,7 +168,7 @@ public class Mixin { return getSenderPsMixin().getSenderPs(senderObject); } - + public static void setSenderPs(Object senderObject, PS ps) { getSenderPsMixin().setSenderPs(senderObject, ps); @@ -418,5 +423,5 @@ public class Mixin { return getCommandMixin().dispatchCommand(presentObject, senderObject, commandLine); } - + } diff --git a/src/com/massivecraft/massivecore/mixin/PlayedMixinDefault.java b/src/com/massivecraft/massivecore/mixin/PlayedMixinDefault.java index 4bd1073a..8e1e4abe 100644 --- a/src/com/massivecraft/massivecore/mixin/PlayedMixinDefault.java +++ b/src/com/massivecraft/massivecore/mixin/PlayedMixinDefault.java @@ -52,4 +52,4 @@ public class PlayedMixinDefault extends PlayedMixinAbstract return ret; } -} \ No newline at end of file +} diff --git a/src/com/massivecraft/massivecore/mixin/WorldMixinAbstract.java b/src/com/massivecraft/massivecore/mixin/WorldMixinAbstract.java index 66acd3e2..bbe75ab6 100644 --- a/src/com/massivecraft/massivecore/mixin/WorldMixinAbstract.java +++ b/src/com/massivecraft/massivecore/mixin/WorldMixinAbstract.java @@ -37,4 +37,4 @@ public abstract class WorldMixinAbstract implements WorldMixin return this.getWorldColor(worldId).toString()+this.getWorldAliasOrId(worldId); } -} \ No newline at end of file +} diff --git a/src/com/massivecraft/massivecore/mixin/WorldMixinDefault.java b/src/com/massivecraft/massivecore/mixin/WorldMixinDefault.java index 5227ed01..1b1392d1 100644 --- a/src/com/massivecraft/massivecore/mixin/WorldMixinDefault.java +++ b/src/com/massivecraft/massivecore/mixin/WorldMixinDefault.java @@ -127,4 +127,4 @@ public class WorldMixinDefault extends WorldMixinAbstract return true; } -} \ No newline at end of file +} diff --git a/src/com/massivecraft/massivecore/money/MoneyMixinAbstract.java b/src/com/massivecraft/massivecore/money/MoneyMixinAbstract.java index 44949bd1..9cf6bd72 100644 --- a/src/com/massivecraft/massivecore/money/MoneyMixinAbstract.java +++ b/src/com/massivecraft/massivecore/money/MoneyMixinAbstract.java @@ -1,8 +1,7 @@ package com.massivecraft.massivecore.money; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; +import java.util.Collections; public abstract class MoneyMixinAbstract implements MoneyMixin { @@ -48,7 +47,7 @@ public abstract class MoneyMixinAbstract implements MoneyMixin public boolean move(String fromId, String toId, String byId, double amount, String category, String message) { - return this.move(fromId, toId, byId, amount, (category == null ? null : Arrays.asList(category)), message); + return this.move(fromId, toId, byId, amount, (category == null ? null : Collections.singletonList(category)), message); } public boolean move(String fromId, String toId, String byId, double amount, Collection categories) { @@ -56,11 +55,11 @@ public abstract class MoneyMixinAbstract implements MoneyMixin } public boolean move(String fromId, String toId, String byId, double amount, String category) { - return this.move(fromId, toId, byId, amount, (category == null ? null : Arrays.asList(category)), null); + return this.move(fromId, toId, byId, amount, (category == null ? null : Collections.singletonList(category)), null); } public boolean move(String fromId, String toId, String byId, double amount) { - return this.move(fromId, toId, byId, amount, new ArrayList(), null); + return this.move(fromId, toId, byId, amount, Collections.emptyList(), null); } // -------------------------------------------- // diff --git a/src/com/massivecraft/massivecore/mson/Mson.java b/src/com/massivecraft/massivecore/mson/Mson.java index 8c0dbf74..684f0e8c 100644 --- a/src/com/massivecraft/massivecore/mson/Mson.java +++ b/src/com/massivecraft/massivecore/mson/Mson.java @@ -14,8 +14,10 @@ import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.inventory.ItemStack; +import com.google.common.collect.ImmutableList; import com.massivecraft.massivecore.Predictate; import com.massivecraft.massivecore.adapter.LowercaseEnumAdapter; +import com.massivecraft.massivecore.cmd.MassiveCommand; import com.massivecraft.massivecore.collections.MassiveList; import com.massivecraft.massivecore.mixin.Mixin; import com.massivecraft.massivecore.util.MUtil; @@ -23,6 +25,7 @@ import com.massivecraft.massivecore.util.Txt; import com.massivecraft.massivecore.xlib.gson.Gson; import com.massivecraft.massivecore.xlib.gson.GsonBuilder; import com.massivecraft.massivecore.xlib.gson.JsonElement; +import com.massivecraft.massivecore.xlib.gson.JsonObject; public class Mson implements Serializable { @@ -55,124 +58,159 @@ public class Mson implements Serializable // A parents text can't be null, then Mojang throws an exception. // It does not make sense for something which doesn't have extras // to not have text, because then it doesn't show up at all. - protected String text = ""; - public String text() { return this.text; } - public Mson text(String text) { this.text = Objects.requireNonNull(text); return this; } - public boolean textHas() { return ! this.text().isEmpty(); } + private final String text; + public String getText() { return this.text; } // FIELD: Color of the mson - protected ChatColor color = null; - public ChatColor color() { return this.color; } - public ChatColor colorEffective() { return color() != null ? color() : colorInherited(); } - public ChatColor colorInherited() { return parentHas() ? parent().colorEffective() : null; } - public Mson color(ChatColor color) - { - if (color != null && ! color.isColor()) throw new IllegalArgumentException("Color must be a color."); - this.color = color; - return this; - } + private final ChatColor color; + public ChatColor getColor() { return this.color; } + public ChatColor getEffectiveColor() { return color != null ? color : getInheritedColor(); } + public ChatColor getInheritedColor() { return hasParent() ? getParent().getEffectiveColor() : null; } // FIELD: bold - protected Boolean bold = null; - public Boolean bold() { return bold; } - public Mson bold(Boolean bold) { this.bold = bold; return this; } - public boolean boldEffective() { return bold() != null ? bold() : boldInherited(); } - public boolean boldInherited() { return parentHas() && parent().boldEffective(); } + private final Boolean bold; + public Boolean isBold() { return bold; } + public boolean isEffectiveBold() { return bold != null ? bold : isInheritedBold(); } + public boolean isInheritedBold() { return hasParent() && getParent().isEffectiveBold(); } // FIELD: italic - protected Boolean italic = null; - public Boolean italic() { return this.italic; } - public Mson italic(Boolean italic) { this.italic = italic; return this; } - public boolean italicEffective() { return italic() != null ? italic() : italicInherited(); } - protected boolean italicInherited() { return parentHas() && parent().italicEffective(); } + private final Boolean italic; + public Boolean isItalic() { return this.italic; } + public boolean isEffectiveItalic() { return italic != null ? italic : isInheritedItalic(); } + protected boolean isInheritedItalic() { return hasParent() && getParent().isEffectiveItalic(); } // FIELD: underlined - protected Boolean underlined = null; - public Boolean underlined() { return this.underlined; } - public Mson underlined(Boolean underlined) { this.underlined = underlined; return this; } - public boolean underlinedEffective() { return italic() != null ? italic() : italicInherited(); } - protected boolean underlinedInherited() { return parentHas() && parent().underlinedEffective(); } + private final Boolean underlined; + public Boolean isUnderlined() { return this.underlined; } + public boolean isEffectiveUnderlined() { return underlined != null ? underlined : isInheritedUnderlined(); } + protected boolean isInheritedUnderlined() { return hasParent() && getParent().isEffectiveUnderlined(); } // FIELD: strikethrough - protected Boolean strikethrough = null; - public Boolean strikethrough() { return this.strikethrough; } - public Mson strikethrough(Boolean strikethrough) { this.strikethrough = strikethrough; return this; } - public boolean strikethroughEffective() { return strikethrough() != null ? strikethrough() : strikethroughInherited(); } - protected boolean strikethroughInherited() { return parentHas() && parent().strikethroughEffective(); } + private final Boolean strikethrough; + public Boolean isStrikethrough() { return this.strikethrough; } + public boolean isEffectiveStrikethrough() { return strikethrough != null ? strikethrough : isInheritedStrikethrough(); } + protected boolean isInheritedStrikethrough() { return hasParent() && getParent().isEffectiveStrikethrough(); } // FIELD: obfuscated - protected Boolean obfuscated = null; - public Boolean obfuscated() { return this.obfuscated; } - public Mson obfuscated(Boolean obfuscated) { this.obfuscated = obfuscated; return this; } - public boolean obfuscatedEffective() { return obfuscated() != null ? obfuscated() : obfuscatedInherited(); } - protected boolean obfuscatedInherited() { return parentHas() && parent().obfuscatedEffective(); } + private final Boolean obfuscated; + public Boolean isObfuscated() { return this.obfuscated; } + public boolean isEffectiveObfuscated() { return obfuscated != null ? obfuscated : isInheritedObfuscated(); } + protected boolean isInheritedObfuscated() { return hasParent() && getParent().isEffectiveObfuscated(); } // FIELD: The Events which happen when you click, hover over or shift-click the message - protected MsonEvent clickEvent = null; - public MsonEvent clickEvent() { return this.clickEvent; } - public MsonEvent clickEventEffective() { return clickEvent() != null ? clickEvent() : clickEventInherited(); } - protected MsonEvent clickEventInherited() { return this.parentHas() ? this.parent().clickEventEffective() : null; } - public Mson clickEvent(MsonEvent clickEvent) - { - if (clickEvent != null && ! clickEvent.isClickEvent()) throw new IllegalArgumentException("ClickEvent may not be a HoverEvent."); - this.clickEvent = clickEvent; - return this; - } + private final MsonEvent clickEvent; + public MsonEvent getClickEvent() { return this.clickEvent; } + public MsonEvent getEffectiveClickEvent() { return clickEvent != null ? clickEvent : getInheritedClickEvent(); } + protected MsonEvent getInheritedClickEvent() { return this.hasParent() ? this.getParent().getEffectiveClickEvent() : null; } - protected MsonEvent hoverEvent = null; - public MsonEvent hoverEvent() { return this.hoverEvent; } - public MsonEvent hoverEventEffective() { return hoverEvent() != null ? hoverEvent() : hoverEventInherited(); } - protected MsonEvent hoverEventInherited() { return this.parentHas() ? this.parent().hoverEventEffective() : null; } - public Mson hoverEvent(MsonEvent hoverEvent) - { - if (hoverEvent != null && ! hoverEvent.isHoverEvent()) throw new IllegalArgumentException("HoverEvent may not be a ClickEvent."); - this.hoverEvent = hoverEvent; - return this; - } + private final MsonEvent hoverEvent; + public MsonEvent getHoverEvent() { return this.hoverEvent; } + public MsonEvent getEffectiveHoverEvent() { return hoverEvent != null ? hoverEvent : getInheritedHoverEvent(); } + protected MsonEvent getInheritedHoverEvent() { return this.hasParent() ? this.getParent().getEffectiveHoverEvent() : null; } - protected String insertionString = null; - public String insertionString() { return this.insertionString; } - public String insertionStringEffective() { return insertionString() != null ? insertionString() : insertionStringInherited(); } - public Mson insertionString(String insertionString) { this.insertionString = insertionString; return this; } - protected String insertionStringInherited() { return this.parentHas() ? this.parent().insertionStringEffective() : null; } + private final String insertionString; + public String getInsertionString() { return this.insertionString; } + public String getEffectiveInsertionString() { return insertionString != null ? insertionString : getInheritedInsertionString(); } + protected String getInheritedInsertionString() { return this.hasParent() ? this.getParent().getEffectiveInsertionString() : null; } // The other parts of the message - protected List extra = null; - public List extra() { return this.extra; } - public Mson extra(List extra) { this.extra = extra; return this; } - public boolean extraHas() { return this.extra() != null; } - - public List extraCreative() - { - if ( ! this.extraHas()) this.extra(new MassiveList()); - return this.extra(); - } + private final List extra; + public List getExtra() { return this.extra; } + public boolean hasExtra() { return this.getExtra() != null; } // Parent & Root - protected transient Mson parent = null; - public Mson parent() { return this.parent; } - public Mson parent(Mson parent) { this.parent = parent; return this; } - public boolean parentHas() { return this.parent() != null; } + private final transient Mson parent; + public Mson getParent() { return this.parent; } + public boolean hasParent() { return this.getParent() != null; } - public Mson parentCreative() - { - if ( ! this.parentHas()) this.parent(new Mson()); - return this.parent(); - } - - public boolean isRoot() { return this.parent() == null; } - public Mson root() + public boolean isRoot() { return this.getParent() == null; } + public Mson getRoot() { Mson root = this; while (true) { - Mson parent = root.parent(); + Mson parent = root.getParent(); if (parent == null) break; root = parent; } return root; } + + // -------------------------------------------- // + // STATE CHECKING + // -------------------------------------------- // + + public boolean isEmpty() + { + // It has text, not empty. + if ( ! this.getText().isEmpty()) return false; + if (this.hasExtra()) + { + for (Mson extra : this.getExtra()) + { + // It is empty + if (extra.isEmpty()) continue; + + // It was not empty. + return false; + } + } + + // We are empty. + return true; + } + + public boolean isTextOnly() + { + if (this.getColor() != null) return false; + if (this.isBold() != null) return false; + if (this.isItalic() != null) return false; + if (this.isUnderlined() != null) return false; + if (this.isStrikethrough() != null) return false; + if (this.isObfuscated() != null) return false; + if (this.getClickEvent() != null) return false; + if (this.getHoverEvent() != null) return false; + if (this.getInsertionString() != null) return false; + if (this.hasExtra()) return false; + return true; + } + + public boolean hasSpecialBehaviour() + { + if (this.getClickEvent() != null) return true; + if (this.getHoverEvent() != null) return true; + if (this.getInsertionString() != null) return true; + + if (this.hasExtra()) + { + for (Mson extra : this.getExtra()) + { + if (extra.hasSpecialBehaviour()) return true; + } + } + + return false; + } + + // -------------------------------------------- // + // WITH FIELDS + // -------------------------------------------- // + + public Mson text(String text) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + public Mson color(ChatColor color) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + public Mson bold(Boolean bold) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + public Mson italic(Boolean italic) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + public Mson underlined(Boolean underlined) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + public Mson strikethrough(Boolean strikethrough) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + public Mson obfuscated(Boolean obfuscated) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + public Mson clickEvent(MsonEvent clickEvent) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + public Mson hoverEvent(MsonEvent hoverEvent) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + public Mson insertionString(String insertionString) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + public Mson extra(List extra) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + public Mson extra(Mson[] extra) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, ImmutableList.copyOf(extra), parent); } + public Mson parent(Mson parent) { return Mson.valueOf(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); } + // -------------------------------------------- // // CONVENIENCE MSON EVENT // -------------------------------------------- // @@ -180,16 +218,20 @@ public class Mson implements Serializable public Mson link(String link) { this.clickEvent(MsonEvent.openUrl(link)); return this; } public Mson suggest(String replace) { this.clickEvent(MsonEvent.replace(replace)); return this; } + public Mson suggest(MassiveCommand command, String... args) { this.clickEvent(MsonEvent.replace(command, args)); return this; } + public Mson suggest(MassiveCommand command, Iterable args) { this.clickEvent(MsonEvent.replace(command, args)); return this; } public Mson command(String command) { this.clickEvent(MsonEvent.performCmd(command)); return this; } + public Mson command(MassiveCommand command, String... args) { this.clickEvent(MsonEvent.performCmd(command, args)); return this; } + public Mson command(MassiveCommand command, Iterable args) { this.clickEvent(MsonEvent.performCmd(command, args)); return this; } - public Mson tooltip(String tooltip) { this.hoverEvent(MsonEvent.hoverText(text)); return this; } - public Mson tooltip(String... tooltip) { this.hoverEvent(MsonEvent.hoverText(text)); return this; } - public Mson tooltip(Collection tooltip) { this.hoverEvent(MsonEvent.hoverText(text)); return this; } + public Mson tooltip(String tooltip) { this.hoverEvent(MsonEvent.hoverText(tooltip)); return this; } + public Mson tooltip(String... tooltip) { this.hoverEvent(MsonEvent.hoverText(tooltip)); return this; } + public Mson tooltip(Collection tooltip) { this.hoverEvent(MsonEvent.hoverText(tooltip)); return this; } - public Mson tooltipParse(String tooltip) { this.hoverEvent(MsonEvent.hoverTextParse(text)); return this; } - public Mson tooltipParse(String... tooltip) { this.hoverEvent(MsonEvent.hoverTextParse(text)); return this; } - public Mson tooltipParse(Collection tooltip) { this.hoverEvent(MsonEvent.hoverTextParse(text)); return this; } + public Mson tooltipParse(String tooltip) { this.hoverEvent(MsonEvent.hoverTextParse(tooltip)); return this; } + public Mson tooltipParse(String... tooltip) { this.hoverEvent(MsonEvent.hoverTextParse(tooltip)); return this; } + public Mson tooltipParse(Collection tooltip) { this.hoverEvent(MsonEvent.hoverTextParse(tooltip)); return this; } public Mson tooltip(ItemStack item) { this.hoverEvent(MsonEvent.item(item)); return this; } @@ -199,15 +241,18 @@ public class Mson implements Serializable public Mson style(ChatColor... styles) { + Mson ret = this; for (ChatColor style : styles) { - this.style(style); + ret = ret.style(style); } - return this; + return ret; } public Mson style(ChatColor style) { + if (style == null) throw new NullPointerException("style"); + if (style == ChatColor.RESET) return this.removeStyles(); if (style == ChatColor.BOLD) return this.bold(true); if (style == ChatColor.ITALIC) return this.italic(true); @@ -223,138 +268,110 @@ public class Mson implements Serializable { // NOTE: We can't use null. // Since we want to override color and format in parents. - this.color = ChatColor.WHITE; - this.bold = false; - this.italic = false; - this.underlined = false; - this.strikethrough = false; - this.obfuscated = false; + return Mson.valueOf(text, ChatColor.WHITE, false, false, false, false, false, clickEvent, hoverEvent, insertionString, extra, parent); + } + + public Mson stripStyle() + { + Mson ret = Mson.valueOf(text, null, null, null, null, null, null, clickEvent, hoverEvent, insertionString, null, parent); + + if (this.hasExtra()) + { + Mson[] extra = new Mson[this.getExtra().size()]; + int i = 0; + for (Mson part : this.getExtra()) + { + extra[i] = part.stripStyle(); + i++; + } + ret = ret.extra(extra); + } + return this; } - // -------------------------------------------- // - // BUILD TREE - // -------------------------------------------- // - - // Child, called on parent or root - public Mson addChild(Object child) - { - if (child == null) throw new NullPointerException("child"); - - Mson mson = Mson.mson(child); - List extra = this.extraCreative(); - - mson.parent(this); - extra.add(mson); - - return mson; // Return child - } - - public Mson addChildren(Object... children) - { - if (children == null) throw new NullPointerException("children"); - - for (Object part : children) - { - this.addChild(part); - } - - return this; // Return this - } - - // Sibling, normally called on child - public Mson addSibling(Object sibling) - { - if (sibling == null) throw new NullPointerException("sibling"); - Mson parent = this.parentCreative(); - return parent.addChild(sibling); // Return sibling - } - - public Mson addSiblings(Object... siblings) - { - if (siblings == null) throw new NullPointerException("siblings"); - Mson parent = this.parentCreative(); - - if ( ! parent.equals(this.parent())) this.parent(parent); - parent.addChildren(siblings); - return this; // Return this - } - - // -------------------------------------------- // - // SIMPLE CLEAN - // -------------------------------------------- // - // These methods, exist to clean up after mistakes. - // So they are very forgiving. - - public boolean isEmpty() - { - // It has text, not empty. - if (this.textHas()) return false; - - if (this.extraHas()) - { - for (Mson extra : this.extra()) - { - // It is null. So kinda empty. - if (extra == null) continue; - - // It is empty - if (extra.isEmpty()) continue; - - // It was not empty. - return false; - } - } - - // We are empty. - return true; - } - - // Detaches uneccessary extras. - public Mson simpleClean() - { - if ( ! this.extraHas()) return this; - if (this.extra().isEmpty()) - { - this.extra(null); - return this; - } - - for (ListIterator it = this.extra().listIterator(); it.hasNext();) - { - Mson extra = it.next(); - if (extra == null) - { - it.remove(); - continue; - } - - if (extra.isEmpty()) - { - extra.parent(null); - it.remove(); - continue; - } - - extra.simpleClean(); - } - return this; - } - // -------------------------------------------- // // CONSTRUCT // -------------------------------------------- // - public Mson() - { - - } + // Empty + private static final Mson EMPTY = mson(""); public static Mson mson() { - return new Mson(); + return EMPTY; } + // Text + Mson(String text) + { + this(text, null, null, null, null, null, null, null, null, null, null, null); + } + + public static Mson mson(String text) + { + return new Mson(text); + } + + // Full + Mson(String text, ChatColor color, Boolean bold, Boolean italic, Boolean underlined, Boolean strikethrough, Boolean obfuscated, MsonEvent clickEvent, MsonEvent hoverEvent, String insertionString, List extra, Mson parent) + { + // Text + this.text = Objects.requireNonNull(text); + + // Color + if (color != null && ! color.isColor()) throw new IllegalArgumentException(color.name() + " is not a color"); + this.color = color; + + // Format + this.bold = bold; + this.italic = italic; + this.underlined = underlined; + this.strikethrough = strikethrough; + this.obfuscated = obfuscated; + + // Click event + if ( clickEvent != null && ! clickEvent.isClickEvent()) throw new IllegalArgumentException(clickEvent.getEventActionType().name() + " is not a clickEventType"); + this.clickEvent = clickEvent; + + // Hover event + if ( hoverEvent != null && ! hoverEvent.isHoverEvent()) throw new IllegalArgumentException(hoverEvent.getEventActionType().name() + " is not a hoverEventType"); + this.hoverEvent = hoverEvent; + + // Insertionstring + this.insertionString = insertionString; + + // Mojang doesn't allow zero sized arrays, but null is fine. So null. + if (extra != null && extra.size() == 0) extra = null; + + // Extra + if (extra != null) + { + Mson[] extras = new Mson[extra.size()]; + for (ListIterator it = extra.listIterator(); it.hasNext();) + { + int i = it.nextIndex(); + Mson part = it.next(); + extras[i] = part.parent(this); + } + this.extra = ImmutableList.copyOf(extras); + } + else + { + this.extra = null; + } + + // Parent + if (this == parent) throw new IllegalArgumentException("Parent can't be oneself."); + this.parent = parent; + } + + public static Mson valueOf(String text, ChatColor color, Boolean bold, Boolean italic, Boolean underlined, Boolean strikethrough, Boolean obfuscated, MsonEvent clickEvent, MsonEvent hoverEvent, String insertionString, List extra, Mson parent) + { + return new Mson(text, color, bold, italic, underlined, strikethrough, obfuscated, clickEvent, hoverEvent, insertionString, extra, parent); + } + + // Object public static Mson mson(Object part) { return Mson.getMson(part); @@ -376,7 +393,7 @@ public class Mson implements Serializable else if (part instanceof String) { String text = (String) part; - return mson().text(text); + return mson(text); } else if (part instanceof Collection) { @@ -401,6 +418,8 @@ public class Mson implements Serializable public static List msons(Object... parts) { + if (parts == null) throw new NullPointerException("parts"); + return msons(Arrays.asList(parts)); } @@ -417,6 +436,10 @@ public class Mson implements Serializable return msons; } + + // -------------------------------------------- // + // PARSE & FORMAT + // -------------------------------------------- // public static Mson fromParsedMessage(String message) { @@ -467,14 +490,7 @@ public class Mson implements Serializable // Don't add empty msons. if (text.isEmpty()) continue; - Mson mson = new Mson() - .text(text) - .color(latestColor) - .bold(bold) - .italic(italic) - .underlined(underlined) - .strikethrough(strikethrough) - .obfuscated(obfuscated); + Mson mson = Mson.valueOf(text, latestColor, bold, italic, underlined, strikethrough, obfuscated, null, null, null, null, null); msons.add(mson); } @@ -497,143 +513,146 @@ public class Mson implements Serializable public static Mson format(String format, Object... args) { - return Mson.mson().text(String.format(format, args)); - } - - public Mson copy() - { - Mson copy = new Mson() - .text(this.text) - .color(this.color) - .bold(this.bold) - .italic(this.italic) - .underlined(this.underlined) - .strikethrough(this.strikethrough) - .obfuscated(this.obfuscated) - .insertionString(this.insertionString) - .clickEvent(this.clickEvent) - .hoverEvent(this.hoverEvent); - - if (this.extraHas()) - { - List extras = new MassiveList(this.extra.size()); - for (Mson extra : this.extra) - { - Mson extraCopy = extra.copy(); - extraCopy.parent(copy); - extras.add(extraCopy); - } - copy.extra(extras); - } - - return copy; - } - - private Mson copyFormatAndBehaviour(Mson ancestor) - { - if (ancestor == null) throw new NullPointerException("ancestor"); - - this.color(ancestor.color()); - this.bold(ancestor.bold()); - this.italic(ancestor.italic()); - this.underlined(ancestor.underlined()); - this.strikethrough(ancestor.strikethrough()); - this.obfuscated(ancestor.obfuscated()); - this.hoverEvent(ancestor.hoverEvent()); - this.clickEvent(ancestor.clickEvent()); - this.insertionString(ancestor.insertionString()); - - return this; + return Mson.mson(String.format(format, args)); } // -------------------------------------------- // // STRING LIKE METHODS // -------------------------------------------- // - - // Split - public List split(String regex) + + // Case + public Mson toLowerCase() { - return this.split(regex, 0); - } + Mson ret = this.text(this.getText().toLowerCase()); + + if (this.hasExtra()) + { + Mson[] extra = new Mson[this.getExtra().size()]; + int i = 0; + for (Mson part : this.getExtra()) + { + extra[i] = part.toLowerCase(); + i++; + } + ret = ret.extra(extra); + } - public List split(String regex, int limit) - { - return split(Pattern.compile(regex), limit); + return ret; } - public List split(Pattern pattern) + public Mson toUpperCase() { - return this.split(pattern, 0); - } - - public List split(Pattern pattern, int limit) - { - if (pattern == null) throw new NullPointerException("pattern"); - - boolean limited = (limit == 0 ? false : true); - List msons = new MassiveList(); - - String[] splited = pattern.split(this.text(), limit); - if (splited.length == 1) return new MassiveList(this); - - for (String string : splited) + Mson ret = this.text(this.getText().toUpperCase()); + + if (this.hasExtra()) { - if (string.isEmpty()) continue; - Mson part = new Mson().text(string); - part.copyFormatAndBehaviour(this); - msons.add(part); - } - - int size = msons.size(); - - for (Mson part : this.extraCreative()) - { - if (limited) + Mson[] extra = new Mson[this.getExtra().size()]; + int i = 0; + for (Mson part : this.getExtra()) { - limit -= size; - if (limit <= 0) break; + extra[i] = part.toUpperCase(); + i++; } - - List innerMsons = part.split(pattern, limit); - msons.addAll(innerMsons); - size = innerMsons.size(); + ret = ret.extra(extra); } - return msons; + return ret; } + + public Mson uppercaseFirst() + { + if ( ! this.getText().isEmpty()) + { + return this.text(Txt.upperCaseFirst(this.getText())); + } + + Mson ret = this; + boolean uppercased = false; + + if (this.hasExtra()) + { + Mson[] extra = new Mson[this.getExtra().size()]; + int i = 0; + for (Mson part : this.getExtra()) + { + if ( ! uppercased) + { + Mson uppercase = part.uppercaseFirst(); + uppercased = (uppercase != part); + part = uppercase; + } + extra[i] = part; + i++; + } + if (uppercased) + { + ret = ret.extra(extra); + } + } + + return ret; + } + + // Whitespace + public Mson trim() + { + Mson ret = this.text(this.getText().trim()); + + if (this.hasExtra()) + { + Mson[] extra = new Mson[this.getExtra().size()]; + int i = 0; + for (Mson part : this.getExtra()) + { + extra[i] = part.trim(); + i++; + } + ret = ret.extra(extra); + } + return ret; + } + // Replace public Mson replace(char oldChar, char newChar) { - this.text(this.text().replace(oldChar, newChar)); - - if (this.extraHas()) + Mson ret = this.text(this.getText().replace(oldChar, newChar)); + + if (this.hasExtra()) { - for (Mson part : this.extra()) + Mson[] extra = new Mson[this.getExtra().size()]; + int i = 0; + for (Mson part : this.getExtra()) { - part.replace(oldChar, newChar); + extra[i] = part.replace(oldChar, newChar); + i++; } + ret = ret.extra(extra); } - return this; + return ret; } - + public Mson replace(CharSequence replace, CharSequence replacement) { if (replace == null) throw new NullPointerException("replace"); if (replacement == null) throw new NullPointerException("replacement"); - - this.text(this.text().replace(replace, replacement)); - - if (this.extraHas()) + + Mson ret = this.text(this.getText().replace(replace, replacement)); + + if (this.hasExtra()) { - for (Mson part : this.extra()) + Mson[] extra = new Mson[this.getExtra().size()]; + int i = 0; + for (Mson part : this.getExtra()) { - part.replace(replace, replacement); + extra[i] = part.replace(replace, replacement); + i++; } + ret = ret.extra(extra); } - return this; + return ret; } public Mson replaceAll(String regex, String replacement) @@ -641,112 +660,32 @@ public class Mson implements Serializable if (regex == null) throw new NullPointerException("regex"); if (replacement == null) throw new NullPointerException("replacement"); - this.text(this.text().replaceAll(regex, replacement)); - - if (this.extraHas()) - { - for (Mson part : this.extra()) - { - part.replaceAll(regex, replacement); - } - } - - return this; - } - - // Special replace all - - // This is old and not the best solution. - // Awaiting further decision. - -/* public Mson replaceAll(String regex, Mson replacement) - { - if (regex == null) throw new NullPointerException("regex"); - if (replacement == null) throw new NullPointerException("replacement"); - return this.replaceAllOld(Pattern.compile(regex), replacement); + return replaceAll(Pattern.compile(regex), replacement); } - - public Mson replaceAll(Pattern pattern, Mson replacement) + public Mson replaceAll(Pattern pattern, String replacement) { if (pattern == null) throw new NullPointerException("pattern"); if (replacement == null) throw new NullPointerException("replacement"); - - // We don't want the same object to eventually be part of itself - Mson repCopy = replacement.copy(); - String text = (this.text() + " "); // Prepare text - - // Split the string of this msons text and create an iterator - // and create the list of mson with the replacements in between ... - List msons = new MassiveList(); - - for (ListIterator it = Arrays.asList(pattern.split(text)).listIterator(); it.hasNext();) - { - String string = it.next(); - - // string might be empty, we don't want these empty msons - if ( ! string.isEmpty()) - { - Mson part = Mson.mson(string); - msons.add(part); - - // Delete security spacing at the last string - if ( ! it.hasNext()) part.text(string.substring(0, string.length() - 1)); - } - - // In between every part, add in replacement - if (it.hasNext()) msons.add(repCopy); - } - - // ... and forge back together, unless the whole text is "replaced", then set it to be the replacement itself. - Mson mson; - if ( ! msons.isEmpty()) - { - mson = msons.get(0).copy(); - msons.remove(0); - mson.copyFormatAndBehaviour(this); - if ( ! msons.isEmpty()) mson.extra(msons); - } - else - { - mson = repCopy; - } - - mson.parent(this.parent()); - - // If there is no extra, return here... - List extra = this.extra(); - if (extra == null) return mson; - - // ... otherwise iterate over the extra and modify it. - for (ListIterator it = extra.listIterator(); it.hasNext();) - { - Mson part = it.next(); - int index = extra.indexOf(part); - - part = part.replaceAll(pattern, replacement); - part.parent(mson); - - extra.set(index, part); - } - - // If the current mson has any extra ... - List extras = mson.extra(); - if( extras != null) - { - // ... apply tree structure again ... - extras.get(extras.size() - 1).extra(extra); - } - else - { - // ... set the extra directly ... - mson.extra(extra); - } - mson.simpleClean(); - // ... and return recreated mson - return mson; - }*/ + Mson ret = this.text(pattern.matcher(this.getText()).replaceAll(replacement)); + + if (this.hasExtra()) + { + Mson[] extra = new Mson[this.getExtra().size()]; + int i = 0; + for (Mson part : this.getExtra()) + { + extra[i] = part.replaceAll(pattern, replacement); + i++; + } + ret = ret.extra(extra); + } + + return ret; + } + + // Special replace all public Mson replaceAll(String regex, Mson replacement) { @@ -762,7 +701,7 @@ public class Mson implements Serializable MsonReplacement replacer = new MsonReplacement() { @Override - public Object getReplacement(String match) + public Mson getReplacement(String match) { return replacement; } @@ -783,24 +722,24 @@ public class Mson implements Serializable if (pattern == null) throw new NullPointerException("pattern"); if (replacer == null) throw new NullPointerException("replacer"); - Mson ret = mson().copyFormatAndBehaviour(this); + Mson ret = this.text(""); List msons = new ArrayList(); StringBuffer currentString = new StringBuffer(); - Matcher matcher = pattern.matcher(text()); + Matcher matcher = pattern.matcher(getText()); while (matcher.find()) { String match = matcher.group(0); - Object replacement = replacer.getReplacement(match); + Mson replacement = replacer.getReplacement(match); // Add the match if (replacement == null) matcher.appendReplacement(currentString, match); // Add the string - else if (replacement instanceof String) matcher.appendReplacement(currentString, replacement.toString()); + else if (replacement.isTextOnly()) matcher.appendReplacement(currentString, replacement.getText()); // Add the mson - else if (replacement instanceof Mson) + else { // Fixup current string matcher.appendReplacement(currentString, ""); @@ -809,9 +748,6 @@ public class Mson implements Serializable // Add this replacement msons.add((Mson) replacement); } - - // Not allowed - else throw new IllegalArgumentException("We only support null, String and Mson."); } // Add the remaining string pieces @@ -819,20 +755,16 @@ public class Mson implements Serializable addStringBuffer(msons, currentString); // Recurse on extras. - if (this.extraHas()) + if (this.hasExtra()) { - for (Mson extra : this.extra()) + for (Mson extra : this.getExtra()) { msons.add(extra.replaceAll(pattern, replacer)); } } // Set extras - for (Mson mson : msons) - { - mson.parent(ret); - } - ret.extra(msons); + ret = ret.extra(msons); return ret; } @@ -840,7 +772,7 @@ public class Mson implements Serializable private static boolean addStringBuffer(List msons, StringBuffer buffer) { if (buffer.length() == 0) return false; - Mson mson = mson().text(buffer.toString()); + Mson mson = mson(buffer.toString()); msons.add(mson); return true; } @@ -849,35 +781,22 @@ public class Mson implements Serializable { if (replace == null) throw new NullPointerException("replace"); if (replacement == null) throw new NullPointerException("replacement"); - - // We don't want the same object to eventually be part of itself - Mson repCopy = replacement.copy(); - - Mson mson = this; - List extra = this.extra(); - - if (mson.equals(replace)) + + Mson ret = this; + + if (this.hasExtra()) { - mson = repCopy; - mson.parent(this.parent()); - if (extra != null) mson.extraCreative().addAll(extra); + Mson[] extra = new Mson[this.getExtra().size()]; + int i = 0; + for (Mson part : this.getExtra()) + { + extra[i] = part.equals(replace) ? replacement : part; + i++; + } + ret = ret.extra(extra); } - if (extra == null) return mson; - - for (ListIterator it = extra.listIterator(); it.hasNext();) - { - int index = it.nextIndex(); - Mson part = it.next(); - - part = part.replaceAll(replace, replacement); - part.parent(mson); - - extra.set(index, part); - } - - mson.extra(extra); - return mson; + return ret; } // -------------------------------------------- // @@ -901,64 +820,60 @@ public class Mson implements Serializable { return Mixin.messageRawOne(senderObject, this); } - + // -------------------------------------------- // - // TO JSON, RAW, PLAIN & STRING + // TO JSON, RAW, PLAIN & STRING // -------------------------------------------- // - public JsonElement rootToJson() { return this.root().toJson(); } public JsonElement toJson() { return GSON.toJsonTree(this); } + public static Mson fromJson(JsonObject json) + { + return GSON.fromJson(json, Mson.class); + } - public String rootToRaw() { return this.root().toRaw(); } + private transient String raw = null; public String toRaw() { - return this.toJson().toString(); + if (raw == null) raw = this.toJson().toString(); + return raw; } - + public String toPlain() { StringBuilder ret = new StringBuilder(); - - ret.append(toPlainSimple(this)); - - if (this.extraHas()) - { - for (Mson part : this.extra()) - { - ret.append(ChatColor.RESET); - ret.append(part.toPlain()); - } - } - + this.toPlain0(ret); return ret.toString(); } - // Turns a single mson (without it's children) into plain text. - protected static String toPlainSimple(Mson mson) + private void toPlain0(StringBuilder builder) { - if (mson.textHas()) + if ( ! this.getText().isEmpty()) { // Color must be put in BEFORE formatting. // http://minecraft.gamepedia.com/Formatting_codes#Formatting_codes - StringBuilder ret = new StringBuilder(mson.text().length()); - if (mson.colorEffective() != null) ret.append(mson.colorEffective()); - if (mson.boldEffective()) ret.append(ChatColor.BOLD); - if (mson.italicEffective()) ret.append(ChatColor.ITALIC); - if (mson.underlinedEffective()) ret.append(ChatColor.UNDERLINE); - if (mson.strikethroughEffective()) ret.append(ChatColor.STRIKETHROUGH); - if (mson.obfuscatedEffective()) ret.append(ChatColor.MAGIC); - ret.append(mson.text()); - - return ret.toString(); + if (this.getEffectiveColor() != null) builder.append(this.getEffectiveColor()); + if (this.isEffectiveBold()) builder.append(ChatColor.BOLD); + if (this.isEffectiveItalic()) builder.append(ChatColor.ITALIC); + if (this.isEffectiveUnderlined()) builder.append(ChatColor.UNDERLINE); + if (this.isEffectiveStrikethrough()) builder.append(ChatColor.STRIKETHROUGH); + if (this.isEffectiveObfuscated()) builder.append(ChatColor.MAGIC); + builder.append(this.getText()); } - return ""; + if (this.hasExtra()) + { + for (Mson part : this.getExtra()) + { + builder.append(ChatColor.RESET); + part.toPlain0(builder); + } + } } - + @Override public String toString() { @@ -992,7 +907,7 @@ public class Mson implements Serializable public boolean equals(Object obj) { if (this == obj) return true; - if ( ! (obj instanceof Mson)) return false; + if ( ! (obj instanceof Mson)) return false; Mson that = (Mson) obj; if ( ! MUtil.equals(this.text, that.text)) return false; diff --git a/src/com/massivecraft/massivecore/mson/MsonEvent.java b/src/com/massivecraft/massivecore/mson/MsonEvent.java index 45b3d001..a8281773 100644 --- a/src/com/massivecraft/massivecore/mson/MsonEvent.java +++ b/src/com/massivecraft/massivecore/mson/MsonEvent.java @@ -6,11 +6,12 @@ import java.util.Objects; import org.bukkit.inventory.ItemStack; +import com.massivecraft.massivecore.cmd.MassiveCommand; import com.massivecraft.massivecore.nms.NmsItem; import com.massivecraft.massivecore.util.MUtil; import com.massivecraft.massivecore.util.Txt; -public class MsonEvent implements Serializable +public final class MsonEvent implements Serializable { // -------------------------------------------- // // CONSTANTS @@ -22,10 +23,10 @@ public class MsonEvent implements Serializable // FIELDS // -------------------------------------------- // - protected final MsonEventAction action; + private final MsonEventAction action; public MsonEventAction getEventActionType() { return this.action; } - protected final String value; + private final String value; public String getActionText() { return this.value; } // -------------------------------------------- // @@ -57,11 +58,27 @@ public class MsonEvent implements Serializable { return MsonEvent.valueOf(MsonEventAction.SUGGEST_COMMAND , replace); } - + public static MsonEvent replace(MassiveCommand cmd, String... args) + { + return MsonEvent.replace(cmd.getCommandLine(args)); + } + public static MsonEvent replace(MassiveCommand cmd, Iterable args) + { + return MsonEvent.replace(cmd.getCommandLine(args)); + } + public static MsonEvent performCmd(String cmd) { return MsonEvent.valueOf(MsonEventAction.RUN_COMMAND, cmd); } + public static MsonEvent performCmd(MassiveCommand cmd, String... args) + { + return MsonEvent.performCmd(cmd.getCommandLine(args)); + } + public static MsonEvent performCmd(MassiveCommand cmd, Iterable args) + { + return MsonEvent.performCmd(cmd.getCommandLine(args)); + } // showText public static MsonEvent hoverText(String hoverText) diff --git a/src/com/massivecraft/massivecore/mson/MsonReplacement.java b/src/com/massivecraft/massivecore/mson/MsonReplacement.java index 153d6cf8..033c4d57 100644 --- a/src/com/massivecraft/massivecore/mson/MsonReplacement.java +++ b/src/com/massivecraft/massivecore/mson/MsonReplacement.java @@ -2,5 +2,5 @@ package com.massivecraft.massivecore.mson; public interface MsonReplacement { - public Object getReplacement(String match); + public Mson getReplacement(String match); } diff --git a/src/com/massivecraft/massivecore/mson/Test.java b/src/com/massivecraft/massivecore/mson/Test.java index 880dd62e..9556fff0 100644 --- a/src/com/massivecraft/massivecore/mson/Test.java +++ b/src/com/massivecraft/massivecore/mson/Test.java @@ -1,10 +1,7 @@ package com.massivecraft.massivecore.mson; import static com.massivecraft.massivecore.mson.Mson.mson; -import static org.bukkit.ChatColor.BLUE; -import static org.bukkit.ChatColor.GREEN; -import static org.bukkit.ChatColor.RED; -import static org.bukkit.ChatColor.YELLOW; +import static org.bukkit.ChatColor.*; import com.massivecraft.massivecore.collections.MassiveList; import com.massivecraft.massivecore.util.Txt; @@ -23,89 +20,110 @@ public class Test } } + public static Mson mson; public static void test() { - Mson mson; - mson = mson("hello"); - test("ofString", mson); + test("ofString"); mson = mson( mson("hello") ); - test("ofMson", mson); + test("ofMson"); mson = mson( new MassiveList("hello ", "you!") ); - test("ofCollection", mson); + test("ofCollection"); - mson = mson("test") - .color(BLUE) - .addChild(" test2").link("www.massivecraft.com") - .addChild(" test3 ") - .addChildren("this ", "is only ", "one way to do it!") - .root() - .tooltip("Holy moly!"); - test("child", mson); - - mson = mson( + mson = mson + ( "test", - " test2", - " test3", - mson().text(" Test4, children: ").addChild("Child1 ").addSiblings("Sibling 1 ", "Sibling 2 ", "Sibling 3 ").addSibling("Sibling 4").root() - ).tooltip("Holy moly!"); - test("sibling", mson); + mson + ( + " test2", + mson + ( + " test3", + mson("this ", "is only ", "one way to do it!") + ) + ).link("www.massivecraft,com") + ).color(BLUE) + .tooltip("Holy Moly"); + + test("child"); + mson = Mson.fromParsedMessage(Txt.parse("white info bad green")); - test("parsed", mson); + test("parsed"); mson = Mson.parse("white info bad green"); - test("parsed2", mson); + test("parsed2"); mson = Mson.parse("insert here %s whatever you %s could wish for!", "!1337!", "herpi derp"); - test("parseFormat", mson); + test("parseFormat"); - Mson format = Mson.format("Just a %s simple string! :)", "very"); - test("format", format); - - // Test split - mson = mson(format.split(Txt.REGEX_WHITESPACE.toString())); - test("split", mson); + mson = Mson.format("Just a %s simple string! :)", "very"); + test("format"); // -------------------------------------------- // // TEST REPLACE // -------------------------------------------- // - mson = mson("1 2 3 4 5 6 1 7 tests").addChild(" 01010101").root().replace('1', '0'); - test("charr", mson); + mson = mson("1 2 3 4 5 6 1 7 tests", " 01010101").getRoot().replace('1', '0'); + test("charr"); - mson = mson("1 2 3 4 5 6 1 7 tests").addChild(" 01010101").root().replace("1", "0"); - test("sequence", mson); + mson = mson("1 2 3 4 5 6 1 7 tests", " 01010101").getRoot().replace("1", "0"); + test("sequence"); - mson = mson("1 2 3 4 5 6 1 7 tests").addChild(" 01010101").root().replaceAll("1", "0"); - test("regex", mson); + mson = mson("1 2 3 4 5 6 1 7 tests", " 01010101").getRoot().replaceAll("1", "0"); + test("regex"); // -------------------------------------------- // // TEST SPECIAL REPLACE ALL // -------------------------------------------- // // replace string mson - mson = mson("1 2 3 4 5 6 1 7 tests").color(BLUE).addChild(" 1+1+1").addChild("herpiderp").root().replaceAll("1", mson("0")); - test("replaceAll1", mson); - mson = mson("hellohello").addChild("hello").addChild("hello").root().replaceAll("hello", mson("lol")); - test("overload", mson); + mson = mson + ( + "1 2 3 4 5 6 1 7 tests", + " 1+1+1", + "herpiderp" + ).style(BLUE).replaceAll("1", mson("0")); + test("replaceAll1"); + + mson = mson + ( + "hellohello", + "hello", + "hello" + ).replaceAll("hello", mson("lol")); + + test("overload"); Mson toReplace = mson("hallo"); // replace mson mson - mson = mson("1 2 3 4 5 6 7 tests").addChild(toReplace).addSibling(" miep").root().replaceAll(toReplace, mson("tests")); - test("replaceAll2", mson); + mson = mson + ( + "1 2 3 4 5 6 7 tests ", + toReplace, + " miep" + ).replaceAll(toReplace, mson("tests")); + test("replaceAll2"); - mson = mson("1 2 3 4 5 6 7 tests").addChild("hallo").addChild("hallo").addChild("hallo").addSibling(" miep").root().replaceAll(mson("hallo"), mson("tests")); - test("overload2", mson); + mson = mson + ( + "1 2 3 4 5 6 7 tests ", + "hallo", + "hallo", + "hallo", + " miep" + ).replaceAll(mson("hallo"), mson("tests")); + + test("overload2"); // -------------------------------------------- // // EXAMPLES @@ -119,7 +137,7 @@ public class Test mson("[deny]").style(GREEN).command("/asfd blah deny"), "?" ).style(YELLOW); - test("Would you like to [allow] or [deny]?", mson); + test("Would you like to [allow] or [deny]?"); // -------------------------------------------- // // SPONGE MIMIC @@ -131,10 +149,15 @@ public class Test mson("Sponges are ").color(YELLOW), mson("invincible!").color(RED) ); - test("Sponges are invincible", mson); + test("Sponges are invincible"); } + public static void test(String name) + { + test(name, mson); + } + public static void test(String name, Mson mson) { System.out.println(name + ": " + mson); diff --git a/src/com/massivecraft/massivecore/store/Coll.java b/src/com/massivecraft/massivecore/store/Coll.java index 8ce12e69..b8252928 100644 --- a/src/com/massivecraft/massivecore/store/Coll.java +++ b/src/com/massivecraft/massivecore/store/Coll.java @@ -796,7 +796,7 @@ public class Coll extends CollAbstract { String id = idToEntry.getKey(); Entry remoteEntry = idToEntry.getValue(); - loadFromRemote(id, remoteEntry); + loadFromRemoteFixed(id, remoteEntry); } } diff --git a/src/com/massivecraft/massivecore/teleport/EngineScheduledTeleport.java b/src/com/massivecraft/massivecore/teleport/EngineScheduledTeleport.java index 860081bd..fef04de9 100644 --- a/src/com/massivecraft/massivecore/teleport/EngineScheduledTeleport.java +++ b/src/com/massivecraft/massivecore/teleport/EngineScheduledTeleport.java @@ -17,6 +17,7 @@ import com.massivecraft.massivecore.MassiveCore; import com.massivecraft.massivecore.mixin.Mixin; import com.massivecraft.massivecore.util.IdUtil; import com.massivecraft.massivecore.util.MUtil; +import com.massivecraft.massivecore.util.TimeUnit; public class EngineScheduledTeleport extends EngineAbstract { @@ -45,7 +46,7 @@ public class EngineScheduledTeleport extends EngineAbstract this.teleporteeIdToScheduledTeleport.put(st.getTeleporteeId(), st); - st.setDueMillis(System.currentTimeMillis() + st.getDelaySeconds()*1000); + st.setDueMillis(System.currentTimeMillis() + st.getDelaySeconds()*TimeUnit.MILLIS_PER_SECOND); return old; } @@ -111,7 +112,7 @@ public class EngineScheduledTeleport extends EngineAbstract public void cancelTeleport(PlayerMoveEvent event) { // If the player moved from one block to another ... - if (MUtil.isSameBlock(event.getFrom(), event.getTo())) return; + if (MUtil.isSameBlock(event)) return; // ... cancel teleport! Player player = event.getPlayer(); diff --git a/src/com/massivecraft/massivecore/util/MUtil.java b/src/com/massivecraft/massivecore/util/MUtil.java index 67b0c876..03f2af03 100644 --- a/src/com/massivecraft/massivecore/util/MUtil.java +++ b/src/com/massivecraft/massivecore/util/MUtil.java @@ -1500,12 +1500,12 @@ public class MUtil // -------------------------------------------- // public static T limitNumber(T d, T min, T max) { - if (min instanceof Number && d.doubleValue() < min.doubleValue()) + if (d.doubleValue() < min.doubleValue()) { return min; } - if (max instanceof Number && d.doubleValue() > max.doubleValue()) + if (d.doubleValue() > max.doubleValue()) { return max; }