MassiveCore - Mixin Stuff part 3

This commit is contained in:
Olof Larsson 2016-05-17 17:20:55 +02:00
parent 4301a8ff31
commit fddb33ff9f
No known key found for this signature in database
GPG Key ID: BBEF14F97DA52474
13 changed files with 595 additions and 272 deletions

View File

@ -85,6 +85,7 @@ import com.massivecraft.massivecore.mixin.MixinWorld;
import com.massivecraft.massivecore.mson.Mson; import com.massivecraft.massivecore.mson.Mson;
import com.massivecraft.massivecore.mson.MsonEvent; import com.massivecraft.massivecore.mson.MsonEvent;
import com.massivecraft.massivecore.nms.NmsBasics; import com.massivecraft.massivecore.nms.NmsBasics;
import com.massivecraft.massivecore.nms.NmsBoard;
import com.massivecraft.massivecore.nms.NmsChat; import com.massivecraft.massivecore.nms.NmsChat;
import com.massivecraft.massivecore.nms.NmsEntityGet; import com.massivecraft.massivecore.nms.NmsEntityGet;
import com.massivecraft.massivecore.nms.NmsItemStackCreate; import com.massivecraft.massivecore.nms.NmsItemStackCreate;
@ -255,6 +256,7 @@ public class MassiveCore extends MassivePlugin
// Nms // Nms
NmsBasics.class, NmsBasics.class,
NmsBoard.class,
NmsChat.class, NmsChat.class,
NmsEntityGet.class, NmsEntityGet.class,
NmsItemStackCreate.class, NmsItemStackCreate.class,

View File

@ -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<Objective, Object>
{
// -------------------------------------------- //
// 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);
}
}

View File

@ -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<Team, Object>
{
// -------------------------------------------- //
// 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);
}
}

View File

@ -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();
}
}

View File

