From 9264013afcc786ea7fcadcf366f7ce4e882ad9d3 Mon Sep 17 00:00:00 2001 From: Brianna Date: Mon, 26 Oct 2020 09:23:40 -0500 Subject: [PATCH 1/4] Increased the default serialized_entity field size. --- .../ultimatestacker/database/migrations/_2_EntityStacks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/songoda/ultimatestacker/database/migrations/_2_EntityStacks.java b/src/main/java/com/songoda/ultimatestacker/database/migrations/_2_EntityStacks.java index 0d9ea95..1fbcebe 100644 --- a/src/main/java/com/songoda/ultimatestacker/database/migrations/_2_EntityStacks.java +++ b/src/main/java/com/songoda/ultimatestacker/database/migrations/_2_EntityStacks.java @@ -32,7 +32,7 @@ public class _2_EntityStacks extends DataMigration { statement.execute("CREATE TABLE " + tablePrefix + "stacked_entities (" + "uuid VARCHAR(36) PRIMARY KEY NOT NULL," + "host INTEGER NOT NULL," + - "serialized_entity VARBINARY(255) NOT NULL" + + "serialized_entity VARBINARY(999) NOT NULL" + ")"); } } From 601dcc1f0932e445b9a1b63fc5b300e62502dc0a Mon Sep 17 00:00:00 2001 From: Brianna Date: Mon, 26 Oct 2020 12:41:54 -0500 Subject: [PATCH 2/4] Added a custom entity api with initial support for MythicMobs. --- .../ultimatestacker/UltimateStacker.java | 6 ++ .../ultimatestacker/settings/Settings.java | 9 +++ .../stackable/entity/ColdEntityStack.java | 19 +++++- .../stackable/entity/custom/CustomEntity.java | 27 +++++++++ .../entity/custom/CustomEntityManager.java | 45 ++++++++++++++ .../entities/MythicMobsCustomEntity.java | 59 +++++++++++++++++++ .../ultimatestacker/tasks/StackingTask.java | 13 +++- .../ultimatestacker/utils/Methods.java | 6 ++ src/main/resources/plugin.yml | 2 +- 9 files changed, 180 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntity.java create mode 100644 src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntityManager.java create mode 100644 src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/entities/MythicMobsCustomEntity.java diff --git a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java index 85c9263..f94a782 100644 --- a/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java +++ b/src/main/java/com/songoda/ultimatestacker/UltimateStacker.java @@ -40,6 +40,7 @@ import com.songoda.ultimatestacker.stackable.block.BlockStack; import com.songoda.ultimatestacker.stackable.block.BlockStackManager; import com.songoda.ultimatestacker.stackable.entity.EntityStack; import com.songoda.ultimatestacker.stackable.entity.EntityStackManager; +import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntityManager; import com.songoda.ultimatestacker.stackable.spawner.SpawnerStack; import com.songoda.ultimatestacker.stackable.spawner.SpawnerStackManager; import com.songoda.ultimatestacker.tasks.StackingTask; @@ -77,6 +78,7 @@ public class UltimateStacker extends SongodaPlugin { private BlockStackManager blockStackManager; private LootablesManager lootablesManager; private CommandManager commandManager; + private CustomEntityManager customEntityManager; private StackingTask stackingTask; private DatabaseConnector databaseConnector; @@ -161,6 +163,7 @@ public class UltimateStacker extends SongodaPlugin { this.spawnerStackManager = new SpawnerStackManager(); this.entityStackManager = new EntityStackManager(this); this.blockStackManager = new BlockStackManager(); + this.customEntityManager = new CustomEntityManager(); guiManager.init(); PluginManager pluginManager = Bukkit.getPluginManager(); @@ -343,6 +346,9 @@ public class UltimateStacker extends SongodaPlugin { return blockStackManager; } + public CustomEntityManager getCustomEntityManager() { + return customEntityManager; + } public void updateHologram(Hologramable stack) { // Is this stack invalid? diff --git a/src/main/java/com/songoda/ultimatestacker/settings/Settings.java b/src/main/java/com/songoda/ultimatestacker/settings/Settings.java index 6b1744f..f6e8bee 100644 --- a/src/main/java/com/songoda/ultimatestacker/settings/Settings.java +++ b/src/main/java/com/songoda/ultimatestacker/settings/Settings.java @@ -152,6 +152,15 @@ public class Settings { public static final ConfigSetting SHEAR_IN_ONE_CLICK = new ConfigSetting(config, "Entities.Shear In One Click", false, "Should entities be sheared in a single click?"); + public static final ConfigSetting ENABLED_CUSTOM_ENTITY_PLUGINS = new ConfigSetting(config, "Entities.Enabled Custom Entity Plugins", Collections.singletonList("MythicMobs"), + "Which custom entity plugins should be used?", + "Remove a plugin from this list to disable the stacking of their entities."); + + public static final ConfigSetting BLACKLISTED_CUSTOM_ENTITIES = new ConfigSetting(config, "Entities.Blacklisted Custom Entities", Collections.singletonList("mythicmobs_test"), + "Which custom entities should not be stacked?", + "List the entities using their plugin name as a prefix in all lowercase.", + "Example: mythicmobs_test"); + public static final ConfigSetting STACK_ITEMS = new ConfigSetting(config, "Items.Enabled", true, "Should items be stacked?"); diff --git a/src/main/java/com/songoda/ultimatestacker/stackable/entity/ColdEntityStack.java b/src/main/java/com/songoda/ultimatestacker/stackable/entity/ColdEntityStack.java index ea35108..b3614c5 100644 --- a/src/main/java/com/songoda/ultimatestacker/stackable/entity/ColdEntityStack.java +++ b/src/main/java/com/songoda/ultimatestacker/stackable/entity/ColdEntityStack.java @@ -3,6 +3,7 @@ package com.songoda.ultimatestacker.stackable.entity; import com.songoda.core.nms.NmsManager; import com.songoda.core.nms.nbt.NBTEntity; import com.songoda.ultimatestacker.UltimateStacker; +import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntity; import com.songoda.ultimatestacker.utils.Stackable; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -71,7 +72,7 @@ public class ColdEntityStack implements Stackable { public List takeEntities(int amount) { List entities = new LinkedList<>(); - for (int i = 0; i < amount; i ++) { + for (int i = 0; i < amount; i++) { StackedEntity entity = stackedEntities.pollFirst(); if (entity != null) entities.add(entity); @@ -90,7 +91,18 @@ public class ColdEntityStack implements Stackable { if (stackedEntities.isEmpty()) return null; NBTEntity nbtEntity = NmsManager.getNbt().newEntity(); nbtEntity.deSerialize(stackedEntities.getFirst().getSerializedEntity()); - LivingEntity newEntity = (LivingEntity)nbtEntity.spawn(location); + + for (CustomEntity customEntity : plugin.getCustomEntityManager().getRegisteredCustomEntities()) { + String identifier = customEntity.getPluginName() + "_UltimateStacker"; + if (!nbtEntity.has(identifier)) continue; + LivingEntity entity = customEntity.spawnFromIdentifier(nbtEntity.getString(identifier), location); + if (entity == null) continue; + stackedEntities.removeFirst(); + plugin.getDataManager().deleteStackedEntity(entity.getUniqueId()); + return entity; + } + + LivingEntity newEntity = (LivingEntity) nbtEntity.spawn(location); stackedEntities.removeFirst(); plugin.getDataManager().deleteStackedEntity(newEntity.getUniqueId()); @@ -126,6 +138,9 @@ public class ColdEntityStack implements Stackable { uuid = UUID.randomUUID(); nbtEntity.set("UUID", uuid); } + CustomEntity customEntity = plugin.getCustomEntityManager().getCustomEntity(entity); + if (customEntity != null) + nbtEntity.set(customEntity.getPluginName() + "_UltimateStacker", customEntity.getNBTIdentifier(entity)); return new StackedEntity(uuid, nbtEntity.serialize("Attributes")); } diff --git a/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntity.java b/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntity.java new file mode 100644 index 0000000..0c0956a --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntity.java @@ -0,0 +1,27 @@ +package com.songoda.ultimatestacker.stackable.entity.custom; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.plugin.Plugin; + +public abstract class CustomEntity { + + protected final Plugin plugin; + + protected CustomEntity(Plugin plugin) { + this.plugin = plugin; + } + + public abstract String getPluginName(); + + public abstract boolean isMatchingType(Entity entity); + + public abstract String getDisplayName(Entity entity); + + public abstract boolean isSimilar(LivingEntity original, LivingEntity entity); + + public abstract String getNBTIdentifier(Entity entity); + + public abstract LivingEntity spawnFromIdentifier(String string, Location location); +} diff --git a/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntityManager.java b/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntityManager.java new file mode 100644 index 0000000..ca08a97 --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/CustomEntityManager.java @@ -0,0 +1,45 @@ +package com.songoda.ultimatestacker.stackable.entity.custom; + +import com.songoda.ultimatestacker.settings.Settings; +import com.songoda.ultimatestacker.stackable.entity.custom.entities.MythicMobsCustomEntity; +import org.bukkit.Bukkit; +import org.bukkit.entity.Entity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class CustomEntityManager { + + public CustomEntityManager() { + load(); + } + + private final List registeredCustomEntities = new ArrayList<>(); + + public void load() { + if (isEnabled("MythicMobs")) + registeredCustomEntities.add(new MythicMobsCustomEntity()); + } + + public boolean isEnabled(String plugin) { + return Bukkit.getPluginManager().isPluginEnabled(plugin) + && Settings.ENABLED_CUSTOM_ENTITY_PLUGINS.getStringList().contains(plugin); + } + + public CustomEntity getCustomEntity(Entity entity) { + for (CustomEntity customEntity : registeredCustomEntities) { + if (customEntity.isMatchingType(entity)) { + if (Settings.BLACKLISTED_CUSTOM_ENTITIES.getStringList() + .contains((customEntity.getPluginName() + "_" + customEntity.getNBTIdentifier(entity)).toLowerCase())) + continue; + return customEntity; + } + } + return null; + } + + public List getRegisteredCustomEntities() { + return Collections.unmodifiableList(registeredCustomEntities); + } +} diff --git a/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/entities/MythicMobsCustomEntity.java b/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/entities/MythicMobsCustomEntity.java new file mode 100644 index 0000000..8783347 --- /dev/null +++ b/src/main/java/com/songoda/ultimatestacker/stackable/entity/custom/entities/MythicMobsCustomEntity.java @@ -0,0 +1,59 @@ +package com.songoda.ultimatestacker.stackable.entity.custom.entities; + +import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntity; +import io.lumine.xikage.mythicmobs.MythicMobs; +import io.lumine.xikage.mythicmobs.mobs.ActiveMob; +import io.lumine.xikage.mythicmobs.mobs.MobManager; +import io.lumine.xikage.mythicmobs.mobs.MythicMob; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; + +public class MythicMobsCustomEntity extends CustomEntity { + + public MythicMobsCustomEntity() { + super(Bukkit.getPluginManager().getPlugin("MythicMobs")); + } + + @Override + public String getPluginName() { + return "MythicMobs"; + } + + @Override + public boolean isMatchingType(Entity entity) { + return getMobManager().isActiveMob(entity.getUniqueId()); + } + + @Override + public String getDisplayName(Entity entity) { + return getMobManager().getMythicMobInstance(entity).getType().getDisplayName().toString(); + } + + @Override + public boolean isSimilar(LivingEntity original, LivingEntity entity) { + if (!isMatchingType(original) || !isMatchingType(entity)) return false; + return getMob(original).getType().equals(getMob(entity).getType()); + } + + @Override + public String getNBTIdentifier(Entity entity) { + return getMob(entity).getType().getInternalName(); + } + + @Override + public LivingEntity spawnFromIdentifier(String string, Location location) { + if (getMobManager().getMobTypes().stream().map(MythicMob::getInternalName).noneMatch(t -> t.equals(string))) + return null; + return (LivingEntity)getMobManager().spawnMob(string, location).getEntity().getBukkitEntity(); + } + + private ActiveMob getMob(Entity entity) { + return getMobManager().getMythicMobInstance(entity); + } + + private MobManager getMobManager() { + return ((MythicMobs) plugin).getMobManager(); + } +} diff --git a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java index dfcd3c5..60e1878 100644 --- a/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java +++ b/src/main/java/com/songoda/ultimatestacker/tasks/StackingTask.java @@ -9,6 +9,7 @@ import com.songoda.ultimatestacker.stackable.entity.Check; import com.songoda.ultimatestacker.stackable.entity.EntityStack; import com.songoda.ultimatestacker.stackable.entity.EntityStackManager; import com.songoda.ultimatestacker.stackable.entity.StackedEntity; +import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntity; import com.songoda.ultimatestacker.utils.CachedChunk; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -167,8 +168,9 @@ public class StackingTask extends BukkitRunnable { // Attempt to split our stack. If the split is successful then skip this entity. if (isStack && attemptSplit(stack, livingEntity)) return; - // If this entity is named or disabled then skip it. - if (!isStack && livingEntity.getCustomName() != null + // If this entity is named, a custom entity or disabled then skip it. + if (!isStack && (livingEntity.getCustomName() != null + && plugin.getCustomEntityManager().getCustomEntity(livingEntity) == null) || !configurationSection.getBoolean("Mobs." + livingEntity.getType().name() + ".Enabled")) return; @@ -286,7 +288,8 @@ public class StackingTask extends BukkitRunnable { && !this.processed.contains(entity.getUniqueId())).limit(maxEntityStackSize).forEach(entity -> { // Make sure we're not naming some poor kids pet. - if (entity.getCustomName() != null) { + if (entity.getCustomName() != null + && plugin.getCustomEntityManager().getCustomEntity(entity) == null) { processed.add(livingEntity.getUniqueId()); newStack.destroy(); return; @@ -405,6 +408,10 @@ public class StackingTask extends BukkitRunnable { entityList.add(entity); } + CustomEntity customEntity = plugin.getCustomEntityManager().getCustomEntity(initialEntity); + if (customEntity != null) + entityList.removeIf(entity -> !customEntity.isSimilar(initialEntity, entity)); + if (stackFlyingDown && canFly(initialEntity)) entityList.removeIf(entity -> entity.getLocation().getY() > initialEntity.getLocation().getY()); diff --git a/src/main/java/com/songoda/ultimatestacker/utils/Methods.java b/src/main/java/com/songoda/ultimatestacker/utils/Methods.java index 8956f34..cbba1d8 100644 --- a/src/main/java/com/songoda/ultimatestacker/utils/Methods.java +++ b/src/main/java/com/songoda/ultimatestacker/utils/Methods.java @@ -6,6 +6,8 @@ import com.songoda.core.nms.nbt.NBTItem; import com.songoda.core.utils.TextUtils; import com.songoda.ultimatestacker.UltimateStacker; import com.songoda.ultimatestacker.settings.Settings; +import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntity; +import com.songoda.ultimatestacker.stackable.entity.custom.CustomEntityManager; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.GameMode; @@ -125,6 +127,10 @@ public class Methods { String nameFormat = Settings.NAME_FORMAT_ENTITY.getString(); String displayName = Methods.formatText(UltimateStacker.getInstance().getMobFile().getString("Mobs." + entity.getType().name() + ".Display Name")); + CustomEntity customEntity = UltimateStacker.getInstance().getCustomEntityManager().getCustomEntity(entity); + if (customEntity != null) + displayName = customEntity.getDisplayName(entity); + nameFormat = nameFormat.replace("{TYPE}", displayName); nameFormat = nameFormat.replace("{AMT}", Integer.toString(amount)); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index a44770a..d1119b1 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: UltimateStacker description: UltimateStacker version: maven-version-number -softdepend: [HolographicDisplays, Holograms, CMI, WorldGuard, EpicSpawners, mcMMO, WildStacker, StackMob] +softdepend: [MythicMobs, HolographicDisplays, Holograms, CMI, WorldGuard, EpicSpawners, mcMMO, WildStacker, StackMob] loadbefore: [WorldGuard] main: com.songoda.ultimatestacker.UltimateStacker author: songoda From 09eb8833240f9972b168bbb26a15b1590f685e1d Mon Sep 17 00:00:00 2001 From: Brianna Date: Mon, 26 Oct 2020 12:44:03 -0500 Subject: [PATCH 3/4] pom --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index f3fbd8d..8e77608 100644 --- a/pom.xml +++ b/pom.xml @@ -160,5 +160,10 @@ sqlite-jdbc 3.23.1 + + io.lumine + MythicMobs + 4.10.1 + From c923493134f43b78bc64a56d8c9ac42307e27492 Mon Sep 17 00:00:00 2001 From: Brianna Date: Mon, 26 Oct 2020 12:42:11 -0500 Subject: [PATCH 4/4] version 2.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8e77608..9188505 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ com.songoda UltimateStacker 4.0.0 - 2.0.10 + 2.1 clean install UltimateStacker-${project.version}