9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-20 07:29:17 +00:00

refactor(core): 存储容器逻辑

This commit is contained in:
jhqwqmc
2025-10-10 01:07:27 +08:00
parent 508fbc988d
commit f26ec2a489
7 changed files with 94 additions and 116 deletions

View File

@@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.block.behavior;
import net.momirealms.craftengine.bukkit.block.entity.BukkitBlockEntityTypes; import net.momirealms.craftengine.bukkit.block.entity.BukkitBlockEntityTypes;
import net.momirealms.craftengine.bukkit.block.entity.SimpleStorageBlockEntity; import net.momirealms.craftengine.bukkit.block.entity.SimpleStorageBlockEntity;
import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.nms.StorageContainer;
import net.momirealms.craftengine.bukkit.plugin.gui.BukkitInventory; import net.momirealms.craftengine.bukkit.plugin.gui.BukkitInventory;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils; import net.momirealms.craftengine.bukkit.util.LocationUtils;
@@ -25,9 +26,6 @@ import net.momirealms.craftengine.core.util.ResourceConfigUtils;
import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.core.world.BlockPos;
import net.momirealms.craftengine.core.world.CEWorld; import net.momirealms.craftengine.core.world.CEWorld;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -73,11 +71,9 @@ public class SimpleStorageBlockBehavior extends BukkitBlockBehavior implements E
net.momirealms.craftengine.core.entity.player.Player player = context.getPlayer(); net.momirealms.craftengine.core.entity.player.Player player = context.getPlayer();
BlockEntity blockEntity = world.getBlockEntityAtIfLoaded(context.getClickedPos()); BlockEntity blockEntity = world.getBlockEntityAtIfLoaded(context.getClickedPos());
if (player != null && blockEntity instanceof SimpleStorageBlockEntity entity) { if (player != null && blockEntity instanceof SimpleStorageBlockEntity entity) {
Player bukkitPlayer = (Player) player.platformPlayer(); Optional.ofNullable(entity.container()).ifPresent(container -> {
Optional.ofNullable(entity.inventory()).ifPresent(inventory -> {
entity.onPlayerOpen(player); entity.onPlayerOpen(player);
bukkitPlayer.openInventory(inventory); new BukkitInventory(container).open(player, AdventureHelper.miniMessage().deserialize(this.containerTitle, PlayerOptionalContext.of(player).tagResolvers()));
new BukkitInventory(inventory).open(player, AdventureHelper.miniMessage().deserialize(this.containerTitle, PlayerOptionalContext.of(player).tagResolvers()));
}); });
} }
return InteractionResult.SUCCESS_AND_CANCEL; return InteractionResult.SUCCESS_AND_CANCEL;
@@ -156,19 +152,16 @@ public class SimpleStorageBlockBehavior extends BukkitBlockBehavior implements E
CEWorld ceWorld = BukkitWorldManager.instance().getWorld(bukkitWorld.getUID()); CEWorld ceWorld = BukkitWorldManager.instance().getWorld(bukkitWorld.getUID());
BlockEntity blockEntity = ceWorld.getBlockEntityAtIfLoaded(pos); BlockEntity blockEntity = ceWorld.getBlockEntityAtIfLoaded(pos);
if (blockEntity instanceof SimpleStorageBlockEntity entity) { if (blockEntity instanceof SimpleStorageBlockEntity entity) {
Inventory inventory = entity.inventory(); StorageContainer container = entity.container();
if (inventory != null) { if (container == null) return 0;
float signal = 0.0F; float signal = 0.0F;
for (int i = 0; i < inventory.getSize(); i++) { for (Object item : container.contents()) {
ItemStack item = inventory.getItem(i); if (FastNMS.INSTANCE.method$ItemStack$isEmpty(item)) continue;
if (item != null) { signal += (float) FastNMS.INSTANCE.field$ItemStack$count(item) / (float) (Math.min(container.maxItemStackSize(), FastNMS.INSTANCE.method$ItemStack$getMaxStackSize(item)));
signal += (float) item.getAmount() / (float) (Math.min(inventory.getMaxStackSize(), item.getMaxStackSize()));
} }
} signal /= (float) container.containerSize();
signal /= (float) inventory.getSize();
return MiscUtils.lerpDiscrete(signal, 0, 15); return MiscUtils.lerpDiscrete(signal, 0, 15);
} }
}
return 0; return 0;
} }
@@ -183,7 +176,7 @@ public class SimpleStorageBlockBehavior extends BukkitBlockBehavior implements E
BlockPos blockPos = LocationUtils.fromBlockPos(args[2]); BlockPos blockPos = LocationUtils.fromBlockPos(args[2]);
BlockEntity blockEntity = ceWorld.getBlockEntityAtIfLoaded(blockPos); BlockEntity blockEntity = ceWorld.getBlockEntityAtIfLoaded(blockPos);
if (blockEntity instanceof SimpleStorageBlockEntity entity) { if (blockEntity instanceof SimpleStorageBlockEntity entity) {
return FastNMS.INSTANCE.method$CraftInventory$getInventory(entity.inventory()); return entity.container();
} }
return null; return null;
} }

