Created
February 20, 2018 13:25
-
-
Save Exerosis/7435a03c4521133b2fd27c97f85a1d84 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TeamsTabList implements TabList { | |
private static final String BLANK = repeat("s", 16); | |
private static final String BLANK_P = repeat("p", 16); | |
//TODO the whole updates vs tablist thing seems ugly... maybe best to do it another way. | |
private final Set<PlayerInfoData> tabList = new HashSet<>(80); | |
private final Set<PlayerInfoData> updates = new HashSet<>(); | |
private final Set<Player> players = new HashSet<>(); | |
private final TeamEntry[] entries; | |
//TODO this certainly doesn't seem ideal... maybe use updates instead somehow? | |
private final boolean[] set = new boolean[80]; | |
private final Scoreboard board; | |
public TeamsTabList() { | |
board = getScoreboardManager().getNewScoreboard(); | |
entries = range(0, 10) | |
.mapToObj(code -> "§" + code) | |
.flatMap(code -> range(1, 9).mapToObj(times -> | |
repeat(code, times) | |
)) | |
.map(blank -> { | |
WrappedGameProfile profile = new WrappedGameProfile(randomUUID(), blank); | |
Team team = board.getTeam(blank); | |
if (team == null) | |
team = board.registerNewTeam(blank); | |
team.setSuffix(BLANK); | |
team.setPrefix(BLANK_P); | |
return new TeamEntry(profile, team); | |
}) | |
.toArray(TeamEntry[]::new); | |
for (TeamEntry entry : entries) | |
tabList.add(entry.data); | |
} | |
private void sendTabList(Player player, boolean show) { | |
PacketContainer addPacket = getProtocolManager().createPacket(PLAYER_INFO); | |
addPacket.getPlayerInfoAction().write(0, show ? ADD_PLAYER : REMOVE_PLAYER); | |
addPacket.getPlayerInfoDataLists().write(0, new ArrayList<>(tabList)); | |
try { | |
getProtocolManager().sendServerPacket(player, addPacket, false); | |
} catch (InvocationTargetException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
@Override | |
public TeamsTabList showTo(Player player) { | |
player.setScoreboard(board); | |
if (players.add(player)) | |
sendTabList(player, true); | |
return this; | |
} | |
@Override | |
public TeamsTabList hideTo(Player player) { | |
//TODO check | |
if (player.getScoreboard().equals(board)) | |
player.setScoreboard(null); | |
if (players.remove(player)) | |
sendTabList(player, false); | |
return this; | |
} | |
@Override | |
public TeamsTabList update() { | |
PacketContainer packet = getProtocolManager().createPacket(PLAYER_INFO); | |
packet.getPlayerInfoAction().write(0, ADD_PLAYER); | |
packet.getPlayerInfoDataLists().write(0, new ArrayList<>(updates)); | |
players.removeIf(player -> { | |
try { | |
getProtocolManager().sendServerPacket(player, packet); | |
} catch (InvocationTargetException e) { | |
throw new RuntimeException(e); | |
} | |
return true; | |
}); | |
return this; | |
} | |
@Override | |
public TeamEntry entry(int index) { | |
return entries[max(min(index, 80), 0)]; | |
} | |
@Override | |
public Entry entry() { | |
for (int i = 0; i < 80; i++) { | |
if (!set[i]) | |
return entry(i); | |
} | |
throw new IllegalStateException("There is no more space in this TabList."); | |
} | |
//TODO ehhhhhh seems a bit... bad? | |
class TeamEntry implements Entry { | |
private final WrappedGameProfile profile; | |
private final Team team; | |
private PlayerInfoData data; | |
public TeamEntry(WrappedGameProfile profile, Team team) { | |
this.profile = profile; | |
this.team = team; | |
queueUpdates(100); | |
} | |
@Override | |
public TeamEntry ping(int ping) { | |
queueUpdates(ping); | |
return this; | |
} | |
@Override | |
public TeamEntry skin(WrappedSignedProperty skin) { | |
Collection<WrappedSignedProperty> textures = profile.getProperties().get("textures"); | |
textures.clear(); | |
textures.add(skin); | |
queueUpdates(data.getLatency()); | |
return this; | |
} | |
@Override | |
public void text(Object text) { | |
String value = text.toString(); | |
team.setPrefix(value.substring(0, min(value.length(), 16))); | |
if (value.length() > 16) | |
team.setSuffix(value.substring(16, min(value.length(), 32))); | |
} | |
private void queueUpdates(int ping) { | |
data = new PlayerInfoData(profile, ping, NOT_SET, null); | |
if (!updates.add(data)) { | |
updates.remove(data); | |
updates.add(data); | |
} | |
if (!tabList.add(data)) { | |
tabList.remove(data); | |
tabList.add(data); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment