Giter Club home page Giter Club logo

holoeasy's Introduction

Note

New update: 3.4.0: BlockLines & Animations. Scroll down for more information.

HoloEasy is a simple, modern and high-performant Java and Kotlin Minecraft Hologram library for 1.8-1.20.4 servers.

Lightweight replacement for Holographic Display. HoloEasy only uses packets instead of registering the entity in the actual Minecraft server.

holoeasy video

Quickstart

Requirements

  • ProtocolLib installed on your server

Add dependency

Maven

<dependency>
    <groupId>com.github.unldenis.holoeasy</groupId>
    <artifactId>holoeasy-core</artifactId>
    <version>3.4.0</version>
</dependency>

<!-- For java projects include also the kotlin stdlib -->
<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib</artifactId>
    <version>1.9.21</version>
</dependency>

Gradle

implementation("com.github.unldenis.holoeasy:holoeasy-core:3.4.0")

// For java projects include also the kotlin stdlib
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.21")

Make sure you include the repository as well.

Start programming

Java

import static org.holoeasy.builder.HologramBuilder.*;

// you can use a Pool or a org.bukkit.Plugin
IHologramPool pool = HoloEasy.startInteractivePool(plugin, 60, 0.5f, 5f);

public void addHologram(Location location) {
    pool.registerHolograms(() -> {
        
        hologram(location, () -> {
            textline("Hello");
            textline("Score {} - {}", 0, 1);
            clickable("Click me").onClick(p -> {
                p.sendTitle(ChatColor.AQUA + "Hi", ChatColor.BOLD + "by HoloEasy",
                        20, 20, 20);
            });
            item(new ItemStack(Material.ENCHANTED_GOLDEN_APPLE));
        });
        // other holograms...
    });

}

Kotlin

import org.holoeasy.builder.HologramBuilder.*

// you can use a Pool or a org.bukkit.Plugin 
val pool = startInteractivePool(plugin, 60.0, 0.5f, 5f)

fun addHologram(location: Location) {
    pool.registerHolograms {

        hologram(location) {
            textline("Hello")
            textline("Score {} - {}", 0, 1)
            clickable("Click me").onClick {
                it.sendTitle(ChatColor.AQUA + "Hi", ChatColor.BOLD + "by HoloEasy",
                    20, 20, 20)
            }
            item(ItemStack(Material.ENCHANTED_GOLDEN_APPLE))
        }
        // other holograms...
    }

}

Reactive Holograms

From 3.1.0 version, the parameters of text lines and item lines can also be reactive. This means that you can update the line by simply calling the 'set' method to these.

holoeasy state video

Warning

Mutable states have no player information at this time. If you need to create a hologram for a specific player, it is recommended that you do not add it to a Pool.

Java

registerHolograms(plugin, () -> {
    var clickCount = mutableStateOf(0); // can be any type
    
    var holo = hologram(location, () -> {
        textline("{}!", "Static");
        textline("Count: {}", clickCount);
        clickable("Click me").onClick(player -> clickCount.update(it -> it + 1));
    });
    
    // It hasn't been added to a pool, so it's up to us to make it visible and hide it from players. It's better to use a pool because it's automatic and performs asynchronous operations.
    holo.show(player);
});

Kotlin

plugin.registerHolograms {
    val clickCount = mutableStateOf(0) // can be any type

    val holo = hologram(location) {
        textline("{}!", "Static")
        textline("Count: {}", clickCount)
        clickable("Click me").onClick { clickCount.update { it + 1 } }
    }

    // It hasn't been added to a pool, so it's up to us to make it visible and hide it from players. It's better to use a pool because it's automatic and performs asynchronous operations.
    holo.show(player)
}

BlockLine & Animations

From 3.4.0 version, library added support for:

  • BlockLine: Instead of a dropping item it spawns an hologram with the block as helmet.
  • Animations: You can apply animations to hologram lines.

holoeasy state video

Java

Iterator<ItemStack> blocks = Arrays.asList(
    new ItemStack(Material.DIRT),
    new ItemStack(Material.IRON_BLOCK),
    new ItemStack(Material.GOLD_BLOCK),
    new ItemStack(Material.DIAMOND_BLOCK)
).iterator();
                    
