Compare commits

..
32 Commits
Author SHA1 Message Date
NEZNAMY 09dc8cd437 version bump 2021-06-16 13:52:27 +02:00
NEZNAMY c613ba401b remove unnecessary this. 2021-06-16 13:03:52 +02:00
NEZNAMY 866df0b5cf remove duplicate content 2021-06-16 11:12:43 +02:00
NEZNAMY 8f2b56ba05 2.9.0 2021-06-16 10:09:20 +02:00
NEZNAMY 2049885f11 more accurate error message 2021-06-16 09:56:15 +02:00
NEZNAMY 4caef337d5 ANOTHER BOSSBAR API BUG IN ANOTHER PLATFORM HAHA LOL 2021-06-15 23:37:02 +02:00
NEZNAMY a644792bf6 simplify 2021-06-15 22:50:16 +02:00
NEZNAMY 54c7f8fc6a drop the rest of title packet 2021-06-15 22:49:23 +02:00
NEZNAMY 2e59b87bbe use getters instead of fields 2021-06-15 22:46:42 +02:00
NEZNAMY f89242ad8f add and use magic code Boolean getters 2021-06-15 22:40:02 +02:00
NEZNAMY 845903788c remove unused code 2021-06-15 22:39:32 +02:00
NEZNAMY 53a9047c20 fix conflict between hidden-by-default and remember-toggle-choice 2021-06-15 22:36:55 +02:00
NEZNAMY a2b74bbc30 correctly display used color codes in parse error messages 2021-06-15 22:36:31 +02:00
NEZNAMY 50ef93cc45 fix stack overflow and stretch with relational placeholders 2021-06-15 22:36:00 +02:00
NEZNAMY e2a5da9c14 deserialize other scoreboard packets as well 2021-06-15 22:35:24 +02:00
NEZNAMY bf31116d0d split method 2021-06-15 22:34:42 +02:00
NEZNAMY d79fa8c4f3 drop title packet 2021-06-15 22:34:31 +02:00
NEZNAMY 87e0a7bea3 remove unused fields 2021-06-15 22:33:33 +02:00
NEZNAMY b34cabd55c optimize check 2021-06-15 22:32:50 +02:00
NEZNAMY 704bd36c77 do not try to use rgb on <1.16 servers 2021-06-14 09:35:23 +02:00
NEZNAMY 5c2c4d0f4b improved error message 2021-06-14 08:43:36 +02:00
NEZNAMY 80cca5cb34 fix #329 2021-06-14 08:22:37 +02:00
NEZNAMY dcd603f2f5 null check to prevent errors 2021-06-13 22:10:30 +02:00
NEZNAMY 1bee3b49bf sending bossbar using bukkit api 2021-06-13 20:46:16 +02:00
NEZNAMY 11bcccb8f9 fix reload from previous commit 2021-06-13 20:24:39 +02:00
NEZNAMY 7425493706 initialization cleanup 2021-06-13 19:09:34 +02:00
NEZNAMY dca0cfd424 removed old value from config 2021-06-13 17:09:03 +02:00
NEZNAMY 21314def89 fix #328 2021-06-13 15:57:06 +02:00
NEZNAMY 90e544d279 option to take groups from backend servers 2021-06-13 11:54:03 +02:00
NEZNAMY 89e21558a1 2.8.11-pre19 2021-06-12 23:23:15 +02:00
NEZNAMY b28cc51457 spigot one dot god damn seventeen 2021-06-12 23:19:09 +02:00
NEZNAMY 2d0a203b5f increased initial delay 2021-06-12 14:28:44 +02:00
45 changed files with 756 additions and 817 deletions

No files matched your search

