mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2025-06-27 11:14:44 +02:00
Memory leak fixes, optimizations, and persistence
This commit is contained in:
@ -0,0 +1,37 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.compat.layers.persistentdata.SpigotPersistentDataLayer_1_13;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
public class TransientMetadataTools {
|
||||
private final mcMMO pluginRef;
|
||||
|
||||
public TransientMetadataTools(mcMMO pluginRef) {
|
||||
this.pluginRef = pluginRef;
|
||||
}
|
||||
|
||||
public void cleanAllMobMetadata(LivingEntity livingEntity) {
|
||||
//Since its not written anywhere, apparently the GC won't touch objects with metadata still present on them
|
||||
if (livingEntity.hasMetadata(mcMMO.customNameKey)) {
|
||||
livingEntity.setCustomName(livingEntity.getMetadata(mcMMO.customNameKey).get(0).asString());
|
||||
livingEntity.removeMetadata(mcMMO.customNameKey, pluginRef);
|
||||
}
|
||||
|
||||
//Involved in changing mob names to hearts
|
||||
if (livingEntity.hasMetadata(mcMMO.customVisibleKey)) {
|
||||
livingEntity.setCustomNameVisible(livingEntity.getMetadata(mcMMO.customVisibleKey).get(0).asBoolean());
|
||||
livingEntity.removeMetadata(mcMMO.customVisibleKey, pluginRef);
|
||||
}
|
||||
|
||||
//Gets assigned to endermen, potentially doesn't get cleared before this point
|
||||
if(livingEntity.hasMetadata(mcMMO.travelingBlock)) {
|
||||
livingEntity.removeMetadata(mcMMO.travelingBlock, pluginRef);
|
||||
}
|
||||
|
||||
//1.13.2 uses transient mob flags and needs to be cleaned up
|
||||
if(mcMMO.getCompatibilityManager().getPersistentDataLayer() instanceof SpigotPersistentDataLayer_1_13) {
|
||||
mcMMO.getCompatibilityManager().getPersistentDataLayer().removeMobFlags(livingEntity);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,32 +1,128 @@
|
||||
package com.gmail.nossr50.util.compat.layers.persistentdata;
|
||||
|
||||
import com.gmail.nossr50.api.exceptions.IncompleteNamespacedKeyRegister;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.compat.layers.AbstractCompatibilityLayer;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.Furnace;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class AbstractPersistentDataLayer extends AbstractCompatibilityLayer {
|
||||
|
||||
public static final String LEGACY_ABILITY_TOOL_LORE = "mcMMO Ability Tool";
|
||||
public final NamespacedKey superAbilityBoosted;
|
||||
public final String SUPER_ABILITY_BOOSTED = "super_ability_boosted";
|
||||
protected final @NotNull NamespacedKey NSK_SUPER_ABILITY_BOOSTED_ITEM;
|
||||
protected final @NotNull NamespacedKey NSK_MOB_SPAWNER_MOB;
|
||||
protected final @NotNull NamespacedKey NSK_EGG_MOB;
|
||||
protected final @NotNull NamespacedKey NSK_NETHER_GATE_MOB;
|
||||
protected final @NotNull NamespacedKey NSK_COTW_SUMMONED_MOB;
|
||||
protected final @NotNull NamespacedKey NSK_PLAYER_BRED_MOB;
|
||||
protected final @NotNull NamespacedKey NSK_PLAYER_TAMED_MOB;
|
||||
protected final @NotNull NamespacedKey NSK_VILLAGER_TRADE_ORIGIN_ITEM;
|
||||
protected final @NotNull NamespacedKey NSK_EXPLOITED_ENDERMEN;
|
||||
|
||||
//Never change these constants
|
||||
public final @NotNull String STR_SUPER_ABILITY_BOOSTED_ITEM = "super_ability_boosted";
|
||||
public final @NotNull String STR_MOB_SPAWNER_MOB = "mcmmo_mob_spawner_mob";
|
||||
public final @NotNull String STR_EGG_MOB = "mcmmo_egg_mob";
|
||||
public final @NotNull String STR_NETHER_PORTAL_MOB = "mcmmo_nethergate_mob";
|
||||
public final @NotNull String STR_COTW_SUMMONED_MOB = "mcmmo_cotw_summoned_mob";
|
||||
public final @NotNull String STR_PLAYER_BRED_MOB = "mcmmo_player_bred_mob";
|
||||
public final @NotNull String STR_PLAYER_TAMED_MOB = "mcmmo_player_tamed_mob";
|
||||
public final @NotNull String STR_VILLAGER_TRADE_ORIGIN_ITEM = "mcmmo_villager_trade_origin_item";
|
||||
public final @NotNull String STR_EXPLOITED_ENDERMEN = "mcmmo_exploited_endermen";
|
||||
|
||||
/*
|
||||
* Don't modify these keys
|
||||
*/
|
||||
public final @NotNull String STR_FURNACE_UUID_MOST_SIG = "furnace_uuid_most_sig";
|
||||
public final @NotNull String STR_FURNACE_UUID_LEAST_SIG = "furnace_uuid_least_sig";
|
||||
|
||||
protected final @NotNull NamespacedKey NSK_FURNACE_UUID_MOST_SIG;
|
||||
protected final @NotNull NamespacedKey NSK_FURNACE_UUID_LEAST_SIG;
|
||||
|
||||
public final @NotNull String LEGACY_ABILITY_TOOL_LORE = "mcMMO Ability Tool";
|
||||
|
||||
protected static final byte SIMPLE_FLAG_VALUE = (byte) 0x1;
|
||||
|
||||
public AbstractPersistentDataLayer() {
|
||||
superAbilityBoosted = getNamespacedKey(SUPER_ABILITY_BOOSTED);
|
||||
NSK_SUPER_ABILITY_BOOSTED_ITEM = getNamespacedKey(STR_SUPER_ABILITY_BOOSTED_ITEM);
|
||||
NSK_MOB_SPAWNER_MOB = getNamespacedKey(STR_MOB_SPAWNER_MOB);
|
||||
NSK_EGG_MOB = getNamespacedKey(STR_EGG_MOB);
|
||||
NSK_NETHER_GATE_MOB = getNamespacedKey(STR_NETHER_PORTAL_MOB);
|
||||
NSK_COTW_SUMMONED_MOB = getNamespacedKey(STR_COTW_SUMMONED_MOB);
|
||||
NSK_PLAYER_BRED_MOB = getNamespacedKey(STR_PLAYER_BRED_MOB);
|
||||
NSK_PLAYER_TAMED_MOB = getNamespacedKey(STR_PLAYER_TAMED_MOB);
|
||||
NSK_VILLAGER_TRADE_ORIGIN_ITEM = getNamespacedKey(STR_VILLAGER_TRADE_ORIGIN_ITEM);
|
||||
NSK_EXPLOITED_ENDERMEN = getNamespacedKey(STR_EXPLOITED_ENDERMEN);
|
||||
NSK_FURNACE_UUID_MOST_SIG = getNamespacedKey(STR_FURNACE_UUID_MOST_SIG);
|
||||
NSK_FURNACE_UUID_LEAST_SIG = getNamespacedKey(STR_FURNACE_UUID_LEAST_SIG);
|
||||
|
||||
initializeLayer();
|
||||
}
|
||||
|
||||
public @NotNull NamespacedKey getNamespacedKey(@NotNull String key) {
|
||||
|
||||
/**
|
||||
* Helper method to simplify generating namespaced keys
|
||||
* @param key the {@link String} value of the key
|
||||
* @return the generated {@link NamespacedKey}
|
||||
*/
|
||||
private @NotNull NamespacedKey getNamespacedKey(@NotNull String key) {
|
||||
return new NamespacedKey(mcMMO.p, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not a target {@link LivingEntity} has a specific mcMMO mob flags
|
||||
* @param flag the type of mob flag to check for
|
||||
* @param livingEntity the living entity to check for metadata
|
||||
* @return true if the mob has metadata values for target {@link MobMetaFlagType}
|
||||
*/
|
||||
public abstract boolean hasMobFlag(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity);
|
||||
|
||||
/**
|
||||
* Whether or not a target {@link LivingEntity} has any mcMMO mob flags
|
||||
* @param livingEntity the living entity to check for metadata
|
||||
* @return true if the mob has any mcMMO mob related metadata values
|
||||
*/
|
||||
public abstract boolean hasMobFlags(@NotNull LivingEntity livingEntity);
|
||||
|
||||
/**
|
||||
* Copies all mcMMO mob flags from one {@link LivingEntity} to another {@link LivingEntity}
|
||||
* This does not clear existing mcMMO mob flags on the target
|
||||
* @param sourceEntity entity to copy from
|
||||
* @param targetEntity entity to copy to
|
||||
*/
|
||||
public abstract void addMobFlags(@NotNull LivingEntity sourceEntity, @NotNull LivingEntity targetEntity);
|
||||
|
||||
/**
|
||||
* Adds a mob flag to a {@link LivingEntity} which effectively acts a true/false boolean
|
||||
* Existence of the flag can be considered a true value, non-existence can be considered false for all intents and purposes
|
||||
* @param flag the desired flag to assign
|
||||
* @param livingEntity the target living entity
|
||||
*/
|
||||
public abstract void flagMetadata(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity);
|
||||
|
||||
/**
|
||||
* Removes a specific mob flag from target {@link LivingEntity}
|
||||
* @param flag desired flag to remove
|
||||
* @param livingEntity the target living entity
|
||||
*/
|
||||
public abstract void removeMobFlag(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity);
|
||||
|
||||
/**
|
||||
* Remove all mcMMO related mob flags from the target {@link LivingEntity}
|
||||
* @param livingEntity target entity
|
||||
*/
|
||||
public void removeMobFlags(@NotNull LivingEntity livingEntity) {
|
||||
for(MobMetaFlagType flag : MobMetaFlagType.values()) {
|
||||
removeMobFlag(flag, livingEntity);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract @Nullable UUID getFurnaceOwner(@NotNull Furnace furnace);
|
||||
|
||||
public abstract void setFurnaceOwner(@NotNull Furnace furnace, @NotNull UUID uuid);
|
||||
@ -39,7 +135,7 @@ public abstract class AbstractPersistentDataLayer extends AbstractCompatibilityL
|
||||
|
||||
public abstract void removeBonusDigSpeedOnSuperAbilityTool(@NotNull ItemStack itemStack);
|
||||
|
||||
public boolean isLegacyAbilityTool(ItemStack itemStack) {
|
||||
public boolean isLegacyAbilityTool(@NotNull ItemStack itemStack) {
|
||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||
|
||||
if(itemMeta == null)
|
||||
@ -53,7 +149,7 @@ public abstract class AbstractPersistentDataLayer extends AbstractCompatibilityL
|
||||
return lore.contains(LEGACY_ABILITY_TOOL_LORE);
|
||||
}
|
||||
|
||||
public static String getLegacyAbilityToolLore() {
|
||||
public @NotNull String getLegacyAbilityToolLore() {
|
||||
return LEGACY_ABILITY_TOOL_LORE;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
package com.gmail.nossr50.util.compat.layers.persistentdata;
|
||||
|
||||
public enum MobMetaFlagType {
|
||||
MOB_SPAWNER_MOB,
|
||||
EGG_MOB,
|
||||
NETHER_PORTAL_MOB,
|
||||
COTW_SUMMONED_MOB,
|
||||
PLAYER_BRED_MOB,
|
||||
PLAYER_TAMED_MOB,
|
||||
EXPLOITED_ENDERMEN,
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
package com.gmail.nossr50.util.compat.layers.persistentdata;
|
||||
|
||||
import com.gmail.nossr50.api.exceptions.IncompleteNamespacedKeyRegister;
|
||||
import com.gmail.nossr50.datatypes.meta.UUIDMeta;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.block.Furnace;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.tags.CustomItemTagContainer;
|
||||
@ -11,6 +13,7 @@ import org.bukkit.inventory.meta.tags.ItemTagType;
|
||||
import org.bukkit.metadata.Metadatable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -18,19 +21,94 @@ import java.util.UUID;
|
||||
*/
|
||||
public class SpigotPersistentDataLayer_1_13 extends AbstractPersistentDataLayer {
|
||||
|
||||
private final String FURNACE_OWNER_METADATA_KEY = "mcMMO_furnace_owner";
|
||||
private final @NotNull String KEY_FURNACE_OWNER = "mcMMO_furnace_owner";
|
||||
private final @NotNull EnumMap<MobMetaFlagType, String> mobFlagKeyMap;
|
||||
|
||||
public SpigotPersistentDataLayer_1_13() {
|
||||
mobFlagKeyMap = new EnumMap<>(MobMetaFlagType.class);
|
||||
initMobFlagKeyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initializeLayer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void initMobFlagKeyMap() throws IncompleteNamespacedKeyRegister {
|
||||
for(MobMetaFlagType flagType : MobMetaFlagType.values()) {
|
||||
switch(flagType) {
|
||||
case MOB_SPAWNER_MOB:
|
||||
mobFlagKeyMap.put(flagType, STR_MOB_SPAWNER_MOB);
|
||||
break;
|
||||
case EGG_MOB:
|
||||
mobFlagKeyMap.put(flagType, STR_EGG_MOB);
|
||||
break;
|
||||
case NETHER_PORTAL_MOB:
|
||||
mobFlagKeyMap.put(flagType, STR_NETHER_PORTAL_MOB);
|
||||
break;
|
||||
case COTW_SUMMONED_MOB:
|
||||
mobFlagKeyMap.put(flagType, STR_COTW_SUMMONED_MOB);
|
||||
break;
|
||||
case PLAYER_BRED_MOB:
|
||||
mobFlagKeyMap.put(flagType, STR_PLAYER_BRED_MOB);
|
||||
break;
|
||||
case PLAYER_TAMED_MOB:
|
||||
mobFlagKeyMap.put(flagType, STR_PLAYER_TAMED_MOB);
|
||||
break;
|
||||
case EXPLOITED_ENDERMEN:
|
||||
mobFlagKeyMap.put(flagType, STR_EXPLOITED_ENDERMEN);
|
||||
break;
|
||||
default:
|
||||
throw new IncompleteNamespacedKeyRegister("Missing flag register for: "+flagType.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMobFlag(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
|
||||
return livingEntity.hasMetadata(mobFlagKeyMap.get(flag));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMobFlags(@NotNull LivingEntity livingEntity) {
|
||||
for(String currentKey : mobFlagKeyMap.values()) {
|
||||
if(livingEntity.hasMetadata(currentKey)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMobFlags(@NotNull LivingEntity sourceEntity, @NotNull LivingEntity targetEntity) {
|
||||
for(MobMetaFlagType flag : MobMetaFlagType.values()) {
|
||||
if(hasMobFlag(flag, sourceEntity)) {
|
||||
flagMetadata(flag, targetEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flagMetadata(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
|
||||
if(!hasMobFlag(flag, livingEntity)) {
|
||||
livingEntity.setMetadata(mobFlagKeyMap.get(flag), mcMMO.metadataValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMobFlag(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
|
||||
if(hasMobFlag(flag, livingEntity)) {
|
||||
livingEntity.removeMetadata(mobFlagKeyMap.get(flag), mcMMO.p);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getFurnaceOwner(@NotNull Furnace furnace) {
|
||||
Metadatable metadatable = (Metadatable) furnace;
|
||||
|
||||
if(metadatable.getMetadata(FURNACE_OWNER_METADATA_KEY).size() > 0) {
|
||||
UUIDMeta uuidMeta = (UUIDMeta) metadatable.getMetadata(FURNACE_OWNER_METADATA_KEY).get(0);
|
||||
if(metadatable.getMetadata(KEY_FURNACE_OWNER).size() > 0) {
|
||||
UUIDMeta uuidMeta = (UUIDMeta) metadatable.getMetadata(KEY_FURNACE_OWNER).get(0);
|
||||
return (UUID) uuidMeta.value();
|
||||
} else {
|
||||
return null;
|
||||
@ -41,11 +119,11 @@ public class SpigotPersistentDataLayer_1_13 extends AbstractPersistentDataLayer
|
||||
public void setFurnaceOwner(@NotNull Furnace furnace, @NotNull UUID uuid) {
|
||||
Metadatable metadatable = (Metadatable) furnace;
|
||||
|
||||
if(metadatable.getMetadata(FURNACE_OWNER_METADATA_KEY).size() > 0) {
|
||||
metadatable.removeMetadata(FURNACE_OWNER_METADATA_KEY, mcMMO.p);
|
||||
if(metadatable.getMetadata(KEY_FURNACE_OWNER).size() > 0) {
|
||||
metadatable.removeMetadata(KEY_FURNACE_OWNER, mcMMO.p);
|
||||
}
|
||||
|
||||
metadatable.setMetadata(FURNACE_OWNER_METADATA_KEY, new UUIDMeta(mcMMO.p, uuid));
|
||||
metadatable.setMetadata(KEY_FURNACE_OWNER, new UUIDMeta(mcMMO.p, uuid));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -57,7 +135,7 @@ public class SpigotPersistentDataLayer_1_13 extends AbstractPersistentDataLayer
|
||||
return;
|
||||
}
|
||||
|
||||
itemMeta.getCustomTagContainer().setCustomTag(superAbilityBoosted, ItemTagType.INTEGER, originalDigSpeed);
|
||||
itemMeta.getCustomTagContainer().setCustomTag(NSK_SUPER_ABILITY_BOOSTED_ITEM, ItemTagType.INTEGER, originalDigSpeed);
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
}
|
||||
|
||||
@ -69,7 +147,7 @@ public class SpigotPersistentDataLayer_1_13 extends AbstractPersistentDataLayer
|
||||
return false;
|
||||
|
||||
CustomItemTagContainer tagContainer = itemMeta.getCustomTagContainer();
|
||||
return tagContainer.hasCustomTag(superAbilityBoosted, ItemTagType.INTEGER);
|
||||
return tagContainer.hasCustomTag(NSK_SUPER_ABILITY_BOOSTED_ITEM, ItemTagType.INTEGER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -81,8 +159,8 @@ public class SpigotPersistentDataLayer_1_13 extends AbstractPersistentDataLayer
|
||||
|
||||
CustomItemTagContainer tagContainer = itemMeta.getCustomTagContainer();
|
||||
|
||||
if(tagContainer.hasCustomTag(superAbilityBoosted , ItemTagType.INTEGER)) {
|
||||
return tagContainer.getCustomTag(superAbilityBoosted, ItemTagType.INTEGER);
|
||||
if(tagContainer.hasCustomTag(NSK_SUPER_ABILITY_BOOSTED_ITEM, ItemTagType.INTEGER)) {
|
||||
return tagContainer.getCustomTag(NSK_SUPER_ABILITY_BOOSTED_ITEM, ItemTagType.INTEGER);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.gmail.nossr50.util.compat.layers.persistentdata;
|
||||
|
||||
import com.gmail.nossr50.api.exceptions.IncompleteNamespacedKeyRegister;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.Furnace;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
@ -12,28 +14,96 @@ import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SpigotPersistentDataLayer_1_14 extends AbstractPersistentDataLayer {
|
||||
|
||||
/*
|
||||
* Don't modify these keys
|
||||
*/
|
||||
public static final String FURNACE_UUID_MOST_SIG = "furnace_uuid_most_sig";
|
||||
public static final String FURNACE_UUID_LEAST_SIG = "furnace_uuid_least_sig";
|
||||
private final @NotNull EnumMap<MobMetaFlagType, NamespacedKey> mobFlagKeyMap;
|
||||
|
||||
private NamespacedKey furnaceOwner_MostSig_Key;
|
||||
private NamespacedKey furnaceOwner_LeastSig_Key;
|
||||
public SpigotPersistentDataLayer_1_14() {
|
||||
mobFlagKeyMap = new EnumMap<>(MobMetaFlagType.class);
|
||||
initMobFlagKeyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initializeLayer() {
|
||||
initNamespacedKeys();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void initNamespacedKeys() {
|
||||
furnaceOwner_MostSig_Key = getNamespacedKey(FURNACE_UUID_MOST_SIG);
|
||||
furnaceOwner_LeastSig_Key = getNamespacedKey(FURNACE_UUID_LEAST_SIG);
|
||||
/**
|
||||
* Registers the namespaced keys required by the API (CB/Spigot)
|
||||
*/
|
||||
private void initMobFlagKeyMap() throws IncompleteNamespacedKeyRegister {
|
||||
for(MobMetaFlagType mobMetaFlagType : MobMetaFlagType.values()) {
|
||||
switch(mobMetaFlagType) {
|
||||
|
||||
case MOB_SPAWNER_MOB:
|
||||
mobFlagKeyMap.put(mobMetaFlagType, NSK_MOB_SPAWNER_MOB);
|
||||
break;
|
||||
case EGG_MOB:
|
||||
mobFlagKeyMap.put(mobMetaFlagType, NSK_EGG_MOB);
|
||||
break;
|
||||
case NETHER_PORTAL_MOB:
|
||||
mobFlagKeyMap.put(mobMetaFlagType, NSK_NETHER_GATE_MOB);
|
||||
break;
|
||||
case COTW_SUMMONED_MOB:
|
||||
mobFlagKeyMap.put(mobMetaFlagType, NSK_COTW_SUMMONED_MOB);
|
||||
break;
|
||||
case PLAYER_BRED_MOB:
|
||||
mobFlagKeyMap.put(mobMetaFlagType, NSK_PLAYER_BRED_MOB);
|
||||
break;
|
||||
case EXPLOITED_ENDERMEN:
|
||||
mobFlagKeyMap.put(mobMetaFlagType, NSK_EXPLOITED_ENDERMEN);
|
||||
break;
|
||||
case PLAYER_TAMED_MOB:
|
||||
mobFlagKeyMap.put(mobMetaFlagType, NSK_PLAYER_TAMED_MOB);
|
||||
break;
|
||||
default:
|
||||
throw new IncompleteNamespacedKeyRegister("missing namespaced key register for type: "+ mobMetaFlagType.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMobFlag(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
|
||||
return livingEntity.getPersistentDataContainer().has(mobFlagKeyMap.get(flag), PersistentDataType.SHORT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMobFlags(@NotNull LivingEntity livingEntity) {
|
||||
for(NamespacedKey currentKey : mobFlagKeyMap.values()) {
|
||||
if(livingEntity.getPersistentDataContainer().has(currentKey, PersistentDataType.BYTE)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMobFlags(@NotNull LivingEntity sourceEntity, @NotNull LivingEntity targetEntity) {
|
||||
for(MobMetaFlagType flag : MobMetaFlagType.values()) {
|
||||
if(hasMobFlag(flag, sourceEntity)) {
|
||||
flagMetadata(flag, targetEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flagMetadata(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
|
||||
if(!hasMobFlag(flag, livingEntity)) {
|
||||
PersistentDataContainer persistentDataContainer = livingEntity.getPersistentDataContainer();
|
||||
persistentDataContainer.set(mobFlagKeyMap.get(flag), PersistentDataType.BYTE, SIMPLE_FLAG_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMobFlag(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
|
||||
if(hasMobFlag(flag, livingEntity)) {
|
||||
PersistentDataContainer persistentDataContainer = livingEntity.getPersistentDataContainer();
|
||||
persistentDataContainer.remove(mobFlagKeyMap.get(flag));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -42,8 +112,8 @@ public class SpigotPersistentDataLayer_1_14 extends AbstractPersistentDataLayer
|
||||
PersistentDataContainer dataContainer = ((PersistentDataHolder) furnace).getPersistentDataContainer();
|
||||
|
||||
//Too lazy to make a custom data type for this stuff
|
||||
Long mostSigBits = dataContainer.get(furnaceOwner_MostSig_Key, PersistentDataType.LONG);
|
||||
Long leastSigBits = dataContainer.get(furnaceOwner_LeastSig_Key, PersistentDataType.LONG);
|
||||
Long mostSigBits = dataContainer.get(NSK_FURNACE_UUID_MOST_SIG, PersistentDataType.LONG);
|
||||
Long leastSigBits = dataContainer.get(NSK_FURNACE_UUID_LEAST_SIG, PersistentDataType.LONG);
|
||||
|
||||
if(mostSigBits != null && leastSigBits != null) {
|
||||
return new UUID(mostSigBits, leastSigBits);
|
||||
@ -56,8 +126,8 @@ public class SpigotPersistentDataLayer_1_14 extends AbstractPersistentDataLayer
|
||||
public void setFurnaceOwner(@NotNull Furnace furnace, @NotNull UUID uuid) {
|
||||
PersistentDataContainer dataContainer = ((PersistentDataHolder) furnace).getPersistentDataContainer();
|
||||
|
||||
dataContainer.set(furnaceOwner_MostSig_Key, PersistentDataType.LONG, uuid.getMostSignificantBits());
|
||||
dataContainer.set(furnaceOwner_LeastSig_Key, PersistentDataType.LONG, uuid.getLeastSignificantBits());
|
||||
dataContainer.set(NSK_FURNACE_UUID_MOST_SIG, PersistentDataType.LONG, uuid.getMostSignificantBits());
|
||||
dataContainer.set(NSK_FURNACE_UUID_LEAST_SIG, PersistentDataType.LONG, uuid.getLeastSignificantBits());
|
||||
|
||||
furnace.update();
|
||||
}
|
||||
@ -72,7 +142,7 @@ public class SpigotPersistentDataLayer_1_14 extends AbstractPersistentDataLayer
|
||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||
PersistentDataContainer dataContainer = itemMeta.getPersistentDataContainer();
|
||||
|
||||
dataContainer.set(superAbilityBoosted, PersistentDataType.INTEGER, originalDigSpeed);
|
||||
dataContainer.set(NSK_SUPER_ABILITY_BOOSTED_ITEM, PersistentDataType.INTEGER, originalDigSpeed);
|
||||
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
}
|
||||
@ -87,7 +157,7 @@ public class SpigotPersistentDataLayer_1_14 extends AbstractPersistentDataLayer
|
||||
PersistentDataContainer dataContainer = itemMeta.getPersistentDataContainer();
|
||||
|
||||
//If this value isn't null, then the tool can be considered dig speed boosted
|
||||
Integer boostValue = dataContainer.get(superAbilityBoosted, PersistentDataType.INTEGER);
|
||||
Integer boostValue = dataContainer.get(NSK_SUPER_ABILITY_BOOSTED_ITEM, PersistentDataType.INTEGER);
|
||||
|
||||
return boostValue != null;
|
||||
}
|
||||
@ -102,12 +172,12 @@ public class SpigotPersistentDataLayer_1_14 extends AbstractPersistentDataLayer
|
||||
|
||||
PersistentDataContainer dataContainer = itemMeta.getPersistentDataContainer();
|
||||
|
||||
if(dataContainer.get(superAbilityBoosted, PersistentDataType.INTEGER) == null) {
|
||||
if(dataContainer.get(NSK_SUPER_ABILITY_BOOSTED_ITEM, PersistentDataType.INTEGER) == null) {
|
||||
mcMMO.p.getLogger().severe("Value should never be null for a boosted item");
|
||||
return 0;
|
||||
} else {
|
||||
//Too lazy to make a custom data type for this stuff
|
||||
Integer boostValue = dataContainer.get(superAbilityBoosted, PersistentDataType.INTEGER);
|
||||
Integer boostValue = dataContainer.get(NSK_SUPER_ABILITY_BOOSTED_ITEM, PersistentDataType.INTEGER);
|
||||
return Math.max(boostValue, 0);
|
||||
}
|
||||
}
|
||||
@ -127,7 +197,7 @@ public class SpigotPersistentDataLayer_1_14 extends AbstractPersistentDataLayer
|
||||
}
|
||||
|
||||
PersistentDataContainer dataContainer = itemMeta.getPersistentDataContainer();
|
||||
dataContainer.remove(superAbilityBoosted); //Remove persistent data
|
||||
dataContainer.remove(NSK_SUPER_ABILITY_BOOSTED_ITEM); //Remove persistent data
|
||||
|
||||
//TODO: needed?
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
|
@ -20,6 +20,8 @@ import com.gmail.nossr50.skills.swords.SwordsManager;
|
||||
import com.gmail.nossr50.skills.taming.TamingManager;
|
||||
import com.gmail.nossr50.skills.unarmed.UnarmedManager;
|
||||
import com.gmail.nossr50.util.*;
|
||||
import com.gmail.nossr50.util.compat.layers.persistentdata.AbstractPersistentDataLayer;
|
||||
import com.gmail.nossr50.util.compat.layers.persistentdata.MobMetaFlagType;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@ -41,8 +43,13 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class CombatUtils {
|
||||
|
||||
private CombatUtils() {}
|
||||
|
||||
private static AbstractPersistentDataLayer getPersistentData() {
|
||||
return mcMMO.getCompatibilityManager().getPersistentDataLayer();
|
||||
}
|
||||
|
||||
//Likely.. because who knows what plugins are throwing around
|
||||
public static boolean isDamageLikelyFromNormalCombat(DamageCause damageCause) {
|
||||
switch (damageCause) {
|
||||
@ -106,6 +113,14 @@ public final class CombatUtils {
|
||||
|
||||
applyScaledModifiers(initialDamage, finalDamage, event);
|
||||
processCombatXP(mcMMOPlayer, target, PrimarySkillType.SWORDS);
|
||||
|
||||
printFinalDamageDebug(player, event, mcMMOPlayer);
|
||||
}
|
||||
|
||||
private static void printFinalDamageDebug(Player player, EntityDamageByEntityEvent event, McMMOPlayer mcMMOPlayer) {
|
||||
if(mcMMOPlayer.isDebugMode()) {
|
||||
player.sendMessage("Final Damage value after mcMMO modifiers: "+ event.getFinalDamage());
|
||||
}
|
||||
}
|
||||
|
||||
// public static void strengthDebug(Player player) {
|
||||
@ -181,6 +196,8 @@ public final class CombatUtils {
|
||||
|
||||
applyScaledModifiers(initialDamage, finalDamage, event);
|
||||
processCombatXP(mcMMOPlayer, target, PrimarySkillType.AXES);
|
||||
|
||||
printFinalDamageDebug(player, event, mcMMOPlayer);
|
||||
}
|
||||
|
||||
private static void processUnarmedCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event) {
|
||||
@ -223,6 +240,8 @@ public final class CombatUtils {
|
||||
|
||||
applyScaledModifiers(initialDamage, finalDamage, event);
|
||||
processCombatXP(mcMMOPlayer, target, PrimarySkillType.UNARMED);
|
||||
|
||||
printFinalDamageDebug(player, event, mcMMOPlayer);
|
||||
}
|
||||
|
||||
private static void processTamingCombat(LivingEntity target, Player master, Wolf wolf, EntityDamageByEntityEvent event) {
|
||||
@ -299,6 +318,8 @@ public final class CombatUtils {
|
||||
|
||||
applyScaledModifiers(initialDamage, finalDamage, event);
|
||||
processCombatXP(mcMMOPlayer, target, PrimarySkillType.ARCHERY, forceMultiplier * distanceMultiplier);
|
||||
|
||||
printFinalDamageDebug(player, event, mcMMOPlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -372,6 +393,7 @@ public final class CombatUtils {
|
||||
|
||||
if (PrimarySkillType.SWORDS.getPermissions(player)) {
|
||||
processSwordCombat(target, player, event);
|
||||
|
||||
}
|
||||
}
|
||||
else if (ItemUtils.isAxe(heldItem)) {
|
||||
@ -428,6 +450,7 @@ public final class CombatUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -547,21 +570,21 @@ public final class CombatUtils {
|
||||
dealDamage(target, damage, DamageCause.CUSTOM, attacker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to damage target for value dmg with reason ENTITY_ATTACK with damager attacker
|
||||
*
|
||||
* @param target LivingEntity which to attempt to damage
|
||||
* @param damage Amount of damage to attempt to do
|
||||
* @param attacker Player to pass to event as damager
|
||||
*/
|
||||
public static void dealDamage(LivingEntity target, double damage, Map<DamageModifier, Double> modifiers, LivingEntity attacker) {
|
||||
if (target.isDead()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Aren't we applying the damage twice????
|
||||
target.damage(getFakeDamageFinalResult(attacker, target, damage, modifiers));
|
||||
}
|
||||
// /**
|
||||
// * Attempt to damage target for value dmg with reason ENTITY_ATTACK with damager attacker
|
||||
// *
|
||||
// * @param target LivingEntity which to attempt to damage
|
||||
// * @param damage Amount of damage to attempt to do
|
||||
// * @param attacker Player to pass to event as damager
|
||||
// */
|
||||
// public static void dealDamage(LivingEntity target, double damage, Map<DamageModifier, Double> modifiers, LivingEntity attacker) {
|
||||
// if (target.isDead()) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // Aren't we applying the damage twice????
|
||||
// target.damage(getFakeDamageFinalResult(attacker, target, damage, modifiers));
|
||||
// }
|
||||
|
||||
/**
|
||||
* Attempt to damage target for value dmg with reason ENTITY_ATTACK with damager attacker
|
||||
@ -576,8 +599,11 @@ public final class CombatUtils {
|
||||
return;
|
||||
}
|
||||
|
||||
if(canDamage(attacker, target, cause, damage))
|
||||
if(canDamage(attacker, target, cause, damage)) {
|
||||
applyIgnoreDamageMetadata(target);
|
||||
target.damage(damage);
|
||||
removeIgnoreDamageMetadata(target);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean processingNoInvulnDamage;
|
||||
@ -596,21 +622,33 @@ public final class CombatUtils {
|
||||
// cause do have issues around plugin observability. This is not a perfect solution, but it appears to be the best one here
|
||||
// We also set no damage ticks to 0, to ensure that damage is applied for this case, and reset it back to the original value
|
||||
// Snapshot current state so we can pop up properly
|
||||
boolean wasMetaSet = target.getMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY).size() != 0;
|
||||
boolean wasMetaSet = hasIgnoreDamageMetadata(target);
|
||||
boolean wasProcessing = processingNoInvulnDamage;
|
||||
// set markers
|
||||
processingNoInvulnDamage = true;
|
||||
target.setMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, mcMMO.metadataValue);
|
||||
applyIgnoreDamageMetadata(target);
|
||||
int noDamageTicks = target.getNoDamageTicks();
|
||||
target.setNoDamageTicks(0);
|
||||
target.damage(damage, attacker);
|
||||
target.setNoDamageTicks(noDamageTicks);
|
||||
if (!wasMetaSet)
|
||||
target.removeMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, mcMMO.p);
|
||||
removeIgnoreDamageMetadata(target);
|
||||
if (!wasProcessing)
|
||||
processingNoInvulnDamage = false;
|
||||
}
|
||||
|
||||
public static void removeIgnoreDamageMetadata(LivingEntity target) {
|
||||
target.removeMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, mcMMO.p);
|
||||
}
|
||||
|
||||
public static void applyIgnoreDamageMetadata(LivingEntity target) {
|
||||
target.setMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY, mcMMO.metadataValue);
|
||||
}
|
||||
|
||||
public static boolean hasIgnoreDamageMetadata(LivingEntity target) {
|
||||
return target.getMetadata(mcMMO.CUSTOM_DAMAGE_METAKEY).size() != 0;
|
||||
}
|
||||
|
||||
public static void dealNoInvulnerabilityTickDamageRupture(LivingEntity target, double damage, Entity attacker, int toolTier) {
|
||||
if (target.isDead()) {
|
||||
return;
|
||||
@ -767,19 +805,20 @@ public final class CombatUtils {
|
||||
}
|
||||
}
|
||||
|
||||
if (target.hasMetadata(mcMMO.entityMetadataKey)
|
||||
//Epic Spawners compatibility
|
||||
|| target.hasMetadata("ES")) {
|
||||
if(getPersistentData().hasMobFlag(MobMetaFlagType.COTW_SUMMONED_MOB, target)) {
|
||||
baseXP = 0;
|
||||
} else if(getPersistentData().hasMobFlag(MobMetaFlagType.MOB_SPAWNER_MOB, target) || target.hasMetadata("ES")) {
|
||||
baseXP *= ExperienceConfig.getInstance().getSpawnedMobXpMultiplier();
|
||||
}
|
||||
|
||||
if (target.hasMetadata(mcMMO.bredMetadataKey)) {
|
||||
} else if(getPersistentData().hasMobFlag(MobMetaFlagType.NETHER_PORTAL_MOB, target)) {
|
||||
baseXP *= ExperienceConfig.getInstance().getNetherPortalXpMultiplier();
|
||||
} else if(getPersistentData().hasMobFlag(MobMetaFlagType.EGG_MOB, target)) {
|
||||
baseXP *= ExperienceConfig.getInstance().getEggXpMultiplier();
|
||||
} else if (getPersistentData().hasMobFlag(MobMetaFlagType.PLAYER_BRED_MOB, target)) {
|
||||
baseXP *= ExperienceConfig.getInstance().getBredMobXpMultiplier();
|
||||
}
|
||||
|
||||
xpGainReason = XPGainReason.PVE;
|
||||
|
||||
baseXP *= 10;
|
||||
xpGainReason = XPGainReason.PVE;
|
||||
}
|
||||
|
||||
baseXP *= multiplier;
|
||||
|
Reference in New Issue
Block a user