Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ allprojects {

maven("https://repo.papermc.io/repository/maven-public/")
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
maven("https://libraries.minecraft.net/")
}

tasks.compileJava {
Expand Down
1 change: 1 addition & 0 deletions core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {
dependencies {
compileOnly("io.papermc.paper:paper-api:26.1.2.build.+")
compileOnly("me.clip:placeholderapi:2.12.2")
compileOnly("com.mojang:authlib:1.5.25")
}

java {
Expand Down
103 changes: 103 additions & 0 deletions core/src/main/java/dev/geco/gholo/object/simple/SimpleItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package dev.geco.gholo.object.simple;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import dev.geco.gholo.GHoloMain;
import dev.geco.gholo.service.VersionService;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.profile.PlayerProfile;
import org.bukkit.profile.PlayerTextures;

import java.lang.reflect.Field;
import java.net.URL;
import java.util.Base64;
import java.util.UUID;

/**
* skull:self -> shows the skull of the player who is viewing the hologram
* skull:eyJ0ZXh0dXJlcyI6... -> shows the skull with the given base64 texture
* player_skull:nrvkg -> shows the skull of the given player
* itemstack:diamond_sword -> shows the given item
*/
public class SimpleItem {

private final static VersionService version = GHoloMain.getInstance().getVersionService();

@SuppressWarnings("deprecation")
public static ItemStack getItem(String content, Player player) {
ItemStack itemStack = null;
String[] contentSplit = content.split(":", 2);
if (contentSplit.length < 2) {
return null;
}

String type = contentSplit[0];
String value = contentSplit[1].trim();
switch (type.toLowerCase()) {
case "itemstack" -> {
Material material = Material.getMaterial(value.toUpperCase());
if (material != null) {
itemStack = new ItemStack(material);
}
}
case "skull" -> {
itemStack = new ItemStack(Material.PLAYER_HEAD);
SkullMeta skullMeta = (SkullMeta) itemStack.getItemMeta();
if (value.equalsIgnoreCase("self")) {
skullMeta.setOwningPlayer(player);
} else {
if (version.isNewerOrVersion(1, 20, 1)) {
PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), GHoloMain.NAME);
PlayerTextures textures = profile.getTextures();
URL url;
try {
String decoded = new String(Base64.getDecoder().decode(value));
String decodedFormatted = decoded.replaceAll("\\s", "");
JsonObject jsonObject = new Gson().fromJson(decodedFormatted, JsonObject.class);
String urlText = jsonObject.get("textures").getAsJsonObject().get("SKIN").getAsJsonObject().get("url").getAsString();
url = new URL(urlText);
} catch (Exception error) {
return null;
}
textures.setSkin(url);
profile.setTextures(textures);
skullMeta.setOwnerProfile(profile);
} else {
GameProfile profile = new GameProfile(UUID.randomUUID(), "");
profile.getProperties().put("textures", new Property("textures", value));

try {
Field profileField = skullMeta.getClass().getDeclaredField("profile");
profileField.setAccessible(true);
profileField.set(skullMeta, profile);
} catch (IllegalArgumentException | NoSuchFieldException | SecurityException |
IllegalAccessException error) {
return null;
}
}
}
itemStack.setItemMeta(skullMeta);
}
case "player_skull" -> {
itemStack = new ItemStack(Material.PLAYER_HEAD);
SkullMeta skullMeta = (SkullMeta) itemStack.getItemMeta();
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(value);
if (offlinePlayer.hasPlayedBefore()) {
skullMeta.setOwningPlayer(offlinePlayer);
} else {
skullMeta.setOwner(value);
}

itemStack.setItemMeta(skullMeta);
}
}
return itemStack;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private void updateContent(String content, Player player) {
if(itemContent == null) itemContent = new GHoloRowItemContent(holoRow, gHoloMain);
yield itemContent;
}
case "itemstack" -> {
case "itemstack", "skull", "player_skull" -> {
if(itemStackContent == null) itemStackContent = new GHoloRowItemStackContent(holoRow, gHoloMain);
yield itemStackContent;
}
Expand All @@ -82,9 +82,9 @@ private void updateContent(String content, Player player) {
IGHoloRowContentType currentContentType = currentContentTypes.get(playerUuid);
if(currentContentType != contentType) {
if(currentContentType != null) currentContentType.unload(player);
contentType.load(player, contentType instanceof GHoloRowTextContent ? content : contentSplit[1], true);
contentType.load(player, contentType instanceof GHoloRowTextContent || contentType instanceof GHoloRowItemStackContent ? content : contentSplit[1], true);
currentContentTypes.put(playerUuid, contentType);
} else contentType.load(player, contentType instanceof GHoloRowTextContent ? content : contentSplit[1], false);
} else contentType.load(player, contentType instanceof GHoloRowTextContent || contentType instanceof GHoloRowItemStackContent ? content : contentSplit[1], false);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,20 @@
import dev.geco.gholo.object.holo.IGHoloRowContentType;
import dev.geco.gholo.object.simple.SimpleLocation;
import dev.geco.gholo.object.simple.SimpleVector;
import net.minecraft.core.registries.BuiltInRegistries;
import dev.geco.gholo.object.simple.SimpleItem;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -60,22 +59,19 @@ public GHoloRowItemStackContent(GHoloRow holoRow, GHoloMain gHoloMain) {
public void load(Player player, String content, boolean create) {
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
if(create) serverPlayer.connection.send(new ClientboundAddEntityPacket(getId(), uuid, getX(), getY(), getZ(), getXRot(), getYRot(), getType(), 0, getDeltaMovement(), getYRot()));
serverPlayer.connection.send(getDataPacket(content));
serverPlayer.connection.send(getDataPacket(content, player));
}

private ClientboundSetEntityDataPacket getDataPacket(String content) {
private ClientboundSetEntityDataPacket getDataPacket(String content, Player player) {
List<SynchedEntityData.DataValue<?>> data = getEntityData().getNonDefaultValues();
if(data == null) data = new ArrayList<>();
else data.removeIf(dataValue -> dataValue.id() == holoItemData.getId());
List<SynchedEntityData.DataValue<?>> defaultResetData = getEntityData().packDirty();
if(defaultResetData != null) data.addAll(defaultResetData);
if(content != null) {
ResourceLocation resourceLocation = ResourceLocation.tryParse(content.toLowerCase());
if(resourceLocation != null) {
try {
Item itemData = BuiltInRegistries.ITEM.get(resourceLocation);
data.add(new SynchedEntityData.DataValue<>(holoItemData.getId(), holoItemData.getSerializer(), itemData.getDefaultInstance()));
} catch(Throwable ignored) { }
org.bukkit.inventory.ItemStack item = SimpleItem.getItem(content, player);
if(item != null) {
data.add(new SynchedEntityData.DataValue<>(holoItemData.getId(), holoItemData.getSerializer(), CraftItemStack.asNMSCopy(item)));
}
}
return new ClientboundSetEntityDataPacket(getId(), data);
Expand Down Expand Up @@ -118,7 +114,7 @@ private void finishUpdate() {
for(Player player : holoRow.getHolo().getRawLocation().getWorld().getPlayers()) {
if(permission != null && !gHoloMain.getPermissionService().hasPermission(player, permission)) continue;
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
serverPlayer.connection.send(getDataPacket(null));
serverPlayer.connection.send(getDataPacket(null, player));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private void updateContent(String content, Player player) {
if(itemContent == null) itemContent = new GHoloRowItemContent(holoRow, gHoloMain);
yield itemContent;
}
case "itemstack" -> {
case "itemstack", "skull", "player_skull" -> {
if(itemStackContent == null) itemStackContent = new GHoloRowItemStackContent(holoRow, gHoloMain);
yield itemStackContent;
}
Expand All @@ -82,9 +82,9 @@ private void updateContent(String content, Player player) {
IGHoloRowContentType currentContentType = currentContentTypes.get(playerUuid);
if(currentContentType != contentType) {
if(currentContentType != null) currentContentType.unload(player);
contentType.load(player, contentType instanceof GHoloRowTextContent ? content : contentSplit[1], true);
contentType.load(player, contentType instanceof GHoloRowTextContent || contentType instanceof GHoloRowItemStackContent ? content : contentSplit[1], true);
currentContentTypes.put(playerUuid, contentType);
} else contentType.load(player, contentType instanceof GHoloRowTextContent ? content : contentSplit[1], false);
} else contentType.load(player, contentType instanceof GHoloRowTextContent || contentType instanceof GHoloRowItemStackContent ? content : contentSplit[1], false);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,20 @@
import dev.geco.gholo.object.holo.IGHoloRowContentType;
import dev.geco.gholo.object.simple.SimpleLocation;
import dev.geco.gholo.object.simple.SimpleVector;
import net.minecraft.core.registries.BuiltInRegistries;
import dev.geco.gholo.object.simple.SimpleItem;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -60,22 +59,19 @@ public GHoloRowItemStackContent(GHoloRow holoRow, GHoloMain gHoloMain) {
public void load(Player player, String content, boolean create) {
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
if(create) serverPlayer.connection.send(new ClientboundAddEntityPacket(getId(), uuid, getX(), getY(), getZ(), getXRot(), getYRot(), getType(), 0, getDeltaMovement(), getYRot()));
serverPlayer.connection.send(getDataPacket(content));
serverPlayer.connection.send(getDataPacket(content, player));
}

private ClientboundSetEntityDataPacket getDataPacket(String content) {
private ClientboundSetEntityDataPacket getDataPacket(String content, Player player) {
List<SynchedEntityData.DataValue<?>> data = getEntityData().getNonDefaultValues();
if(data == null) data = new ArrayList<>();
else data.removeIf(dataValue -> dataValue.id() == holoItemData.getId());
List<SynchedEntityData.DataValue<?>> defaultResetData = getEntityData().packDirty();
if(defaultResetData != null) data.addAll(defaultResetData);
if(content != null) {
ResourceLocation resourceLocation = ResourceLocation.tryParse(content.toLowerCase());
if(resourceLocation != null) {
try {
Item itemData = BuiltInRegistries.ITEM.get(resourceLocation);
data.add(new SynchedEntityData.DataValue<>(holoItemData.getId(), holoItemData.getSerializer(), itemData.getDefaultInstance()));
} catch(Throwable ignored) { }
org.bukkit.inventory.ItemStack item = SimpleItem.getItem(content, player);
if(item != null) {
data.add(new SynchedEntityData.DataValue<>(holoItemData.getId(), holoItemData.getSerializer(), CraftItemStack.asNMSCopy(item)));
}
}
return new ClientboundSetEntityDataPacket(getId(), data);
Expand Down Expand Up @@ -118,7 +114,7 @@ private void finishUpdate() {
for(Player player : holoRow.getHolo().getRawLocation().getWorld().getPlayers()) {
if(permission != null && !gHoloMain.getPermissionService().hasPermission(player, permission)) continue;
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
serverPlayer.connection.send(getDataPacket(null));
serverPlayer.connection.send(getDataPacket(null, player));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private void updateContent(String content, Player player) {
if(itemContent == null) itemContent = new GHoloRowItemContent(holoRow, gHoloMain);
yield itemContent;
}
case "itemstack" -> {
case "itemstack", "skull", "player_skull" -> {
if(itemStackContent == null) itemStackContent = new GHoloRowItemStackContent(holoRow, gHoloMain);
yield itemStackContent;
}
Expand All @@ -82,9 +82,9 @@ private void updateContent(String content, Player player) {
IGHoloRowContentType currentContentType = currentContentTypes.get(playerUuid);
if(currentContentType != contentType) {
if(currentContentType != null) currentContentType.unload(player);
contentType.load(player, contentType instanceof GHoloRowTextContent ? content : contentSplit[1], true);
contentType.load(player, contentType instanceof GHoloRowTextContent || contentType instanceof GHoloRowItemStackContent ? content : contentSplit[1], true);
currentContentTypes.put(playerUuid, contentType);
} else contentType.load(player, contentType instanceof GHoloRowTextContent ? content : contentSplit[1], false);
} else contentType.load(player, contentType instanceof GHoloRowTextContent || contentType instanceof GHoloRowItemStackContent ? content : contentSplit[1], false);
}

@Override
Expand Down
Loading