9
0
mirror of https://github.com/Xiao-MoMi/Custom-Nameplates.git synced 2025-12-19 15:09:23 +00:00
This commit is contained in:
XiaoMoMi
2024-01-26 16:35:25 +08:00
parent f70918befd
commit dc149dbb05
19 changed files with 254 additions and 59 deletions

View File

@@ -46,7 +46,8 @@ public interface TeamManager {
* Get the team player in
*
* @param player player
* @param viewer
* @return team name
*/
String getTeamName(Player player);
String getTeamName(Player player, Player viewer);
}

View File

@@ -7,7 +7,7 @@ plugins {
allprojects {
version = "2.3.0.0"
version = "2.3.0.2"
apply<JavaPlugin>()
apply(plugin = "java")

View File

@@ -100,7 +100,7 @@ public class CustomNameplatesPluginImpl extends CustomNameplatesPlugin implement
if (scheduler != null) ((SchedulerImpl) this.scheduler).shutdown();
if (actionBarManager != null) ((ActionBarManagerImpl) actionBarManager).unload();
if (nameplateManager != null) ((NameplateManagerImpl) this.nameplateManager).disable();
if (teamManager != null) ((TeamManagerImpl) this.teamManager).unload();
if (teamManager != null) ((TeamManagerImpl) this.teamManager).disable();
if (bossBarManager != null) ((BossBarManagerImpl) this.bossBarManager).unload();
if (imageManager != null) ((ImageManagerImpl) this.imageManager).unload();
if (backGroundManager != null) ((BackGroundManagerImpl) this.backGroundManager).unload();

View File

@@ -34,6 +34,7 @@ public class EntityDestroyListener extends PacketAdapter {
this.manager = manager;
}
@Override
public void onPacketSending(PacketEvent event) {
PacketContainer packet = event.getPacket();
manager.onEntityDestroy(event.getPlayer(), packet.getIntLists().read(0));

View File

@@ -34,6 +34,7 @@ public class EntityLookListener extends PacketAdapter {
this.manager = manager;
}
@Override
public void onPacketSending(PacketEvent event) {
PacketContainer packet = event.getPacket();
manager.onEntityMove(event.getPlayer(),

View File

@@ -34,6 +34,7 @@ public class EntityMoveListener extends PacketAdapter {
this.manager = manager;
}
@Override
public void onPacketSending(PacketEvent event) {
PacketContainer packet = event.getPacket();
manager.onEntityMove(event.getPlayer(),

View File

@@ -33,7 +33,8 @@ public class EntitySpawnListener extends PacketAdapter {
this.manager = manager;
}
public synchronized void onPacketSending(PacketEvent event) {
@Override
public void onPacketSending(PacketEvent event) {
manager.onEntitySpawn(event.getPlayer(), event.getPacket().getIntegers().read(0));
}
}

View File

@@ -34,6 +34,7 @@ public class EntityTeleportListener extends PacketAdapter {
this.manager = manager;
}
@Override
public void onPacketSending(PacketEvent event) {
PacketContainer packet = event.getPacket();
manager.onEntityTeleport(

View File

@@ -44,6 +44,7 @@ public class PlayerInfoListener extends PacketAdapter {
this.manager = manager;
}
@Override
public void onPacketSending(PacketEvent event) {
PacketContainer packet = event.getPacket();
Set<EnumWrappers.PlayerInfoAction> actions = packet.getPlayerInfoActions().read(0);

View File

@@ -40,7 +40,7 @@ public class TeamTagManagerImpl implements TeamTagManager {
private final NameplateManager manager;
private final ConcurrentHashMap<UUID, TeamPlayer> teamPlayerMap;
private CancellableTask refreshTask;
private PlayerInfoListener tabListener;
private final PlayerInfoListener tabListener;
public TeamTagManagerImpl(NameplateManager manager) {
this.manager = manager;

View File

@@ -17,6 +17,8 @@
package net.momirealms.customnameplates.paper.mechanic.team;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
@@ -34,11 +36,16 @@ import net.momirealms.customnameplates.paper.mechanic.team.provider.*;
import net.momirealms.customnameplates.paper.setting.CNConfig;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.messaging.PluginMessageListener;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.Objects;
import java.util.Optional;
public class TeamManagerImpl implements TeamManager, PluginMessageListener {
@@ -52,65 +59,94 @@ public class TeamManagerImpl implements TeamManager, PluginMessageListener {
this.teamPacketAdaptor = new TeamPacket_1_17();
}
/**
* This method would only be called when CustomNameplates manage the team
*
* @param player player
*/
@Override
public void createTeam(Player player) {
if (CNConfig.disableTeamManage) return;
String team = teamProvider.getTeam(player);
if (team == null) {
LogUtils.warn("Failed to get player " + player.getName() + "'s team.");
return;
}
PacketContainer createOwner = teamPacketAdaptor.getTeamCreatePacket(
TeamCreate.builder()
.teamName(team)
.color(TeamColor.WHITE)
.display("")
.prefix("")
.suffix("")
.members(Collections.singletonList(player.getName()))
.collisionRule(TeamCollisionRule.ALWAYS)
.tagVisibility(TeamTagVisibility.ALWAYS)
.build()
);
for (Player online : Bukkit.getOnlinePlayers()) {
PacketManager.getInstance().send(online, createOwner);
if (online == player) continue;
String onlineTeam = teamProvider.getTeam(online);
PacketContainer createOther = teamPacketAdaptor.getTeamCreatePacket(
if (CNConfig.isOtherTeamPluginHooked()) return;
String team = teamProvider.getTeam(player, null);
if (!team.equals(player.getName())) return;
if (CNConfig.createRealTeam) {
Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard();
Team playerTeam = scoreboard.getTeam(team);
if (playerTeam == null) {
playerTeam = scoreboard.registerNewTeam(team);
}
playerTeam.addPlayer(player);
} else {
PacketContainer createOwner = teamPacketAdaptor.getTeamCreatePacket(
TeamCreate.builder()
.teamName(onlineTeam)
.teamName(team)
.color(TeamColor.WHITE)
.display("")
.prefix("")
.suffix("")
.members(Collections.singletonList(online.getName()))
.members(Collections.singletonList(player.getName()))
.collisionRule(TeamCollisionRule.ALWAYS)
.tagVisibility(TeamTagVisibility.ALWAYS)
.build()
);
PacketManager.getInstance().send(player, createOther);
for (Player online : Bukkit.getOnlinePlayers()) {
PacketManager.getInstance().send(online, createOwner);
if (online == player) continue;
String onlineTeam = teamProvider.getTeam(online, null);
PacketContainer createOther = teamPacketAdaptor.getTeamCreatePacket(
TeamCreate.builder()
.teamName(onlineTeam)
.color(TeamColor.WHITE)
.display("")
.prefix("")
.suffix("")
.members(Collections.singletonList(online.getName()))
.collisionRule(TeamCollisionRule.ALWAYS)
.tagVisibility(TeamTagVisibility.ALWAYS)
.build()
);
PacketManager.getInstance().send(player, createOther);
}
}
}
/**
* This method would only be called when CustomNameplates manage the team
*
* @param player player
*/
@Override
public void removeTeam(Player player) {
if (CNConfig.disableTeamManage) return;
String team = teamProvider.getTeam(player);
PacketContainer packet = teamPacketAdaptor.getTeamRemovePacket(
TeamRemove.builder()
.teamName(team)
.build()
);
for (Player online : Bukkit.getOnlinePlayers()) {
if (player == online) continue;
PacketManager.getInstance().send(online, packet);
if (CNConfig.isOtherTeamPluginHooked()) return;
String team = teamProvider.getTeam(player, null);
// If the team is created by other plugins
if (!team.equals(player.getName())) return;
if (CNConfig.createRealTeam) {
Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard();
Optional.ofNullable(scoreboard.getTeam(team)).ifPresent(Team::unregister);
} else {
PacketContainer packet = teamPacketAdaptor.getTeamRemovePacket(
TeamRemove.builder()
.teamName(team)
.build()
);
for (Player online : Bukkit.getOnlinePlayers()) {
if (player == online) continue;
PacketManager.getInstance().send(online, packet);
}
}
}
@Override
public void updateTeam(Player owner, Player viewer, String prefix, String suffix, TeamColor color, TeamTagVisibility visibility) {
if (CNConfig.disableTeamManage) return;
String team = teamProvider.getTeam(owner);
String team = teamProvider.getTeam(owner, viewer);
if (team == null) {
LogUtils.warn("Failed to get player " + owner.getName() + "'s team for viewer " + viewer.getName());
return;
}
if (color == TeamColor.NONE || color == TeamColor.CUSTOM)
color = TeamColor.WHITE;
if (plugin.getNameplateManager().isProxyMode()) {
@@ -145,6 +181,12 @@ public class TeamManagerImpl implements TeamManager, PluginMessageListener {
}
public void unload() {
if (teamProvider instanceof Listener listener) {
HandlerList.unregisterAll(listener);
}
if (teamProvider instanceof PacketAdapter adapter) {
ProtocolLibrary.getProtocolManager().removePacketListener(adapter);
}
Bukkit.getServer().getMessenger().unregisterIncomingPluginChannel(plugin, CHANNEL);
Bukkit.getServer().getMessenger().unregisterOutgoingPluginChannel(plugin, CHANNEL);
}
@@ -159,13 +201,19 @@ public class TeamManagerImpl implements TeamManager, PluginMessageListener {
} else {
teamProvider = new DefaultProvider();
}
if (teamProvider instanceof Listener listener) {
Bukkit.getPluginManager().registerEvents(listener, plugin);
}
if (teamProvider instanceof PacketAdapter adapter) {
ProtocolLibrary.getProtocolManager().addPacketListener(adapter);
}
Bukkit.getServer().getMessenger().registerOutgoingPluginChannel(plugin, CHANNEL);
Bukkit.getServer().getMessenger().registerIncomingPluginChannel(plugin, CHANNEL, this);
}
@Override
public String getTeamName(Player player) {
return null;
public String getTeamName(Player player, Player viewer) {
return teamProvider.getTeam(player, viewer);
}
private void handleMessage(String... message) {
@@ -198,4 +246,13 @@ public class TeamManagerImpl implements TeamManager, PluginMessageListener {
player.sendPluginMessage(plugin, CHANNEL, dataOutput.toByteArray());
});
}
public void disable() {
unload();
if (CNConfig.disableTeamManage) return;
if (CNConfig.isOtherTeamPluginHooked()) return;
for (Player player : Bukkit.getOnlinePlayers()) {
removeTeam(player);
}
}
}

View File

@@ -24,7 +24,7 @@ import org.bukkit.scoreboard.Team;
public class CMIProvider implements TeamProvider {
@Override
public String getTeam(Player player) {
public String getTeam(Player player, Player ignore) {
Team team = CMI.getInstance().getSB().getPlayerTeam(player);
if (team == null) return null;
return team.getName();

View File

@@ -17,12 +17,20 @@
package net.momirealms.customnameplates.paper.mechanic.team.provider;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
public class DefaultProvider implements TeamProvider {
@Override
public String getTeam(Player player) {
return player.getName();
public String getTeam(Player player, Player ignore) {
Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard();
Team team = scoreboard.getPlayerTeam(player);
if (team == null) {
return player.getName();
}
return team.getName();
}
}

View File

@@ -37,7 +37,7 @@ public class TABProvider implements TeamProvider {
}
@Override
public String getTeam(Player player) {
public String getTeam(Player player, Player ignore) {
TabPlayer tabPlayer = api.getPlayer(player.getUniqueId());
if (tabPlayer == null) {
return null;

View File

@@ -21,5 +21,5 @@ import org.bukkit.entity.Player;
public interface TeamProvider {
String getTeam(Player player);
String getTeam(Player player, Player viewer);
}

View File

@@ -17,15 +17,73 @@
package net.momirealms.customnameplates.paper.mechanic.team.provider;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.*;
import com.comphenix.protocol.utility.MinecraftReflection;
import net.momirealms.customnameplates.api.CustomNameplatesPlugin;
import net.momirealms.customnameplates.common.team.TeamColor;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
public class UnknownProvider implements TeamProvider {
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class UnknownProvider extends PacketAdapter implements TeamProvider, Listener {
private final HashMap<UUID, PlayerTeamView> teamViewMap;
public UnknownProvider() {
super(CustomNameplatesPlugin.getInstance(), ListenerPriority.HIGHEST, PacketType.Play.Server.SCOREBOARD_TEAM);
this.teamViewMap = new HashMap<>();
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
teamViewMap.put(event.getPlayer().getUniqueId(), new PlayerTeamView());
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
teamViewMap.remove(event.getPlayer().getUniqueId());
}
@Override
public String getTeam(Player player) {
public void onPacketSending(PacketEvent event) {
Player receiver = event.getPlayer();
PlayerTeamView view = teamViewMap.get(receiver.getUniqueId());
if (view == null) {
return;
}
PacketContainer packet = event.getPacket();
String team = (String) packet.getModifier().read(1);
switch ((int) packet.getModifier().read(0)) {
case 0, 3 -> view.addMembers(team, (Collection<String>) packet.getModifier().read(2));
case 1 -> view.removeTeam(team);
case 4 -> view.removeMembers(team, (Collection<String>) packet.getModifier().read(2));
default -> {
// ignore 2 update team info
}
}
}
@Override
public String getTeam(Player player, Player viewer) {
PlayerTeamView view = teamViewMap.get(viewer.getUniqueId());
if (view != null) {
String team = view.getTeam(player);
if (team != null)
return team;
}
// should not reach here
CustomNameplatesPlugin.get().debug("Getting real teams for " + player.getName() + " viewer: " + viewer.getName());
Scoreboard scoreboard = Bukkit.getScoreboardManager().getMainScoreboard();
Team team = scoreboard.getPlayerTeam(player);
if (team == null) {
@@ -33,4 +91,65 @@ public class UnknownProvider implements TeamProvider {
}
return team.getName();
}
public static class PlayerTeamView {
private final HashMap<String, String> playerToTeamMap;
private final HashMap<String, String[]> teamToPlayerMap;
public PlayerTeamView() {
this.playerToTeamMap = new HashMap<>();
this.teamToPlayerMap = new HashMap<>();
}
public String getTeam(Player player) {
return playerToTeamMap.get(player.getName());
}
public void removeTeam(String team) {
String[] removedMembers = teamToPlayerMap.remove(team);
if (removedMembers != null) {
for (String member : removedMembers) {
playerToTeamMap.remove(member);
}
}
}
public void addMembers(String team, Collection<String> members) {
String[] oldMembers = teamToPlayerMap.remove(team);
if (oldMembers != null) {
String[] newMembers = new String[members.size() + oldMembers.length];
int i = 0;
for (String m : oldMembers) {
newMembers[i] = m;
i++;
}
for (String m : members) {
newMembers[i] = m;
i++;
}
teamToPlayerMap.put(team, newMembers);
for (String member : newMembers) {
playerToTeamMap.put(member, team);
}
} else {
teamToPlayerMap.put(team, members.toArray(new String[0]));
for (String member : members) {
playerToTeamMap.put(member, team);
}
}
}
public void removeMembers(String team, Collection<String> members) {
String[] oldMembers = teamToPlayerMap.remove(team);
if (oldMembers != null) {
ArrayList<String> newMembers = new ArrayList<>(Arrays.asList(oldMembers));
for (String member : members) {
playerToTeamMap.remove(member);
newMembers.remove(member);
}
teamToPlayerMap.put(team, newMembers.toArray(new String[0]));
}
}
}
}

View File

@@ -38,7 +38,7 @@ import java.util.Objects;
public class CNConfig {
public static String configVersion = "23";
public static String configVersion = "24";
public static int cacheSize;
public static int corePoolSize;
public static long keepAliveTime;
@@ -80,6 +80,7 @@ public class CNConfig {
public static boolean disableTeamManage;
public static boolean velocitab;
public static boolean unknownTeam;
public static boolean createRealTeam;
public static void load() {
try {
@@ -166,9 +167,10 @@ public class CNConfig {
cacheSize = config.getInt("other-settings.cache-size", 100);
legacyColorSupport = config.getBoolean("other-settings.legacy-color-code-support");
createRealTeam = config.getBoolean("other-settings.create-real-teams", false);
}
public static boolean isOtherTeamPluginHooked() {
return tabTeam || cmiTeam;
return tabTeam || cmiTeam || unknownTeam;
}
}

View File

@@ -1,5 +1,5 @@
# Do not change
config-version: '23'
config-version: '24'
# Debug mode
debug: false
@@ -79,8 +79,12 @@ resource-pack:
other-settings:
# Disable CustomNameplates' team management
# Never enable this if you are using "Team" mode for name tags
disable-team-management: false
# Create real teams on serverside. It's not recommended to enable this unless you meet BungeeCord team bugs.
create-real-teams: false
# It's recommended to use MiniMessage format. If you insist on using legacy color code "&", enable the support below.
legacy-color-code-support: false

View File

@@ -1,16 +1,14 @@
# https://mo-mi.gitbook.io/xiaomomi-plugins/plugin-wiki/customnameplates/custom-placeholders/conditional-text
conditional-text:
actionbar:
priority_0:
text: '%nameplates_background_other_actionbar%'
conditions:
'!gamemode': survival
priority_1:
text: '%nameplates_background_other_actionbar%'
conditions:
'!=':
value1: '%player_remaining_air%'
value2: "300"
'||':
'!=':
value1: '%player_remaining_air%'
value2: "300"
'!gamemode': survival
priority_2:
text: '%nameplates_static_money_hud%%nameplates_offset_-180%%nameplates_static_other_actionbar%'
conditions: