mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-30 20:39:10 +00:00
盔甲重构part1
This commit is contained in:
@@ -15,10 +15,7 @@ import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.ThrowableProjectile;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
@@ -32,6 +29,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class BukkitProjectileManager implements Listener, ProjectileManager {
|
||||
private static BukkitProjectileManager instance;
|
||||
@@ -47,11 +45,22 @@ public class BukkitProjectileManager implements Listener, ProjectileManager {
|
||||
@Override
|
||||
public void delayedInit() {
|
||||
Bukkit.getPluginManager().registerEvents(this, this.plugin.javaPlugin());
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
List<Entity> entities = world.getEntities();
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof Projectile projectile) {
|
||||
handleProjectileLoad(projectile);
|
||||
if (VersionHelper.isFolia()) {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
List<Entity> entities = world.getEntities();
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof Projectile projectile) {
|
||||
projectile.getScheduler().run(this.plugin.javaPlugin(), (t) -> handleProjectileLoad(projectile), () -> {});
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
List<Entity> entities = world.getEntities();
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof Projectile projectile) {
|
||||
handleProjectileLoad(projectile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ public class BukkitCustomItem extends AbstractCustomItem<ItemStack> {
|
||||
@Override
|
||||
public CustomItem<ItemStack> build() {
|
||||
this.modifiers.addAll(this.settings.modifiers());
|
||||
this.clientBoundModifiers.addAll(this.settings.clientBoundModifiers());
|
||||
return new BukkitCustomItem(this.id, this.item, this.clientBoundItem, this.itemKey, this.clientBoundItemKey, List.copyOf(this.behaviors),
|
||||
List.copyOf(this.modifiers), List.copyOf(this.clientBoundModifiers), this.settings, this.events);
|
||||
}
|
||||
|
||||
@@ -11,11 +11,14 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries;
|
||||
import net.momirealms.craftengine.bukkit.util.ComponentUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.ItemUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.KeyUtils;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.item.*;
|
||||
import net.momirealms.craftengine.core.item.equipment.TrimBasedEquipment;
|
||||
import net.momirealms.craftengine.core.item.modifier.IdModifier;
|
||||
import net.momirealms.craftengine.core.pack.AbstractPackManager;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.context.ContextHolder;
|
||||
import net.momirealms.craftengine.core.plugin.locale.LocalizedResourceConfigException;
|
||||
@@ -33,9 +36,7 @@ import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
static {
|
||||
@@ -50,6 +51,8 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
private final DebugStickListener debugStickListener;
|
||||
private final ArmorEventListener armorEventListener;
|
||||
private final NetworkItemHandler<ItemStack> networkItemHandler;
|
||||
private final Object bedrockItemHolder;
|
||||
private boolean registeredTrimMaterial;
|
||||
|
||||
public BukkitItemManager(BukkitCraftEngine plugin) {
|
||||
super(plugin);
|
||||
@@ -61,6 +64,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
this.armorEventListener = new ArmorEventListener();
|
||||
this.networkItemHandler = VersionHelper.isOrAbove1_20_5() ? new ModernNetworkItemHandler() : new LegacyNetworkItemHandler();
|
||||
this.registerAllVanillaItems();
|
||||
this.bedrockItemHolder = FastNMS.INSTANCE.method$Registry$getHolderByResourceKey(MBuiltInRegistries.ITEM, FastNMS.INSTANCE.method$ResourceKey$create(MRegistries.ITEM, KeyUtils.toResourceLocation(Key.of("minecraft:bedrock")))).get();;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,6 +138,78 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
HandlerList.unregisterAll(this.armorEventListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerArmorTrimPattern(Collection<TrimBasedEquipment> equipments) {
|
||||
if (equipments.isEmpty()) return;
|
||||
this.registerCustomTrimMaterial();
|
||||
Object registry = FastNMS.INSTANCE.method$RegistryAccess$lookupOrThrow(FastNMS.INSTANCE.registryAccess(), MRegistries.TRIM_PATTERN);
|
||||
try {
|
||||
CoreReflections.field$MappedRegistry$frozen.set(registry, false);
|
||||
for (TrimBasedEquipment equipment : equipments) {
|
||||
Object resourceLocation = KeyUtils.toResourceLocation(equipment.assetId());
|
||||
Object previous = FastNMS.INSTANCE.method$Registry$getValue(registry, resourceLocation);
|
||||
if (previous == null) {
|
||||
Object trimPattern = createTrimPattern(equipment.assetId());
|
||||
Object holder = CoreReflections.method$Registry$registerForHolder.invoke(null, registry, resourceLocation, trimPattern);
|
||||
CoreReflections.method$Holder$Reference$bindValue.invoke(holder, trimPattern);
|
||||
CoreReflections.field$Holder$Reference$tags.set(holder, Set.of());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
this.plugin.logger().warn("Failed to register armor trim pattern.", e);
|
||||
} finally {
|
||||
try {
|
||||
CoreReflections.field$MappedRegistry$frozen.set(registry, true);
|
||||
} catch (ReflectiveOperationException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerCustomTrimMaterial() {
|
||||
if (this.registeredTrimMaterial) return;
|
||||
Object registry = FastNMS.INSTANCE.method$RegistryAccess$lookupOrThrow(FastNMS.INSTANCE.registryAccess(), MRegistries.TRIM_MATERIAL);
|
||||
Object resourceLocation = KeyUtils.toResourceLocation(Key.of("minecraft", AbstractPackManager.TRIM_MATERIAL));
|
||||
Object previous = FastNMS.INSTANCE.method$Registry$getValue(registry, resourceLocation);
|
||||
if (previous == null) {
|
||||
try {
|
||||
CoreReflections.field$MappedRegistry$frozen.set(registry, false);
|
||||
Object trimMaterial = createTrimMaterial();
|
||||
Object holder = CoreReflections.method$Registry$registerForHolder.invoke(null, registry, resourceLocation, trimMaterial);
|
||||
CoreReflections.method$Holder$Reference$bindValue.invoke(holder, trimMaterial);
|
||||
CoreReflections.field$Holder$Reference$tags.set(holder, Set.of());
|
||||
} catch (Exception e) {
|
||||
this.plugin.logger().warn("Failed to register trim material.", e);
|
||||
} finally {
|
||||
try {
|
||||
CoreReflections.field$MappedRegistry$frozen.set(registry, true);
|
||||
} catch (ReflectiveOperationException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
this.registeredTrimMaterial = true;
|
||||
}
|
||||
|
||||
private Object createTrimPattern(Key key) throws ReflectiveOperationException {
|
||||
if (VersionHelper.isOrAbove1_21_5()) {
|
||||
return CoreReflections.constructor$TrimPattern.newInstance(KeyUtils.toResourceLocation(key), CoreReflections.instance$Component$empty, false);
|
||||
} else if (VersionHelper.isOrAbove1_20_2()) {
|
||||
return CoreReflections.constructor$TrimPattern.newInstance(KeyUtils.toResourceLocation(key), this.bedrockItemHolder, CoreReflections.instance$Component$empty, false);
|
||||
} else {
|
||||
return CoreReflections.constructor$TrimPattern.newInstance(KeyUtils.toResourceLocation(key), this.bedrockItemHolder, CoreReflections.instance$Component$empty);
|
||||
}
|
||||
}
|
||||
|
||||
private Object createTrimMaterial() throws ReflectiveOperationException {
|
||||
if (VersionHelper.isOrAbove1_21_5()) {
|
||||
Object assetGroup = CoreReflections.method$MaterialAssetGroup$create.invoke(null, "custom");
|
||||
return CoreReflections.constructor$TrimMaterial.newInstance(assetGroup, CoreReflections.instance$Component$empty);
|
||||
} else if (VersionHelper.isOrAbove1_21_4()) {
|
||||
return CoreReflections.constructor$TrimMaterial.newInstance("custom", this.bedrockItemHolder, Map.of(), CoreReflections.instance$Component$empty);
|
||||
} else {
|
||||
return CoreReflections.constructor$TrimMaterial.newInstance("custom", this.bedrockItemHolder, 1_000_000.0f, Map.of(), CoreReflections.instance$Component$empty);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public Item<ItemStack> fromByteArray(byte[] bytes) {
|
||||
|
||||
@@ -2,9 +2,17 @@ package net.momirealms.craftengine.bukkit.item.factory;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.item.ComponentItemWrapper;
|
||||
import net.momirealms.craftengine.bukkit.item.ComponentTypes;
|
||||
import net.momirealms.craftengine.core.entity.EquipmentSlot;
|
||||
import net.momirealms.craftengine.core.item.equipment.Equipments;
|
||||
import net.momirealms.craftengine.core.item.setting.EquipmentData;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.MiscUtils;
|
||||
import net.momirealms.sparrow.nbt.CompoundTag;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ComponentItemFactory1_21_2 extends ComponentItemFactory1_21 {
|
||||
@@ -52,6 +60,18 @@ public class ComponentItemFactory1_21_2 extends ComponentItemFactory1_21 {
|
||||
|
||||
@Override
|
||||
protected Optional<EquipmentData> equippable(ComponentItemWrapper item) {
|
||||
throw new UnsupportedOperationException("Not implemented yet.");
|
||||
Optional<Object> optionalData = item.getJavaComponent(ComponentTypes.EQUIPPABLE);
|
||||
if (optionalData.isEmpty()) return Optional.empty();
|
||||
Map<String, Object> data = MiscUtils.castToMap(optionalData.get(), false);
|
||||
String slot = data.get("slot").toString();
|
||||
return Optional.of(new EquipmentData(
|
||||
EquipmentSlot.valueOf(slot.toUpperCase(Locale.ENGLISH)),
|
||||
data.containsKey("asset_id") ? Key.of((String) data.get("asset_id")) : null,
|
||||
(boolean) data.getOrDefault("dispensable", true),
|
||||
(boolean) data.getOrDefault("swappable", true),
|
||||
(boolean) data.getOrDefault("damage_on_hurt", true),
|
||||
(boolean) data.getOrDefault("equip_on_interact", false),
|
||||
data.containsKey("camera_overlay") ? Key.of((String) data.get("camera_overlay")) : null
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -3588,12 +3588,37 @@ public final class CoreReflections {
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$TrimPattern = requireNonNull(
|
||||
VersionHelper.isOrAbove1_21_2() ?
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.item.equipment.trim.TrimPattern",
|
||||
"world.item.equipment.trim.TrimPattern"
|
||||
) :
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.item.armortrim.TrimPattern",
|
||||
"world.item.armortrim.TrimPattern"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$TrimMaterial = requireNonNull(
|
||||
VersionHelper.isOrAbove1_21_2() ?
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.item.equipment.trim.TrimMaterial",
|
||||
"world.item.equipment.trim.TrimMaterial"
|
||||
) :
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.item.armortrim.TrimMaterial",
|
||||
"world.item.armortrim.TrimMaterial"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Class<?> clazz$MaterialAssetGroup = BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.item.equipment.trim.MaterialAssetGroup",
|
||||
"world.item.equipment.trim.MaterialAssetGroup"
|
||||
);
|
||||
|
||||
public static final Method method$MaterialAssetGroup$create = Optional.ofNullable(clazz$MaterialAssetGroup)
|
||||
.map(it -> ReflectionUtils.getStaticMethod(it, it, String.class)).orElse(null);
|
||||
|
||||
public static final Constructor<?> constructor$TrimPattern = requireNonNull(
|
||||
VersionHelper.isOrAbove1_21_5() ?
|
||||
ReflectionUtils.getConstructor(clazz$TrimPattern, clazz$ResourceLocation, clazz$Component, boolean.class) :
|
||||
@@ -3601,4 +3626,12 @@ public final class CoreReflections {
|
||||
ReflectionUtils.getConstructor(clazz$TrimPattern, clazz$ResourceLocation, clazz$Holder, clazz$Component, boolean.class) :
|
||||
ReflectionUtils.getConstructor(clazz$TrimPattern, clazz$ResourceLocation, clazz$Holder, clazz$Component)
|
||||
);
|
||||
|
||||
public static final Constructor<?> constructor$TrimMaterial = requireNonNull(
|
||||
VersionHelper.isOrAbove1_21_5() ?
|
||||
ReflectionUtils.getConstructor(clazz$TrimMaterial, clazz$MaterialAssetGroup, clazz$Component) :
|
||||
VersionHelper.isOrAbove1_21_4() ?
|
||||
ReflectionUtils.getConstructor(clazz$TrimMaterial, String.class, clazz$Holder, Map.class, clazz$Component) :
|
||||
ReflectionUtils.getConstructor(clazz$TrimMaterial, String.class, clazz$Holder, float.class, Map.class, clazz$Component)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ public final class MRegistries {
|
||||
public static final Object CONFIGURED_FEATURE;
|
||||
public static final Object PLACED_FEATURE;
|
||||
public static final Object TRIM_PATTERN;
|
||||
public static final Object TRIM_MATERIAL;
|
||||
@Nullable // 1.21+
|
||||
public static final Object JUKEBOX_SONG;
|
||||
@Nullable // 1.21+
|
||||
@@ -48,6 +49,7 @@ public final class MRegistries {
|
||||
Object registries$JukeboxSong = null;
|
||||
Object registries$Recipe = null;
|
||||
Object registries$TrimPattern = null;
|
||||
Object registries$TrimMaterial = null;
|
||||
for (Field field : fields) {
|
||||
Type fieldType = field.getGenericType();
|
||||
if (fieldType instanceof ParameterizedType paramType) {
|
||||
@@ -91,6 +93,8 @@ public final class MRegistries {
|
||||
registries$PlacedFeature = field.get(null);
|
||||
} else if (type == CoreReflections.clazz$TrimPattern) {
|
||||
registries$TrimPattern = field.get(null);
|
||||
} else if (type == CoreReflections.clazz$TrimMaterial) {
|
||||
registries$TrimMaterial = field.get(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,6 +115,7 @@ public final class MRegistries {
|
||||
CONFIGURED_FEATURE = requireNonNull(registries$ConfiguredFeature);
|
||||
PLACED_FEATURE = requireNonNull(registries$PlacedFeature);
|
||||
TRIM_PATTERN = requireNonNull(registries$TrimPattern);
|
||||
TRIM_MATERIAL = requireNonNull(registries$TrimMaterial);
|
||||
JUKEBOX_SONG = registries$JukeboxSong;
|
||||
RECIPE = registries$Recipe;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
|
||||
@@ -30,10 +30,10 @@ public class BukkitSoundManager extends AbstractSoundManager {
|
||||
@Override
|
||||
protected void registerSongs(Map<Key, JukeboxSong> songs) {
|
||||
if (songs.isEmpty()) return;
|
||||
Object registry = FastNMS.INSTANCE.method$RegistryAccess$lookupOrThrow(FastNMS.INSTANCE.registryAccess(), MRegistries.JUKEBOX_SONG);
|
||||
try {
|
||||
// 获取 JUKEBOX_SONG 注册表
|
||||
Object registry = FastNMS.INSTANCE.method$RegistryAccess$lookupOrThrow(FastNMS.INSTANCE.registryAccess(), MRegistries.JUKEBOX_SONG);
|
||||
unfreezeRegistry(registry);
|
||||
CoreReflections.field$MappedRegistry$frozen.set(registry, false);
|
||||
for (Map.Entry<Key, JukeboxSong> entry : songs.entrySet()) {
|
||||
Key id = entry.getKey();
|
||||
JukeboxSong jukeboxSong = entry.getValue();
|
||||
@@ -54,17 +54,12 @@ public class BukkitSoundManager extends AbstractSoundManager {
|
||||
CoreReflections.field$Holder$Reference$tags.set(holder, Set.of());
|
||||
}
|
||||
}
|
||||
freezeRegistry(registry);
|
||||
} catch (Exception e) {
|
||||
plugin.logger().warn("Failed to register jukebox songs.", e);
|
||||
this.plugin.logger().warn("Failed to register jukebox songs.", e);
|
||||
} finally {
|
||||
try {
|
||||
CoreReflections.field$MappedRegistry$frozen.set(registry, true);
|
||||
} catch (ReflectiveOperationException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
private void unfreezeRegistry(Object registry) throws IllegalAccessException {
|
||||
CoreReflections.field$MappedRegistry$frozen.set(registry, false);
|
||||
}
|
||||
|
||||
private void freezeRegistry(Object registry) throws IllegalAccessException {
|
||||
CoreReflections.field$MappedRegistry$frozen.set(registry, true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user