From fddb33ff9f6f6330dbd5e9983d2a34525dbd2522 Mon Sep 17 00:00:00 2001 From: Olof Larsson Date: Tue, 17 May 2016 17:20:55 +0200 Subject: [PATCH] MassiveCore - Mixin Stuff part 3 --- .../massivecraft/massivecore/MassiveCore.java | 2 + .../ComparatorHandleIdentityObjective.java | 32 +++ .../nms/ComparatorHandleIdentityTeam.java | 32 +++ .../massivecore/nms/NmsAbstract.java | 76 ------- .../massivecore/nms/NmsBasics.java | 12 + .../massivecore/nms/NmsBasics17R4P.java | 30 +++ .../massivecore/nms/NmsBoard.java | 206 +++++++----------- .../massivecore/nms/NmsBoard17R4.java | 191 ++++++++++++++++ .../massivecore/nms/NmsBoard18R1P.java | 61 ++++++ .../massivecore/nms/NmsBoard19R1P.java | 98 +++++++++ .../massivecore/nms/TeamOptionKey.java | 8 + .../massivecore/nms/TeamOptionValue.java | 9 + .../massivecore/util/BoardUtil.java | 110 ++++------ 13 files changed, 595 insertions(+), 272 deletions(-) create mode 100644 src/com/massivecraft/massivecore/nms/ComparatorHandleIdentityObjective.java create mode 100644 src/com/massivecraft/massivecore/nms/ComparatorHandleIdentityTeam.java delete mode 100644 src/com/massivecraft/massivecore/nms/NmsAbstract.java create mode 100644 src/com/massivecraft/massivecore/nms/NmsBoard17R4.java create mode 100644 src/com/massivecraft/massivecore/nms/NmsBoard18R1P.java create mode 100644 src/com/massivecraft/massivecore/nms/NmsBoard19R1P.java create mode 100644 src/com/massivecraft/massivecore/nms/TeamOptionKey.java create mode 100644 src/com/massivecraft/massivecore/nms/TeamOptionValue.java diff --git a/src/com/massivecraft/massivecore/MassiveCore.java b/src/com/massivecraft/massivecore/MassiveCore.java index 76f98df9..96f92ca0 100644 --- a/src/com/massivecraft/massivecore/MassiveCore.java +++ b/src/com/massivecraft/massivecore/MassiveCore.java @@ -85,6 +85,7 @@ import com.massivecraft.massivecore.mixin.MixinWorld; import com.massivecraft.massivecore.mson.Mson; import com.massivecraft.massivecore.mson.MsonEvent; import com.massivecraft.massivecore.nms.NmsBasics; +import com.massivecraft.massivecore.nms.NmsBoard; import com.massivecraft.massivecore.nms.NmsChat; import com.massivecraft.massivecore.nms.NmsEntityGet; import com.massivecraft.massivecore.nms.NmsItemStackCreate; @@ -255,6 +256,7 @@ public class MassiveCore extends MassivePlugin // Nms NmsBasics.class, + NmsBoard.class, NmsChat.class, NmsEntityGet.class, NmsItemStackCreate.class, diff --git a/src/com/massivecraft/massivecore/nms/ComparatorHandleIdentityObjective.java b/src/com/massivecraft/massivecore/nms/ComparatorHandleIdentityObjective.java new file mode 100644 index 00000000..f194af11 --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/ComparatorHandleIdentityObjective.java @@ -0,0 +1,32 @@ +package com.massivecraft.massivecore.nms; + +import org.bukkit.scoreboard.Objective; + +import com.massivecraft.massivecore.comparator.ComparatorAbstractTransformer; +import com.massivecraft.massivecore.comparator.ComparatorIdentity; + +public class ComparatorHandleIdentityObjective extends ComparatorAbstractTransformer +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static ComparatorHandleIdentityObjective i = new ComparatorHandleIdentityObjective(); + public static ComparatorHandleIdentityObjective get() { return i; } + public ComparatorHandleIdentityObjective() + { + super(ComparatorIdentity.get()); + } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public Object transform(Objective objective) + { + NmsBasics nms = NmsBasics.get(); + return nms.getHandle(objective); + } + +} diff --git a/src/com/massivecraft/massivecore/nms/ComparatorHandleIdentityTeam.java b/src/com/massivecraft/massivecore/nms/ComparatorHandleIdentityTeam.java new file mode 100644 index 00000000..de99ccf6 --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/ComparatorHandleIdentityTeam.java @@ -0,0 +1,32 @@ +package com.massivecraft.massivecore.nms; + +import org.bukkit.scoreboard.Team; + +import com.massivecraft.massivecore.comparator.ComparatorAbstractTransformer; +import com.massivecraft.massivecore.comparator.ComparatorIdentity; + +public class ComparatorHandleIdentityTeam extends ComparatorAbstractTransformer +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static ComparatorHandleIdentityTeam i = new ComparatorHandleIdentityTeam(); + public static ComparatorHandleIdentityTeam get() { return i; } + public ComparatorHandleIdentityTeam() + { + super(ComparatorIdentity.get()); + } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public Object transform(Team team) + { + NmsBasics nms = NmsBasics.get(); + return nms.getHandle(team); + } + +} diff --git a/src/com/massivecraft/massivecore/nms/NmsAbstract.java b/src/com/massivecraft/massivecore/nms/NmsAbstract.java deleted file mode 100644 index 37abca18..00000000 --- a/src/com/massivecraft/massivecore/nms/NmsAbstract.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.massivecraft.massivecore.nms; - -import java.util.logging.Level; - -import com.massivecraft.massivecore.MassiveCore; -import com.massivecraft.massivecore.particleeffect.ParticleEffect.ParticlePacket; - -public abstract class NmsAbstract -{ - // -------------------------------------------- // - // CONSTANTS - // -------------------------------------------- // - - public static final int DEFAULT_REQUIRED_VERSION = 7; - - public static final String BUG_TRACKER_URL = "https://github.com/MassiveCraft/MassiveCore/issues"; - - // -------------------------------------------- // - // FIELDS - // -------------------------------------------- // - - private boolean available = false; - public boolean isAvailable() { return this.available; } - - // -------------------------------------------- // - // CONSTRUCT - // -------------------------------------------- // - - public NmsAbstract() - { - try - { - if (this.isAvailableForCurrentVersion()) - { - setup(); - available = true; - - /*String name = this.getClass().getSimpleName(); - name = name.substring(3); - name = name + "s"; - String msg = String.format("The NMS util for %s was enabled.", name); - MassiveCore.get().log(msg);*/ - } - } - catch (Throwable t) - { - String errorMsg = String.format("If you use 1.%s.X or above, please report this error at %s", this.getRequiredVersion(), BUG_TRACKER_URL); - MassiveCore.get().log(Level.INFO, errorMsg); - t.printStackTrace(); - - available = false; - } - } - - protected abstract void setup() throws Throwable; - - // -------------------------------------------- // - // VERSIONING - // -------------------------------------------- // - - public static int getCurrentVersion() - { - return ParticlePacket.getVersion(); - } - - public int getRequiredVersion() - { - return DEFAULT_REQUIRED_VERSION; - } - - public boolean isAvailableForCurrentVersion() - { - return getCurrentVersion() >= this.getRequiredVersion(); - } - -} diff --git a/src/com/massivecraft/massivecore/nms/NmsBasics.java b/src/com/massivecraft/massivecore/nms/NmsBasics.java index ac24b866..add62320 100644 --- a/src/com/massivecraft/massivecore/nms/NmsBasics.java +++ b/src/com/massivecraft/massivecore/nms/NmsBasics.java @@ -3,6 +3,8 @@ package com.massivecraft.massivecore.nms; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; import com.massivecraft.massivecore.mixin.Mixin; @@ -38,11 +40,21 @@ public class NmsBasics extends Mixin throw this.notImplemented(); } + public T getHandle(Scoreboard scoreboard) + { + throw this.notImplemented(); + } + public T getHandle(Team team) { throw this.notImplemented(); } + public T getHandle(Objective objective) + { + throw this.notImplemented(); + } + // -------------------------------------------- // // GET BUKKIT // -------------------------------------------- // diff --git a/src/com/massivecraft/massivecore/nms/NmsBasics17R4P.java b/src/com/massivecraft/massivecore/nms/NmsBasics17R4P.java index e054db4f..b467c64f 100644 --- a/src/com/massivecraft/massivecore/nms/NmsBasics17R4P.java +++ b/src/com/massivecraft/massivecore/nms/NmsBasics17R4P.java @@ -6,6 +6,8 @@ import java.lang.reflect.Method; import org.bukkit.World; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; @@ -36,11 +38,21 @@ public class NmsBasics17R4P extends NmsBasics // org.bukkit.craftbukkit.CraftWorld#world public Field fieldCraftWorldWorld; + // org.bukkit.craftbukkit.scoreboard.CraftScoreboard + private Class classCraftScoreboard; + // org.bukkit.craftbukkit.scoreboard.CraftScoreboard#board + private Field fieldCraftScoreboardHandle; + // org.bukkit.craftbukkit.scoreboard.CraftTeam private Class classCraftTeam; // org.bukkit.craftbukkit.scoreboard.CraftTeam#team private Field fieldCraftTeamHandle; + // org.bukkit.craftbukkit.scoreboard.CraftObjective + private Class classCraftObjective; + // org.bukkit.craftbukkit.scoreboard.CraftObjective#objective + private Field fieldCraftObjectiveHandle; + // GET BUKKIT // net.minecraft.server.Entity private Class classNmsEntity; @@ -75,9 +87,15 @@ public class NmsBasics17R4P extends NmsBasics this.classCraftWorld = PackageType.CRAFTBUKKIT.getClass("CraftWorld"); this.fieldCraftWorldWorld = ReflectionUtil.getField(this.classCraftWorld, "world"); + this.classCraftScoreboard = PackageType.CRAFTBUKKIT_SCOREBOARD.getClass("CraftScoreboard"); + this.fieldCraftScoreboardHandle = ReflectionUtil.getField(this.classCraftScoreboard, "board"); + this.classCraftTeam = PackageType.CRAFTBUKKIT_SCOREBOARD.getClass("CraftTeam"); this.fieldCraftTeamHandle = ReflectionUtil.getField(this.classCraftTeam, "team"); + this.classCraftObjective = PackageType.CRAFTBUKKIT_SCOREBOARD.getClass("CraftObjective"); + this.fieldCraftObjectiveHandle = ReflectionUtil.getField(this.classCraftObjective, "objective"); + // GET BUKKIT this.classNmsEntity = PackageType.MINECRAFT_SERVER.getClass("Entity"); this.methodNmsEntityGetBukkitEntity = ReflectionUtil.getMethod(this.classNmsEntity, "getBukkitEntity"); @@ -107,12 +125,24 @@ public class NmsBasics17R4P extends NmsBasics return ReflectionUtil.getField(this.fieldCraftWorldWorld, world); } + @Override + public T getHandle(Scoreboard scoreboard) + { + return ReflectionUtil.getField(this.fieldCraftScoreboardHandle, scoreboard); + } + @Override public T getHandle(Team team) { return ReflectionUtil.getField(this.fieldCraftTeamHandle, team); } + @Override + public T getHandle(Objective objective) + { + return ReflectionUtil.getField(this.fieldCraftObjectiveHandle, objective); + } + // -------------------------------------------- // // GET BUKKIT // -------------------------------------------- // diff --git a/src/com/massivecraft/massivecore/nms/NmsBoard.java b/src/com/massivecraft/massivecore/nms/NmsBoard.java index a97e717d..94e509b7 100644 --- a/src/com/massivecraft/massivecore/nms/NmsBoard.java +++ b/src/com/massivecraft/massivecore/nms/NmsBoard.java @@ -1,186 +1,130 @@ package com.massivecraft.massivecore.nms; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; +import java.util.Set; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; +import org.bukkit.scoreboard.Objective; +import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; -import com.google.common.collect.BiMap; -import com.google.common.collect.ImmutableBiMap; -import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; -import com.massivecraft.massivecore.util.ReflectionUtil; +import com.massivecraft.massivecore.collections.MassiveSet; +import com.massivecraft.massivecore.collections.MassiveTreeSet; +import com.massivecraft.massivecore.mixin.Mixin; -public class NmsBoard extends NmsAbstract +public class NmsBoard extends Mixin { + // -------------------------------------------- // + // DEFAULT + // -------------------------------------------- // + + private static NmsBoard d = new NmsBoard().setAlternatives( + NmsBoard19R1P.class, + NmsBoard18R1P.class, + NmsBoard17R4.class + ); + // -------------------------------------------- // // INSTANCE & CONSTRUCT // -------------------------------------------- // - private static NmsBoard i = new NmsBoard(); - public static NmsBoard get () { return i; } + private static NmsBoard i = d; + public static NmsBoard get() { return i; } // -------------------------------------------- // - // FIELDS + // RESEARCH // -------------------------------------------- // - - // net.minecraft.server.ScoreboardTeam - private Class classNmsTeam; - - // net.minecraft.server.ScoreboardTeam#k <--- color - private Field fieldNmsTeamColor; - - // net.minecraft.server.EnumChatFormat - private Class classNmsColor; - - // net.minecraft.server.EnumChatFormat#C <-- code - private Field fieldNmsColorCode; - - // net.minecraft.server.EnumChatFormat.a(int i) <-- for code - private Method methodNmsColorFor; - - // net.minecraft.server.PacketPlayOutScoreboardTeam - private Class classPacketTeam; - - // net.minecraft.server.PacketPlayOutScoreboardTeam(ScoreboardTeam, int) - private Constructor constructorPacketTeamUpdate; + // Minecraft 1.8 ended with 29 Feb 2016 + // Minecraft 1.7 ended with 25 Nov 2014 + // + // This means that 1.8 lacks the Option and OptionStatus system. + // https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/diff/src/main/java/org/bukkit/scoreboard/Team.java?until=f8573a0ca2e384e889832dc30ed41712e046fd30 + // + // This means that 1.7 lacks the String Team entries: + // https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/diff/src/main/java/org/bukkit/scoreboard/Team.java?until=d24844cdd9ed1568412ebc2ad7e6b6157ac2c26a + // + // This means that 1.7 lacks name tag visibility. + // Note that it should be implemented as part of the Option system. + // https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/diff/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java?autoSincePath=false&until=606cf0eea44b88d5630623ff8a5d63571fa42793 + // + // This means that 1.7 lacks proper equals and hash code implementation: + // https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/diff/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java?autoSincePath=false&until=4b6df5adfeb92cd09428e59a963a6ee56d7d28d6 // -------------------------------------------- // - // OVERRIDE + // OPTIONS // -------------------------------------------- // - @Override - public int getRequiredVersion() + public TeamOptionValue getOption(Team team, TeamOptionKey key) { - return 9; + throw notImplemented(); } - @Override - protected void setup() throws Throwable + public void setOption(Team team, TeamOptionKey key, TeamOptionValue value) { - // TODO: Move to provoke? - NmsBasics.get().require(); - - this.classNmsTeam = PackageType.MINECRAFT_SERVER.getClass("ScoreboardTeam"); - this.fieldNmsTeamColor = ReflectionUtil.getField(this.classNmsTeam, "k"); - - this.classNmsColor = PackageType.MINECRAFT_SERVER.getClass("EnumChatFormat"); - this.fieldNmsColorCode = ReflectionUtil.getField(this.classNmsColor, "C"); - this.methodNmsColorFor = ReflectionUtil.getMethod(this.classNmsColor, "a", int.class); - - this.classPacketTeam = PackageType.MINECRAFT_SERVER.getClass("PacketPlayOutScoreboardTeam"); - this.constructorPacketTeamUpdate = ReflectionUtil.getConstructor(this.classPacketTeam, this.classNmsTeam, int.class); + throw notImplemented(); } // -------------------------------------------- // - // ACCESS + // MEMBERS // -------------------------------------------- // - public ChatColor getColor(Team team) + public void addMember(Team team, String key) { - if ( ! this.isAvailable()) return null; - - Object nmsTeam = NmsBasics.get().getHandle(team); - Object nmsColor = ReflectionUtil.getField(this.fieldNmsTeamColor, nmsTeam); - - return convertColor(nmsColor); + throw notImplemented(); } - public void setColor(Team team, ChatColor color) + public boolean removeMember(Team team, String key) { - if ( ! this.isAvailable()) return; - - Object nmsTeam = NmsBasics.get().getHandle(team); - Object nmsColor = convertColor(color); - ReflectionUtil.setField(this.fieldNmsTeamColor, nmsTeam, nmsColor); - - // This is a quick and dirty solution. - // It makes sure the scoreboard is updated. - team.setDisplayName(team.getDisplayName()); + throw notImplemented(); + } + + public boolean isMember(Team team, String key) + { + throw notImplemented(); + } + + public Set getMembers(Team team) + { + throw notImplemented(); } // -------------------------------------------- // - // PACKET + // KEY TEAM // -------------------------------------------- // - // This is a magic NMS value for the packet constructor. - // 2 simply means update exiting team rather than creating a new one. - private static final int PACKET_UPDATE_MODE = 2; - - public T createTeamUpdatePacket(Team team) + public Team getKeyTeam(Scoreboard board, String key) { - Object handle = NmsBasics.get().getHandle(team); - return ReflectionUtil.invokeConstructor(this.constructorPacketTeamUpdate, handle, PACKET_UPDATE_MODE); - } - - public void sendTeamUpdatePacket(Team team, Player player) - { - Object packet = this.createTeamUpdatePacket(team); - NmsBasics.get().sendPacket(player, packet); + throw notImplemented(); } // -------------------------------------------- // - // COLOR > CONVERT + // IS EQUALS IMPLEMENTED // -------------------------------------------- // - public ChatColor convertColor(Object nms) + public boolean isEqualsImplemented() { - if (nms == null) return null; - int code = ReflectionUtil.getField(this.fieldNmsColorCode, nms); - return code(code); + throw notImplemented(); } - public T convertColor(ChatColor bukkit) + public Set createTeamSet() { - if (bukkit == null) return null; - int code = code(bukkit); - return ReflectionUtil.invokeMethod(this.methodNmsColorFor, null, code); + if (this.isEqualsImplemented()) return new MassiveSet<>(); + return new MassiveTreeSet<>(ComparatorHandleIdentityTeam.get()); + } + + public Set createObjectiveSet() + { + if (this.isEqualsImplemented()) return new MassiveSet<>(); + return new MassiveTreeSet<>(ComparatorHandleIdentityObjective.get()); } // -------------------------------------------- // - // COLOR > CODE + // ENUM CONVERT // -------------------------------------------- // - public static ChatColor code(int code) + protected static > T convert(Enum from, T[] to) { - ChatColor ret = COLOR_TO_CODE.inverse().get(code); - if (ret == null) throw new IllegalArgumentException("Unsupported Code " + code); - return ret; + return to[from.ordinal()]; } - public static int code(ChatColor color) - { - Integer ret = COLOR_TO_CODE.get(color); - if (ret == null) throw new IllegalArgumentException("Unsupported Color " + color); - return ret; - } - - public static final BiMap COLOR_TO_CODE = ImmutableBiMap.builder() - .put(ChatColor.BLACK, 0) - .put(ChatColor.DARK_BLUE, 1) - .put(ChatColor.DARK_GREEN, 2) - .put(ChatColor.DARK_AQUA, 3) - .put(ChatColor.DARK_RED, 4) - .put(ChatColor.DARK_PURPLE, 5) - .put(ChatColor.GOLD, 6) - .put(ChatColor.GRAY, 7) - .put(ChatColor.DARK_GRAY, 8) - .put(ChatColor.BLUE, 9) - .put(ChatColor.GREEN, 10) - .put(ChatColor.AQUA, 11) - .put(ChatColor.RED, 12) - .put(ChatColor.LIGHT_PURPLE, 13) - .put(ChatColor.YELLOW, 14) - .put(ChatColor.WHITE, 15) - // The only supported format is RESET. - // .put(ChatColor.MAGIC, ???) - // .put(ChatColor.BOLD, ???) - // .put(ChatColor.STRIKETHROUGH, ???) - // .put(ChatColor.UNDERLINE, ???) - // .put(ChatColor.ITALIC, ???) - .put(ChatColor.RESET, -1) - .build(); - } + + diff --git a/src/com/massivecraft/massivecore/nms/NmsBoard17R4.java b/src/com/massivecraft/massivecore/nms/NmsBoard17R4.java new file mode 100644 index 00000000..eaa89252 --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsBoard17R4.java @@ -0,0 +1,191 @@ +package com.massivecraft.massivecore.nms; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.Set; + +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; + +import com.google.common.collect.ImmutableSet; +import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; +import com.massivecraft.massivecore.util.ReflectionUtil; + +public class NmsBoard17R4 extends NmsBoard +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsBoard17R4 i = new NmsBoard17R4(); + public static NmsBoard17R4 get() { return i; } + + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + // net.minecraft.server.Scoreboard + protected Class classNmsScoreboard; + // net.minecraft.server.Scoreboard#getTeam(String) + protected Method methodNmsScoreboardGetTeam; + // net.minecraft.server.Scoreboard#addPlayerToTeam(String, String) + protected Method methodNmsScoreboardAddPlayerToTeam; + // net.minecraft.server.Scoreboard#removePlayerFromTeam(String, String) + protected Method methodNmsScoreboardRemovePlayerFromTeam; + // net.minecraft.server.Scoreboard#getPlayerTeam(String) + protected Method methodNmsScoreboardGetPlayerTeam; + + // net.minecraft.server.ScoreboardTeam + protected Class classNmsScoreboardTeam; + // net.minecraft.server.ScoreboardTeam#getPlayerNameSet() + protected Method methodNmsScoreboardTeamGetPlayerNameSet; + + // org.bukkit.craftbukkit.scoreboard.CraftScoreboard + protected Class classCraftScoreboard; + // org.bukkit.craftbukkit.scoreboard.CraftTeam + protected Class classCraftTeam; + // org.bukkit.craftbukkit.scoreboard.CraftTeam(org.bukkit.craftbukkit.scoreboard.CraftScoreboard, net.minecraft.server.ScoreboardTeam) + protected Constructor constructorCraftTeam; + + // -------------------------------------------- // + // SETUP + // -------------------------------------------- // + + @Override + public void setup() throws Throwable + { + try + { + NmsBasics.get().require(); + + this.classNmsScoreboard = PackageType.MINECRAFT_SERVER.getClass("Scoreboard"); + this.methodNmsScoreboardGetTeam = ReflectionUtil.getMethod(this.classNmsScoreboard, "getTeam", String.class); + this.methodNmsScoreboardAddPlayerToTeam = ReflectionUtil.getMethod(this.classNmsScoreboard, "addPlayerToTeam", String.class, String.class); + this.methodNmsScoreboardRemovePlayerFromTeam = ReflectionUtil.getMethod(this.classNmsScoreboard, "removePlayerFromTeam", String.class, String.class); + this.methodNmsScoreboardGetPlayerTeam = ReflectionUtil.getMethod(this.classNmsScoreboard, "getPlayerTeam", String.class); + + this.classNmsScoreboardTeam = PackageType.MINECRAFT_SERVER.getClass("ScoreboardTeam"); + this.methodNmsScoreboardTeamGetPlayerNameSet = ReflectionUtil.getMethod(this.classNmsScoreboardTeam, "getPlayerNameSet"); + + this.classCraftScoreboard = PackageType.CRAFTBUKKIT_SCOREBOARD.getClass("CraftScoreboard"); + this.classCraftTeam = PackageType.CRAFTBUKKIT_SCOREBOARD.getClass("CraftTeam"); + this.constructorCraftTeam = ReflectionUtil.getConstructor(this.classCraftTeam, this.classCraftScoreboard, this.classNmsScoreboardTeam); + } + catch (Throwable t) + { + t.printStackTrace(); + throw t; + } + } + + // -------------------------------------------- // + // OPTIONS + // -------------------------------------------- // + // In 1.7 there were no options. + + @Override + public TeamOptionValue getOption(Team team, TeamOptionKey key) + { + return null; + } + + @Override + public void setOption(Team team, TeamOptionKey key, TeamOptionValue value) + { + + } + + // -------------------------------------------- // + // MEMBERS + // -------------------------------------------- // + + @Override + public void addMember(Team team, String key) + { + Object handle = this.getBoardHandleValidated(team); + + ReflectionUtil.invokeMethod(this.methodNmsScoreboardAddPlayerToTeam, handle, key, team.getName()); + } + + @Override + public boolean removeMember(Team team, String key) + { + Object handle = this.getBoardHandleValidated(team); + + if ( ! this.getMembersRaw(team).contains(key)) return false; + + ReflectionUtil.invokeMethod(this.methodNmsScoreboardRemovePlayerFromTeam, handle, key, team.getName()); + return true; + } + + @Override + public boolean isMember(Team team, String key) + { + this.getBoardHandleValidated(team); + + Set members = this.getMembersRaw(team); + + return members.contains(key); + } + + public Set getMembers(Team team) + { + this.getBoardHandleValidated(team); + + Set members = this.getMembersRaw(team); + + ImmutableSet.Builder ret = ImmutableSet.builder(); + for (String member : members) + { + ret.add(member); + } + + return ret.build(); + } + + protected Set getMembersRaw(Team team) + { + Object handle = NmsBasics.get().getHandle(team); + return ReflectionUtil.invokeMethod(this.methodNmsScoreboardTeamGetPlayerNameSet, handle); + } + + protected T getBoardHandleValidated(Team team) + { + Scoreboard board = team.getScoreboard(); + T handle = NmsBasics.get().getHandle(board); + if (ReflectionUtil.invokeMethod(this.methodNmsScoreboardGetTeam, handle, team.getName()) == null) throw new IllegalStateException("Unregistered scoreboard component"); + return handle; + } + + + // -------------------------------------------- // + // KEY TEAM + // -------------------------------------------- // + + @Override + public Team getKeyTeam(Scoreboard board, String key) + { + if (board == null) throw new NullPointerException("board"); + if (key == null) throw new NullPointerException("key"); + + Object boardHandle = NmsBasics.get().getHandle(board); + Object teamHandle = ReflectionUtil.invokeMethod(this.methodNmsScoreboardGetPlayerTeam, boardHandle, key); + + if (teamHandle == null) return null; + return ReflectionUtil.invokeConstructor(this.constructorCraftTeam, board, teamHandle); + } + + // -------------------------------------------- // + // IS EQUALS IMPLEMENTED + // -------------------------------------------- // + // In 1.7 the equals was not yet implemented. + + @Override + public boolean isEqualsImplemented() + { + return false; + } + +} + + diff --git a/src/com/massivecraft/massivecore/nms/NmsBoard18R1P.java b/src/com/massivecraft/massivecore/nms/NmsBoard18R1P.java new file mode 100644 index 00000000..077c0bc9 --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsBoard18R1P.java @@ -0,0 +1,61 @@ +package com.massivecraft.massivecore.nms; + +import org.bukkit.scoreboard.NameTagVisibility; +import org.bukkit.scoreboard.Team; + +@SuppressWarnings("deprecation") +public class NmsBoard18R1P extends NmsBoard17R4 +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsBoard18R1P i = new NmsBoard18R1P(); + public static NmsBoard18R1P get() { return i; } + + // -------------------------------------------- // + // PROVOKE + // -------------------------------------------- // + + @Override + public Object provoke() throws Throwable + { + super.provoke(); + return NameTagVisibility.ALWAYS; + } + + // -------------------------------------------- // + // OPTIONS + // -------------------------------------------- // + // In 1.8 there were only name tag visibility. + + @Override + public TeamOptionValue getOption(Team team, TeamOptionKey key) + { + if (key != TeamOptionKey.NAME_TAG_VISIBILITY) return null; + NameTagVisibility bukkitValue = team.getNameTagVisibility(); + return convert(bukkitValue, TeamOptionValue.values()); + } + + @Override + public void setOption(Team team, TeamOptionKey key, TeamOptionValue value) + { + if (key != TeamOptionKey.NAME_TAG_VISIBILITY) return; + NameTagVisibility bukkitValue = convert(value, NameTagVisibility.values()); + team.setNameTagVisibility(bukkitValue); + } + + // -------------------------------------------- // + // IS EQUALS IMPLEMENTED + // -------------------------------------------- // + // In 1.8 the equals was implemented and we no longer need a custom comparator. + + @Override + public boolean isEqualsImplemented() + { + return true; + } + +} + + diff --git a/src/com/massivecraft/massivecore/nms/NmsBoard19R1P.java b/src/com/massivecraft/massivecore/nms/NmsBoard19R1P.java new file mode 100644 index 00000000..bc5f20dd --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/NmsBoard19R1P.java @@ -0,0 +1,98 @@ +package com.massivecraft.massivecore.nms; + +import java.util.Set; + +import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.scoreboard.Team; +import org.bukkit.scoreboard.Team.Option; +import org.bukkit.scoreboard.Team.OptionStatus; + +public class NmsBoard19R1P extends NmsBoard +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static NmsBoard19R1P i = new NmsBoard19R1P(); + public static NmsBoard19R1P get() { return i; } + + // -------------------------------------------- // + // PROVOKE + // -------------------------------------------- // + + @Override + public Option provoke() throws Throwable + { + return Option.COLLISION_RULE; + } + + // -------------------------------------------- // + // OPTIONS + // -------------------------------------------- // + + @Override + public TeamOptionValue getOption(Team team, TeamOptionKey key) + { + Option bukkitKey = convert(key, Option.values()); + OptionStatus bukkitValue = team.getOption(bukkitKey); + return convert(bukkitValue, TeamOptionValue.values()); + } + + @Override + public void setOption(Team team, TeamOptionKey key, TeamOptionValue value) + { + Option bukkitKey = convert(key, Option.values()); + OptionStatus bukkitValue = convert(value, OptionStatus.values()); + team.setOption(bukkitKey, bukkitValue); + } + + // -------------------------------------------- // + // MEMBERS + // -------------------------------------------- // + + @Override + public void addMember(Team team, String key) + { + team.addEntry(key); + } + + @Override + public boolean removeMember(Team team, String key) + { + return team.removeEntry(key); + } + + @Override + public boolean isMember(Team team, String key) + { + return team.hasEntry(key); + } + + @Override + public Set getMembers(Team team) + { + return team.getEntries(); + } + + // -------------------------------------------- // + // KEY TEAM + // -------------------------------------------- // + + @Override + public Team getKeyTeam(Scoreboard board, String key) + { + return board.getEntryTeam(key); + } + + // -------------------------------------------- // + // IS EQUALS IMPLEMENTED + // -------------------------------------------- // + + public boolean isEqualsImplemented() + { + return true; + } + +} + + diff --git a/src/com/massivecraft/massivecore/nms/TeamOptionKey.java b/src/com/massivecraft/massivecore/nms/TeamOptionKey.java new file mode 100644 index 00000000..fa171bf9 --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/TeamOptionKey.java @@ -0,0 +1,8 @@ +package com.massivecraft.massivecore.nms; + +public enum TeamOptionKey +{ + NAME_TAG_VISIBILITY, + DEATH_MESSAGE_VISIBILITY, + COLLISION_RULE +} diff --git a/src/com/massivecraft/massivecore/nms/TeamOptionValue.java b/src/com/massivecraft/massivecore/nms/TeamOptionValue.java new file mode 100644 index 00000000..7f315d4c --- /dev/null +++ b/src/com/massivecraft/massivecore/nms/TeamOptionValue.java @@ -0,0 +1,9 @@ +package com.massivecraft.massivecore.nms; + +public enum TeamOptionValue +{ + ALWAYS, + NEVER, + FOR_OTHER_TEAMS, + FOR_OWN_TEAM +} diff --git a/src/com/massivecraft/massivecore/util/BoardUtil.java b/src/com/massivecraft/massivecore/util/BoardUtil.java index b00d6205..4886846c 100644 --- a/src/com/massivecraft/massivecore/util/BoardUtil.java +++ b/src/com/massivecraft/massivecore/util/BoardUtil.java @@ -18,14 +18,14 @@ import org.bukkit.scoreboard.Objective; import org.bukkit.scoreboard.Score; import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Team; -import org.bukkit.scoreboard.Team.Option; -import org.bukkit.scoreboard.Team.OptionStatus; import com.massivecraft.massivecore.Engine; import com.massivecraft.massivecore.collections.MassiveList; import com.massivecraft.massivecore.collections.MassiveMap; import com.massivecraft.massivecore.collections.MassiveSet; import com.massivecraft.massivecore.nms.NmsBoard; +import com.massivecraft.massivecore.nms.TeamOptionKey; +import com.massivecraft.massivecore.nms.TeamOptionValue; // # RESEARCH > CLEANUP // The main server scoreboard is the only one that is saved to NBT. @@ -98,11 +98,19 @@ public class BoardUtil extends Engine public static void setEnsureTeamStrict() { ensureTeamStrict = true; } // Temporary Fake Fields - public static Set temporaryObjectives = new MassiveSet<>(); - public static Set getTemporaryObjectives() { return temporaryObjectives; } + private static Set temporaryObjectives = null; + public static Set getTemporaryObjectives() + { + if (temporaryObjectives == null) temporaryObjectives = NmsBoard.get().createObjectiveSet(); + return temporaryObjectives; + } - public static Set temporaryTeams = new MassiveSet<>(); - public static Set getTemporaryTeams() { return temporaryTeams; } + private static Set temporaryTeams = null; + public static Set getTemporaryTeams() + { + if (temporaryTeams == null) temporaryTeams = NmsBoard.get().createTeamSet(); + return temporaryTeams; + } // -------------------------------------------- // // UPDATE @@ -568,14 +576,13 @@ public class BoardUtil extends Engine deleteTeam(team); } - public static boolean setTeam(Team team, Boolean persistent, String name, String prefix, String suffix, ChatColor color, Boolean friendlyFireEnabled, Boolean friendlyTruesightEnabled, Map options, Set members) + public static boolean setTeam(Team team, Boolean persistent, String name, String prefix, String suffix, Boolean friendlyFireEnabled, Boolean friendlyTruesightEnabled, Map options, Set members) { boolean ret = false; ret |= setTeamPersistent(team, persistent); ret |= setTeamName(team, name); ret |= setTeamPrefix(team, prefix); ret |= setTeamSuffix(team, suffix); - ret |= setTeamColor(team, color); ret |= setTeamFriendlyFireEnabled(team, friendlyFireEnabled); ret |= setTeamFriendlyTruesightEnabled(team, friendlyTruesightEnabled); ret |= setTeamOptions(team, options); @@ -590,7 +597,6 @@ public class BoardUtil extends Engine getTeamName(blueprint), getTeamPrefix(blueprint), getTeamSuffix(blueprint), - getTeamColor(blueprint), isTeamFriendlyFireEnabled(blueprint), isTeamFriendlyTruesightEnabled(blueprint), getTeamOptions(blueprint), @@ -607,11 +613,6 @@ public class BoardUtil extends Engine team.setDisplayName(team.getDisplayName()); } - public static void sendTeamUpdate(Team team, Player player) - { - NmsBoard.get().sendTeamUpdatePacket(team, player); - } - // -------------------------------------------- // // TEAM > ID // -------------------------------------------- // @@ -698,26 +699,6 @@ public class BoardUtil extends Engine return true; } - // -------------------------------------------- // - // TEAM > COLOR - // -------------------------------------------- // - // SINCE: Minecraft 1.9 - // NOTE: We use reflected NMS implementation since Spigot does not have an implementation yet. - - public static ChatColor getTeamColor(Team team) - { - return NmsBoard.get().getColor(team); - } - - public static boolean setTeamColor(Team team, ChatColor color) - { - if (color == null) return false; - ChatColor before = getTeamColor(team); - if (MUtil.equals(before, color)) return false; - NmsBoard.get().setColor(team, color); - return true; - } - // -------------------------------------------- // // TEAM > FRIENDLY FIRE ENABLED // -------------------------------------------- // @@ -758,17 +739,17 @@ public class BoardUtil extends Engine // TEAM > OPTION // -------------------------------------------- // - public static OptionStatus getTeamOption(Team team, Option option) + public static TeamOptionValue getTeamOption(Team team, TeamOptionKey key) { - return team.getOption(option); + return NmsBoard.get().getOption(team, key); } - public static boolean setTeamOption(Team team, Option option, OptionStatus status) + public static boolean setTeamOption(Team team, TeamOptionKey key, TeamOptionValue value) { - if (status == null) return false; - OptionStatus before = getTeamOption(team, option); - if (before == status) return false; - team.setOption(option, status); + if (value == null) return false; + TeamOptionValue before = getTeamOption(team, key); + if (before == value) return false; + NmsBoard.get().setOption(team, key, value); return true; } @@ -776,31 +757,32 @@ public class BoardUtil extends Engine // TEAM > OPTIONS // -------------------------------------------- // - public static Map getTeamOptions(Team team) + public static Map getTeamOptions(Team team) { // Create - Map ret = new MassiveMap<>(); + Map ret = new MassiveMap<>(); // Fill - for (Option option : Option.values()) + for (TeamOptionKey key : TeamOptionKey.values()) { - OptionStatus status = getTeamOption(team, option); - ret.put(option, status); + TeamOptionValue value = getTeamOption(team, key); + if (value == null) continue; + ret.put(key, value); } // Return return ret; } - public static boolean setTeamOptions(Team team, Map options) + public static boolean setTeamOptions(Team team, Map options) { if (options == null) return false; boolean ret = false; - for (Entry entry : options.entrySet()) + for (Entry entry : options.entrySet()) { - Option option = entry.getKey(); - OptionStatus status = entry.getValue(); + TeamOptionKey option = entry.getKey(); + TeamOptionValue status = entry.getValue(); ret |= setTeamOption(team, option, status); } return ret; @@ -813,25 +795,25 @@ public class BoardUtil extends Engine public static boolean addTeamMember(Team team, Object key) { if (isTeamMember(team, key)) return false; - team.addEntry(getKey(key)); + NmsBoard.get().addMember(team, getKey(key)); return true; } public static boolean removeTeamMember(Team team, Object key) { if ( ! isTeamMember(team, key)) return false; - team.removeEntry(getKey(key)); + NmsBoard.get().removeMember(team, getKey(key)); return true; } public static boolean isTeamMember(Team team, Object key) { - return team.hasEntry(getKey(key)); + return NmsBoard.get().isMember(team, getKey(key)); } public static Set getTeamMembers(Team team) { - return team.getEntries(); + return NmsBoard.get().getMembers(team); } public static boolean setTeamMembers(Team team, Set members) @@ -844,7 +826,7 @@ public class BoardUtil extends Engine for (String member : members) { if (befores.contains(member)) continue; - team.addEntry(member); + NmsBoard.get().addMember(team, member); ret = true; } @@ -852,7 +834,7 @@ public class BoardUtil extends Engine for (String before : befores) { if (members.contains(before)) continue; - team.removeEntry(before); + NmsBoard.get().removeMember(team, before); ret = true; } @@ -867,7 +849,7 @@ public class BoardUtil extends Engine public static Team getKeyTeam(Scoreboard board, Object key) { - return board.getEntryTeam(getKey(key)); + return NmsBoard.get().getKeyTeam(board, getKey(key)); } public static void setKeyTeam(Scoreboard board, Object key, Team team) @@ -889,13 +871,12 @@ public class BoardUtil extends Engine private static final String PERSONAL_DEFAULT_NAME = null; private static final String PERSONAL_DEFAULT_PREFIX = ""; private static final String PERSONAL_DEFAULT_SUFFIX = ChatColor.RESET.toString(); - private static final ChatColor PERSONAL_DEFAULT_COLOR = ChatColor.RESET; private static final Boolean PERSONAL_DEFAULT_FRIENDLY_FIRE_ENABLED = true; private static final Boolean PERSONAL_DEFAULT_FRIENDLY_TRUESIGHT_ENABLED = false; - private static final Map PERSONAL_DEFAULT_OPTIONS = new MassiveMap<>( - Option.COLLISION_RULE, OptionStatus.ALWAYS, - Option.DEATH_MESSAGE_VISIBILITY, OptionStatus.ALWAYS, - Option.NAME_TAG_VISIBILITY, OptionStatus.ALWAYS + private static final Map PERSONAL_DEFAULT_OPTIONS = new MassiveMap<>( + TeamOptionKey.COLLISION_RULE, TeamOptionValue.ALWAYS, + TeamOptionKey.DEATH_MESSAGE_VISIBILITY, TeamOptionValue.ALWAYS, + TeamOptionKey.NAME_TAG_VISIBILITY, TeamOptionValue.ALWAYS ); public static boolean isPersonalTeam(Scoreboard board, Object key) @@ -922,13 +903,12 @@ public class BoardUtil extends Engine String name = PERSONAL_DEFAULT_NAME; String prefix = PERSONAL_DEFAULT_PREFIX; String suffix = PERSONAL_DEFAULT_SUFFIX; - ChatColor color = PERSONAL_DEFAULT_COLOR; Boolean friendlyFireEnabled = PERSONAL_DEFAULT_FRIENDLY_FIRE_ENABLED; Boolean friendlyTruesightEnabled = PERSONAL_DEFAULT_FRIENDLY_TRUESIGHT_ENABLED; - Map options = PERSONAL_DEFAULT_OPTIONS; + Map options = PERSONAL_DEFAULT_OPTIONS; Set members = Collections.singleton(id); - setTeam(team, persistent, name, prefix, suffix, color, friendlyFireEnabled, friendlyTruesightEnabled, options, members); + setTeam(team, persistent, name, prefix, suffix, friendlyFireEnabled, friendlyTruesightEnabled, options, members); // Return return team;