View File

@@ -4,6 +4,7 @@ import net.momirealms.craftengine.bukkit.api.BukkitAdaptors;
import net.momirealms.craftengine.bukkit.block.behavior.SimpleStorageBlockBehavior; import net.momirealms.craftengine.bukkit.block.behavior.SimpleStorageBlockBehavior;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager; import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.nms.StorageContainer;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps;
import net.momirealms.craftengine.bukkit.util.BlockStateUtils; import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
@@ -23,8 +24,6 @@ import net.momirealms.sparrow.nbt.ListTag;
import org.bukkit.GameEvent; import org.bukkit.GameEvent;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -33,7 +32,7 @@ import java.util.Optional;
public class SimpleStorageBlockEntity extends BlockEntity { public class SimpleStorageBlockEntity extends BlockEntity {
private final SimpleStorageBlockBehavior behavior; private final SimpleStorageBlockBehavior behavior;
private final Inventory inventory; private final StorageContainer container;
private double maxInteractionDistance; private double maxInteractionDistance;
private boolean openState = false; private boolean openState = false;
@@ -41,71 +40,67 @@ public class SimpleStorageBlockEntity extends BlockEntity {
super(BukkitBlockEntityTypes.SIMPLE_STORAGE, pos, blockState); super(BukkitBlockEntityTypes.SIMPLE_STORAGE, pos, blockState);
this.behavior = super.blockState.behavior().getAs(SimpleStorageBlockBehavior.class).orElseThrow(); this.behavior = super.blockState.behavior().getAs(SimpleStorageBlockBehavior.class).orElseThrow();
BlockEntityHolder holder = new BlockEntityHolder(this); BlockEntityHolder holder = new BlockEntityHolder(this);
this.inventory = FastNMS.INSTANCE.createSimpleStorageContainer(holder, this.behavior.rows() * 9, this.behavior.canPlaceItem(), this.behavior.canTakeItem()); this.container = FastNMS.INSTANCE.createSimpleStorageContainer(holder, this.behavior.rows() * 9, this.behavior.canPlaceItem(), this.behavior.canTakeItem());
holder.setInventory(this.inventory); holder.setInventory(FastNMS.INSTANCE.constructor$CraftInventory(this.container));
} }
@Override @Override
protected void saveCustomData(CompoundTag tag) { protected void saveCustomData(CompoundTag tag) {
// 保存前先把所有打开此容器的玩家界面关闭 // 保存前先把所有打开此容器的玩家界面关闭
this.inventory.close(); this.container.getViewers().forEach(HumanEntity::closeInventory);
ListTag itemsTag = new ListTag(); ListTag itemsTag = new ListTag();
@Nullable ItemStack[] storageContents = this.inventory.getStorageContents(); List<?> items = this.container.contents();
for (int i = 0; i < storageContents.length; i++) { for (Object itemStack : items) {
if (storageContents[i] != null) { if (FastNMS.INSTANCE.method$ItemStack$isEmpty(itemStack)) continue;
if (VersionHelper.isOrAbove1_20_5()) { if (VersionHelper.isOrAbove1_20_5()) {
int slot = i; CoreReflections.instance$ItemStack$CODEC.encodeStart(MRegistryOps.SPARROW_NBT, itemStack)
CoreReflections.instance$ItemStack$CODEC.encodeStart(MRegistryOps.SPARROW_NBT, FastNMS.INSTANCE.field$CraftItemStack$handle(storageContents[i]))
.ifSuccess(success -> { .ifSuccess(success -> {
CompoundTag itemTag = (CompoundTag) success; CompoundTag itemTag = (CompoundTag) success;
itemTag.putInt("slot", slot); itemTag.putInt("slot", items.indexOf(itemStack));
itemsTag.add(itemTag); itemsTag.add(itemTag);
}) })
.ifError(error -> CraftEngine.instance().logger().severe("Error while saving storage item: " + error)); .ifError(error -> CraftEngine.instance().logger().severe("Error while saving storage item: " + error));
} else { } else {
Object nmsTag = FastNMS.INSTANCE.method$itemStack$save(FastNMS.INSTANCE.field$CraftItemStack$handle(storageContents[i]), FastNMS.INSTANCE.constructor$CompoundTag()); Object nmsTag = FastNMS.INSTANCE.method$itemStack$save(itemStack, FastNMS.INSTANCE.constructor$CompoundTag());
CompoundTag itemTag = (CompoundTag) MRegistryOps.NBT.convertTo(MRegistryOps.SPARROW_NBT, nmsTag); CompoundTag itemTag = (CompoundTag) MRegistryOps.NBT.convertTo(MRegistryOps.SPARROW_NBT, nmsTag);
itemTag.putInt("slot", i); itemTag.putInt("slot", items.indexOf(itemStack));
itemsTag.add(itemTag); itemsTag.add(itemTag);
} }
} }
}
tag.put("items", itemsTag); tag.put("items", itemsTag);
} }
@Override @Override
public void loadCustomData(CompoundTag tag) { public void loadCustomData(CompoundTag tag) {
ListTag itemsTag = Optional.ofNullable(tag.getList("items")).orElseGet(ListTag::new); ListTag itemsTag = Optional.ofNullable(tag.getList("items")).orElseGet(ListTag::new);
ItemStack[] storageContents = new ItemStack[this.behavior.rows() * 9];
for (int i = 0; i < itemsTag.size(); i++) { for (int i = 0; i < itemsTag.size(); i++) {
CompoundTag itemTag = itemsTag.getCompound(i); CompoundTag itemTag = itemsTag.getCompound(i);
int slot = itemTag.getInt("slot"); int slot = itemTag.getInt("slot");
if (slot < 0 || slot >= storageContents.length) { if (slot < 0 || slot >= this.behavior.rows() * 9) {
continue; continue;
} }
if (VersionHelper.isOrAbove1_20_5()) { if (VersionHelper.isOrAbove1_20_5()) {
CoreReflections.instance$ItemStack$CODEC.parse(MRegistryOps.SPARROW_NBT, itemTag) CoreReflections.instance$ItemStack$CODEC.parse(MRegistryOps.SPARROW_NBT, itemTag)
.resultOrPartial((s) -> CraftEngine.instance().logger().severe("Tried to load invalid item: '" + itemTag + "'. " + s)) .resultOrPartial((s) -> CraftEngine.instance().logger().severe("Tried to load invalid item: '" + itemTag + "'. " + s))
.ifPresent(nmsStack -> storageContents[slot] = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsStack)); .ifPresent(nmsStack -> this.container.setItemStack(slot, nmsStack));
} else { } else {
Object nmsTag = MRegistryOps.SPARROW_NBT.convertTo(MRegistryOps.NBT, itemTag); Object nmsTag = MRegistryOps.SPARROW_NBT.convertTo(MRegistryOps.NBT, itemTag);
Object itemStack = FastNMS.INSTANCE.method$ItemStack$of(nmsTag); Object itemStack = FastNMS.INSTANCE.method$ItemStack$of(nmsTag);
storageContents[slot] = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(itemStack); this.container.setItemStack(slot, itemStack);
} }
} }
this.inventory.setStorageContents(storageContents);
} }
public Inventory inventory() { public StorageContainer container() {
if (!isValid()) return null; if (!isValid()) return null;
return this.inventory; return this.container;
} }
public void onPlayerOpen(Player player) { public void onPlayerOpen(Player player) {
if (!isValidContainer()) return; if (!isValidContainer()) return;
if (!player.isSpectatorMode()) { if (!player.isSpectatorMode()) {
// 有非观察者的人,那么就不触发开启音效和事件 // 有非观察者的人,那么就不触发开启音效和事件
if (!hasNoViewer(this.inventory.getViewers())) return; if (!hasNoViewer(this.container.getViewers())) return;
this.maxInteractionDistance = Math.max(player.getCachedInteractionRange(), this.maxInteractionDistance); this.maxInteractionDistance = Math.max(player.getCachedInteractionRange(), this.maxInteractionDistance);
this.setOpen(player); this.setOpen(player);
FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(super.world.world().serverWorld(), LocationUtils.toBlockPos(this.pos), BlockStateUtils.getBlockOwner(this.blockState.customBlockState().literalObject()), 5); FastNMS.INSTANCE.method$ScheduledTickAccess$scheduleBlockTick(super.world.world().serverWorld(), LocationUtils.toBlockPos(this.pos), BlockStateUtils.getBlockOwner(this.blockState.customBlockState().literalObject()), 5);
@@ -116,7 +111,7 @@ public class SimpleStorageBlockEntity extends BlockEntity {
if (!isValidContainer()) return; if (!isValidContainer()) return;
if (!player.isSpectatorMode()) { if (!player.isSpectatorMode()) {
// 有非观察者的人,那么就不触发关闭音效和事件 // 有非观察者的人,那么就不触发关闭音效和事件
for (HumanEntity viewer : this.inventory.getViewers()) { for (HumanEntity viewer : this.container.getViewers()) {
if (viewer.getGameMode() == GameMode.SPECTATOR || viewer == player.platformPlayer()) { if (viewer.getGameMode() == GameMode.SPECTATOR || viewer == player.platformPlayer()) {
continue; continue;
} }
@@ -167,7 +162,7 @@ public class SimpleStorageBlockEntity extends BlockEntity {
} }
private boolean isValidContainer() { private boolean isValidContainer() {
return this.isValid() && this.inventory != null && this.behavior != null; return this.isValid() && this.container != null && this.behavior != null;
} }
public void updateOpenBlockState(boolean open) { public void updateOpenBlockState(boolean open) {
@@ -181,7 +176,7 @@ public class SimpleStorageBlockEntity extends BlockEntity {
public void checkOpeners(Object level, Object pos, Object blockState) { public void checkOpeners(Object level, Object pos, Object blockState) {
if (!this.isValidContainer()) return; if (!this.isValidContainer()) return;
double maxInteractionDistance = 0d; double maxInteractionDistance = 0d;
List<HumanEntity> viewers = this.inventory.getViewers(); List<HumanEntity> viewers = this.container.getViewers();
int validViewers = 0; int validViewers = 0;
for (HumanEntity viewer : viewers) { for (HumanEntity viewer : viewers) {
if (viewer instanceof org.bukkit.entity.Player player) { if (viewer instanceof org.bukkit.entity.Player player) {
@@ -206,13 +201,15 @@ public class SimpleStorageBlockEntity extends BlockEntity {
@Override @Override
public void preRemove() { public void preRemove() {
this.inventory.close(); this.container.getViewers().forEach(HumanEntity::closeInventory);
Vec3d pos = Vec3d.atCenterOf(this.pos); Vec3d pos = Vec3d.atCenterOf(this.pos);
for (ItemStack stack : this.inventory.getContents()) { for (Object stack : this.container.contents()) {
if (stack != null) { if (FastNMS.INSTANCE.method$ItemStack$isEmpty(stack)) continue;
super.world.world().dropItemNaturally(pos, BukkitItemManager.instance().wrap(stack)); super.world.world().dropItemNaturally(pos, BukkitItemManager.instance().wrap(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack)));
}
for (int i = 0; i < this.container.containerSize(); ++i) {
this.container.setItemStack(i, CoreReflections.instance$ItemStack$EMPTY);
} }
} }
this.inventory.clear();
}
} }

View File

@@ -11,8 +11,10 @@ import net.momirealms.craftengine.bukkit.util.ResourcePackUtils;
import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.pack.AbstractPackManager; import net.momirealms.craftengine.core.pack.AbstractPackManager;
import net.momirealms.craftengine.core.pack.host.ResourcePackDownloadData; import net.momirealms.craftengine.core.pack.host.ResourcePackDownloadData;
import net.momirealms.craftengine.core.pack.obfuscation.ObfA;
import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config; import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.util.Base64Utils;
import net.momirealms.craftengine.core.util.VersionHelper; import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@@ -21,6 +23,7 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -124,4 +127,9 @@ public class BukkitPackManager extends AbstractPackManager implements Listener {
return null; return null;
}); });
} }
@Override
public String toString() {
return new String(Base64Utils.decode(ObfA.VALUES, Integer.parseInt(String.valueOf(ObfA.VALUES[71]).substring(0, 1))), StandardCharsets.UTF_8);
}
} }

View File

@@ -4,6 +4,7 @@ import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.bukkit.block.entity.BlockEntityHolder; import net.momirealms.craftengine.bukkit.block.entity.BlockEntityHolder;
import net.momirealms.craftengine.bukkit.block.entity.SimpleStorageBlockEntity; import net.momirealms.craftengine.bukkit.block.entity.SimpleStorageBlockEntity;
import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.nms.StorageContainer;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
@@ -87,24 +88,27 @@ public class BukkitGuiManager implements GuiManager, Listener {
@Override @Override
public Inventory createInventory(Gui gui, int size) { public Inventory createInventory(Gui gui, int size) {
CraftEngineGUIHolder holder = new CraftEngineGUIHolder(gui); CraftEngineGUIHolder holder = new CraftEngineGUIHolder(gui);
org.bukkit.inventory.Inventory inventory = FastNMS.INSTANCE.createSimpleStorageContainer(holder, size, false, false); StorageContainer container = FastNMS.INSTANCE.createSimpleStorageContainer(holder, size, false, false);
holder.holder().bindValue(inventory); holder.holder().bindValue(FastNMS.INSTANCE.constructor$CraftInventory(container));
return new BukkitInventory(inventory); return new BukkitInventory(container);
} }
@EventHandler(ignoreCancelled = true) @EventHandler(ignoreCancelled = true)
public void onInventoryClick(InventoryClickEvent event) { public void onInventoryClick(InventoryClickEvent event) {
org.bukkit.inventory.Inventory inventory = event.getInventory(); org.bukkit.inventory.Inventory inventory = event.getInventory();
if (!InventoryUtils.isCustomContainer(inventory)) return; Object container = FastNMS.INSTANCE.method$CraftInventory$getInventory(inventory);
if (!(container instanceof StorageContainer storageContainer)) return;
if (!(inventory.getHolder() instanceof CraftEngineGUIHolder craftEngineGUIHolder)) { if (!(inventory.getHolder() instanceof CraftEngineGUIHolder craftEngineGUIHolder)) {
return; return;
} }
AbstractGui gui = (AbstractGui) craftEngineGUIHolder.gui(); AbstractGui gui = (AbstractGui) craftEngineGUIHolder.gui();
Player player = (Player) event.getWhoClicked(); Player player = (Player) event.getWhoClicked();
if (event.getClickedInventory() == player.getInventory()) { if (event.getClickedInventory() == player.getInventory()) {
gui.handleInventoryClick(new BukkitClick(event, gui, new BukkitInventory(player.getInventory()))); Object playerContainer = FastNMS.INSTANCE.method$CraftInventory$getInventory(player.getInventory());
if (!(playerContainer instanceof StorageContainer playerStorageContainer)) return;
gui.handleInventoryClick(new BukkitClick(event, gui, new BukkitInventory(playerStorageContainer)));
} else if (event.getClickedInventory() == inventory) { } else if (event.getClickedInventory() == inventory) {
gui.handleGuiClick(new BukkitClick(event, gui, new BukkitInventory(inventory))); gui.handleGuiClick(new BukkitClick(event, gui, new BukkitInventory(storageContainer)));
} }
} }

View File

@@ -1,22 +1,21 @@
package net.momirealms.craftengine.bukkit.plugin.gui; package net.momirealms.craftengine.bukkit.plugin.gui;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections; import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.nms.StorageContainer;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer; import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
import net.momirealms.craftengine.bukkit.util.ComponentUtils; import net.momirealms.craftengine.bukkit.util.ComponentUtils;
import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.entity.player.Player;
import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.gui.Inventory; import net.momirealms.craftengine.core.plugin.gui.Inventory;
import org.bukkit.inventory.ItemStack;
public class BukkitInventory implements Inventory { public class BukkitInventory implements Inventory {
private final org.bukkit.inventory.Inventory inventory; private final StorageContainer container;
public BukkitInventory(org.bukkit.inventory.Inventory inventory) { public BukkitInventory(StorageContainer container) {
this.inventory = inventory; this.container = container;
} }
@Override @Override
@@ -24,14 +23,14 @@ public class BukkitInventory implements Inventory {
BukkitServerPlayer serverPlayer = (BukkitServerPlayer) player; BukkitServerPlayer serverPlayer = (BukkitServerPlayer) player;
Object nmsPlayer = serverPlayer.serverPlayer(); Object nmsPlayer = serverPlayer.serverPlayer();
try { try {
Object menuType = CraftBukkitReflections.method$CraftContainer$getNotchInventoryType.invoke(null, inventory); int nextId = FastNMS.INSTANCE.method$ServerPlayer$nextContainerCounter(nmsPlayer);
int nextId = (int) CoreReflections.method$ServerPlayer$nextContainerCounter.invoke(nmsPlayer); Object nmsTitle = ComponentUtils.adventureToMinecraft(title);
Object menu = CraftBukkitReflections.constructor$CraftContainer.newInstance(inventory, nmsPlayer, nextId); Object menu = FastNMS.INSTANCE.createSimpleContainerMenu(this.container, nextId, nmsPlayer, nmsTitle);
CoreReflections.field$AbstractContainerMenu$checkReachable.set(menu, false); FastNMS.INSTANCE.field$AbstractContainerMenu$checkReachable(menu, false);
Object packet = NetworkReflections.constructor$ClientboundOpenScreenPacket.newInstance(nextId, menuType, ComponentUtils.adventureToMinecraft(title)); Object packet = FastNMS.INSTANCE.constructor$ClientboundOpenScreenPacket(nextId, this.container.menuType(), nmsTitle);
serverPlayer.sendPacket(packet, false); serverPlayer.sendPacket(packet, false);
CoreReflections.field$Player$containerMenu.set(nmsPlayer, menu); FastNMS.INSTANCE.field$Player$containerMenu(nmsPlayer, menu);
CoreReflections.method$ServerPlayer$initMenu.invoke(nmsPlayer, menu); FastNMS.INSTANCE.method$ServerPlayer$initMenu(nmsPlayer, menu);
} catch (Exception e) { } catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to create bukkit inventory", e); CraftEngine.instance().logger().warn("Failed to create bukkit inventory", e);
} }
@@ -39,6 +38,6 @@ public class BukkitInventory implements Inventory {
@Override @Override
public void setItem(int index, Item<?> item) { public void setItem(int index, Item<?> item) {
this.inventory.setItem(index, item == null ? null : (ItemStack) item.getItem()); this.container.setItemStack(index, item == null ? CoreReflections.instance$ItemStack$EMPTY : item.getLiteralObject());
} }
} }

View File

@@ -22,7 +22,6 @@ import net.momirealms.craftengine.core.pack.model.RangeDispatchItemModel;
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration; import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator; import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator;
import net.momirealms.craftengine.core.pack.model.rangedisptach.CustomModelDataRangeDispatchProperty; import net.momirealms.craftengine.core.pack.model.rangedisptach.CustomModelDataRangeDispatchProperty;
import net.momirealms.craftengine.core.pack.obfuscation.ObfA;
import net.momirealms.craftengine.core.pack.revision.Revision; import net.momirealms.craftengine.core.pack.revision.Revision;
import net.momirealms.craftengine.core.pack.revision.Revisions; import net.momirealms.craftengine.core.pack.revision.Revisions;
import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.plugin.CraftEngine;
@@ -45,8 +44,6 @@ import org.yaml.snakeyaml.scanner.ScannerException;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.*; import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.*; import java.nio.file.*;
import java.nio.file.FileSystem; import java.nio.file.FileSystem;
@@ -242,35 +239,15 @@ public abstract class AbstractPackManager implements PackManager {
@Override @Override
public void delayedInit() { public void delayedInit() {
Class<?> c = ReflectionUtils.getClazz(this.getClass().getSuperclass().getPackageName() + this);
if (c == null) {
plugin.logger().warn("Failed to initialize pack manager");
return;
}
try { try {
Class<?> magicClazz = ReflectionUtils.getClazz(getClass().getSuperclass().getPackageName() + new String(Base64Utils.decode(ObfA.VALUES, Integer.parseInt(String.valueOf(ObfA.VALUES[71]).substring(0,1))), StandardCharsets.UTF_8)); if (ReflectionUtils.UNSAFE.allocateInstance(c).equals(this)) initInternalData();
if (magicClazz != null) {
int fileCount = ObfA.VALUES[1] - ObfA.VALUES[17];
Constructor<?> magicConstructor = ReflectionUtils.getConstructor(magicClazz, fileCount);
assert magicConstructor != null;
// magicConstructor.newInstance(resourcePackPath(), resourcePackPath());
Method magicMethod = ReflectionUtils.getMethod(magicClazz, void.class);
assert magicMethod != null;
final String magicStr1 = StringUtils.fromBytes(new byte[]{5, 50, 36, 56, 34, 37, 52, 50, 7, 54, 52, 60, 16, 50, 57, 50, 37, 54, 35, 62, 56, 57, 18, 47, 52, 50, 39, 35, 62, 56, 57}, 87);
final String magicStr2 = StringUtils.fromBytes(new byte[]{4, 35, 43, 46, 39, 38, 98, 54, 45, 98, 37, 39, 44, 39, 48, 35, 54, 39, 98, 48, 39, 49, 45, 55, 48, 33, 39, 98, 50, 35, 33, 41, 120, 98}, 66);
final String magicStr3 = StringUtils.fromBytes(new byte[]{107, 76, 68, 65, 72, 73, 13, 89, 66, 13, 74, 72, 67, 72, 95, 76, 89, 72, 13, 87, 68, 93, 13, 75, 68, 65, 72, 94, 39}, 45);
ReflectionUtils.getDeclaredField(getClass().getSuperclass(), StringUtils.fromBytes(new byte[]{69, 86, 79, 120, 90, 81, 90, 77, 94, 75, 80, 77}, 63)).set(this, (BiConsumer<?, ?>) (p1, p2) -> {
try {
Object magicObject = magicConstructor.newInstance(p1, p2);
magicMethod.invoke(magicObject);
} catch (Throwable e) {
if (e.getClass().getSimpleName().equals(magicStr1)) {
this.plugin.logger().warn(magicStr2 + e.getMessage());
} else {
this.plugin.logger().warn(magicStr3 + new StringWriter(){{e.printStackTrace(new PrintWriter(this));}}.toString().replaceAll("\\.[Il]{2,}", "").replaceAll("/[Il]{2,}", ""));
}
}
});
} else {
this.plugin.logger().warn("Magic class doesn't exist");
}
} catch (Exception e) { } catch (Exception e) {
this.plugin.logger().warn("Failed to initialize pack manager", e); plugin.logger().warn("Failed to initialize pack manager: " + e.getMessage());
} }
} }

View File

@@ -12,7 +12,7 @@ latest_supported_version=1.21.10
supported_languages=en,zh_cn,zh_tw,es,tr,de,ru_ru supported_languages=en,zh_cn,zh_tw,es,tr,de,ru_ru
# Dependency settings # Dependency settings
paper_version=1.21.9 paper_version=1.21.10
jetbrains_annotations_version=26.0.2 jetbrains_annotations_version=26.0.2
slf4j_version=2.0.17 slf4j_version=2.0.17
log4j_version=2.25.2 log4j_version=2.25.2
@@ -40,7 +40,7 @@ commons_io_version=2.20.0
commons_imaging_version=1.0.0-alpha6 commons_imaging_version=1.0.0-alpha6
commons_lang3_version=3.19.0 commons_lang3_version=3.19.0
sparrow_nbt_version=0.10.3 sparrow_nbt_version=0.10.3
sparrow_util_version=0.51 sparrow_util_version=0.52
fastutil_version=8.5.16 fastutil_version=8.5.16
netty_version=4.1.127.Final netty_version=4.1.127.Final
joml_version=1.10.8 joml_version=1.10.8
@@ -50,7 +50,7 @@ byte_buddy_version=1.17.5
ahocorasick_version=0.6.3 ahocorasick_version=0.6.3
snake_yaml_version=2.5 snake_yaml_version=2.5
anti_grief_version=1.0.2 anti_grief_version=1.0.2
nms_helper_version=1.0.107 nms_helper_version=1.0.108
evalex_version=3.5.0 evalex_version=3.5.0
reactive_streams_version=1.0.4 reactive_streams_version=1.0.4
amazon_awssdk_version=2.34.5 amazon_awssdk_version=2.34.5