MassiveCore - Boards and NMS

This commit is contained in:
Olof Larsson 2016-05-11 12:55:38 +02:00
parent 4a307e619f
commit a46e8e2573
No known key found for this signature in database
GPG Key ID: BBEF14F97DA52474
8 changed files with 204 additions and 240 deletions

View File

@ -1,17 +1,19 @@
package com.massivecraft.massivecore.collections;
import java.util.Arrays;
import java.util.Collection;
import com.massivecraft.massivecore.comparator.ComparatorCaseInsensitive;
public class ExceptionSet<T>
public class ExceptionSet
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
public boolean standard = true;
private boolean standard = true;
public boolean isStandard() { return this.standard; }
public void setStandard(boolean standard) { this.standard = standard; }
public MassiveTreeSet<String, ComparatorCaseInsensitive> exceptions = new MassiveTreeSet<>(ComparatorCaseInsensitive.get());
@ -30,66 +32,64 @@ public class ExceptionSet<T>
}
@SafeVarargs
public <X extends Object> ExceptionSet(boolean standard, X... exceptions)
public <O extends Object> ExceptionSet(boolean standard, O... exceptions)
{
this.standard = standard;
if (exceptions.length == 0) return;
this.exceptions.addAll(asStrings(exceptions));
}
// -------------------------------------------- //
// AS STRING
// -------------------------------------------- //
public String asString(Object exception)
{
if (exception == null) return null;
if (exception instanceof String) return (String)exception;
@SuppressWarnings("unchecked")
T t = (T)exception;
return this.convert(t);
}
public MassiveTreeSet<String, ComparatorCaseInsensitive> asStrings(Object... exceptions)
{
return asStrings(Arrays.asList(exceptions));
}
public MassiveTreeSet<String, ComparatorCaseInsensitive> asStrings(Iterable<?> exceptions)
{
MassiveTreeSet<String, ComparatorCaseInsensitive> ret = new MassiveTreeSet<>(ComparatorCaseInsensitive.get());
for (Object exception : exceptions)
{
String string = asString(exception);
ret.add(string);
}
return ret;
}
// -------------------------------------------- //
// CONVERT
// -------------------------------------------- //
public String convert(T item)
{
return item.toString();
Collection<String> strings = stringifyAll(exceptions);
this.exceptions.addAll(strings);
}
// -------------------------------------------- //
// CONTAINS
// -------------------------------------------- //
public boolean contains(Object object)
public <O extends Object> boolean contains(O object)
{
if (object == null) return ! this.standard;
String string = asString(object);
String string = stringify(object);
if (this.exceptions.contains(string)) return ! this.standard;
return this.standard;
}
// -------------------------------------------- //
// STRINGIFY
// -------------------------------------------- //
public String stringify(Object object)
{
if (object == null) return null;
if (object instanceof String) return (String)object;
String ret = this.stringifyInner(object);
if (ret != null) return ret;
return object.toString();
}
public String stringifyInner(Object object)
{
return null;
}
// -------------------------------------------- //
// STRINGIFY ALL
// -------------------------------------------- //
public MassiveTreeSet<String, ComparatorCaseInsensitive> stringifyAll(Object... exceptions)
{
return stringifyAll(Arrays.asList(exceptions));
}
public MassiveTreeSet<String, ComparatorCaseInsensitive> stringifyAll(Iterable<?> exceptions)
{
MassiveTreeSet<String, ComparatorCaseInsensitive> ret = new MassiveTreeSet<>(ComparatorCaseInsensitive.get());
for (Object exception : exceptions)
{
String string = stringify(exception);
ret.add(string);
}
return ret;
}
}

View File

@ -6,7 +6,7 @@ import org.bukkit.entity.Entity;
import com.massivecraft.massivecore.ps.PS;
public class WorldExceptionSet extends ExceptionSet<World>
public class WorldExceptionSet extends ExceptionSet
{
// -------------------------------------------- //
// CONSTRUCT
@ -23,7 +23,7 @@ public class WorldExceptionSet extends ExceptionSet<World>
}
@SafeVarargs
public <X extends Object> WorldExceptionSet(boolean standard, X... exceptions)
public <O extends Object> WorldExceptionSet(boolean standard, O... exceptions)
{
super(standard, exceptions);
}
@ -32,12 +32,6 @@ public class WorldExceptionSet extends ExceptionSet<World>
// CONTAINS
// -------------------------------------------- //
@Override
public String convert(World world)
{
return world.getName();
}
public boolean contains(PS ps)
{
return this.contains(ps.getWorld());
@ -53,4 +47,16 @@ public class WorldExceptionSet extends ExceptionSet<World>
return this.contains(entity.getWorld());
}
// -------------------------------------------- //
// STRINGIFY
// -------------------------------------------- //
@Override
public String stringifyInner(Object object)
{
if ( ! (object instanceof World)) return null;
World world = (World)object;
return world.getName();
}
}