pool.registerHolograms(() -> {

    Hologram holo = hologram(location, () -> {
        MutableState<ItemStack> currBlock = mutableStateOf(blocks.next()); // can be any type
    
        textline("Hello");
        clickable("Update me").onClick(p -> currBlock.set(blocks.next()));
        block(currBlock);
    });
                
    holo.lineAt(2).setAnimation(Animations.CIRCLE);
});

Kotlin

val blocks = arrayOf(
    ItemStack(Material.DIRT),
    ItemStack(Material.IRON_BLOCK),
    ItemStack(Material.GOLD_BLOCK),
    ItemStack(Material.DIAMOND_BLOCK),
).iterator()

pool.registerHolograms {

    val holo = hologram(location) {
        val currBlock = mutableStateOf(blocks.next()) 

        textline("Hello")
        clickable("Update me").onClick { currBlock.set(blocks.next()) }
        block(currBlock)
    }
    holo[2].setAnimation(Animations.CIRCLE)
}

Ex (Hologram-Lib)

Are you using a version older than 3.0.0? You can find the documentation here.

Stargazers over time

Stargazers over time

holoeasy's People

Contributors

15ibans avatar alex1607 avatar badaccuracyid avatar eternalhittman avatar its-c10 avatar nicholasveronico avatar sasuked avatar thomaswega avatar unldenis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

holoeasy's Issues

Find alternative to fastutil

FastUtil is taking 25MB+ of space meaning any plugins using this library will not be able to be uploaded to SpigotMC due to their restriction of max 5MB per plugin.

Exception with the latest ProtocolLib version #608

Hi,

Having issue with the latest ProtocolLib and papermc latest versions.
ProtocolLib : #608
Papermc : #347

As long as holograms are enabled on my plugin, I can't connect, I crash with the exception below. If I disable them, I can connect.

Packet encoding of packet ID 78 threw (skippable? false)
java.lang.ClassCastException: class net.minecraft.network.syncher.DataWatcher$Item cannot be cast to class net.minecraft.network.syncher.DataWatcher$b (net.minecraft.network.syncher.DataWatcher$Item and net.minecraft.network.syncher.DataWatcher$b are in unnamed module of loader java.net.URLClassLoader @36aa7bc2)
	at net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket.pack(ClientboundSetEntityDataPacket.java:17) ~[?:?]
	at net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket.write(ClientboundSetEntityDataPacket.java:38) ~[?:?]
	at net.minecraft.network.PacketEncoder.encode(PacketEncoder.java:41) ~[paper-1.19.3.jar:git-Paper-347]
	at net.minecraft.network.PacketEncoder.encode(PacketEncoder.java:14) ~[paper-1.19.3.jar:git-Paper-347]
	at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107) ~[netty-codec-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:709) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:792) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:702) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:120) ~[netty-codec-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:709) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:792) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:702) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.channel.DefaultChannelPipeline.write(DefaultChannelPipeline.java:1015) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.channel.AbstractChannel.write(AbstractChannel.java:301) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
	at com.comphenix.protocol.injector.netty.channel.NettyChannelProxy.write(NettyChannelProxy.java:210) ~[ProtocolLib.jar:?]
	at com.comphenix.protocol.injector.netty.channel.NettyChannelProxy.write(NettyChannelProxy.java:199) ~[ProtocolLib.jar:?]
	at net.minecraft.network.Connection.doSendPacket(Connection.java:459) ~[?:?]
	at net.minecraft.network.Connection.lambda$sendPacket$10(Connection.java:428) ~[?:?]
	at com.comphenix.protocol.injector.netty.channel.NettyEventLoopProxy.lambda$proxyRunnable$2(NettyEventLoopProxy.java:48) ~[ProtocolLib.jar:?]
	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute$$$capture(AbstractEventExecutor.java:167) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]
`` 

Concurrent modification exception

Since the last update, when there are two players online and one removes a hologram, the following error may occur.

java.util.ConcurrentModificationException: null
	at java.util.HashMap$HashIterator.nextNode(HashMap.java:1605) ~[?:?]
	at java.util.HashMap$KeyIterator.next(HashMap.java:1628) ~[?:?]
	at com.github.unldenis.hologram.HologramPool.remove(HologramPool.java:56) ~[InfiniteForge (2).jar:?]
	at xyz.arcadiadevs.infiniteforge.utils.HologramsUtil.removeHologram(HologramsUtil.java:65) ~[InfiniteForge (2).jar:?]

