Skip to content

Commit

Permalink
Merge branch 'v4' into feature/dynamic-dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
diogotcorreia committed Dec 18, 2023
2 parents d0f43f7 + 9219770 commit 535df52
Show file tree
Hide file tree
Showing 15 changed files with 163 additions and 75 deletions.
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ allprojects {
repositories {
mavenLocal()
mavenCentral()
maven {
name 'diogotcRepositorySnapshots'
url 'https://repo.diogotc.com/snapshots/'
}
maven {
url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
content {
Expand All @@ -32,10 +36,6 @@ allprojects {
name 'velocity'
url 'https://nexus.velocitypowered.com/repository/maven-public/'
}
maven {
name 'diogotcRepositorySnapshots'
url 'https://repo.diogotc.com/snapshots/'
}
maven {
// Mirror other people's repositories
name 'diogotcRepositoryMirror'
Expand Down
2 changes: 1 addition & 1 deletion triton-spigot/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ dependencies {
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.11.0'
compileOnly 'net.kyori:adventure-text-serializer-bungeecord:4.1.2'

compileOnly 'com.comphenix.protocol:ProtocolLib:5.1.1-SNAPSHOT'
compileOnly 'com.comphenix.protocol:ProtocolLib:5.2.0-SNAPSHOT'
compileOnly 'me.clip:placeholderapi:2.11.1'

// Libraries available on Spigot
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.rexcantor64.triton.spigot;

import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.rexcantor64.triton.Triton;
import com.rexcantor64.triton.api.players.LanguagePlayer;
import com.rexcantor64.triton.player.PlayerManager;
Expand Down Expand Up @@ -114,7 +115,7 @@ public void onEnable() {
}

if (getConfig().isBungeecord()) {
if (!isSpigotProxyMode()) {
if (!isSpigotProxyMode() && !isPaperProxyMode()) {
getLogger().logError("DANGER! DANGER! DANGER!");
getLogger().logError("Proxy mode is enabled on Triton but disabled on Spigot!");
getLogger().logError("A malicious player can run ANY command as the server.");
Expand Down Expand Up @@ -168,7 +169,7 @@ protected void startConfigRefreshTask() {
/**
* Checks if ProtocolLib is enabled and if its version matches
* the expected version.
* Triton requires ProtocolLib 5.1.0 or later.
* Triton requires ProtocolLib 5.2.0 or later.
*
* @return Whether the plugin should continue loading
* @since 3.8.2
Expand All @@ -185,13 +186,11 @@ private boolean isProtocolLibAvailable() {
return true;
}

val version = protocolLib.getDescription().getVersion();
val versionParts = version.split("\\.");
val majorVersion = Integer.parseInt(versionParts[0]);
val minorVersion = Integer.parseInt(versionParts[1]);
if (majorVersion < 5 || (majorVersion == 5 && minorVersion < 1)) {
// Triton requires ProtocolLib 5.1.0 or later
getLogger().logError("ProtocolLib 5.1.0 or later is required! Older versions of ProtocolLib will only partially work, and are therefore not recommended.");
try {
MinecraftVersion ignore = MinecraftVersion.v1_20_4;
} catch (NoSuchFieldError ignore) {
// Triton requires ProtocolLib 5.2.0 or later
getLogger().logError("ProtocolLib 5.2.0 or later is required! Older versions of ProtocolLib will only partially work or not work at all, and are therefore not recommended.");
getLogger().logError("If you want to enable the plugin anyway, add `i-know-what-i-am-doing: true` to Triton's config.yml.");
return false;
}
Expand Down Expand Up @@ -302,4 +301,27 @@ public boolean isSpigotProxyMode() {
return false;
}
}

/**
* Use reflection to check if this Paper server has velocity modern forwarding enabled on paper-global.yml.
* This is used to show a warning if Paper is in proxy mode, but the server is not.
*
* @return Whether this Spigot server has velocity forwarding enabled on paper-global.yml.
*/
public boolean isPaperProxyMode() {
try {
Class<?> paperConfigClass = Class.forName("io.papermc.paper.configuration.GlobalConfiguration");

Object instance = paperConfigClass.getMethod("get").invoke(null);
Object proxies = instance.getClass().getField("proxies").get(instance);
Object velocity = proxies.getClass().getField("velocity").get(proxies);
Object velocityEnabled = velocity.getClass().getField("enabled").get(velocity);
if (velocityEnabled == null) {
return false;
}
return (boolean) velocityEnabled;
} catch (Exception e) {
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,14 @@ public class ProtocolLibListener implements PacketListener {
private final Class<BaseComponent[]> BASE_COMPONENT_ARRAY_CLASS = BaseComponent[].class;
private StructureModifier<Object> SCOREBOARD_TEAM_METADATA_MODIFIER = null;
private final Class<Component> ADVENTURE_COMPONENT_CLASS = Component.class;
private final Optional<Class<?>> NUMBER_FORMAT_CLASS;
private final Field PLAYER_ACTIVE_CONTAINER_FIELD;
private final String MERCHANT_RECIPE_SPECIAL_PRICE_FIELD;
private final String MERCHANT_RECIPE_DEMAND_FIELD;

private final HandlerFunction ASYNC_PASSTHROUGH = asAsync((_packet, _player) -> {
});

private final SignPacketHandler signPacketHandler = new SignPacketHandler();
private final AdvancementsPacketHandler advancementsPacketHandler = AdvancementsPacketHandler.newInstance();
private final EntitiesPacketHandler entitiesPacketHandler = new EntitiesPacketHandler();
Expand Down Expand Up @@ -110,6 +114,7 @@ public ProtocolLibListener(SpigotTriton main, HandlerFunction.HandlerType... all
ReflectionUtils.getClass("net.minecraft.world.inventory.ContainerPlayer") :
NMSUtils.getNMSClass("ContainerPlayer");
BOSSBAR_UPDATE_TITLE_ACTION_CLASS = main.getMcVersion() >= 17 ? ReflectionUtils.getClass("net.minecraft.network.protocol.game.PacketPlayOutBoss$e") : null;
NUMBER_FORMAT_CLASS = MinecraftReflection.getOptionalNMS("network.chat.numbers.NumberFormat");

MERCHANT_RECIPE_SPECIAL_PRICE_FIELD = getMCVersion() >= 17 ? "g" : "specialPrice";
MERCHANT_RECIPE_DEMAND_FIELD = getMCVersion() >= 17 ? "h" : "demand";
Expand Down Expand Up @@ -161,6 +166,12 @@ private void setupPacketHandlers() {
// It allows unlimited length team prefixes and suffixes
packetHandlers.put(PacketType.Play.Server.SCOREBOARD_TEAM, asAsync(this::handleScoreboardTeam));
packetHandlers.put(PacketType.Play.Server.SCOREBOARD_OBJECTIVE, asAsync(this::handleScoreboardObjective));
// Register the packets below so their order is kept between all scoreboard packets
packetHandlers.put(PacketType.Play.Server.SCOREBOARD_DISPLAY_OBJECTIVE, ASYNC_PASSTHROUGH);
packetHandlers.put(PacketType.Play.Server.SCOREBOARD_SCORE, ASYNC_PASSTHROUGH);
if (MinecraftVersion.v1_20_4.atOrAbove()) {
packetHandlers.put(PacketType.Play.Server.RESET_SCORE, ASYNC_PASSTHROUGH);
}
}
packetHandlers.put(PacketType.Play.Server.WINDOW_ITEMS, asAsync(this::handleWindowItems));
packetHandlers.put(PacketType.Play.Server.SET_SLOT, asAsync(this::handleSetSlot));
Expand Down Expand Up @@ -276,13 +287,16 @@ private void handleSystemChat(PacketEvent packet, SpigotLanguagePlayer languageP
if ((ab && !main.getConfig().isActionbars()) || (!ab && !main.getConfig().isChat())) return;

val stringModifier = packet.getPacket().getStrings();
val chatModifier = packet.getPacket().getChatComponents();

Component message = null;

val adventureModifier = packet.getPacket().getSpecificModifier(ADVENTURE_COMPONENT_CLASS);

if (adventureModifier.readSafely(0) != null) {
message = adventureModifier.readSafely(0);
} else if (chatModifier.readSafely(0) != null) {
message = WrappedComponentUtils.deserialize(chatModifier.readSafely(0));
} else {
val msgJson = stringModifier.readSafely(0);
if (msgJson != null) {
Expand All @@ -306,6 +320,9 @@ private void handleSystemChat(PacketEvent packet, SpigotLanguagePlayer languageP
if (adventureModifier.size() > 0) {
// On a Paper or fork, so we can directly set the Adventure Component
adventureModifier.writeSafely(0, result);
} else if (chatModifier.size() > 0) {
// Starting on MC 1.20.3 this packet takes a chat component instead of a json string
chatModifier.writeSafely(0, WrappedComponentUtils.serialize(result));
} else {
stringModifier.writeSafely(0, ComponentUtils.serializeToJson(result));
}
Expand Down Expand Up @@ -721,8 +738,11 @@ private void handleScoreboardObjective(PacketEvent packet, SpigotLanguagePlayer

val healthDisplay = packet.getPacket().getModifier().readSafely(2);
val displayName = chatComponentsModifier.readSafely(0);
val numberFormat = NUMBER_FORMAT_CLASS
.map(numberFormatClass -> packet.getPacket().getSpecificModifier(numberFormatClass).readSafely(0))
.orElse(null);

languagePlayer.setScoreboardObjective(objectiveName, displayName.getJson(), healthDisplay);
languagePlayer.setScoreboardObjective(objectiveName, displayName.getJson(), healthDisplay, numberFormat);

parser()
.translateComponent(
Expand Down Expand Up @@ -815,9 +835,12 @@ public ListeningWhitelist getSendingWhitelist() {
@Override
public ListeningWhitelist getReceivingWhitelist() {
val types = new ArrayList<PacketType>();
types.add(PacketType.Play.Client.SETTINGS);
if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { // MC 1.20.2
types.add(PacketType.Configuration.Client.CLIENT_INFORMATION);
if (this.allowedTypes.contains(HandlerFunction.HandlerType.SYNC)) {
// only listen for these packets in the sync handler
types.add(PacketType.Play.Client.SETTINGS);
if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) { // MC 1.20.2
types.add(PacketType.Configuration.Client.CLIENT_INFORMATION);
}
}

return ListeningWhitelist.newBuilder()
Expand Down Expand Up @@ -891,6 +914,9 @@ public void refreshScoreboard(SpigotLanguagePlayer player) {
packet.getStrings().writeSafely(0, key);
packet.getChatComponents().writeSafely(0, WrappedChatComponent.fromJson(value.getChatJson()));
packet.getModifier().writeSafely(2, value.getType());
NUMBER_FORMAT_CLASS.ifPresent(numberFormatClass ->
packet.getSpecificModifier((Class<Object>) numberFormatClass)
.writeSafely(0, value.getNumberFormat()));
ProtocolLibrary.getProtocolManager().sendServerPacket(bukkitPlayer, packet, true);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ public SpigotLanguagePlayer(UUID p) {
load();
}

public void setScoreboardObjective(String name, String chatJson, Object type) {
public void setScoreboardObjective(String name, String chatJson, Object type, Object numberFormat) {
ScoreboardObjective objective = this.objectivesMap.computeIfAbsent(name, k -> new ScoreboardObjective());
objective.setChatJson(chatJson);
objective.setType(type);
objective.setNumberFormat(numberFormat);
}

public void removeScoreboardObjective(String name) {
Expand Down Expand Up @@ -271,6 +272,7 @@ public String toString() {
public static class ScoreboardObjective {
private String chatJson;
private Object type;
private Object numberFormat;
}

@Data
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package com.rexcantor64.triton.spigot.wrappers;

import com.comphenix.protocol.reflect.EquivalentConverter;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.comphenix.protocol.wrappers.AbstractWrapper;
import com.comphenix.protocol.wrappers.BukkitConverters;
import com.comphenix.protocol.wrappers.Converters;
import com.comphenix.protocol.wrappers.WrappedChatComponent;

import java.util.Optional;

/**
* Custom ProtocolLib Wrapper of NMS' AdvancementDisplay
*/
Expand All @@ -19,19 +23,20 @@ public class WrappedAdvancementDisplay extends AbstractWrapper {
private static Class<?> ADVANCEMENT_FRAME_TYPE_CLASS = MinecraftReflection.getMinecraftClass("advancements.AdvancementFrameType", "AdvancementFrameType");
private static ConstructorAccessor ADVANCEMENT_DISPLAY_CONSTRUTOR = Accessors.getConstructorAccessor(
ADVANCEMENT_DISPLAY,
MinecraftReflection.getItemStackClass(),
MinecraftReflection.getIChatBaseComponentClass(),
MinecraftReflection.getIChatBaseComponentClass(),
MinecraftReflection.getMinecraftKeyClass(),
ADVANCEMENT_FRAME_TYPE_CLASS,
boolean.class,
boolean.class,
boolean.class);
MinecraftReflection.getItemStackClass(), // icon
MinecraftReflection.getIChatBaseComponentClass(), // title
MinecraftReflection.getIChatBaseComponentClass(), // description
MinecraftVersion.v1_20_4.atOrAbove() ? Optional.class : MinecraftReflection.getMinecraftKeyClass(), // background
ADVANCEMENT_FRAME_TYPE_CLASS, // frame
boolean.class, // showToast
boolean.class, // announceToChat
boolean.class // hidden
);
private static FieldAccessor[] CHAT_COMPONENTS = Accessors.getFieldAccessorArray(ADVANCEMENT_DISPLAY, MinecraftReflection.getIChatBaseComponentClass(), true);
private static FieldAccessor TITLE = CHAT_COMPONENTS[0];
private static FieldAccessor DESCRIPTION = CHAT_COMPONENTS[1];
private static FieldAccessor ITEM_STACK = Accessors.getFieldAccessor(ADVANCEMENT_DISPLAY, MinecraftReflection.getItemStackClass(), true);
private static FieldAccessor MINECRAFT_KEY = Accessors.getFieldAccessor(ADVANCEMENT_DISPLAY, MinecraftReflection.getMinecraftKeyClass(), true);
private static FieldAccessor MINECRAFT_KEY;
private static FieldAccessor ADVANCEMENT_FRAME_TYPE = Accessors.getFieldAccessor(ADVANCEMENT_DISPLAY, ADVANCEMENT_FRAME_TYPE_CLASS, true);
private static FieldAccessor[] BOOLEANS = Accessors.getFieldAccessorArray(ADVANCEMENT_DISPLAY, boolean.class, true);
private static FieldAccessor SHOW_TOAST = BOOLEANS[0];
Expand All @@ -47,6 +52,15 @@ public class WrappedAdvancementDisplay extends AbstractWrapper {

private boolean hasChanged = false;

static {
if (MinecraftVersion.v1_20_4.atOrAbove()) {
FuzzyReflection fuzzyReflection = FuzzyReflection.fromClass(ADVANCEMENT_DISPLAY, true);
MINECRAFT_KEY = Accessors.getFieldAccessor(fuzzyReflection.getParameterizedField(Optional.class, MinecraftReflection.getMinecraftKeyClass()));
} else {
MINECRAFT_KEY = Accessors.getFieldAccessor(ADVANCEMENT_DISPLAY, MinecraftReflection.getMinecraftKeyClass(), true);
}
}

/**
* Construct a new AdvancementDisplay wrapper.
*/
Expand Down Expand Up @@ -81,14 +95,14 @@ public boolean hasChangedAndReset() {

public WrappedAdvancementDisplay shallowClone() {
Object newInstance = ADVANCEMENT_DISPLAY_CONSTRUTOR.invoke(
ITEM_STACK.get(handle),
TITLE.get(handle),
DESCRIPTION.get(handle),
MINECRAFT_KEY.get(handle),
ADVANCEMENT_FRAME_TYPE.get(handle),
SHOW_TOAST.get(handle),
ANNOUNCE_TO_CHAT.get(handle),
HIDDEN.get(handle)
ITEM_STACK.get(handle),
TITLE.get(handle),
DESCRIPTION.get(handle),
MINECRAFT_KEY.get(handle),
ADVANCEMENT_FRAME_TYPE.get(handle),
SHOW_TOAST.get(handle),
ANNOUNCE_TO_CHAT.get(handle),
HIDDEN.get(handle)
);
X_CORD.set(newInstance, X_CORD.get(handle));
Y_CORD.set(newInstance, Y_CORD.get(handle));
Expand All @@ -98,6 +112,7 @@ public WrappedAdvancementDisplay shallowClone() {

/**
* Construct a wrapped advancement display from a native NMS object.
*
* @param handle - the native object.
* @return The wrapped advancement display object.
*/
Expand Down
4 changes: 2 additions & 2 deletions triton-velocity/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ dependencies {
compileOnly project(path: ":api")
compileOnly project(path: ":core")

annotationProcessor 'com.velocitypowered:velocity-api:3.1.0'
annotationProcessor 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'

compileOnly 'com.velocitypowered:velocity-proxy:3.2.0-SNAPSHOT'
compileOnly 'com.velocitypowered:velocity-proxy:3.3.0-SNAPSHOT'

compileOnly 'io.netty:netty-codec:4.1.80.Final'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import com.rexcantor64.triton.Triton;
import com.rexcantor64.triton.api.config.FeatureSyntax;
import com.rexcantor64.triton.api.language.MessageParser;
import com.rexcantor64.triton.velocity.utils.ComponentUtils;
import com.rexcantor64.triton.velocity.player.VelocityLanguagePlayer;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packet.BossBar;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import lombok.val;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -44,16 +44,16 @@ private FeatureSyntax getBossBarSyntax() {

val text = bossBarPacket.getName();
if (text != null && (action == BossBar.ADD || action == BossBar.UPDATE_NAME)) {
player.setBossbar(uuid, bossBarPacket.getName());
player.setBossbar(uuid, bossBarPacket.getName().getComponent());

parser()
.translateComponent(
ComponentUtils.deserializeFromJson(bossBarPacket.getName(), player.getProtocolVersion()),
bossBarPacket.getName().getComponent(),
player,
getBossBarSyntax()
)
.getResultOrToRemove(Component::empty)
.map(result -> ComponentUtils.serializeToJson(result, player.getProtocolVersion()))
.map(result -> new ComponentHolder(player.getProtocolVersion(), result))
.ifPresent(bossBarPacket::setName);
}
return Optional.of(bossBarPacket);
Expand Down
Loading

0 comments on commit 535df52

Please sign in to comment.