Skip to content

Commit b49c613

Browse files
committed
Add Folia scoreboard support
1 parent c6ba298 commit b49c613

File tree

12 files changed

+516
-45
lines changed

12 files changed

+516
-45
lines changed

main/pom.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,17 @@
146146
<version>0.10.2</version>
147147
<scope>test</scope>
148148
</dependency>
149+
<dependency>
150+
<groupId>net.megavex</groupId>
151+
<artifactId>scoreboard-library-api</artifactId>
152+
<version>2.6.0</version>
153+
</dependency>
154+
<dependency>
155+
<groupId>net.megavex</groupId>
156+
<artifactId>scoreboard-library-implementation</artifactId>
157+
<version>2.6.0</version>
158+
<scope>runtime</scope>
159+
</dependency>
149160
</dependencies>
150161
<url>http://www.citizensnpcs.co</url>
151162
<ciManagement>
@@ -267,6 +278,12 @@
267278
<include>**</include>
268279
</includes>
269280
</filter>
281+
<filter>
282+
<artifact>net.megavex:scoreboard-library-*</artifact>
283+
<includes>
284+
<include>**</include>
285+
</includes>
286+
</filter>
270287
</filters>
271288
<relocations>
272289
<!--
@@ -283,6 +300,10 @@
283300
<pattern>net.byteflux.libby</pattern>
284301
<shadedPattern>clib.net.byteflux.libby</shadedPattern>
285302
</relocation>
303+
<relocation>
304+
<pattern>net.megavex.scoreboardlibrary</pattern>
305+
<shadedPattern>clib.net.megavex.scoreboardlibrary</shadedPattern>
306+
</relocation>
286307
</relocations>
287308
</configuration>
288309
</execution>

main/src/main/java/net/citizensnpcs/Citizens.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
import java.util.Map;
1111
import java.util.UUID;
1212