Individual Hologram player

Hello, I am setting up a ranking and need to make holograms in individual for each player, the player will be able to switch the ranking depending on types and because of this I need the hologram to be unique.

I tested the placeholders and it seems to be very complex to use them for this case, could you show me an example of how to do this ?

Doesn't work in 1.8.0 -1.8.8

causes this:

[09:20:36 WARN]: Exception in thread "Craft Scheduler Thread - 1"
[09:20:36 WARN]: org.apache.commons.lang.UnhandledException: Plugin LootChest v2.3.6 generated an exception while executing task 13
        at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:56)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: FieldAccessException: Field index 0 is out of bounds for length 0
        at com.comphenix.protocol.reflect.FieldAccessException.fromFormat(FieldAccessException.java:49)
        at com.comphenix.protocol.reflect.StructureModifier.write(StructureModifier.java:315)
        at org.holoeasy.ext.StructureModifierExtKt.set(StructureModifierExt.kt:6)
        at org.holoeasy.packet.spawn.SpawnPacketA$spawn$1.invoke(SpawnPacketA.kt:51)
        at org.holoeasy.packet.spawn.SpawnPacketA$spawn$1.invoke(SpawnPacketA.kt:37)
        at org.holoeasy.packet.PacketBuilderKt.packet(PacketBuilder.kt:8)
        at org.holoeasy.packet.spawn.SpawnPacketA.spawn(SpawnPacketA.kt:37)
        at org.holoeasy.line.Line.spawn(Line.kt:28)
        at org.holoeasy.line.TextLine.show(TextLine.kt:103)
        at org.holoeasy.hologram.Hologram.show(Hologram.kt:58)
        at org.holoeasy.pool.HologramPool.hologramTick$lambda$5(HologramPool.kt:112)
        at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftTask.run(CraftTask.java:71)
        at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:53)
        ... 3 more
        ```

java.lang.IllegalArgumentException: Registry has no elements!

I Have tried the ExampleHolograms class from the readme, and it shows a error.

Version: 1.8.8

[HologramLib] Task #6 for HologramLib v1.0.0 generated an exception
java.lang.IllegalArgumentException: Registry has no elements!
        at org.apache.commons.lang.Validate.notEmpty(Validate.java:248) ~[patched.jar:git-PaperSpigot-"4c7641d"]
        at com.comphenix.protocol.wrappers.WrappedDataWatcher$Registry.get(WrappedDataWatcher.java:966) ~[?:?]
        at com.comphenix.protocol.wrappers.WrappedDataWatcher$Registry.getChatComponentSerializer(WrappedDataWatcher.java:1057) ~[?:?]
        at com.github.unldenis.hologram.line.TextLine.update(TextLine.java:64) ~[?:?]
        at java.util.concurrent.CopyOnWriteArrayList.forEach(CopyOnWriteArrayList.java:895) ~[?:1.8.0_312]
        at java.util.concurrent.CopyOnWriteArraySet.forEach(CopyOnWriteArraySet.java:404) ~[?:1.8.0_312]
        at com.github.unldenis.hologram.Hologram.setLine(Hologram.java:87) ~[?:?]
        at com.github.unldenis.hologram.ExampleHolograms$1.run(ExampleHolograms.java:61) ~[?:?]
        at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftTask.run(CraftTask.java:59) ~[patched.jar:git-PaperSpigot-"4c7641d"]
        at org.bukkit.craftbukkit.v1_8_R3.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:352) [patched.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:783) [patched.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:378) [patched.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:713) [patched.jar:git-PaperSpigot-"4c7641d"]
        at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:616) [patched.jar:git-PaperSpigot-"4c7641d"]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_312]       

Crash

I tried to test the library but putting it to show the player when entering simply crashes the game.

// Why is it breaking :(

Time: 03/11/22 10:45 PM
Description: Ticking entity

java.lang.ClassCastException: java.lang.Byte cannot be cast to dc
	at pz.h(DataWatcher.java:149)
	at um.t_(SourceFile:538)
	at adm.a(SourceFile:1408)
	at adm.g(SourceFile:1386)
	at adm.i(SourceFile:1279)
	at ave.s(SourceFile:1850)
	at ave.av(SourceFile:889)
	at ave.a(SourceFile:325)
	at net.minecraft.client.main.Main.main(SourceFile:124)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
	at net.minecraft.launchwrapper.Launch.main(Launch.java:28)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Stacktrace:
	at pz.h(DataWatcher.java:149)
	at um.t_(SourceFile:538)
	at adm.a(SourceFile:1408)
	at adm.g(SourceFile:1386)

-- Entity being ticked --
Details:
	Entity Type: ArmorStand (um)
	Entity ID: -2146099896
	Entity Name: Hello World!
	Entity's Exact location: 0,84, 88,88, 0,38
	Entity's Block location: 0,00,88,00,0,00 - World: (0,88,0), Chunk: (at 0,5,0 in 0,0; contains blocks 0,0,0 to 15,255,15), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,0,0 to 511,255,511)
	Entity's Momentum: 0,00, 0,00, 0,00
	Entity's Rider: ~~ERROR~~ NullPointerException: null
	Entity's Vehicle: ~~ERROR~~ NullPointerException: null
Stacktrace:
	at adm.i(SourceFile:1279)

Code:

public class ExampleHolograms implements Listener {

    private final Plugin plugin;
    private final HologramPool hologramPool;

    public ExampleHolograms(Plugin plugin) {
        this.plugin = plugin;
        this.hologramPool = new HologramPool(plugin, 70, 0.5f, 5f);
        Bukkit.getPluginManager().registerEvents(this, plugin);
    }

    /**
     * Appends a new Hologram to the pool.
     *
     * @param location The location the Hologram will be spawned at
     * @param excludedPlayer A player which will not see the Hologram for 10
     * seconds
     */
    public void appendHOLO(Location location, Player excludedPlayer) {
        Hologram hologram = Hologram.builder()
                .location(location)
                .addLine("Hello World!", false)
                .addLine("Using Hologram-Lib", false)
                .addLine("Hello %%player%%", true)
                .addLine(new ItemStack(Material.IRON_BLOCK))
                .addPlaceholder("%%player%%", Player::getName)
                .build(hologramPool);

        hologram.getLines().get(3).setAnimation(Animation.AnimationType.CIRCLE);

        if (excludedPlayer != null) {
            // adding the excluded player which will not see the Hologram
            hologram.addExcludedPlayer(excludedPlayer);

            // shows 10 seconds after theHologram
            Bukkit.getScheduler().runTaskLater(plugin, () -> hologram.removeExcludedPlayer(excludedPlayer), 20L * 10);
        }
    }

    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        appendHOLO(player.getLocation(), null);
    }

    @EventHandler
    public void onHologramInteract(PlayerHologramInteractEvent e) {
        Player player = e.getPlayer();
        TextLine line = e.getLine();
        player.sendMessage("Click at " + line.parse(player));
    }
}

ItemLine doesn't appear on paper 1.8.8

Hello, I am using the latest version of Paper 1.8.8 and the latest version of Hologram-Lib (1.2.6).

And I do not why but my item line doesn't appear.
This is my code:

Hologram.Builder builder = Hologram.builder()
                        .location(location.clone().add(0.5, -1.0, 0.5))
                        .addPlaceholder("<playerName>", Player::getName);

builder.addLine(new ItemStack(Material.FISHING_ROD));
builder.addLine(Common.colorize("&7A item should appear above"));
this.holograms.add(builder.build(pool));

Image:
image

Changing the text of an holo that already haves text bugs it

Executing this code:

		TextLine textLine = new TextLine((Plugin)Main.getInstance(), name, null, false);
		hologram.load(textLine);

in 1.16.5 on a new hologram doesn't cause issue. Bug an hologram that already has text will bug. That being said, the hologram is correctly remove on logout/login.
I chose to remove the hologram before changing its text, and it works, so I won't have this bug in other versions (sorry)

NoClassDefFoundError

image

Whenever I attempt to run my sever, my plugin is stopped with the above error. ProtocolLib is added to my plugins folder and added as a dependency for my plugin.

Gradle Build File

plugins {
    id("java")
}

group = "org.example"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
    maven("https://repo.papermc.io/repository/maven-public/")
    maven("https://jitpack.io")
}

dependencies {
    compileOnly("io.papermc.paper:paper-api:1.19.2-R0.1-SNAPSHOT")
    implementation("com.github.unldenis:Hologram-Lib:master-SNAPSHOT")
}

tasks.getByName<Test>("test") {
    useJUnitPlatform()
}

java {
    toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}

Hologram is invisible

I try to create many holograms at one time, they create, but are invisible until I reload the chunk.

Code:

        public static void createHolo(Location loc) {
        Line line = new Line(GameAPI.instance());

        Spawner spawner = EggWars.getInstance().getSpawnerManager().getSpawner(loc);
        TextLine textLine = new TextLine(line, spawner.getName() + " " + spawner.getRomLevel(), null);

        Location holoLoc = loc.clone().add(0, 1, 0);
        Hologram hologram = new Hologram(GameAPI.instance(), holoLoc, new TextSequentialLoader());

        hologram.load(textLine);

        for(Player all : Bukkit.getOnlinePlayers()) {
            hologram.show(all);
        }
        hologramPool.put(loc, hologram);
        System.out.println("Hologram bei " + holoLoc + " gespawnt!");
        
        //tried if it helps
        for(Player all : Bukkit.getOnlinePlayers()) {
            Bukkit.getScheduler().runTaskLater(GameAPI.instance(), () -> hologram.show(all), 25L * 30);
        }
    }

They will be created on a teleport to a new World. How can I manage to let them instantly be visible?

Getting a hologram

How can I get some hologram, I was looking at the library code and I can't find any method to get this unless I modify it.

ex:

public void moveHologram(Player player, ???? ???) {
    hologramPool.getHologram(???).teleport(player.getLocation());
}

warn spam in console when changing world

Hi, i use the Hologram-Lib version 1.2.1. But its spam a error in console when somebody change the world. HydroGame is the overworld and HydroGame_nether the nether. I don't know why its spamming like this. By the way its only spamming, when a player, no matter who, is in the nether.

I use the Hologram-Lib for my ChestShop system. when a ChestShop is created, it displays the item above the chest that the player is selling.
Here is a screen:
hologram

Somebody has a idea?

HologramLib 3

I know that there is a need to update to the latest versions as well (which someone could help me with, there will only be something to change in the Packets).

Solving #41 is also a goal

To make the library safer, taking advantage of kotlin's null safety and its other features, I created a branch to rewrite the project in kotlin with other new features.

The aim is to create a powerful library that can be used by both java and kotlin users.

For example, to create holograms, right now the most convenient utility is HologramBuilder.

Hologram.builder(plugin, loc)                                                  // initialize the builder
        .addTextLine("Hello")                                                      // add a text line
        .addTextLine("%%player%%")                                                 // add another text line
        .addClickableTextLine("Click me", 0.5f, 5f)                                 // add a clickable text line
        .addBlockLine(new ItemStack(Material.GOLD_BLOCK))                           // add a block line
        .addBlockLine(new ItemStack(Material.DIAMOND_BLOCK), AnimationType.CIRCLE)  // add a block line with animation
        .placeholders(placeholders)                                                // add placeholders
        .loadAndBuild(pool); 

I took a cue from SparkJava and Javalin to make it possible to create holograms declaratively, similar to kotlin's DSLs, which can also be used in java. Example

hologram(pool, loc, () -> {
  name("this is an internal name");

  textline("First Line");
  clickableline("This is a clickable line");
  blockline(new ItemStack(Material.GOLD_BLOCK), Animation.AnimationType.CIRCLE);

  // custom library line, remember to support the IHologramLoader
  customline(plugin -> {
      var line = new Line(plugin);
      var textLine = new TextLine(line, "Click me");
      return new ClickableTextLine(textLine, 0.5f, 5f);
  });
});

Kotlin

hologram(pool, loc) {
    name("this is an internal name")
    textline("First Line")
    clickableline("This is a clickable line")
    blockline(ItemStack(Material.GOLD_BLOCK), AnimationType.CIRCLE)

    // custom library line, remember to support the IHologramLoader
    customline {
        val line = Line(it)
        val textLine = TextLine(line, "Click me")
        ClickableTextLine(textLine, 0.5f, 5f)
    }
}

Doesn't work in 1.19.4 (and maybe other 1.19 versions)

gives this

[09:36:43] [Netty Server IO #2/ERROR]: Error receiving packet 82
java.lang.ClassCastException: class net.minecraft.network.syncher.DataWatcher$Item cannot be cast to class net.minecraft.network.syncher.DataWatcher$b (net.minecraft.network.syncher.DataWatcher$Item and net.minecraft.network.syncher.DataWatcher$b are in unnamed module of loader java.net.URLClassLoader @2530c12)
        at net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata.a(SourceFile:21) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
        at net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata.a(SourceFile:41) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
        at net.minecraft.network.PacketEncoder.a(SourceFile:45) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
        at net.minecraft.network.PacketEncoder.encode(SourceFile:14) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
        at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107) ~[netty-codec-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:709) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:792) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:702) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:120) ~[netty-codec-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:709) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:792) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:702) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:113) ~[netty-codec-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:764) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:790) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:758) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1020) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:311) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]
        at com.comphenix.protocol.injector.netty.channel.NettyChannelProxy.writeAndFlush(NettyChannelProxy.java:227) ~[?:?]
        at com.comphenix.protocol.injector.netty.channel.NettyChannelProxy.writeAndFlush(NettyChannelProxy.java:233) ~[?:?]
        at net.minecraft.network.NetworkManager.a(NetworkManager.java:231) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
        at net.minecraft.network.NetworkManager.lambda$7(NetworkManager.java:220) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
        at com.comphenix.protocol.injector.netty.channel.NettyEventLoopProxy.lambda$proxyRunnable$2(NettyEventLoopProxy.java:48) ~[?:?]
        at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) ~[netty-transport-4.1.82.Final.jar:4.1.82.Final]        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.82.Final.jar:4.1.82.Final]
        at java.lang.Thread.run(Thread.java:833) ~[?:?]

1.8-1.8.9 version support

With the last commit I implemented version 1.8-1.8.9 seen the difference in the packets compared to the later versions.

However the ItemLines seem to have some problem with the position in these older versions. (Not the armorstands but just the head slot).

Preview

Jitpack down

Please move to another repository because jitpack is not doing well

Custom collection classes

FastUtil required a space of 25mb, so in 2.4.0 I preferred to implement the three classes IntHashSet, ReferenceHashSet and ReferenceArrayList from scratch.
The IntHashSet class is used only to manage player IDs in ClickableTextLine.
The other two allow me a comparison between Player, for example, directly between references.

If you want to contribute and improve these classes, don't hesitate to send PRs.

error when the hologram is loaded

java.lang.NullPointerException: Cannot invoke "java.lang.Class.enumConstantDirectory()" because "enumClass" is null
at java.lang.Enum.valueOf(Enum.java:267) ~[?:?]
at com.comphenix.protocol.wrappers.EnumWrappers$EnumConverter.getGeneric(EnumWrappers.java:823) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.wrappers.EnumWrappers$EnumConverter.getGeneric(EnumWrappers.java:804) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.wrappers.BukkitConverters$4.getGeneric(BukkitConverters.java:388) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.wrappers.BukkitConverters$4.getGeneric(BukkitConverters.java:385) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.wrappers.Converters$1.getGeneric(Converters.java:48) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.wrappers.BukkitConverters.getGenericList(BukkitConverters.java:303) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.wrappers.BukkitConverters.access$100(BukkitConverters.java:91) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.wrappers.BukkitConverters$3.getGeneric(BukkitConverters.java:370) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.wrappers.BukkitConverters$3.getGeneric(BukkitConverters.java:362) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.wrappers.Converters$1.getGeneric(Converters.java:48) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.reflect.StructureModifier.writeInternal(StructureModifier.java:331) ~[ProtocolLib.jar:?]
at com.comphenix.protocol.reflect.StructureModifier.write(StructureModifier.java:295) ~[ProtocolLib.jar:?]
at com.github.unldenis.hologram.packet.IPackets$PacketsV1_9V1_18.equipmentPacket(IPackets.java:212) ~[TestPlugin.jar:?]
at com.github.unldenis.hologram.line.ItemLine.update(ItemLine.java:50) ~[TestPlugin.jar:?]
at com.github.unldenis.hologram.line.ItemLine.show(ItemLine.java:44) ~[TestPlugin.jar:?]
at com.github.unldenis.hologram.Hologram.show(Hologram.java:144) ~[TestPlugin.jar:?]
at com.github.unldenis.hologram.HologramPool.lambda$hologramTick$5(HologramPool.java:167) ~[TestPlugin.jar:?]
at org.bukkit.craftbukkit.v1_19_R1.scheduler.CraftTask.run(CraftTask.java:101) ~[paper-1.19.2.jar:git-Paper-113]
at org.bukkit.craftbukkit.v1_19_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:57) ~[paper-1.19.2.jar:git-Paper-113]
at com.destroystokyo.paper.ServerSchedulerReportingWrapper.run(ServerSchedulerReportingWrapper.java:22) ~[paper-1.19.2.jar:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
at java.lang.Thread.run(Thread.java:833) ~[?:?]

    ------------
    
    Server version: paper 1.19.2
    Protocol version: 5.0.0 snapshot b606

Update Method

Is it possible to add method which update all lines in a Hologram?

Ability to hide the hologram from all players

Hello, great resource!

Is there any way to add a method in Hologram to choose to hide or show the hologram to all players by default (ex: hologram.setVisibleByDefault(false)) ?

In my case, I want to create a hologram, hide it from all players (and those who will join later) and under certain conditions display it to some players.

Is this kind of functionality implementable?

Thanks :)

Add info on how to build sources

When using ./gradle build, we get an api-3.1.1.jar somewhere, but this jar isn't usable in production (missing kotlin classes)
The project may include some info on how to build it?

IllegalArgumentException when joining world with some hologram near to me

Hi,

Having this exception when I join the world with an hologram near to me

[15:57:50 WARN]: [HeadBlocks] Plugin HeadBlocks v2.0.7 generated an exception while executing task 31
java.lang.IllegalArgumentException: No serializer found for class java.lang.Byte
at com.comphenix.protocol.wrappers.WrappedDataWatcher$Registry.get(WrappedDataWatcher.java:939) ~[ProtocolLib (2).jar:?]
at com.github.unldenis.hologram.packet.IPackets$PacketsV1_9V1_18.metadataPacket(IPackets.java:205) ~[HeadBlocks-2.0.7.jar:?]
at com.github.unldenis.hologram.TextLine.show(TextLine.java:42) ~[HeadBlocks-2.0.7.jar:?]
at com.github.unldenis.hologram.Hologram.show(Hologram.java:131) ~[HeadBlocks-2.0.7.jar:?]
at com.github.unldenis.hologram.HologramPool.lambda$hologramTick$5(HologramPool.java:150) ~[HeadBlocks-2.0.7.jar:?]
at org.bukkit.craftbukkit.v1_19_R1.scheduler.CraftTask.run(CraftTask.java:101) ~[paper-1.19.jar:git-Paper-17]
at org.bukkit.craftbukkit.v1_19_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:57) ~[paper-1.19.jar:git-Paper-17]
at com.destroystokyo.paper.ServerSchedulerReportingWrapper.run(ServerSchedulerReportingWrapper.java:22) ~[paper-1.19.jar:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
at java.lang.Thread.run(Thread.java:833) ~[?:?]

What should I do to correct the problem? Thank you!
Best regards,

Does not work correctly on Paper 1.18.2

Hey there! I was looking for a Hologram API for a project, and this one looked perfect.
Unfortunately, I'm unable to spawn a working hologram. Here's my current code:

final HologramPool pool = new HologramPool(warcrafted, 70);
Hologram.builder(warcrafted, player.getLocation())
		.addLine("Hello")
		.addClickableLine("Click me", 0.5f, 5f)
		.addBlockLine(new ItemStack(Material.GOLD_BLOCK))
		.addBlockLine(new ItemStack(Material.DIAMOND_BLOCK), Animation.AnimationType.CIRCLE)
		.loadAndBuild(pool);

I tried to follow the wiki to end there. When the code is run, it only spawns stacked ghasts with no errors in the console or the chat:
image

Env Info:

  • Server version: 1.18.2-R0.1-SNAPSHOT (Paper)
  • ProtocolLib version: 5.0.0
  • Hologram-Lib version: 2.6.0

Thanks for your help in advance :p

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.