Skip to content

Commit

Permalink
bug fix
Browse files Browse the repository at this point in the history
  • Loading branch information
acrylic-style committed Nov 3, 2024
1 parent cb4824a commit 7e4c850
Show file tree
Hide file tree
Showing 17 changed files with 145 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,14 @@ public static boolean isModernNMS() {
throw new RuntimeException(e);
}
}

public static void setField(@NotNull Object o, @NotNull String fieldName, @NotNull Object value) {
try {
Field field = o.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(o, value);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
}
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {

allprojects {
group = "net.azisaba.loreeditor"
version = "1.2.0"
version = "1.2.1"

apply {
plugin("java")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ public PacketPreHandler(@NotNull Plugin plugin, @NotNull Player player) {
public void channelRead(@NotNull ChannelHandlerContext ctx, @NotNull Object msg) throws Exception {
// client -> server
try {
if (msg.getClass().getSimpleName().contains("SetCreativeSlot")) {
if (msg.getClass().getSimpleName().contains("SetCreative")) {
ServerboundSetCreativeSlot packet = ServerboundSetCreativeSlot.getInstance(msg);
reverseProcessItemStack(packet.getItem());
} else if (msg.getClass().getSimpleName().contains("WindowClick")) {
} else if (msg.getClass().getSimpleName().contains("WindowClick") || msg.getClass().getSimpleName().contains("ContainerClick")) {
ServerboundClickContainerSlot packet = ServerboundClickContainerSlot.getInstance(msg);
reverseProcessItemStack(packet.getItem());
} else if (msg.getClass().getSimpleName().contains("CloseWindow")) {
} else if (msg.getClass().getSimpleName().contains("ContainerClose") || msg.getClass().getSimpleName().contains("WindowClose")) {
if (player.getOpenInventory().getType() == InventoryType.MERCHANT) {
// re-add lore after trading
Bukkit.getScheduler().runTask(plugin, player::updateInventory);
Expand All @@ -75,23 +75,28 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
if (msg.getClass().getSimpleName().contains("WindowItems") || msg.getClass().getSimpleName().contains("ContainerSetContent")) {
if (player.getOpenInventory().getType() != InventoryType.MERCHANT) {
ClientboundWindowItems packet = ClientboundWindowItems.getInstance(msg);
packet.getItems().forEach(i -> {
packet.setItems(packet.getItems().stream().map(ItemStack::copy).peek(i -> {
PROCESS_ITEM_PERF_COUNTER.recordStart();
try {
processItemStack(i);
} finally {
PROCESS_ITEM_PERF_COUNTER.recordEnd();
}
});
}).collect(Collectors.toList()));
}
} else if (msg.getClass().getSimpleName().contains("SetSlot")) {
if (player.getOpenInventory().getType() != InventoryType.MERCHANT) {
ClientboundSetSlot packet = ClientboundSetSlot.getInstance(msg);
PROCESS_ITEM_PERF_COUNTER.recordStart();
try {
processItemStack(packet.getItem());
} finally {
PROCESS_ITEM_PERF_COUNTER.recordEnd();
ItemStack item = packet.getItem();
if (item != null) {
item = item.copy();
PROCESS_ITEM_PERF_COUNTER.recordStart();
try {
processItemStack(item);
} finally {
PROCESS_ITEM_PERF_COUNTER.recordEnd();
}
packet.replaceItem(item);
}
}
}
Expand All @@ -102,14 +107,14 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
}

public void processItemStack(@Nullable ItemStack item) {
if (item == null) return;
if (item == null || item.getCount() == 0) return;
CompoundTag tag = item.getTag();
boolean hadTag = tag != null;
if (tag == null) {
tag = CompoundTag.getInstance(null).constructor();
}
if (tag.hasKeyOfType("lore_editor", 10)) {
reverseProcessItemStack(item);
return;
}
CompoundTag loreEditorTag = CompoundTag.getInstance(null).constructor();
AtomicReference<CompoundTag> displayTag = new AtomicReference<>(tag.getCompound("display"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,10 @@ public interface ClientboundSetSlot {

@Nullable
ItemStack getItem();

/**
* Replaces the item tag/component. Other properties of the item stack are not guaranteed to be preserved.
* @param item new item tag/component
*/
void replaceItem(@NotNull ItemStack item);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ public interface ClientboundWindowItems {
*/
@NotNull
List<ItemStack> getItems();

void setItems(@NotNull List<ItemStack> items);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,9 @@ public ClientboundSetSlotImpl(PacketPlayOutSetSlot handle) {
public @Nullable ItemStack getItem() {
return ItemStackImpl.getInstance(ReflectionUtil.getField(handle, "c"));
}

@Override
public void replaceItem(@NotNull ItemStack item) {
ReflectionUtil.setField(handle, "c", ((ItemStackImpl) item).getHandle());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,13 @@ public ClientboundWindowItemsImpl(@NotNull PacketPlayOutWindowItems handle) {
}
return items;
}

@Override
public void setItems(@NotNull List<ItemStack> items) {
List<Object> list = new ArrayList<>();
for (ItemStack item : items) {
list.add(((ItemStackImpl) item).getHandle());
}
ReflectionUtil.setField(getHandle(), "b", list);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,9 @@ public ClientboundSetSlotImpl(PacketPlayOutSetSlot handle) {
public @Nullable ItemStack getItem() {
return ItemStackImpl.getInstance(ReflectionUtil.getField(handle, "c"));
}

@Override
public void replaceItem(@NotNull ItemStack item) {
ReflectionUtil.setField(handle, "c", ((ItemStackImpl) item).getHandle());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,13 @@ public ClientboundWindowItemsImpl(@NotNull PacketPlayOutWindowItems handle) {
}
return items;
}

@Override
public void setItems(@NotNull List<ItemStack> items) {
List<Object> list = new ArrayList<>();
for (ItemStack item : items) {
list.add(((ItemStackImpl) item).getHandle());
}
ReflectionUtil.setField(getHandle(), "b", list);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,10 @@ public ClientboundSetSlotImpl(PacketPlayOutSetSlot handle) {
public @Nullable ItemStack getItem() {
return ItemStackImpl.getInstance(ReflectionUtil.getField(handle, "f"));
}

@Override
public void replaceItem(@NotNull ItemStack item) {
if (getItem() == null) throw new IllegalStateException("Cannot replace null item (for now)");
getItem().setTag(item.getTag());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import net.azisaba.loreeditor.api.item.ItemStack;
import net.azisaba.loreeditor.common.network.packet.ClientboundWindowItems;
import net.azisaba.loreeditor.api.util.ReflectionUtil;
import net.azisaba.loreeditor.v1_19_R3.item.ItemStackImpl;
import net.minecraft.network.protocol.game.PacketPlayOutWindowItems;
import org.jetbrains.annotations.Contract;
Expand Down Expand Up @@ -30,9 +29,16 @@ public ClientboundWindowItemsImpl(@NotNull PacketPlayOutWindowItems handle) {
@Override
public @NotNull List<ItemStack> getItems() {
List<ItemStack> items = new ArrayList<>();
for (Object o : ((List<?>) ReflectionUtil.getField(getHandle(), "c"))) {
for (Object o : handle.c()) {
items.add(ItemStackImpl.getInstance(o));
}
return items;
}

@Override
public void setItems(@NotNull List<ItemStack> items) {
for (int i = 0; i < items.size(); i++) {
handle.c().set(i, ((ItemStackImpl) items.get(i)).getHandle());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,10 @@ public ClientboundSetSlotImpl(PacketPlayOutSetSlot handle) {
public @Nullable ItemStack getItem() {
return ItemStackImpl.getInstance(ReflectionUtil.getField(handle, "f"));
}

@Override
public void replaceItem(@NotNull ItemStack item) {
if (getItem() == null) throw new IllegalStateException("Cannot replace null item (for now)");
getItem().setTag(item.getTag());
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package net.azisaba.loreeditor.v1_20.network.packet;

import net.azisaba.loreeditor.api.item.ItemStack;
import net.azisaba.loreeditor.api.util.ReflectionUtil;
import net.azisaba.loreeditor.common.network.packet.ClientboundWindowItems;
import net.azisaba.loreeditor.v1_20.item.ItemStackImpl;
import net.minecraft.network.protocol.game.PacketPlayOutWindowItems;
Expand Down Expand Up @@ -30,9 +29,16 @@ public ClientboundWindowItemsImpl(@NotNull PacketPlayOutWindowItems handle) {
@Override
public @NotNull List<ItemStack> getItems() {
List<ItemStack> items = new ArrayList<>();
for (Object o : ((List<?>) ReflectionUtil.getField(getHandle(), "c"))) {
for (Object o : handle.d()) {
items.add(ItemStackImpl.getInstance(o));
}
return items;
}

@Override
public void setItems(@NotNull List<ItemStack> items) {
for (int i = 0; i < items.size(); i++) {
handle.d().set(i, ((ItemStackImpl) items.get(i)).handle());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public static MutableComponent deserializeFromJson(@NotNull String input) {
return net.minecraft.network.chat.Component.Serializer.fromJson(input, registries);
}

public static String serializeToJson(@NotNull MutableComponent component) {
public static String serializeToJson(@NotNull net.minecraft.network.chat.Component component) {
RegistryAccess registries = ((CraftServer) Bukkit.getServer()).getServer().registryAccess();
return net.minecraft.network.chat.Component.Serializer.toJson(component, registries);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
import net.azisaba.loreeditor.v1_21_1.chat.ComponentImpl;
import net.azisaba.loreeditor.v1_21_1.item.tag.CompoundTagImpl;
import net.azisaba.loreeditor.v1_21_1.item.tag.ListTagImpl;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.component.ItemLore;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -45,17 +48,38 @@ public ItemStackImpl(net.minecraft.world.item.ItemStack handle) {
customData = CustomData.of(new net.minecraft.nbt.CompoundTag());
handle.set(DataComponents.CUSTOM_DATA, customData);
}
return new CompoundTagImpl(customData.getUnsafe());
return handleLore(new CompoundTagImpl(customData.getUnsafe()));
}

@SuppressWarnings("deprecation")
@Override
public @Nullable CompoundTag getTag() {
CustomData customData = handle.get(DataComponents.CUSTOM_DATA);
if (customData == null) {
return null;
return handleLore(null);
}
return new CompoundTagImpl(customData.getUnsafe());
return handleLore(new CompoundTagImpl(customData.getUnsafe()));
}

private CompoundTag handleLore(@Nullable CompoundTag base) {
var handle = new net.minecraft.nbt.ListTag();
ListTag listTag = new ListTagImpl(handle);
if (handle().has(DataComponents.LORE)) {
Objects.requireNonNull(handle().get(DataComponents.LORE)).lines()
.forEach(component -> handle.add(StringTag.valueOf(ComponentImpl.serializeToJson(component))));
} else {
return base;
}
if (handle.isEmpty()) {
return base;
}
if (base == null) {
base = new CompoundTagImpl(new net.minecraft.nbt.CompoundTag());
}
CompoundTag displayTag = base.getCompound("display");
displayTag.set("Lore", listTag);
base.set("display", displayTag);
return base;
}

@Override
Expand All @@ -75,6 +99,8 @@ public void setTag(@Nullable CompoundTag tag) {
.map(ComponentImpl::deserializeFromJson)
.collect(Collectors.toUnmodifiableList());
handle.set(DataComponents.LORE, new ItemLore(lore));
} else {
handle.remove(DataComponents.LORE);
}
}
}
Expand All @@ -86,6 +112,15 @@ public int getCount() {

@Override
public @NotNull ItemStack copy() {
return new ItemStackImpl(handle.copy());
org.bukkit.inventory.ItemStack originalStack = handle.getBukkitStack();
org.bukkit.inventory.ItemStack stack = new org.bukkit.inventory.ItemStack(originalStack.getType(), handle.getCount());
if (originalStack.hasItemMeta()) {
stack.setItemMeta(originalStack.getItemMeta().clone());
}
return new ItemStackImpl(CraftItemStack.asNMSCopy(stack));
}

public DataComponentMap getComponents() {
return handle.getComponents();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,10 @@ public ClientboundSetSlotImpl(ClientboundContainerSetSlotPacket handle) {
public @Nullable ItemStack getItem() {
return ItemStackImpl.getInstance(handle.getItem());
}

@Override
public void replaceItem(@NotNull ItemStack item) {
if (getItem() == null) throw new IllegalStateException("Cannot replace null item (for now)");
((ItemStackImpl) getItem()).handle().restorePatch(((ItemStackImpl) item).handle().getComponentsPatch());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,11 @@ public ClientboundWindowItemsImpl(@NotNull ClientboundContainerSetContentPacket
}
return items;
}

@Override
public void setItems(@NotNull List<ItemStack> items) {
for (int i = 0; i < items.size(); i++) {
handle.getItems().set(i, ((ItemStackImpl) items.get(i)).handle());
}
}
}

0 comments on commit 7e4c850

Please sign in to comment.