13+
import net.megavex.scoreboardlibrary.api.ScoreboardLibrary;
14+
import net.megavex.scoreboardlibrary.api.exception.NoPacketAdapterAvailableException;
15+
import net.megavex.scoreboardlibrary.api.noop.NoopScoreboardLibrary;
16+
import net.megavex.scoreboardlibrary.api.team.TeamManager;
1317
import org.bukkit.Bukkit;
1418
import org.bukkit.OfflinePlayer;
1519
import org.bukkit.command.BlockCommandSender;
@@ -96,6 +100,8 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
96100
private boolean enabled;
97101
private ExpressionRegistry expressionRegistry;
98102
private LocationLookup locationLookup;
103+
private ScoreboardLibrary scoreboardLibrary;
104+
private TeamManager teamManager;
99105
private final NMSHelper nmsHelper = new NMSHelper() {
100106
private boolean SUPPORT_OWNER_PROFILE = false;
101107
{
@@ -315,6 +321,14 @@ public TraitFactory getTraitFactory() {
315321
return traitFactory;
316322
}
317323

324+
public ScoreboardLibrary getScoreboardLibrary() {
325+
return scoreboardLibrary;
326+
}
327+
328+
public TeamManager getTeamManager() {
329+
return teamManager;
330+
}
331+
318332
private void initialiseBehaviorRegistry() {
319333
expressionRegistry = new ExpressionRegistry();
320334
expressionRegistry.registerEngine(new MolangEngine());
@@ -405,6 +419,8 @@ public void onDisable() {
405419
if (packetEventsEnabled) {
406420
PacketEvents.getAPI().terminate();
407421
}
422+
423+
scoreboardLibrary.close();
408424
}
409425

410426
@Override
@@ -475,6 +491,15 @@ public void onEnable() {
475491
Messaging.severeTr(Messages.LOAD_TASK_NOT_SCHEDULED);
476492
Bukkit.getPluginManager().disablePlugin(this);
477493
}
494+
495+
try {
496+
scoreboardLibrary = ScoreboardLibrary.loadScoreboardLibrary(this);
497+
teamManager = scoreboardLibrary.createTeamManager();
498+
} catch (NoPacketAdapterAvailableException e) {
499+
scoreboardLibrary = new NoopScoreboardLibrary();
500+
getLogger().warning("Server version unsupported, scoreboard functionality will not be visible!");
501+
}
502+
478503
}
479504

480505
@Override

main/src/main/java/net/citizensnpcs/EventListen.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,7 @@ public void onPlayerJoin(PlayerJoinEvent event) {
789789
skinUpdateTracker.updatePlayer(event.getPlayer(), Setting.INITIAL_PLAYER_JOIN_SKIN_PACKET_DELAY.asTicks(),
790790
true);
791791
plugin.getLocationLookup().onJoin(event);
792+
plugin.getTeamManager().addPlayer(event.getPlayer());
792793
}
793794

794795
@EventHandler(ignoreCancelled = true)
@@ -821,6 +822,7 @@ public void onPlayerQuit(PlayerQuitEvent event) {
821822
}
822823
skinUpdateTracker.removePlayer(event.getPlayer().getUniqueId());
823824
plugin.getLocationLookup().onQuit(event);
825+
plugin.getTeamManager().removePlayer(event.getPlayer());
824826
}
825827

826828
@EventHandler(priority = EventPriority.MONITOR)

main/src/main/java/net/citizensnpcs/npc/CitizensNPC.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.UUID;
77
import java.util.function.Consumer;
88

9+
import net.citizensnpcs.api.trait.Trait;
910
import org.bukkit.Bukkit;
1011
import org.bukkit.Location;
1112
import org.bukkit.Registry;
@@ -76,6 +77,15 @@ public CitizensNPC(UUID uuid, int id, String name, EntityController controller,
7677
setEntityController(controller);
7778
}
7879

80+
@Override
81+
public boolean hasTrait(Class<? extends Trait> clazz) {
82+
int value = plugin.getTraitFactory().getId(clazz);
83+
if (value == -1) {
84+
return false;
85+
}
86+
return traits.has(plugin.getTraitFactory().getId(clazz));
87+
}
88+
7989
@Override
8090
public boolean despawn(DespawnReason reason) {
8191
if (reason == DespawnReason.RELOAD) {

main/src/main/java/net/citizensnpcs/npc/CitizensTraitFactory.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ public CitizensTraitFactory(Citizens plugin) {
172172

173173
@Override
174174
public int getId(Class<? extends Trait> clazz) {
175+
if (clazz == null) {
176+
return -1;
177+
}
175178
return idOf.get(clazz);
176179
}
177180

main/src/main/java/net/citizensnpcs/trait/ScoreboardTrait.java

Lines changed: 49 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33
import java.util.Set;
44

5+
import net.citizensnpcs.Citizens;
6+
import net.citizensnpcs.trait.scoreboard.AbstractScoreboard;
7+
import net.citizensnpcs.trait.scoreboard.AbstractTeam;
8+
import net.citizensnpcs.trait.scoreboard.BukkitScoreboardImpl;
9+
import net.citizensnpcs.trait.scoreboard.FoliaScoreboardImpl;
10+
import net.megavex.scoreboardlibrary.api.team.TeamManager;
511
import org.bukkit.Bukkit;
612
import org.bukkit.ChatColor;
713
import org.bukkit.entity.Entity;
814
import org.bukkit.entity.LivingEntity;
915
import org.bukkit.entity.Player;
10-
import org.bukkit.scoreboard.Scoreboard;
1116
import org.bukkit.scoreboard.Team;
12-
import org.bukkit.scoreboard.Team.Option;
1317
import org.bukkit.scoreboard.Team.OptionStatus;
1418

1519
import com.google.common.collect.Iterables;
@@ -25,7 +29,6 @@
2529
import net.citizensnpcs.api.trait.TraitName;
2630
import net.citizensnpcs.api.util.DataKey;
2731
import net.citizensnpcs.api.util.SpigotUtil;
28-
import net.citizensnpcs.util.NMS;
2932
import net.citizensnpcs.util.Util;
3033

3134
@TraitName("scoreboardtrait")
@@ -39,6 +42,8 @@ public class ScoreboardTrait extends Trait {
3942
@Persist
4043
private Set<String> tags = Sets.newHashSet("CITIZENS_NPC");
4144

45+
private final AbstractScoreboard scoreboard;
46+
4247
public ScoreboardTrait() {
4348
super("scoreboardtrait");
4449
metadata = CitizensAPI.getLocationLookup().<Boolean> registerMetadata("scoreboard", (meta, event) -> {
@@ -47,34 +52,36 @@ public ScoreboardTrait() {
4752
if (trait == null)
4853
continue;
4954

50-
Team team = trait.getTeam();
55+
AbstractTeam team = trait.getTeam();
5156
if (team == null || meta.has(event.getPlayer().getUniqueId(), team.getName()))
5257
continue;
5358

54-
NMS.sendTeamPacket(event.getPlayer(), team, 0);
59+
//NMS.sendTeamPacket(event.getPlayer(), team, 0);
60+
team.sendToPlayer(event.getPlayer(), AbstractTeam.SendMode.ADD_OR_MODIFY);
5561

5662
meta.set(event.getPlayer().getUniqueId(), team.getName(), true);
5763
}
5864
});
65+
66+
TeamManager teamManager = ((Citizens) CitizensAPI.getPlugin()).getTeamManager();
67+
this.scoreboard = SpigotUtil.isFoliaServer() ? new FoliaScoreboardImpl(teamManager) : new BukkitScoreboardImpl();
5968
}
6069

61-
private void clearClientTeams(Team team) {
70+
private void clearClientTeams(AbstractTeam team) {
6271
for (Player player : Bukkit.getOnlinePlayers()) {
6372
if (metadata.remove(player.getUniqueId(), team.getName())) {
64-
NMS.sendTeamPacket(player, team, 1);
73+
team.sendToPlayer(player, AbstractTeam.SendMode.REMOVE);
74+
//NMS.sendTeamPacket(player, team, 1);
6575
}
6676
}
6777
}
6878

6979
public void createTeam(String entityName) {
70-
if (SpigotUtil.isFoliaServer())
71-
return; // not supported on Folia
7280
String teamName = Util.getTeamName(npc.getUniqueId());
7381
npc.data().set(NPC.Metadata.SCOREBOARD_FAKE_TEAM_NAME, teamName);
74-
Scoreboard scoreboard = Util.getDummyScoreboard();
75-
Team team = scoreboard.getTeam(teamName);
82+
AbstractTeam team = scoreboard.getTeam(teamName);
7683
if (team == null) {
77-
team = scoreboard.registerNewTeam(teamName);
84+
team = scoreboard.createTeam(teamName);
7885
}
7986
if (!team.hasEntry(entityName)) {
8087
clearClientTeams(team);
@@ -86,11 +93,11 @@ public ChatColor getColor() {
8693
return color;
8794
}
8895

89-
private Team getTeam() {
96+
private AbstractTeam getTeam() {
9097
String teamName = npc.data().get(NPC.Metadata.SCOREBOARD_FAKE_TEAM_NAME, "");
9198
if (teamName.isEmpty())
9299
return null;
93-
return Util.getDummyScoreboard().getTeam(teamName);
100+
return scoreboard.getTeam(teamName);
94101
}
95102

96103
@Override
@@ -102,20 +109,18 @@ public void load(DataKey key) {
102109

103110
@Override
104111
public void onDespawn(DespawnReason reason) {
105-
if (SpigotUtil.isFoliaServer())
106-
return; // Not Supported on Folia
107112
previousGlowingColor = null;
108113
String name = lastName;
109114
String teamName = npc.data().get(NPC.Metadata.SCOREBOARD_FAKE_TEAM_NAME, "");
110115
if (teamName.isEmpty())
111116
return;
112-
Team team = Util.getDummyScoreboard().getTeam(teamName);
117+
AbstractTeam team = scoreboard.getTeam(teamName);
113118
npc.data().remove(NPC.Metadata.SCOREBOARD_FAKE_TEAM_NAME);
114119
if (team == null || name == null || !team.hasEntry(name)) {
115120
try {
116121
if (team != null && team.getSize() == 0) {
117122
clearClientTeams(team);
118-
team.unregister();
123+
scoreboard.removeTeam(teamName);
119124
}
120125
} catch (IllegalStateException ex) {
121126
}
@@ -131,7 +136,7 @@ public void onDespawn(DespawnReason reason) {
131136
}
132137
if (team.getSize() <= 1) {
133138
clearClientTeams(team);
134-
team.unregister();
139+
scoreboard.removeTeam(teamName);
135140
} else {
136141
team.removeEntry(name);
137142
}
@@ -177,16 +182,18 @@ public void update() {
177182
String forceVisible = npc.data().<Object> get(NPC.Metadata.NAMEPLATE_VISIBLE, true).toString();
178183
boolean nameVisibility = !npc.requiresNameHologram()
179184
&& (forceVisible.equals("true") || forceVisible.equals("hover"));
180-
Team team = getTeam();
185+
AbstractTeam team = getTeam();
181186
if (team == null)
182187
return;
183188

184189
if (!Setting.USE_SCOREBOARD_TEAMS.asBoolean()) {
185190
for (Player player : Bukkit.getOnlinePlayers()) {
186191
metadata.remove(player.getUniqueId(), team.getName());
187-
NMS.sendTeamPacket(player, team, 1);
192+
//NMS.sendTeamPacket(player, team, 1);
193+
team.sendToPlayer(player, AbstractTeam.SendMode.REMOVE);
188194
}
189-
team.unregister();
195+
//team.unregister();
196+
scoreboard.removeTeam(team.getName());
190197
npc.data().remove(NPC.Metadata.SCOREBOARD_FAKE_TEAM_NAME);
191198
return;
192199
}
@@ -196,40 +203,35 @@ public void update() {
196203
: npc.getUniqueId().toString();
197204
}
198205
if (SUPPORT_TEAM_SETOPTION) {
199-
OptionStatus visibility = nameVisibility ? OptionStatus.ALWAYS : OptionStatus.NEVER;
200-
if (visibility != team.getOption(Option.NAME_TAG_VISIBILITY)) {
206+
AbstractTeam.NameTags visibility = nameVisibility ? AbstractTeam.NameTags.ALWAYS_SHOW : AbstractTeam.NameTags.NEVER_SHOW;
207+
if (visibility != team.getNameTagVisibility()) {
201208
changed = true;
202209
}
203-
team.setOption(Option.NAME_TAG_VISIBILITY, visibility);
204-
} else {
205-
NMS.setTeamNameTagVisible(team, nameVisibility);
210+
team.setNameTagVisibility(visibility);
206211
}
212+
// else { // TODO
213+
// NMS.setTeamNameTagVisible(team, nameVisibility);
214+
// }
215+
207216
if (SUPPORT_COLLIDABLE_SETOPTION) {
208217
try {
209-
OptionStatus collide = npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected())
210-
? OptionStatus.ALWAYS
211-
: OptionStatus.NEVER;
212-
if (collide != team.getOption(Option.COLLISION_RULE)) {
218+
AbstractTeam.CollisionRule collide = npc.data().<Boolean> get(NPC.Metadata.COLLIDABLE, !npc.isProtected())
219+
? AbstractTeam.CollisionRule.ALWAYS
220+
: AbstractTeam.CollisionRule.NEVER;
221+
if (collide != team.getCollisionRule()) {
213222
changed = true;
214223
}
215-
team.setOption(Option.COLLISION_RULE, collide);
224+
team.setCollisionRule(collide);
225+
//team.setOption(Option.COLLISION_RULE, collide);
216226
} catch (NoSuchMethodError e) {
217227
SUPPORT_COLLIDABLE_SETOPTION = false;
218228
} catch (NoClassDefFoundError e) {
219229
SUPPORT_COLLIDABLE_SETOPTION = false;
220230
}
221231
}
222-
if (color != null) {
223-
if (SUPPORT_GLOWING_COLOR) {
224-
if (team.getColor() == null || previousGlowingColor == null
225-
|| previousGlowingColor != null && color != previousGlowingColor) {
226-
team.setColor(color);
227-
previousGlowingColor = color;
228-
changed = true;
229-
}
230-
} else if (team.getPrefix() == null || team.getPrefix().length() == 0 || previousGlowingColor == null
231-
|| previousGlowingColor != null && !team.getPrefix().equals(previousGlowingColor.toString())) {
232-
team.setPrefix(color.toString());
232+
if (color != null && SUPPORT_GLOWING_COLOR) {
233+
if (team.getColor() == null || previousGlowingColor == null || color != previousGlowingColor) {
234+
team.setColor(color);
233235
previousGlowingColor = color;
234236
changed = true;
235237
}
@@ -241,9 +243,11 @@ public void update() {
241243
continue;
242244

243245
if (metadata.has(player.getUniqueId(), team.getName())) {
244-
NMS.sendTeamPacket(player, team, 2);
246+
//NMS.sendTeamPacket(player, team, 2);
247+
team.sendToPlayer(player, AbstractTeam.SendMode.ADD_OR_MODIFY);
245248
} else {
246-
NMS.sendTeamPacket(player, team, 0);
249+
//NMS.sendTeamPacket(player, team, 0);
250+
team.sendToPlayer(player, AbstractTeam.SendMode.ADD_OR_MODIFY);
247251

248252
metadata.set(player.getUniqueId(), team.getName(), true);
249253
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package net.citizensnpcs.trait.scoreboard;
2+
3+
public interface AbstractScoreboard {
4+
5+
AbstractTeam getTeam(String name);
6+
7+
void removeTeam(String name);
8+
9+
AbstractTeam createTeam(String name);
10+
}

0 commit comments

Comments
 (0)