View File

@ -154,11 +154,6 @@ public class RegistryType
{
return TypeEntry.get(getType(paramType.getActualTypeArguments()[0]), getType(paramType.getActualTypeArguments()[1]));
}
if (ExceptionSet.class.isAssignableFrom(parent))
{
return TypeExceptionSet.get(getType(paramType.getActualTypeArguments()[0]));
}
}
throw new IllegalArgumentException("Unknown type: " + reflectType);
@ -247,7 +242,8 @@ public class RegistryType
register(TypeMultiverse.get());
// Collection
register(WorldExceptionSet.class, TypeExceptionSet.get(TypeWorld.get()));
register(ExceptionSet.class, TypeExceptionSet.get());
register(WorldExceptionSet.class, TypeExceptionSet.get());
}
}

View File

@ -19,7 +19,7 @@ public class TypeItemStack extends TypeAbstract<ItemStack>
// FIELDS
// -------------------------------------------- //
private final ExceptionSet<Material> materialsAllowed;
private final ExceptionSet materialsAllowed;
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
@ -30,11 +30,11 @@ public class TypeItemStack extends TypeAbstract<ItemStack>
public static TypeItemStack get(Material... materialWhitelist)
{
ExceptionSet<Material> materialsAllowed = new ExceptionSet<>(false, materialWhitelist);
ExceptionSet materialsAllowed = new ExceptionSet(false, materialWhitelist);
return new TypeItemStack(materialsAllowed);
}
public TypeItemStack(ExceptionSet<Material> materialsAllowed)
public TypeItemStack(ExceptionSet materialsAllowed)
{
super(ItemStack.class);
this.materialsAllowed = materialsAllowed;
@ -42,7 +42,7 @@ public class TypeItemStack extends TypeAbstract<ItemStack>
public TypeItemStack()
{
this(new ExceptionSet<Material>(true));
this(new ExceptionSet(true));
}
// -------------------------------------------- //

View File

@ -1,127 +1,19 @@
package com.massivecraft.massivecore.command.type.container;
import java.util.Collection;
import java.util.Set;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.MassiveException;
import com.massivecraft.massivecore.collections.ExceptionSet;
import com.massivecraft.massivecore.collections.MassiveSet;
import com.massivecraft.massivecore.command.editor.Property;
import com.massivecraft.massivecore.command.editor.PropertyReflection;
import com.massivecraft.massivecore.command.type.Type;
import com.massivecraft.massivecore.command.type.TypeAbstract;
import com.massivecraft.massivecore.command.type.primitive.TypeBoolean;
import com.massivecraft.massivecore.util.ReflectionUtil;
import com.massivecraft.massivecore.util.Txt;
import com.massivecraft.massivecore.command.type.TypeReflection;
public class TypeExceptionSet<E> extends TypeAbstract<ExceptionSet<E>>
public class TypeExceptionSet extends TypeReflection<ExceptionSet>
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private final TypeSet<E> typeElements;
public TypeSet<E> getTypeElements() { return this.typeElements; }
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
public static <E> TypeExceptionSet<E> get(Type<E> innerType)
{
return new TypeExceptionSet<E>(innerType);
}
@SuppressWarnings("unchecked")
public TypeExceptionSet(final Type<E> innerType)
private static TypeExceptionSet i = new TypeExceptionSet();
public static TypeExceptionSet get() { return i; }
public TypeExceptionSet()
{
super(ExceptionSet.class);
this.typeElements = TypeSet.get(innerType);
// PROPERTIES
Property<ExceptionSet<E>, Boolean> propertyStandard = PropertyReflection.get(ReflectionUtil.getField(ExceptionSet.class, "standard"), this);
Property<ExceptionSet<E>, Set<E>> propertyExceptions = new Property<ExceptionSet<E>, Set<E>>(this, typeElements, "exceptions")
{
@Override
public Set<E> getRaw(ExceptionSet<E> object)
{
Set<E> ret = new MassiveSet<>();
for (String exception : object.exceptions)
{
try
{
ret.add(innerType.read(exception));
}
catch (MassiveException e)
{
e.printStackTrace();
}
}
return ret;
}
@Override
public ExceptionSet<E> setRaw(ExceptionSet<E> object, Set<E> value)
{
object.exceptions = object.asStrings(value);
return object;
}
};
propertyExceptions.setNullable(false);
this.setInnerProperties(propertyStandard, propertyExceptions);
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
// TODO: Do we even need this now?
@Override
public ExceptionSet<E> read(String arg, CommandSender sender) throws MassiveException
{
String[] args = Txt.PATTERN_WHITESPACE.split(arg, 2);
String first = args[0];
String second = args.length == 2 ? args[1] : "";
boolean standard = TypeBoolean.getTrue().read(first, sender);
Set<E> exceptions = this.getTypeElements().read(second, sender);
ExceptionSet<E> ret = new ExceptionSet<>();
ret.standard = standard;
for (E exception: exceptions)
{
ret.exceptions.add(ret.convert(exception));
}
return ret;
}
@Override
public Collection<String> getTabList(CommandSender sender, String arg)
{
if (arg.contains(" "))
{
return this.getTypeElements().getTabList(sender, arg.substring(arg.indexOf(' ')));
}
else
{
return TypeBoolean.getTrue().getTabList(sender, arg);
}
}
@Override
public boolean allowSpaceAfterTab()
{
return this.getTypeElements().allowSpaceAfterTab();
}
}

View File

@ -1,9 +1,11 @@
package com.massivecraft.massivecore.nms;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Team;
import com.google.common.collect.BiMap;
@ -11,14 +13,14 @@ import com.google.common.collect.ImmutableBiMap;
import com.massivecraft.massivecore.particleeffect.ReflectionUtils.PackageType;
import com.massivecraft.massivecore.util.ReflectionUtil;
public class NmsTeamColor extends NmsAbstract
public class NmsBoard extends NmsAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static NmsTeamColor i = new NmsTeamColor();
public static NmsTeamColor get () { return i; }
private static NmsBoard i = new NmsBoard();
public static NmsBoard get () { return i; }
// -------------------------------------------- //
// FIELDS
@ -45,6 +47,12 @@ public class NmsTeamColor extends NmsAbstract
// 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;
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@ -67,27 +75,30 @@ public class NmsTeamColor extends NmsAbstract
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
// -------------------------------------------- //
public ChatColor get(Team team)
public ChatColor getColor(Team team)
{
if ( ! this.isAvailable()) return null;
Object nmsTeam = convertTeam(team);
Object nmsTeam = getTeamHandle(team);
Object nmsColor = ReflectionUtil.getField(this.fieldNmsTeamColor, nmsTeam);
return convertColor(nmsColor);
}
public void set(Team team, ChatColor color)
public void setColor(Team team, ChatColor color)
{
if ( ! this.isAvailable()) return;
Object nmsTeam = convertTeam(team);
Object nmsTeam = getTeamHandle(team);
Object nmsColor = convertColor(color);
ReflectionUtil.setField(this.fieldNmsTeamColor, nmsTeam, nmsColor);
@ -97,26 +108,46 @@ public class NmsTeamColor extends NmsAbstract
}
// -------------------------------------------- //
// CONVERT TEAM
// TEAM
// -------------------------------------------- //
private Object convertTeam(Team team)
public <T> T getTeamHandle(Team team)
{
return ReflectionUtil.getField(this.fieldCraftTeamHandle, team);
}
// -------------------------------------------- //
// CONVERT COLOR
// PACKET
// -------------------------------------------- //
private ChatColor convertColor(Object nms)
// 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> T createTeamUpdatePacket(Team team)
{
Object handle = getTeamHandle(team);
return ReflectionUtil.invokeConstructor(this.constructorPacketTeamUpdate, handle, PACKET_UPDATE_MODE);
}
public void sendTeamUpdatePacket(Team team, Player player)
{
Object packet = this.createTeamUpdatePacket(team);
NmsPacket.sendPacket(player, packet);
}
// -------------------------------------------- //
// COLOR > CONVERT
// -------------------------------------------- //
public ChatColor convertColor(Object nms)
{
if (nms == null) return null;
int code = ReflectionUtil.getField(this.fieldNmsColorCode, nms);
return code(code);
}
private Object convertColor(ChatColor bukkit)
public <T> T convertColor(ChatColor bukkit)
{
if (bukkit == null) return null;
int code = code(bukkit);
@ -124,24 +155,24 @@ public class NmsTeamColor extends NmsAbstract
}
// -------------------------------------------- //
// CODE
// COLOR > CODE
// -------------------------------------------- //
private static ChatColor code(int code)
public static ChatColor code(int code)
{
ChatColor ret = COLOR_TO_CODE.inverse().get(code);
if (ret == null) throw new IllegalArgumentException("Unsupported Code " + code);
return ret;
}
private static int code(ChatColor color)
public static int code(ChatColor color)
{
Integer ret = COLOR_TO_CODE.get(color);
if (ret == null) throw new IllegalArgumentException("Unsupported Color " + color);
return ret;
}
private static final BiMap<ChatColor, Integer> COLOR_TO_CODE = ImmutableBiMap.<ChatColor, Integer>builder()
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)

