Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PaperAPI support #219

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public interface ItemNameAdapter {
if (MinecraftVersion.isMocked()) {
// Special case for MockBukkit
return new ItemNameAdapterMockBukkit();
}else if(ItemNameAdapterPaper.canUse()) {
//when mcpaper or like are present then rely on paperAPI rather then deep diving into NMS
return new ItemNameAdapterPaper();
} else if (version.isAtLeast(1, 20)) {
return new ItemNameAdapter20();
} else if (version.isAtLeast(1, 19)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.github.bakedlibs.dough.items.nms;

import io.github.bakedlibs.dough.reflection.ReflectionUtils;
import org.bukkit.inventory.ItemStack;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class ItemNameAdapterPaper implements ItemNameAdapter {

private final Method getName;

ItemNameAdapterPaper() {
super();

getName = ReflectionUtils.getMethod(ItemStack.class, "getI18NDisplayName");
}

public static boolean canUse() {
try {
ReflectionUtils.getMethod(ItemStack.class, "getI18NDisplayName");
return true;
} catch (Exception e) {
return false;
}
}

@Override
public String getName(ItemStack item) throws IllegalAccessException, InvocationTargetException {
return (String) getName.invoke(item);
}

}
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
package io.github.bakedlibs.dough.skins.nms;

import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;

import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;

import org.bukkit.block.Block;

import com.mojang.authlib.GameProfile;

import io.github.bakedlibs.dough.common.DoughLogger;
import io.github.bakedlibs.dough.versions.MinecraftVersion;
import org.bukkit.block.Block;

public interface PlayerHeadAdapter {

@ParametersAreNonnullByDefault
@Nullable
Object getTileEntity(Block block) throws IllegalAccessException, InvocationTargetException, InstantiationException;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;

@ParametersAreNonnullByDefault
void setGameProfile(Object tileEntity, GameProfile profile) throws IllegalAccessException, InvocationTargetException;
public interface PlayerHeadAdapter {

public static @Nullable PlayerHeadAdapter get() {
try {
if (PlayerHeadAdapterPaper.canApply()) {
return new PlayerHeadAdapterPaper();
}

MinecraftVersion version = MinecraftVersion.get();

if (version.isAtLeast(1, 18)) {
Expand All @@ -43,4 +37,11 @@ public interface PlayerHeadAdapter {
}

}

@ParametersAreNonnullByDefault
@Nullable
Object getTileEntity(Block block) throws IllegalAccessException, InvocationTargetException, InstantiationException;

@ParametersAreNonnullByDefault
void setGameProfile(Object tileEntity, GameProfile profile) throws IllegalAccessException, InvocationTargetException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package io.github.bakedlibs.dough.skins.nms;

import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import io.github.bakedlibs.dough.reflection.ReflectionUtils;
import io.github.bakedlibs.dough.versions.UnknownServerVersionException;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.Skull;

import javax.annotation.Nullable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;

public class PlayerHeadAdapterPaper implements PlayerHeadAdapter {

private static final String PROPERTY_KEY = "textures";
private final Method createPaperGameProfile;
private final Method paperGameProfileSetProperty;
private final Constructor<?> createProperty;
private final Method setGameProfile;


public PlayerHeadAdapterPaper() throws NoSuchMethodException, SecurityException, ClassNotFoundException, UnknownServerVersionException {
Class<?> paperGameProfile = Class.forName("com.destroystokyo.paper.profile.PlayerProfile");
Class<?> paperProperty = Class.forName("com.destroystokyo.paper.profile.ProfileProperty");
createPaperGameProfile = ReflectionUtils.getMethod(Bukkit.class, "createProfile");
paperGameProfileSetProperty = ReflectionUtils.getMethod(paperGameProfile, "setProperty", paperProperty);
createProperty = ReflectionUtils.getConstructor(paperProperty, String.class, String.class);
setGameProfile = ReflectionUtils.getMethod(Skull.class, "setPlayerProfile", paperGameProfile);
}

public static boolean canApply() {
try {
Class.forName("com.destroystokyo.paper.profile.PlayerProfile");
return true;
} catch (ClassNotFoundException e) {
return false;
}

}

@Nullable
@Override
public Object getTileEntity(Block block) throws IllegalAccessException, InvocationTargetException, InstantiationException {
return block.getState();
}

@Override
public void setGameProfile(Object tileEntity, GameProfile profile) throws IllegalAccessException, InvocationTargetException {
if (!(tileEntity instanceof Skull)) {
throw new IllegalArgumentException("tileEntity must be BukkitAPI Skull tile entity. Provided " + tileEntity.getClass().getName());
}
Skull skull = (Skull) tileEntity;
Collection<Property> properties = profile.getProperties().get(PROPERTY_KEY);
if (properties.isEmpty()) {
return;
}
String texture = properties.iterator().next().getValue();

Object paperGameProfile = createPaperGameProfile.invoke(null, profile.getId());
Object property;
try {
property = createProperty.newInstance(PROPERTY_KEY, texture);
} catch (InstantiationException e) {
//shouldnt fail if it got this far
throw new InvocationTargetException(e);
}
paperGameProfileSetProperty.invoke(paperGameProfile, property);
setGameProfile.invoke(skull, paperGameProfile);
}
}