Skip to content

Commit

Permalink
fix: 1.20.6 support and Paper support
Browse files Browse the repository at this point in the history
  • Loading branch information
timbru31 committed Jun 1, 2024
1 parent 8756644 commit a0edc4d
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;

import org.apache.commons.lang.StringUtils;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Server;
import org.bukkit.UnsafeValues;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
Expand All @@ -24,6 +29,8 @@
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;

import com.vdurmont.semver4j.Semver;

import de.dustplanet.silkspawners.commands.SilkSpawnersTabCompleter;
import de.dustplanet.silkspawners.commands.SpawnerCommand;
import de.dustplanet.silkspawners.configs.Config;
Expand Down Expand Up @@ -56,6 +63,12 @@ public class SilkSpawners extends JavaPlugin {
private static final String[] COMPATIBLE_MINECRAFT_VERSIONS = { "v1_8_R3", "v1_11_R1", "v1_12_R1", "v1_13_R2", "v1_14_R1", "v1_15_R1",
"v1_16_R1", "v1_16_R2", "v1_16_R3", "v1_17_R1", "v1_18_R1", "v1_18_R2", "v1_19_R1", "v1_19_R2", "v1_19_R3", "v1_20_R1",
"v1_20_R2", "v1_20_R3", "v1_20_R4" };
public static final Map<Integer, String> PROTOCOL_VERSION_PACKAGE_MAP = new HashMap<Integer, String>() {
private static final long serialVersionUID = -5188779509588704507L;
{
put(766, "v1_20_R4");
}
};
public CommentedConfiguration config;
public CommentedConfiguration localization;
@Getter
Expand All @@ -78,7 +91,21 @@ public void onEnable() {
final String packageName = getServer().getClass().getPackage().getName();
// org.bukkit.craftbukkit.version
// Get the last element of the package
setNmsVersion(packageName.substring(packageName.lastIndexOf('.') + 1));
String _nmsVersion = packageName.substring(packageName.lastIndexOf('.') + 1);
if (_nmsVersion.equals("craftbukkit")) {
try {
String minecraftVersion = (String) Server.class.getDeclaredMethod("getMinecraftVersion").invoke(Bukkit.getServer());
Semver semver = new Semver(minecraftVersion);
if (semver.isGreaterThanOrEqualTo("1.20.5")) {
@SuppressWarnings("deprecation")
int protocolVersion = (Integer) UnsafeValues.class.getDeclaredMethod("getProtocolVersion").invoke(Bukkit.getUnsafe());
_nmsVersion = PROTOCOL_VERSION_PACKAGE_MAP.get(protocolVersion);
}
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
setNmsVersion(_nmsVersion);

// Test for right Minecraft version
if (config.getBoolean("testMCVersion", true)) {
Expand Down Expand Up @@ -403,7 +430,7 @@ private void loadRecipes() {
// If the custom recipe fails, we have a fallback
getLogger().log(Level.WARNING, "Could not add the recipe of {0}!", entityID);
getLogger().log(Level.WARNING, "Error:", e);
recipe.shape(new String[] { "AAA", "ABA", "AAA" });
recipe.shape("AAA", "ABA", "AAA");
recipe.setIngredient('A', su.nmsProvider.getIronFenceMaterial());
if (legacySpawnEggs) {
recipe.setIngredient('X', su.nmsProvider.getSpawnEggMaterial(), 0);
Expand Down Expand Up @@ -496,7 +523,7 @@ private void loadBaseEggRecipe() {
} catch (final IllegalArgumentException e) {
// If the custom recipe fails, we have a fallback
getLogger().log(Level.WARNING, "Could not add the default recipe!", e);
baseSpawnerRecipe.shape(new String[] { "AAA", "ABA", "AAA" });
baseSpawnerRecipe.shape("AAA", "ABA", "AAA");
baseSpawnerRecipe.setIngredient('A', su.nmsProvider.getIronFenceMaterial());
// Use the right egg!
baseSpawnerRecipe.setIngredient('B', su.nmsProvider.getSpawnEggMaterial());
Expand Down Expand Up @@ -529,7 +556,7 @@ private boolean shapeContainsIngredient(final List<String> shape, final char c)
/**
* Sends a message to the player if the 'silkspawners.info' permission is granted. Empty messages are ignored and not are not sent.
*
* @param player the player to message
* @param player the player to message
* @param message the message to send
*/
public void informPlayer(final Player player, final String message) {
Expand Down
55 changes: 38 additions & 17 deletions modules/SilkSpawners/src/main/java/de/dustplanet/util/SilkUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.UnsafeValues;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.CreatureSpawner;
Expand All @@ -41,6 +43,7 @@
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import com.sk89q.worldguard.protection.regions.RegionQuery;
import com.vdurmont.semver4j.Semver;

import de.dustplanet.silkspawners.SilkSpawners;
import de.dustplanet.silkspawners.compat.api.NMSProvider;
Expand Down Expand Up @@ -160,7 +163,21 @@ private boolean setupNMSProvider() {
// Rare cases might trigger API usage before SilkSpawners
if (version == null) {
final String packageName = Bukkit.getServer().getClass().getPackage().getName();
version = (packageName.substring(packageName.lastIndexOf('.') + 1));
String nmsVersion = packageName.substring(packageName.lastIndexOf('.') + 1);
if (nmsVersion.equals("craftbukkit")) {
try {
String minecraftVersion = (String) Server.class.getDeclaredMethod("getMinecraftVersion").invoke(Bukkit.getServer());
Semver semver = new Semver(minecraftVersion);
if (semver.isGreaterThanOrEqualTo("1.20.5")) {
@SuppressWarnings("deprecation")
int protocolVersion = (Integer) UnsafeValues.class.getDeclaredMethod("getProtocolVersion")
.invoke(Bukkit.getUnsafe());
version = SilkSpawners.PROTOCOL_VERSION_PACKAGE_MAP.get(protocolVersion);
}
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
}

final FileConfiguration config = plugin.getConfig();
Expand Down Expand Up @@ -320,7 +337,7 @@ public boolean isVanillaBossBar() {
*
* @deprecated Use {@link SilkUtil#newEggItem(String, int, String)} instead.
* @param entityID which mob should be spawned
* @param amount the amount of spawn eggs
* @param amount the amount of spawn eggs
* @return the ItemStack
*/
@Deprecated
Expand All @@ -331,8 +348,8 @@ public ItemStack newEggItem(final String entityID, final int amount) {
/**
* Returns a new ItemStack of a spawn egg with the specified amount and mob.
*
* @param entityID which mob should be spawned
* @param amount the amount of spawn eggs
* @param entityID which mob should be spawned
* @param amount the amount of spawn eggs
* @param displayName the display name of the egg in case of unknown entities
* @return the ItemStack
*/
Expand All @@ -344,10 +361,10 @@ public ItemStack newEggItem(final String entityID, final int amount, final Strin
/**
* This method will make a new MobSpawner with a custom entityID, name and amount.
*
* @param entityID the mob
* @param entityID the mob
* @param customName if the MobSpawner should be named different
* @param amount the wanted amount
* @param forceLore whether the lore tag should be forces
* @param amount the wanted amount
* @param forceLore whether the lore tag should be forces
* @return the ItemStack with the configured options
*/
public ItemStack newSpawnerItem(final String entityID, final String customName, final int amount, final boolean forceLore) {
Expand Down Expand Up @@ -395,10 +412,12 @@ public String getStoredEggEntityID(final ItemStack item) {
if (isUsingReflection()) {
// Now try reflection for NBT tag
entityID = nmsProvider.getSilkSpawnersNBTEntityID(item);
plugin.getLogger().log(Level.FINE, "EntityID from egg item stack (custom tag) is {0}", entityID);
if (entityID != null) {
return entityID;
}
entityID = nmsProvider.getVanillaEggNBTEntityID(item);
plugin.getLogger().log(Level.FINE, "EntityID from egg item stack (vanilla tag) is {0}", entityID);
if (entityID != null) {
return entityID;
}
Expand All @@ -423,10 +442,12 @@ public String getStoredEggEntityID(final ItemStack item) {
public String getStoredSpawnerItemEntityID(final ItemStack item) {
if (isUsingReflection()) {
String entityID = nmsProvider.getSilkSpawnersNBTEntityID(item);
plugin.getLogger().log(Level.FINE, "EntityID from item stack (custom tag) is {0}", entityID);
if (StringUtils.isNotBlank(entityID)) {
return entityID;
}
entityID = nmsProvider.getVanillaNBTEntityID(item);
plugin.getLogger().log(Level.FINE, "EntityID from item stack (vanilla tag) is {0}", entityID);
if (StringUtils.isNotBlank(entityID)) {
return entityID.replace("minecraft:", "");
}
Expand Down Expand Up @@ -505,7 +526,7 @@ public String getSpawnerEntityID(final Block block) {
/**
* Set the specified MonterSpawner to another entity ID.
*
* @param block MonsterSpawner
* @param block MonsterSpawner
* @param entity the wanted entity
*/
public void setSpawnerEntityID(final Block block, final String entity) {
Expand Down Expand Up @@ -539,9 +560,9 @@ public void setSpawnerEntityID(final Block block, final String entity) {
/**
* Set a spawner (if allowed) to a new mob.
*
* @param block the MonsterSpawner
* @param entityID the new entity ID
* @param player the player
* @param block the MonsterSpawner
* @param entityID the new entity ID
* @param player the player
* @param messageDenied the message which is shown, when the player can't build here see {@link #canBuildHere(Player, Location)}
* @return whether the operation was successful or not
*/
Expand All @@ -559,8 +580,8 @@ public boolean setSpawnerType(final Block block, final String entityID, final Pl
/**
* Sets a spawner item or egg to a new ID.
*
* @param item ItemStack (Egg or Spawner)
* @param entityID wanted entity ID
* @param item ItemStack (Egg or Spawner)
* @param entityID wanted entity ID
* @param customName if a custom name should be used (null for none)
* @return the updated ItemStack
*/
Expand Down Expand Up @@ -706,7 +727,7 @@ public List<String> scanEntityMap() {
/**
* Notify a player about the spawner.
*
* @param player the player
* @param player the player
* @param spawnerName the creature name
*/
@SuppressWarnings("deprecation")
Expand Down Expand Up @@ -892,7 +913,7 @@ private void getWorldGuard() {
/**
* Checks if a player can build here (WorldGuard).
*
* @param player the player
* @param player the player
* @param location the location to check
* @return the result, true or false
*/
Expand Down Expand Up @@ -934,9 +955,9 @@ public boolean isLegacySpawnEggs() {
/**
* Helper methods to check if a player has any of the aliases permissions for a given mobID.
*
* @param permissible - the permissible to check the permission for
* @param permissible - the permissible to check the permission for
* @param basePermission - the basis permission without the specific mob
* @param entityID - the internal mob ID (not display name)
* @param entityID - the internal mob ID (not display name)
* @return the permission check result, true if the player has got the permission, false otherwise
*/
public boolean hasPermission(final Permissible permissible, final String basePermission, final String entityID) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,21 +231,16 @@ public ItemStack setNBTEntityID(final ItemStack item, final String entity) {
final CraftItemStack craftStack = CraftItemStack.asCraftCopy(item);
itemStack = CraftItemStack.asNMSCopy(craftStack);
final CustomData blockData = itemStack.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY);
final CustomData customData = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
CompoundTag tag = blockData.copyTag();
CompoundTag customTag = customData.copyTag();

// Check for SilkSpawners key
if (!tag.contains("SilkSpawners")) {
tag.put("SilkSpawners", new CompoundTag());
}

tag.getCompound("SilkSpawners").putString("entity", entity);

// Check for Vanilla keys
if (!tag.contains("BlockEntityTag")) {
tag.put("BlockEntityTag", new CompoundTag());
if (!customTag.contains("SilkSpawners")) {
customTag.put("SilkSpawners", new CompoundTag());
}

tag = tag.getCompound("BlockEntityTag");
customTag.getCompound("SilkSpawners").putString("entity", entity);

// EntityId - Deprecated in 1.9
tag.putString("EntityId", entity);
Expand Down Expand Up @@ -273,6 +268,7 @@ public ItemStack setNBTEntityID(final ItemStack item, final String entity) {
tag.getCompound("EntityTag").putString("id", prefixedEntity);

itemStack.set(DataComponents.BLOCK_ENTITY_DATA, CustomData.of(tag));
itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(customTag));
return CraftItemStack.asCraftMirror(itemStack);
}

Expand All @@ -282,10 +278,10 @@ public String getSilkSpawnersNBTEntityID(final ItemStack item) {
net.minecraft.world.item.ItemStack itemStack = null;
final CraftItemStack craftStack = CraftItemStack.asCraftCopy(item);
itemStack = CraftItemStack.asNMSCopy(craftStack);
final CustomData blockEntityData = itemStack.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY);
final CustomData blockEntityData = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
final CompoundTag tag = blockEntityData.copyTag();

if (tag == null || !tag.contains("SilkSpawners")) {
if (!tag.contains("SilkSpawners")) {
return null;
}
return tag.getCompound("SilkSpawners").getString("entity");
Expand All @@ -300,11 +296,6 @@ public String getVanillaNBTEntityID(final ItemStack item) {
final CustomData blockEntityData = itemStack.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY);
CompoundTag tag = blockEntityData.copyTag();

if (tag == null || !tag.contains("BlockEntityTag")) {
return null;
}

tag = tag.getCompound("BlockEntityTag");
if (tag.contains("EntityId")) {
return tag.getString("EntityId");
} else if (tag.contains("SpawnData") && tag.getCompound("SpawnData").contains("id")) {
Expand Down Expand Up @@ -352,28 +343,27 @@ public ItemStack newEggItem(final String entityID, final int amount, final Strin
net.minecraft.world.item.ItemStack itemStack = null;
final CraftItemStack craftStack = CraftItemStack.asCraftCopy(item);
itemStack = CraftItemStack.asNMSCopy(craftStack);
final CustomData blockEntityData = itemStack.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY);
final CompoundTag tag = blockEntityData.copyTag();
final CustomData blockData = itemStack.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
final CustomData customData = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY);
CompoundTag tag = blockData.copyTag();
CompoundTag customTag = customData.copyTag();

if (!tag.contains("SilkSpawners")) {
tag.put("SilkSpawners", new CompoundTag());
if (!customTag.contains("SilkSpawners")) {
customTag.put("SilkSpawners", new CompoundTag());
}

tag.getCompound("SilkSpawners").putString("entity", entityID);

if (!tag.contains("EntityTag")) {
tag.put("EntityTag", new CompoundTag());
}
customTag.getCompound("SilkSpawners").putString("entity", entityID);

String prefixedEntity;
if (!entityID.startsWith("minecraft:")) {
prefixedEntity = "minecraft:" + entityID;
} else {
prefixedEntity = entityID;
}
tag.getCompound("EntityTag").putString("id", prefixedEntity);
tag.putString("id", prefixedEntity);

itemStack.set(DataComponents.BLOCK_ENTITY_DATA, CustomData.of(tag));
itemStack.set(DataComponents.ENTITY_DATA, CustomData.of(tag));
itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(customTag));
return CraftItemStack.asCraftMirror(itemStack);
}

Expand All @@ -382,21 +372,19 @@ public String getVanillaEggNBTEntityID(final ItemStack item) {
net.minecraft.world.item.ItemStack itemStack = null;
final CraftItemStack craftStack = CraftItemStack.asCraftCopy(item);
itemStack = CraftItemStack.asNMSCopy(craftStack);
final CustomData blockEntityData = itemStack.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY);
final CustomData blockEntityData = itemStack.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY);
CompoundTag tag = blockEntityData.copyTag();

if (tag == null || !tag.contains("EntityTag")) {
final Registry<Item> itemRegistry = BuiltInRegistries.ITEM;
final ResourceLocation vanillaKey = itemRegistry.getKey(itemStack.getItem());
if (vanillaKey != null) {
return vanillaKey.getPath().replace("minecraft:", "").replace("_spawn_egg", "");
}
} else {
tag = tag.getCompound("EntityTag");
if (tag.contains("id")) {
return tag.getString("id").replace("minecraft:", "");
}
if (tag.contains("id")) {
return tag.getString("id").replace("minecraft:", "");
}

final Registry<Item> itemRegistry = BuiltInRegistries.ITEM;
final ResourceLocation vanillaKey = itemRegistry.getKey(itemStack.getItem());
if (vanillaKey != null) {
return vanillaKey.getPath().replace("minecraft:", "").replace("_spawn_egg", "");
}

return null;
}

Expand Down

0 comments on commit a0edc4d

Please sign in to comment.