Added survival friendly way to obtain invisible item frames

This commit is contained in:
LOOHP committed 2025-02-04 01:51:25 +00:00
1 parent ea0563ff50
commit 0c2d8f7787
48 files changed
+2073 -23

No files matched your search

+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_16</artifactId>
@@ -23,6 +23,10 @@ package com.loohp.imageframe.nms;
import com.loohp.imageframe.objectholders.CombinedMapItemInfo;
import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.UUIDUtils;
import com.loohp.imageframe.utils.UnsafeAccessor;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import net.minecraft.server.v1_16_R1.ChunkProviderServer;
import net.minecraft.server.v1_16_R1.DataWatcher;
import net.minecraft.server.v1_16_R1.DataWatcherObject;
@@ -33,6 +37,8 @@ import net.minecraft.server.v1_16_R1.IChatBaseComponent;
import net.minecraft.server.v1_16_R1.ItemWorldMap;
import net.minecraft.server.v1_16_R1.MapIcon;
import net.minecraft.server.v1_16_R1.NBTTagCompound;
import net.minecraft.server.v1_16_R1.NBTTagList;
import net.minecraft.server.v1_16_R1.NBTTagString;
import net.minecraft.server.v1_16_R1.Packet;
import net.minecraft.server.v1_16_R1.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_16_R1.PacketPlayOutMap;
@@ -43,18 +49,23 @@ import net.minecraft.server.v1_16_R1.WorldMap;
import net.minecraft.server.v1_16_R1.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2IntMap;
import org.bukkit.craftbukkit.v1_16_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_16_R1.map.CraftMapView;
import org.bukkit.craftbukkit.v1_16_R1.map.RenderData;
import org.bukkit.craftbukkit.v1_16_R1.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -72,6 +83,7 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_16 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field nmsMapIconTypeDisplayField;
private final Field[] nmsPacketPlayOutEntityMetadataFields;
@@ -80,6 +92,7 @@ public class V1_16 extends NMSWrapper {
public V1_16() {
try {
nmsEntityByteDataWatcherField = net.minecraft.server.v1_16_R1.Entity.class.getDeclaredField("T");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
nmsMapIconTypeDisplayField = MapIcon.Type.class.getDeclaredField("C");
nmsPacketPlayOutEntityMetadataFields = PacketPlayOutEntityMetadata.class.getDeclaredFields();
@@ -242,6 +255,46 @@ public class V1_16 extends NMSWrapper {
}
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.server.v1_16_R1.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.getDataWatcher();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.get(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.Item<?>> dataWatchers = Collections.singletonList(new DataWatcher.Item<>(byteField, value));
PacketPlayOutEntityMetadata packet = (PacketPlayOutEntityMetadata) UnsafeAccessor.getUnsafe().allocateInstance(PacketPlayOutEntityMetadata.class);
nmsPacketPlayOutEntityMetadataFields[0].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[0].setInt(packet, entityId);
nmsPacketPlayOutEntityMetadataFields[1].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[1].set(packet, dataWatchers);
return packet;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().playerConnection.sendPacket((Packet<?>) packet);
@@ -275,4 +328,41 @@ public class V1_16 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.server.v1_16_R1.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == 9) {
NBTTagList loreLineTagList = displayTag.getList("Lore", 8);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.getString(i));
}
} else {
loreLines = new ArrayList<>(1);
}
TranslatableComponent translatableComponent = new TranslatableComponent("effect.minecraft.invisibility");
translatableComponent.setColor(ChatColor.GRAY);
translatableComponent.setItalic(false);
loreLines.add(0, ComponentSerializer.toString(translatableComponent));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.set("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_16_2</artifactId>
@@ -23,6 +23,10 @@ package com.loohp.imageframe.nms;
import com.loohp.imageframe.objectholders.CombinedMapItemInfo;
import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.UUIDUtils;
import com.loohp.imageframe.utils.UnsafeAccessor;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import net.minecraft.server.v1_16_R2.ChunkProviderServer;
import net.minecraft.server.v1_16_R2.DataWatcher;
import net.minecraft.server.v1_16_R2.DataWatcherObject;
@@ -33,6 +37,8 @@ import net.minecraft.server.v1_16_R2.IChatBaseComponent;
import net.minecraft.server.v1_16_R2.ItemWorldMap;
import net.minecraft.server.v1_16_R2.MapIcon;
import net.minecraft.server.v1_16_R2.NBTTagCompound;
import net.minecraft.server.v1_16_R2.NBTTagList;
import net.minecraft.server.v1_16_R2.NBTTagString;
import net.minecraft.server.v1_16_R2.Packet;
import net.minecraft.server.v1_16_R2.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_16_R2.PacketPlayOutMap;
@@ -43,18 +49,23 @@ import net.minecraft.server.v1_16_R2.WorldMap;
import net.minecraft.server.v1_16_R2.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2IntMap;
import org.bukkit.craftbukkit.v1_16_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_16_R2.map.CraftMapView;
import org.bukkit.craftbukkit.v1_16_R2.map.RenderData;
import org.bukkit.craftbukkit.v1_16_R2.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -72,6 +83,7 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_16_2 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field nmsMapIconTypeDisplayField;
private final Field[] nmsPacketPlayOutEntityMetadataFields;
@@ -80,6 +92,7 @@ public class V1_16_2 extends NMSWrapper {
public V1_16_2() {
try {
nmsEntityByteDataWatcherField = net.minecraft.server.v1_16_R2.Entity.class.getDeclaredField("S");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
nmsMapIconTypeDisplayField = MapIcon.Type.class.getDeclaredField("C");
nmsPacketPlayOutEntityMetadataFields = PacketPlayOutEntityMetadata.class.getDeclaredFields();
@@ -242,6 +255,46 @@ public class V1_16_2 extends NMSWrapper {
}
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.server.v1_16_R2.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.getDataWatcher();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.get(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.Item<?>> dataWatchers = Collections.singletonList(new DataWatcher.Item<>(byteField, value));
PacketPlayOutEntityMetadata packet = (PacketPlayOutEntityMetadata) UnsafeAccessor.getUnsafe().allocateInstance(PacketPlayOutEntityMetadata.class);
nmsPacketPlayOutEntityMetadataFields[0].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[0].setInt(packet, entityId);
nmsPacketPlayOutEntityMetadataFields[1].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[1].set(packet, dataWatchers);
return packet;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().playerConnection.sendPacket((Packet<?>) packet);
@@ -275,4 +328,41 @@ public class V1_16_2 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.server.v1_16_R2.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == 9) {
NBTTagList loreLineTagList = displayTag.getList("Lore", 8);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.getString(i));
}
} else {
loreLines = new ArrayList<>(1);
}
TranslatableComponent translatableComponent = new TranslatableComponent("effect.minecraft.invisibility");
translatableComponent.setColor(ChatColor.GRAY);
translatableComponent.setItalic(false);
loreLines.add(0, ComponentSerializer.toString(translatableComponent));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.set("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_16_4</artifactId>
@@ -23,6 +23,10 @@ package com.loohp.imageframe.nms;
import com.loohp.imageframe.objectholders.CombinedMapItemInfo;
import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.UUIDUtils;
import com.loohp.imageframe.utils.UnsafeAccessor;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import net.minecraft.server.v1_16_R3.ChunkProviderServer;
import net.minecraft.server.v1_16_R3.DataWatcher;
import net.minecraft.server.v1_16_R3.DataWatcherObject;
@@ -33,6 +37,8 @@ import net.minecraft.server.v1_16_R3.IChatBaseComponent;
import net.minecraft.server.v1_16_R3.ItemWorldMap;
import net.minecraft.server.v1_16_R3.MapIcon;
import net.minecraft.server.v1_16_R3.NBTTagCompound;
import net.minecraft.server.v1_16_R3.NBTTagList;
import net.minecraft.server.v1_16_R3.NBTTagString;
import net.minecraft.server.v1_16_R3.Packet;
import net.minecraft.server.v1_16_R3.PacketPlayOutEntityMetadata;
import net.minecraft.server.v1_16_R3.PacketPlayOutMap;
@@ -43,18 +49,23 @@ import net.minecraft.server.v1_16_R3.WorldMap;
import net.minecraft.server.v1_16_R3.WorldServer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2IntMap;
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_16_R3.map.CraftMapView;
import org.bukkit.craftbukkit.v1_16_R3.map.RenderData;
import org.bukkit.craftbukkit.v1_16_R3.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -72,6 +83,7 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_16_4 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field nmsMapIconTypeDisplayField;
private final Field[] nmsPacketPlayOutEntityMetadataFields;
@@ -80,6 +92,7 @@ public class V1_16_4 extends NMSWrapper {
public V1_16_4() {
try {
nmsEntityByteDataWatcherField = net.minecraft.server.v1_16_R3.Entity.class.getDeclaredField("S");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
nmsMapIconTypeDisplayField = MapIcon.Type.class.getDeclaredField("C");
nmsPacketPlayOutEntityMetadataFields = PacketPlayOutEntityMetadata.class.getDeclaredFields();
@@ -242,6 +255,46 @@ public class V1_16_4 extends NMSWrapper {
}
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.server.v1_16_R3.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.getDataWatcher();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.get(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.Item<?>> dataWatchers = Collections.singletonList(new DataWatcher.Item<>(byteField, value));
PacketPlayOutEntityMetadata packet = (PacketPlayOutEntityMetadata) UnsafeAccessor.getUnsafe().allocateInstance(PacketPlayOutEntityMetadata.class);
nmsPacketPlayOutEntityMetadataFields[0].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[0].setInt(packet, entityId);
nmsPacketPlayOutEntityMetadataFields[1].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[1].set(packet, dataWatchers);
return packet;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().playerConnection.sendPacket((Packet<?>) packet);
@@ -275,4 +328,41 @@ public class V1_16_4 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.server.v1_16_R3.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == 9) {
NBTTagList loreLineTagList = displayTag.getList("Lore", 8);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.getString(i));
}
} else {
loreLines = new ArrayList<>(1);
}
TranslatableComponent translatableComponent = new TranslatableComponent("effect.minecraft.invisibility");
translatableComponent.setColor(ChatColor.GRAY);
translatableComponent.setItalic(false);
loreLines.add(0, ComponentSerializer.toString(translatableComponent));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.set("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_17</artifactId>
@@ -24,7 +24,13 @@ import com.loohp.imageframe.objectholders.CombinedMapItemInfo;
import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.UUIDUtils;
import com.loohp.imageframe.utils.UnsafeAccessor;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
@@ -45,18 +51,23 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.objects.Object2IntMap;
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_17_R1.map.CraftMapView;
import org.bukkit.craftbukkit.v1_17_R1.map.RenderData;
import org.bukkit.craftbukkit.v1_17_R1.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -74,6 +85,7 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_17 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field[] nmsPacketPlayOutEntityMetadataFields;
private final Field nmsItemFrameItemStackDataWatcherField;
@@ -81,6 +93,7 @@ public class V1_17 extends NMSWrapper {
public V1_17() {
try {
nmsEntityByteDataWatcherField = net.minecraft.world.entity.Entity.class.getDeclaredField("Z");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
nmsPacketPlayOutEntityMetadataFields = PacketPlayOutEntityMetadata.class.getDeclaredFields();
nmsItemFrameItemStackDataWatcherField = EntityItemFrame.class.getDeclaredField("ao");
@@ -229,6 +242,46 @@ public class V1_17 extends NMSWrapper {
}
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.getDataWatcher();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.get(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.Item<?>> dataWatchers = Collections.singletonList(new DataWatcher.Item<>(byteField, value));
PacketPlayOutEntityMetadata packet = (PacketPlayOutEntityMetadata) UnsafeAccessor.getUnsafe().allocateInstance(PacketPlayOutEntityMetadata.class);
nmsPacketPlayOutEntityMetadataFields[0].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[0].setInt(packet, entityId);
nmsPacketPlayOutEntityMetadataFields[1].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[1].set(packet, dataWatchers);
return packet;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().b.sendPacket((Packet<?>) packet);
@@ -262,4 +315,41 @@ public class V1_17 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == NBTBase.q) {
NBTTagList loreLineTagList = displayTag.getList("Lore", NBTBase.p);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.getString(i));
}
} else {
loreLines = new ArrayList<>(1);
}
TranslatableComponent translatableComponent = new TranslatableComponent("effect.minecraft.invisibility");
translatableComponent.setColor(ChatColor.GRAY);
translatableComponent.setItalic(false);
loreLines.add(0, ComponentSerializer.toString(translatableComponent));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.set("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_18</artifactId>
@@ -26,7 +26,13 @@ import com.loohp.imageframe.utils.UUIDUtils;
import com.loohp.imageframe.utils.UnsafeAccessor;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
@@ -47,16 +53,21 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_18_R1.map.CraftMapView;
import org.bukkit.craftbukkit.v1_18_R1.map.RenderData;
import org.bukkit.craftbukkit.v1_18_R1.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -74,6 +85,7 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_18 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field[] nmsPacketPlayOutEntityMetadataFields;
private final Field nmsItemFrameItemStackDataWatcherField;
@@ -81,6 +93,7 @@ public class V1_18 extends NMSWrapper {
public V1_18() {
try {
nmsEntityByteDataWatcherField = net.minecraft.world.entity.Entity.class.getDeclaredField("aa");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
nmsPacketPlayOutEntityMetadataFields = PacketPlayOutEntityMetadata.class.getDeclaredFields();
nmsItemFrameItemStackDataWatcherField = EntityItemFrame.class.getDeclaredField("ap");
@@ -229,6 +242,46 @@ public class V1_18 extends NMSWrapper {
}
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.ai();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.Item<?>> dataWatchers = Collections.singletonList(new DataWatcher.Item<>(byteField, value));
PacketPlayOutEntityMetadata packet = (PacketPlayOutEntityMetadata) UnsafeAccessor.getUnsafe().allocateInstance(PacketPlayOutEntityMetadata.class);
nmsPacketPlayOutEntityMetadataFields[0].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[0].setInt(packet, entityId);
nmsPacketPlayOutEntityMetadataFields[1].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[1].set(packet, dataWatchers);
return packet;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().b.a((Packet<?>) packet);
@@ -262,4 +315,41 @@ public class V1_18 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == NBTBase.q) {
NBTTagList loreLineTagList = displayTag.c("Lore", NBTBase.p);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.j(i));
}
} else {
loreLines = new ArrayList<>(1);
}
TranslatableComponent translatableComponent = new TranslatableComponent("effect.minecraft.invisibility");
translatableComponent.setColor(ChatColor.GRAY);
translatableComponent.setItalic(false);
loreLines.add(0, ComponentSerializer.toString(translatableComponent));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.a("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_18_2</artifactId>
@@ -26,7 +26,13 @@ import com.loohp.imageframe.utils.UUIDUtils;
import com.loohp.imageframe.utils.UnsafeAccessor;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.TranslatableComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
@@ -47,16 +53,21 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_18_R2.map.CraftMapView;
import org.bukkit.craftbukkit.v1_18_R2.map.RenderData;
import org.bukkit.craftbukkit.v1_18_R2.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -74,6 +85,7 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_18_2 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field[] nmsPacketPlayOutEntityMetadataFields;
private final Field nmsItemFrameItemStackDataWatcherField;
@@ -81,6 +93,7 @@ public class V1_18_2 extends NMSWrapper {
public V1_18_2() {
try {
nmsEntityByteDataWatcherField = net.minecraft.world.entity.Entity.class.getDeclaredField("Z");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
nmsPacketPlayOutEntityMetadataFields = PacketPlayOutEntityMetadata.class.getDeclaredFields();
nmsItemFrameItemStackDataWatcherField = EntityItemFrame.class.getDeclaredField("ao");
@@ -229,6 +242,46 @@ public class V1_18_2 extends NMSWrapper {
}
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.ai();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.Item<?>> dataWatchers = Collections.singletonList(new DataWatcher.Item<>(byteField, value));
PacketPlayOutEntityMetadata packet = (PacketPlayOutEntityMetadata) UnsafeAccessor.getUnsafe().allocateInstance(PacketPlayOutEntityMetadata.class);
nmsPacketPlayOutEntityMetadataFields[0].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[0].setInt(packet, entityId);
nmsPacketPlayOutEntityMetadataFields[1].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[1].set(packet, dataWatchers);
return packet;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().b.a((Packet<?>) packet);
@@ -262,4 +315,41 @@ public class V1_18_2 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == NBTBase.q) {
NBTTagList loreLineTagList = displayTag.c("Lore", NBTBase.p);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.j(i));
}
} else {
loreLines = new ArrayList<>(1);
}
TranslatableComponent translatableComponent = new TranslatableComponent("effect.minecraft.invisibility");
translatableComponent.setColor(ChatColor.GRAY);
translatableComponent.setItalic(false);
loreLines.add(0, ComponentSerializer.toString(translatableComponent));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.a("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_19</artifactId>
@@ -26,7 +26,12 @@ import com.loohp.imageframe.utils.UUIDUtils;
import com.loohp.imageframe.utils.UnsafeAccessor;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
@@ -47,16 +52,21 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_19_R1.map.CraftMapView;
import org.bukkit.craftbukkit.v1_19_R1.map.RenderData;
import org.bukkit.craftbukkit.v1_19_R1.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -74,6 +84,7 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_19 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field[] nmsPacketPlayOutEntityMetadataFields;
private final Field nmsItemFrameItemStackDataWatcherField;
@@ -81,6 +92,7 @@ public class V1_19 extends NMSWrapper {
public V1_19() {
try {
nmsEntityByteDataWatcherField = net.minecraft.world.entity.Entity.class.getDeclaredField("Z");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
nmsPacketPlayOutEntityMetadataFields = PacketPlayOutEntityMetadata.class.getDeclaredFields();
nmsItemFrameItemStackDataWatcherField = EntityItemFrame.class.getDeclaredField("ao");
@@ -229,6 +241,46 @@ public class V1_19 extends NMSWrapper {
}
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.ai();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.Item<?>> dataWatchers = Collections.singletonList(new DataWatcher.Item<>(byteField, value));
PacketPlayOutEntityMetadata packet = (PacketPlayOutEntityMetadata) UnsafeAccessor.getUnsafe().allocateInstance(PacketPlayOutEntityMetadata.class);
nmsPacketPlayOutEntityMetadataFields[0].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[0].setInt(packet, entityId);
nmsPacketPlayOutEntityMetadataFields[1].setAccessible(true);
nmsPacketPlayOutEntityMetadataFields[1].set(packet, dataWatchers);
return packet;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().b.a((Packet<?>) packet);
@@ -262,4 +314,38 @@ public class V1_19 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == NBTBase.q) {
NBTTagList loreLineTagList = displayTag.c("Lore", NBTBase.p);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.j(i));
}
} else {
loreLines = new ArrayList<>(1);
}
loreLines.add(0, CraftChatMessage.toJSON(IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false))));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.a("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_19_3</artifactId>
@@ -25,12 +25,18 @@ import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ChunkProviderServer;
import net.minecraft.server.level.PlayerChunkMap;
@@ -45,16 +51,21 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_19_R2.map.CraftMapView;
import org.bukkit.craftbukkit.v1_19_R2.map.RenderData;
import org.bukkit.craftbukkit.v1_19_R2.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -72,11 +83,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_19_3 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_19_3() {
try {
nmsEntityByteDataWatcherField = net.minecraft.world.entity.Entity.class.getDeclaredField("Z");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = PersistentIdCounts.class.getDeclaredField("b");
} catch (NoSuchFieldException e) {
@@ -211,6 +224,41 @@ public class V1_19_3 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.al();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.b<?>> dataWatchers = Collections.singletonList(DataWatcher.b.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().b.a((Packet<?>) packet);
@@ -244,4 +292,38 @@ public class V1_19_3 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == NBTBase.q) {
NBTTagList loreLineTagList = displayTag.c("Lore", NBTBase.p);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.j(i));
}
} else {
loreLines = new ArrayList<>(1);
}
loreLines.add(0, CraftChatMessage.toJSON(IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false))));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.a("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_19_4</artifactId>
@@ -25,12 +25,18 @@ import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ChunkProviderServer;
import net.minecraft.server.level.PlayerChunkMap;
@@ -45,16 +51,21 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_19_R3.map.CraftMapView;
import org.bukkit.craftbukkit.v1_19_R3.map.RenderData;
import org.bukkit.craftbukkit.v1_19_R3.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -72,11 +83,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_19_4 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_19_4() {
try {
nmsEntityByteDataWatcherField = net.minecraft.world.entity.Entity.class.getDeclaredField("an");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = PersistentIdCounts.class.getDeclaredField("b");
} catch (NoSuchFieldException e) {
@@ -211,6 +224,41 @@ public class V1_19_4 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.aj();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.b<?>> dataWatchers = Collections.singletonList(DataWatcher.b.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().b.a((Packet<?>) packet);
@@ -244,4 +292,38 @@ public class V1_19_4 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == NBTBase.q) {
NBTTagList loreLineTagList = displayTag.c("Lore", NBTBase.p);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.j(i));
}
} else {
loreLines = new ArrayList<>(1);
}
loreLines.add(0, CraftChatMessage.toJSON(IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false))));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.a("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_20</artifactId>
@@ -25,12 +25,18 @@ import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ChunkProviderServer;
import net.minecraft.server.level.PlayerChunkMap;
@@ -45,16 +51,21 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R1.map.CraftMapView;
import org.bukkit.craftbukkit.v1_20_R1.map.RenderData;
import org.bukkit.craftbukkit.v1_20_R1.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -72,11 +83,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_20 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_20() {
try {
nmsEntityByteDataWatcherField = net.minecraft.world.entity.Entity.class.getDeclaredField("an");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = PersistentIdCounts.class.getDeclaredField("b");
} catch (NoSuchFieldException e) {
@@ -211,6 +224,41 @@ public class V1_20 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.aj();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.b(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.b<?>> dataWatchers = Collections.singletonList(DataWatcher.b.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().c.a((Packet<?>) packet);
@@ -244,4 +292,38 @@ public class V1_20 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == NBTBase.q) {
NBTTagList loreLineTagList = displayTag.c("Lore", NBTBase.p);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.j(i));
}
} else {
loreLines = new ArrayList<>(1);
}
loreLines.add(0, CraftChatMessage.toJSON(IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false))));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.a("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_20_2</artifactId>
@@ -25,12 +25,18 @@ import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ChunkProviderServer;
import net.minecraft.server.level.PlayerChunkMap;
@@ -45,16 +51,21 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R2.map.CraftMapView;
import org.bukkit.craftbukkit.v1_20_R2.map.RenderData;
import org.bukkit.craftbukkit.v1_20_R2.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -72,11 +83,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_20_2 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_20_2() {
try {
nmsEntityByteDataWatcherField = net.minecraft.world.entity.Entity.class.getDeclaredField("ao");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = PersistentIdCounts.class.getDeclaredField("b");
} catch (NoSuchFieldException e) {
@@ -211,6 +224,41 @@ public class V1_20_2 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.al();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.b(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.b<?>> dataWatchers = Collections.singletonList(DataWatcher.b.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().c.b((Packet<?>) packet);
@@ -244,4 +292,38 @@ public class V1_20_2 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == NBTBase.q) {
NBTTagList loreLineTagList = displayTag.c("Lore", NBTBase.p);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.j(i));
}
} else {
loreLines = new ArrayList<>(1);
}
loreLines.add(0, CraftChatMessage.toJSON(IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false))));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.a("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_20_3</artifactId>
@@ -24,12 +24,18 @@ import com.loohp.imageframe.objectholders.CombinedMapItemInfo;
import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.decoration.EntityItemFrame;
@@ -40,16 +46,21 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R3.map.CraftMapView;
import org.bukkit.craftbukkit.v1_20_R3.map.RenderData;
import org.bukkit.craftbukkit.v1_20_R3.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -67,11 +78,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_20_3 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_20_3() {
try {
nmsEntityByteDataWatcherField = net.minecraft.world.entity.Entity.class.getDeclaredField("ao");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = PersistentIdCounts.class.getDeclaredField("b");
} catch (NoSuchFieldException e) {
@@ -191,6 +204,41 @@ public class V1_20_3 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.an();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.b(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.b<?>> dataWatchers = Collections.singletonList(DataWatcher.b.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().c.b((Packet<?>) packet);
@@ -224,4 +272,38 @@ public class V1_20_3 extends NMSWrapper {
}
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
NBTTagCompound displayTag = nmsItemStack.a("display");
List<String> loreLines;
if (displayTag.d("Lore") == NBTBase.q) {
NBTTagList loreLineTagList = displayTag.c("Lore", NBTBase.p);
loreLines = new ArrayList<>(loreLineTagList.size());
for (int i = 0; i < loreLineTagList.size(); i++) {
loreLines.add(loreLineTagList.j(i));
}
} else {
loreLines = new ArrayList<>(1);
}
loreLines.add(0, CraftChatMessage.toJSON(IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false))));
NBTTagList loreLineTagList = new NBTTagList();
for (int i = 0; i < loreLines.size(); i++) {
loreLineTagList.a(i, NBTTagString.a(loreLines.get(i)));
}
displayTag.a("Lore", loreLineTagList);
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_20_5</artifactId>
@@ -25,20 +25,24 @@ import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.ReflectionUtils;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.decoration.EntityItemFrame;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.component.ItemLore;
import net.minecraft.world.level.saveddata.maps.MapDecorationType;
import net.minecraft.world.level.saveddata.maps.MapIcon;
import net.minecraft.world.level.saveddata.maps.MapId;
@@ -46,17 +50,22 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_20_R4.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R4.map.CraftMapCursor;
import org.bukkit.craftbukkit.v1_20_R4.map.CraftMapView;
import org.bukkit.craftbukkit.v1_20_R4.map.RenderData;
import org.bukkit.craftbukkit.v1_20_R4.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -75,11 +84,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_20_5 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_20_5() {
try {
nmsEntityByteDataWatcherField = ReflectionUtils.findDeclaredField(net.minecraft.world.entity.Entity.class, DataWatcherObject.class, "DATA_SHARED_FLAGS_ID", "ap");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = ReflectionUtils.findDeclaredField(PersistentIdCounts.class, Object2IntMap.class, "usedAuxIds", "b");
} catch (NoSuchFieldException e) {
@@ -199,6 +210,41 @@ public class V1_20_5 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.ap();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.c<?>> dataWatchers = Collections.singletonList(DataWatcher.c.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().c.sendPacket((Packet<?>) packet);
@@ -238,4 +284,25 @@ public class V1_20_5 extends NMSWrapper {
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.b, CustomData.a(tag)).a());
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
ItemLore itemLore = nmsItemStack.a(DataComponents.i, ItemLore.a);
List<IChatBaseComponent> loreLines = new ArrayList<>(itemLore.a());
loreLines.add(0, IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false)));
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.i, new ItemLore(loreLines)).a());
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK_OF_THE_SEA, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_20_6</artifactId>
@@ -25,20 +25,24 @@ import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.ReflectionUtils;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.decoration.EntityItemFrame;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.component.ItemLore;
import net.minecraft.world.level.saveddata.maps.MapDecorationType;
import net.minecraft.world.level.saveddata.maps.MapIcon;
import net.minecraft.world.level.saveddata.maps.MapId;
@@ -46,17 +50,22 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_20_R4.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R4.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R4.map.CraftMapCursor;
import org.bukkit.craftbukkit.v1_20_R4.map.CraftMapView;
import org.bukkit.craftbukkit.v1_20_R4.map.RenderData;
import org.bukkit.craftbukkit.v1_20_R4.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -75,11 +84,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_20_6 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_20_6() {
try {
nmsEntityByteDataWatcherField = ReflectionUtils.findDeclaredField(net.minecraft.world.entity.Entity.class, DataWatcherObject.class, "DATA_SHARED_FLAGS_ID", "ap");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = ReflectionUtils.findDeclaredField(PersistentIdCounts.class, Object2IntMap.class, "usedAuxIds", "b");
} catch (NoSuchFieldException e) {
@@ -199,6 +210,41 @@ public class V1_20_6 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.ap();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.c<?>> dataWatchers = Collections.singletonList(DataWatcher.c.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().c.sendPacket((Packet<?>) packet);
@@ -238,4 +284,25 @@ public class V1_20_6 extends NMSWrapper {
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.b, CustomData.a(tag)).a());
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
ItemLore itemLore = nmsItemStack.a(DataComponents.i, ItemLore.a);
List<IChatBaseComponent> loreLines = new ArrayList<>(itemLore.a());
loreLines.add(0, IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false)));
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.i, new ItemLore(loreLines)).a());
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK_OF_THE_SEA, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_21</artifactId>
@@ -25,20 +25,24 @@ import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.ReflectionUtils;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.decoration.EntityItemFrame;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.component.ItemLore;
import net.minecraft.world.level.saveddata.maps.MapDecorationType;
import net.minecraft.world.level.saveddata.maps.MapIcon;
import net.minecraft.world.level.saveddata.maps.MapId;
@@ -46,17 +50,22 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_21_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_21_R1.map.CraftMapCursor;
import org.bukkit.craftbukkit.v1_21_R1.map.CraftMapView;
import org.bukkit.craftbukkit.v1_21_R1.map.RenderData;
import org.bukkit.craftbukkit.v1_21_R1.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -75,11 +84,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_21 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_21() {
try {
nmsEntityByteDataWatcherField = ReflectionUtils.findDeclaredField(net.minecraft.world.entity.Entity.class, DataWatcherObject.class, "DATA_SHARED_FLAGS_ID", "ap");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = ReflectionUtils.findDeclaredField(PersistentIdCounts.class, Object2IntMap.class, "usedAuxIds", "b");
} catch (NoSuchFieldException e) {
@@ -199,6 +210,41 @@ public class V1_21 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.ar();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.c<?>> dataWatchers = Collections.singletonList(DataWatcher.c.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().c.sendPacket((Packet<?>) packet);
@@ -238,4 +284,25 @@ public class V1_21 extends NMSWrapper {
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.b, CustomData.a(tag)).a());
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
ItemLore itemLore = nmsItemStack.a(DataComponents.i, ItemLore.a);
List<IChatBaseComponent> loreLines = new ArrayList<>(itemLore.a());
loreLines.add(0, IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false)));
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.i, new ItemLore(loreLines)).a());
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK_OF_THE_SEA, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_21_1</artifactId>
@@ -25,20 +25,24 @@ import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.ReflectionUtils;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.decoration.EntityItemFrame;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.component.ItemLore;
import net.minecraft.world.level.saveddata.maps.MapDecorationType;
import net.minecraft.world.level.saveddata.maps.MapIcon;
import net.minecraft.world.level.saveddata.maps.MapId;
@@ -46,17 +50,22 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_21_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_21_R1.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_21_R1.map.CraftMapCursor;
import org.bukkit.craftbukkit.v1_21_R1.map.CraftMapView;
import org.bukkit.craftbukkit.v1_21_R1.map.RenderData;
import org.bukkit.craftbukkit.v1_21_R1.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -75,11 +84,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_21_1 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_21_1() {
try {
nmsEntityByteDataWatcherField = ReflectionUtils.findDeclaredField(net.minecraft.world.entity.Entity.class, DataWatcherObject.class, "DATA_SHARED_FLAGS_ID", "ap");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = ReflectionUtils.findDeclaredField(PersistentIdCounts.class, Object2IntMap.class, "usedAuxIds", "b");
} catch (NoSuchFieldException e) {
@@ -199,6 +210,41 @@ public class V1_21_1 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.ar();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.c<?>> dataWatchers = Collections.singletonList(DataWatcher.c.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().c.sendPacket((Packet<?>) packet);
@@ -238,4 +284,25 @@ public class V1_21_1 extends NMSWrapper {
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.b, CustomData.a(tag)).a());
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
ItemLore itemLore = nmsItemStack.a(DataComponents.i, ItemLore.a);
List<IChatBaseComponent> loreLines = new ArrayList<>(itemLore.a());
loreLines.add(0, IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false)));
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.i, new ItemLore(loreLines)).a());
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK_OF_THE_SEA, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_21_2</artifactId>
@@ -25,20 +25,24 @@ import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.ReflectionUtils;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.decoration.EntityItemFrame;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.component.ItemLore;
import net.minecraft.world.level.saveddata.maps.MapDecorationType;
import net.minecraft.world.level.saveddata.maps.MapIcon;
import net.minecraft.world.level.saveddata.maps.MapId;
@@ -46,17 +50,22 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_21_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_21_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_21_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_21_R2.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_21_R2.map.CraftMapCursor;
import org.bukkit.craftbukkit.v1_21_R2.map.CraftMapView;
import org.bukkit.craftbukkit.v1_21_R2.map.RenderData;
import org.bukkit.craftbukkit.v1_21_R2.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -75,11 +84,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_21_2 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_21_2() {
try {
nmsEntityByteDataWatcherField = ReflectionUtils.findDeclaredField(net.minecraft.world.entity.Entity.class, DataWatcherObject.class, "DATA_SHARED_FLAGS_ID", "am");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = ReflectionUtils.findDeclaredField(PersistentIdCounts.class, Object2IntMap.class, "usedAuxIds", "b");
} catch (NoSuchFieldException e) {
@@ -199,6 +210,41 @@ public class V1_21_2 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.au();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.c<?>> dataWatchers = Collections.singletonList(DataWatcher.c.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().f.sendPacket((Packet<?>) packet);
@@ -238,4 +284,25 @@ public class V1_21_2 extends NMSWrapper {
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.b, CustomData.a(tag)).a());
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
ItemLore itemLore = nmsItemStack.a(DataComponents.j, ItemLore.a);
List<IChatBaseComponent> loreLines = new ArrayList<>(itemLore.a());
loreLines.add(0, IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false)));
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.j, new ItemLore(loreLines)).a());
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK_OF_THE_SEA, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_21_3</artifactId>
@@ -25,20 +25,24 @@ import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.ReflectionUtils;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.decoration.EntityItemFrame;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.component.ItemLore;
import net.minecraft.world.level.saveddata.maps.MapDecorationType;
import net.minecraft.world.level.saveddata.maps.MapIcon;
import net.minecraft.world.level.saveddata.maps.MapId;
@@ -46,17 +50,22 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_21_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_21_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_21_R2.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_21_R2.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_21_R2.map.CraftMapCursor;
import org.bukkit.craftbukkit.v1_21_R2.map.CraftMapView;
import org.bukkit.craftbukkit.v1_21_R2.map.RenderData;
import org.bukkit.craftbukkit.v1_21_R2.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -75,11 +84,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_21_3 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_21_3() {
try {
nmsEntityByteDataWatcherField = ReflectionUtils.findDeclaredField(net.minecraft.world.entity.Entity.class, DataWatcherObject.class, "DATA_SHARED_FLAGS_ID", "am");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = ReflectionUtils.findDeclaredField(PersistentIdCounts.class, Object2IntMap.class, "usedAuxIds", "b");
} catch (NoSuchFieldException e) {
@@ -199,6 +210,40 @@ public class V1_21_3 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.au();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.c<?>> dataWatchers = Collections.singletonList(DataWatcher.c.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().f.sendPacket((Packet<?>) packet);
@@ -238,4 +283,25 @@ public class V1_21_3 extends NMSWrapper {
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.b, CustomData.a(tag)).a());
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
ItemLore itemLore = nmsItemStack.a(DataComponents.j, ItemLore.a);
List<IChatBaseComponent> loreLines = new ArrayList<>(itemLore.a());
loreLines.add(0, IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false)));
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.j, new ItemLore(loreLines)).a());
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK_OF_THE_SEA, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-V1_21_4</artifactId>
@@ -25,20 +25,24 @@ import com.loohp.imageframe.objectholders.MutablePair;
import com.loohp.imageframe.utils.ReflectionUtils;
import com.loohp.imageframe.utils.UUIDUtils;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.minecraft.EnumChatFormat;
import net.minecraft.core.Holder;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.chat.ChatModifier;
import net.minecraft.network.chat.IChatBaseComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata;
import net.minecraft.network.protocol.game.PacketPlayOutMap;
import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.network.syncher.DataWatcherObject;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.decoration.EntityItemFrame;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.component.ItemLore;
import net.minecraft.world.level.saveddata.maps.MapDecorationType;
import net.minecraft.world.level.saveddata.maps.MapIcon;
import net.minecraft.world.level.saveddata.maps.MapId;
@@ -46,17 +50,22 @@ import net.minecraft.world.level.saveddata.maps.PersistentIdCounts;
import net.minecraft.world.level.saveddata.maps.WorldMap;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_21_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_21_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_21_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_21_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_21_R3.map.CraftMapCursor;
import org.bukkit.craftbukkit.v1_21_R3.map.CraftMapView;
import org.bukkit.craftbukkit.v1_21_R3.map.RenderData;
import org.bukkit.craftbukkit.v1_21_R3.util.CraftChatMessage;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapView;
@@ -75,11 +84,13 @@ import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class V1_21_4 extends NMSWrapper {
private final Field nmsEntityByteDataWatcherField;
private final Field craftMapViewWorldMapField;
private final Field persistentIdCountsUsedAuxIdsField;
public V1_21_4() {
try {
nmsEntityByteDataWatcherField = ReflectionUtils.findDeclaredField(net.minecraft.world.entity.Entity.class, DataWatcherObject.class, "DATA_SHARED_FLAGS_ID", "am");
craftMapViewWorldMapField = CraftMapView.class.getDeclaredField("worldMap");
persistentIdCountsUsedAuxIdsField = ReflectionUtils.findDeclaredField(PersistentIdCounts.class, Object2IntMap.class, "usedAuxIds", "b");
} catch (NoSuchFieldException e) {
@@ -199,6 +210,41 @@ public class V1_21_4 extends NMSWrapper {
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
}
@SuppressWarnings("unchecked")
@Override
public Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing) {
try {
int entityId = entity.getEntityId();
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle();
nmsEntityByteDataWatcherField.setAccessible(true);
DataWatcher watcher = nmsEntity.au();
DataWatcherObject<Byte> byteField = (DataWatcherObject<Byte>) nmsEntityByteDataWatcherField.get(null);
byte value = watcher.a(byteField);
if (invisible != null) {
if (invisible) {
value = (byte) (value | 0x20);
} else {
value = (byte) (value & ~0x20);
}
}
if (glowing != null) {
if (glowing) {
value = (byte) (value | 0x40);
} else {
value = (byte) (value & ~0x40);
}
}
List<DataWatcher.c<?>> dataWatchers = Collections.singletonList(DataWatcher.c.a(byteField, value));
return new PacketPlayOutEntityMetadata(entityId, dataWatchers);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void sendPacket(Player player, Object packet) {
((CraftPlayer) player).getHandle().f.sendPacket((Packet<?>) packet);
@@ -238,4 +284,26 @@ public class V1_21_4 extends NMSWrapper {
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.b, CustomData.a(tag)).a());
return CraftItemStack.asCraftMirror(nmsItemStack);
}
@Override
public ItemStack withInvisibleItemFrameMeta(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
net.minecraft.world.item.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
ItemLore itemLore = nmsItemStack.a(DataComponents.j, ItemLore.a);
List<IChatBaseComponent> loreLines = new ArrayList<>(itemLore.a());
loreLines.add(0, IChatBaseComponent.c("effect.minecraft.invisibility").c(ChatModifier.a.c(EnumChatFormat.h).b(false)));
nmsItemStack.b(DataComponentPatch.a().a(DataComponents.j, new ItemLore(loreLines)).a());
ItemStack modified = CraftItemStack.asCraftMirror(nmsItemStack);
ItemMeta itemMeta = modified.getItemMeta();
if (itemMeta == null) {
return itemStack;
}
itemMeta.addEnchant(Enchantment.LUCK_OF_THE_SEA, 1, true);
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
modified.setItemMeta(itemMeta);
return modified;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<parent>
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
</parent>
<artifactId>ImageFrame-Abstraction</artifactId>
@@ -60,10 +60,14 @@ public abstract class NMSWrapper {
public abstract Object createItemFrameItemChangePacket(int entityId, ItemStack itemStack);
public abstract Object createEntityFlagsPacket(Entity entity, Boolean invisible, Boolean glowing);
public abstract void sendPacket(Player player, Object packet);
public abstract CombinedMapItemInfo getCombinedMapItemInfo(ItemStack itemStack);
public abstract ItemStack withCombinedMapItemInfo(ItemStack itemStack, CombinedMapItemInfo combinedMapItemInfo);
public abstract ItemStack withInvisibleItemFrameMeta(ItemStack itemStack);
}
+1 -1
View File
@@ -6,7 +6,7 @@
<groupId>com.loohp</groupId>
<artifactId>ImageFrame</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
<packaging>jar</packaging>
<name>ImageFrame</name>
@@ -42,7 +42,9 @@ import com.loohp.imageframe.updater.Updater;
import com.loohp.imageframe.utils.ChatColorUtils;
import com.loohp.imageframe.utils.HTTPRequestUtils;
import com.loohp.imageframe.utils.ImageMapUtils;
import com.loohp.imageframe.utils.MCVersion;
import com.loohp.imageframe.utils.MapUtils;
import com.loohp.imageframe.utils.MathUtils;
import com.loohp.imageframe.utils.PlayerUtils;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
@@ -71,6 +73,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.PrimitiveIterator;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -1278,6 +1281,49 @@ public class Commands implements CommandExecutor, TabCompleter {
sender.sendMessage(ImageFrame.messageNoPermission);
}
return true;
} else if (args[0].equalsIgnoreCase("giveinvisibleframe")) {
if (args.length > 1) {
if (sender.hasPermission("imageframe.giveinvisibleframe")) {
Player target;
if (args.length > 3) {
target = Bukkit.getPlayer(args[3]);
if (target == null) {
sender.sendMessage(ImageFrame.messagePlayerNotFound);
return true;
}
} else if (!(sender instanceof Player)) {
sender.sendMessage(ImageFrame.messageNoConsole);
return true;
} else {
target = (Player) sender;
}
String type = args[1];
int amount = 1;
try {
amount = args.length > 2 ? Integer.parseInt(args[2]) : 1;
} catch (NumberFormatException ignore) {
}
amount = Math.max(1, amount);
ItemStack itemStack;
if (type.equalsIgnoreCase("glowing") && ImageFrame.version.isNewerOrEqualTo(MCVersion.V1_17)) {
itemStack = new ItemStack(Material.valueOf("GLOW_ITEM_FRAME"));
} else {
itemStack = new ItemStack(Material.ITEM_FRAME);
}
ItemStack modified = ImageFrame.invisibleFrameManager.withInvisibleItemFrameData(itemStack);
for (PrimitiveIterator.OfInt itr = MathUtils.splitToChunksOf(amount, 64); itr.hasNext();) {
ItemStack finalStack = modified.clone();
finalStack.setAmount(itr.nextInt());
target.getWorld().dropItem(target.getEyeLocation(), finalStack).setVelocity(new Vector(0, 0, 0));
}
sender.sendMessage(ImageFrame.messageGivenInvisibleFrame.replace("{Amount}", String.valueOf(amount)).replace("{Player}", target.getName()));
} else {
sender.sendMessage(ImageFrame.messageNoPermission);
}
} else {
sender.sendMessage(ImageFrame.messageInvalidUsage);
}
return true;
}
sender.sendMessage(ChatColorUtils.translateAlternateColorCodes('&', Bukkit.spigot().getConfig().getString("messages.unknown-command")));
@@ -1350,6 +1396,9 @@ public class Commands implements CommandExecutor, TabCompleter {
if (sender.hasPermission("imageframe.preference")) {
tab.add("preference");
}
if (sender.hasPermission("imageframe.giveinvisibleframe")) {
tab.add("giveinvisibleframe");
}
return tab;
case 1:
if (sender.hasPermission("imageframe.reload")) {
@@ -1452,6 +1501,11 @@ public class Commands implements CommandExecutor, TabCompleter {
tab.add("preference");
}
}
if (sender.hasPermission("imageframe.giveinvisibleframe")) {
if ("giveinvisibleframe".startsWith(args[0].toLowerCase())) {
tab.add("giveinvisibleframe");
}
}
return tab;
case 2:
if (sender.hasPermission("imageframe.create")) {
@@ -1579,6 +1633,16 @@ public class Commands implements CommandExecutor, TabCompleter {
}
}
}
if (sender.hasPermission("imageframe.giveinvisibleframe")) {
if ("giveinvisibleframe".equalsIgnoreCase(args[0])) {
if ("regular".startsWith(args[1].toLowerCase())) {
tab.add("regular");
}
if (ImageFrame.version.isNewerOrEqualTo(MCVersion.V1_17) && "glowing".startsWith(args[1].toLowerCase())) {
tab.add("glowing");
}
}
}
return tab;
case 3:
if (sender.hasPermission("imageframe.create")) {
@@ -1680,6 +1744,11 @@ public class Commands implements CommandExecutor, TabCompleter {
}
}
}
if (sender.hasPermission("imageframe.giveinvisibleframe")) {
if ("giveinvisibleframe".equalsIgnoreCase(args[0])) {
tab.add("<amount>");
}
}
return tab;
case 4:
if (sender.hasPermission("imageframe.create")) {
@@ -1776,6 +1845,15 @@ public class Commands implements CommandExecutor, TabCompleter {
}
}
}
if (sender.hasPermission("imageframe.giveinvisibleframe")) {
if ("giveinvisibleframe".equalsIgnoreCase(args[0])) {
for (Player player : Bukkit.getOnlinePlayers()) {
if (player.getName().toLowerCase().startsWith(args[3].toLowerCase())) {
tab.add(player.getName());
}
}
}
}
return tab;
case 5:
if (sender.hasPermission("imageframe.create")) {
@@ -22,6 +22,7 @@ package com.loohp.imageframe;
import com.loohp.imageframe.config.Config;
import com.loohp.imageframe.debug.Debug;
import com.loohp.imageframe.invisibleframe.InvisibleFrameManager;
import com.loohp.imageframe.listeners.Events;
import com.loohp.imageframe.metrics.Charts;
import com.loohp.imageframe.metrics.Metrics;
@@ -135,6 +136,7 @@ public class ImageFrame extends JavaPlugin {
public static String messageMarkersNotRenderOnFrameWarning;
public static String messageMarkersLimitReached;
public static String messageInvalidOverlayMap;
public static String messageGivenInvisibleFrame;
public static SimpleDateFormat dateFormat;
@@ -162,6 +164,9 @@ public class ImageFrame extends JavaPlugin {
public static boolean handleAnimatedMapsOnMainThread;
public static boolean sendAnimatedMapsOnMainThread;
public static int invisibleFrameMaxConversionsPerSplash;
public static boolean invisibleFrameGlowEmptyFrames;
public static Set<CommandSender> processingMapCreation;
public static ImageMapManager imageMapManager;
@@ -171,6 +176,7 @@ public class ImageFrame extends JavaPlugin {
public static CombinedMapItemHandler combinedMapItemHandler;
public static AnimatedFakeMapManager animatedFakeMapManager;
public static RateLimitedPacketSendingManager rateLimitedPacketSendingManager;
public static InvisibleFrameManager invisibleFrameManager;
public static boolean isURLAllowed(String link) {
if (!restrictImageUrlEnabled) {
@@ -307,6 +313,7 @@ public class ImageFrame extends JavaPlugin {
animatedFakeMapManager = new AnimatedFakeMapManager();
rateLimitedPacketSendingManager = new RateLimitedPacketSendingManager();
Scheduler.runTaskAsynchronously(this, () -> imageMapManager.loadMaps());
invisibleFrameManager = new InvisibleFrameManager();
getServer().getConsoleSender().sendMessage(ChatColor.GREEN + "[ImageFrame] ImageFrame has been Enabled!");
}
@@ -391,6 +398,7 @@ public class ImageFrame extends JavaPlugin {
messageMarkersNotRenderOnFrameWarning = ChatColorUtils.translateAlternateColorCodes('&', config.getConfiguration().getString("Messages.Markers.NotRenderOnFrameWarning"));
messageMarkersLimitReached = ChatColorUtils.translateAlternateColorCodes('&', config.getConfiguration().getString("Messages.Markers.LimitReached"));
messageInvalidOverlayMap = ChatColorUtils.translateAlternateColorCodes('&', config.getConfiguration().getString("Messages.InvalidOverlayMap"));
messageGivenInvisibleFrame = ChatColorUtils.translateAlternateColorCodes('&', config.getConfiguration().getString("Messages.GivenInvisibleFrame"));
dateFormat = new SimpleDateFormat(config.getConfiguration().getString("Messages.DateFormat"));
@@ -445,6 +453,9 @@ public class ImageFrame extends JavaPlugin {
handleAnimatedMapsOnMainThread = config.getConfiguration().getBoolean("Settings.HandleAnimatedMapsOnMainThread");
sendAnimatedMapsOnMainThread = config.getConfiguration().getBoolean("Settings.SendAnimatedMapsOnMainThread");
invisibleFrameMaxConversionsPerSplash = config.getConfiguration().getInt("InvisibleFrame.MaxConversionsPerSplash");
invisibleFrameGlowEmptyFrames = config.getConfiguration().getBoolean("InvisibleFrame.GlowEmptyFrames");
if (updaterTask != null) {
updaterTask.cancel();
}
@@ -0,0 +1,392 @@
/*
* This file is part of ImageFrame.
*
* Copyright (C) 2025. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2025. Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.loohp.imageframe.invisibleframe;
import com.loohp.imageframe.ImageFrame;
import com.loohp.imageframe.nms.NMS;
import com.loohp.imageframe.objectholders.Scheduler;
import com.loohp.imageframe.utils.MCVersion;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.AreaEffectCloudApplyEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.entity.LingeringPotionSplashEvent;
import org.bukkit.event.entity.PotionSplashEvent;
import org.bukkit.event.hanging.HangingBreakEvent;
import org.bukkit.event.hanging.HangingPlaceEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.CraftingRecipe;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
import org.bukkit.util.BoundingBox;
import org.bukkit.util.Vector;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
public class InvisibleFrameManager implements Listener {
public static final NamespacedKey INVISIBLE_GLOW_ITEM_FRAME_CRAFTING_KEY = new NamespacedKey(ImageFrame.plugin, "invisible_glow_item_frame");
public static final NamespacedKey INVISIBLE_KEY = new NamespacedKey(ImageFrame.plugin, "invisible");
private final Map<UUID, Location> removedInvisibleFrames;
private final Set<UUID> knownAreaEffectClouds;
public InvisibleFrameManager() {
this.removedInvisibleFrames = new ConcurrentHashMap<>();
this.knownAreaEffectClouds = ConcurrentHashMap.newKeySet();
Bukkit.getPluginManager().registerEvents(this, ImageFrame.plugin);
if (ImageFrame.version.isNewerOrEqualTo(MCVersion.V1_17)) {
addRecipes();
}
}
private void addRecipes() {
ItemStack result = new ItemStack(Material.valueOf("GLOW_ITEM_FRAME"));
CraftingRecipe vanillaRecipe = (CraftingRecipe) Bukkit.getRecipesFor(result).stream()
.filter(r -> r instanceof CraftingRecipe)
.findFirst()
.orElse(null);
ShapelessRecipe recipe = new ShapelessRecipe(INVISIBLE_GLOW_ITEM_FRAME_CRAFTING_KEY, withInvisibleItemFrameData(result))
.addIngredient(Material.valueOf("GLOW_INK_SAC"))
.addIngredient(new RecipeChoice.ExactChoice(withInvisibleItemFrameData(new ItemStack(Material.ITEM_FRAME))));
if (vanillaRecipe != null) {
recipe.setCategory(vanillaRecipe.getCategory());
recipe.setGroup(vanillaRecipe.getGroup());
}
Bukkit.addRecipe(recipe);
Bukkit.updateRecipes();
}
public ItemStack withInvisibleItemFrameData(ItemStack itemStack) {
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
return itemStack;
}
if (isInvisibleItemFrame(itemStack)) {
return itemStack;
}
ItemStack modified = NMS.getInstance().withInvisibleItemFrameMeta(itemStack);
ItemMeta meta = modified.getItemMeta();
if (meta == null) {
return itemStack;
}
meta.getPersistentDataContainer().set(INVISIBLE_KEY, PersistentDataType.BYTE, (byte) 1);
modified.setItemMeta(meta);
return modified;
}
public boolean isInvisibleItemFrame(ItemStack itemStack) {
if (itemStack == null || !itemStack.hasItemMeta()) {
return false;
}
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return false;
}
return meta.getPersistentDataContainer().getOrDefault(INVISIBLE_KEY, PersistentDataType.BYTE, (byte) 0) > 0;
}
public void setInvisibleItemFrameData(Entity entity) {
if (entity instanceof ItemFrame) {
entity.getPersistentDataContainer().set(INVISIBLE_KEY, PersistentDataType.BYTE, (byte) 1);
}
}
public boolean isInvisibleItemFrame(Entity entity) {
return entity instanceof ItemFrame && entity.getPersistentDataContainer().getOrDefault(INVISIBLE_KEY, PersistentDataType.BYTE, (byte) 0) > 0;
}
@SuppressWarnings("ConstantValue")
public void updateInvisibleItemFrame(ItemFrame itemFrame) {
if (!itemFrame.isValid()) {
return;
}
ItemStack itemStack = itemFrame.getItem();
if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
if (ImageFrame.invisibleFrameGlowEmptyFrames) {
itemFrame.setGlowing(true);
}
itemFrame.setInvisible(false);
} else {
itemFrame.setGlowing(false);
itemFrame.setInvisible(true);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlace(HangingPlaceEvent event) {
if (!isInvisibleItemFrame(event.getItemStack())) {
return;
}
Entity entity = event.getEntity();
if (!(entity instanceof ItemFrame)) {
return;
}
Location location = entity.getLocation();
setInvisibleItemFrameData(entity);
Scheduler.runTaskLater(ImageFrame.plugin, () -> updateInvisibleItemFrame((ItemFrame) entity), 1, location);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBreak(HangingBreakEvent event) {
Entity entity = event.getEntity();
if (!isInvisibleItemFrame(entity)) {
return;
}
UUID uuid = entity.getUniqueId();
Location location = entity.getLocation();
removedInvisibleFrames.put(uuid, entity.getLocation());
Scheduler.runTaskLater(ImageFrame.plugin, () -> removedInvisibleFrames.remove(uuid), 1, location);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onItemSpawn(ItemSpawnEvent event) {
Item item = event.getEntity();
ItemStack itemStack = item.getItemStack();
String type = itemStack.getType().name();
if (!type.equals("ITEM_FRAME") && !type.equals("GLOW_ITEM_FRAME")) {
return;
}
if (isInvisibleItemFrame(itemStack)) {
return;
}
for (Iterator<Map.Entry<UUID, Location>> itr = removedInvisibleFrames.entrySet().iterator(); itr.hasNext();) {
Map.Entry<UUID, Location> entry = itr.next();
Location location = entry.getValue();
if (location.getWorld().equals(item.getWorld())) {
BoundingBox boundingBox = BoundingBox.of(location, 1, 1, 1);
if (boundingBox.contains(item.getLocation().toVector())) {
ItemStack modified = withInvisibleItemFrameData(itemStack);
item.setItemStack(modified);
itr.remove();
break;
}
}
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlaceItem(PlayerInteractEntityEvent event) {
Entity entity = event.getRightClicked();
if (!(entity instanceof ItemFrame)) {
return;
}
Location location = entity.getLocation();
Scheduler.runTaskLater(ImageFrame.plugin, () -> updateInvisibleItemFrame((ItemFrame) entity), 1, location);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onRemoveItem(EntityDamageByEntityEvent event) {
Entity entity = event.getEntity();
if (!(entity instanceof ItemFrame)) {
return;
}
Location location = entity.getLocation();
Scheduler.runTaskLater(ImageFrame.plugin, () -> updateInvisibleItemFrame((ItemFrame) entity), 1, location);
}
public ItemStack splitItemStacks(ItemStack itemStack, int maxSize) {
if (maxSize < 0) {
return null;
}
int amount = itemStack.getAmount();
if (amount <= maxSize) {
return null;
}
itemStack.setAmount(maxSize);
ItemStack splitStack = itemStack.clone();
splitStack.setAmount(amount - maxSize);
return splitStack;
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPotionSplash(PotionSplashEvent event) {
ThrownPotion thrownPotion = event.getEntity();
if (thrownPotion.getEffects().stream().noneMatch(e -> e.getType().equals(PotionEffectType.INVISIBILITY))) {
return;
}
int conversionsRemaining = ImageFrame.invisibleFrameMaxConversionsPerSplash;
BoundingBox boundingBox = thrownPotion.getBoundingBox().expand(4.0, 2.0, 4.0);
for (Entity entity : thrownPotion.getWorld().getNearbyEntities(boundingBox)) {
if (conversionsRemaining == 0) {
break;
}
if (!(entity instanceof Item)) {
continue;
}
Item item = (Item) entity;
ItemStack itemStack = item.getItemStack();
String type = itemStack.getType().name();
if (!type.equals("ITEM_FRAME") && !type.equals("GLOW_ITEM_FRAME")) {
continue;
}
if (isInvisibleItemFrame(itemStack)) {
continue;
}
if (entity.getLocation().distanceSquared(thrownPotion.getLocation()) < 16.0D) {
ItemStack splitStack = splitItemStacks(itemStack, conversionsRemaining);
Location location = item.getLocation();
if (itemStack.getAmount() > 0) {
item.setItemStack(withInvisibleItemFrameData(itemStack));
item.getWorld().playSound(item.getLocation(), Sound.BLOCK_ENCHANTMENT_TABLE_USE, SoundCategory.BLOCKS, 1F, 1F);
} else {
item.remove();
}
Vector velocity = null;
if (splitStack != null) {
Item splitItem = thrownPotion.getWorld().dropItem(location, splitStack);
velocity = splitItem.getVelocity();
splitItem.setVelocity(new Vector(0, 0, 0));
}
if (velocity != null) {
item.setVelocity(velocity);
}
if (conversionsRemaining >= 0) {
conversionsRemaining = Math.max(0, conversionsRemaining - itemStack.getAmount());
}
}
}
}
private boolean hasInvisibilityEffect(AreaEffectCloud areaEffectCloud) {
PotionType baseType = areaEffectCloud.getBasePotionType();
if (baseType != null) {
if (baseType.getPotionEffects().stream().anyMatch(e -> e.getType().equals(PotionEffectType.INVISIBILITY))) {
return true;
}
}
return areaEffectCloud.hasCustomEffect(PotionEffectType.INVISIBILITY);
}
private void handleAreaEffectCloud(AreaEffectCloud areaEffectCloud) {
UUID uuid = areaEffectCloud.getUniqueId();
if (!knownAreaEffectClouds.add(uuid)) {
return;
}
AtomicReference<Runnable> runnableReference = new AtomicReference<>(null);
AtomicReference<Scheduler.ScheduledTask> taskReference = new AtomicReference<>(null);
runnableReference.set(new Runnable() {
int conversionsRemaining = ImageFrame.invisibleFrameMaxConversionsPerSplash;
boolean firstTick = true;
@Override
public void run() {
if (firstTick) {
firstTick = false;
} else if (!areaEffectCloud.isValid()) {
Scheduler.ScheduledTask task = taskReference.get();
if (task != null) {
task.cancel();
}
knownAreaEffectClouds.remove(uuid);
return;
}
taskReference.set(Scheduler.runTaskLater(ImageFrame.plugin, runnableReference.get(), 1, areaEffectCloud.getLocation()));
if (!hasInvisibilityEffect(areaEffectCloud)) {
return;
}
if (areaEffectCloud.getTicksLived() % 5 != 0) {
return;
}
BoundingBox boundingBox = areaEffectCloud.getBoundingBox();
for (Entity entity : areaEffectCloud.getWorld().getNearbyEntities(boundingBox)) {
if (conversionsRemaining == 0) {
break;
}
if (!(entity instanceof Item)) {
continue;
}
Item item = (Item) entity;
ItemStack itemStack = item.getItemStack();
String type = itemStack.getType().name();
if (!type.equals("ITEM_FRAME") && !type.equals("GLOW_ITEM_FRAME")) {
continue;
}
if (isInvisibleItemFrame(itemStack)) {
continue;
}
ItemStack splitStack = splitItemStacks(itemStack, conversionsRemaining);
Location location = item.getLocation();
if (itemStack.getAmount() > 0) {
item.setItemStack(withInvisibleItemFrameData(itemStack));
item.getWorld().playSound(item.getLocation(), Sound.BLOCK_ENCHANTMENT_TABLE_USE, SoundCategory.BLOCKS, 1F, 1F);
} else {
item.remove();
}
Vector velocity = null;
if (splitStack != null) {
Item splitItem = areaEffectCloud.getWorld().dropItem(location, splitStack);
velocity = splitItem.getVelocity();
splitItem.setVelocity(new Vector(0, 0, 0));
}
if (velocity != null) {
item.setVelocity(velocity);
}
if (conversionsRemaining >= 0) {
conversionsRemaining = Math.max(0, conversionsRemaining - itemStack.getAmount());
}
}
}
});
runnableReference.get().run();
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPotionLinger(EntitySpawnEvent event) {
Entity entity = event.getEntity();
if (entity instanceof AreaEffectCloud) {
handleAreaEffectCloud((AreaEffectCloud) entity);
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPotionLinger(LingeringPotionSplashEvent event) {
handleAreaEffectCloud(event.getAreaEffectCloud());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onAreaEffectCloudApply(AreaEffectCloudApplyEvent event) {
handleAreaEffectCloud(event.getEntity());
}
}
@@ -0,0 +1,45 @@
/*
* This file is part of ImageFrame.
*
* Copyright (C) 2025. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2025. Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.loohp.imageframe.utils;
import java.util.PrimitiveIterator;
public class MathUtils {
public static PrimitiveIterator.OfInt splitToChunksOf(int value, int chunkSize) {
return new PrimitiveIterator.OfInt() {
private int currentValue = value;
@Override
public boolean hasNext() {
return currentValue > 0;
}
@Override
public int nextInt() {
int nextInt = Math.min(currentValue, chunkSize);
currentValue -= nextInt;
return nextInt;
}
};
}
}
+13 -1
View File
@@ -35,12 +35,13 @@ Messages:
NotEnoughMaps: "&cYou do not have {Amount} maps!"
Oversize: "&cThat is too big! Max size for a map is {MaxSize}"
URLRestricted: "&cThat URL is restricted and cannot be used to create image maps."
PlayerCreationLimitReached: "&cYou can only create <Limit> maps at once! Delete some to create new ones"
PlayerCreationLimitReached: "&cYou can only create {Limit} maps at once! Delete some to create new ones"
DuplicateMapName: "&cYou've already created an image map with that name!"
MapLookup: "&bList of image maps by {CreatorName} ({CreatorUUID}):"
ItemFrameOccupied: "&cFailed to place or remove some maps on selected ItemFrame, they are either destroyed, replaced, occupied or protected."
NotEnoughSpace: "&cUnable to place Combined ImageMap as there is not enough room."
InvalidImageMap: "&cThis image map had likely already been deleted."
GivenInvisibleFrame: "&aGiven {Amount} invisible item frames to {Player}."
AccessPermission:
Updated: "&aUpdated access for {PlayerName} ({PlayerUUID}), they now have {Permission} permission."
Types:
@@ -138,6 +139,17 @@ Settings:
HandleAnimatedMapsOnMainThread: false
SendAnimatedMapsOnMainThread: false
#ImageFrame's built in survival friendly way of making invisible item frames
InvisibleFrame:
#Survival friendly way to get invisible item frames by splashing dropped items with invisibility potions
#Set to -1 for unlimited
#Set to 0 to disable
MaxConversionsPerSplash: 8
#Should empty invisible item frames glow
#Existing frames are not updated until they are interacted with
GlowEmptyFrames: true
Hooks:
ViaVersion:
#Enable this if your players below 1.13 is having network issues
+3
View File
@@ -89,6 +89,9 @@ permissions:
imageframe.preference.others:
default: op
description: Allow players to update other players' player preferences
imageframe.giveinvisibleframe:
default: op
description: Allow players to give invisible item frames
imageframe.update:
default: op
description: Allows you receive update messages
+1 -1
View File
@@ -6,7 +6,7 @@
<groupId>com.loohp</groupId>
<artifactId>ImageFrame-Parent</artifactId>
<version>1.7.14.0</version>
<version>1.7.14.1</version>
<packaging>pom</packaging>
<properties>