Skip to content

Commit

Permalink
Add integration with text
Browse files Browse the repository at this point in the history
  • Loading branch information
lucko committed Oct 8, 2017
1 parent 399fbf2 commit 01f85f6
Show file tree
Hide file tree
Showing 5 changed files with 365 additions and 1 deletion.
29 changes: 28 additions & 1 deletion helper/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<artifactId>helper</artifactId>
<packaging>jar</packaging>
<version>3.1.2</version>
<version>3.1.3</version>

<name>helper</name>
<description>A utility to reduce boilerplate code in Bukkit plugins.</description>
Expand Down Expand Up @@ -79,6 +79,7 @@
<includes>
<include>com.flowpowered:flow-math</include>
<include>co.aikar:minecraft-timings</include>
<include>net.kyori:text</include>
<include>ninja.leaping.configurate:configurate-core</include>
<include>ninja.leaping.configurate:configurate-yaml</include>
<include>ninja.leaping.configurate:configurate-gson</include>
Expand All @@ -99,6 +100,10 @@
<pattern>com.typesafe.config</pattern>
<shadedPattern>${shade.pattern}hocon</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori.text</pattern>
<shadedPattern>me.lucko.helper.text</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
Expand Down Expand Up @@ -220,6 +225,28 @@
</exclusion>
</exclusions>
</dependency>
<!-- text -->
<dependency>
<groupId>net.kyori</groupId>
<artifactId>text</artifactId>
<version>1.11-1.3.0</version>
<scope>compile</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</exclusion>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- timings -->
<dependency>
<groupId>co.aikar</groupId>
Expand Down
28 changes: 28 additions & 0 deletions helper/src/main/java/me/lucko/helper/Events.java
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,34 @@ public static void callSync(Event event) {
Scheduler.runSync(() -> call(event));
}

/**
* Submit the event on the current thread
*
* @param event the event to call
*/
public static <T extends Event> T callAndReturn(T event) {
Helper.plugins().callEvent(event);
return event;
}

/**
* Submit the event on a new async thread.
*
* @param event the event to call
*/
public static <T extends Event> T callAsyncAndJoin(T event) {
return Scheduler.supplyAsync(() -> callAndReturn(event)).join();
}

/**
* Submit the event on the main server thread.
*
* @param event the event to call
*/
public static <T extends Event> T callSyncAndJoin(T event) {
return Scheduler.supplySync(() -> callAndReturn(event)).join();
}

/**
* Responsible for the handling of a given event
*
Expand Down
143 changes: 143 additions & 0 deletions helper/src/main/java/me/lucko/helper/text/BukkitTextUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* This file is part of helper, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <[email protected]>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package me.lucko.helper.text;

import me.lucko.helper.utils.NmsUtil;

import net.kyori.text.Component;
import net.kyori.text.serializer.ComponentSerializers;

import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
* Utility for sending JSON components to players.
*
* @author https://github.com/lucko/LuckPerms/blob/master/bukkit/src/main/java/me/lucko/luckperms/bukkit/compat/BukkitJsonMessageHandler.java
*/
class BukkitTextUtils {

private static final boolean CHAT_COMPATIBLE = !NmsUtil.getServerVersion().startsWith("v1_7_");

private static boolean setup = false;
private static boolean triedAndFailed = false;

private static Method GET_HANDLE_METHOD;
private static Field PLAYER_CONNECTION_FIELD;
private static Method SEND_PACKET_METHOD;
private static Constructor<?> PACKET_CHAT_CONSTRUCTOR;
private static Method SERIALIZE_METHOD;

private static void setup(Object player) throws Exception {
Class<?> craftPlayerClass = player.getClass();
GET_HANDLE_METHOD = craftPlayerClass.getDeclaredMethod("getHandle");

Object handleObject = GET_HANDLE_METHOD.invoke(player);
Class<?> handleClass = handleObject.getClass();

PLAYER_CONNECTION_FIELD = handleClass.getDeclaredField("playerConnection");

Object playerConnectionObject = PLAYER_CONNECTION_FIELD.get(handleObject);

Method[] playerConnectionMethods = playerConnectionObject.getClass().getDeclaredMethods();
for (Method m : playerConnectionMethods) {
if (m.getName().equals("sendPacket")) {
SEND_PACKET_METHOD = m;
break;
}
}

Class<?> packetChatClass = NmsUtil.nmsClass("PacketPlayOutChat");
Constructor[] packetConstructors = packetChatClass.getDeclaredConstructors();
for (Constructor c : packetConstructors) {
Class<?>[] parameters = c.getParameterTypes();
if (parameters.length == 1 && parameters[0].getName().endsWith("IChatBaseComponent")) {
PACKET_CHAT_CONSTRUCTOR = c;
break;
}
}

Class<?> baseComponentClass = NmsUtil.nmsClass("IChatBaseComponent");
Class<?> chatSerializerClass;

if (baseComponentClass.getClasses().length > 0) {
chatSerializerClass = baseComponentClass.getClasses()[0];
} else {
// 1.7 class is here instead.
chatSerializerClass = NmsUtil.nmsClass("ChatSerializer");
}

SERIALIZE_METHOD = chatSerializerClass.getDeclaredMethod("a", String.class);
}

private static synchronized boolean trySetup(Object player) {
if (setup) return true;
if (triedAndFailed) return false;

try {
setup(player);
setup = true;
return true;
} catch (Throwable e) {
triedAndFailed = true;
return false;
}
}

private static boolean sendJsonMessage(Player player, String json) {
if (!trySetup(player)) {
return false;
}

try {
Object connection = PLAYER_CONNECTION_FIELD.get(GET_HANDLE_METHOD.invoke(player));
SEND_PACKET_METHOD.invoke(connection, PACKET_CHAT_CONSTRUCTOR.newInstance(SERIALIZE_METHOD.invoke(null, json)));
return true;
} catch (Exception e) {
return false;
}
}

public static void sendJsonMessage(CommandSender sender, Component message) {
if (CHAT_COMPATIBLE && sender instanceof Player) {
Player player = (Player) sender;
String json = ComponentSerializers.JSON.serialize(message);

// Try Bukkit.
if (sendJsonMessage(player, json)) {
return;
}
}

// Fallback to Bukkit
sender.sendMessage(TextUtils.toLegacy(message));
}

}
73 changes: 73 additions & 0 deletions helper/src/main/java/me/lucko/helper/text/TextUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* This file is part of helper, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <[email protected]>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package me.lucko.helper.text;

import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.serializer.ComponentSerializers;

import org.bukkit.command.CommandSender;

import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@SuppressWarnings("deprecation")
public final class TextUtils {

public static String joinNewline(String... strings) {
return joinNewline(Arrays.stream(strings));
}

public static String joinNewline(Stream<String> strings) {
return strings.collect(Collectors.joining("\n"));
}

public static TextComponent fromLegacy(String input, char character) {
return ComponentSerializers.LEGACY.deserialize(input, character);
}

public static TextComponent fromLegacy(String input) {
return ComponentSerializers.LEGACY.deserialize(input);
}

public static String toLegacy(Component component, char character) {
return ComponentSerializers.LEGACY.serialize(component, character);
}

public static String toLegacy(Component component) {
return ComponentSerializers.LEGACY.serialize(component);
}

public static void sendMessage(CommandSender sender, Component message) {
BukkitTextUtils.sendJsonMessage(sender, message);
}

private TextUtils() {
throw new UnsupportedOperationException("This class cannot be instantiated");
}

}
Loading

0 comments on commit 01f85f6

Please sign in to comment.