@ -3,6 +3,8 @@ package com.massivecraft.massivecore.nms;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team; import org.bukkit.scoreboard.Team;
import com.massivecraft.massivecore.mixin.Mixin; import com.massivecraft.massivecore.mixin.Mixin;
@ -38,11 +40,21 @@ public class NmsBasics extends Mixin
throw this.notImplemented(); throw this.notImplemented();
} }
public <T> T getHandle(Scoreboard scoreboard)
{
throw this.notImplemented();
}
public <T> T getHandle(Team team) public <T> T getHandle(Team team)
{ {
throw this.notImplemented(); throw this.notImplemented();
} }
public <T> T getHandle(Objective objective)
{
throw this.notImplemented();
}
// -------------------------------------------- // // -------------------------------------------- //
// GET BUKKIT // GET BUKKIT
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -6,6 +6,8 @@ import java.lang.reflect.Method;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team; import org.bukkit.scoreboard.Team;
import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType;
@ -36,11 +38,21 @@ public class NmsBasics17R4P extends NmsBasics
// org.bukkit.craftbukkit.CraftWorld#world // org.bukkit.craftbukkit.CraftWorld#world
public Field fieldCraftWorldWorld; 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 // org.bukkit.craftbukkit.scoreboard.CraftTeam
private Class<?> classCraftTeam; private Class<?> classCraftTeam;
// org.bukkit.craftbukkit.scoreboard.CraftTeam#team // org.bukkit.craftbukkit.scoreboard.CraftTeam#team
private Field fieldCraftTeamHandle; private Field fieldCraftTeamHandle;
// org.bukkit.craftbukkit.scoreboard.CraftObjective
private Class<?> classCraftObjective;
// org.bukkit.craftbukkit.scoreboard.CraftObjective#objective
private Field fieldCraftObjectiveHandle;
// GET BUKKIT // GET BUKKIT
// net.minecraft.server.Entity // net.minecraft.server.Entity
private Class<?> classNmsEntity; private Class<?> classNmsEntity;
@ -75,9 +87,15 @@ public class NmsBasics17R4P extends NmsBasics
this.classCraftWorld = PackageType.CRAFTBUKKIT.getClass("CraftWorld"); this.classCraftWorld = PackageType.CRAFTBUKKIT.getClass("CraftWorld");
this.fieldCraftWorldWorld = ReflectionUtil.getField(this.classCraftWorld, "world"); 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.classCraftTeam = PackageType.CRAFTBUKKIT_SCOREBOARD.getClass("CraftTeam");
this.fieldCraftTeamHandle = ReflectionUtil.getField(this.classCraftTeam, "team"); this.fieldCraftTeamHandle = ReflectionUtil.getField(this.classCraftTeam, "team");
this.classCraftObjective = PackageType.CRAFTBUKKIT_SCOREBOARD.getClass("CraftObjective");
this.fieldCraftObjectiveHandle = ReflectionUtil.getField(this.classCraftObjective, "objective");
// GET BUKKIT // GET BUKKIT
this.classNmsEntity = PackageType.MINECRAFT_SERVER.getClass("Entity"); this.classNmsEntity = PackageType.MINECRAFT_SERVER.getClass("Entity");
this.methodNmsEntityGetBukkitEntity = ReflectionUtil.getMethod(this.classNmsEntity, "getBukkitEntity"); this.methodNmsEntityGetBukkitEntity = ReflectionUtil.getMethod(this.classNmsEntity, "getBukkitEntity");
@ -107,12 +125,24 @@ public class NmsBasics17R4P extends NmsBasics
return ReflectionUtil.getField(this.fieldCraftWorldWorld, world); return ReflectionUtil.getField(this.fieldCraftWorldWorld, world);
} }
@Override
public <T> T getHandle(Scoreboard scoreboard)
{
return ReflectionUtil.getField(this.fieldCraftScoreboardHandle, scoreboard);
}
@Override @Override
public <T> T getHandle(Team team) public <T> T getHandle(Team team)
{ {
return ReflectionUtil.getField(this.fieldCraftTeamHandle, team); return ReflectionUtil.getField(this.fieldCraftTeamHandle, team);
} }
@Override
public <T> T getHandle(Objective objective)
{
return ReflectionUtil.getField(this.fieldCraftObjectiveHandle, objective);
}
// -------------------------------------------- // // -------------------------------------------- //
// GET BUKKIT // GET BUKKIT
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -1,186 +1,130 @@
package com.massivecraft.massivecore.nms; package com.massivecraft.massivecore.nms;
import java.lang.reflect.Constructor; import java.util.Set;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.bukkit.ChatColor; import org.bukkit.scoreboard.Objective;
import org.bukkit.entity.Player; import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team; import org.bukkit.scoreboard.Team;
import com.google.common.collect.BiMap; import com.massivecraft.massivecore.collections.MassiveSet;
import com.google.common.collect.ImmutableBiMap; import com.massivecraft.massivecore.collections.MassiveTreeSet;
import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType; import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.util.ReflectionUtil;
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 // INSTANCE & CONSTRUCT
// -------------------------------------------- // // -------------------------------------------- //
private static NmsBoard i = new NmsBoard(); private static NmsBoard i = d;
public static NmsBoard get () { return i; } public static NmsBoard get() { return i; }
// -------------------------------------------- // // -------------------------------------------- //
// FIELDS // RESEARCH
// -------------------------------------------- // // -------------------------------------------- //
// Minecraft 1.8 ended with 29 Feb 2016
// net.minecraft.server.ScoreboardTeam // Minecraft 1.7 ended with 25 Nov 2014
private Class<?> classNmsTeam; //
// This means that 1.8 lacks the Option and OptionStatus system.
// net.minecraft.server.ScoreboardTeam#k <--- color // https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/diff/src/main/java/org/bukkit/scoreboard/Team.java?until=f8573a0ca2e384e889832dc30ed41712e046fd30
private Field fieldNmsTeamColor; //
// This means that 1.7 lacks the String Team entries:
// net.minecraft.server.EnumChatFormat // https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/diff/src/main/java/org/bukkit/scoreboard/Team.java?until=d24844cdd9ed1568412ebc2ad7e6b6157ac2c26a
private Class<?> classNmsColor; //
// This means that 1.7 lacks name tag visibility.
// net.minecraft.server.EnumChatFormat#C <-- code // Note that it should be implemented as part of the Option system.
private Field fieldNmsColorCode; // https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/diff/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java?autoSincePath=false&until=606cf0eea44b88d5630623ff8a5d63571fa42793
//
// net.minecraft.server.EnumChatFormat.a(int i) <-- for code // This means that 1.7 lacks proper equals and hash code implementation:
private Method methodNmsColorFor; // https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/diff/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java?autoSincePath=false&until=4b6df5adfeb92cd09428e59a963a6ee56d7d28d6
// net.minecraft.server.PacketPlayOutScoreboardTeam
private Class<?> classPacketTeam;
// net.minecraft.server.PacketPlayOutScoreboardTeam(ScoreboardTeam, int)
private Constructor<?> constructorPacketTeamUpdate;
// -------------------------------------------- // // -------------------------------------------- //
// OVERRIDE // OPTIONS
// -------------------------------------------- // // -------------------------------------------- //
@Override public TeamOptionValue getOption(Team team, TeamOptionKey key)
public int getRequiredVersion()
{ {
return 9; throw notImplemented();
} }
@Override public void setOption(Team team, TeamOptionKey key, TeamOptionValue value)
protected void setup() throws Throwable
{ {
// TODO: Move to provoke? throw notImplemented();
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);
} }
// -------------------------------------------- // // -------------------------------------------- //
// ACCESS // MEMBERS
// -------------------------------------------- // // -------------------------------------------- //
public ChatColor getColor(Team team) public void addMember(Team team, String key)
{ {
if ( ! this.isAvailable()) return null; throw notImplemented();
Object nmsTeam = NmsBasics.get().getHandle(team);
Object nmsColor = ReflectionUtil.getField(this.fieldNmsTeamColor, nmsTeam);
return convertColor(nmsColor);
} }
public void setColor(Team team, ChatColor color) public boolean removeMember(Team team, String key)
{ {
if ( ! this.isAvailable()) return; throw notImplemented();
}
Object nmsTeam = NmsBasics.get().getHandle(team);
Object nmsColor = convertColor(color); public boolean isMember(Team team, String key)
ReflectionUtil.setField(this.fieldNmsTeamColor, nmsTeam, nmsColor); {
throw notImplemented();
// This is a quick and dirty solution. }
// It makes sure the scoreboard is updated.
team.setDisplayName(team.getDisplayName()); public Set<String> getMembers(Team team)
{
throw notImplemented();
} }
// -------------------------------------------- // // -------------------------------------------- //
// PACKET // KEY TEAM
// -------------------------------------------- // // -------------------------------------------- //
// This is a magic NMS value for the packet constructor. public Team getKeyTeam(Scoreboard board, String key)
// 2 simply means update exiting team rather than creating a new one.
private static final int PACKET_UPDATE_MODE = 2;
public <T> T createTeamUpdatePacket(Team team)
{ {
Object handle = NmsBasics.get().getHandle(team); throw notImplemented();
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);
} }
// -------------------------------------------- // // -------------------------------------------- //
// COLOR > CONVERT // IS EQUALS IMPLEMENTED
// -------------------------------------------- // // -------------------------------------------- //
public ChatColor convertColor(Object nms) public boolean isEqualsImplemented()
{ {
if (nms == null) return null; throw notImplemented();
int code = ReflectionUtil.getField(this.fieldNmsColorCode, nms);
return code(code);
} }
public <T> T convertColor(ChatColor bukkit) public Set<Team> createTeamSet()
{ {
if (bukkit == null) return null; if (this.isEqualsImplemented()) return new MassiveSet<>();
int code = code(bukkit); return new MassiveTreeSet<>(ComparatorHandleIdentityTeam.get());
return ReflectionUtil.invokeMethod(this.methodNmsColorFor, null, code); }
public Set<Objective> 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 extends Enum<T>> T convert(Enum<?> from, T[] to)
{ {
ChatColor ret = COLOR_TO_CODE.inverse().get(code); return to[from.ordinal()];
if (ret == null) throw new IllegalArgumentException("Unsupported Code " + code);
return ret;
} }
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<ChatColor, Integer> COLOR_TO_CODE = ImmutableBiMap.<ChatColor, Integer>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();
} }