+2 -7
View File
@@ -19,13 +19,8 @@ Premium version
Bukkit bridge https://www.spigotmc.org/resources/83966/
Wiki https://github.com/NEZNAMY/TAB/wiki
Discord invite link: https://discord.gg/EaSvdk6
## Downloads
Official release: https://www.spigotmc.org/resources/57806/
Pre-releases: https://github.com/NEZNAMY/TAB/releases
## Maven Repository
```
<repositories>
+13 -6
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>me.neznamy</groupId>
<artifactId>TAB</artifactId>
<version>2.8.11-pre18</version>
<version>2.9.0</version>
</parent>
<artifactId>bukkit</artifactId>
@@ -35,6 +35,10 @@
<url>https://repo.viaversion.com/</url>
</repository>
<repository>
<id>aikar</id>
<url>https://repo.aikar.co/content/groups/aikar/</url>
</repository>
</repositories>
<dependencies>
@@ -57,7 +61,7 @@
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.5-R0.1-SNAPSHOT</version>
<version>1.17-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
@@ -76,10 +80,6 @@
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
@@ -126,5 +126,12 @@
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mojang</groupId>
<artifactId>authlib</artifactId>
<version>1.11</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
@@ -1,17 +1,22 @@
package me.neznamy.tab.platforms.bukkit;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.gson.JsonParser;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.PropertyMap;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.gson.JsonParser;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import me.neznamy.tab.platforms.bukkit.nms.NMSStorage;
@@ -20,6 +25,7 @@ import me.neznamy.tab.shared.ProtocolVersion;
import me.neznamy.tab.shared.TAB;
import me.neznamy.tab.shared.packets.EnumChatFormat;
import me.neznamy.tab.shared.packets.IChatBaseComponent;
import me.neznamy.tab.shared.packets.IChatBaseComponent.ClickAction;
import me.neznamy.tab.shared.packets.PacketBuilder;
import me.neznamy.tab.shared.packets.PacketPlayOutBoss;
import me.neznamy.tab.shared.packets.PacketPlayOutBoss.Action;
@@ -34,8 +40,6 @@ import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardObjective;
import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardObjective.EnumScoreboardHealthDisplay;
import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardScore;
import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardTeam;
import me.neznamy.tab.shared.packets.PacketPlayOutTitle;
import me.neznamy.tab.shared.packets.IChatBaseComponent.ClickAction;
import me.neznamy.tab.shared.rgb.TextColor;
@SuppressWarnings("unchecked")
@@ -43,7 +47,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
//nms storage
private NMSStorage nms;
//entity type ids
private Map<EntityType, Integer> entityIds = new HashMap<EntityType, Integer>();
@@ -63,12 +67,12 @@ public class BukkitPacketBuilder implements PacketBuilder {
}
}
}
@Override
public Object build(PacketPlayOutBoss packet, ProtocolVersion clientVersion) throws Exception {
if (nms.minorVersion >= 9) {
//1.9+ server
return buildBossPacket19(packet, clientVersion);
//1.9+ server, handled using bukkit api
return packet;
}
if (clientVersion.getMinorVersion() >= 9 && Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) {
//1.9+ client on 1.8 server
@@ -80,27 +84,6 @@ public class BukkitPacketBuilder implements PacketBuilder {
return buildBossPacketEntity(packet, clientVersion);
}
/**
* Build 1.9 boss packet
* @param packet - packet to build
* @param clientVersion - client version
* @return 1.9 bossbar packet
* @throws Exception - if something fails
*/
private Object buildBossPacket19(PacketPlayOutBoss packet, ProtocolVersion clientVersion) throws Exception {
Object nmsPacket = nms.newPacketPlayOutBoss.newInstance();
nms.PacketPlayOutBoss_UUID.set(nmsPacket, packet.id);
nms.PacketPlayOutBoss_ACTION.set(nmsPacket, Enum.valueOf(nms.PacketPlayOutBoss_Action, packet.operation.toString()));
nms.PacketPlayOutBoss_PROGRESS.set(nmsPacket, packet.pct);
nms.PacketPlayOutBoss_NAME.set(nmsPacket, packet.name == null ? null : toNMSComponent(IChatBaseComponent.optimizedComponent(packet.name), clientVersion));
nms.PacketPlayOutBoss_COLOR.set(nmsPacket, packet.color == null ? null : Enum.valueOf(nms.BarColor, packet.color.toString()));
nms.PacketPlayOutBoss_STYLE.set(nmsPacket, packet.overlay == null ? null : Enum.valueOf(nms.BarStyle, packet.overlay.toString()));
nms.PacketPlayOutBoss_DARKEN_SKY.set(nmsPacket, packet.darkenScreen);
nms.PacketPlayOutBoss_PLAY_MUSIC.set(nmsPacket, packet.playMusic);
nms.PacketPlayOutBoss_CREATE_FOG.set(nmsPacket, packet.createWorldFog);
return nmsPacket;
}
/**
* Builds 1.9 bossbar packet bytebuf using viaversion
* @param packet - packet to build
@@ -180,36 +163,41 @@ public class BukkitPacketBuilder implements PacketBuilder {
@Override
public Object build(PacketPlayOutChat packet, ProtocolVersion clientVersion) throws Exception {
Object nmsPacket = nms.newPacketPlayOutChat.newInstance();
nms.PacketPlayOutChat_MESSAGE.set(nmsPacket, stringToComponent(packet.message.toString(clientVersion))); //using old method for chat packets due to broken item/entity deserializer
if (nms.minorVersion >= 12) {
nms.PacketPlayOutChat_POSITION.set(nmsPacket, Enum.valueOf(nms.ChatMessageType, packet.type.toString()));
} else if (nms.minorVersion >= 8) {
nms.PacketPlayOutChat_POSITION.set(nmsPacket, (byte)packet.type.ordinal());
}
Object component = stringToComponent(packet.message.toString(clientVersion));
if (nms.minorVersion >= 16) {
nms.PacketPlayOutChat_SENDER.set(nmsPacket, UUID.randomUUID());
return nms.newPacketPlayOutChat.newInstance(component, ((Object[])nms.ChatMessageType.getMethod("values").invoke(null))[packet.type.ordinal()], UUID.randomUUID());
}
return nmsPacket;
if (nms.minorVersion >= 12) {
return nms.newPacketPlayOutChat.newInstance(component, Enum.valueOf(nms.ChatMessageType, packet.type.toString()));
}
if (nms.minorVersion >= 8) {
return nms.newPacketPlayOutChat.newInstance(component, (byte) packet.type.ordinal());
}
if (nms.minorVersion == 7) {
return nms.newPacketPlayOutChat.newInstance(component);
}
throw new IllegalStateException("Not supported on <1.7");
}
@Override
public Object build(PacketPlayOutPlayerInfo packet, ProtocolVersion clientVersion) throws Exception {
if (nms.minorVersion < 8) return null;
Object nmsPacket = nms.newPacketPlayOutPlayerInfo.newInstance();
nms.PacketPlayOutPlayerInfo_ACTION.set(nmsPacket, Enum.valueOf(nms.EnumPlayerInfoAction, packet.action.toString()));
Object nmsPacket = nms.newPacketPlayOutPlayerInfo.newInstance(((Object[])nms.EnumPlayerInfoAction.getMethod("values").invoke(null))[packet.action.ordinal()], Array.newInstance(nms.EntityPlayer, 0));
List<Object> items = new ArrayList<Object>();
for (PlayerInfoData data : packet.entries) {
Object profile = nms.newGameProfile.newInstance(data.uniqueId, data.name);
if (data.skin != null) nms.PropertyMap_putAll.invoke(nms.GameProfile_PROPERTIES.get(profile), data.skin);
GameProfile profile = new GameProfile(data.uniqueId, data.name);
if (data.skin != null) profile.getProperties().putAll((PropertyMap) data.skin);
List<Object> parameters = new ArrayList<Object>();
if (nms.newPlayerInfoData.getParameterCount() == 5) {
items.add(nms.newPlayerInfoData.newInstance(nms.newPacketPlayOutPlayerInfo.newInstance(), profile, data.latency, data.gameMode == null ? null : Enum.valueOf(nms.EnumGamemode, data.gameMode.toString()),
data.displayName == null ? null : toNMSComponent(data.displayName, clientVersion)));
} else {
//1.8.8 paper
items.add(nms.newPlayerInfoData.newInstance(profile, data.latency, data.gameMode == null ? null : Enum.valueOf(nms.EnumGamemode, data.gameMode.toString()),
data.displayName == null ? null : toNMSComponent(data.displayName, clientVersion)));
parameters.add(nmsPacket);
}
parameters.add(profile);
parameters.add(data.latency);
Object[] values = (Object[]) nms.EnumGamemode.getMethod("values").invoke(null);
parameters.add(data.gameMode == null ? null : values[values.length-EnumGamemode.values().length+data.gameMode.ordinal()]); //not_set was removed in 1.17
parameters.add(data.displayName == null ? null : toNMSComponent(data.displayName, clientVersion));
items.add(nms.newPlayerInfoData.newInstance(parameters.toArray()));
}
nms.PacketPlayOutPlayerInfo_PLAYERS.set(nmsPacket, items);
return nmsPacket;
@@ -218,6 +206,9 @@ public class BukkitPacketBuilder implements PacketBuilder {
@Override
public Object build(PacketPlayOutPlayerListHeaderFooter packet, ProtocolVersion clientVersion) throws Exception {
if (nms.PacketPlayOutPlayerListHeaderFooter == null) return null;
if (nms.minorVersion >= 17) {
return nms.newPacketPlayOutPlayerListHeaderFooter.newInstance(toNMSComponent(packet.header, clientVersion), toNMSComponent(packet.footer, clientVersion));
}
Object nmsPacket = nms.newPacketPlayOutPlayerListHeaderFooter.newInstance();
nms.PacketPlayOutPlayerListHeaderFooter_HEADER.set(nmsPacket, toNMSComponent(packet.header, clientVersion));
nms.PacketPlayOutPlayerListHeaderFooter_FOOTER.set(nmsPacket, toNMSComponent(packet.footer, clientVersion));
@@ -226,31 +217,24 @@ public class BukkitPacketBuilder implements PacketBuilder {
@Override
public Object build(PacketPlayOutScoreboardDisplayObjective packet, ProtocolVersion clientVersion) throws Exception {
Object nmsPacket = nms.newPacketPlayOutScoreboardDisplayObjective.newInstance();
nms.PacketPlayOutScoreboardDisplayObjective_POSITION.set(nmsPacket, packet.slot);
nms.PacketPlayOutScoreboardDisplayObjective_OBJECTIVENAME.set(nmsPacket, packet.objectiveName);
return nmsPacket;
return nms.newPacketPlayOutScoreboardDisplayObjective.newInstance(packet.slot, newScoreboardObjective(packet.objectiveName));
}
@Override
public Object build(PacketPlayOutScoreboardObjective packet, ProtocolVersion clientVersion) throws Exception {
String displayName = packet.displayName;
if (clientVersion.getMinorVersion() < 13) {
displayName = cutTo(displayName, 32);
String displayName = clientVersion.getMinorVersion() < 13 ? cutTo(packet.displayName, 32) : packet.displayName;
if (nms.minorVersion >= 13) {
return nms.newPacketPlayOutScoreboardObjective.newInstance(nms.newScoreboardObjective.newInstance(null, packet.objectiveName, null,
toNMSComponent(IChatBaseComponent.optimizedComponent(displayName), clientVersion),
packet.renderType == null ? null : ((Object[])nms.EnumScoreboardHealthDisplay.getMethod("values").invoke(null))[packet.renderType.ordinal()]),
packet.method);
}
Object nmsPacket = nms.newPacketPlayOutScoreboardObjective.newInstance();
nms.PacketPlayOutScoreboardObjective_OBJECTIVENAME.set(nmsPacket, packet.objectiveName);
if (nms.minorVersion >= 13) {
nms.PacketPlayOutScoreboardObjective_DISPLAYNAME.set(nmsPacket, toNMSComponent(IChatBaseComponent.optimizedComponent(displayName), clientVersion));
} else {
nms.PacketPlayOutScoreboardObjective_DISPLAYNAME.set(nmsPacket, displayName);
}
nms.PacketPlayOutScoreboardObjective_DISPLAYNAME.set(nmsPacket, displayName);
if (nms.PacketPlayOutScoreboardObjective_RENDERTYPE != null && packet.renderType != null) {
if (nms.minorVersion >= 8) {
nms.PacketPlayOutScoreboardObjective_RENDERTYPE.set(nmsPacket, Enum.valueOf(nms.EnumScoreboardHealthDisplay, packet.renderType.toString()));
} else {
nms.PacketPlayOutScoreboardObjective_RENDERTYPE.set(nmsPacket, packet.renderType.ordinal());
}
nms.PacketPlayOutScoreboardObjective_RENDERTYPE.set(nmsPacket, Enum.valueOf(nms.EnumScoreboardHealthDisplay, packet.renderType.toString()));
}
nms.PacketPlayOutScoreboardObjective_METHOD.set(nmsPacket, packet.method);
return nmsPacket;
@@ -259,21 +243,17 @@ public class BukkitPacketBuilder implements PacketBuilder {
@Override
public Object build(PacketPlayOutScoreboardScore packet, ProtocolVersion clientVersion) throws Exception {
if (nms.minorVersion >= 13) {
return nms.newPacketPlayOutScoreboardScore_1_13.newInstance(Enum.valueOf(nms.EnumScoreboardAction, packet.action.toString()), packet.objectiveName, packet.player, packet.score);
return nms.newPacketPlayOutScoreboardScore_1_13.newInstance(((Object[])nms.EnumScoreboardAction.getMethod("values").invoke(null))[packet.action.ordinal()], packet.objectiveName, packet.player, packet.score);
}
if (packet.action == PacketPlayOutScoreboardScore.Action.REMOVE) {
return nms.newPacketPlayOutScoreboardScore_String.newInstance(packet.player);
}
Object nmsPacket = nms.newPacketPlayOutScoreboardScore0.newInstance();
nms.PacketPlayOutScoreboardScore_PLAYER.set(nmsPacket, packet.player);
nms.PacketPlayOutScoreboardScore_OBJECTIVENAME.set(nmsPacket, packet.objectiveName);
nms.PacketPlayOutScoreboardScore_SCORE.set(nmsPacket, packet.score);
Object score = nms.newScoreboardScore.newInstance(nms.newScoreboard.newInstance(), newScoreboardObjective(packet.objectiveName), packet.player);
nms.ScoreboardScore_setScore.invoke(score, packet.score);
if (nms.minorVersion >= 8) {
nms.PacketPlayOutScoreboardScore_ACTION.set(nmsPacket, Enum.valueOf(nms.EnumScoreboardAction, packet.action.toString()));
} else {
nms.PacketPlayOutScoreboardScore_ACTION.set(nmsPacket, packet.action.ordinal());
return nms.newPacketPlayOutScoreboardScore.newInstance(score);
}
return nmsPacket;
return nms.newPacketPlayOutScoreboardScore.newInstance(score, 0);
}
@Override
@@ -284,44 +264,52 @@ public class BukkitPacketBuilder implements PacketBuilder {
prefix = cutTo(prefix, 16);
suffix = cutTo(suffix, 16);
}
Object nmsPacket = nms.newPacketPlayOutScoreboardTeam.newInstance();
nms.PacketPlayOutScoreboardTeam_NAME.set(nmsPacket, packet.name);
Object team = nms.newScoreboardTeam.newInstance(nms.newScoreboard.newInstance(), packet.name);
((Collection<String>)nms.ScoreboardTeam_getPlayerNameSet.invoke(team)).addAll(packet.players);
if (nms.minorVersion >= 13) {
nms.PacketPlayOutScoreboardTeam_DISPLAYNAME.set(nmsPacket, toNMSComponent(IChatBaseComponent.optimizedComponent(packet.name), clientVersion));
if (prefix != null && prefix.length() > 0) nms.PacketPlayOutScoreboardTeam_PREFIX.set(nmsPacket, toNMSComponent(IChatBaseComponent.optimizedComponent(prefix), clientVersion));
if (suffix != null && suffix.length() > 0) nms.PacketPlayOutScoreboardTeam_SUFFIX.set(nmsPacket, toNMSComponent(IChatBaseComponent.optimizedComponent(suffix), clientVersion));
if (prefix != null && prefix.length() > 0) nms.ScoreboardTeam_setPrefix.invoke(team, toNMSComponent(IChatBaseComponent.optimizedComponent(prefix), clientVersion));
if (suffix != null && suffix.length() > 0) nms.ScoreboardTeam_setSuffix.invoke(team, toNMSComponent(IChatBaseComponent.optimizedComponent(suffix), clientVersion));
EnumChatFormat format = packet.color != null ? packet.color : EnumChatFormat.lastColorsOf(prefix);
nms.PacketPlayOutScoreboardTeam_CHATFORMAT.set(nmsPacket, Enum.valueOf(nms.EnumChatFormat, format.toString()));
nms.ScoreboardTeam_setColor.invoke(team, ((Object[])nms.EnumChatFormat.getMethod("values").invoke(null))[format.ordinal()]);
} else {
nms.PacketPlayOutScoreboardTeam_DISPLAYNAME.set(nmsPacket, packet.name);
nms.PacketPlayOutScoreboardTeam_PREFIX.set(nmsPacket, prefix);
nms.PacketPlayOutScoreboardTeam_SUFFIX.set(nmsPacket, suffix);
if (prefix != null) nms.ScoreboardTeam_setPrefix.invoke(team, prefix);
if (suffix != null) nms.ScoreboardTeam_setSuffix.invoke(team, suffix);
}
if (nms.PacketPlayOutScoreboardTeam_VISIBILITY != null) nms.PacketPlayOutScoreboardTeam_VISIBILITY.set(nmsPacket, packet.nametagVisibility);
if (nms.PacketPlayOutScoreboardTeam_COLLISION != null) nms.PacketPlayOutScoreboardTeam_COLLISION.set(nmsPacket, packet.collisionRule);
nms.PacketPlayOutScoreboardTeam_PLAYERS.set(nmsPacket, packet.players);
nms.PacketPlayOutScoreboardTeam_ACTION.set(nmsPacket, packet.method);
nms.PacketPlayOutScoreboardTeam_SIGNATURE.set(nmsPacket, packet.options);
return nmsPacket;
if (nms.EnumNameTagVisibility != null && packet.nametagVisibility != null) nms.ScoreboardTeam_setNameTagVisibility.invoke(team, packet.nametagVisibility.equals("always") ? ((Object[])nms.EnumNameTagVisibility.getMethod("values").invoke(null))[0] : ((Object[])nms.EnumNameTagVisibility.getMethod("values").invoke(null))[1]);
if (nms.EnumTeamPush != null && packet.collisionRule != null) nms.ScoreboardTeam_setCollisionRule.invoke(team, packet.collisionRule.equals("always") ? ((Object[])nms.EnumTeamPush.getMethod("values").invoke(null))[0] : ((Object[])nms.EnumTeamPush.getMethod("values").invoke(null))[1]);
if (nms.minorVersion >= 17) {
switch (packet.method) {
case 0:
return nms.PacketPlayOutScoreboardTeam_ofBoolean.invoke(null, team, true);
case 1:
return nms.PacketPlayOutScoreboardTeam_of.invoke(null, team);
case 2:
return nms.PacketPlayOutScoreboardTeam_ofBoolean.invoke(null, team, false);
case 3:
return nms.PacketPlayOutScoreboardTeam_ofString.invoke(null, team, packet.players.toArray(new String[0])[0], ((Object[])nms.PacketPlayOutScoreboardTeam_a.getMethod("values").invoke(null))[0]);
case 4:
return nms.PacketPlayOutScoreboardTeam_ofString.invoke(null, team, packet.players.toArray(new String[0])[0], ((Object[])nms.PacketPlayOutScoreboardTeam_a.getMethod("values").invoke(null))[1]);
default:
throw new IllegalArgumentException("Invalid action: " + packet.method);
}
}
return nms.newPacketPlayOutScoreboardTeam.newInstance(team, packet.method);
}
@Override
public Object build(PacketPlayOutTitle packet, ProtocolVersion clientVersion) throws Exception {
if (nms.minorVersion < 8) return null;
return nms.newPacketPlayOutTitle.newInstance(Enum.valueOf(nms.EnumTitleAction, packet.action.toString()),
packet.text == null ? null : toNMSComponent(IChatBaseComponent.optimizedComponent(packet.text), clientVersion), packet.fadeIn, packet.stay, packet.fadeOut);
}
/**
* Builds entity destroy packet with given parameter
* @param ids - entity ids to destroy
* @param id - entity id to destroy
* @return destroy packet
* @throws Exception - if reflection fails
*/
public Object buildEntityDestroyPacket(int... ids) throws Exception {
return nms.newPacketPlayOutEntityDestroy.newInstance(ids);
public Object buildEntityDestroyPacket(int id) throws Exception {
if (nms.minorVersion >= 17) {
return nms.newPacketPlayOutEntityDestroy.newInstance(id);
}
return nms.newPacketPlayOutEntityDestroy.newInstance(new int[] {id});
}
/**
* Builds entity metadata packet with given parameters
* @param entityId - entity id
@@ -332,7 +320,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
public Object buildEntityMetadataPacket(int entityId, DataWatcher dataWatcher) throws Exception {
return nms.newPacketPlayOutEntityMetadata.newInstance(entityId, dataWatcher.toNMS(), true);
}
/**
* Builds entity spawn packet with given parameters
* @param entityId - entity id
@@ -344,7 +332,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
* @throws Exception - if reflection fails
*/
public Object buildEntitySpawnPacket(int entityId, UUID uuid, EntityType entityType, Location loc, DataWatcher dataWatcher) throws Exception {
Object nmsPacket = nms.newPacketPlayOutSpawnEntityLiving.newInstance();
Object nmsPacket = nms.newPacketPlayOutSpawnEntityLiving.newInstance(nms.getHandle.invoke(Bukkit.getOnlinePlayers().iterator().next()));
nms.PacketPlayOutSpawnEntityLiving_ENTITYID.set(nmsPacket, entityId);
nms.PacketPlayOutSpawnEntityLiving_ENTITYTYPE.set(nmsPacket, entityIds.get(entityType));
nms.PacketPlayOutSpawnEntityLiving_YAW.set(nmsPacket, (byte)(loc.getYaw() * 256.0f / 360.0f));
@@ -364,7 +352,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
}
return nmsPacket;
}
/**
* Builds entity teleport packet with given parameters
* @param entityId - entity id
@@ -373,7 +361,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
* @throws Exception - if reflection fails
*/
public Object buildEntityTeleportPacket(int entityId, Location location) throws Exception {
Object nmsPacket = nms.newPacketPlayOutEntityTeleport.newInstance();
Object nmsPacket = nms.newPacketPlayOutEntityTeleport.newInstance(nms.getHandle.invoke(Bukkit.getOnlinePlayers().iterator().next()));
nms.PacketPlayOutEntityTeleport_ENTITYID.set(nmsPacket, entityId);
if (nms.minorVersion >= 9) {
nms.PacketPlayOutEntityTeleport_X.set(nmsPacket, location.getX());
@@ -395,12 +383,12 @@ public class BukkitPacketBuilder implements PacketBuilder {
EnumPlayerInfoAction action = EnumPlayerInfoAction.valueOf(nms.PacketPlayOutPlayerInfo_ACTION.get(nmsPacket).toString());
List<PlayerInfoData> listData = new ArrayList<PlayerInfoData>();
for (Object nmsData : (List<?>) nms.PacketPlayOutPlayerInfo_PLAYERS.get(nmsPacket)) {
Object nmsGamemode = nms.PlayerInfoData_GAMEMODE.get(nmsData);
EnumGamemode gamemode = nmsGamemode == null ? null : EnumGamemode.valueOf(nmsGamemode.toString());
Object profile = nms.PlayerInfoData_PROFILE.get(nmsData);
Object nmsComponent = nms.PlayerInfoData_LISTNAME.get(nmsData);
IChatBaseComponent listName = fromNMSComponent(nmsComponent);
listData.add(new PlayerInfoData((String) nms.GameProfile_NAME.get(profile), (UUID) nms.GameProfile_ID.get(profile), nms.GameProfile_PROPERTIES.get(profile), nms.PlayerInfoData_PING.getInt(nmsData), gamemode, listName));
Object nmsGamemode = nms.PlayerInfoData_getGamemode.invoke(nmsData);
EnumGamemode gamemode = (nmsGamemode == null) ? null : EnumGamemode.valueOf(nmsGamemode.toString());
GameProfile profile = (GameProfile) nms.PlayerInfoData_getProfile.invoke(nmsData);
Object nmsComponent = nms.PlayerInfoData_getDisplayName.invoke(nmsData);
IChatBaseComponent listName = nmsComponent == null ? null : fromNMSComponent(nmsComponent);
listData.add(new PlayerInfoData(profile.getName(), profile.getId(), profile.getProperties(), (int)nms.PlayerInfoData_getLatency.invoke(nmsData), gamemode, listName));
}
return new PacketPlayOutPlayerInfo(action, listData);
}
@@ -420,11 +408,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
if (nms.PacketPlayOutScoreboardObjective_RENDERTYPE != null) {
Object nmsRender = nms.PacketPlayOutScoreboardObjective_RENDERTYPE.get(nmsPacket);
if (nmsRender != null) {
if (nms.minorVersion >= 8) {
renderType = EnumScoreboardHealthDisplay.valueOf(nmsRender.toString());
} else {
renderType = EnumScoreboardHealthDisplay.values()[(int)nmsRender];
}
renderType = EnumScoreboardHealthDisplay.valueOf(nmsRender.toString());
}
}
int method = nms.PacketPlayOutScoreboardObjective_METHOD.getInt(nmsPacket);
@@ -438,7 +422,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
(String) nms.PacketPlayOutScoreboardDisplayObjective_OBJECTIVENAME.get(nmsPacket)
);
}
/**
* A method yoinked from minecraft code used to convert double to int
* @param paramDouble double value
@@ -448,7 +432,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
int i = (int)paramDouble;
return paramDouble < i ? i - 1 : i;
}
/**
* Converts json string into a component
* @param json json as string
@@ -459,7 +443,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
if (json == null) return null;
return nms.ChatSerializer_DESERIALIZE.invoke(null, json);
}
/**
* Converts minecraft IChatBaseComponent into TAB's component class. Currently does not support hover event.
* @param component - component to convert
@@ -472,7 +456,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
TAB.getInstance().getCPUManager().addMethodTime("fromNMSComponent", System.nanoTime()-time);
return obj;
}
//separate method to prevent extras counting cpu again due to recursion and finally showing higher usage than real
@SuppressWarnings("rawtypes")
public IChatBaseComponent fromNMSComponent0(Object component) throws Exception {
@@ -504,7 +488,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
if (clickEvent != null) {
chat.onClick(ClickAction.valueOf(nms.ChatClickable_action.get(clickEvent).toString().toUpperCase()), (String) nms.ChatClickable_value.get(clickEvent));
}
/* Object hoverEvent = nms.ChatModifier_hoverEvent.get(modifier);
/* Object hoverEvent = nms.ChatModifier_hoverEvent.get(modifier);
if (hoverEvent != null) {
chat.onHover(HoverAction.fromString(nms.ChatHoverable_action.get(hoverEvent).toString()), fromNMSComponent(nms.ChatHoverable_value.get(hoverEvent)));
}*/
@@ -514,7 +498,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
}
return chat;
}
/**
* Converts TAB's IChatBaseComponent into minecraft's component. Currently does not support hover event.
* @param component - component to convert
@@ -528,7 +512,7 @@ public class BukkitPacketBuilder implements PacketBuilder {
TAB.getInstance().getCPUManager().addMethodTime("toNMSComponent", System.nanoTime()-time);
return obj;
}
//separate method to prevent extras counting cpu again due to recursion and finally showing higher usage than real
private Object toNMSComponent0(IChatBaseComponent component, ProtocolVersion clientVersion) throws Exception {
if (component == null) return null;
@@ -544,16 +528,16 @@ public class BukkitPacketBuilder implements PacketBuilder {
}
}
modifier = nms.newChatModifier.newInstance(
color,
component.isBold() ? true : null,
component.isItalic() ? true : null,
component.isUnderlined() ? true : null,
component.isStrikethrough() ? true : null,
component.isObfuscated() ? true : null,
component.getClickAction() == null ? null : nms.newChatClickable.newInstance(nms.EnumClickAction_a.invoke(null, component.getClickAction().toString().toLowerCase()), component.getClickValue().toString()),
null, //component.getHoverAction() == null ? null : nms.newChatHoverable.newInstance(nms.EnumHoverAction_a.invoke(null, component.getHoverAction().toString().toLowerCase()), stringToComponent(component.getHoverValue().toString())),
null, null
);
color,
component.getBold(),
component.getItalic(),
component.getUnderlined(),
component.getStrikethrough(),
component.getObfuscated(),
component.getClickAction() == null ? null : nms.newChatClickable.newInstance(nms.EnumClickAction_a.invoke(null, component.getClickAction().toString().toLowerCase()), component.getClickValue().toString()),
null, //component.getHoverAction() == null ? null : nms.newChatHoverable.newInstance(nms.EnumHoverAction_a.invoke(null, component.getHoverAction().toString().toLowerCase()), stringToComponent(component.getHoverValue().toString())),
null, null
);
} else {
modifier = nms.newChatModifier.newInstance();
if (component.getClickAction() != null){
@@ -575,4 +559,11 @@ public class BukkitPacketBuilder implements PacketBuilder {
}
return chat;
}
private Object newScoreboardObjective(String objectiveName) throws Exception {
if (nms.minorVersion >= 13) {
return nms.newScoreboardObjective.newInstance(null, objectiveName, null, stringToComponent("{\"text\":\"\"}"), null);
}
return nms.newScoreboardObjective.newInstance(null, objectiveName, nms.getFields(nms.IScoreboardCriteria, nms.IScoreboardCriteria).get(0).get(null));
}
}
@@ -64,24 +64,25 @@ public class BukkitPipelineInjector extends PipelineInjector {
@SuppressWarnings("unchecked")
private void modifyPlayers(Object packetPlayOutScoreboardTeam) throws Exception {
long time = System.nanoTime();
if (nms.PacketPlayOutScoreboardTeam_SIGNATURE.getInt(packetPlayOutScoreboardTeam) != 69) {
Collection<String> players = (Collection<String>) nms.PacketPlayOutScoreboardTeam_PLAYERS.get(packetPlayOutScoreboardTeam);
//creating a new list to prevent NoSuchFieldException in minecraft packet encoder when a player is removed
Collection<String> newList = new ArrayList<String>();
for (String entry : players) {
TabPlayer p = tab.getPlayer(entry);
if (p == null) {
newList.add(entry);
continue;
}
if (tab.getFeatureManager().getNameTagFeature().isDisabledWorld(p.getWorldName()) || p.hasTeamHandlingPaused()) {
newList.add(entry);
} else {
logTeamOverride((String) nms.PacketPlayOutScoreboardTeam_NAME.get(packetPlayOutScoreboardTeam), entry);
}
Collection<String> players = (Collection<String>) nms.PacketPlayOutScoreboardTeam_PLAYERS.get(packetPlayOutScoreboardTeam);
String teamName = (String) nms.PacketPlayOutScoreboardTeam_NAME.get(packetPlayOutScoreboardTeam);
if (players == null) return;
//creating a new list to prevent NoSuchFieldException in minecraft packet encoder when a player is removed
Collection<String> newList = new ArrayList<String>();
for (String entry : players) {
TabPlayer p = tab.getPlayer(entry);
if (p == null) {
newList.add(entry);
continue;
}
if (!tab.getFeatureManager().getNameTagFeature().isDisabledWorld(p.getWorldName()) && !p.hasTeamHandlingPaused() &&
!p.getTeamName().equals(teamName)) {
logTeamOverride(teamName, entry);
} else {
newList.add(entry);
}
nms.PacketPlayOutScoreboardTeam_PLAYERS.set(packetPlayOutScoreboardTeam, newList);
}
nms.PacketPlayOutScoreboardTeam_PLAYERS.set(packetPlayOutScoreboardTeam, newList);
tab.getCPUManager().addTime(TabFeature.NAMETAGS, UsageType.ANTI_OVERRIDE, System.nanoTime()-time);
}
@@ -260,6 +260,7 @@ public class BukkitPlaceholderRegistry implements PlaceholderRegistry {
if (Bukkit.getPluginManager().isPluginEnabled("Essentials")) {
placeholders.add(new PlayerPlaceholder("%essentialsnick%", 1000) {
public String get(TabPlayer p) {
if (getNickname == null) return "<Internal plugin error>";
String name = null;
try {
name = (String) getNickname.invoke(getUser.invoke(Bukkit.getPluginManager().getPlugin("Essentials"), p.getPlayer()));
@@ -1,9 +1,18 @@
package me.neznamy.tab.platforms.bukkit;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import com.viaversion.viaversion.api.Via;
import org.bukkit.Bukkit;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarFlag;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider;
@@ -15,6 +24,8 @@ import me.neznamy.tab.platforms.bukkit.nms.NMSStorage;
import me.neznamy.tab.shared.ITabPlayer;
import me.neznamy.tab.shared.ProtocolVersion;
import me.neznamy.tab.shared.TAB;
import me.neznamy.tab.shared.packets.PacketPlayOutBoss;
import me.neznamy.tab.shared.rgb.RGBUtils;
/**
* TabPlayer for Bukkit
@@ -29,6 +40,9 @@ public class BukkitTabPlayer extends ITabPlayer {
//nms player connection
private Object playerConnection;
//player's visible boss bars
private Map<UUID, BossBar> bossbars = new HashMap<UUID, BossBar>();
/**
* Constructs new instance with given parameter
@@ -96,7 +110,7 @@ public class BukkitTabPlayer extends ITabPlayer {
TAB.getInstance().debug("ViaVersion returned protocol version " + version + " for " + getName());
return version;
} catch (Throwable e) {
return TAB.getInstance().getErrorManager().printError(ProtocolVersion.SERVER_VERSION.getNetworkId(), "Failed to get protocol version of " + getName() + " using ViaVersion", e);
return TAB.getInstance().getErrorManager().printError(ProtocolVersion.SERVER_VERSION.getNetworkId(), "Failed to get protocol version of " + getName() + " using ViaVersion v" + Bukkit.getPluginManager().getPlugin("ViaVersion").getDescription().getVersion() + ". Is it the latest version?", e);
}
}
@@ -129,11 +143,71 @@ public class BukkitTabPlayer extends ITabPlayer {
}
return;
}
if (nmsPacket instanceof PacketPlayOutBoss) {
handle((PacketPlayOutBoss) nmsPacket);
return;
}
NMSStorage.getInstance().sendPacket.invoke(playerConnection, nmsPacket);
} catch (Throwable e) {
TAB.getInstance().getErrorManager().printError("An error occurred when sending " + nmsPacket.getClass().getSimpleName(), e);
}
}
private void handle(PacketPlayOutBoss packet) {
Set<BarFlag> flags = new HashSet<BarFlag>();
BossBar bar;
switch (packet.operation) {
case ADD:
if (packet.createWorldFog) flags.add(BarFlag.CREATE_FOG);
if (packet.darkenScreen) flags.add(BarFlag.DARKEN_SKY);
if (packet.playMusic) flags.add(BarFlag.PLAY_BOSS_MUSIC);
bar = Bukkit.createBossBar(RGBUtils.getInstance().convertToBukkitFormat(packet.name, getVersion().getMinorVersion() >= 16 && NMSStorage.getInstance().minorVersion >= 16),
BarColor.valueOf(packet.color.name()),
BarStyle.valueOf(packet.overlay.name().replace("PROGRESS", "SOLID").replace("NOTCHED", "SEGMENTED")),
flags.toArray(new BarFlag[0]));
bossbars.put(packet.id, bar);
bar.addPlayer(player);
break;
case REMOVE:
bossbars.get(packet.id).removePlayer(player);
bossbars.remove(packet.id);
break;
case UPDATE_PCT:
bossbars.get(packet.id).setProgress(packet.pct);
break;
case UPDATE_NAME:
bossbars.get(packet.id).setTitle(RGBUtils.getInstance().convertToBukkitFormat(packet.name, getVersion().getMinorVersion() >= 16 && NMSStorage.getInstance().minorVersion >= 16));
break;
case UPDATE_STYLE:
bar = bossbars.get(packet.id);
//yet another platform with yet another buggy bossbar API, how lovely it is regressing back to APIs instead of internals
bar.removePlayer(player);
bar.setColor(BarColor.valueOf(packet.color.name()));
bar.setStyle(BarStyle.valueOf(packet.overlay.name().replace("PROGRESS", "SOLID").replace("NOTCHED", "SEGMENTED")));
bar.addPlayer(player);
break;
case UPDATE_PROPERTIES:
bar = bossbars.get(packet.id);
processFlag(bar, packet.createWorldFog, BarFlag.CREATE_FOG);
processFlag(bar, packet.darkenScreen, BarFlag.DARKEN_SKY);
processFlag(bar, packet.playMusic, BarFlag.PLAY_BOSS_MUSIC);
break;
default:
break;
}
}
private void processFlag(BossBar bar, boolean targetValue, BarFlag flag) {
if (targetValue) {
if (!bar.hasFlag(flag)) {
bar.addFlag(flag);
}
} else {
if (bar.hasFlag(flag)) {
bar.removeFlag(flag);
}
}
}
@Override
public boolean hasInvisibilityPotion() {
@@ -73,7 +73,7 @@ public class Main extends JavaPlugin {
"v1_5_R1", "v1_5_R2", "v1_5_R3", "v1_6_R1", "v1_6_R2", "v1_6_R3",
"v1_7_R1", "v1_7_R2", "v1_7_R3", "v1_7_R4", "v1_8_R1", "v1_8_R2", "v1_8_R3",
"v1_9_R1", "v1_9_R2", "v1_10_R1", "v1_11_R1", "v1_12_R1", "v1_13_R1", "v1_13_R2",
"v1_14_R1", "v1_15_R1", "v1_16_R1", "v1_16_R2", "v1_16_R3");
"v1_14_R1", "v1_15_R1", "v1_16_R1", "v1_16_R2", "v1_16_R3", "v1_17_R1");
String serverPackage = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
try {
NMSStorage.setInstance(new NMSStorage());
@@ -46,8 +46,8 @@ public class ExpansionDownloader {
@Override
public void run() {
try {
//initial delay to give PlaceholderAPI time to load
Thread.sleep(5000);
//initial delay to give PlaceholderAPI & plugins with expansions time to load
Thread.sleep(10000);
TAB.getInstance().debug("Used expansions: " + expansions.toString());
TAB.getInstance().debug("Registered expansions in PlaceholderAPI: " + PlaceholderAPI.getRegisteredIdentifiers());
expansions.removeAll(PlaceholderAPI.getRegisteredIdentifiers());
@@ -45,7 +45,10 @@ public class PetFix implements RawPacketListener, QuitEventListener {
* @return position of pet owner field based on server version
*/
private int getPetOwnerPosition() {
if (nms.minorVersion >= 15) {
if (nms.minorVersion >= 17) {
//1.17.x
return 18;
} else if (nms.minorVersion >= 15) {
//1.15.x, 1.16.x
return 17;
} else if (nms.minorVersion >= 14) {
@@ -74,7 +74,13 @@ public class PacketListener implements RawPacketListener {
onEntitySpawn(receiver, nms.PacketPlayOutNamedEntitySpawn_ENTITYID.getInt(packet));
}
if (nms.PacketPlayOutEntityDestroy.isInstance(packet)) {
onEntityDestroy(receiver, (int[]) nms.PacketPlayOutEntityDestroy_ENTITIES.get(packet));
if (nms.minorVersion >= 17) {
onEntityDestroy(receiver, nms.PacketPlayOutEntityDestroy_ENTITIES.getInt(packet));
} else {
for (int entity : (int[]) nms.PacketPlayOutEntityDestroy_ENTITIES.get(packet)) {
onEntityDestroy(receiver, entity);
}
}
}
}
@@ -107,12 +113,10 @@ public class PacketListener implements RawPacketListener {
}
}
public void onEntityDestroy(TabPlayer receiver, int[] entities) {
for (int id : entities) {
TabPlayer despawnedPlayer = nameTagX.entityIdMap.get(id);
if (despawnedPlayer != null && despawnedPlayer.isLoaded())
tab.getCPUManager().runMeasuredTask("processing EntityDestroy", getFeatureType(), UsageType.PACKET_ENTITY_DESTROY, () -> despawnedPlayer.getArmorStandManager().destroy(receiver));
}
public void onEntityDestroy(TabPlayer receiver, int entity) {
TabPlayer despawnedPlayer = nameTagX.entityIdMap.get(entity);
if (despawnedPlayer != null && despawnedPlayer.isLoaded())
tab.getCPUManager().runMeasuredTask("processing EntityDestroy", getFeatureType(), UsageType.PACKET_ENTITY_DESTROY, () -> despawnedPlayer.getArmorStandManager().destroy(receiver));
}
@Override
@@ -1,13 +1,13 @@
package me.neznamy.tab.platforms.bukkit.nms;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
@@ -21,19 +21,22 @@ public class NMSStorage {
//instance of this class
private static NMSStorage instance;
//field mapping changes in thermos
private Map<String, String> thermosFieldMappings = new HashMap<String, String>();
//data watcher registry
public DataWatcherRegistry dataWatcherRegistry;
//server package, such as "v1_16_R3"
private String serverPackage;
//server minor version such as "16"
public int minorVersion;
public Class<?> Entity;
public Class<?> EntityLiving;
private Class<?> Packet;
private Class<?> PlayerConnection;
private Class<?> NetworkManager;
public Class<?> EntityPlayer;
public Field PING;
public Field PLAYER_CONNECTION;
public Field NETWORK_MANAGER;
@@ -44,16 +47,16 @@ public class NMSStorage {
//chat
public Class<Enum> EnumChatFormat;
public Class<?> IChatBaseComponent;
public Class<?> ChatBaseComponent;
public Class<?> ChatSerializer;
public Class<?> EnumClickAction;
public Class<?> EnumHoverAction;
public Class<?> ChatModifier;
private Class<?> IChatBaseComponent;
private Class<?> ChatBaseComponent;
private Class<?> ChatSerializer;
private Class<?> EnumClickAction;
private Class<?> EnumHoverAction;
private Class<?> ChatModifier;
public Class<?> ChatComponentText;
public Class<?> ChatClickable;
public Class<?> ChatHoverable;
public Class<?> ChatHexColor;
private Class<?> ChatClickable;
private Class<?> ChatHoverable;
private Class<?> ChatHexColor;
public Constructor<?> newChatComponentText;
public Constructor<?> newChatClickable;
public Constructor<?> newChatHoverable;
@@ -82,29 +85,10 @@ public class NMSStorage {
public Method ChatHexColor_ofString;
public Method ChatComponentText_addSibling;
//PacketPlayOutBoss
public Class<?> PacketPlayOutBoss;
public Class<Enum> BarColor;
public Class<Enum> BarStyle;
public Class<Enum> PacketPlayOutBoss_Action;
public Constructor<?> newPacketPlayOutBoss;
public Field PacketPlayOutBoss_UUID;
public Field PacketPlayOutBoss_ACTION;
public Field PacketPlayOutBoss_NAME;
public Field PacketPlayOutBoss_PROGRESS;
public Field PacketPlayOutBoss_COLOR;
public Field PacketPlayOutBoss_STYLE;
public Field PacketPlayOutBoss_DARKEN_SKY;
public Field PacketPlayOutBoss_PLAY_MUSIC;
public Field PacketPlayOutBoss_CREATE_FOG;
//PacketPlayOutChat
public Class<?> PacketPlayOutChat;
private Class<?> PacketPlayOutChat;
public Class<Enum> ChatMessageType;
public Constructor<?> newPacketPlayOutChat;
public Field PacketPlayOutChat_MESSAGE;
public Field PacketPlayOutChat_POSITION;
public Field PacketPlayOutChat_SENDER;
//PacketPlayOutPlayerListHeaderFooter
public Class<?> PacketPlayOutPlayerListHeaderFooter;
@@ -120,78 +104,76 @@ public class NMSStorage {
//PacketPlayOutScoreboardObjective
public Class<?> PacketPlayOutScoreboardObjective;
public Class<?> IScoreboardCriteria;
private Class<?> ScoreboardObjective;
public Class<Enum> EnumScoreboardHealthDisplay;
public Constructor<?> newPacketPlayOutScoreboardObjective;
public Constructor<?> newScoreboardObjective;
public Field PacketPlayOutScoreboardObjective_OBJECTIVENAME;
public Field PacketPlayOutScoreboardObjective_DISPLAYNAME;
public Field PacketPlayOutScoreboardObjective_RENDERTYPE;
public Field PacketPlayOutScoreboardObjective_METHOD;
//PacketPlayOutScoreboardScore
public Class<?> PacketPlayOutScoreboardScore;
private Class<?> PacketPlayOutScoreboardScore;
private Class<?> ScoreboardScore;
public Class<Enum> EnumScoreboardAction;
public Constructor<?> newPacketPlayOutScoreboardScore0;
public Constructor<?> newPacketPlayOutScoreboardScore;
public Constructor<?> newPacketPlayOutScoreboardScore_String;
public Constructor<?> newPacketPlayOutScoreboardScore_1_13;
public Field PacketPlayOutScoreboardScore_PLAYER;
public Field PacketPlayOutScoreboardScore_OBJECTIVENAME;
public Field PacketPlayOutScoreboardScore_SCORE;
public Field PacketPlayOutScoreboardScore_ACTION;
public Constructor<?> newScoreboardScore;
public Method ScoreboardScore_setScore;
//PacketPlayOutScoreboardTeam
public Class<?> PacketPlayOutScoreboardTeam;
public Class<?> EnumNameTagVisibility;
public Class<?> EnumTeamPush;
public Constructor<?> newPacketPlayOutScoreboardTeam;
public Field PacketPlayOutScoreboardTeam_NAME;
public Field PacketPlayOutScoreboardTeam_DISPLAYNAME;
public Field PacketPlayOutScoreboardTeam_PREFIX;
public Field PacketPlayOutScoreboardTeam_SUFFIX;
public Field PacketPlayOutScoreboardTeam_VISIBILITY; //1.8+
public Field PacketPlayOutScoreboardTeam_CHATFORMAT; //1.13+
public Field PacketPlayOutScoreboardTeam_COLLISION; //1.9+
public Field PacketPlayOutScoreboardTeam_PLAYERS;
public Field PacketPlayOutScoreboardTeam_ACTION;
public Field PacketPlayOutScoreboardTeam_SIGNATURE;
private Class<?> Scoreboard;
private Class<?> ScoreboardTeam;
public Constructor<?> newScoreboard;
public Constructor<?> newScoreboardTeam;
public Method ScoreboardTeam_setPrefix;
public Method ScoreboardTeam_setSuffix;
public Method ScoreboardTeam_setNameTagVisibility;
public Method ScoreboardTeam_setCollisionRule;
public Method ScoreboardTeam_setColor;
public Method ScoreboardTeam_getPlayerNameSet;
//1.17
public Class<?> PacketPlayOutScoreboardTeam_a;
public Method PacketPlayOutScoreboardTeam_of;
public Method PacketPlayOutScoreboardTeam_ofBoolean;
public Method PacketPlayOutScoreboardTeam_ofString;
//PacketPlayOutPlayerInfo
public Class<?> PacketPlayOutPlayerInfo;
public Class<Enum> EnumGamemode;
public Class<Enum> EnumPlayerInfoAction;
public Class<?> PlayerInfoData;
private Class<?> PlayerInfoData;
public Constructor<?> newPacketPlayOutPlayerInfo;
public Constructor<?> newPlayerInfoData;
public Class<?> GameProfile;
public Constructor<?> newGameProfile;
public Field GameProfile_ID;
public Field GameProfile_NAME;
public Field GameProfile_PROPERTIES;
public Class<?> PropertyMap;
public Method PropertyMap_putAll;
public Field PacketPlayOutPlayerInfo_ACTION;
public Field PacketPlayOutPlayerInfo_PLAYERS;
public Field PlayerInfoData_PING;
public Field PlayerInfoData_GAMEMODE;
public Field PlayerInfoData_PROFILE;
public Field PlayerInfoData_LISTNAME;
//PacketPlayOutTitle
public Class<?> PacketPlayOutTitle;
public Constructor<?> newPacketPlayOutTitle;
public Class<Enum> EnumTitleAction;
public Method PlayerInfoData_getProfile;
public Method PlayerInfoData_getLatency;
public Method PlayerInfoData_getGamemode;
public Method PlayerInfoData_getDisplayName;
public Class<?> PacketPlayOutEntityDestroy;
public Constructor<?> newPacketPlayOutEntityDestroy;
public Field PacketPlayOutEntityDestroy_ENTITIES;
public Class<?> PacketPlayInUseEntity;
private Class<?> EnumEntityUseAction;
public Field PacketPlayInUseEntity_ENTITY;
public Field PacketPlayInUseEntity_ACTION;
public Class<?> PacketPlayOutNamedEntitySpawn;
public Field PacketPlayOutNamedEntitySpawn_ENTITYID;
public Class<?> PacketPlayOutEntity;
public Class<?> PacketPlayOutEntityLook;
public Field PacketPlayOutEntity_ENTITYID;
@@ -222,21 +204,21 @@ public class NMSStorage {
public Field PacketPlayOutSpawnEntityLiving_DATAWATCHER;
//DataWatcher
public Class<?> DataWatcher;
private Class<?> DataWatcher;
public Constructor<?> newDataWatcher;
public Method DataWatcher_REGISTER;
public Class<?> DataWatcherItem;
public Constructor<?> newDataWatcherItem;
private Class<?> DataWatcherItem;
public Field DataWatcherItem_TYPE;
public Field DataWatcherItem_VALUE;
public Class<?> DataWatcherObject;
private Class<?> DataWatcherObject;
public Constructor<?> newDataWatcherObject;
public Field DataWatcherObject_SLOT;
public Field DataWatcherObject_SERIALIZER;
public Class<?> DataWatcherRegistry;
private Class<?> DataWatcherRegistry;
private Class<?> DataWatcherSerializer;
/**
* Creates new instance, initializes required NMS classes and fields
@@ -245,14 +227,13 @@ public class NMSStorage {
public NMSStorage() throws Exception {
serverPackage = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
minorVersion = Integer.parseInt(serverPackage.split("_")[1]);
loadThermosMappings();
initializeClasses();
initializeConstructors();
initializeFields();
initializeMethods();
dataWatcherRegistry = new DataWatcherRegistry(this, DataWatcherRegistry);
}
/**
* Sets new instance
* @param instance - new instance
@@ -260,7 +241,7 @@ public class NMSStorage {
public static void setInstance(NMSStorage instance) {
NMSStorage.instance = instance;
}
/**
* Returns instance
* @return instance
@@ -269,74 +250,77 @@ public class NMSStorage {
return instance;
}
/**
* Puts thermos mapping changes into map
*/
private void loadThermosMappings() {
thermosFieldMappings.put("ping", "field_71138_i");
thermosFieldMappings.put("playerConnection", "field_71135_a");
thermosFieldMappings.put("networkManager", "field_147371_a");
}
/**
* Initializes required NMS classes
* @throws Exception - if something fails
*/
public void initializeClasses() throws Exception {
DataWatcher = getNMSClass("DataWatcher");
DataWatcherItem = getNMSClass("DataWatcher$Item", "DataWatcher$WatchableObject", "WatchableObject");
EnumChatFormat = (Class<Enum>) getNMSClass("EnumChatFormat");
PacketPlayInUseEntity = getNMSClass("PacketPlayInUseEntity", "Packet7UseEntity");
PacketPlayOutChat = getNMSClass("PacketPlayOutChat", "Packet3Chat");
PacketPlayOutEntity = getNMSClass("PacketPlayOutEntity", "Packet30Entity");
PacketPlayOutEntityDestroy = getNMSClass("PacketPlayOutEntityDestroy", "Packet29DestroyEntity");
PacketPlayOutEntityLook = getNMSClass("PacketPlayOutEntity$PacketPlayOutEntityLook", "PacketPlayOutEntityLook", "Packet32EntityLook");
PacketPlayOutEntityMetadata = getNMSClass("PacketPlayOutEntityMetadata", "Packet40EntityMetadata");
PacketPlayOutEntityTeleport = getNMSClass("PacketPlayOutEntityTeleport", "Packet34EntityTeleport");
PacketPlayOutNamedEntitySpawn = getNMSClass("PacketPlayOutNamedEntitySpawn", "Packet20NamedEntitySpawn");
PacketPlayOutScoreboardDisplayObjective = getNMSClass("PacketPlayOutScoreboardDisplayObjective", "Packet208SetScoreboardDisplayObjective");
PacketPlayOutScoreboardObjective = getNMSClass("PacketPlayOutScoreboardObjective", "Packet206SetScoreboardObjective");
PacketPlayOutScoreboardScore = getNMSClass("PacketPlayOutScoreboardScore", "Packet207SetScoreboardScore");
PacketPlayOutScoreboardTeam = getNMSClass("PacketPlayOutScoreboardTeam", "Packet209SetScoreboardTeam");
PacketPlayOutSpawnEntityLiving = getNMSClass("PacketPlayOutSpawnEntityLiving", "Packet24MobSpawn");
private void initializeClasses() throws Exception {
DataWatcher = getNMSClass("net.minecraft.network.syncher.DataWatcher", "DataWatcher");
DataWatcherItem = getNMSClass("net.minecraft.network.syncher.DataWatcher$Item", "DataWatcher$Item", "DataWatcher$WatchableObject", "WatchableObject");
EntityPlayer = getNMSClass("net.minecraft.server.level.EntityPlayer", "EntityPlayer");
EnumChatFormat = (Class<Enum>) getNMSClass("net.minecraft.EnumChatFormat", "EnumChatFormat");
Entity = getNMSClass("net.minecraft.world.entity.Entity", "Entity");
EntityLiving = getNMSClass("net.minecraft.world.entity.EntityLiving", "EntityLiving");
Packet = getNMSClass("net.minecraft.network.protocol.Packet", "Packet");
PacketPlayInUseEntity = getNMSClass("net.minecraft.network.protocol.game.PacketPlayInUseEntity", "PacketPlayInUseEntity", "Packet7UseEntity");
PacketPlayOutChat = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutChat", "PacketPlayOutChat", "Packet3Chat");
PacketPlayOutEntity = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutEntity", "PacketPlayOutEntity", "Packet30Entity");
PacketPlayOutEntityDestroy = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutEntityDestroy", "PacketPlayOutEntityDestroy", "Packet29DestroyEntity");
PacketPlayOutEntityLook = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutEntity$PacketPlayOutEntityLook", "PacketPlayOutEntity$PacketPlayOutEntityLook", "PacketPlayOutEntityLook", "Packet32EntityLook");
PacketPlayOutEntityMetadata = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata", "PacketPlayOutEntityMetadata", "Packet40EntityMetadata");
PacketPlayOutEntityTeleport = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutEntityTeleport", "PacketPlayOutEntityTeleport", "Packet34EntityTeleport");
PacketPlayOutNamedEntitySpawn = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutNamedEntitySpawn", "PacketPlayOutNamedEntitySpawn", "Packet20NamedEntitySpawn");
PacketPlayOutScoreboardDisplayObjective = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutScoreboardDisplayObjective", "PacketPlayOutScoreboardDisplayObjective", "Packet208SetScoreboardDisplayObjective");
PacketPlayOutScoreboardObjective = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutScoreboardObjective", "PacketPlayOutScoreboardObjective", "Packet206SetScoreboardObjective");
PacketPlayOutScoreboardScore = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutScoreboardScore", "PacketPlayOutScoreboardScore", "Packet207SetScoreboardScore");
PacketPlayOutScoreboardTeam = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutScoreboardTeam", "PacketPlayOutScoreboardTeam", "Packet209SetScoreboardTeam");
PacketPlayOutSpawnEntityLiving = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutSpawnEntityLiving", "PacketPlayOutSpawnEntityLiving", "Packet24MobSpawn");
PlayerConnection = getNMSClass("net.minecraft.server.network.PlayerConnection", "PlayerConnection");
NetworkManager = getNMSClass("net.minecraft.network.NetworkManager", "NetworkManager");
Scoreboard = getNMSClass("net.minecraft.world.scores.Scoreboard", "Scoreboard");
ScoreboardObjective = getNMSClass("net.minecraft.world.scores.ScoreboardObjective", "ScoreboardObjective");
ScoreboardTeam = getNMSClass("net.minecraft.world.scores.ScoreboardTeam", "ScoreboardTeam");
ScoreboardScore = getNMSClass("net.minecraft.world.scores.ScoreboardScore", "ScoreboardScore");
IScoreboardCriteria = getNMSClass("net.minecraft.world.scores.criteria.IScoreboardCriteria", "IScoreboardCriteria");
if (minorVersion >= 7) {
ChatBaseComponent = getNMSClass("ChatBaseComponent");
ChatClickable = getNMSClass("ChatClickable");
ChatComponentText = getNMSClass("ChatComponentText");
ChatHoverable = getNMSClass("ChatHoverable");
ChatModifier = getNMSClass("ChatModifier");
ChatSerializer = getNMSClass("IChatBaseComponent$ChatSerializer", "ChatSerializer");
EnumClickAction = getNMSClass("ChatClickable$EnumClickAction", "EnumClickAction");
EnumHoverAction = getNMSClass("ChatHoverable$EnumHoverAction", "EnumHoverAction");
IChatBaseComponent = getNMSClass("IChatBaseComponent");
ChatBaseComponent = getNMSClass("net.minecraft.network.chat.ChatBaseComponent", "ChatBaseComponent");
ChatClickable = getNMSClass("net.minecraft.network.chat.ChatClickable", "ChatClickable");
ChatComponentText = getNMSClass("net.minecraft.network.chat.ChatComponentText", "ChatComponentText");
ChatHoverable = getNMSClass("net.minecraft.network.chat.ChatHoverable", "ChatHoverable");
ChatModifier = getNMSClass("net.minecraft.network.chat.ChatModifier", "ChatModifier");
ChatSerializer = getNMSClass("net.minecraft.network.chat.IChatBaseComponent$ChatSerializer", "IChatBaseComponent$ChatSerializer", "ChatSerializer");
EnumClickAction = getNMSClass("net.minecraft.network.chat.ChatClickable$EnumClickAction", "ChatClickable$EnumClickAction", "EnumClickAction");
EnumHoverAction = getNMSClass("net.minecraft.network.chat.ChatHoverable$EnumHoverAction", "ChatHoverable$EnumHoverAction", "EnumHoverAction");
IChatBaseComponent = getNMSClass("net.minecraft.network.chat.IChatBaseComponent", "IChatBaseComponent");
EnumEntityUseAction = getNMSClass("net.minecraft.network.protocol.game.PacketPlayInUseEntity$EnumEntityUseAction", "PacketPlayInUseEntity$EnumEntityUseAction", "EnumEntityUseAction");
}
if (minorVersion >= 8) {
GameProfile = Class.forName("com.mojang.authlib.GameProfile");
PropertyMap = Class.forName("com.mojang.authlib.properties.PropertyMap");
PacketPlayOutPlayerInfo = getNMSClass("PacketPlayOutPlayerInfo");
PacketPlayOutPlayerListHeaderFooter = getNMSClass("PacketPlayOutPlayerListHeaderFooter");
PacketPlayOutTitle = getNMSClass("PacketPlayOutTitle");
EnumPlayerInfoAction = (Class<Enum>) getNMSClass("PacketPlayOutPlayerInfo$EnumPlayerInfoAction", "EnumPlayerInfoAction");
PlayerInfoData = getNMSClass("PacketPlayOutPlayerInfo$PlayerInfoData", "PlayerInfoData");
EnumScoreboardHealthDisplay = (Class<Enum>) getNMSClass("IScoreboardCriteria$EnumScoreboardHealthDisplay", "EnumScoreboardHealthDisplay");
EnumTitleAction = (Class<Enum>) getNMSClass("PacketPlayOutTitle$EnumTitleAction", "EnumTitleAction");
EnumGamemode = (Class<Enum>) getNMSClass("EnumGamemode", "WorldSettings$EnumGamemode");
EnumScoreboardAction = (Class<Enum>) getNMSClass("ScoreboardServer$Action", "PacketPlayOutScoreboardScore$EnumScoreboardAction", "EnumScoreboardAction");
PacketPlayOutPlayerInfo = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutPlayerInfo", "PacketPlayOutPlayerInfo");
PacketPlayOutPlayerListHeaderFooter = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutPlayerListHeaderFooter", "PacketPlayOutPlayerListHeaderFooter");
EnumPlayerInfoAction = (Class<Enum>) getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutPlayerInfo$EnumPlayerInfoAction", "PacketPlayOutPlayerInfo$EnumPlayerInfoAction", "EnumPlayerInfoAction");
PlayerInfoData = getNMSClass("net.minecraft.network.protocol.game.PacketPlayOutPlayerInfo$PlayerInfoData", "PacketPlayOutPlayerInfo$PlayerInfoData", "PlayerInfoData");
EnumScoreboardHealthDisplay = (Class<Enum>) getNMSClass("net.minecraft.world.scores.criteria.IScoreboardCriteria$EnumScoreboardHealthDisplay", "IScoreboardCriteria$EnumScoreboardHealthDisplay", "EnumScoreboardHealthDisplay");
EnumGamemode = (Class<Enum>) getNMSClass("net.minecraft.world.level.EnumGamemode", "EnumGamemode", "WorldSettings$EnumGamemode");
EnumScoreboardAction = (Class<Enum>) getNMSClass("net.minecraft.server.ScoreboardServer$Action", "ScoreboardServer$Action", "PacketPlayOutScoreboardScore$EnumScoreboardAction", "EnumScoreboardAction");
EnumNameTagVisibility = getNMSClass("net.minecraft.world.scores.ScoreboardTeamBase$EnumNameTagVisibility", "ScoreboardTeamBase$EnumNameTagVisibility", "EnumNameTagVisibility");
}
if (minorVersion >= 9) {
DataWatcherObject = getNMSClass("DataWatcherObject");
DataWatcherRegistry = getNMSClass("DataWatcherRegistry");
PacketPlayOutBoss = getNMSClass("PacketPlayOutBoss");
BarColor = (Class<Enum>) getNMSClass("BossBattle$BarColor");
BarStyle = (Class<Enum>) getNMSClass("BossBattle$BarStyle");
PacketPlayOutBoss_Action = (Class<Enum>) getNMSClass("PacketPlayOutBoss$Action");
DataWatcherObject = getNMSClass("net.minecraft.network.syncher.DataWatcherObject", "DataWatcherObject");
DataWatcherRegistry = getNMSClass("net.minecraft.network.syncher.DataWatcherRegistry", "DataWatcherRegistry");
DataWatcherSerializer = getNMSClass("net.minecraft.network.syncher.DataWatcherSerializer", "DataWatcherSerializer");
EnumTeamPush = getNMSClass("net.minecraft.world.scores.ScoreboardTeamBase$EnumTeamPush", "ScoreboardTeamBase$EnumTeamPush");
}
if (minorVersion >= 12) {
ChatMessageType = (Class<Enum>) getNMSClass("ChatMessageType");
ChatMessageType = (Class<Enum>) getNMSClass("net.minecraft.network.chat.ChatMessageType", "ChatMessageType");
}
if (minorVersion >= 16) {
ChatHexColor = getNMSClass("ChatHexColor");
ChatHexColor = getNMSClass("net.minecraft.network.chat.ChatHexColor", "ChatHexColor");
}
if (minorVersion >= 17) {
PacketPlayOutScoreboardTeam_a = Class.forName("net.minecraft.network.protocol.game.PacketPlayOutScoreboardTeam$a");
}
}
@@ -344,49 +328,57 @@ public class NMSStorage {
* Initializes required NMS constructors
* @throws Exception - if something fails
*/
public void initializeConstructors() throws Exception {
private void initializeConstructors() throws Exception {
newDataWatcher = DataWatcher.getConstructors()[0];
newDataWatcherItem = DataWatcherItem.getConstructors()[0];
newPacketPlayOutChat = PacketPlayOutChat.getConstructor();
newPacketPlayOutScoreboardDisplayObjective = PacketPlayOutScoreboardDisplayObjective.getConstructor();
newPacketPlayOutScoreboardObjective = PacketPlayOutScoreboardObjective.getConstructor();
newPacketPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.getConstructor();
newPacketPlayOutEntityDestroy = PacketPlayOutEntityDestroy.getConstructor(int[].class);
newPacketPlayOutEntityMetadata = PacketPlayOutEntityMetadata.getConstructor(int.class, DataWatcher, boolean.class);
newPacketPlayOutEntityTeleport = PacketPlayOutEntityTeleport.getConstructor();
newPacketPlayOutSpawnEntityLiving = PacketPlayOutSpawnEntityLiving.getConstructor();
newScoreboardObjective = ScoreboardObjective.getConstructors()[0];
newScoreboard = Scoreboard.getConstructor();
newScoreboardTeam = ScoreboardTeam.getConstructor(Scoreboard, String.class);
newScoreboardScore = ScoreboardScore.getConstructor(Scoreboard, ScoreboardObjective, String.class);
newPacketPlayOutEntityDestroy = getConstructor(PacketPlayOutEntityDestroy, 1);
newPacketPlayOutEntityTeleport = PacketPlayOutEntityTeleport.getConstructor(Entity);
newPacketPlayOutSpawnEntityLiving = PacketPlayOutSpawnEntityLiving.getConstructor(EntityLiving);
newPacketPlayOutScoreboardDisplayObjective = PacketPlayOutScoreboardDisplayObjective.getConstructor(int.class, ScoreboardObjective);
if (minorVersion >= 7) {
newChatComponentText = ChatComponentText.getConstructor(String.class);
newChatClickable = ChatClickable.getConstructor(EnumClickAction, String.class);
newChatHoverable = ChatHoverable.getConstructors()[0];
}
if (minorVersion >= 8) {
newGameProfile = GameProfile.getConstructor(UUID.class, String.class);
newPacketPlayOutPlayerListHeaderFooter = PacketPlayOutPlayerListHeaderFooter.getConstructor();
newPacketPlayOutTitle = PacketPlayOutTitle.getConstructor(EnumTitleAction, IChatBaseComponent, int.class, int.class, int.class);
newPacketPlayOutPlayerInfo = PacketPlayOutPlayerInfo.getConstructor();
try {
newPlayerInfoData = PlayerInfoData.getConstructor(PacketPlayOutPlayerInfo, GameProfile, int.class, EnumGamemode, IChatBaseComponent);
} catch (Exception e) {
//1.8.8 paper
newPlayerInfoData = PlayerInfoData.getConstructor(GameProfile, int.class, EnumGamemode, IChatBaseComponent);
}
newPacketPlayOutPlayerListHeaderFooter = PacketPlayOutPlayerListHeaderFooter.getConstructors()[0];
newPacketPlayOutPlayerInfo = PacketPlayOutPlayerInfo.getConstructor(EnumPlayerInfoAction, Array.newInstance(EntityPlayer, 0).getClass());
newPlayerInfoData = PlayerInfoData.getConstructors()[0];
}
if (minorVersion >= 9) {
newDataWatcherObject = DataWatcherObject.getConstructors()[0];
newPacketPlayOutBoss = PacketPlayOutBoss.getConstructor();
}
if (minorVersion >= 13) {
newPacketPlayOutScoreboardObjective = PacketPlayOutScoreboardObjective.getConstructor(ScoreboardObjective, int.class);
newPacketPlayOutScoreboardScore_1_13 = PacketPlayOutScoreboardScore.getConstructor(EnumScoreboardAction, String.class, String.class, int.class);
} else {
newPacketPlayOutScoreboardScore0 = PacketPlayOutScoreboardScore.getConstructor();
newPacketPlayOutScoreboardObjective = PacketPlayOutScoreboardObjective.getConstructor();
newPacketPlayOutScoreboardScore_String = PacketPlayOutScoreboardScore.getConstructor(String.class);
if (minorVersion >= 8) {
newPacketPlayOutScoreboardScore = PacketPlayOutScoreboardScore.getConstructor(ScoreboardScore);
} else {
newPacketPlayOutScoreboardScore = PacketPlayOutScoreboardScore.getConstructor(ScoreboardScore, int.class);
}
}
if (minorVersion >= 16) {
newChatHoverable = ChatHoverable.getConstructor(EnumHoverAction, Object.class);
newChatModifier = getConstructor(ChatModifier, 10);
newPacketPlayOutChat = PacketPlayOutChat.getConstructor(IChatBaseComponent, ChatMessageType, UUID.class);
} else if (minorVersion >= 7) {
newChatHoverable = ChatHoverable.getConstructor(EnumHoverAction, IChatBaseComponent);
newChatModifier = ChatModifier.getConstructor();
if (minorVersion >= 12) {
newPacketPlayOutChat = PacketPlayOutChat.getConstructor(IChatBaseComponent, ChatMessageType);
} else if (minorVersion >= 8) {
newPacketPlayOutChat = PacketPlayOutChat.getConstructor(IChatBaseComponent, byte.class);
} else {
newPacketPlayOutChat = PacketPlayOutChat.getConstructor(IChatBaseComponent);
}
}
if (minorVersion < 17) {
newPacketPlayOutScoreboardTeam = PacketPlayOutScoreboardTeam.getConstructor(ScoreboardTeam, int.class);
}
}
@@ -394,178 +386,117 @@ public class NMSStorage {
* Initializes required NMS fields
* @throws Exception - if something fails
*/
public void initializeFields() throws Exception {
PING = getField(getNMSClass("EntityPlayer"), "ping");
PLAYER_CONNECTION = getField(getNMSClass("EntityPlayer"), "playerConnection");
NETWORK_MANAGER = getField(PLAYER_CONNECTION.getType(), "networkManager");
private void initializeFields() throws Exception {
PLAYER_CONNECTION = getFields(EntityPlayer, PlayerConnection).get(0);
PacketPlayOutScoreboardDisplayObjective_POSITION = getField(PacketPlayOutScoreboardDisplayObjective, "a");
PacketPlayOutScoreboardDisplayObjective_OBJECTIVENAME = getField(PacketPlayOutScoreboardDisplayObjective, "b");
PacketPlayOutScoreboardObjective_OBJECTIVENAME = getField(PacketPlayOutScoreboardObjective, "a");
PacketPlayOutScoreboardObjective_DISPLAYNAME = getField(PacketPlayOutScoreboardObjective, "b");
PacketPlayOutScoreboardScore_PLAYER = getField(PacketPlayOutScoreboardScore, "a");
PacketPlayOutScoreboardScore_OBJECTIVENAME = getField(PacketPlayOutScoreboardScore, "b");
PacketPlayOutScoreboardScore_SCORE = getField(PacketPlayOutScoreboardScore, "c");
PacketPlayOutScoreboardScore_ACTION = getField(PacketPlayOutScoreboardScore, "d");
PacketPlayOutScoreboardTeam_NAME = getField(PacketPlayOutScoreboardTeam, "a");
PacketPlayOutScoreboardTeam_DISPLAYNAME = getField(PacketPlayOutScoreboardTeam, "b");
PacketPlayOutScoreboardTeam_PREFIX = getField(PacketPlayOutScoreboardTeam, "c");
PacketPlayOutScoreboardTeam_SUFFIX = getField(PacketPlayOutScoreboardTeam, "d");
PacketPlayOutEntityTeleport_ENTITYID = getField(PacketPlayOutEntityTeleport, "a");
PacketPlayOutEntityTeleport_X = getField(PacketPlayOutEntityTeleport, "b");
PacketPlayOutEntityTeleport_Y = getField(PacketPlayOutEntityTeleport, "c");
PacketPlayOutEntityTeleport_Z = getField(PacketPlayOutEntityTeleport, "d");
PacketPlayOutEntityTeleport_YAW = getField(PacketPlayOutEntityTeleport, "e");
PacketPlayOutEntityTeleport_PITCH = getField(PacketPlayOutEntityTeleport, "f");
PacketPlayOutEntity_ENTITYID = getField(PacketPlayOutEntity, "a");
PacketPlayOutEntityMetadata_LIST = getField(PacketPlayOutEntityMetadata, "b");
PacketPlayOutSpawnEntityLiving_ENTITYID = getField(PacketPlayOutSpawnEntityLiving, "a");
PacketPlayOutScoreboardDisplayObjective_POSITION = getFields(PacketPlayOutScoreboardDisplayObjective, int.class).get(0);
PacketPlayOutScoreboardDisplayObjective_OBJECTIVENAME = getFields(PacketPlayOutScoreboardDisplayObjective, String.class).get(0);
PacketPlayOutEntityDestroy_ENTITIES = getField(PacketPlayOutEntityDestroy, "a");
PacketPlayOutNamedEntitySpawn_ENTITYID = getField(PacketPlayOutNamedEntitySpawn, "a");
PacketPlayOutScoreboardObjective_OBJECTIVENAME = getFields(PacketPlayOutScoreboardObjective, String.class).get(0);
List<Field> fields = getFields(PacketPlayOutScoreboardObjective, int.class);
PacketPlayOutScoreboardObjective_METHOD = fields.get(fields.size()-1);
PacketPlayOutScoreboardTeam_NAME = getFields(PacketPlayOutScoreboardTeam, String.class).get(0);
PacketPlayOutScoreboardTeam_PLAYERS = getFields(PacketPlayOutScoreboardTeam, Collection.class).get(0);
PacketPlayOutEntityTeleport_ENTITYID = getFields(PacketPlayOutEntityTeleport, int.class).get(0);
PacketPlayOutEntityTeleport_YAW = getFields(PacketPlayOutEntityTeleport, byte.class).get(0);
PacketPlayOutEntityTeleport_PITCH = getFields(PacketPlayOutEntityTeleport, byte.class).get(1);
PacketPlayOutEntity_ENTITYID = getFields(PacketPlayOutEntity, int.class).get(0);
PacketPlayOutEntityMetadata_LIST = getFields(PacketPlayOutEntityMetadata, List.class).get(0);
PacketPlayOutSpawnEntityLiving_ENTITYID = getFields(PacketPlayOutSpawnEntityLiving, int.class).get(0);
PacketPlayOutSpawnEntityLiving_ENTITYTYPE = getFields(PacketPlayOutSpawnEntityLiving, int.class).get(1);
PacketPlayOutSpawnEntityLiving_YAW = getFields(PacketPlayOutSpawnEntityLiving, byte.class).get(0);
PacketPlayOutSpawnEntityLiving_PITCH = getFields(PacketPlayOutSpawnEntityLiving, byte.class).get(0);
(PacketPlayOutEntityDestroy_ENTITIES = PacketPlayOutEntityDestroy.getDeclaredFields()[0]).setAccessible(true);
PacketPlayOutNamedEntitySpawn_ENTITYID = getFields(PacketPlayOutNamedEntitySpawn, int.class).get(0);
if (minorVersion >= 7) {
PacketPlayOutChat_MESSAGE = getField(PacketPlayOutChat, "a");
NETWORK_MANAGER = getFields(PlayerConnection, NetworkManager).get(0);
ChatBaseComponent_extra = getFields(ChatBaseComponent, List.class).get(0);
ChatBaseComponent_modifier = getFields(ChatBaseComponent, ChatModifier).get(0);
ChatComponentText_text = getFields(ChatComponentText, String.class).get(0);
ChatClickable_action = getField(ChatClickable, "a");
ChatClickable_value = getField(ChatClickable, "b");
PacketPlayInUseEntity_ENTITY = getField(PacketPlayInUseEntity, "a");
try {
//1.14.4+
ChatBaseComponent_extra = getField(ChatBaseComponent, "siblings");
ChatModifier_color = getField(ChatModifier, "color");
ChatModifier_bold = getField(ChatModifier, "bold");
ChatModifier_italic = getField(ChatModifier, "italic");
ChatModifier_underlined = getField(ChatModifier, "underlined");
ChatModifier_strikethrough = getField(ChatModifier, "strikethrough");
ChatModifier_obfuscated = getField(ChatModifier, "obfuscated");
ChatModifier_clickEvent = getField(ChatModifier, "clickEvent");
ChatModifier_hoverEvent = getField(ChatModifier, "hoverEvent");
} catch (NoSuchFieldException e) {
//1.14.3-
ChatBaseComponent_extra = getField(ChatBaseComponent, "a");
ChatModifier_color = getField(ChatModifier, "b");
ChatModifier_bold = getField(ChatModifier, "c");
ChatModifier_italic = getField(ChatModifier, "d");
ChatModifier_underlined = getField(ChatModifier, "e");
ChatModifier_strikethrough = getField(ChatModifier, "f");
ChatModifier_obfuscated = getField(ChatModifier, "g");
ChatModifier_clickEvent = getField(ChatModifier, "h");
ChatModifier_hoverEvent = getField(ChatModifier, "i");
}
} else {
//1.6-
(PacketPlayOutChat_MESSAGE = PacketPlayOutChat.getDeclaredField("message")).setAccessible(true);
ChatClickable_action = getFields(ChatClickable, EnumClickAction).get(0);
ChatClickable_value = getFields(ChatClickable, String.class).get(0);
ChatHoverable_action = getFields(ChatHoverable, EnumHoverAction).get(0);
List<Field> booleans = getFields(ChatModifier, Boolean.class);
ChatModifier_bold = booleans.get(0);
ChatModifier_italic = booleans.get(1);
ChatModifier_underlined = booleans.get(2);
ChatModifier_strikethrough = booleans.get(3);
ChatModifier_obfuscated = booleans.get(4);
ChatModifier_clickEvent = getFields(ChatModifier, ChatClickable).get(0);
ChatModifier_hoverEvent = getFields(ChatModifier, ChatHoverable).get(0);
PacketPlayInUseEntity_ENTITY = getFields(PacketPlayInUseEntity, int.class).get(0);
PacketPlayInUseEntity_ACTION = getFields(PacketPlayInUseEntity, EnumEntityUseAction).get(0);
}
if (minorVersion >= 8) {
CHANNEL = getFields(NetworkManager, Channel.class).get(0);
PacketPlayOutPlayerInfo_ACTION = getFields(PacketPlayOutPlayerInfo, EnumPlayerInfoAction).get(0);
PacketPlayOutPlayerInfo_PLAYERS = getFields(PacketPlayOutPlayerInfo, List.class).get(0);
PacketPlayOutPlayerListHeaderFooter_HEADER = getFields(PacketPlayOutPlayerListHeaderFooter, IChatBaseComponent).get(0);
PacketPlayOutPlayerListHeaderFooter_FOOTER = getFields(PacketPlayOutPlayerListHeaderFooter, IChatBaseComponent).get(1);
PacketPlayOutScoreboardObjective_RENDERTYPE = getFields(PacketPlayOutScoreboardObjective, EnumScoreboardHealthDisplay).get(0);
}
if (minorVersion >= 8) {
//1.8+
CHANNEL = getFields(getNMSClass("NetworkManager"), Channel.class).get(0);
PacketPlayOutChat_POSITION = getField(PacketPlayOutChat, "b");
PacketPlayOutScoreboardObjective_RENDERTYPE = getField(PacketPlayOutScoreboardObjective, "c");
PacketPlayOutScoreboardObjective_METHOD = getField(PacketPlayOutScoreboardObjective, "d");
GameProfile_ID = getField(GameProfile, "id");
GameProfile_NAME = getField(GameProfile, "name");
GameProfile_PROPERTIES = getField(GameProfile, "properties");
PacketPlayOutPlayerInfo_ACTION = getField(PacketPlayOutPlayerInfo, "a");
PacketPlayOutPlayerInfo_PLAYERS = getField(PacketPlayOutPlayerInfo, "b");
PlayerInfoData_PING = getField(PlayerInfoData, "b");
PlayerInfoData_GAMEMODE = getField(PlayerInfoData, "c");
PlayerInfoData_PROFILE = getField(PlayerInfoData, "d");
PlayerInfoData_LISTNAME = getField(PlayerInfoData, "e");
List<Field> fields = getFields(PacketPlayOutPlayerListHeaderFooter, IChatBaseComponent);
PacketPlayOutPlayerListHeaderFooter_HEADER = fields.get(0);
PacketPlayOutPlayerListHeaderFooter_FOOTER = fields.get(1);
} else {
//1.7-
PacketPlayOutScoreboardObjective_METHOD = getField(PacketPlayOutScoreboardObjective, "c");
}
if (minorVersion >= 9) {
//1.9+
DataWatcherItem_TYPE = getField(DataWatcherItem, "a");
DataWatcherItem_VALUE = getField(DataWatcherItem, "b");
DataWatcherObject_SLOT = getField(DataWatcherObject, "a");
DataWatcherObject_SERIALIZER = getField(DataWatcherObject, "b");
PacketPlayOutBoss_UUID = getField(PacketPlayOutBoss, "a");
PacketPlayOutBoss_ACTION = getField(PacketPlayOutBoss, "b");
PacketPlayOutBoss_NAME = getField(PacketPlayOutBoss, "c");
PacketPlayOutBoss_PROGRESS = getField(PacketPlayOutBoss, "d");
PacketPlayOutBoss_COLOR = getField(PacketPlayOutBoss, "e");
PacketPlayOutBoss_STYLE = getField(PacketPlayOutBoss, "f");
PacketPlayOutBoss_DARKEN_SKY = getField(PacketPlayOutBoss, "g");
PacketPlayOutBoss_PLAY_MUSIC = getField(PacketPlayOutBoss, "h");
PacketPlayOutBoss_CREATE_FOG = getField(PacketPlayOutBoss, "i");
PacketPlayOutScoreboardTeam_VISIBILITY = getField(PacketPlayOutScoreboardTeam, "e");
PacketPlayOutScoreboardTeam_COLLISION = getField(PacketPlayOutScoreboardTeam, "f");
PacketPlayOutScoreboardTeam_PLAYERS = getField(PacketPlayOutScoreboardTeam, "h");
PacketPlayOutScoreboardTeam_ACTION = getField(PacketPlayOutScoreboardTeam, "i");
PacketPlayOutScoreboardTeam_SIGNATURE = getField(PacketPlayOutScoreboardTeam, "j");
PacketPlayOutSpawnEntityLiving_UUID = getField(PacketPlayOutSpawnEntityLiving, "b");
PacketPlayOutSpawnEntityLiving_ENTITYTYPE = getField(PacketPlayOutSpawnEntityLiving, "c");
PacketPlayOutSpawnEntityLiving_X = getField(PacketPlayOutSpawnEntityLiving, "d");
PacketPlayOutSpawnEntityLiving_Y = getField(PacketPlayOutSpawnEntityLiving, "e");
PacketPlayOutSpawnEntityLiving_Z = getField(PacketPlayOutSpawnEntityLiving, "f");
PacketPlayOutSpawnEntityLiving_YAW = getField(PacketPlayOutSpawnEntityLiving, "j");
PacketPlayOutSpawnEntityLiving_PITCH = getField(PacketPlayOutSpawnEntityLiving, "k");
PacketPlayInUseEntity_ACTION = getField(PacketPlayInUseEntity, "action");
DataWatcherItem_TYPE = getFields(DataWatcherItem, DataWatcherObject).get(0);
DataWatcherItem_VALUE = getFields(DataWatcherItem, Object.class).get(0);
DataWatcherObject_SLOT = getFields(DataWatcherObject, int.class).get(0);
DataWatcherObject_SERIALIZER = getFields(DataWatcherObject, DataWatcherSerializer).get(0);
PacketPlayOutEntityTeleport_X = getFields(PacketPlayOutEntityTeleport, double.class).get(0);
PacketPlayOutEntityTeleport_Y = getFields(PacketPlayOutEntityTeleport, double.class).get(1);
PacketPlayOutEntityTeleport_Z = getFields(PacketPlayOutEntityTeleport, double.class).get(2);
PacketPlayOutSpawnEntityLiving_UUID = getFields(PacketPlayOutSpawnEntityLiving, UUID.class).get(0);
PacketPlayOutSpawnEntityLiving_X = getFields(PacketPlayOutSpawnEntityLiving, double.class).get(0);
PacketPlayOutSpawnEntityLiving_Y = getFields(PacketPlayOutSpawnEntityLiving, double.class).get(1);
PacketPlayOutSpawnEntityLiving_Z = getFields(PacketPlayOutSpawnEntityLiving, double.class).get(2);
} else {
//1.8-
DataWatcherItem_TYPE = getField(DataWatcherItem, "b");
DataWatcherItem_VALUE = getField(DataWatcherItem, "c");
PacketPlayOutSpawnEntityLiving_ENTITYTYPE = getField(PacketPlayOutSpawnEntityLiving, "b");
PacketPlayOutSpawnEntityLiving_X = getField(PacketPlayOutSpawnEntityLiving, "c");
PacketPlayOutSpawnEntityLiving_Y = getField(PacketPlayOutSpawnEntityLiving, "d");
PacketPlayOutSpawnEntityLiving_Z = getField(PacketPlayOutSpawnEntityLiving, "e");
PacketPlayOutSpawnEntityLiving_YAW = getField(PacketPlayOutSpawnEntityLiving, "i");
PacketPlayOutSpawnEntityLiving_PITCH = getField(PacketPlayOutSpawnEntityLiving, "j");
if (minorVersion == 8) {
//1.8.x
PacketPlayOutScoreboardTeam_VISIBILITY = getField(PacketPlayOutScoreboardTeam, "e");
PacketPlayOutScoreboardTeam_PLAYERS = getField(PacketPlayOutScoreboardTeam, "g");
PacketPlayOutScoreboardTeam_ACTION = getField(PacketPlayOutScoreboardTeam, "h");
PacketPlayOutScoreboardTeam_SIGNATURE = getField(PacketPlayOutScoreboardTeam, "i");
} else {
//1.5.x - 1.7.x
PacketPlayOutScoreboardTeam_PLAYERS = getField(PacketPlayOutScoreboardTeam, "e");
PacketPlayOutScoreboardTeam_ACTION = getField(PacketPlayOutScoreboardTeam, "f");
PacketPlayOutScoreboardTeam_SIGNATURE = getField(PacketPlayOutScoreboardTeam, "g");
}
DataWatcherItem_TYPE = getFields(DataWatcherItem, int.class).get(1);
DataWatcherItem_VALUE = getFields(DataWatcherItem, Object.class).get(0);
PacketPlayOutEntityTeleport_X = getFields(PacketPlayOutEntityTeleport, int.class).get(1);
PacketPlayOutEntityTeleport_Y = getFields(PacketPlayOutEntityTeleport, int.class).get(2);
PacketPlayOutEntityTeleport_Z = getFields(PacketPlayOutEntityTeleport, int.class).get(3);
PacketPlayOutSpawnEntityLiving_X = getFields(PacketPlayOutSpawnEntityLiving, int.class).get(2);
PacketPlayOutSpawnEntityLiving_Y = getFields(PacketPlayOutSpawnEntityLiving, int.class).get(3);
PacketPlayOutSpawnEntityLiving_Z = getFields(PacketPlayOutSpawnEntityLiving, int.class).get(4);
}
if (minorVersion >= 13) {
//1.13+
PacketPlayOutScoreboardTeam_CHATFORMAT = getField(PacketPlayOutScoreboardTeam, "g");
PacketPlayOutScoreboardObjective_DISPLAYNAME = getFields(PacketPlayOutScoreboardObjective, IChatBaseComponent).get(0);
} else {
PacketPlayOutScoreboardObjective_DISPLAYNAME = getFields(PacketPlayOutScoreboardObjective, String.class).get(1);
}
if (minorVersion <= 14) {
PacketPlayOutSpawnEntityLiving_DATAWATCHER = getFields(PacketPlayOutSpawnEntityLiving, DataWatcher).get(0);
}
if (minorVersion >= 16) {
//1.16+
ChatHexColor_name = getField(ChatHexColor, "name");
ChatHexColor_rgb = getField(ChatHexColor, "rgb");
ChatHoverable_action = getField(ChatHoverable, "b");
ChatHoverable_value = getField(ChatHoverable, "c");
PacketPlayOutChat_SENDER = getField(PacketPlayOutChat, "c");
fields = getFields(ChatHexColor, String.class);
ChatHexColor_name = fields.get(fields.size()-1);
ChatHexColor_rgb = getFields(ChatHexColor, int.class).get(0);
ChatHoverable_value = getFields(ChatHoverable, Object.class).get(0);
ChatModifier_color = getFields(ChatModifier, ChatHexColor).get(0);
} else if (minorVersion >= 7) {
ChatHoverable_action = getField(ChatHoverable, "a");
ChatHoverable_value = getField(ChatHoverable, "b");
ChatHoverable_value = getFields(ChatHoverable, IChatBaseComponent).get(0);
ChatModifier_color = getFields(ChatModifier, EnumChatFormat).get(0);
}
if (minorVersion >= 17) {
try {
PING = getField(EntityPlayer, "e");
} catch (NoSuchFieldException e) {
//deobfuscated spigot jat
PING = getField(EntityPlayer, "latency");
}
} else {
PING = getField(EntityPlayer, "ping");
}
}
@@ -573,9 +504,11 @@ public class NMSStorage {
* Initializes required NMS methods
* @throws Exception - if something fails
*/
public void initializeMethods() throws Exception {
private void initializeMethods() throws Exception {
getHandle = Class.forName("org.bukkit.craftbukkit." + serverPackage + ".entity.CraftPlayer").getMethod("getHandle");
sendPacket = getMethod(getNMSClass("PlayerConnection"), new String[]{"sendPacket", "func_147359_a"}, getNMSClass("Packet"));
sendPacket = getMethod(PlayerConnection, new String[]{"sendPacket", "func_147359_a"}, Packet);
ScoreboardTeam_getPlayerNameSet = getMethod(ScoreboardTeam, new String[]{"getPlayerNameSet", "func_96670_d"});
ScoreboardScore_setScore = getMethod(ScoreboardScore, new String[]{"setScore", "func_96647_c"}, int.class);
if (minorVersion >= 7) {
ChatComponentText_addSibling = getMethod(ChatComponentText, new String[]{"addSibling", "a", "func_150257_a"}, IChatBaseComponent); //v1.7.R4+, v1.7.R3-
ChatSerializer_DESERIALIZE = getMethod(ChatSerializer, new String[]{"a", "func_150699_a"}, String.class);
@@ -583,25 +516,38 @@ public class NMSStorage {
EnumHoverAction_a = getMethod(EnumHoverAction, new String[]{"a", "func_150684_a"}, String.class);
}
if (minorVersion >= 8) {
getProfile = getNMSClass("EntityHuman").getMethod("getProfile");
for (Method m : PropertyMap.getMethods()) {
if (m.getName().equals("putAll") && m.getParameterCount() == 1) PropertyMap_putAll = m;
}
if (PropertyMap_putAll == null) throw new IllegalStateException("putAll method not found");
PlayerInfoData_getProfile = PlayerInfoData.getMethod("a");
PlayerInfoData_getLatency = PlayerInfoData.getMethod("b");
PlayerInfoData_getGamemode = PlayerInfoData.getMethod("c");
PlayerInfoData_getDisplayName = PlayerInfoData.getMethod("d");
ScoreboardTeam_setNameTagVisibility = getMethod(ScoreboardTeam, new String[]{"setNameTagVisibility", "a"}, EnumNameTagVisibility);
getProfile = EntityPlayer.getMethod("getProfile");
}
if (minorVersion >= 9) {
//1.9+
ScoreboardTeam_setCollisionRule = ScoreboardTeam.getMethod("setCollisionRule", EnumTeamPush);
DataWatcher_REGISTER = DataWatcher.getMethod("register", DataWatcherObject, Object.class);
} else {
//1.7.x - 1.8.x
DataWatcher_REGISTER = getMethod(DataWatcher, new String[]{"a", "func_75682_a"}, int.class, Object.class);
}
if (minorVersion >= 13) {
ScoreboardTeam_setPrefix = ScoreboardTeam.getMethod("setPrefix", IChatBaseComponent);
ScoreboardTeam_setSuffix = ScoreboardTeam.getMethod("setSuffix", IChatBaseComponent);
ScoreboardTeam_setColor = ScoreboardTeam.getMethod("setColor", EnumChatFormat);
} else {
ScoreboardTeam_setPrefix = getMethod(ScoreboardTeam, new String[]{"setPrefix", "func_96666_b"}, String.class);
ScoreboardTeam_setSuffix = getMethod(ScoreboardTeam, new String[]{"setSuffix", "func_96662_c"}, String.class);
}
if (minorVersion >= 16) {
ChatHexColor_ofInt = ChatHexColor.getMethod("a", int.class);
ChatHexColor_ofString = ChatHexColor.getMethod("a", String.class);
}
if (minorVersion >= 17) {
PacketPlayOutScoreboardTeam_of = PacketPlayOutScoreboardTeam.getMethod("a", ScoreboardTeam);
PacketPlayOutScoreboardTeam_ofBoolean = PacketPlayOutScoreboardTeam.getMethod("a", ScoreboardTeam, boolean.class);
PacketPlayOutScoreboardTeam_ofString = PacketPlayOutScoreboardTeam.getMethod("a", ScoreboardTeam, String.class, PacketPlayOutScoreboardTeam_a);
}
}
/**
* A helper method that prints all methods of class into console, including their return type, name and parameters
* Useful for modded servers which code I can not access
@@ -627,27 +573,31 @@ public class NMSStorage {
} catch (ClassNotFoundException e) {
}
}
throw new ClassNotFoundException("No class found with possible names " + names);
throw new ClassNotFoundException("No class found with possible names " + Arrays.toString(names));
}
/**
* Returns class from given name
* @param name - class name
* @return class from given name
* @throws ClassNotFoundException if class was not found
*/
public Class<?> getNMSClass(String name) throws ClassNotFoundException {
try {
return Class.forName("net.minecraft.server." + serverPackage + "." + name);
} catch (ClassNotFoundException e) {
//modded server?
return Main.class.getClassLoader().loadClass("net.minecraft.server." + serverPackage + "." + name);
} catch (NullPointerException e) {
//nested class in modded server
throw new ClassNotFoundException(name);
private Class<?> getNMSClass(String name) throws ClassNotFoundException {
if (minorVersion >= 17) {
return Class.forName(name);
} else {
try {
return Class.forName("net.minecraft.server." + serverPackage + "." + name);
} catch (ClassNotFoundException e) {
//modded server?
return Main.class.getClassLoader().loadClass("net.minecraft.server." + serverPackage + "." + name);
} catch (NullPointerException e) {
//nested class in modded server
throw new ClassNotFoundException(name);
}
}
}
/**
* Returns method with specified possible names and parameters. Throws exception if no such method was found
* @param clazz - class to get method from
@@ -656,7 +606,7 @@ public class NMSStorage {
* @return method with specified name and parameters
* @throws NoSuchMethodException if no such method exists
*/
public Method getMethod(Class<?> clazz, String[] names, Class<?>... parameterTypes) throws NoSuchMethodException {
private Method getMethod(Class<?> clazz, String[] names, Class<?>... parameterTypes) throws NoSuchMethodException {
for (String name : names) {
try {
return clazz.getMethod(name, parameterTypes);
@@ -672,7 +622,7 @@ public class NMSStorage {
* @param type - field type to check for
* @return list of all fields with specified class type
*/
private List<Field> getFields(Class<?> clazz, Class<?> type){
public List<Field> getFields(Class<?> clazz, Class<?> type){
if (clazz == null) throw new IllegalArgumentException("Source class cannot be null");
List<Field> list = new ArrayList<Field>();
for (Field field : clazz.getDeclaredFields()) {
@@ -681,7 +631,7 @@ public class NMSStorage {
}
return list;
}
/**
* Returns field with specified name and makes it accessible
* @param clazz - class to get field from
@@ -696,12 +646,12 @@ public class NMSStorage {
return f;
}
}
if (thermosFieldMappings.containsKey(name)) {
return getField(clazz, thermosFieldMappings.get(name));
if (name.equals("ping")){
return getField(clazz, "field_71138_i"); //thermos
}
throw new NoSuchFieldException("Field \"" + name + "\" was not found in class " + clazz.getName());
}
private Constructor<?> getConstructor(Class<?> clazz, int parameterCount) throws NoSuchMethodException {
for (Constructor<?> c : clazz.getDeclaredConstructors()) {
if (c.getParameterCount() == parameterCount) {
@@ -36,7 +36,10 @@ public class DataWatcherHelper {
* @return armor stand flags position based on server version
*/
private int getArmorStandFlagsPosition() {
if (NMSStorage.getInstance().minorVersion >= 15) {
if (NMSStorage.getInstance().minorVersion >= 17) {
//1.17.x
return 15;
} else if (NMSStorage.getInstance().minorVersion >= 15) {
//1.15.x, 1.16.x
return 14;
} else if (NMSStorage.getInstance().minorVersion >= 14) {
@@ -36,11 +36,6 @@ public class DataWatcherRegistry {
} else {
Boolean = fields.get("h");
}
} else {
Byte = 0;
Integer = 2;
Float = 3;
String = 4;
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>me.neznamy</groupId>
<artifactId>TAB</artifactId>
<version>2.8.11-pre18</version>
<version>2.9.0</version>
</parent>
<artifactId>bungeecord</artifactId>
@@ -19,21 +19,16 @@ import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardObjective;
import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardObjective.EnumScoreboardHealthDisplay;
import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardScore;
import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardTeam;
import me.neznamy.tab.shared.packets.PacketPlayOutTitle;
import net.md_5.bungee.protocol.packet.BossBar;
import net.md_5.bungee.protocol.packet.Chat;
import net.md_5.bungee.protocol.packet.ClearTitles;
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
import net.md_5.bungee.protocol.packet.PlayerListItem;
import net.md_5.bungee.protocol.packet.PlayerListItem.Item;
import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
import net.md_5.bungee.protocol.packet.ScoreboardObjective;
import net.md_5.bungee.protocol.packet.ScoreboardObjective.HealthDisplay;
import net.md_5.bungee.protocol.packet.ScoreboardScore;
import net.md_5.bungee.protocol.packet.Subtitle;
import net.md_5.bungee.protocol.packet.Team;
import net.md_5.bungee.protocol.packet.Title;
import net.md_5.bungee.protocol.packet.TitleTimes;
import net.md_5.bungee.protocol.packet.PlayerListItem.Item;
/**
* Packet builder for BungeeCord platform
@@ -118,47 +113,6 @@ public class BungeePacketBuilder implements PacketBuilder {
packet.nametagVisibility, packet.collisionRule, color, (byte)packet.options, packet.players.toArray(new String[0]));
}
@Override
public Object build(PacketPlayOutTitle packet, ProtocolVersion clientVersion) {
if (clientVersion.getMinorVersion() >= 17) {
switch (packet.action) {
case TITLE:
Title title = new Title();
title.setText(IChatBaseComponent.optimizedComponent(packet.text).toString(clientVersion));
return title;
case SUBTITLE:
Subtitle subtitle = new Subtitle();
subtitle.setText(IChatBaseComponent.optimizedComponent(packet.text).toString(clientVersion));
return subtitle;
case ACTIONBAR:
//md_5 forgot actionbar packet
return new Chat(IChatBaseComponent.optimizedComponent(packet.text).toString(clientVersion), (byte) 2);
case TIMES:
TitleTimes times = new TitleTimes();
times.setFadeIn(packet.fadeIn);
times.setStay(packet.stay);
times.setFadeOut(packet.fadeOut);
return times;
case CLEAR:
return new ClearTitles();
case RESET:
ClearTitles reset = new ClearTitles();
reset.setReset(true);
return reset;
default:
throw new IllegalStateException("Action is null");
}
} else {
Title bungeePacket = new Title();
bungeePacket.setAction(Title.Action.valueOf(packet.action.toString()));
if (packet.text != null) bungeePacket.setText(IChatBaseComponent.optimizedComponent(packet.text).toString(clientVersion));
bungeePacket.setFadeIn(packet.fadeIn);
bungeePacket.setStay(packet.stay);
bungeePacket.setFadeOut(packet.fadeOut);
return bungeePacket;
}
}
@Override
public PacketPlayOutPlayerInfo readPlayerInfo(Object bungeePacket, ProtocolVersion clientVersion) {
PlayerListItem item = (PlayerListItem) bungeePacket;
@@ -58,16 +58,15 @@ public class BungeePipelineInjector extends PipelineInjector {
private void modifyPlayers(Team packet){
long time = System.nanoTime();
if (packet.getPlayers() == null) return;
if (packet.getFriendlyFire() != 69) {
Collection<String> col = Lists.newArrayList(packet.getPlayers());
for (TabPlayer p : tab.getPlayers()) {
if (col.contains(p.getName()) && !tab.getFeatureManager().getNameTagFeature().isDisabledWorld(p.getWorldName()) && !p.hasTeamHandlingPaused()) {
logTeamOverride(packet.getName(), p.getName());
col.remove(p.getName());
}
Collection<String> col = Lists.newArrayList(packet.getPlayers());
for (TabPlayer p : tab.getPlayers()) {
if (col.contains(p.getName()) && !tab.getFeatureManager().getNameTagFeature().isDisabledWorld(p.getWorldName()) &&
!p.hasTeamHandlingPaused() && !p.getTeamName().equals(packet.getName())) {
logTeamOverride(packet.getName(), p.getName());
col.remove(p.getName());
}
packet.setPlayers(col.toArray(new String[0]));
}
packet.setPlayers(col.toArray(new String[0]));
tab.getCPUManager().addTime(TabFeature.NAMETAGS, UsageType.ANTI_OVERRIDE, System.nanoTime()-time);
}
@@ -94,47 +93,45 @@ public class BungeePipelineInjector extends PipelineInjector {
super.write(context, tab.getFeatureManager().onPacketPlayOutPlayerInfo(player, packet), channelPromise);
return;
}
Object modifiedPacket = packet;
long time = System.nanoTime();
if (packet instanceof ByteBuf) {
modifiedPacket = deserialize((ByteBuf) packet);
}
tab.getCPUManager().addTime(TabFeature.PACKET_DESERIALIZING, UsageType.PACKET_READING_OUT, System.nanoTime()-time);
if (tab.getFeatureManager().isFeatureEnabled("nametag16") && antiOverrideTeams) {
if (packet instanceof Team) {
//team packet coming from a bungeecord plugin
modifyPlayers((Team) packet);
super.write(context, packet, channelPromise);
time = System.nanoTime();
if (modifiedPacket instanceof Team) {
modifyPlayers((Team) modifiedPacket);
tab.getCPUManager().addTime(TabFeature.NAMETAGS, UsageType.ANTI_OVERRIDE, System.nanoTime()-time);
super.write(context, modifiedPacket, channelPromise);
return;
}
if (packet instanceof ByteBuf) {
long time = System.nanoTime();
ByteBuf buf = ((ByteBuf) packet);
//for now protocolsupport will break the plugin
/* if (modifiedPacket instanceof ByteBuf) {
ByteBuf buf = ((ByteBuf) modifiedPacket);
int marker = buf.readerIndex();
int packetId = buf.readByte();
if (packetId == ((BungeeTabPlayer)player).getPacketId(Team.class)) {
//team packet sent by backend server, proxy does not deserialize those for whatever reason
Team team = new Team();
team.read(buf, null, ((ProxiedPlayer)player.getPlayer()).getPendingConnection().getVersion());
if (packetId + 128 == ((BungeeTabPlayer)player).getPacketId(Team.class)){
//compressed team packet when using protocolsupport, proper decompression will be needed
buf.release();
tab.getCPUManager().addTime(TabFeature.NAMETAGS, UsageType.ANTI_OVERRIDE, System.nanoTime()-time);
modifyPlayers(team);
super.write(context, team, channelPromise);
return;
} else if (packetId + 128 == ((BungeeTabPlayer)player).getPacketId(Team.class)){
//compressed team packet when using protocolsupport, just kill it as it does not come from tab anyway
buf.release();
return;
}
buf.readerIndex(marker);
}
}*/
tab.getCPUManager().addTime(TabFeature.NAMETAGS, UsageType.ANTI_OVERRIDE, System.nanoTime()-time);
}
if (packet instanceof ScoreboardDisplay && antiOverrideObjectives && tab.getFeatureManager().onDisplayObjective(player, packet)) {
//TODO add support for serialized packets as above with teams
if (modifiedPacket instanceof ScoreboardDisplay && antiOverrideObjectives && tab.getFeatureManager().onDisplayObjective(player, modifiedPacket)) {
return;
}
if (packet instanceof ScoreboardObjective && antiOverrideObjectives) {
//TODO add support for serialized packets as above with teams
tab.getFeatureManager().onObjective(player, packet);
if (modifiedPacket instanceof ScoreboardObjective && antiOverrideObjectives) {
tab.getFeatureManager().onObjective(player, modifiedPacket);
}
//client reset packet
if (packet instanceof Login) {
if (modifiedPacket instanceof Login) {
//making sure to not send own packets before login packet is actually sent
super.write(context, packet, channelPromise);
super.write(context, modifiedPacket, channelPromise);
tab.getFeatureManager().onLoginPacket(player);
return;
}
@@ -143,5 +140,36 @@ public class BungeePipelineInjector extends PipelineInjector {
}
super.write(context, packet, channelPromise);
}
/**
* Deserializes bytebuf in case it is one of the tracked packets coming from backend server and returns it.
* If the packet is not one of them, returns input
* @param buf - bytebuf to deserialize
* @return deserialized packet or input bytebuf if packet is not tracked
*/
private Object deserialize(ByteBuf buf) {
int marker = buf.readerIndex();
int packetId = buf.readByte();
if (packetId == ((BungeeTabPlayer)player).getPacketId(Team.class)) {
Team team = new Team();
team.read(buf, null, ((ProxiedPlayer)player.getPlayer()).getPendingConnection().getVersion());
buf.release();
return team;
}
if (packetId == ((BungeeTabPlayer)player).getPacketId(ScoreboardDisplay.class)) {
ScoreboardDisplay display = new ScoreboardDisplay();
display.read(buf, null, ((ProxiedPlayer)player.getPlayer()).getPendingConnection().getVersion());
buf.release();
return display;
}
if (packetId == ((BungeeTabPlayer)player).getPacketId(ScoreboardObjective.class)) {
ScoreboardObjective objective = new ScoreboardObjective();
objective.read(buf, null, ((ProxiedPlayer)player.getPlayer()).getPendingConnection().getVersion());
buf.release();
return objective;
}
buf.readerIndex(marker);
return buf;
}
}
}
@@ -42,7 +42,9 @@ public class BungeePlatform implements Platform {
@Override
public PermissionPlugin detectPermissionPlugin() {
if (ProxyServer.getInstance().getPluginManager().getPlugin("LuckPerms") != null) {
if (TAB.getInstance().getConfiguration().bukkitPermissions) {
return new VaultBridge(Main.plm);
} else if (ProxyServer.getInstance().getPluginManager().getPlugin("LuckPerms") != null) {
return new LuckPerms(ProxyServer.getInstance().getPluginManager().getPlugin("LuckPerms").getDescription().getVersion());
} else if (ProxyServer.getInstance().getPluginManager().getPlugin("UltraPermissions") != null) {
return new UltraPermissions(ProxyServer.getInstance().getPluginManager().getPlugin("UltraPermissions").getDescription().getVersion());
@@ -65,7 +65,7 @@ public class BungeeTabPlayer extends ITabPlayer {
@Override
public boolean hasPermission(String permission) {
if (TAB.getInstance().isSupportBukkitPermission()) {
if (TAB.getInstance().getConfiguration().bukkitPermissions) {
String merge = "hasPermission:" + permission;
Main.plm.requestAttribute(this, merge);
if (!attributes.containsKey(merge)) return false;
@@ -1,6 +1,6 @@
# Detailed explanation of all options available at https://github.com/NEZNAMY/TAB/wiki/config.yml
# Used to use bukkit permission management in the case of Bungee or Velocity.
#taking permission nodes and groups from backend servers
use-bukkit-permissions-manager: false
#changing nametags, affecting sorting, collision rule
+1 -5
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>me.neznamy</groupId>
<artifactId>TAB</artifactId>
<version>2.8.11-pre18</version>
<version>2.9.0</version>
</parent>
<artifactId>jar</artifactId>
<build>
@@ -85,10 +85,6 @@
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</exclusion>
<exclusion>
<groupId>com.github.NEZNAMY</groupId>
<artifactId>VelocityInternals</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
+1 -1
View File
@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>me.neznamy</groupId>
<artifactId>TAB</artifactId>
<version>2.8.11-pre18</version>
<version>2.9.0</version>
<packaging>pom</packaging>
<description>An all-in-one solution that works</description>
<modules>
+2 -2
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>me.neznamy</groupId>
<artifactId>TAB</artifactId>
<version>2.8.11-pre18</version>
<version>2.9.0</version>
</parent>
<artifactId>shared</artifactId>
@@ -61,7 +61,7 @@
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.16-R0.5-SNAPSHOT</version>
<version>1.17-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
@@ -108,12 +108,12 @@ public class ErrorManager {
if (file.length() > 1000000) return; //not going over 1 MB
BufferedWriter buf = new BufferedWriter(new FileWriter(file, true));
if (message != null) {
write(buf, "&c[TAB v" + tab.getPluginVersion() + (tab.isPremium() ? " Premium": "") + "] " + message, intoConsoleToo);
write(buf, "&c[TAB v" + tab.getPluginVersion() + (tab.isPremium() ? " Premium": "") + "] ", message.replace('\u00a7', '&'), intoConsoleToo);
}
if (error != null) {
write(buf, "&c" + error.getClass().getName() + ": " + error.getMessage(), intoConsoleToo);
write(buf, "&c", error.getClass().getName() + ": " + error.getMessage(), intoConsoleToo);
for (StackTraceElement ste : error.getStackTrace()) {
write(buf, "&c at " + ste.toString(), intoConsoleToo);
write(buf, "&c at ", ste.toString(), intoConsoleToo);
}
}
buf.close();
@@ -149,9 +149,9 @@ public class ErrorManager {
* @param forceConsole - send into console even without debug mode
* @throws IOException - if IO writer operation fails
*/
private void write(BufferedWriter buf, String message, boolean forceConsole) throws IOException {
buf.write(getCurrentTime() + removeColors(message) + System.getProperty("line.separator"));
if (tab.debugMode || forceConsole) tab.getPlatform().sendConsoleMessage(message, true);
private void write(BufferedWriter buf, String prefix, String message, boolean forceConsole) throws IOException {
buf.write(getCurrentTime() + removeColors(prefix) + message + System.getProperty("line.separator"));
if (tab.debugMode || forceConsole) tab.getPlatform().sendConsoleMessage(prefix.replace('&', '\u00a7') + message, false);
}
/**
@@ -1,5 +1,6 @@
package me.neznamy.tab.shared;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -418,9 +419,13 @@ public abstract class ITabPlayer implements TabPlayer {
sendMessage(scoreboardManager.scoreboard_on, true);
}
if (scoreboardManager.remember_toggle_choice) {
scoreboardManager.sb_off_players.remove(getName());
if (scoreboardManager.hiddenByDefault) {
scoreboardManager.sb_off_players.add(getName());
} else {
scoreboardManager.sb_off_players.remove(getName());
}
synchronized (scoreboardManager.sb_off_players){
TAB.getInstance().getConfiguration().playerdata.set("scoreboard-off", scoreboardManager.sb_off_players);
TAB.getInstance().getConfiguration().playerdata.set("scoreboard-off", new ArrayList<>(scoreboardManager.sb_off_players));
}
}
} else {
@@ -429,9 +434,13 @@ public abstract class ITabPlayer implements TabPlayer {
sendMessage(scoreboardManager.scoreboard_off, true);
}
if (scoreboardManager.remember_toggle_choice) {
scoreboardManager.sb_off_players.add(getName());
TAB.getInstance().getConfiguration().playerdata.set("scoreboard-off", scoreboardManager.sb_off_players);synchronized (scoreboardManager.sb_off_players){
TAB.getInstance().getConfiguration().playerdata.set("scoreboard-off", scoreboardManager.sb_off_players);
if (scoreboardManager.hiddenByDefault) {
scoreboardManager.sb_off_players.remove(getName());
} else {
scoreboardManager.sb_off_players.add(getName());
}
synchronized (scoreboardManager.sb_off_players){
TAB.getInstance().getConfiguration().playerdata.set("scoreboard-off", new ArrayList<>(scoreboardManager.sb_off_players));
}
}
}
@@ -155,7 +155,6 @@ public interface Platform {
*/
public default void loadUniversalFeatures() {
TAB tab = TAB.getInstance();
TAB.getInstance().setSupportBukkitPermission(tab.getConfiguration().config.getBoolean("use-bukkit-permissions-manager", false));
if (tab.getConfiguration().config.getBoolean("enable-header-footer", true)) tab.getFeatureManager().registerFeature("headerfooter", new HeaderFooter(tab));
if (tab.getConfiguration().removeGhostPlayers) tab.getFeatureManager().registerFeature("ghostplayerfix", new GhostPlayerFix());
if (ProtocolVersion.SERVER_VERSION.getMinorVersion() >= 8 && tab.getConfiguration().config.getBoolean("change-tablist-prefix-suffix", true)) {
@@ -70,10 +70,11 @@ public class Property {
* @param temporaryValue - temporary value to be assigned
*/
public void setTemporaryValue(String temporaryValue) {
this.temporaryValue = RGBUtils.getInstance().applyFormats(temporaryValue, true);
if (temporaryValue != null) {
analyze(temporaryValue);
this.temporaryValue = RGBUtils.getInstance().applyFormats(temporaryValue, true);
analyze(this.temporaryValue);
} else {
this.temporaryValue = null;
analyze(rawValue);
}
update();
@@ -188,11 +189,10 @@ public class Property {
* @return format for the viewer
*/
public String getFormat(TabPlayer viewer) {
if (viewer == null) return lastReplacedValue;
String format = lastReplacedValue;
for (String identifier : relPlaceholders) {
RelationalPlaceholder pl = (RelationalPlaceholder) TAB.getInstance().getPlaceholderManager().getPlaceholder(identifier);
if (pl != null) format = format.replace(pl.getIdentifier(), pl.getLastValue(viewer, owner));
if (pl != null) format = format.replace(pl.getIdentifier(), viewer == null ? "" : pl.getLastValue(viewer, owner));
}
return format;
}
@@ -25,7 +25,7 @@ public class TAB {
private static TAB instance;
//version of plugin
public static final String pluginVersion = "2.8.11-pre18";
public static final String pluginVersion = "2.9.0";
//player data
public final Map<UUID, TabPlayer> data = new ConcurrentHashMap<UUID, TabPlayer>();
@@ -33,9 +33,6 @@ public class TAB {
//the command
public TabCommand command;
// Used to use bukkit permission management in the case of Bungee or Velocity.
private boolean supportBukkitPermission;
//command used if plugin is disabled due to a broken configuration file
public final DisabledCommand disabledCommand = new DisabledCommand();
@@ -242,15 +239,7 @@ public class TAB {
public boolean isDisabled() {
return disabled;
}
public void setSupportBukkitPermission(boolean support) {
supportBukkitPermission = support;
}
public boolean isSupportBukkitPermission() {
return supportBukkitPermission;
}
public PlaceholderManager getPlaceholderManager() {
return placeholderManager;
}
@@ -40,6 +40,7 @@ public class Configs {
public boolean removeGhostPlayers;
public boolean layout;
public boolean pipelineInjection;
public boolean bukkitPermissions;
//animations.yml file
public ConfigurationFile animation;
@@ -124,6 +125,9 @@ public class Configs {
removeGhostPlayers = (boolean) getSecretOption("remove-ghost-players", false);
layout = (boolean) getSecretOption("layout", false);
pipelineInjection = (boolean) getSecretOption("pipeline-injection", true);
if (tab.getPlatform().getSeparatorType().equals("server")) {
bukkitPermissions = config.getBoolean("use-bukkit-permissions-manager", false);
}
//checking for unnecessary copypaste in config
Set<Object> groups = config.getConfigurationSection("Groups").keySet();
@@ -48,8 +48,8 @@ public class AlignedSuffix implements QuitEventListener, WorldChangeListener {
}
}
public String formatNameAndUpdateLeader(TabPlayer player, String prefixAndName, String suffix) {
int playerNameWidth = getTextWidth(IChatBaseComponent.fromColoredText(prefixAndName + suffix));
public String formatNameAndUpdateLeader(TabPlayer player, TabPlayer viewer) {
int playerNameWidth = getTextWidth(IChatBaseComponent.fromColoredText(player.getProperty("tabprefix").getFormat(null) + player.getProperty("customtabname").getFormat(null) + player.getProperty("tabsuffix").getFormat(null)));
if (player == maxPlayer && playerNameWidth < maxWidth) {
maxWidth = playerNameWidth;
for (TabPlayer all : tab.getPlayers()) {
@@ -65,7 +65,7 @@ public class AlignedSuffix implements QuitEventListener, WorldChangeListener {
maxPlayer = player;
updateAllNames(player);
}
return formatName(prefixAndName, suffix);
return formatName(player.getProperty("tabprefix").getFormat(viewer) + player.getProperty("customtabname").getFormat(viewer), player.getProperty("tabsuffix").getFormat(viewer));
}
public String formatName(String prefixAndName, String suffix) {
@@ -109,7 +109,7 @@ public class AlignedSuffix implements QuitEventListener, WorldChangeListener {
* @return width of player's tablist name format
*/
private int getPlayerNameWidth(TabPlayer p) {
String format = p.getProperty("tabprefix").get() + p.getProperty("customtabname").get() + p.getProperty("tabsuffix").get();
String format = p.getProperty("tabprefix").getFormat(null) + p.getProperty("customtabname").getFormat(null) + p.getProperty("tabsuffix").getFormat(null);
return getTextWidth(IChatBaseComponent.fromColoredText(format));
}
@@ -123,7 +123,7 @@ public class BelowName implements Loadable, JoinEventListener, WorldChangeListen
}
private int getValue(TabPlayer p) {
return tab.getErrorManager().parseInteger(p.getProperty(numberPropertyName).updateAndGet(), 0, "belowname");
return tab.getErrorManager().parseInteger(p.getProperty(numberPropertyName).updateAndGet(), 0, "belowname number");
}
@Override
@@ -144,7 +144,7 @@ public class Playerlist implements JoinEventListener, Loadable, WorldChangeListe
String format;
AlignedSuffix alignedSuffix = (AlignedSuffix) tab.getFeatureManager().getFeature("alignedsuffix");
if (alignedSuffix != null) {
format = alignedSuffix.formatNameAndUpdateLeader(refreshed, prefix.getFormat(viewer) + name.getFormat(viewer), suffix.getFormat(viewer));
format = alignedSuffix.formatNameAndUpdateLeader(refreshed, viewer);
} else {
format = prefix.getFormat(viewer) + name.getFormat(viewer) + suffix.getFormat(viewer);
}
@@ -13,7 +13,7 @@ import me.neznamy.tab.shared.TAB;
public class UpdateChecker {
//separate field to prevent false flag on pre releases
private final String currentRelease = "2.8.10";
private final String currentRelease = "2.9.0";
public UpdateChecker(TAB tab) {
new Thread(new Runnable() {
@@ -4,9 +4,11 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import me.neznamy.tab.api.TabPlayer;
import me.neznamy.tab.shared.ITabPlayer;
@@ -59,7 +61,7 @@ public class ScoreboardManager implements Loadable, JoinEventListener, QuitEvent
public boolean remember_toggle_choice;
//list of players with disabled scoreboard
public List<String> sb_off_players = Collections.synchronizedList(new ArrayList<String>());
public Set<String> sb_off_players = new HashSet<String>();
//scoreboards registered via API
public List<me.neznamy.tab.api.Scoreboard> APIscoreboards = new ArrayList<>();
@@ -71,7 +73,7 @@ public class ScoreboardManager implements Loadable, JoinEventListener, QuitEvent
public int staticNumber;
//hidden by default, toggle command must be ran to show it
private boolean hiddenByDefault;
public boolean hiddenByDefault;
//scoreboard toggle on message
public String scoreboard_on;
@@ -103,7 +105,7 @@ public class ScoreboardManager implements Loadable, JoinEventListener, QuitEvent
scoreboard_on = tab.getConfiguration().premiumconfig.getString("scoreboard-on", "&2Scorebord enabled");
scoreboard_off = tab.getConfiguration().premiumconfig.getString("scoreboard-off", "&7Scoreboard disabled");
if (remember_toggle_choice) {
sb_off_players = Collections.synchronizedList(new ArrayList<String>(tab.getConfiguration().getPlayerData("scoreboard-off")));
sb_off_players = Collections.synchronizedSet(new HashSet<String>(tab.getConfiguration().getPlayerData("scoreboard-off")));
}
staticNumber = tab.getConfiguration().premiumconfig.getInt("scoreboard.static-number", 0);
joinDelay = tab.getConfiguration().premiumconfig.getInt("scoreboard.delay-on-join-milliseconds", 0);
@@ -154,7 +156,7 @@ public class ScoreboardManager implements Loadable, JoinEventListener, QuitEvent
@Override
public void load() {
for (TabPlayer p : tab.getPlayers()) {
p.setScoreboardVisible(!sb_off_players.contains(p.getName()) && !hiddenByDefault, false);
p.setScoreboardVisible(hiddenByDefault == sb_off_players.contains(p.getName()), false);
}
tab.getCPUManager().startRepeatingMeasuredTask(1000, "refreshing scoreboard conditions", TabFeature.SCOREBOARD, UsageType.REPEATING_TASK, new Runnable() {
public void run() {
@@ -190,11 +192,11 @@ public class ScoreboardManager implements Loadable, JoinEventListener, QuitEvent
joinDelayed.add(p);
tab.getCPUManager().runTaskLater(joinDelay, "processing player join", getFeatureType(), UsageType.PLAYER_JOIN_EVENT, () -> {
if (((ITabPlayer)p).getOtherPluginScoreboard() == null) p.setScoreboardVisible(!sb_off_players.contains(p.getName()) && !hiddenByDefault, false);
if (((ITabPlayer)p).getOtherPluginScoreboard() == null) p.setScoreboardVisible(hiddenByDefault == sb_off_players.contains(p.getName()), false);
joinDelayed.remove(p);
});
} else {
p.setScoreboardVisible(!sb_off_players.contains(p.getName()) && !hiddenByDefault, false);
p.setScoreboardVisible(hiddenByDefault == sb_off_players.contains(p.getName()), false);
}
}
@@ -27,7 +27,7 @@ public class Groups extends SortingType {
if (chars == null) {
chars = String.valueOf(sortedGroups.size()+1);
if (!group.equals("<null>")) {
TAB.getInstance().getErrorManager().oneTimeConsoleError(String.format("Group \"&e%s&c\" is not defined in sorting list! This will result in players in that group not being sorted correctly. To fix this, add group \"&e%s&c\" into &egroup-sorting-priority-list in config.yml&c. Your current list: %s", group, group, sortedGroups.keySet()));
TAB.getInstance().getErrorManager().oneTimeConsoleError(String.format("Group \"%s\" is not defined in sorting list! This will result in players in that group not being sorted correctly. To fix this, add group \"%s\" into &egroup-sorting-priority-list in config.yml. Your current list: %s", group, group, sortedGroups.keySet()));
}
p.setTeamNameNote(p.getTeamNameNote() + "&cPlayer's primary group is not in sorting list. &r");
} else {
@@ -161,6 +161,46 @@ public class IChatBaseComponent {
public boolean isObfuscated(){
return obfuscated == null ? false : obfuscated;
}
/**
* Returns value of bold
* @return value of bold
*/
public Boolean getBold(){
return bold;
}
/**
* Returns value of italic
* @return value of italic
*/
public Boolean getItalic(){
return italic;
}
/**
* Returns value of underlined
* @return value of underlined
*/
public Boolean getUnderlined(){
return underlined;
}
/**
* Returns value of strikethrough
* @return value of strikethrough
*/
public Boolean getStrikethrough(){
return strikethrough;
}
/**
* Returns value of obfuscation
* @return value of obfuscation
*/
public Boolean getObfuscated(){
return obfuscated;
}
/**
* Sets text of this component
@@ -78,15 +78,6 @@ public interface PacketBuilder {
* @throws Exception - when something fails
*/
public Object build(PacketPlayOutScoreboardTeam packet, ProtocolVersion clientVersion) throws Exception;
/**
* Constructs platform-specific PacketPlayOutTitle class based on custom packet class
* @param packet - custom packet to be built
* @param clientVersion - version of client to receive the packet
* @return platform-specific packet
* @throws Exception - when something fails
*/
public Object build(PacketPlayOutTitle packet, ProtocolVersion clientVersion) throws Exception;
/**
* Cuts given string to specified character length (or length-1 if last character is a color character) and translates RGB to legacy colors
@@ -1,124 +0,0 @@
package me.neznamy.tab.shared.packets;
import me.neznamy.tab.shared.ProtocolVersion;
import me.neznamy.tab.shared.TAB;
/**
* A class representing platform specific packet class
*/
public class PacketPlayOutTitle extends UniversalPacketPlayOut {
//packet action
public EnumTitleAction action;
//displayed text
public String text;
//ticks to spend fading in
public int fadeIn;
//ticks to stay
public int stay;
//ticks to spend fading out
public int fadeOut;
/**
* Constructs new instance with all arguments
* @param action - packet action
* @param text - displayed text
* @param fadeIn - ticks to spend fading in
* @param stay - ticks to stay
* @param fadeOut - ticks to spend fading out
*/
private PacketPlayOutTitle(EnumTitleAction action, String text, int fadeIn, int stay, int fadeOut) {
this.action = action;
this.text = text;
this.fadeIn = fadeIn;
this.stay = stay;
this.fadeOut = fadeOut;
}
/**
* Creates new packet with action set to TITLE with given text
* @param text - text to display
* @return Created packet with with TITLE action and given text
*/
public static PacketPlayOutTitle title(String text) {
return new PacketPlayOutTitle(EnumTitleAction.TITLE, text, 0, 0, 0);
}
/**
* Creates new packet with action set to SUBTITLE with given text.
* Note: subtitle only displays after title is sent. If you don't want any title, send a title packet with invisible text such as &r
* @param text - text to display
* @return Created packet with with0 SUBTITLE action and given text
*/
public static PacketPlayOutTitle subtitle(String text) {
return new PacketPlayOutTitle(EnumTitleAction.SUBTITLE, text, 0, 0, 0);
}
/**
* Creates new packet with action set to ACTIONBAR with given text.
* Note: This was added in 1.11
* @param text - text to display
* @return Created packet with with ACTIONBAR action and given text
*/
public static PacketPlayOutTitle actionbar(String text) {
if (ProtocolVersion.SERVER_VERSION.getMinorVersion() < 11) throw new IllegalStateException("Not supported on <1.11");
return new PacketPlayOutTitle(EnumTitleAction.ACTIONBAR, text, 0, 0, 0);
}
/**
* Creates new packet with action set to TIMES with given parameters
* @param fadeIn - ticks to fade in
* @param stay - ticks to stay
* @param fadeOut - ticks to fade out
* @return Created packet with TIMES action and given parameters
*/
public static PacketPlayOutTitle times(int fadeIn, int stay, int fadeOut) {
return new PacketPlayOutTitle(EnumTitleAction.TIMES, null, fadeIn, stay, fadeOut);
}
/**
* Clears current title/subtitle and prevents any new from appearing
* @return Created packet with CLEAR action
*/
public static PacketPlayOutTitle clear() {
return new PacketPlayOutTitle(EnumTitleAction.CLEAR, null, 0, 0, 0);
}
/**
* Resets title times to their original values and makes titles appear again if CLEAR was used before
* @return Created packet with RESET action
*/
public static PacketPlayOutTitle reset() {
return new PacketPlayOutTitle(EnumTitleAction.RESET, null, 0, 0, 0);
}
@Override
protected Object build(ProtocolVersion clientVersion) throws Exception {
return TAB.getInstance().getPacketBuilder().build(this, clientVersion);
}
/**
* An override to toString() method for better output
*/
@Override
public String toString() {
return String.format("PacketPlayOutTitle{action%s,text=%s,fadeIn=%s,stay=%s,fadeOut=%s}", action, text, fadeIn, stay, fadeOut);
}
/**
* List of possible packet actions
*/
public enum EnumTitleAction {
TITLE,
SUBTITLE,
ACTIONBAR,
TIMES,
CLEAR,
RESET;
}
}
@@ -36,25 +36,27 @@ public abstract class Placeholder {
if (!identifier.startsWith("%") || !identifier.endsWith("%")) throw new IllegalArgumentException("Identifier must start and end with %");
this.identifier = identifier;
this.refresh = refresh;
if (TAB.getInstance().getConfiguration().premiumconfig != null) {
Map<Object, Object> original = TAB.getInstance().getConfiguration().premiumconfig.getConfigurationSection("placeholder-output-replacements." + identifier);
for (Entry<Object, Object> entry : original.entrySet()) {
String key = entry.getKey().toString();
String value = entry.getValue().toString();
replacements.put(key.replace('&', '\u00a7'), value);
//snakeyaml converts yes & no to booleans, making them not work when used without "
if (key.equals("true")) {
replacements.put("yes", value);
}
if (key.equals("false")) {
replacements.put("no", value);
}
if (key.equals("else") && value.equals("%value%")) {
TAB.getInstance().print('9', "Hint: Placeholder " + identifier + " has configured \"else\" replacement to %value%, which is default behavior already. You can remove it for cleaner configuration.");
}
for (String id : TAB.getInstance().getPlaceholderManager().detectAll(entry.getValue().toString())) {
if (!outputPlaceholders.contains(id)) outputPlaceholders.add(id);
}
if (TAB.getInstance().isPremium()) loadReplacements();
}
private void loadReplacements() {
Map<Object, Object> original = TAB.getInstance().getConfiguration().premiumconfig.getConfigurationSection("placeholder-output-replacements." + identifier);
for (Entry<Object, Object> entry : original.entrySet()) {
String key = entry.getKey().toString();
String value = entry.getValue().toString();
replacements.put(key.replace('&', '\u00a7'), value);
//snakeyaml converts yes & no to booleans, making them not work when used without "
if (key.equals("true")) {
replacements.put("yes", value);
}
if (key.equals("false")) {
replacements.put("no", value);
}
if (key.equals("else") && value.equals("%value%")) {
TAB.getInstance().print('9', "Hint: Placeholder " + identifier + " has configured \"else\" replacement to %value%, which is default behavior already. You can remove it for cleaner configuration.");
}
for (String id : TAB.getInstance().getPlaceholderManager().detectAll(entry.getValue().toString())) {
if (!outputPlaceholders.contains(id)) outputPlaceholders.add(id);
}
}
}
@@ -2,9 +2,12 @@ package me.neznamy.tab.shared.rgb;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import me.neznamy.tab.shared.TAB;
import me.neznamy.tab.shared.packets.EnumChatFormat;
import me.neznamy.tab.shared.packets.IChatBaseComponent;
import me.neznamy.tab.shared.rgb.format.BukkitFormat;
import me.neznamy.tab.shared.rgb.format.CMIFormat;
import me.neznamy.tab.shared.rgb.format.HtmlFormat;
@@ -29,6 +32,10 @@ public class RGBUtils {
//list of gradient patterns
private Set<GradientPattern> gradients = new HashSet<GradientPattern>();
//TAB's RGB format
private final Pattern tabPattern = Pattern.compile("#[0-9a-fA-F]{6}");
private final Pattern tabPatternLegacy = Pattern.compile("#[0-9a-fA-F]{6}\\|.");
public RGBUtils() {
registerRGBFormatter(new BukkitFormat());
@@ -66,6 +73,28 @@ public class RGBUtils {
return replaced;
}
public String convertToBukkitFormat(String text, boolean rgbClient) {
if (rgbClient) {
//converting random formats to TAB one
String replaced = applyFormats(text, false);
Matcher m = tabPatternLegacy.matcher(replaced);
while (m.find()) {
String hexcode = m.group();
String fixed = "&x&" + hexcode.charAt(1) + "&" + hexcode.charAt(2) + "&" + hexcode.charAt(3) + "&" + hexcode.charAt(4) + "&" + hexcode.charAt(5) + "&" + hexcode.charAt(6);
replaced = replaced.replace(hexcode, fixed.replace('&', '\u00a7'));
}
m = tabPattern.matcher(replaced);
while (m.find()) {
String hexcode = m.group();
String fixed = "&x&" + hexcode.charAt(1) + "&" + hexcode.charAt(2) + "&" + hexcode.charAt(3) + "&" + hexcode.charAt(4) + "&" + hexcode.charAt(5) + "&" + hexcode.charAt(6);
replaced = replaced.replace(hexcode, fixed.replace('&', '\u00a7'));
}
return replaced;
} else {
return IChatBaseComponent.fromColoredText(text).toLegacyText();
}
}
/**
* Registers RGB formatter
* @param formatter - formatter to register
+1 -1
View File
@@ -1,12 +1,12 @@
#sorting type, having premium version automatically overrides sorting options from advancedconfig (if set)
#GROUPS = groups from config.yml, in that order
#GROUP_PERMISSIONS = ^, but players need tab.sort.<group> permission to be considered in that group
#TABPREFIX_A_TO_Z = alphabetically by tabprefix property
#PLACEHOLDER_LOW_TO_HIGH = insert a numeric placeholder below, sorting from lowest value to highest
#PLACEHOLDER_HIGH_TO_LOW = ^, highest to lowest, can be used for some kind of levelling system
#PLACEHOLDER_A_TO_Z = alphabetically by the placeholder
#GROUPS_THEN_PLACEHOLDER_HIGH_TO_LOW = primary sorting by groups, secondary by numeric placeholder (high to low)
#GROUPS_THEN_PLACEHOLDER_LOW_TO_HIGH = primary sorting by groups, secondary by numeric placeholder (low to high)
#... and more
sorting-type: GROUPS
sorting-placeholder: "%some_level_maybe?%"
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<groupId>me.neznamy</groupId>
<artifactId>TAB</artifactId>
<version>2.8.11-pre18</version>
<version>2.9.0</version>
</parent>
<artifactId>velocity-1.1.0</artifactId>
@@ -10,7 +10,6 @@ import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardDisplayObjective;
import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardObjective;
import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardScore;
import me.neznamy.tab.shared.packets.PacketPlayOutScoreboardTeam;
import me.neznamy.tab.shared.packets.PacketPlayOutTitle;
/**
* Packet builder for Velocity platform
@@ -57,11 +56,6 @@ public class VelocityPacketBuilder implements PacketBuilder {
return null;
}
@Override
public Object build(PacketPlayOutTitle packet, ProtocolVersion clientVersion) {
return null;
}
@Override
public PacketPlayOutPlayerInfo readPlayerInfo(Object packet, ProtocolVersion clientVersion) {
return null;
@@ -37,7 +37,9 @@ public class VelocityPlatform implements Platform {
@Override
public PermissionPlugin detectPermissionPlugin() {
if (server.getPluginManager().getPlugin("luckperms").isPresent()) {
if (TAB.getInstance().getConfiguration().bukkitPermissions) {
return new VaultBridge(Main.plm);
} else if (server.getPluginManager().getPlugin("luckperms").isPresent()) {
return new LuckPerms(server.getPluginManager().getPlugin("luckperms").get().getDescription().getVersion().get());
} else {
return new VaultBridge(Main.plm);
@@ -65,7 +65,7 @@ public class VelocityTabPlayer extends ITabPlayer {
@Override
public boolean hasPermission(String permission) {
if (TAB.getInstance().isSupportBukkitPermission()) {
if (TAB.getInstance().getConfiguration().bukkitPermissions) {
String merge = "hasPermission:" + permission;
Main.plm.requestAttribute(this, merge);
if (!attributes.containsKey(merge)) return false;
@@ -105,11 +105,10 @@ public class VelocityTabPlayer extends ITabPlayer {
}
private void handle(PacketPlayOutBoss packet) {
Set<Flag> flags;
Set<Flag> flags = new HashSet<Flag>();
BossBar bar;
switch (packet.operation) {
case ADD:
flags = new HashSet<Flag>();
if (packet.createWorldFog) flags.add(Flag.CREATE_WORLD_FOG);
if (packet.darkenScreen) flags.add(Flag.DARKEN_SCREEN);
if (packet.playMusic) flags.add(Flag.PLAY_BOSS_MUSIC);
@@ -140,7 +139,6 @@ public class VelocityTabPlayer extends ITabPlayer {
player.showBossBar(bar);
break;
case UPDATE_PROPERTIES:
flags = new HashSet<Flag>();
if (packet.createWorldFog) flags.add(Flag.CREATE_WORLD_FOG);
if (packet.darkenScreen) flags.add(Flag.DARKEN_SCREEN);
if (packet.playMusic) flags.add(Flag.PLAY_BOSS_MUSIC);
@@ -1,7 +1,7 @@
# Detailed explanation of all options available at https://github.com/NEZNAMY/TAB/wiki/config.yml
# Used to use bukkit permission management in the case of Bungee or Velocity.
#taking permission nodes and groups from backend servers
use-bukkit-permissions-manager: false
#prefix/suffix in tablist