mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-28 05:35:28 +01:00
Add support for using multiple lines in WrappedServerPing.
This commit is contained in:
parent
75fe2c6db9
commit
a902c1f186
@ -4,25 +4,50 @@ import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import com.comphenix.protocol.reflect.ClassAnalyser.AsmMethod.AsmOpcodes;
|
||||
import com.comphenix.protocol.reflect.compiler.EmptyClassVisitor;
|
||||
import com.comphenix.protocol.reflect.compiler.EmptyMethodVisitor;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.sf.cglib.asm.ClassReader;
|
||||
import net.sf.cglib.asm.MethodVisitor;
|
||||
import net.sf.cglib.asm.Opcodes;
|
||||
import net.sf.cglib.asm.Type;
|
||||
|
||||
public class ClassAnalyser {
|
||||
/**
|
||||
* Represents a method in ASM.
|
||||
* <p>
|
||||
* Keep in mind that this may also invoke a constructor.
|
||||
* @author Kristian
|
||||
*/
|
||||
public static class AsmMethod {
|
||||
public enum AsmOpcodes {
|
||||
INVOKE_VIRTUAL,
|
||||
INVOKE_SPECIAL,
|
||||
INVOKE_STATIC,
|
||||
INVOKE_INTERFACE,
|
||||
INVOKE_DYNAMIC;
|
||||
|
||||
public static AsmOpcodes fromIntOpcode(int opcode) {
|
||||
switch (opcode) {
|
||||
case Opcodes.INVOKEVIRTUAL: return AsmOpcodes.INVOKE_VIRTUAL;
|
||||
case Opcodes.INVOKESPECIAL: return AsmOpcodes.INVOKE_SPECIAL;
|
||||
case Opcodes.INVOKESTATIC: return AsmOpcodes.INVOKE_STATIC;
|
||||
case Opcodes.INVOKEINTERFACE: return AsmOpcodes.INVOKE_INTERFACE;
|
||||
case Opcodes.INVOKEDYNAMIC: return AsmOpcodes.INVOKE_DYNAMIC;
|
||||
default: throw new IllegalArgumentException("Unknown opcode: " + opcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final AsmOpcodes opcode;
|
||||
private final String ownerClass;
|
||||
private final String methodName;
|
||||
private final String signature;
|
||||
|
||||
public AsmMethod(String ownerClass, String methodName, String signature) {
|
||||
public AsmMethod(AsmOpcodes opcode, String ownerClass, String methodName, String signature) {
|
||||
this.opcode = opcode;
|
||||
this.ownerClass = ownerClass;
|
||||
this.methodName = methodName;
|
||||
this.signature = signature;
|
||||
@ -32,6 +57,14 @@ public class ClassAnalyser {
|
||||
return ownerClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the opcode used to invoke this method or constructor.
|
||||
* @return The opcode.
|
||||
*/
|
||||
public AsmOpcodes getOpcode() {
|
||||
return opcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the associated owner class.
|
||||
* @return The owner class.
|
||||
@ -92,7 +125,7 @@ public class ClassAnalyser {
|
||||
return new EmptyMethodVisitor() {
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
|
||||
output.add(new AsmMethod(owner, name, desc));
|
||||
output.add(new AsmMethod(AsmOpcodes.fromIntOpcode(opcode), owner, methodName, desc));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -670,6 +670,33 @@ public class MinecraftReflection {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the NMS chat component text class.
|
||||
* @return The chat component class.
|
||||
*/
|
||||
public static Class<?> getChatComponentTextClass() {
|
||||
try {
|
||||
return getMinecraftClass("ChatComponentText");
|
||||
} catch (RuntimeException e) {
|
||||
try {
|
||||
Method getScoreboardDisplayName = FuzzyReflection.fromClass(getEntityClass()).
|
||||
getMethodByParameters("getScoreboardDisplayName", getIChatBaseComponentClass(), new Class<?>[0]);
|
||||
Class<?> baseClass = getIChatBaseComponentClass();
|
||||
|
||||
for (AsmMethod method : ClassAnalyser.getDefault().getMethodCalls(getScoreboardDisplayName)) {
|
||||
Class<?> owner = method.getOwnerClass();
|
||||
|
||||
if (isMinecraftClass(owner) && baseClass.isAssignableFrom(owner)) {
|
||||
return setMinecraftClass("ChatComponentText", owner);
|
||||
}
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
throw new IllegalStateException("Cannot find ChatComponentText class.", e);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Cannot find ChatComponentText class.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to find the ChatSerializer class.
|
||||
* @return The serializer class.
|
||||
|
@ -4,8 +4,10 @@ import org.bukkit.ChatColor;
|
||||
|
||||
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.MethodAccessor;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/**
|
||||
* Represents a chat component added in Minecraft 1.7.2
|
||||
@ -17,6 +19,7 @@ public class WrappedChatComponent extends AbstractWrapper {
|
||||
private static MethodAccessor SERIALIZE_COMPONENT = null;
|
||||
private static MethodAccessor DESERIALIZE_COMPONENT = null;
|
||||
private static MethodAccessor CONSTRUCT_COMPONENT = null;
|
||||
private static ConstructorAccessor CONSTRUCT_TEXT_COMPONENT = null;
|
||||
|
||||
static {
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(SERIALIZER);
|
||||
@ -30,6 +33,10 @@ public class WrappedChatComponent extends AbstractWrapper {
|
||||
// Get a component from a standard Minecraft message
|
||||
CONSTRUCT_COMPONENT = Accessors.getMethodAccessor(
|
||||
MinecraftReflection.getCraftChatMessage(), "fromString", String.class);
|
||||
|
||||
// And the component text constructor
|
||||
CONSTRUCT_TEXT_COMPONENT = Accessors.getConstructorAccessor(
|
||||
MinecraftReflection.getChatComponentTextClass(), String.class);
|
||||
}
|
||||
|
||||
private transient String cache;
|
||||
@ -58,6 +65,16 @@ public class WrappedChatComponent extends AbstractWrapper {
|
||||
return new WrappedChatComponent(DESERIALIZE_COMPONENT.invoke(null, json), json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a wrapper around a new text chat component with the given text.
|
||||
* @param text - the text of the text chat component.
|
||||
* @return The wrapper around the new chat component.
|
||||
*/
|
||||
public static WrappedChatComponent fromText(String text) {
|
||||
Preconditions.checkNotNull(text, "text cannot be NULL.");
|
||||
return fromHandle(CONSTRUCT_TEXT_COMPONENT.invoke(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an array of chat components from a standard Minecraft message.
|
||||
* <p>
|
||||
|
@ -135,12 +135,10 @@ public class WrappedServerPing extends AbstractWrapper {
|
||||
|
||||
/**
|
||||
* Set the message of the day.
|
||||
* <p>
|
||||
* <b>Warning:</b> Only the first line will be transmitted.
|
||||
* @param description - the message.
|
||||
*/
|
||||
public void setMotD(String message) {
|
||||
setMotD(WrappedChatComponent.fromChatMessage(message)[0]);
|
||||
setMotD(WrappedChatComponent.fromText(message));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,6 +2,7 @@ package com.comphenix.protocol.utility;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import net.minecraft.server.v1_7_R1.ChatComponentText;
|
||||
import net.minecraft.server.v1_7_R1.ChatSerializer;
|
||||
import net.minecraft.server.v1_7_R1.ChunkCoordIntPair;
|
||||
import net.minecraft.server.v1_7_R1.IChatBaseComponent;
|
||||
@ -44,6 +45,11 @@ public class MinecraftReflectionTest {
|
||||
assertEquals(IChatBaseComponent.class, MinecraftReflection.getIChatBaseComponentClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChatComponentText() {
|
||||
assertEquals(ChatComponentText.class, MinecraftReflection.getChatComponentTextClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChatSerializer() {
|
||||
assertEquals(ChatSerializer.class, MinecraftReflection.getChatSerializerClass());
|
||||
|
@ -0,0 +1,23 @@
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
|
||||
public class WrappedChatComponentTest {
|
||||
@BeforeClass
|
||||
public static void initializeBukkit() throws IllegalAccessException {
|
||||
BukkitInitialization.initializePackage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testText() {
|
||||
WrappedChatComponent test = WrappedChatComponent.fromText("Hello.");
|
||||
String json = test.getJson();
|
||||
|
||||
assertNotNull(json);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user