View File

@ -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<String> members = this.getMembersRaw(team);
return members.contains(key);
}
public Set<String> getMembers(Team team)
{
this.getBoardHandleValidated(team);
Set<String> members = this.getMembersRaw(team);
ImmutableSet.Builder<String> ret = ImmutableSet.builder();
for (String member : members)
{
ret.add(member);
}
return ret.build();
}
protected Set<String> getMembersRaw(Team team)
{
Object handle = NmsBasics.get().getHandle(team);
return ReflectionUtil.invokeMethod(this.methodNmsScoreboardTeamGetPlayerNameSet, handle);
}
protected <T> 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;
}
}

View File

@ -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;
}
}

View File

@ -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<String> 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;
}
}

View File

@ -0,0 +1,8 @@
package com.massivecraft.massivecore.nms;
public enum TeamOptionKey
{
NAME_TAG_VISIBILITY,
DEATH_MESSAGE_VISIBILITY,
COLLISION_RULE
}

View File

@ -0,0 +1,9 @@
package com.massivecraft.massivecore.nms;
public enum TeamOptionValue
{
ALWAYS,
NEVER,
FOR_OTHER_TEAMS,
FOR_OWN_TEAM
}

View File

@ -18,14 +18,14 @@ import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Score; import org.bukkit.scoreboard.Score;
import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team; 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.Engine;
import com.massivecraft.massivecore.collections.MassiveList; import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.collections.MassiveMap; import com.massivecraft.massivecore.collections.MassiveMap;
import com.massivecraft.massivecore.collections.MassiveSet; import com.massivecraft.massivecore.collections.MassiveSet;
import com.massivecraft.massivecore.nms.NmsBoard; import com.massivecraft.massivecore.nms.NmsBoard;
import com.massivecraft.massivecore.nms.TeamOptionKey;
import com.massivecraft.massivecore.nms.TeamOptionValue;
// # RESEARCH > CLEANUP // # RESEARCH > CLEANUP
// The main server scoreboard is the only one that is saved to NBT. // 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; } public static void setEnsureTeamStrict() { ensureTeamStrict = true; }
// Temporary Fake Fields // Temporary Fake Fields
public static Set<Objective> temporaryObjectives = new MassiveSet<>(); private static Set<Objective> temporaryObjectives = null;
public static Set<Objective> getTemporaryObjectives() { return temporaryObjectives; } public static Set<Objective> getTemporaryObjectives()
{
if (temporaryObjectives == null) temporaryObjectives = NmsBoard.get().createObjectiveSet();
return temporaryObjectives;
}
public static Set<Team> temporaryTeams = new MassiveSet<>(); private static Set<Team> temporaryTeams = null;
public static Set<Team> getTemporaryTeams() { return temporaryTeams; } public static Set<Team> getTemporaryTeams()
{
if (temporaryTeams == null) temporaryTeams = NmsBoard.get().createTeamSet();
return temporaryTeams;
}
// -------------------------------------------- // // -------------------------------------------- //
// UPDATE // UPDATE
@ -568,14 +576,13 @@ public class BoardUtil extends Engine
deleteTeam(team); deleteTeam(team);
} }
public static boolean setTeam(Team team, Boolean persistent, String name, String prefix, String suffix, ChatColor color, Boolean friendlyFireEnabled, Boolean friendlyTruesightEnabled, Map<Option, OptionStatus> options, Set<String> members) public static boolean setTeam(Team team, Boolean persistent, String name, String prefix, String suffix, Boolean friendlyFireEnabled, Boolean friendlyTruesightEnabled, Map<TeamOptionKey, TeamOptionValue> options, Set<String> members)
{ {
boolean ret = false; boolean ret = false;
ret |= setTeamPersistent(team, persistent); ret |= setTeamPersistent(team, persistent);
ret |= setTeamName(team, name); ret |= setTeamName(team, name);
ret |= setTeamPrefix(team, prefix); ret |= setTeamPrefix(team, prefix);
ret |= setTeamSuffix(team, suffix); ret |= setTeamSuffix(team, suffix);
ret |= setTeamColor(team, color);
ret |= setTeamFriendlyFireEnabled(team, friendlyFireEnabled); ret |= setTeamFriendlyFireEnabled(team, friendlyFireEnabled);
ret |= setTeamFriendlyTruesightEnabled(team, friendlyTruesightEnabled); ret |= setTeamFriendlyTruesightEnabled(team, friendlyTruesightEnabled);
ret |= setTeamOptions(team, options); ret |= setTeamOptions(team, options);
@ -590,7 +597,6 @@ public class BoardUtil extends Engine
getTeamName(blueprint), getTeamName(blueprint),
getTeamPrefix(blueprint), getTeamPrefix(blueprint),
getTeamSuffix(blueprint), getTeamSuffix(blueprint),
getTeamColor(blueprint),
isTeamFriendlyFireEnabled(blueprint), isTeamFriendlyFireEnabled(blueprint),
isTeamFriendlyTruesightEnabled(blueprint), isTeamFriendlyTruesightEnabled(blueprint),
getTeamOptions(blueprint), getTeamOptions(blueprint),
@ -607,11 +613,6 @@ public class BoardUtil extends Engine
team.setDisplayName(team.getDisplayName()); team.setDisplayName(team.getDisplayName());
} }
public static void sendTeamUpdate(Team team, Player player)
{
NmsBoard.get().sendTeamUpdatePacket(team, player);
}
// -------------------------------------------- // // -------------------------------------------- //
// TEAM > ID // TEAM > ID
// -------------------------------------------- // // -------------------------------------------- //
@ -698,26 +699,6 @@ public class BoardUtil extends Engine
return true; 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 // TEAM > FRIENDLY FIRE ENABLED
// -------------------------------------------- // // -------------------------------------------- //
@ -758,17 +739,17 @@ public class BoardUtil extends Engine
// TEAM > OPTION // 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; if (value == null) return false;
OptionStatus before = getTeamOption(team, option); TeamOptionValue before = getTeamOption(team, key);
if (before == status) return false; if (before == value) return false;
team.setOption(option, status); NmsBoard.get().setOption(team, key, value);
return true; return true;
} }
@ -776,31 +757,32 @@ public class BoardUtil extends Engine
// TEAM > OPTIONS // TEAM > OPTIONS
// -------------------------------------------- // // -------------------------------------------- //
public static Map<Option, OptionStatus> getTeamOptions(Team team) public static Map<TeamOptionKey, TeamOptionValue> getTeamOptions(Team team)
{ {
// Create // Create
Map<Option, OptionStatus> ret = new MassiveMap<>(); Map<TeamOptionKey, TeamOptionValue> ret = new MassiveMap<>();
// Fill // Fill
for (Option option : Option.values()) for (TeamOptionKey key : TeamOptionKey.values())
{ {
OptionStatus status = getTeamOption(team, option); TeamOptionValue value = getTeamOption(team, key);
ret.put(option, status); if (value == null) continue;
ret.put(key, value);
} }
// Return // Return
return ret; return ret;
} }
public static boolean setTeamOptions(Team team, Map<Option, OptionStatus> options) public static boolean setTeamOptions(Team team, Map<TeamOptionKey, TeamOptionValue> options)
{ {
if (options == null) return false; if (options == null) return false;
boolean ret = false; boolean ret = false;
for (Entry<Option, OptionStatus> entry : options.entrySet()) for (Entry<TeamOptionKey, TeamOptionValue> entry : options.entrySet())
{ {
Option option = entry.getKey(); TeamOptionKey option = entry.getKey();
OptionStatus status = entry.getValue(); TeamOptionValue status = entry.getValue();
ret |= setTeamOption(team, option, status); ret |= setTeamOption(team, option, status);
} }
return ret; return ret;
@ -813,25 +795,25 @@ public class BoardUtil extends Engine
public static boolean addTeamMember(Team team, Object key) public static boolean addTeamMember(Team team, Object key)
{ {
if (isTeamMember(team, key)) return false; if (isTeamMember(team, key)) return false;
team.addEntry(getKey(key)); NmsBoard.get().addMember(team, getKey(key));
return true; return true;
} }
public static boolean removeTeamMember(Team team, Object key) public static boolean removeTeamMember(Team team, Object key)
{ {
if ( ! isTeamMember(team, key)) return false; if ( ! isTeamMember(team, key)) return false;
team.removeEntry(getKey(key)); NmsBoard.get().removeMember(team, getKey(key));
return true; return true;
} }
public static boolean isTeamMember(Team team, Object key) public static boolean isTeamMember(Team team, Object key)
{ {
return team.hasEntry(getKey(key)); return NmsBoard.get().isMember(team, getKey(key));
} }
public static Set<String> getTeamMembers(Team team) public static Set<String> getTeamMembers(Team team)
{ {
return team.getEntries(); return NmsBoard.get().getMembers(team);
} }
public static boolean setTeamMembers(Team team, Set<String> members) public static boolean setTeamMembers(Team team, Set<String> members)
@ -844,7 +826,7 @@ public class BoardUtil extends Engine
for (String member : members) for (String member : members)
{ {
if (befores.contains(member)) continue; if (befores.contains(member)) continue;
team.addEntry(member); NmsBoard.get().addMember(team, member);
ret = true; ret = true;
} }
@ -852,7 +834,7 @@ public class BoardUtil extends Engine
for (String before : befores) for (String before : befores)
{ {
if (members.contains(before)) continue; if (members.contains(before)) continue;
team.removeEntry(before); NmsBoard.get().removeMember(team, before);
ret = true; ret = true;
} }
@ -867,7 +849,7 @@ public class BoardUtil extends Engine
public static Team getKeyTeam(Scoreboard board, Object key) 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) 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_NAME = null;
private static final String PERSONAL_DEFAULT_PREFIX = ""; private static final String PERSONAL_DEFAULT_PREFIX = "";
private static final String PERSONAL_DEFAULT_SUFFIX = ChatColor.RESET.toString(); 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_FIRE_ENABLED = true;
private static final Boolean PERSONAL_DEFAULT_FRIENDLY_TRUESIGHT_ENABLED = false; private static final Boolean PERSONAL_DEFAULT_FRIENDLY_TRUESIGHT_ENABLED = false;
private static final Map<Option, OptionStatus> PERSONAL_DEFAULT_OPTIONS = new MassiveMap<>( private static final Map<TeamOptionKey, TeamOptionValue> PERSONAL_DEFAULT_OPTIONS = new MassiveMap<>(
Option.COLLISION_RULE, OptionStatus.ALWAYS, TeamOptionKey.COLLISION_RULE, TeamOptionValue.ALWAYS,
Option.DEATH_MESSAGE_VISIBILITY, OptionStatus.ALWAYS, TeamOptionKey.DEATH_MESSAGE_VISIBILITY, TeamOptionValue.ALWAYS,
Option.NAME_TAG_VISIBILITY, OptionStatus.ALWAYS TeamOptionKey.NAME_TAG_VISIBILITY, TeamOptionValue.ALWAYS
); );
public static boolean isPersonalTeam(Scoreboard board, Object key) public static boolean isPersonalTeam(Scoreboard board, Object key)
@ -922,13 +903,12 @@ public class BoardUtil extends Engine
String name = PERSONAL_DEFAULT_NAME; String name = PERSONAL_DEFAULT_NAME;
String prefix = PERSONAL_DEFAULT_PREFIX; String prefix = PERSONAL_DEFAULT_PREFIX;
String suffix = PERSONAL_DEFAULT_SUFFIX; String suffix = PERSONAL_DEFAULT_SUFFIX;
ChatColor color = PERSONAL_DEFAULT_COLOR;
Boolean friendlyFireEnabled = PERSONAL_DEFAULT_FRIENDLY_FIRE_ENABLED; Boolean friendlyFireEnabled = PERSONAL_DEFAULT_FRIENDLY_FIRE_ENABLED;
Boolean friendlyTruesightEnabled = PERSONAL_DEFAULT_FRIENDLY_TRUESIGHT_ENABLED; Boolean friendlyTruesightEnabled = PERSONAL_DEFAULT_FRIENDLY_TRUESIGHT_ENABLED;
Map<Option, OptionStatus> options = PERSONAL_DEFAULT_OPTIONS; Map<TeamOptionKey, TeamOptionValue> options = PERSONAL_DEFAULT_OPTIONS;
Set<String> members = Collections.singleton(id); Set<String> 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
return team; return team;