Skip to content

Commit

Permalink
1.17 support
Browse files Browse the repository at this point in the history
  • Loading branch information
linsaftw committed Oct 6, 2021
1 parent 9e1b93e commit 697046c
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 77 deletions.
12 changes: 7 additions & 5 deletions src/dev/_2lstudios/hamsterapi/HamsterAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ public static synchronized HamsterAPI getInstance() {
}

private static String getVersion(Server server) {
final String packageName = server.getClass().getPackage().getName();
return packageName.substring(packageName.lastIndexOf('.') + 1);
}
final String packageName = server.getClass().getPackage().getName();
return packageName.substring(packageName.lastIndexOf('.') + 1);
}

private void initialize() {
final Server server = getServer();
Expand Down Expand Up @@ -77,7 +77,7 @@ public void onEnable() {
pluginManager.registerEvents(new PlayerQuitListener(hamsterPlayerManager), this);

for (final Player player : server.getOnlinePlayers()) {
final HamsterPlayer hamsterPlayer = this.hamsterPlayerManager.get(player);
final HamsterPlayer hamsterPlayer = this.hamsterPlayerManager.add(player);

hamsterPlayer.tryInject();
}
Expand All @@ -92,7 +92,9 @@ public void onDisable() {
for (final Player player : server.getOnlinePlayers()) {
final HamsterPlayer hamsterPlayer = this.hamsterPlayerManager.get(player);

hamsterPlayer.uninject();
if (hamsterPlayer != null) {
hamsterPlayer.uninject();
}

this.hamsterPlayerManager.remove(player);
}
Expand Down
134 changes: 89 additions & 45 deletions src/dev/_2lstudios/hamsterapi/hamsterplayer/HamsterPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.channels.ClosedChannelException;
import java.util.UUID;

import org.bukkit.Server;
import org.bukkit.entity.Player;
Expand Down Expand Up @@ -39,50 +40,93 @@ public Player getPlayer() {
return this.player;
}

// Sends an ActionBar to the HamsterPlayer
public void sendActionbar(final String text) {
public void sendActionbarPacketOld(final String text) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchMethodException, SecurityException {
final Reflection reflection = hamsterAPI.getReflection();
final Object chatAction = toChatBaseComponent.invoke(null, "{ \"text\":\"" + text + "\" }");
final Object packet = reflection.getPacketPlayOutChat().getConstructor(iChatBaseComponentClass, byte.class)
.newInstance(chatAction, (byte) 2);

try {
Object chatAction = toChatBaseComponent.invoke(null, "{ \"text\":\"" + text + "\" }");
Object packet = reflection.getNMSClass("PacketPlayOutChat")
.getConstructor(iChatBaseComponentClass, byte.class).newInstance(chatAction, (byte) 2);
sendPacket(packet);
}

sendPacket(packet);
} catch (final Exception e) {
e.printStackTrace();
public void sendActionbarPacketNew(final String text) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchMethodException, SecurityException {
final Reflection reflection = hamsterAPI.getReflection();
final Object chatAction = toChatBaseComponent.invoke(null, "{ \"text\":\"" + text + "\" }");
final Class<?> chatMessageTypeClass = reflection.getChatMessageType();
final Object[] enumConstants = chatMessageTypeClass.getEnumConstants();
final Object packet = reflection.getPacketPlayOutChat()
.getConstructor(iChatBaseComponentClass, chatMessageTypeClass, UUID.class).newInstance(chatAction, enumConstants[2], player.getUniqueId());

sendPacket(packet);
}

// Sends an ActionBar to the HamsterPlayer
public void sendActionbar(final String text) {
try {
sendActionbarPacketNew(text);
} catch (final Exception e1) {
try {
sendActionbarPacketOld(text);
} catch (final Exception e2) {
hamsterAPI.getLogger().info("Failed to send actionbar packet to player " + player.getName() + "!");
}
}
}

// Sends a Title to the HamsterPlayer
public void sendTitle(String title, String subtitle, int fadeInTime, int showTime, int fadeOutTime) {
public void sendTitlePacketOld(final String title, final String subtitle, final int fadeInTime, final int showTime, final int fadeOutTime)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
SecurityException, InstantiationException, NoSuchFieldException {
final Reflection reflection = hamsterAPI.getReflection();

try {
Object chatTitle = toChatBaseComponent.invoke(null, "{ \"text\":\"" + title + "\" }");
Constructor<?> titleConstructor = reflection.getNMSClass("PacketPlayOutTitle").getConstructor(
reflection.getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], iChatBaseComponentClass,
int.class, int.class, int.class);

Object packet = titleConstructor
.newInstance(reflection.getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0]
.getDeclaredField("TITLE").get(null), chatTitle, fadeInTime, showTime, fadeOutTime);

Object chatSubTitle = toChatBaseComponent.invoke(null, "{ \"text\":\"" + subtitle + "\" }");
Constructor<?> timingTitleConstructor = reflection.getNMSClass("PacketPlayOutTitle").getConstructor(
reflection.getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], iChatBaseComponentClass,
int.class, int.class, int.class);

Object timingPacket = timingTitleConstructor
.newInstance(
reflection.getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0]
.getDeclaredField("SUBTITLE").get(null),
chatSubTitle, fadeInTime, showTime, fadeOutTime);
final Object chatTitle = toChatBaseComponent.invoke(null, "{ \"text\":\"" + title + "\" }");
final Object chatSubTitle = toChatBaseComponent.invoke(null, "{ \"text\":\"" + subtitle + "\" }");
final Class<?> enumTitleActionClass = reflection.getPacketPlayOutTitle().getDeclaredClasses()[0];
final Constructor<?> titleConstructor = reflection.getPacketPlayOutTitle().getConstructor(enumTitleActionClass,
iChatBaseComponentClass, int.class, int.class, int.class);
final Object titlePacket = titleConstructor.newInstance(enumTitleActionClass.getDeclaredField("TITLE").get(null),
chatTitle, fadeInTime, showTime, fadeOutTime);
final Object subtitlePacket = titleConstructor.newInstance(
enumTitleActionClass.getDeclaredField("SUBTITLE").get(null), chatSubTitle, fadeInTime, showTime,
fadeOutTime);

sendPacket(titlePacket);
sendPacket(subtitlePacket);
}

sendPacket(packet);
sendPacket(timingPacket);
} catch (Exception e) {
e.printStackTrace();
public void sendTitlePacketNew(final String title, final String subtitle, final int fadeInTime, final int showTime, final int fadeOutTime)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
SecurityException, InstantiationException, NoSuchFieldException {
final Reflection reflection = hamsterAPI.getReflection();

final Constructor<?> timingTitleConstructor = reflection.getClientboundSetTitlesAnimationPacket()
.getConstructor(int.class, int.class, int.class);
final Object timingPacket = timingTitleConstructor.newInstance(fadeInTime, showTime, fadeOutTime);

final Object chatTitle = toChatBaseComponent.invoke(null, "{ \"text\":\"" + title + "\" }");
final Constructor<?> titleConstructor = reflection.getClientboundSetTitleTextPacket()
.getConstructor(iChatBaseComponentClass);
final Object titlePacket = titleConstructor.newInstance(chatTitle);

final Object chatSubTitle = toChatBaseComponent.invoke(null, "{ \"text\":\"" + subtitle + "\" }");
final Constructor<?> subTitleConstructor = reflection.getClientboundSetSubtitleTextPacket()
.getConstructor(iChatBaseComponentClass);
final Object subTitlePacket = subTitleConstructor.newInstance(chatSubTitle);

sendPacket(timingPacket);
sendPacket(titlePacket);
sendPacket(subTitlePacket);
}

// Sends a Title to the HamsterPlayer
public void sendTitle(final String title, final String subtitle, final int fadeInTime, final int showTime, final int fadeOutTime) {
try {
sendTitlePacketNew(title, subtitle, fadeInTime, showTime, fadeOutTime);
} catch (final Exception e1) {
try {
sendTitlePacketOld(title, subtitle, fadeInTime, showTime, fadeOutTime);
} catch (final Exception e2) {
hamsterAPI.getLogger().info("Failed to send title packet to player " + player.getName() + "!");
}
}
}

Expand All @@ -107,12 +151,12 @@ public void disconnect(final String reason) {

try {
final Object chatKick = toChatBaseComponent.invoke(null, "{ \"text\":\"" + reason + "\" }");
final Object packet = reflection.getNMSClass("PacketPlayOutKickDisconnect")
.getConstructor(iChatBaseComponentClass).newInstance(chatKick);
final Object packet = reflection.getPacketPlayOutKickDisconnect().getConstructor(iChatBaseComponentClass)
.newInstance(chatKick);

sendPacket(packet);
} catch (final Exception e) {
e.printStackTrace();
hamsterAPI.getLogger().info("Failed to send disconnect packet to player " + player.getName() + "!");
}

hamsterAPI.getBungeeMessenger().sendPluginMessage("kickPlayer", player.getName(), reason);
Expand All @@ -128,7 +172,7 @@ public void sendPacket(final Object packet) {
try {
sendPacketMethod.invoke(playerConnection, packet);
} catch (final Exception e) {
e.printStackTrace();
hamsterAPI.getLogger().info("Failed to send packet to player " + player.getName() + "!");
}
}

Expand Down Expand Up @@ -166,12 +210,12 @@ public void setup()
final Reflection reflection = hamsterAPI.getReflection();
final Object handler = player.getClass().getDeclaredMethod("getHandle").invoke(player);

this.playerConnection = reflection.getField(handler, "playerConnection");
this.networkManager = reflection.getField(playerConnection, "networkManager");
this.channel = (Channel) reflection.getField(networkManager, "channel");
this.iChatBaseComponentClass = reflection.getNMSClass("IChatBaseComponent");
this.playerConnection = reflection.getField(handler, reflection.getPlayerConnection());
this.networkManager = reflection.getField(playerConnection, reflection.getNetworkManager());
this.channel = (Channel) reflection.getField(networkManager, Channel.class);
this.iChatBaseComponentClass = reflection.getIChatBaseComponent();
this.sendPacketMethod = this.playerConnection.getClass().getDeclaredMethod("sendPacket",
reflection.getNMSClass("Packet"));
reflection.getPacket());
this.toChatBaseComponent = iChatBaseComponentClass.getDeclaredClasses()[0].getDeclaredMethod("a",
String.class);
this.setup = true;
Expand Down Expand Up @@ -208,7 +252,7 @@ public void inject() throws IllegalAccessException, InvocationTargetException, N
"No ChannelHandler was found on the pipeline to inject " + hamsterChannelHandler);
}

this.injected = true;
this.injected = true;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.logging.Logger;

import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
Expand Down
4 changes: 2 additions & 2 deletions src/dev/_2lstudios/hamsterapi/messengers/BungeeMessenger.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import org.bukkit.plugin.Plugin;

import dev._2lstudios.hamsterapi.HamsterAPI;
import dev._2lstudios.hamsterapi.utils.Utilities;
import dev._2lstudios.hamsterapi.utils.BukkitUtils;

public class BungeeMessenger {
private final HamsterAPI instance;
Expand All @@ -17,7 +17,7 @@ public BungeeMessenger(final HamsterAPI instance) {
}

public void sendPluginMessage(final String subChannel, final String... args) {
final Player messenger = Utilities.getRandomPlayer();
final Player messenger = BukkitUtils.getRandomPlayer();

if (messenger != null) {
final ByteArrayDataOutput out = ByteStreams.newDataOutput();
Expand Down
8 changes: 4 additions & 4 deletions src/dev/_2lstudios/hamsterapi/utils/BufferIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ public class BufferIO {
private final int compressionThreshold;

public BufferIO(final Reflection reflection, final String bukkitVersion, final int compressionThreshold) {
this.packetDataSerializerClass = reflection.getNMSClass("PacketDataSerializer");
this.networkManagerClass = reflection.getNMSClass("NetworkManager");
this.enumProtocolClass = reflection.getNMSClass("EnumProtocol");
this.enumProtocolDirectionClass = reflection.getNMSClass("EnumProtocolDirection");
this.packetDataSerializerClass = reflection.getPacketDataSerializer();
this.networkManagerClass = reflection.getNetworkManager();
this.enumProtocolClass = reflection.getEnumProtocol();
this.enumProtocolDirectionClass = reflection.getEnumProtocolDirection();
this.inflater = new Inflater();
this.bukkitVersion = Integer.parseInt(bukkitVersion);
this.compressionThreshold = compressionThreshold;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

public class Utilities {
public class BukkitUtils {
public static Player getRandomPlayer() {
final Collection<? extends Player> players = Bukkit.getServer().getOnlinePlayers();

Expand Down
Loading

1 comment on commit 697046c

@linsaftw
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested on spigot 1.8 & 1.17

Please sign in to comment.