diff --git a/pom.xml b/pom.xml
index a29c55494..fdab99147 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
me.lokka30
LevelledMobs
- 3.8.2 b721
+ 3.9.0 b727
jar
LevelledMobs
The Ultimate RPG Mob Levelling Plugin
@@ -33,38 +33,6 @@
net.md-5
specialsource-maven-plugin
1.2.2
-
-
- package
-
- remap
-
- remap-obf
-
- org.spigotmc:minecraft-server:1.19.2-R0.1-SNAPSHOT:txt:maps-mojang
- true
- org.spigotmc:spigot:1.19.2-R0.1-SNAPSHOT:jar:remapped-mojang
-
- true
- remapped-obf
-
-
-
- package
-
- remap
-
- remap-spigot
-
-
- ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar
-
- org.spigotmc:minecraft-server:1.19.2-R0.1-SNAPSHOT:csrg:maps-spigot
- org.spigotmc:spigot:1.19.2-R0.1-SNAPSHOT:jar:remapped-obf
-
-
-
-
org.apache.maven.plugins
@@ -188,13 +156,6 @@
1.19.2-R0.1-SNAPSHOT
provided
-
- org.spigotmc
- spigot
- 1.19.2-R0.1-SNAPSHOT
- remapped-mojang
- provided
-
org.bstats
bstats-bukkit
@@ -228,7 +189,7 @@
com.google.code.gson
gson
- 2.9.0
+ 2.10
provided
diff --git a/src/main/java/me/lokka30/levelledmobs/LevelledMobs.java b/src/main/java/me/lokka30/levelledmobs/LevelledMobs.java
index d9fbb680b..1aae085e5 100644
--- a/src/main/java/me/lokka30/levelledmobs/LevelledMobs.java
+++ b/src/main/java/me/lokka30/levelledmobs/LevelledMobs.java
@@ -31,6 +31,7 @@
import me.lokka30.levelledmobs.misc.NamespacedKeys;
import me.lokka30.levelledmobs.misc.NametagTimerChecker;
import me.lokka30.levelledmobs.misc.YmlParsingHelper;
+import me.lokka30.levelledmobs.nms.Definitions;
import me.lokka30.levelledmobs.rules.RulesManager;
import me.lokka30.levelledmobs.rules.RulesParsingManager;
import me.lokka30.levelledmobs.util.ConfigUtils;
@@ -76,6 +77,7 @@ public final class LevelledMobs extends JavaPlugin {
public YmlParsingHelper helperSettings;
public long playerLevellingMinRelevelTime;
public int maxPlayersRecorded;
+ private Definitions definitions;
private static LevelledMobs instance;
// Configuration
@@ -101,6 +103,7 @@ public void onLoad() {
public void onEnable() {
final QuickTimer timer = new QuickTimer();
+ this.definitions = new Definitions();
this.nametagQueueManager = new NametagQueueManager(this);
this.mobsQueueManager = new MobsQueueManager(this);
this.companion = new Companion(this);
@@ -207,6 +210,10 @@ public static LevelledMobs getInstance(){
return instance;
}
+ public @NotNull Definitions getDefinitions(){
+ return this.definitions;
+ }
+
@Override
public void onDisable() {
final QuickTimer disableTimer = new QuickTimer();
diff --git a/src/main/java/me/lokka30/levelledmobs/commands/subcommands/RulesSubcommand.java b/src/main/java/me/lokka30/levelledmobs/commands/subcommands/RulesSubcommand.java
index 7b2e36bb0..3b5cdcf09 100644
--- a/src/main/java/me/lokka30/levelledmobs/commands/subcommands/RulesSubcommand.java
+++ b/src/main/java/me/lokka30/levelledmobs/commands/subcommands/RulesSubcommand.java
@@ -157,7 +157,7 @@ private void forceRelevel(final CommandSender sender) {
for (final World world : Bukkit.getWorlds()) {
worldCount++;
for (final Entity entity : world.getEntities()) {
- if (!(entity instanceof LivingEntity)) {
+ if (!(entity instanceof LivingEntity) || entity instanceof Player) {
continue;
}
diff --git a/src/main/java/me/lokka30/levelledmobs/listeners/EntityDamageListener.java b/src/main/java/me/lokka30/levelledmobs/listeners/EntityDamageListener.java
index ed117c1e3..1ec0300b9 100644
--- a/src/main/java/me/lokka30/levelledmobs/listeners/EntityDamageListener.java
+++ b/src/main/java/me/lokka30/levelledmobs/listeners/EntityDamageListener.java
@@ -201,9 +201,9 @@ private void processRangedDamage2(@NotNull final LivingEntityWrapper shooter,
main.mobsQueueManager.addToQueue(new QueueItem(shooter, event));
}
- final double newDamage =
- event.getDamage() + main.mobDataManager.getAdditionsForLevel(shooter,
- Addition.CUSTOM_RANGED_ATTACK_DAMAGE, event.getDamage());
+ final float newDamage =
+ (float) event.getDamage() + main.mobDataManager.getAdditionsForLevel(shooter,
+ Addition.CUSTOM_RANGED_ATTACK_DAMAGE, (float) event.getDamage());
Utils.debugLog(main, DebugType.RANGED_DAMAGE_MODIFICATION, String.format(
"&7Source: &b%s&7 (lvl &b%s&7), damage: &b%s&7, new damage: &b%s&7",
shooter.getNameIfBaby(), shooter.getMobLevel(), event.getDamage(), newDamage));
@@ -238,7 +238,7 @@ private void processOtherRangedDamage(@NotNull final EntityDamageByEntityEvent e
final LivingEntityWrapper lmEntity = LivingEntityWrapper.getInstance(livingEntity, main);
event.setDamage(
main.mobDataManager.getAdditionsForLevel(lmEntity, Addition.CUSTOM_RANGED_ATTACK_DAMAGE,
- event.getDamage())); // use ranged attack damage value
+ (float) event.getDamage())); // use ranged attack damage value
Utils.debugLog(main, DebugType.RANGED_DAMAGE_MODIFICATION,
"New guardianDamage: &b" + event.getDamage());
lmEntity.free();
diff --git a/src/main/java/me/lokka30/levelledmobs/managers/LevelManager.java b/src/main/java/me/lokka30/levelledmobs/managers/LevelManager.java
index 4472244a2..b7b835cd4 100644
--- a/src/main/java/me/lokka30/levelledmobs/managers/LevelManager.java
+++ b/src/main/java/me/lokka30/levelledmobs/managers/LevelManager.java
@@ -544,7 +544,7 @@ public void setLevelledItemDrops(final LivingEntityWrapper lmEntity,
if (!doNotMultiplyDrops && !dropsToMultiply.isEmpty()) {
// Get currentDrops added per level valu
final double additionValue = main.mobDataManager.getAdditionsForLevel(lmEntity,
- Addition.CUSTOM_ITEM_DROP, 2.0);
+ Addition.CUSTOM_ITEM_DROP, 2.0f);
if (additionValue == -1) {
Utils.debugLog(main, DebugType.SET_LEVELLED_ITEM_DROPS, String.format(
"&7Mob: &b%s&7, mob-lvl: &b%s&7, removing any drops present",
@@ -611,7 +611,7 @@ public void multiplyDrop(final LivingEntityWrapper lmEntity,
// look thru the animal's inventory for leather. That is the only item that will get duplicated
for (final ItemStack item : chestItems) {
if (item.getType() == Material.LEATHER) {
- return Collections.singletonList(item);
+ return List.of(item);
}
}
@@ -669,7 +669,7 @@ public void removeVanillaDrops(@NotNull final LivingEntityWrapper lmEntity,
public int getLevelledExpDrops(@NotNull final LivingEntityWrapper lmEntity, final double xp) {
if (lmEntity.isLevelled()) {
final double dropAddition = main.mobDataManager.getAdditionsForLevel(lmEntity,
- Addition.CUSTOM_XP_DROP, 3.0);
+ Addition.CUSTOM_XP_DROP, 3.0f);
double newXp = 0;
if (dropAddition > -1) {
newXp = Math.round(xp + (xp * dropAddition));
@@ -1145,7 +1145,7 @@ private void checkLevelledEntity(@NotNull final LivingEntityWrapper lmEntity,
final boolean preserveMobName = !main.nametagQueueManager.nmsHandler.isUsingProtocolLib;
final NametagResult nametag = main.levelManager.getNametag(lmEntity, false, preserveMobName);
main.nametagQueueManager.addToQueue(
- new QueueItem(lmEntity, nametag, Collections.singletonList(player)));
+ new QueueItem(lmEntity, nametag, List.of(player)));
}
}
diff --git a/src/main/java/me/lokka30/levelledmobs/managers/MobDataManager.java b/src/main/java/me/lokka30/levelledmobs/managers/MobDataManager.java
index 4dbb8041e..ea7f7a1d7 100644
--- a/src/main/java/me/lokka30/levelledmobs/managers/MobDataManager.java
+++ b/src/main/java/me/lokka30/levelledmobs/managers/MobDataManager.java
@@ -13,6 +13,7 @@
import me.lokka30.levelledmobs.misc.CachedModalList;
import me.lokka30.levelledmobs.misc.DebugType;
import me.lokka30.levelledmobs.misc.LivingEntityWrapper;
+import me.lokka30.levelledmobs.rules.FineTuningAttributes;
import me.lokka30.levelledmobs.rules.VanillaBonusEnum;
import me.lokka30.levelledmobs.util.Utils;
import org.bukkit.Material;
@@ -90,9 +91,9 @@ void setAdditionsForLevel(@NotNull final LivingEntityWrapper lmEntity,
final @NotNull Attribute attribute, final Addition addition) {
final boolean useStaticValues = main.helperSettings.getBoolean(main.settingsCfg,
"attributes-use-preset-base-values");
- final double defaultValue = useStaticValues ?
- (double) Objects.requireNonNull(getAttributeDefaultValue(lmEntity, attribute)) :
- Objects.requireNonNull(lmEntity.getLivingEntity().getAttribute(attribute))
+ final float defaultValue = useStaticValues ?
+ (float) Objects.requireNonNull(getAttributeDefaultValue(lmEntity, attribute)) :
+ (float) Objects.requireNonNull(lmEntity.getLivingEntity().getAttribute(attribute))
.getBaseValue();
final double additionValue = getAdditionsForLevel(lmEntity, addition, defaultValue);
@@ -172,115 +173,44 @@ void setAdditionsForLevel(@NotNull final LivingEntityWrapper lmEntity,
}
}
- public final double getAdditionsForLevel(final LivingEntityWrapper lmEntity,
- final Addition addition, final double defaultValue) {
- final double maxLevel = main.rulesManager.getRuleMobMaxLevel(lmEntity);
-
- double attributeValue = 0;
- double attributeMax = 0;
-
- if (lmEntity.getFineTuningAttributes() != null) {
- switch (addition) {
- case CUSTOM_XP_DROP:
- if (lmEntity.getFineTuningAttributes().xpDrop != null) {
- attributeValue = lmEntity.getFineTuningAttributes().xpDrop;
- }
- if (attributeValue == -1.0) {
- return -1;
- }
- break;
- case CUSTOM_ITEM_DROP:
- if (lmEntity.getFineTuningAttributes().itemDrop != null) {
- attributeValue = lmEntity.getFineTuningAttributes().itemDrop;
- }
- if (attributeValue == -1.0) {
- return -1;
- }
- break;
- case ATTRIBUTE_MAX_HEALTH:
- if (lmEntity.getFineTuningAttributes().maxHealth != null) {
- attributeValue = lmEntity.getFineTuningAttributes().maxHealth;
- }
- break;
- case ATTRIBUTE_ATTACK_DAMAGE:
- if (lmEntity.getFineTuningAttributes().attackDamage != null) {
- attributeValue = lmEntity.getFineTuningAttributes().attackDamage;
- }
- break;
- case ATTRIBUTE_MOVEMENT_SPEED:
- if (lmEntity.getFineTuningAttributes().movementSpeed != null) {
- attributeValue = lmEntity.getFineTuningAttributes().movementSpeed;
- }
- break;
- case CUSTOM_RANGED_ATTACK_DAMAGE:
- if (lmEntity.getFineTuningAttributes().rangedAttackDamage != null) {
- attributeValue = lmEntity.getFineTuningAttributes().rangedAttackDamage;
- }
- break;
- case CREEPER_BLAST_DAMAGE:
- if (lmEntity.getFineTuningAttributes().creeperExplosionRadius != null) {
- attributeValue = lmEntity.getFineTuningAttributes().creeperExplosionRadius;
- }
- break;
- case ATTRIBUTE_HORSE_JUMP_STRENGTH:
- if (lmEntity.getFineTuningAttributes().horseJumpStrength != null) {
- attributeValue = lmEntity.getFineTuningAttributes().horseJumpStrength;
- }
- break;
- case ATTRIBUTE_ARMOR_BONUS:
- attributeMax = 30.0;
- if (lmEntity.getFineTuningAttributes().armorBonus != null) {
- attributeValue = lmEntity.getFineTuningAttributes().armorBonus;
- }
- break;
- case ATTRIBUTE_ARMOR_TOUGHNESS:
- attributeMax = 50.0;
- if (lmEntity.getFineTuningAttributes().armorToughness != null) {
- attributeValue = lmEntity.getFineTuningAttributes().armorToughness;
- }
- break;
- case ATTRIBUTE_ATTACK_KNOCKBACK:
- attributeMax = 5.0;
- if (lmEntity.getFineTuningAttributes().attackKnockback != null) {
- attributeValue = lmEntity.getFineTuningAttributes().attackKnockback;
- }
- break;
- case ATTRIBUTE_FLYING_SPEED:
- if (lmEntity.getFineTuningAttributes().flyingSpeed != null) {
- attributeValue = lmEntity.getFineTuningAttributes().flyingSpeed;
- }
- break;
- case ATTRIBUTE_KNOCKBACK_RESISTANCE:
- attributeMax = 1.0;
- if (lmEntity.getFineTuningAttributes().knockbackResistance != null) {
- attributeValue = lmEntity.getFineTuningAttributes().knockbackResistance;
- }
- break;
- case ATTRIBUTE_ZOMBIE_SPAWN_REINFORCEMENTS:
- attributeMax = 1.0;
- if (lmEntity.getFineTuningAttributes().zombieReinforcements != null) {
- attributeValue = lmEntity.getFineTuningAttributes().zombieReinforcements;
- }
- break;
- case ATTRIBUTE_FOLLOW_RANGE:
- if (lmEntity.getFineTuningAttributes().followRange != null) {
- attributeValue = lmEntity.getFineTuningAttributes().followRange;
- }
- break;
+ public final float getAdditionsForLevel(final LivingEntityWrapper lmEntity,
+ final Addition addition, final float defaultValue) {
+ final float maxLevel = main.rulesManager.getRuleMobMaxLevel(lmEntity);
+
+ //double attributeValue = 0;
+ final FineTuningAttributes fineTuning = lmEntity.getFineTuningAttributes();
+ FineTuningAttributes.Multiplier multiplier = null;
+ float attributeMax = 0;
+
+ if (fineTuning != null) {
+ multiplier = fineTuning.getItem(addition);
+ switch (addition){
+ case ATTRIBUTE_ARMOR_BONUS -> attributeMax = 30.0f;
+ case ATTRIBUTE_ARMOR_TOUGHNESS -> attributeMax = 50.0f;
+ case ATTRIBUTE_ATTACK_KNOCKBACK -> attributeMax = 5.0f;
+ case ATTRIBUTE_KNOCKBACK_RESISTANCE,
+ ATTRIBUTE_ZOMBIE_SPAWN_REINFORCEMENTS -> attributeMax = 1.0f;
}
}
- if (maxLevel == 0 || attributeValue == 0) {
- return 0.0;
+ if (maxLevel == 0 || multiplier == null) {
+ return 0.0f;
}
- // only used for 5 specific attributes
- if (attributeMax > 0.0) {
- return (lmEntity.getMobLevel() / maxLevel) * (attributeMax * attributeValue);
- } else
- // normal formula for most attributes
- {
- return (defaultValue * attributeValue) * ((lmEntity.getMobLevel()) / maxLevel);
+ final float multiplierValue = multiplier.value();
+
+ if (fineTuning.useStacked || multiplier.useStacked()){
+ return (float) lmEntity.getMobLevel() * multiplierValue;
+ }
+ else {
+ // only used for 5 specific attributes
+ if (attributeMax > 0.0) {
+ return (lmEntity.getMobLevel() / maxLevel) * (attributeMax * multiplierValue);
+ } else
+ // normal formula for most attributes
+ {
+ return (defaultValue * multiplierValue) * ((lmEntity.getMobLevel()) / maxLevel);
+ }
}
}
}
diff --git a/src/main/java/me/lokka30/levelledmobs/misc/LivingEntityWrapper.java b/src/main/java/me/lokka30/levelledmobs/misc/LivingEntityWrapper.java
index f1bf506ee..453d13ed9 100644
--- a/src/main/java/me/lokka30/levelledmobs/misc/LivingEntityWrapper.java
+++ b/src/main/java/me/lokka30/levelledmobs/misc/LivingEntityWrapper.java
@@ -63,7 +63,7 @@ private LivingEntityWrapper(final @NotNull LevelledMobs main) {
// privates:
private LivingEntity livingEntity;
- @NotNull private Set applicableGroups;
+ private @NotNull Set applicableGroups;
private boolean hasCache;
private boolean isBuildingCache;
private boolean groupsAreBuilt;
@@ -74,9 +74,9 @@ private LivingEntityWrapper(final @NotNull LevelledMobs main) {
private long nametagCooldownTime;
private String sourceSpawnerName;
private String sourceSpawnEggName;
- @NotNull private final List applicableRules;
+ private @NotNull final List applicableRules;
private List spawnedWGRegions;
- @NotNull private final List mobExternalTypes;
+ private @NotNull final List mobExternalTypes;
private FineTuningAttributes fineTuningAttributes;
private LevelledMobSpawnReason spawnReason;
private Player playerForLevelling;
@@ -105,7 +105,7 @@ private LivingEntityWrapper(final @NotNull LevelledMobs main) {
public Player playerForPermissionsCheck;
public CommandSender summonedSender;
- @NotNull public static LivingEntityWrapper getInstance(final LivingEntity livingEntity,
+ public @NotNull static LivingEntityWrapper getInstance(final LivingEntity livingEntity,
final @NotNull LevelledMobs main) {
final LivingEntityWrapper lew;
@@ -369,7 +369,7 @@ private void cachePrevChanceResults() {
}
}
- @Nullable public Map getPrevChanceRuleResults() {
+ public @Nullable Map getPrevChanceRuleResults() {
return this.prevChanceRuleResults;
}
@@ -377,11 +377,11 @@ public LivingEntity getLivingEntity() {
return this.livingEntity;
}
- @NotNull public String getTypeName() {
+ public @NotNull String getTypeName() {
return this.livingEntity.getType().toString();
}
- @NotNull public Set getApplicableGroups() {
+ public @NotNull Set getApplicableGroups() {
if (!groupsAreBuilt) {
this.applicableGroups = buildApplicableGroupsForMob();
groupsAreBuilt = true;
@@ -398,7 +398,7 @@ public long getNametagCooldownTime() {
return this.nametagCooldownTime;
}
- @Nullable public Player getPlayerForLevelling() {
+ public @Nullable Player getPlayerForLevelling() {
synchronized (playerLock) {
return this.playerForLevelling;
}
@@ -411,7 +411,7 @@ public void setPlayerForLevelling(final Player player) {
this.playerForPermissionsCheck = player;
}
- @Nullable public FineTuningAttributes getFineTuningAttributes() {
+ public @Nullable FineTuningAttributes getFineTuningAttributes() {
if (!hasCache) {
buildCache();
}
@@ -419,7 +419,7 @@ public void setPlayerForLevelling(final Player player) {
return this.fineTuningAttributes;
}
- @NotNull public List getApplicableRules() {
+ public @NotNull List getApplicableRules() {
if (!hasCache) {
buildCache();
}
@@ -445,7 +445,7 @@ public boolean isLevelled() {
return this.livingEntity.getType();
}
- @NotNull public PersistentDataContainer getPDC() {
+ public @NotNull PersistentDataContainer getPDC() {
return livingEntity.getPersistentDataContainer();
}
@@ -466,7 +466,7 @@ public boolean isBabyMob() {
return false;
}
- @NotNull public LevelledMobSpawnReason getSpawnReason() {
+ public @NotNull LevelledMobSpawnReason getSpawnReason() {
if (this.spawnReason != null) {
return this.spawnReason;
}
@@ -633,7 +633,7 @@ public void setSourceSpawnerName(final String name) {
}
}
- @Nullable public String getSourceSpawnerName() {
+ public @Nullable String getSourceSpawnerName() {
if (this.sourceSpawnerName != null) {
return this.sourceSpawnerName;
}
@@ -657,7 +657,7 @@ public void setSourceSpawnerName(final String name) {
return this.sourceSpawnerName;
}
- @Nullable public String getSourceSpawnEggName() {
+ public @Nullable String getSourceSpawnEggName() {
if (this.sourceSpawnEggName != null) {
return this.sourceSpawnEggName;
}
@@ -680,7 +680,7 @@ public void setSourceSpawnerName(final String name) {
return this.sourceSpawnEggName;
}
- @NotNull public String getNameIfBaby() {
+ public @NotNull String getNameIfBaby() {
return this.isBabyMob() ?
"BABY_" + getTypeName() :
getTypeName();
@@ -697,7 +697,7 @@ public void setMobExternalType(
}
}
- @NotNull public List getMobExternalTypes() {
+ public @NotNull List getMobExternalTypes() {
return this.mobExternalTypes;
}
@@ -717,7 +717,7 @@ public boolean hasOverridenEntityName() {
}
}
- @Nullable public String getOverridenEntityName() {
+ public @Nullable String getOverridenEntityName() {
if (!getPDCLock()) {
return null;
}
@@ -730,7 +730,7 @@ public boolean hasOverridenEntityName() {
}
}
- @NotNull public String getWGRegionName() {
+ public @NotNull String getWGRegionName() {
if (this.spawnedWGRegions == null || this.spawnedWGRegions.isEmpty()) {
return "";
}
@@ -843,7 +843,7 @@ public boolean isWasSummoned() {
return this.wasSummoned;
}
- @NotNull private Set buildApplicableGroupsForMob() {
+ private @NotNull Set buildApplicableGroupsForMob() {
final Set groups = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
for (final Map.Entry> mobGroup : main.customMobGroups.entrySet()) {
diff --git a/src/main/java/me/lokka30/levelledmobs/misc/NametagTimerChecker.java b/src/main/java/me/lokka30/levelledmobs/misc/NametagTimerChecker.java
index 91185dcd7..238b5e96e 100644
--- a/src/main/java/me/lokka30/levelledmobs/misc/NametagTimerChecker.java
+++ b/src/main/java/me/lokka30/levelledmobs/misc/NametagTimerChecker.java
@@ -1,6 +1,5 @@
package me.lokka30.levelledmobs.misc;
-
import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
@@ -10,6 +9,7 @@
import java.util.Queue;
import java.util.WeakHashMap;
import me.lokka30.levelledmobs.LevelledMobs;
+import me.lokka30.levelledmobs.result.NametagResult;
import me.lokka30.levelledmobs.rules.NametagVisibilityEnum;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@@ -107,8 +107,9 @@ public void checkNametags() {
final LivingEntityWrapper lmEntity = LivingEntityWrapper.getInstance(
livingEntity, main);
- main.levelManager.updateNametag(lmEntity,
- main.levelManager.getNametag(lmEntity, false), List.of(player));
+
+ final NametagResult nametag = main.levelManager.getNametag(lmEntity, false, true);
+ main.levelManager.updateNametag(lmEntity, nametag, List.of(player));
lmEntity.free();
}
diff --git a/src/main/java/me/lokka30/levelledmobs/nms/ComponentUtils.java b/src/main/java/me/lokka30/levelledmobs/nms/ComponentUtils.java
new file mode 100644
index 000000000..c1cc520ec
--- /dev/null
+++ b/src/main/java/me/lokka30/levelledmobs/nms/ComponentUtils.java
@@ -0,0 +1,88 @@
+package me.lokka30.levelledmobs.nms;
+
+import me.lokka30.levelledmobs.LevelledMobs;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class ComponentUtils {
+ public static void append(
+ final @NotNull Object component,
+ final @Nullable Object appendingComponent
+ ) {
+ if (appendingComponent == null) return;
+ final Definitions def = LevelledMobs.getInstance().getDefinitions();
+
+ try {
+ if (component.getClass() != def.clazz_IChatMutableComponent) {
+ throw new Exception("Invalid type: " + component.getClass().getName());
+ }
+
+ if (appendingComponent.getClass() != def.clazz_IChatMutableComponent){
+ throw new Exception("Invalid type: " + appendingComponent.getClass().getName());
+ }
+
+ def.method_ComponentAppend.invoke(component, appendingComponent);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static @NotNull Object getEmptyComponent() {
+ final Object result = getTextComponent(null);
+ assert result != null;
+ return result;
+ }
+
+ public static @Nullable Object getTextComponent(
+ final @Nullable String text
+ ) {
+ final Definitions def = LevelledMobs.getInstance().getDefinitions();
+ try {
+ if (text == null && def.getServerVersionInfo().getMinecraftVersion() >= 1.19) {
+ // #empty()
+ return def.method_EmptyComponent.invoke(null);
+ } else {
+ // #nullToEmpty(text)
+ return def.method_TextComponent.invoke(null, text);
+ }
+ } catch (Exception e){
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static @Nullable Object getTranslatableComponent(
+ final @NotNull String key
+ ) {
+ return getTranslatableComponent(key, (Object) null);
+ }
+
+ public static @Nullable Object getTranslatableComponent(
+ final @NotNull String key,
+ final @Nullable Object... args
+ ) {
+ final Definitions def = LevelledMobs.getInstance().getDefinitions();
+ try {
+ if (def.getServerVersionInfo().getMinecraftVersion() >= 1.19){
+ if (args == null || args.length == 0) {
+ return def.method_Translatable.invoke(null, key);
+ }
+ else {
+ return def.method_TranslatableWithArgs.invoke(null, key, args);
+ }
+ }
+ else{
+ if (args == null || args.length == 0) {
+ return def.clazz_TranslatableComponent.getConstructor(String.class).newInstance(key);
+ }
+ else {
+ return def.clazz_TranslatableComponent.getConstructor(
+ String.class, Object[].class).newInstance(key, args);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/me/lokka30/levelledmobs/nms/Definitions.java b/src/main/java/me/lokka30/levelledmobs/nms/Definitions.java
new file mode 100644
index 000000000..c09518167
--- /dev/null
+++ b/src/main/java/me/lokka30/levelledmobs/nms/Definitions.java
@@ -0,0 +1,379 @@
+package me.lokka30.levelledmobs.nms;
+
+import net.kyori.adventure.text.Component;
+import org.bukkit.entity.LivingEntity;
+import org.jetbrains.annotations.NotNull;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Optional;
+
+public class Definitions {
+ public Definitions(){
+ this.ver = new ServerVersionInfo();
+ build();
+ }
+
+ private final ServerVersionInfo ver;
+ private boolean hasKiori;
+ private boolean isOneNinteenThreeOrNewer;
+
+ // classes:
+ Class> clazz_IChatMutableComponent;
+ Class> clazz_IChatBaseComponent;
+ Class> clazz_TranslatableComponent;
+ Class> clazz_CraftLivingEntity;
+ Class> clazz_CraftEntity;
+ Class> clazz_Entity;
+ Class> clazz_DataWatcher;
+ Class> clazz_DataWatcher_Item;
+ Class> clazz_DataWatcherRegistry;
+ Class> clazz_DataWatcherObject;
+ Class> clazz_DataWatcherSerializer;
+ Class> clazz_ClientboundSetEntityDataPacket;
+ Class> clazz_CraftPlayer;
+ Class> clazz_Packet;
+ Class> clazz_PlayerConnection;
+ Class> clazz_ServerPlayerConnection;
+ Class> clazz_NetworkManager;
+ Class> clazz_EntityPlayer;
+ Class> clazz_PaperAdventure;
+ Class> clazz_EntityTypes;
+
+ // methods:
+ Method method_ComponentAppend;
+ Method method_EmptyComponent;
+ Method method_TextComponent;
+ Method method_Translatable;
+ Method method_TranslatableWithArgs;
+ Method method_getHandle;
+ Method method_getEntityData;
+ Method method_set;
+ Method method_getId;
+ Method method_PlayergetHandle;
+ Method method_Send;
+ Method method_getAll;
+ Method method_define;
+ Method method_getAccessor;
+ Method method_getValue;
+ Method method_AsVanilla;
+ Method method_EntityTypeByString;
+ Method method_GetDescriptionId;
+ Method method_getNonDefaultValues;
+ Method method_SynchedEntityData_Define;
+ Method method_DataWatcher_GetItem;
+ Method method_DataWatcherItem_Value;
+
+ // fields
+ Field field_OPTIONAL_COMPONENT;
+ Field field_BOOLEAN;
+ Field field_Connection;
+ Field field_Int2ObjectMap;
+
+ // Constructors
+ Constructor> ctor_EntityDataAccessor;
+ Constructor> ctor_SynchedEntityData;
+ Constructor> ctor_Packet;
+
+ private void build(){
+ this.isOneNinteenThreeOrNewer = ver.getMinecraftVersion() == 1.19 && ver.getRevision()>= 3 ||
+ ver.getMinecraftVersion() >= 1.20;
+
+ try {
+ buildClasses();
+
+ // build methods
+ getMethodComponentAppend();
+ getMethodTextComponents();
+ getMethodTranslatable();
+ buildSimpleMethods();
+ buildFields();
+ buildConstructors();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void buildClasses() throws ClassNotFoundException {
+ this.clazz_IChatMutableComponent = Class.forName(
+ "net.minecraft.network.chat.IChatMutableComponent");
+
+ this.clazz_IChatBaseComponent = Class.forName(
+ "net.minecraft.network.chat.IChatBaseComponent");
+
+ this.clazz_CraftEntity = Class.forName(
+ "org.bukkit.craftbukkit." + ver.getNMSVersion() + ".entity.CraftEntity");
+
+ this.clazz_CraftLivingEntity = Class.forName(
+ "org.bukkit.craftbukkit." + ver.getNMSVersion() + ".entity.CraftLivingEntity");
+
+ // net.minecraft.network.syncher.SynchedEntityData
+ this.clazz_DataWatcher = Class.forName(
+ "net.minecraft.network.syncher.DataWatcher");
+
+ this.clazz_DataWatcher_Item = Class.forName(
+ "net.minecraft.network.syncher.DataWatcher$Item");
+
+ this.clazz_DataWatcherRegistry = Class.forName(
+ "net.minecraft.network.syncher.DataWatcherRegistry");
+
+ this.clazz_Entity = Class.forName(
+ "net.minecraft.world.entity.Entity");
+
+ this.clazz_DataWatcherObject = Class.forName(
+ "net.minecraft.network.syncher.DataWatcherObject");
+
+ this.clazz_DataWatcherSerializer = Class.forName(
+ "net.minecraft.network.syncher.DataWatcherSerializer");
+
+ this.clazz_ClientboundSetEntityDataPacket = Class.forName(
+ "net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata");
+
+ this.clazz_CraftPlayer = Class.forName(
+ "org.bukkit.craftbukkit." + ver.getNMSVersion() + ".entity.CraftPlayer");
+
+ this.clazz_Packet = Class.forName(
+ "net.minecraft.network.protocol.Packet");
+
+ this.clazz_NetworkManager = Class.forName(
+ "net.minecraft.network.NetworkManager");
+
+ //net.minecraft.server.network.ServerPlayerConnection ->
+ // void send(net.minecraft.network.protocol.Packet) ->
+ this.clazz_PlayerConnection = Class.forName(
+ "net.minecraft.server.network.PlayerConnection");
+
+ this.clazz_ServerPlayerConnection = Class.forName(
+ "net.minecraft.server.network.ServerPlayerConnection");
+
+ // net.minecraft.server.level.ServerPlayer ->
+ this.clazz_EntityPlayer = Class.forName(
+ "net.minecraft.server.level.EntityPlayer");
+
+ if (ver.getMinecraftVersion() < 1.19) {
+ // this is basically TranslatableComponent
+ this.clazz_TranslatableComponent = Class.forName(
+ "net.minecraft.network.chat.ChatMessage");
+ }
+
+ try {
+ this.clazz_PaperAdventure = Class.forName(
+ "io.papermc.paper.adventure.PaperAdventure");
+ this.hasKiori = true;
+ }
+ catch (ClassNotFoundException ignored){ }
+
+ this.clazz_EntityTypes = Class.forName(
+ "net.minecraft.world.entity.EntityTypes");
+ }
+
+ private void getMethodComponentAppend() throws NoSuchMethodException {
+ // net.minecraft.network.chat.MutableComponent append(net.minecraft.network.chat.Component) ->
+ // 1.18 = b, 1.19.0 = a, 1.19.1 = b
+ String methodName = ver.getRevision() == 0 || ver.getMinecraftVersion() == 1.18
+ ? "a" : "b";
+
+ if (ver.getMinecraftVersion() <= 1.17)
+ methodName = "addSibling";
+
+ this.method_ComponentAppend = clazz_IChatMutableComponent.getDeclaredMethod(
+ methodName, this.clazz_IChatBaseComponent);
+ }
+
+ private void getMethodTextComponents() throws NoSuchMethodException{
+ // net.minecraft.network.chat.Component ->
+ // net.minecraft.network.chat.MutableComponent empty()
+
+ if (ver.getMinecraftVersion() >= 1.19) {
+ // 1.19.0 = g, 1.19.1 = h
+ final String methodName = ver.getRevision() == 0 ? "g" : "h";
+
+ // net.minecraft.network.chat.Component ->
+ // net.minecraft.network.chat.MutableComponent empty()
+ this.method_EmptyComponent = clazz_IChatBaseComponent.getDeclaredMethod(methodName);
+ }
+
+ // 1.18 doesn't have #empty(), instead use #nullToEmpty()
+ // net.minecraft.network.chat.Component -> qk:
+ // net.minecraft.network.chat.Component nullToEmpty(java.lang.String) -> a
+ this.method_TextComponent = clazz_IChatBaseComponent.getDeclaredMethod("a", String.class);
+
+ }
+
+ private void getMethodTranslatable() throws NoSuchMethodException {
+ if (ver.getMinecraftVersion() < 1.19) {
+ // 1.18 instantiates an object, so this method doesn't apply
+ return;
+ }
+
+ // net.minecraft.network.chat.Component ->
+ // net.minecraft.network.chat.MutableComponent translatable(java.lang.String)
+ // net.minecraft.network.chat.MutableComponent translatable(java.lang.String,java.lang.Object[])
+
+ this.method_Translatable = clazz_IChatBaseComponent.getDeclaredMethod("a");
+ this.method_TranslatableWithArgs = clazz_IChatBaseComponent.getDeclaredMethod("a", String.class, Object[].class);
+ }
+
+ @SuppressWarnings("deprecation")
+ public @NotNull String getTranslationKey(final @NotNull LivingEntity livingEntity){
+ // only needed for spigot. paper has a built-in method
+
+ // net.minecraft.world.entity.EntityType ->
+ // 300:300:java.util.Optional byString(java.lang.String) -> a
+ // public static Optional> byString(String s)
+
+ Optional> optionalResult;
+ try {
+ optionalResult = (Optional>)this.method_EntityTypeByString.invoke(null, livingEntity.getType().getName());
+
+ if (optionalResult.isEmpty()) {
+ return "";
+ }
+
+ // net.minecraft.world.entity.EntityTypes
+ return (String) method_GetDescriptionId.invoke(optionalResult.get());
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ e.printStackTrace();
+ }
+
+ return "";
+ }
+
+ private void buildSimpleMethods() throws NoSuchMethodException {
+ this.method_getHandle = clazz_CraftLivingEntity.getDeclaredMethod("getHandle");
+
+ // net.minecraft.network.syncher.SynchedEntityData getEntityData() ->
+
+ String methodName = this.isOneNinteenThreeOrNewer ?
+ "al" : "ai";
+ if (ver.getMinecraftVersion() <= 1.17)
+ methodName = "getDataWatcher";
+
+ // net.minecraft.network.syncher.SynchedEntityData getEntityData() ->
+ this.method_getEntityData = clazz_Entity.getMethod(methodName);
+
+ methodName = ver.getMinecraftVersion() >= 1.18 ?
+ "b" : "set";
+
+ // set(net.minecraft.network.syncher.EntityDataAccessor,java.lang.Object) ->
+ this.method_set = clazz_DataWatcher.getMethod(methodName, clazz_DataWatcherObject, Object.class);
+
+ // int getId() ->
+ methodName = this.isOneNinteenThreeOrNewer ?
+ "ah" : "ae";
+ if (ver.getMinecraftVersion() <= 1.17)
+ methodName = "getId";
+
+ this.method_getId = clazz_Entity.getDeclaredMethod(methodName);
+
+ this.method_PlayergetHandle = clazz_CraftPlayer.getDeclaredMethod("getHandle");
+
+ // net.minecraft.server.network.ServerGamePacketListenerImpl ->
+ // void send(net.minecraft.network.protocol.Packet) ->
+
+ methodName = ver.getMinecraftVersion() >= 1.18 ?
+ "a" : "sendPacket";
+ this.method_Send = clazz_ServerPlayerConnection.getDeclaredMethod(methodName, clazz_Packet);
+
+ methodName = ver.getMinecraftVersion() >= 1.18 ?
+ "c" : "getAll";
+ // java.util.List getAll() ->
+ this.method_getAll = clazz_DataWatcher.getDeclaredMethod(methodName);
+
+ methodName = ver.getMinecraftVersion() >= 1.18 ?
+ "a" : "register";
+
+ // net.minecraft.network.syncher.SynchedEntityData ->
+ // define(net.minecraft.network.syncher.EntityDataAccessor,java.lang.Object) ->
+ this.method_define = clazz_DataWatcher.getDeclaredMethod(methodName, clazz_DataWatcherObject, Object.class);
+
+ // net.minecraft.network.syncher.EntityDataAccessor getAccessor() ->
+ this.method_getAccessor = clazz_DataWatcher_Item.getDeclaredMethod("a");
+ // java.lang.Object getValue() ->
+ this.method_getValue = clazz_DataWatcher_Item.getDeclaredMethod("b");
+
+ // net.minecraft.network.Connection getConnection() ->
+ //this.method_getConnection = clazz_CraftPlayer.getDeclaredMethod("networkManager");
+
+ if (this.hasKiori)
+ this.method_AsVanilla = clazz_PaperAdventure.getDeclaredMethod("asVanilla", Component.class);
+
+ // java.util.Optional byString(java.lang.String) -> a
+ this.method_EntityTypeByString = clazz_EntityTypes.getDeclaredMethod("a", String.class);
+
+ // java.lang.String getDescriptionId() -> g
+ this.method_GetDescriptionId = clazz_EntityTypes.getDeclaredMethod("g");
+
+ if (this.getIsOneNinteenThreeOrNewer()){
+ // new methods here were added in 1.19.3
+
+ // java.util.List getNonDefaultValues() -> c
+ this.method_getNonDefaultValues = clazz_DataWatcher.getDeclaredMethod("c");
+
+ // define(net.minecraft.network.syncher.EntityDataAccessor,java.lang.Object) -> a
+ this.method_SynchedEntityData_Define = clazz_DataWatcher.getMethod("a", clazz_DataWatcherObject, Object.class);
+
+ // private DataWatcher.Item getItem(DataWatcherObject datawatcherobject)
+ // net.minecraft.network.syncher.SynchedEntityData$DataItem getItem(net.minecraft.network.syncher.EntityDataAccessor) -> b
+ this.method_DataWatcher_GetItem = clazz_DataWatcher.getDeclaredMethod("b", clazz_DataWatcherObject);
+ this.method_DataWatcher_GetItem.setAccessible(true);
+
+ // net.minecraft.network.syncher.SynchedEntityData$DataItem -> abq$a:
+ // net.minecraft.network.syncher.SynchedEntityData$DataValue value() -> e
+ this.method_DataWatcherItem_Value = clazz_DataWatcher_Item.getDeclaredMethod("e");
+ }
+ }
+
+ private void buildFields() throws NoSuchFieldException {
+ // net.minecraft.network.syncher.EntityDataSerializer OPTIONAL_COMPONENT
+ this.field_OPTIONAL_COMPONENT = clazz_DataWatcherRegistry.getDeclaredField("f");
+
+ // net.minecraft.network.syncher.EntityDataSerializer BOOLEAN
+ this.field_BOOLEAN = clazz_DataWatcherRegistry.getDeclaredField("i");
+
+ // net.minecraft.server.level.ServerPlayer ->
+ // net.minecraft.server.network.ServerGamePacketListenerImpl connection ->
+ this.field_Connection = clazz_EntityPlayer.getDeclaredField("b");
+
+ if (this.isOneNinteenThreeOrNewer){
+ // private final Int2ObjectMap> itemsById
+ this.field_Int2ObjectMap = clazz_DataWatcher.getDeclaredField("e");
+ this.field_Int2ObjectMap.setAccessible(true);
+ }
+ }
+
+ private void buildConstructors() throws NoSuchMethodException {
+ this.ctor_EntityDataAccessor = clazz_DataWatcherObject.getConstructor(
+ int.class, clazz_DataWatcherSerializer);
+
+ this.ctor_SynchedEntityData = clazz_DataWatcher.getConstructor(clazz_Entity);
+
+ if (this.isOneNinteenThreeOrNewer) {
+ // starting with 1.19.3 use this one:
+ // public net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata(int,java.util.List>)
+
+ this.ctor_Packet = clazz_ClientboundSetEntityDataPacket.getConstructor(
+ int.class, List.class);
+ }
+ else{
+ // up to 1.19.2 use this one:
+ this.ctor_Packet = clazz_ClientboundSetEntityDataPacket.getConstructor(
+ int.class, clazz_DataWatcher, boolean.class);
+ }
+ }
+
+ public boolean getHasKiori(){
+ return this.hasKiori;
+ }
+
+ public @NotNull ServerVersionInfo getServerVersionInfo(){
+ return this.ver;
+ }
+
+ public boolean getIsOneNinteenThreeOrNewer(){
+ return this.isOneNinteenThreeOrNewer;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/lokka30/levelledmobs/nms/KyoriNametags.java b/src/main/java/me/lokka30/levelledmobs/nms/KyoriNametags.java
index 57793b90a..fe2ad66fb 100644
--- a/src/main/java/me/lokka30/levelledmobs/nms/KyoriNametags.java
+++ b/src/main/java/me/lokka30/levelledmobs/nms/KyoriNametags.java
@@ -10,7 +10,7 @@
import java.lang.reflect.Method;
public class KyoriNametags {
- public static @NotNull net.minecraft.network.chat.Component generateComponent(
+ public static @NotNull Object generateComponent(
final @NotNull LivingEntity livingEntity, final @NotNull NametagResult nametagResult){
final String nametag = nametagResult.getNametagNonNull();
@@ -30,13 +30,12 @@ public class KyoriNametags {
try{
final Class> clazz = Class.forName("io.papermc.paper.adventure.PaperAdventure");
final Method asVanilla = clazz.getDeclaredMethod("asVanilla", Component.class);
- final Object mcComponent = asVanilla.invoke(clazz, result);
- return (net.minecraft.network.chat.Component) mcComponent;
+ return asVanilla.invoke(clazz, result);
}
catch (Exception e){
e.printStackTrace();
}
- return net.minecraft.network.chat.Component.empty();
+ return ComponentUtils.getEmptyComponent();
}
}
diff --git a/src/main/java/me/lokka30/levelledmobs/nms/MiscUtils.java b/src/main/java/me/lokka30/levelledmobs/nms/MiscUtils.java
index 0257659e6..8273e370c 100644
--- a/src/main/java/me/lokka30/levelledmobs/nms/MiscUtils.java
+++ b/src/main/java/me/lokka30/levelledmobs/nms/MiscUtils.java
@@ -1,7 +1,6 @@
package me.lokka30.levelledmobs.nms;
import me.lokka30.levelledmobs.LevelledMobs;
-import net.minecraft.nbt.CompoundTag;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.NotNull;
@@ -9,61 +8,19 @@
public class MiscUtils {
public static @NotNull String getNBTDump(final @NotNull LivingEntity livingEntity, final @NotNull LevelledMobs main){
- final ServerVersionInfo versionInfo = main.nametagQueueManager.nmsHandler.versionInfo;
- if (versionInfo.getMinecraftVersion() <= 1.16){
- return getNBTDump_1_16(livingEntity, versionInfo.getNMSVersion());
- }
+// final ServerVersionInfo versionInfo = main.nametagQueueManager.nmsHandler.versionInfo;
+// if (versionInfo.getMinecraftVersion() <= 1.16){
+// return getNBTDump_1_16(livingEntity, versionInfo.getNMSVersion());
+// }
+ final Definitions def = LevelledMobs.getInstance().getDefinitions();
try {
- final Class> clazz_CraftLivingEntity;
-
- clazz_CraftLivingEntity = Class.forName(
- "org.bukkit.craftbukkit." + versionInfo.getNMSVersion() + ".entity.CraftLivingEntity");
-
- final Method method_getHandle = clazz_CraftLivingEntity.getDeclaredMethod("getHandle");
- final net.minecraft.world.entity.LivingEntity internalLivingEntity = (net.minecraft.world.entity.LivingEntity) method_getHandle.invoke(
- livingEntity);
-
+ //final Method method_getHandle = def.clazz_CraftLivingEntity.getDeclaredMethod("getHandle");
+ final Object internalLivingEntity = def.method_getHandle.invoke(livingEntity);
final Class> compoundTagClazz = Class.forName("net.minecraft.nbt.NBTTagCompound");
final Object compoundTag = compoundTagClazz.getConstructor().newInstance();
-
- if (versionInfo.getMinecraftVersion() >= 1.18){
- internalLivingEntity.saveWithoutId((CompoundTag) compoundTag);
- }
- else {
- final Class> entityClazz = Class.forName("net.minecraft.world.entity.Entity");
- final Method saveWithoutId = entityClazz.getDeclaredMethod("save", compoundTagClazz);
- saveWithoutId.invoke(internalLivingEntity, compoundTag);
- }
- return compoundTag.toString();
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return "";
- }
-
- private static @NotNull String getNBTDump_1_16(final @NotNull LivingEntity livingEntity, final String nmsVersion){
- final String compoundTagName = "net.minecraft.server.v1_16_R3.NBTTagCompound";
- final String methodName = "save";
-
- try {
- final Class> clazz_CraftLivingEntity;
-
- clazz_CraftLivingEntity = Class.forName(
- "org.bukkit.craftbukkit." + nmsVersion + ".entity.CraftLivingEntity");
- final Method method_getHandle = clazz_CraftLivingEntity.getDeclaredMethod("getHandle");
-
- // net.minecraft.server.v1_16_R3.EntityLiving
- final Object internalLivingEntity = method_getHandle.invoke(livingEntity);
-
- final Class> compoundTagClazz = Class.forName(compoundTagName);
- final Object compoundTag = compoundTagClazz.getConstructor().newInstance();
-
- final Class> clazz_Entity = Class.forName("net.minecraft.server." + nmsVersion + ".Entity");
- final Method saveWithoutId = clazz_Entity.getDeclaredMethod(methodName, compoundTagClazz);
+ final Method saveWithoutId = def.clazz_Entity.getDeclaredMethod("e", compoundTagClazz);
saveWithoutId.invoke(internalLivingEntity, compoundTag);
-
return compoundTag.toString();
} catch (Exception e) {
e.printStackTrace();
@@ -71,4 +28,34 @@ public class MiscUtils {
return "";
}
+
+// private static @NotNull String getNBTDump_1_16(final @NotNull LivingEntity livingEntity, final String nmsVersion){
+// final String compoundTagName = "net.minecraft.server.v1_16_R3.NBTTagCompound";
+// final String methodName = "save";
+// final Definitions def = LevelledMobs.getInstance().getDefinitions();
+//
+// try {
+// final Class> clazz_CraftLivingEntity;
+//
+// clazz_CraftLivingEntity = Class.forName(
+// "org.bukkit.craftbukkit." + nmsVersion + ".entity.CraftLivingEntity");
+// final Method method_getHandle = clazz_CraftLivingEntity.getDeclaredMethod("getHandle");
+//
+// // net.minecraft.server.v1_16_R3.EntityLiving
+// final Object internalLivingEntity = method_getHandle.invoke(livingEntity);
+//
+// final Class> compoundTagClazz = Class.forName(compoundTagName);
+// final Object compoundTag = compoundTagClazz.getConstructor().newInstance();
+//
+// //final Class> clazz_Entity = Class.forName("net.minecraft.server." + nmsVersion + ".Entity");
+// final Method saveWithoutId = def.clazz_Entity.getDeclaredMethod(methodName, compoundTagClazz);
+// saveWithoutId.invoke(internalLivingEntity, compoundTag);
+//
+// return compoundTag.toString();
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+//
+// return "";
+// }
}
diff --git a/src/main/java/me/lokka30/levelledmobs/nms/NMSHandler.java b/src/main/java/me/lokka30/levelledmobs/nms/NMSHandler.java
index e1a35b057..87ebe1f34 100644
--- a/src/main/java/me/lokka30/levelledmobs/nms/NMSHandler.java
+++ b/src/main/java/me/lokka30/levelledmobs/nms/NMSHandler.java
@@ -35,11 +35,13 @@ public NMSHandler(final @NotNull LevelledMobs main) {
// supported is paper >= 1.18 or spigot >= 1.19
// otherwise protocollib is used
- if (hasPaper && versionInfo.getMinecraftVersion() >= 1.18 ||
- !hasPaper && versionInfo.getMinecraftVersion() >= 1.19) {
+ //if (hasPaper && versionInfo.getMinecraftVersion() >= 1.18 ||
+ // !hasPaper && versionInfo.getMinecraftVersion() >= 1.19) {
+
+ if (versionInfo.getMinecraftVersion() >= 1.17) {
// 1.18 and newer we support with direct nms (Paper)
// or 1.19 spigot and newer
- this.currentUtil = new NametagSender(versionInfo, hasPaper);
+ this.currentUtil = new NametagSender();
Utils.logger.info(
String.format("Using NMS version %s for nametag support", versionInfo.getNMSVersion()));
} else if (ExternalCompatibilityManager.hasProtocolLibInstalled()) {
diff --git a/src/main/java/me/lokka30/levelledmobs/nms/NametagSender.java b/src/main/java/me/lokka30/levelledmobs/nms/NametagSender.java
index 5edf23778..abc34a71c 100644
--- a/src/main/java/me/lokka30/levelledmobs/nms/NametagSender.java
+++ b/src/main/java/me/lokka30/levelledmobs/nms/NametagSender.java
@@ -1,18 +1,15 @@
package me.lokka30.levelledmobs.nms;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
import java.util.Optional;
+import me.lokka30.levelledmobs.LevelledMobs;
import me.lokka30.levelledmobs.result.NametagResult;
import me.lokka30.microlib.messaging.MessageUtils;
-import net.minecraft.network.chat.Component;
-import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
-import net.minecraft.network.syncher.EntityDataAccessor;
-import net.minecraft.network.syncher.EntityDataSerializers;
-import net.minecraft.network.syncher.SynchedEntityData;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.world.entity.Entity;
+import org.bukkit.Bukkit;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
@@ -24,123 +21,175 @@
* @author stumper66
* @since 3.6.0
*/
+@SuppressWarnings("unchecked")
public class NametagSender implements NMSUtil {
- public NametagSender(final @NotNull ServerVersionInfo versionInfo, final boolean hasKiori) {
- this.versionInfo = versionInfo;
- this.nmsVersion = versionInfo.getNMSVersion();
- this.hasKiori = hasKiori;
- buildReflection();
+ public NametagSender() {
+ this.def = LevelledMobs.getInstance().getDefinitions();
}
- private final ServerVersionInfo versionInfo;
- private final String nmsVersion;
- private final boolean hasKiori;
- private Method resolveStringMethod;
- private Method emptyComponentMethod;
- private Method appendComponentMethod;
- private Method nullToEmptyMethod;
- private Class> clazz_CraftChatMessage;
- private Class> clazz_TranslatableComponent;
+ private final Definitions def;
- private void buildReflection(){
- String methodName;
+ public void sendNametag(final @NotNull LivingEntity livingEntity, final @NotNull NametagResult nametag,
+ final @NotNull Player player, final boolean doAlwaysVisible) {
+
+ if (!player.isOnline() || !player.isValid()) return;
+
+ final Runnable runnable = () -> sendNametagNonAsync(livingEntity, nametag, player, doAlwaysVisible);
+
+ Bukkit.getScheduler().runTask(LevelledMobs.getInstance(), runnable);
+ }
+
+ private void sendNametagNonAsync(final @NotNull LivingEntity livingEntity, final @NotNull NametagResult nametag,
+ final @NotNull Player player, final boolean doAlwaysVisible) {
try {
- // we're only here if we have:
- // Paper 1.18.0 +
- // Spigot 1.19.0 +
+ // livingEntity.getHandle()
+ final Object internalLivingEntity = def.method_getHandle.invoke(livingEntity);
+ // internalLivingEntity.getEntityData()
+ final Object entityDataPreClone = def.method_getEntityData.invoke(internalLivingEntity);
+ final Object entityData = cloneEntityData(entityDataPreClone, internalLivingEntity);
+
+ if (entityData == null){
+ return;
+ }
+
+ //final Object entityData = entityDataPreClone;
+ final Object optionalComponent = def.field_OPTIONAL_COMPONENT.get(def.clazz_DataWatcherRegistry);
- this.clazz_CraftChatMessage = Class.forName(
- "org.bukkit.craftbukkit." + nmsVersion + ".util.CraftChatMessage");
+ // final EntityDataAccessor> customNameAccessor =
+ // //new EntityDataAccessor<>(2, EntityDataSerializers.OPTIONAL_COMPONENT);
+ final Object customNameAccessor = def.ctor_EntityDataAccessor.newInstance(2, optionalComponent);
+ final Optional