Added support for 1.8.x and 1.12.2 clients (#87)

* Added support for 1.12.2 players

* Added support for 1.8.x & fixed code style

* Moved VersionManager inside ScoreboardManager

* Code refactor

* Update src/main/java/net/william278/velocitab/packet/UpdateTeamsPacket.java

Co-authored-by: William <will27528@gmail.com>

* Update src/main/java/net/william278/velocitab/packet/UpdateTeamsPacket.java

Co-authored-by: William <will27528@gmail.com>

* Update src/main/java/net/william278/velocitab/packet/ProtocolAbstractAdapter.java

Co-authored-by: William <will27528@gmail.com>

* Added requested changes

* Code refactoring

---------

Co-authored-by: William <will27528@gmail.com>
This commit is contained in:
AlexDev_ 2023-09-12 16:30:55 +02:00 committed by GitHub
parent 1544e302b2
commit 8d654d6b26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 396 additions and 57 deletions

View File

@ -0,0 +1,89 @@
/*
* This file is part of Velocitab, licensed under the Apache License 2.0.
*
* Copyright (c) William278 <will27528@gmail.com>
* Copyright (c) contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.william278.velocitab.packet;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@SuppressWarnings("DuplicatedCode")
public class Protocol340Adapter extends TeamsPacketAdapter {
public Protocol340Adapter() {
super(Set.of(ProtocolVersion.MINECRAFT_1_12_2));
}
@Override
public void decode(ByteBuf byteBuf, UpdateTeamsPacket updateTeamsPacket) {
updateTeamsPacket.teamName(ProtocolUtils.readString(byteBuf));
UpdateTeamsPacket.UpdateMode mode = UpdateTeamsPacket.UpdateMode.byId(byteBuf.readByte());
if (mode == UpdateTeamsPacket.UpdateMode.REMOVE_TEAM) {
return;
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.UPDATE_INFO) {
updateTeamsPacket.displayName(ProtocolUtils.readString(byteBuf));
updateTeamsPacket.prefix(ProtocolUtils.readString(byteBuf));
updateTeamsPacket.suffix(ProtocolUtils.readString(byteBuf));
updateTeamsPacket.friendlyFlags(UpdateTeamsPacket.FriendlyFlag.fromBitMask(byteBuf.readByte()));
updateTeamsPacket.nameTagVisibility(UpdateTeamsPacket.NameTagVisibility.byId(ProtocolUtils.readString(byteBuf)));
updateTeamsPacket.collisionRule(UpdateTeamsPacket.CollisionRule.byId(ProtocolUtils.readString(byteBuf)));
updateTeamsPacket.color(byteBuf.readByte());
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.ADD_PLAYERS || mode == UpdateTeamsPacket.UpdateMode.REMOVE_PLAYERS) {
int entityCount = ProtocolUtils.readVarInt(byteBuf);
List<String> entities = new ArrayList<>(entityCount);
for (int j = 0; j < entityCount; j++) {
entities.add(ProtocolUtils.readString(byteBuf));
}
updateTeamsPacket.entities(entities);
}
}
@Override
public void encode(ByteBuf byteBuf, UpdateTeamsPacket updateTeamsPacket) {
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.teamName().substring(0, Math.min(updateTeamsPacket.teamName().length(), 16)));
UpdateTeamsPacket.UpdateMode mode = updateTeamsPacket.mode();
byteBuf.writeByte(mode.id());
if (mode == UpdateTeamsPacket.UpdateMode.REMOVE_TEAM) {
return;
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.UPDATE_INFO) {
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.displayName());
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.prefix());
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.suffix());
byteBuf.writeByte(UpdateTeamsPacket.FriendlyFlag.toBitMask(updateTeamsPacket.friendlyFlags()));
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.nameTagVisibility().id());
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.collisionRule().id());
byteBuf.writeByte(updateTeamsPacket.color());
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.ADD_PLAYERS || mode == UpdateTeamsPacket.UpdateMode.REMOVE_PLAYERS) {
List<String> entities = updateTeamsPacket.entities();
ProtocolUtils.writeVarInt(byteBuf, entities != null ? entities.size() : 0);
for (String entity : entities != null ? entities : new ArrayList<String>()) {
ProtocolUtils.writeString(byteBuf, entity);
}
}
}
}

View File

@ -0,0 +1,97 @@
/*
* This file is part of Velocitab, licensed under the Apache License 2.0.
*
* Copyright (c) William278 <will27528@gmail.com>
* Copyright (c) contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.william278.velocitab.packet;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@SuppressWarnings("DuplicatedCode")
public class Protocol403Adapter extends TeamsPacketAdapter {
public Protocol403Adapter() {
super(Set.of(ProtocolVersion.MINECRAFT_1_13_2,
ProtocolVersion.MINECRAFT_1_14_4,
ProtocolVersion.MINECRAFT_1_15_2,
ProtocolVersion.MINECRAFT_1_16_4,
ProtocolVersion.MINECRAFT_1_17_1,
ProtocolVersion.MINECRAFT_1_18_2,
ProtocolVersion.MINECRAFT_1_19_4,
ProtocolVersion.MINECRAFT_1_20
));
}
@Override
public void decode(ByteBuf byteBuf, UpdateTeamsPacket updateTeamsPacket) {
updateTeamsPacket.teamName(ProtocolUtils.readString(byteBuf));
UpdateTeamsPacket.UpdateMode mode = UpdateTeamsPacket.UpdateMode.byId(byteBuf.readByte());
if (mode == UpdateTeamsPacket.UpdateMode.REMOVE_TEAM) {
return;
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.UPDATE_INFO) {
updateTeamsPacket.displayName(ProtocolUtils.readString(byteBuf));
updateTeamsPacket.friendlyFlags(UpdateTeamsPacket.FriendlyFlag.fromBitMask(byteBuf.readByte()));
updateTeamsPacket.nameTagVisibility(UpdateTeamsPacket.NameTagVisibility.byId(ProtocolUtils.readString(byteBuf)));
updateTeamsPacket.collisionRule(UpdateTeamsPacket.CollisionRule.byId(ProtocolUtils.readString(byteBuf)));
updateTeamsPacket.color(byteBuf.readByte());
updateTeamsPacket.prefix(ProtocolUtils.readString(byteBuf));
updateTeamsPacket.suffix(ProtocolUtils.readString(byteBuf));
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.ADD_PLAYERS || mode == UpdateTeamsPacket.UpdateMode.REMOVE_PLAYERS) {
int entityCount = ProtocolUtils.readVarInt(byteBuf);
List<String> entities = new ArrayList<>(entityCount);
for (int j = 0; j < entityCount; j++) {
entities.add(ProtocolUtils.readString(byteBuf));
}
updateTeamsPacket.entities(entities);
}
}
@Override
public void encode(ByteBuf byteBuf, UpdateTeamsPacket updateTeamsPacket) {
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.teamName());
UpdateTeamsPacket.UpdateMode mode = updateTeamsPacket.mode();
byteBuf.writeByte(mode.id());
if (mode == UpdateTeamsPacket.UpdateMode.REMOVE_TEAM) {
return;
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.UPDATE_INFO) {
ProtocolUtils.writeString(byteBuf, getChatString(updateTeamsPacket.displayName()));
byteBuf.writeByte(UpdateTeamsPacket.FriendlyFlag.toBitMask(updateTeamsPacket.friendlyFlags()));
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.nameTagVisibility().id());
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.collisionRule().id());
byteBuf.writeByte(updateTeamsPacket.color());
ProtocolUtils.writeString(byteBuf, getChatString(updateTeamsPacket.prefix()));
ProtocolUtils.writeString(byteBuf, getChatString(updateTeamsPacket.suffix()));
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.ADD_PLAYERS || mode == UpdateTeamsPacket.UpdateMode.REMOVE_PLAYERS) {
List<String> entities = updateTeamsPacket.entities();
ProtocolUtils.writeVarInt(byteBuf, entities != null ? entities.size() : 0);
for (String entity : entities != null ? entities : new ArrayList<String>()) {
ProtocolUtils.writeString(byteBuf, entity);
}
}
}
}

View File

@ -0,0 +1,87 @@
/*
* This file is part of Velocitab, licensed under the Apache License 2.0.
*
* Copyright (c) William278 <will27528@gmail.com>
* Copyright (c) contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.william278.velocitab.packet;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@SuppressWarnings("DuplicatedCode")
public class Protocol48Adapter extends TeamsPacketAdapter {
public Protocol48Adapter() {
super(Set.of(ProtocolVersion.MINECRAFT_1_8));
}
@Override
public void decode(ByteBuf byteBuf, UpdateTeamsPacket updateTeamsPacket) {
updateTeamsPacket.teamName(ProtocolUtils.readString(byteBuf));
UpdateTeamsPacket.UpdateMode mode = UpdateTeamsPacket.UpdateMode.byId(byteBuf.readByte());
if (mode == UpdateTeamsPacket.UpdateMode.REMOVE_TEAM) {
return;
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.UPDATE_INFO) {
updateTeamsPacket.displayName(ProtocolUtils.readString(byteBuf));
updateTeamsPacket.prefix(ProtocolUtils.readString(byteBuf));
updateTeamsPacket.suffix(ProtocolUtils.readString(byteBuf));
updateTeamsPacket.friendlyFlags(UpdateTeamsPacket.FriendlyFlag.fromBitMask(byteBuf.readByte()));
updateTeamsPacket.nameTagVisibility(UpdateTeamsPacket.NameTagVisibility.byId(ProtocolUtils.readString(byteBuf)));
updateTeamsPacket.color(byteBuf.readByte());
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.ADD_PLAYERS || mode == UpdateTeamsPacket.UpdateMode.REMOVE_PLAYERS) {
int entityCount = ProtocolUtils.readVarInt(byteBuf);
List<String> entities = new ArrayList<>(entityCount);
for (int j = 0; j < entityCount; j++) {
entities.add(ProtocolUtils.readString(byteBuf));
}
updateTeamsPacket.entities(entities);
}
}
@Override
public void encode(ByteBuf byteBuf, UpdateTeamsPacket updateTeamsPacket) {
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.teamName().substring(0, Math.min(updateTeamsPacket.teamName().length(), 16)));
UpdateTeamsPacket.UpdateMode mode = updateTeamsPacket.mode();
byteBuf.writeByte(mode.id());
if (mode == UpdateTeamsPacket.UpdateMode.REMOVE_TEAM) {
return;
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.UPDATE_INFO) {
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.displayName());
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.prefix());
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.suffix());
byteBuf.writeByte(UpdateTeamsPacket.FriendlyFlag.toBitMask(updateTeamsPacket.friendlyFlags()));
ProtocolUtils.writeString(byteBuf, updateTeamsPacket.nameTagVisibility().id());
byteBuf.writeByte(updateTeamsPacket.color());
}
if (mode == UpdateTeamsPacket.UpdateMode.CREATE_TEAM || mode == UpdateTeamsPacket.UpdateMode.ADD_PLAYERS || mode == UpdateTeamsPacket.UpdateMode.REMOVE_PLAYERS) {
List<String> entities = updateTeamsPacket.entities();
ProtocolUtils.writeVarInt(byteBuf, entities != null ? entities.size() : 0);
for (String entity : entities != null ? entities : new ArrayList<String>()) {
ProtocolUtils.writeString(byteBuf, entity);
}
}
}
}

View File

@ -19,6 +19,7 @@
package net.william278.velocitab.packet;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
@ -38,11 +39,31 @@ public class ScoreboardManager {
private final Velocitab plugin;
private final Map<UUID, List<String>> createdTeams;
private final Map<UUID, Map<String, String>> roleMappings;
private final Set<TeamsPacketAdapter> versions;
public ScoreboardManager(@NotNull Velocitab velocitab) {
this.plugin = velocitab;
this.createdTeams = new HashMap<>();
this.roleMappings = new HashMap<>();
this.versions = new HashSet<>();
this.registerVersions();
}
private void registerVersions() {
versions.add(new Protocol403Adapter());
versions.add(new Protocol340Adapter());
versions.add(new Protocol48Adapter());
}
public TeamsPacketAdapter getPacketAdapter(ProtocolVersion protocolVersion) {
return versions.stream()
.filter(version -> version.getProtocolVersions().contains(protocolVersion))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No version found for protocol version " + protocolVersion));
}
public void sendProtocolError(String message) {
plugin.log(Level.ERROR, message);
}
public void resetCache(@NotNull Player player) {
@ -69,7 +90,7 @@ public class ScoreboardManager {
return;
}
if (!createdTeams.getOrDefault(player.getUniqueId(), List.of()).contains(role)) {
dispatchPacket(UpdateTeamsPacket.create(role, playerNames), player);
dispatchPacket(UpdateTeamsPacket.create(plugin, role, playerNames), player);
createdTeams.computeIfAbsent(player.getUniqueId(), k -> new ArrayList<>()).add(role);
roleMappings.computeIfAbsent(player.getUniqueId(), k -> new HashMap<>()).put(player.getUsername(), role);
} else {
@ -77,8 +98,8 @@ public class ScoreboardManager {
.entrySet().stream()
.filter((entry) -> List.of(playerNames).contains(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
.forEach((playerName, oldRole) -> dispatchPacket(UpdateTeamsPacket.removeFromTeam(oldRole, playerName), player));
dispatchPacket(UpdateTeamsPacket.addToTeam(role, playerNames), player);
.forEach((playerName, oldRole) -> dispatchPacket(UpdateTeamsPacket.removeFromTeam(plugin, oldRole, playerName), player));
dispatchPacket(UpdateTeamsPacket.addToTeam(plugin, role, playerNames), player);
roleMappings.computeIfAbsent(player.getUniqueId(), k -> new HashMap<>()).put(player.getUsername(), role);
}
}
@ -101,8 +122,10 @@ public class ScoreboardManager {
try {
packetRegistration = PacketRegistration.of(UpdateTeamsPacket.class)
.direction(ProtocolUtils.Direction.CLIENTBOUND)
.packetSupplier(UpdateTeamsPacket::new)
.packetSupplier(() -> new UpdateTeamsPacket(plugin))
.stateRegistry(StateRegistry.PLAY)
.mapping(0x3E, MINECRAFT_1_8, false)
.mapping(0x44, MINECRAFT_1_12_2, false)
.mapping(0x47, MINECRAFT_1_13, false)
.mapping(0x4B, MINECRAFT_1_14, false)
.mapping(0x4C, MINECRAFT_1_15, false)
@ -117,7 +140,7 @@ public class ScoreboardManager {
}
public void unregisterPacket() {
if(packetRegistration==null) {
if (packetRegistration == null) {
return;
}
try {

View File

@ -0,0 +1,48 @@
/*
* This file is part of Velocitab, licensed under the Apache License 2.0.
*
* Copyright (c) William278 <will27528@gmail.com>
* Copyright (c) contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.william278.velocitab.packet;
import com.velocitypowered.api.network.ProtocolVersion;
import io.netty.buffer.ByteBuf;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.commons.text.StringEscapeUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
@Getter
@RequiredArgsConstructor
public abstract class TeamsPacketAdapter {
private final Set<ProtocolVersion> protocolVersions;
public abstract void decode(ByteBuf byteBuf, UpdateTeamsPacket updateTeamsPacket);
public abstract void encode(ByteBuf byteBuf, UpdateTeamsPacket updateTeamsPacket);
@NotNull
protected String getChatString(@NotNull String string) {
return String.format("{\"text\":\"%s\"}", StringEscapeUtils.escapeJson(string));
}
}

View File

@ -26,24 +26,25 @@ import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
import lombok.*;
import lombok.experimental.Accessors;
import org.apache.commons.text.StringEscapeUtils;
import net.william278.velocitab.Velocitab;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
@Accessors(fluent = true)
public class UpdateTeamsPacket implements MinecraftPacket {
private final Velocitab plugin;
private String teamName;
private UpdateMode mode;
private String displayName;
@ -55,89 +56,77 @@ public class UpdateTeamsPacket implements MinecraftPacket {
private String suffix;
private List<String> entities;
public UpdateTeamsPacket(Velocitab plugin) {
this.plugin = plugin;
}
@NotNull
protected static UpdateTeamsPacket create(@NotNull String teamName, @NotNull String... teamMembers) {
return new UpdateTeamsPacket()
protected static UpdateTeamsPacket create(@NotNull Velocitab plugin, @NotNull String teamName, @NotNull String... teamMembers) {
return new UpdateTeamsPacket(plugin)
.teamName(teamName.length() > 16 ? teamName.substring(0, 16) : teamName)
.mode(UpdateMode.CREATE_TEAM)
.displayName(getChatString(teamName))
.displayName(teamName)
.friendlyFlags(List.of(FriendlyFlag.CAN_HURT_FRIENDLY))
.nameTagVisibility(NameTagVisibility.ALWAYS)
.collisionRule(CollisionRule.ALWAYS)
.color(15)
.prefix(getChatString(""))
.suffix(getChatString(""))
.prefix("")
.suffix("")
.entities(Arrays.asList(teamMembers));
}
@NotNull
protected static UpdateTeamsPacket addToTeam(@NotNull String teamName, @NotNull String... teamMembers) {
return new UpdateTeamsPacket()
protected static UpdateTeamsPacket addToTeam(@NotNull Velocitab plugin, @NotNull String teamName, @NotNull String... teamMembers) {
return new UpdateTeamsPacket(plugin)
.teamName(teamName.length() > 16 ? teamName.substring(0, 16) : teamName)
.mode(UpdateMode.ADD_PLAYERS)
.entities(Arrays.asList(teamMembers));
}
@NotNull
protected static UpdateTeamsPacket removeFromTeam(@NotNull String teamName, @NotNull String... teamMembers) {
return new UpdateTeamsPacket()
protected static UpdateTeamsPacket removeFromTeam(@NotNull Velocitab plugin, @NotNull String teamName, @NotNull String... teamMembers) {
return new UpdateTeamsPacket(plugin)
.teamName(teamName.length() > 16 ? teamName.substring(0, 16) : teamName)
.mode(UpdateMode.REMOVE_PLAYERS)
.entities(Arrays.asList(teamMembers));
}
@NotNull
private static String getChatString(@NotNull String string) {
return "{\"text\":\"" + StringEscapeUtils.escapeJson(string) + "\"}";
}
@Override
public void decode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
teamName = ProtocolUtils.readString(byteBuf);
mode = UpdateMode.byId(byteBuf.readByte());
if (mode == UpdateMode.REMOVE_TEAM) {
Optional<ScoreboardManager> scoreboardManagerOptional = plugin.getScoreboardManager();
if (scoreboardManagerOptional.isEmpty()) {
return;
}
if (mode == UpdateMode.CREATE_TEAM || mode == UpdateMode.UPDATE_INFO) {
displayName = ProtocolUtils.readString(byteBuf);
friendlyFlags = FriendlyFlag.fromBitMask(byteBuf.readByte());
nameTagVisibility = NameTagVisibility.byId(ProtocolUtils.readString(byteBuf));
collisionRule = CollisionRule.byId(ProtocolUtils.readString(byteBuf));
color = byteBuf.readByte();
prefix = ProtocolUtils.readString(byteBuf);
suffix = ProtocolUtils.readString(byteBuf);
}
if (mode == UpdateMode.CREATE_TEAM || mode == UpdateMode.ADD_PLAYERS || mode == UpdateMode.REMOVE_PLAYERS) {
int entityCount = ProtocolUtils.readVarInt(byteBuf);
entities = new ArrayList<>(entityCount);
for (int j = 0; j < entityCount; j++) {
entities.add(ProtocolUtils.readString(byteBuf));
}
ScoreboardManager scoreboardManager = scoreboardManagerOptional.get();
if (mode == null) {
scoreboardManager.sendProtocolError("Something went wrong while decoding a UpdateTeamsPacket" +
", if your server is on 1.8.x and you are using ViaVersion," +
", please disable 'auto-team' in the config.yml and reload it.");
}
scoreboardManager.getPacketAdapter(protocolVersion).decode(byteBuf, this);
}
@Override
public void encode(ByteBuf byteBuf, ProtocolUtils.Direction direction, ProtocolVersion protocolVersion) {
ProtocolUtils.writeString(byteBuf, teamName);
byteBuf.writeByte(mode.id());
if (mode == UpdateMode.REMOVE_TEAM) {
Optional<ScoreboardManager> scoreboardManagerOptional = plugin.getScoreboardManager();
if (scoreboardManagerOptional.isEmpty()) {
return;
}
if (mode == UpdateMode.CREATE_TEAM || mode == UpdateMode.UPDATE_INFO) {
ProtocolUtils.writeString(byteBuf, displayName);
byteBuf.writeByte(FriendlyFlag.toBitMask(friendlyFlags));
ProtocolUtils.writeString(byteBuf, nameTagVisibility.id());
ProtocolUtils.writeString(byteBuf, collisionRule.id());
byteBuf.writeByte(color);
ProtocolUtils.writeString(byteBuf, prefix);
ProtocolUtils.writeString(byteBuf, suffix);
}
if (mode == UpdateMode.CREATE_TEAM || mode == UpdateMode.ADD_PLAYERS || mode == UpdateMode.REMOVE_PLAYERS) {
ProtocolUtils.writeVarInt(byteBuf, entities != null ? entities.size() : 0);
for (String entity : entities != null ? entities : new ArrayList<String>()) {
ProtocolUtils.writeString(byteBuf, entity);
}
ScoreboardManager scoreboardManager = scoreboardManagerOptional.get();
if (mode == null) {
scoreboardManager.sendProtocolError("Something went wrong while encoding a UpdateTeamsPacket" +
", if your server is on 1.8.x and you are using ViaVersion," +
", please disable 'auto-team' in the config.yml and reload it.");
}
scoreboardManager.getPacketAdapter(protocolVersion).encode(byteBuf, this);
}
@Override

View File

@ -67,6 +67,7 @@ public class PlayerTabList {
final Player joined = event.getPlayer();
plugin.getScoreboardManager().ifPresent(manager -> manager.resetCache(joined));
// Remove the player from the tracking list if they are switching servers
final RegisteredServer previousServer = event.getPreviousServer();
if (previousServer == null) {
@ -90,6 +91,8 @@ public class PlayerTabList {
final TabPlayer tabPlayer = plugin.getTabPlayer(joined);
players.add(tabPlayer);
// Update lists
plugin.getServer().getScheduler()
.buildTask(plugin, () -> {
@ -111,9 +114,12 @@ public class PlayerTabList {
() -> createEntry(player, tabList).thenAccept(tabList::addEntry)
);
addPlayerToTabList(player, tabPlayer);
player.sendHeaderAndFooter(this);
}
plugin.getScoreboardManager().ifPresent(manager -> manager.setRoles(joined, playerRoles));
})
.delay(500, TimeUnit.MILLISECONDS)