View File

@ -4,6 +4,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.massivecraft.massivecore.util.ReflectionUtil;
import com.massivecraft.massivecore.util.Txt;
import org.bukkit.entity.Player;
import org.json.simple.JSONObject;
@ -242,14 +243,21 @@ public final class NmsPacket extends NmsAbstract
// UTIL
// -------------------------------------------- //
public static void sendPacket(Player player, Object packet) throws Exception
public static void sendPacket(Player player, Object packet)
{
sendPacket.invoke(getPlayerConnection(player), packet);
Object connection = getPlayerConnection(player);
ReflectionUtil.invokeMethod(sendPacket, connection, packet);
}
public static Object getPlayerConnection(Player player) throws Exception
public static <T> T getPlayerConnection(Player player)
{
return playerConnection.get(getHandle.invoke(player));
Object handle = getHandle(player);
return ReflectionUtil.getField(playerConnection, handle);
}
public static <T> T getHandle(Player player)
{
return ReflectionUtil.invokeMethod(getHandle, player);
}
public static Object toChatBaseComponent(String str) throws Exception

View File

@ -26,7 +26,7 @@ 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.NmsTeamColor;
import com.massivecraft.massivecore.nms.NmsBoard;
// # RESEARCH > CLEANUP
// The main server scoreboard is the only one that is saved to NBT.
@ -320,6 +320,25 @@ public class BoardUtil extends Engine
return getBoardOur().equals(board);
}
// -------------------------------------------- //
// BOARD > TEMPORARY
// -------------------------------------------- //
// This board is used for the construction of lies and bogus only.
// It should never ever be directly assigned to a player.
private static Scoreboard BOARD_TEMPORARY = null;
public static Scoreboard getBoardTemporary()
{
if (BOARD_TEMPORARY == null) BOARD_TEMPORARY = Bukkit.getScoreboardManager().getNewScoreboard();
return BOARD_TEMPORARY;
}
public static boolean isBoardTemporary(Scoreboard board)
{
return getBoardOur().equals(board);
}
// -------------------------------------------- //
// OBJECTIVE
// -------------------------------------------- //
@ -333,10 +352,10 @@ public class BoardUtil extends Engine
return board.registerNewObjective(id, OBJECTIVE_CRITERIA_DUMMY);
}
public static Objective createObjective(Scoreboard board, String id, boolean persistent, String name, DisplaySlot slot, Map<String, Integer> entries)
public static Objective getObjective(Scoreboard board, String id, boolean creative)
{
Objective objective = createObjective(board, id);
setObjective(objective, persistent, name, slot, entries);
Objective objective = board.getObjective(id);
if (objective == null && creative) createObjective(board, id);
return objective;
}
@ -360,21 +379,6 @@ public class BoardUtil extends Engine
deleteObjective(objective);
}
public static Objective getObjective(Scoreboard board, String id, boolean creative)
{
Objective objective = board.getObjective(id);
if (objective == null && creative) createObjective(board, id);
return objective;
}
public static Objective getObjective(Scoreboard board, String id, boolean creative, Boolean persistent, String name, DisplaySlot slot, Map<String, Integer> entries)
{
Objective objective = getObjective(board, id, creative);
if (objective == null) return null;
setObjective(objective, persistent, name, slot, entries);
return objective;
}
public static void setObjective(Objective objective, Boolean persistent, String name, DisplaySlot slot, Map<String, Integer> entries)
{
setObjectivePersistent(objective, persistent);
@ -383,6 +387,16 @@ public class BoardUtil extends Engine
setObjectiveEntries(objective, entries);
}
public static void setObjective(Objective objective, Objective blueprint)
{
setObjective(objective,
isObjectivePersistent(blueprint),
getObjectiveName(blueprint),
getObjectiveSlot(blueprint),
getObjectiveEntries(blueprint)
);
}
// -------------------------------------------- //
// OBJECTIVE > ID
// -------------------------------------------- //
@ -533,10 +547,10 @@ public class BoardUtil extends Engine
return board.registerNewTeam(id);
}
public static Team createTeam(Scoreboard board, String id, Boolean persistent, String name, String prefix, String suffix, ChatColor color, Boolean friendlyFireEnabled, Boolean friendlyTruesightEnabled, Map<Option, OptionStatus> options, Set<String> members)
public static Team getTeam(Scoreboard board, String id, boolean creative)
{
Team team = createTeam(board, id);
setTeam(team, persistent, name, prefix, suffix, color, friendlyFireEnabled, friendlyTruesightEnabled, options, members);
Team team = board.getTeam(id);
if (team == null && creative) team = createTeam(board, id);
return team;
}
@ -560,21 +574,6 @@ public class BoardUtil extends Engine
deleteTeam(team);
}
public static Team getTeam(Scoreboard board, String id, boolean creative)
{
Team team = board.getTeam(id);
if (team == null && creative) team = createTeam(board, id);
return team;
}
public static Team getTeam(Scoreboard board, String id, boolean creative, Boolean persistent, String name, String prefix, String suffix, ChatColor color, Boolean friendlyFireEnabled, Boolean friendlyTruesightEnabled, Map<Option, OptionStatus> options, Set<String> members)
{
Team team = getTeam(board, id, creative);
if (team == null) return null;
setTeam(team, persistent, name, prefix, suffix, color, friendlyFireEnabled, friendlyTruesightEnabled, options, members);
return team;
}
public static void setTeam(Team team, Boolean persistent, String name, String prefix, String suffix, ChatColor color, Boolean friendlyFireEnabled, Boolean friendlyTruesightEnabled, Map<Option, OptionStatus> options, Set<String> members)
{
setTeamPersistent(team, persistent);
@ -588,6 +587,30 @@ public class BoardUtil extends Engine
setTeamMembers(team, members);
}
public static void setTeam(Team team, Team blueprint)
{
setTeam(team,
isTeamPersistent(blueprint),
getTeamName(blueprint),
getTeamPrefix(blueprint),
getTeamSuffix(blueprint),
getTeamColor(blueprint),
isTeamFriendlyFireEnabled(blueprint),
isTeamFriendlyTruesightEnabled(blueprint),
getTeamOptions(blueprint),
getTeamMembers(blueprint)
);
}
// -------------------------------------------- //
// TEAM > SEND
// -------------------------------------------- //
public static void sendTeamUpdate(Team team, Player player)
{
NmsBoard.get().sendTeamUpdatePacket(team, player);
}
// -------------------------------------------- //
// TEAM > ID
// -------------------------------------------- //
@ -679,7 +702,7 @@ public class BoardUtil extends Engine
public static ChatColor getTeamColor(Team team)
{
return NmsTeamColor.get().get(team);
return NmsBoard.get().getColor(team);
}
public static void setTeamColor(Team team, ChatColor color)
@ -687,7 +710,7 @@ public class BoardUtil extends Engine
if (color == null) return;
ChatColor before = getTeamColor(team);
if (MUtil.equals(before, color)) return;
NmsTeamColor.get().set(team, color);
NmsBoard.get().setColor(team, color);
}
// -------------------------------------------- //
@ -869,7 +892,11 @@ public class BoardUtil extends Engine
public static Team createPersonalTeam(Scoreboard board, Object key)
{
// Create
String id = getKey(key);
Team team = createTeam(board, id);
// Fill
Boolean persistent = PERSONAL_DEFAULT_PERSISTENT;
String name = PERSONAL_DEFAULT_NAME;
String prefix = PERSONAL_DEFAULT_PREFIX;
@ -879,7 +906,11 @@ public class BoardUtil extends Engine
Boolean friendlyTruesightEnabled = PERSONAL_DEFAULT_FRIENDLY_TRUESIGHT_ENABLED;
Map<Option, OptionStatus> options = PERSONAL_DEFAULT_OPTIONS;
Set<String> members = Collections.singleton(id);
return createTeam(board, id, persistent, name, prefix, suffix, color, friendlyFireEnabled, friendlyTruesightEnabled, options, members);
setTeam(team, persistent, name, prefix, suffix, color, friendlyFireEnabled, friendlyTruesightEnabled, options, members);
// Return
return team;
}
public static Team getPersonalTeam(Scoreboard board, Object key, boolean creative)