yeet packetevents adapter

This commit is contained in:
vytskalt committed 2026-02-14 01:21:47 +02:00
1 parent 6158c71cc9
commit ce1533ded5
13 files changed
+3 -599

No files matched your search

-1
View File
@@ -17,7 +17,6 @@ dependencies {
// Add packet adapter implementations you want:
runtimeOnly("net.megavex:scoreboard-library-modern:$scoreboardLibraryVersion") // 1.17+
runtimeOnly("net.megavex:scoreboard-library-packetevents:$scoreboardLibraryVersion") // 1.8+
runtimeOnly("net.megavex:scoreboard-library-legacy:$scoreboardLibraryVersion") // 1.7.10-1.12.2
// If using the PacketEvents implementation, scoreboard-library expects PacketEvents to be in the classpath.
-1
View File
@@ -25,7 +25,6 @@ Join the [Discord](https://discord.gg/v7nmTDTW8W) or create an issue for support
- **modern.** Supports 1.17-1.21.11. Can take advantage of [Paper](https://papermc.io)'s native adventure support to be more efficient.
- **legacy.** Supports 1.7.10-1.12.2.
- **PacketEvents.** Supports 1.8+. Requires [PacketEvents 2.0](https://github.com/retrooper/packetevents/tree/2.0) to be shaded or installed as a plugin.
> [!NOTE]
> You can add multiple packet adapters, the best one will automatically be picked depending on the server version.
@@ -9,9 +9,7 @@ import org.jetbrains.annotations.Nullable;
import java.lang.reflect.InvocationTargetException;
public final class PacketAdapterLoader {
private static final String MODERN = "modern",
LEGACY = "legacy",
PACKET_EVENTS = "packetevents";
private static final String MODERN = "modern", LEGACY = "legacy";
private PacketAdapterLoader() {
}
@@ -36,12 +34,7 @@ public final class PacketAdapterLoader {
version = version.substring(0, dashIndex);
}
Class<?> nmsClass = tryLoadVersion(version);
if (nmsClass != null) {
return nmsClass;
}
return tryLoadPacketEvents();
return tryLoadVersion(version);
}
private static @Nullable Class<?> tryLoadVersion(@NotNull String serverVersion) {
@@ -126,20 +119,6 @@ public final class PacketAdapterLoader {
}
}
private static @Nullable Class<?> tryLoadPacketEvents() {
Class<?> nmsClass = tryLoadImplementationClass(PACKET_EVENTS);
if (nmsClass == null) {
return null;
}
try {
Class.forName("com.github.retrooper.packetevents.PacketEvents");
return nmsClass;
} catch (ClassNotFoundException ignored) {
return null;
}
}
private static @Nullable Class<?> tryLoadImplementationClass(@NotNull String name) {
try {
String path = "net.megavex.scoreboardlibrary.implementation.packetAdapter." + name + ".PacketAdapterProviderImpl";
+1 -9
View File
@@ -2,12 +2,4 @@ plugins {
id("net.megavex.scoreboardlibrary.base-conventions")
}
repositories {
maven("https://repo.codemc.io/repository/maven-releases/")
}
dependencies {
compileOnly(project(":scoreboard-library-packet-adapter-base"))
compileOnly(libs.packetEvents)
compileOnly(libs.spigotApi)
}
// packetevents adapter is gone, this module is kept for compatibility
@@ -1,161 +0,0 @@
package net.megavex.scoreboardlibrary.implementation.packetAdapter.packetevents;
import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisplayScoreboard;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerResetScore;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerScoreboardObjective;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateScore;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.translation.GlobalTranslator;
import net.megavex.scoreboardlibrary.api.objective.ObjectiveDisplaySlot;
import net.megavex.scoreboardlibrary.api.objective.ObjectiveRenderType;
import net.megavex.scoreboardlibrary.api.objective.ScoreFormat;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.PropertiesPacketType;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectiveConstants;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectivePacketAdapter;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.util.LocalePacketUtil;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Locale;
import java.util.Optional;
public class ObjectivePacketAdapterImpl implements ObjectivePacketAdapter {
private final PacketSender<PacketWrapper<?>> provider;
private final PacketEventsAPI<?> packetEvents;
private final String objectiveName;
private WrapperPlayServerScoreboardObjective removePacket;
public ObjectivePacketAdapterImpl(@NotNull PacketSender<PacketWrapper<?>> provider, @NotNull PacketEventsAPI<?> packetEvents, @NotNull String objectiveName) {
this.provider = provider;
this.packetEvents = packetEvents;
this.objectiveName = objectiveName;
}
@Override
public @NotNull String objectiveName() {
return objectiveName;
}
@Override
public void display(@NotNull Collection<Player> players, @NotNull ObjectiveDisplaySlot slot) {
WrapperPlayServerDisplayScoreboard packet = new WrapperPlayServerDisplayScoreboard(ObjectiveConstants.displaySlotIndex(slot), objectiveName);
provider.sendPacket(players, packet);
}
@Override
public void sendProperties(
@NotNull Collection<Player> players,
@NotNull PropertiesPacketType packetType,
@NotNull Component value,
@NotNull ObjectiveRenderType renderType,
@Nullable ScoreFormat scoreFormat
) {
LocalePacketUtil.sendLocalePackets(
provider,
players,
locale -> createObjectivePacket(locale, packetType, value, renderType, scoreFormat)
);
}
@Override
public void remove(@NotNull Collection<Player> players) {
if (removePacket == null) {
removePacket = new WrapperPlayServerScoreboardObjective(
objectiveName,
WrapperPlayServerScoreboardObjective.ObjectiveMode.REMOVE,
null,
null
);
}
provider.sendPacket(players, removePacket);
}
@Override
public void sendScore(
@NotNull Collection<Player> players,
@NotNull String entry,
int value,
@Nullable Component display,
@Nullable ScoreFormat scoreFormat
) {
LocalePacketUtil.sendLocalePackets(
provider,
players,
locale -> new WrapperPlayServerUpdateScore(
entry,
WrapperPlayServerUpdateScore.Action.CREATE_OR_UPDATE_ITEM,
objectiveName,
value,
display != null ? GlobalTranslator.render(display, locale) : null,
ScoreFormatConverter.convert(locale, scoreFormat)
)
);
}
@Override
public void removeScore(@NotNull Collection<Player> players, @NotNull String entry) {
WrapperPlayServerUpdateScore oldPacket = new WrapperPlayServerUpdateScore(
entry,
WrapperPlayServerUpdateScore.Action.REMOVE_ITEM,
objectiveName,
Optional.empty()
);
WrapperPlayServerResetScore newPacket = new WrapperPlayServerResetScore(
entry,
objectiveName
);
if (packetEvents.getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_20_3)) {
provider.sendPacket(players, newPacket);
} else {
provider.sendPacket(players, oldPacket);
}
}
private WrapperPlayServerScoreboardObjective createObjectivePacket(
@NotNull Locale locale,
@NotNull PropertiesPacketType packetType,
@NotNull Component value,
@NotNull ObjectiveRenderType renderType,
@Nullable ScoreFormat format
) {
WrapperPlayServerScoreboardObjective.ObjectiveMode peMode;
switch (packetType) {
case CREATE:
peMode = WrapperPlayServerScoreboardObjective.ObjectiveMode.CREATE;
break;
case UPDATE:
peMode = WrapperPlayServerScoreboardObjective.ObjectiveMode.UPDATE;
break;
default:
throw new IllegalStateException();
}
WrapperPlayServerScoreboardObjective.RenderType peRenderType;
switch (renderType) {
case INTEGER:
peRenderType = WrapperPlayServerScoreboardObjective.RenderType.INTEGER;
break;
case HEARTS:
peRenderType = WrapperPlayServerScoreboardObjective.RenderType.HEARTS;
break;
default:
throw new IllegalStateException();
}
return new WrapperPlayServerScoreboardObjective(
objectiveName,
peMode,
GlobalTranslator.render(value, locale),
peRenderType,
ScoreFormatConverter.convert(locale, format)
);
}
}
@@ -1,56 +0,0 @@
package net.megavex.scoreboardlibrary.implementation.packetAdapter.packetevents;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import net.megavex.scoreboardlibrary.implementation.commons.LineRenderingStrategy;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketAdapterProvider;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.objective.ObjectivePacketAdapter;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.packetevents.team.TeamsPacketAdapterImpl;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamsPacketAdapter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused")
public class PacketAdapterProviderImpl implements PacketAdapterProvider {
private final PacketEventsAPI<?> packetEvents;
private final PacketEventsSender packetSender;
public PacketAdapterProviderImpl() {
this.packetEvents = PacketEvents.getAPI();
if (this.packetEvents == null) {
throw new IllegalStateException("PacketEvents exists in classpath but isn't loaded");
}
this.packetSender = new PacketEventsSender(this.packetEvents);
}
@Override
public @NotNull TeamsPacketAdapter createTeamPacketAdapter(@NotNull String teamName) {
return new TeamsPacketAdapterImpl(packetSender, teamName);
}
@Override
public @NotNull ObjectivePacketAdapter createObjectiveAdapter(@NotNull String objectiveName) {
return new ObjectivePacketAdapterImpl(packetSender, packetEvents, objectiveName);
}
@Override
public @NotNull LineRenderingStrategy lineRenderingStrategy(@NotNull Player player) {
ServerVersion serverVer = packetEvents.getServerManager().getVersion();
return serverVer.isNewerThanOrEquals(ServerVersion.V_1_13) ? LineRenderingStrategy.MODERN : LineRenderingStrategy.LEGACY;
// Waiting for packetevents to fix https://github.com/retrooper/packetevents/issues/1024
/*
if (serverVer.isOlderThan(ServerVersion.V_1_13)) {
return LineRenderingStrategy.LEGACY;
}
if (Bukkit.getServer().getPluginManager().isPluginEnabled("ProtocolSupport")) {
return LineRenderingStrategy.MODERN;
}
ClientVersion clientVer = packetEvents.getPlayerManager().getClientVersion(player);
return clientVer.isNewerThanOrEquals(ClientVersion.V_1_13) ? LineRenderingStrategy.MODERN : LineRenderingStrategy.LEGACY;
*/
}
}
@@ -1,65 +0,0 @@
package net.megavex.scoreboardlibrary.implementation.packetAdapter.packetevents;
import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
import com.github.retrooper.packetevents.netty.channel.ChannelHelper;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
public class PacketEventsSender implements PacketSender<PacketWrapper<?>> {
private final PacketEventsAPI<?> packetEvents;
public PacketEventsSender(@NotNull PacketEventsAPI<?> packetEvents) {
this.packetEvents = packetEvents;
}
//@SuppressWarnings("UnstableApiUsage, deprecation")
@Override
public void sendPacket(Player player, PacketWrapper<?> packet) {
packetEvents.getPlayerManager().sendPacket(player, packet);
/*
ServerVersion serverVer = packetEvents.getServerManager().getVersion();
ClientVersion clientVer = packetEvents.getPlayerManager().getClientVersion(player);
if (serverVer.isOlderThan(ServerVersion.V_1_13) || clientVer.isNewerThanOrEquals(ClientVersion.V_1_13)) {
packetEvents.getPlayerManager().sendPacket(player, packet);
return;
}
// This is a hack to send packets directly skipping plugins such as ViaVersion and ViaRewind
// Based on https://discord.com/channels/721686193061888071/755472595096174873/1193239879560212520
// (PacketEvents Discord)
User user = packetEvents.getPlayerManager().getUser(player);
if (user == null) {
return;
}
Object channel = user.getChannel();
if (!ChannelHelper.isOpen(channel)) {
return;
}
String viaEncoder = "via-encoder";
if (ChannelHelper.getPipelineHandler(channel, viaEncoder) == null) {
packetEvents.getPlayerManager().sendPacket(player, packet);
return;
}
packet.buffer = ChannelHelper.pooledByteBuf(channel);
int id = Objects.requireNonNull(packet.getPacketTypeData().getPacketType()).getId(user.getClientVersion());
ByteBufHelper.writeVarInt(packet.buffer, id);
packet.setServerVersion(clientVer.toServerVersion());
packet.write();
ChannelHelper.writeAndFlushInContext(channel, viaEncoder, packet.buffer);
*/
}
}
@@ -1,31 +0,0 @@
package net.megavex.scoreboardlibrary.implementation.packetAdapter.packetevents;
import net.kyori.adventure.translation.GlobalTranslator;
import net.megavex.scoreboardlibrary.api.objective.ScoreFormat;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
import static com.github.retrooper.packetevents.protocol.score.ScoreFormat.*;
public final class ScoreFormatConverter {
private ScoreFormatConverter() {
}
public static @Nullable com.github.retrooper.packetevents.protocol.score.ScoreFormat convert(@NotNull Locale locale, @Nullable ScoreFormat format) {
if (format == null) {
return null;
}
if (format == ScoreFormat.blank()) {
return blankScore();
} else if (format instanceof ScoreFormat.Styled) {
return styledScore(((ScoreFormat.Styled) format).style());
} else if (format instanceof ScoreFormat.Fixed) {
return fixedScore(GlobalTranslator.render(((ScoreFormat.Fixed) format).content(), locale));
} else {
throw new IllegalArgumentException("Invalid score format: " + format);
}
}
}
@@ -1,61 +0,0 @@
package net.megavex.scoreboardlibrary.implementation.packetAdapter.packetevents.team;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTeams;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.ImmutableTeamProperties;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.PropertiesPacketType;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.EntriesPacketType;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamDisplayPacketAdapter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public abstract class AbstractTeamDisplayPacketAdapter<T> implements TeamDisplayPacketAdapter {
protected final PacketSender<PacketWrapper<?>> sender;
protected final String teamName;
protected final ImmutableTeamProperties<T> properties;
public AbstractTeamDisplayPacketAdapter(@NotNull PacketSender<PacketWrapper<?>> sender, @NotNull String teamName, @NotNull ImmutableTeamProperties<T> properties) {
this.sender = sender;
this.teamName = teamName;
this.properties = properties;
}
@Override
public void sendEntries(@NotNull EntriesPacketType packetType, @NotNull Collection<Player> players, @NotNull Collection<String> entries) {
WrapperPlayServerTeams.TeamMode peMode;
switch (packetType) {
case ADD:
peMode = WrapperPlayServerTeams.TeamMode.ADD_ENTITIES;
break;
case REMOVE:
peMode = WrapperPlayServerTeams.TeamMode.REMOVE_ENTITIES;
break;
default:
throw new IllegalStateException();
}
sender.sendPacket(
players,
new WrapperPlayServerTeams(
teamName,
peMode,
(WrapperPlayServerTeams.ScoreBoardTeamInfo) null,
entries
)
);
}
protected @NotNull WrapperPlayServerTeams.TeamMode mode(@NotNull PropertiesPacketType packetType) {
switch (packetType) {
case CREATE:
return WrapperPlayServerTeams.TeamMode.CREATE;
case UPDATE:
return WrapperPlayServerTeams.TeamMode.UPDATE;
default:
throw new IllegalStateException();
}
}
}
@@ -1,55 +0,0 @@
package net.megavex.scoreboardlibrary.implementation.packetAdapter.packetevents.team;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTeams;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.translation.GlobalTranslator;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.ImmutableTeamProperties;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.PropertiesPacketType;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.util.LocalePacketUtil;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public class AdventureTeamDisplayPacketAdapter extends AbstractTeamDisplayPacketAdapter<Component> {
public AdventureTeamDisplayPacketAdapter(@NotNull PacketSender<PacketWrapper<?>> sender, @NotNull String teamName, @NotNull ImmutableTeamProperties<Component> properties) {
super(sender, teamName, properties);
}
@Override
public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Collection<Player> players) {
LocalePacketUtil.sendLocalePackets(
sender,
players,
locale -> {
Component displayName = GlobalTranslator.render(properties.displayName(), locale);
Component prefix = GlobalTranslator.render(properties.prefix(), locale);
Component suffix = GlobalTranslator.render(properties.suffix(), locale);
WrapperPlayServerTeams.NameTagVisibility nameTagVisibility = WrapperPlayServerTeams.NameTagVisibility.values()[properties.nameTagVisibility().ordinal()];
WrapperPlayServerTeams.CollisionRule collisionRule = WrapperPlayServerTeams.CollisionRule.values()[properties.collisionRule().ordinal()];
NamedTextColor color = properties.playerColor() != null ? properties.playerColor() : NamedTextColor.WHITE;
WrapperPlayServerTeams.OptionData optionData = WrapperPlayServerTeams.OptionData.fromValue((byte) properties.packOptions());
WrapperPlayServerTeams.ScoreBoardTeamInfo info = new WrapperPlayServerTeams.ScoreBoardTeamInfo(
displayName,
prefix,
suffix,
nameTagVisibility,
collisionRule,
color,
optionData
);
return new WrapperPlayServerTeams(
teamName,
mode(packetType),
info,
properties.syncedEntries()
);
});
}
}
@@ -1,31 +0,0 @@
package net.megavex.scoreboardlibrary.implementation.packetAdapter.packetevents.team;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.ImmutableTeamProperties;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.PropertiesPacketType;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.util.LocalePacketUtil;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public class LegacyTeamDisplayPacketAdapter extends AbstractTeamDisplayPacketAdapter<String> {
public LegacyTeamDisplayPacketAdapter(@NotNull PacketSender<PacketWrapper<?>> sender, @NotNull String teamName, @NotNull ImmutableTeamProperties<String> properties) {
super(sender, teamName, properties);
}
@Override
public void sendProperties(@NotNull PropertiesPacketType packetType, @NotNull Collection<Player> players) {
LocalePacketUtil.sendLocalePackets(
sender,
players,
locale -> new WrapperPlayServerTeamsLegacy(
teamName,
properties,
mode(packetType)
)
);
}
}
@@ -1,45 +0,0 @@
package net.megavex.scoreboardlibrary.implementation.packetAdapter.packetevents.team;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTeams;
import net.kyori.adventure.text.Component;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.ImmutableTeamProperties;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.PacketSender;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamDisplayPacketAdapter;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.team.TeamsPacketAdapter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class TeamsPacketAdapterImpl implements TeamsPacketAdapter {
private final PacketSender<PacketWrapper<?>> sender;
private final String teamName;
private WrapperPlayServerTeams removePacket;
public TeamsPacketAdapterImpl(PacketSender<PacketWrapper<?>> sender, String teamName) {
this.sender = sender;
this.teamName = teamName;
}
@Override
public void removeTeam(@NotNull Iterable<Player> players) {
if (removePacket == null) {
removePacket = new WrapperPlayServerTeams(
teamName,
WrapperPlayServerTeams.TeamMode.REMOVE,
(WrapperPlayServerTeams.ScoreBoardTeamInfo) null
);
}
sender.sendPacket(players, removePacket);
}
@Override
public @NotNull TeamDisplayPacketAdapter createTeamDisplayAdapter(@NotNull ImmutableTeamProperties<Component> properties) {
return new AdventureTeamDisplayPacketAdapter(sender, teamName, properties);
}
@Override
public @NotNull TeamDisplayPacketAdapter createLegacyTeamDisplayAdapter(@NotNull ImmutableTeamProperties<String> properties) {
return new LegacyTeamDisplayPacketAdapter(sender, teamName, properties);
}
}
@@ -1,60 +0,0 @@
package net.megavex.scoreboardlibrary.implementation.packetAdapter.packetevents.team;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.util.ColorUtil;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTeams;
import com.google.common.base.Preconditions;
import net.megavex.scoreboardlibrary.api.team.enums.NameTagVisibility;
import net.megavex.scoreboardlibrary.implementation.packetAdapter.ImmutableTeamProperties;
public class WrapperPlayServerTeamsLegacy extends PacketWrapper<WrapperPlayServerTeamsLegacy> {
private final String teamName;
private final ImmutableTeamProperties<String> properties;
private final WrapperPlayServerTeams.TeamMode teamMode;
public WrapperPlayServerTeamsLegacy(String teamName, ImmutableTeamProperties<String> properties, WrapperPlayServerTeams.TeamMode teamMode) {
super(PacketType.Play.Server.TEAMS);
this.teamName = teamName;
this.properties = properties;
Preconditions.checkArgument(teamMode == WrapperPlayServerTeams.TeamMode.CREATE || teamMode == WrapperPlayServerTeams.TeamMode.UPDATE);
this.teamMode = teamMode;
}
@Override
public void write() {
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_13)) {
throw new IllegalStateException("Tried to serialize legacy teams packet on 1.13+ server version");
}
writeString(teamName, 16);
writeByte(teamMode.ordinal());
writeString(properties.displayName());
writeString(properties.prefix());
writeString(properties.suffix());
writeByte(properties.packOptions());
if (serverVersion == ServerVersion.V_1_7_10) {
writeString(NameTagVisibility.ALWAYS.key());
writeByte(15);
} else {
writeString(properties.nameTagVisibility().key());
if (serverVersion.isNewerThanOrEquals(ServerVersion.V_1_9)) {
writeString(properties.collisionRule().key());
}
writeByte(ColorUtil.getId(properties.playerColor()));
}
if (teamMode == WrapperPlayServerTeams.TeamMode.CREATE) {
if (serverVersion == ServerVersion.V_1_7_10) {
writeShort(properties.syncedEntries().size());
} else {
writeVarInt(properties.syncedEntries().size());
}
for (String entry : properties.syncedEntries()) {
writeString(entry);
}
}
}
}