package eu.thog.uhcrun.compatibility;
import eu.thog.uhcrun.utils.Reflection;
import net.minecraft.server.v1_8_R3.IScoreboardCriteria;
import net.minecraft.server.v1_8_R3.PacketPlayOutScoreboardScore;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* This file is a part of the UHCRun Project CodeBase
* Created by Thog
* (C) Copyright Thomas Guillemard 2016
* All rights reserved.
*/
public class ObjectiveSign
{
private static Method getEntityHandle;
private static Field getPlayerConnection;
private static Method sendPacket;
private static Class<?> packetScoreBoardObjective, packetDisplayObjective;
static
{
try
{
getEntityHandle = Reflection.getOBCClass("entity.CraftPlayer").getMethod("getHandle");
getPlayerConnection = Reflection.getNMSClass("EntityPlayer").getDeclaredField("playerConnection");
sendPacket = Reflection.getNMSClass("PlayerConnection").getMethod("sendPacket", Reflection.getNMSClass("Packet"));
packetScoreBoardObjective = Reflection.getNMSClass("PacketPlayOutScoreboardObjective");
packetDisplayObjective = Reflection.getNMSClass("PacketPlayOutScoreboardDisplayObjective");
} catch (ReflectiveOperationException e)
{
e.printStackTrace();
}
}
protected String oldName;
protected String name;
protected String displayName;
protected Player player;
protected boolean toggled;
protected List<Score> scores = new ArrayList<>(15);
public ObjectiveSign(String name, String displayName, Player player)
{
this.name = name;
this.oldName = name;
this.displayName = displayName;
this.player = player;
sendObjective(player, name, displayName, 0, IScoreboardCriteria.EnumScoreboardHealthDisplay.INTEGER); // Create the tmp Objective
showSideBar(player);
updateScoreObjective(player);
}
public void updateLines()
{
if (player.isOnline())
{
this.toggled = !toggled;
this.name = oldName + toggled;
sendObjective(player, name, displayName, 0, IScoreboardCriteria.EnumScoreboardHealthDisplay.INTEGER); // Create the tmp Objective
updateScoreObjective(player);
showSideBar(player);
sendObjective(player, oldName + !toggled, "", 1, IScoreboardCriteria.EnumScoreboardHealthDisplay.INTEGER); // Force clean up
}
}
private void updateScoreObjective(Player player)
{
for (Score score : scores)
{
sendScore(player, score.name, scores.size() - score.score - 1, PacketPlayOutScoreboardScore.EnumScoreboardAction.CHANGE);
}
}
private void sendScore(Player player, String name, int score, PacketPlayOutScoreboardScore.EnumScoreboardAction en)
{
try
{
Object packet = new PacketPlayOutScoreboardScore();
Reflection.setValue(packet, "a", name);
Reflection.setValue(packet, "b", this.name);
Reflection.setValue(packet, "c", score);
Reflection.setValue(packet, "d", en); // TODO: Remove NMS dependency
this.sendPacket(packet, player);
} catch (ReflectiveOperationException e)
{
e.printStackTrace();
}
}
/**
* Send Objective creation packet
*
* @param player
* @param displayName
*/
private void sendObjective(Player player, String name, String displayName, int id, IScoreboardCriteria.EnumScoreboardHealthDisplay en)
{
try
{
Object packet = packetScoreBoardObjective.newInstance();
Reflection.setValue(packet, "a", name);
Reflection.setValue(packet, "b", displayName);
Reflection.setValue(packet, "c", en); // TODO: Remove NMS dependency
Reflection.setValue(packet, "d", id);
this.sendPacket(packet, player);
} catch (ReflectiveOperationException e)
{
e.printStackTrace();
}
}
private void showSideBar(Player player)
{
try
{
Object packet = packetDisplayObjective.newInstance();
Reflection.setValue(packet, "a", 1);
Reflection.setValue(packet, "b", name);
this.sendPacket(packet, player);
} catch (ReflectiveOperationException e)
{
e.printStackTrace();
}
}
private void sendPacket(Object packet, Player player)
{
try
{
Object thePlayer = getEntityHandle.invoke(player);
Object playerConnection = getPlayerConnection.get(thePlayer);
sendPacket.invoke(playerConnection, packet);
} catch (ReflectiveOperationException e)
{
e.printStackTrace();
}
}
public void setLine(int index, String value)
{
if (index > 15 || index < 0)
{
return;
}
if (scores.size() <= index)
{
scores.add(index, new Score(value, index));
} else
{
scores.set(index, new Score(value, index));
}
}
public static class Score
{
private int score;
private String name;
public Score(String name, int score)
{
this.name = name;
this.score = score;
}
public void setScore(int score)
{
this.score = score;
}
public String getName()
{
return name;
}
}
}