#help-development

1 messages · Page 610 of 1

buoyant viper
#

getOfflinePlayer().getId() maybe

#

idk if its the same uuid

#

?jd-s

undone axleBOT
tender shard
#

i don't like the new switch syntax. the old one is way tidier

magic glacier
quaint mantle
#

Anyone know why when this is ran and you enter the student id it just skips over the course code? ```c
void addStudent(int* student_id, int* course_code, Student* students, Course* courses) {
char id[MAX_ID];
char code[MAX_CODE];

printf("Enter Student ID: ");
fgets(id, MAX_ID, stdin);
id[strcspn(id, "\n")] = '\0';

int i, j;

for (i = 0; i < *student_id; i++) {
    if (strcmp(students[i].id, id) == 0) {
        break;
    }
}

if (i == *student_id) {
    printf("Student ID not found.\n");
    return;
}

printf("Enter Course Code: ");
fgets(code, MAX_CODE, stdin);
code[strcspn(code, "\n")] = '\0';

for (j = 0; j < *course_code; j++) {
    if (strcmp(courses[j].code, code) == 0) {
        break;
    }
}

if (j == *course_code) {
    printf("Course Code not found.\n");
    return;
}

printf("Student %s added to Course %s.\n", id, code);

}
output
Enter your choice: 1
Enter Student ID: 12345
Enter Course Code: Course Code not found.

buoyant viper
ivory sleet
#

public class Human {
private String name;

public Human(){}

public String getName(){ return name;}
public String setName(String name) { this.name = name; }

public void setFromConfig(ConfigurationSection section){
this.name = section.getString("name");
}

public void setToConfig(ConfigurationSection section) {
this.section.set("name".this.name);
}
}

Then outside the class you just use
Human human = …;
human.setFromConfig(config.getConfigurationSection("someSection"));
human.setToConfig(config.getConfigurationSection("someSection"));

@worthy moat

magic glacier
buoyant viper
buoyant viper
magic glacier
#

and how to solve it

buoyant viper
#

update? idk DogJA

quaint mantle
buoyant viper
#

does the method not exist in 1.8?

#

(getUniqueId)

magic glacier
#

it exists

buoyant viper
#

then you have no problem..?

magic glacier
#

no i have

twin venture
#

hi , mm i know this looks like a dumb question ..

#

i made a shop plugin , fully working my only problem is

magic glacier
#

getOfflinePlayer(player_name).getUniqueId().toString()

twin venture
#

when i buy an item the lore of the price is still there ..

quaint mantle
#

i think its called meta?

magic glacier
#

i think you should remove it from the meta

quaint mantle
#

meta data?

ivory sleet
magic glacier
#

yep item meta

twin venture
ivory sleet
twin venture
#

already doing that

ivory sleet
#

Dont see the issue

worthy moat
quaint mantle
magic glacier
ivory sleet
#

Yes

magic glacier
#

okay

twin venture
ivory sleet
#

Its because getOfflinePlayer(name) is deprecated

#

Since it may be blocking

ivory sleet
#

Remove the this.

worthy moat
ivory sleet
#

Yes

#

You can change their names

shadow owl
# twin venture explain?

you're clearing the List but not resetting the list as the lore, so you need to do lore.clear and then meta.setlore(lore) then item.setmeta(meta)... a bit annoying but that should help

ivory sleet
#

To read and respectively write

ornate patio
#

bump

ivory sleet
#

Yeah

shadow owl
# twin venture

But do keep in mind this will remove lore that the user already has on the item, so if someone else is using a plugin that adds items with lore, your plugin will remove it

ivory sleet
#

Whats wrong with that okay1204?

ornate patio
#

I just wanna increase the attack damage of the weapon

#

but for some reason using an attribute MODIFIER resets the damage

#

and makes it do only 1 damage

#

and also displays all that annoying text

#

"When in main hand..."

ornate patio
#

just want to change this text from "8 attack damage" to "9 attack damage"

#

and have the sword deal one more damage

worthy moat
ivory sleet
ornate patio
#

yeah but then i have to manually display it in the lore

#

i thought there would be a better way

#

also how do i increase the damage

worthy moat
#

okay to write something you mentioned this (I altered it to my classes):

#

Cache.arena.write(AlphaWars.data.getConfig().getConfigurationSection("someSection"));

#

But what exactly do you mean by "someSection" What do I put in there?

#

Its the path of ConfigurationSection

#

Is that just the Key for my Object in yaml?

#

Like test: "test"

wet breach
ornate patio
#

yeah thats what ive been trying to do

shadow owl
# worthy moat ``` Cache.arena.write(AlphaWars.data.getConfig().getConfigurationSection("someSe...

If you're trying to save a custom class to a yaml file I'd really recommend serialization. You basically provide some methods that tell Spigot how to parse your class into config data and how to parse the config data into a class. This guide really helped me: https://www.spigotmc.org/wiki/introduction-to-serialization-section-2/

wet breach
#

sometimes you need to use NMS for it

ornate patio
#
Collection<AttributeModifier> modifiers = meta.getAttributeModifiers(attribute);

if (modifiers != null) {
    for (AttributeModifier modifier : modifiers) {
        if (modifier.getName().equals("smithingEnhancement")) {
            meta.removeAttributeModifier(attribute, modifier);
        }
    }
}

meta.addAttributeModifier(attribute, new AttributeModifier(UUID.randomUUID(), "smithingEnhancement", level, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.HAND));

this just sets the damage to level

#

doesn't add to the damage like how i expected

river oracle
#

Any suggestions for ensuring an RTP teleports above ground and not in a cave

worthy moat
river oracle
#

thanks

ornate patio
#

ive done that

shadow owl
ornate patio
#

it looks different though

#

also still doesnt add to attack damage

#

it just sets it to 1

young knoll
#

You need to get the base attributes

#

Material#getDefaultAttributeModifiers

ornate patio
#

so I just use this to get the original attack damage

#

and add to it?

ivory sleet
#

So in yaml I’d have

someSection:
  name: Conclube
worthy moat
ivory sleet
#

“someSection” gets the indented stuff under it

ornate patio
worthy moat
#

damn got an error

#
Caused by: java.lang.NullPointerException: Cannot invoke "org.bukkit.configuration.ConfigurationSection.set(String, Object)" because "map" is null
        at de.marvn.alphablock.alphawars.util.objects.Arena.write(Arena.java:31) ~[?:?]
        at de.marvn.alphablock.alphawars.listeners.PlayerInventoryClick.onPlayerInventoryClick(PlayerInventoryClick.java:61) ~[?:?]
        at jdk.internal.reflect.GeneratedMethodAccessor747.invoke(Unknown Source) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:300) ~[patched_1.8.8.jar:git-PaperSpigot-445]
        ... 19 more```
#
    public void write (ConfigurationSection map) {
        map.set("name", name);
        map.set("maxPlayers", maxPlayers);
        map.set("teams", teams);

        map.set("bronzeSpawner", bronzeSpawner);
        map.set("silverSpawner", silverSpawner);
        map.set("goldSpawner", goldSpawner);
        map.set("diamondSpawner", diamondSpawner);
        map.set("emeraldSpawner", emeraldSpawner);
    }```
#

the first set is line 31

#

How does this happen?

ivory sleet
#

u’re calling write(null) effectively

quaint mantle
worthy moat
ivory sleet
#

getConfigurationSection(“someSection") probably returns null

ivory sleet
#

I didnt mean that u should use “someSection” literally

ornate patio
ivory sleet
#

It was an example

quaint mantle
#

OH im dumb i forgot to add getchar();

compact haven
#

Anyone know why when this is ran and you

worthy moat
hazy parrot
worthy moat
#

But should the name be my class or what?

ivory sleet
#

Yeah

#

Sounds reasonable

quaint mantle
hazy parrot
quaint mantle
#

yea

hazy parrot
#

Causing "enter" to be course code

worthy moat
# ivory sleet Yeah

Ok i probably misunderstand something...What exactly should I enter there?

ivory sleet
#

How does config look rn?

worthy moat
#

you mean the yml?

ivory sleet
#

Yep

worthy moat
#
Lobby:
  ==: org.bukkit.Location
  world: world
  x: 735.5
  y: 23.0
  z: -1012.5
  pitch: -0.053918753
  yaw: 315.0
#

Only this

#

nvm still lost

ivory sleet
#

Is this data u’re gonna store or just a set config format?

worthy moat
ivory sleet
#

Can u store it again?

#

Like without reading it first

#

But else

#

You probably wanna add
if (section == null) return;

worthy moat
#

Is the part in the write () the reading part? Yes am I right?

ivory sleet
#

Oh yeah fuck me

#

I forgot that may be null

worthy moat
#

hahaha ok

#

so in the write method check if null?

#

nvm that would cancel all

ivory sleet
#

Yeah

#

So just do this instead

#

ConfigurationSection section = new MemoryConfiguration();
blah.write(section);
config.set(…, section);

worthy moat
#

so like this?

#
ConfigurationSection section = new MemoryConfiguration();
                        Cache.arena.write(section);
                        AlphaWars.data.getConfig().set("Test", section);```
ivory sleet
#

Yea

worthy moat
#

NOW IT WORKS

#

BUT

#

HashMap<String, Team> teams = new HashMap<>();

#

I ve got this in my Object

#

(another Object)

#

I added the same methods...But how do I fix this then?

#
Test:
  name: PirateCraft
  maxPlayers: 2
  teams:
    RED: !!de.marvn.alphablock.alphawars.util.objects.Team
      spawnBlock:
        ==: org.bukkit.Location
        world: PirateCraft
        x: -122.0
        y: 64.0
        z: -326.0
        pitch: 0.0
        yaw: 0.0
      spawnPoint:
        ==: org.bukkit.Location
        world: PirateCraft
        x: -122.0
        y: 64.0
        z: -325.0
        pitch: 0.0
        yaw: 0.0
    BLUE: !!de.marvn.alphablock.alphawars.util.objects.Team
      spawnBlock:
        ==: org.bukkit.Location
        world: PirateCraft```
ivory sleet
#

Its a bit complicated but basically

#

For write
{
ConfigurationSection subSection = new MemoryConfiguration();
teams.forEach((key,value) -> {
subSection.set(key,value);
});
section.set("teams",subSection);
}

worthy moat
#

ok let me test

ivory sleet
#

For read
{
ConfigurationSection subSection = section.getConfigurationSection(“teams”);
if (subSection != null) {
subSection.getValues(false).forEach((key, value) -> {
teams.put(key,(Location)value);
});
}
}

#

You get the concept I hope

worthy moat
#

Bruh it does overwrite my other data

#

it basiucally deletes everything and does only add my stuff

#

And in the write secion the teams thing does somehow not work

ivory sleet
#

How did u incorporate it

worthy moat
#

wdym with incoporate?

#

I save it like that

ivory sleet
#

Add it to ur own code

worthy moat
#
                        ConfigurationSection section = new MemoryConfiguration();
                        Cache.arena.write(section);
                        AlphaWars.data.getConfig().set(Cache.arena.getName(), section);
                        AlphaWars.data.save();```
worthy moat
ivory sleet
#

Cache.arena

worthy moat
#

so everytime I set something it just added those stuff

#

wait let me retry

#

nvm it just added the stuff

#

but still this

#
    RED: !!de.marvn.alphablock.alphawars.util.objects.Team
      spawnBlock:
        ==: org.bukkit.Location
        world: PirateCraft
        x: -153.0
        y: 64.0
        z: -219.0
        pitch: 0.0
        yaw: 0.0
      spawnPoint:
        ==: org.bukkit.Location
        world: PirateCraft
        x: -159.0
        y: 64.0
        z: -219.0
        pitch: 0.0
        yaw: 0.0
    BLUE: !!de.marvn.alphablock.alphawars.util.objects.Team```
ivory sleet
#

Yea

#

Do u just use set("path”, team) or what lol

worthy moat
# ivory sleet Yea

this is how my write looks like

    public void write (ConfigurationSection map) {

        ConfigurationSection subSection = new MemoryConfiguration();
        teams.forEach(subSection::set);
        map.set("teams", subSection);

        map.set("name", name);
        map.set("maxPlayers", maxPlayers);


        map.set("bronzeSpawner", bronzeSpawner);
        map.set("silverSpawner", silverSpawner);
        map.set("goldSpawner", goldSpawner);
        map.set("diamondSpawner", diamondSpawner);
        map.set("emeraldSpawner", emeraldSpawner);
    }```
ivory sleet
#

Ah

#

I might wanna do it like

#

(key,value) -> {
ConfigurationSection s = new MemoryConfiguration();
value.write(s);
config.set(key,s);
}

worthy moat
#

This Serialize shit is going so far that I am really this close to just use a DB

ivory sleet
#

Lol

#

I think ConfigurationSerializable wouldve worked fine

#

I don’t like it but it works yk

worthy moat
ivory sleet
#

Bad try

worthy moat
ivory sleet
#

I mean

#

Idk what else I can say

worthy moat
#

Should I now rollback to the Serializable shit or push this current thing further?

ivory sleet
#

U choose

worthy moat
#

You say the Spigot thing is much better in my dumb case?

ivory sleet
#

I have to go to sleep quite soon

ivory sleet
worthy moat
ivory sleet
#

Sweden actually

worthy moat
worthy moat
ivory sleet
#

Yeah close enough, so where are you from if I may reciprocate the question

tender shard
#

package name starting with .de = germany

ivory sleet
#

Ah

worthy moat
#

I try this guide then

worthy moat
ivory sleet
#

Yeah maybe alex can help now instead

#

Well I had this gf who lived in germany, but never got good at german, else pretty nice

worthy moat
#

I cant believe I write whole backend stuff and other applications but fail to understand minectaft..Sometimes I think all I know is just flushed down the toilet as soon as I start with MC

ivory sleet
#

Haven’t you worked with like configuration parsers before?

#

And serialization data modelling

worthy moat
ivory sleet
#

Yea

worthy moat
#

Yeah but Jackson is far away from that...Or at least I never hat do dig that down

ivory sleet
#

Just treat the spigot config api like jackson without the annotation stuff

worthy moat
#

hmm ok

#

I try this guide now at first

ivory sleet
#

Yeah

#

All parsers are similar

#

They have ways to write and read from readers and writers such that they yield and consume some type of glorified map object

worthy moat
#

I mean with jackson i just built my object....Added the Annotations and then I could parse and read

ivory sleet
#

Oh

#

Then nvm

#

Dont treat spigot like jackson

worthy moat
#

yeah jackson is very powerful and isnt complicated

#

xD

ivory sleet
#

Cuz spigot doesnt have that annot thingy

ivory sleet
#

It can be complicated if u want

worthy moat
ivory sleet
#

But yeah its probably more trivial for the averagw java dev

#

Yeah

worthy moat
#

Damn

#

something just popped up

ivory sleet
#

Anyway im dipping, good luck

#

Oh?

worthy moat
#

Why didnt I just use Jackson for YML instead of this spigot thingy?

#

Damn

ivory sleet
#

Jackson is a json parser lib

#

It doesnt aim to satisfy all yaml specs

worthy moat
tender shard
ivory sleet
#

Its like

#

Sure I can use java.util.logging for logging

#

But do I want to? Hell na

worthy moat
#

xD

echo basalt
#

mhm static arena object

worthy moat
#

another one who hates this test thing

#

xD

worthy moat
echo basalt
#

Maybe because it's static aboose

#

Just do it right the first time

worthy moat
#

xD

echo basalt
#

or well.. majorly fuck up the first time and get it right the second

echo basalt
#

Which is what I did with my minigame lib

young knoll
#

It’s not trial and error if there is no error

buoyant viper
young knoll
#

Not enough RCE exploits

buoyant viper
#

True

young knoll
ivory sleet
#

You all so goofy ah

opaque scarab
#

How can I set custom model data for world.item.ItemStack?

ivory sleet
buoyant viper
ivory sleet
ornate patio
#

also is it just me or does spigot 1.20.1 have a memory leak?

ivory sleet
#

Shouldn’t have?

ornate patio
#

i removed my plugin to make sure its not mine thats causing it

ornate patio
#

i left it running for 15 minutes and i came back, my memory usage went from 60% to 95%

ivory sleet
#

Mem leaks r often very subtle

#

Well

#

Maybe ur gc just didnt sweep for a while?

ornate patio
#

its been happening consistently for a couple days

opaque scarab
ornate patio
#

just now i removed my plugin to confirm that it wasnt mine

echo basalt
#

I'd use spark to profile it

#

Run /spark heapdump once it reaches 95%

ornate patio
echo basalt
#

And it'll generate a file that's usually as big as the amount of RAM the JVM is using

ornate patio
#

is it a plugin?

echo basalt
#

yeah

ornate patio
#

alr ill download it and see

echo basalt
#

Anyways you'll want to grab that file and run it on a profiler

#

I usually use YourKit although it's pricy

#

Think I forced my boss to pay 100$ for a 1 year personal license

worthy moat
#

Guys how do I serialize a HasMap ?

#
        for(Allergy allergy : this.allergies)
            tempSerializeAllergies.add(allergy.serialize()); // Serialize this allergy and add it into the temporary list```
echo basalt
#

You serialize its keys and values

worthy moat
#

wait

#

Let me try

echo basalt
#

or store a maplist or something

worthy moat
#

like that?

echo basalt
#

wh

#

no

worthy moat
#

xD

echo basalt
#

PlayerMove could've been fired and then cancelled

#

Some other plugin

worthy moat
echo basalt
#

What data is there to serialize?

worthy moat
echo basalt
#

I saw something about a list of allergies

worthy moat
echo basalt
#

Okay

#

Does Team implement ConfigurationSerializable

worthy moat
#

oui

echo basalt
#

Okay

carmine mica
#

what? no it doesn't

echo basalt
#

we're not talking about bukkit's team class

worthy moat
#

yep

#

its my own

carmine mica
#

oh ok

echo basalt
#

Anyways your structure is pretty simple then

#

Just a map where the key is a string

ornate patio
#

how can I get the default attack speed of a tool/weapon

echo basalt
#

So we can store that as a section where the key (string) is the name and the team is the value

#

Something like

Map<String, Team> teams = ...;

for(Map.Entry<String, Team> entry : teams.entrySet()) {
  String teamName = entry.getKey();
  Team team = entry.getValue();

  config.set(teamName, team);
}
#

Ideally in its own teams section

ornate patio
echo basalt
#

And then to read you get the teams section, loop through its keys and call section.get(key, Team.class) and it does magic

worthy moat
#

I try to write something not read

echo basalt
worthy moat
#
        ArrayList<Map<String, Object>> tempSerializeAllergies = new ArrayList<>(); // Using this as temporary container allowing us to serialize each allergy into a list
        for(Allergy allergy : this.allergies)
            tempSerializeAllergies.add(allergy.serialize());```
#

I try to reproduce this

#

just with a HashMap instead of an Array

#

Or did I misunderstand something?

echo basalt
#

Yeah you misunderstood it completely

ornate patio
#

I just want to fetch the attack speed that is displayed on the item here

worthy moat
echo basalt
ornate patio
#

i've tried that

#

getAttributes(Attribute.GENERIC_ATTACK_SPEED) returns null

#

and material.getDefaultAttributeModifiers(EquipmentSlot.HAND).get(Attribute.GENERIC_ATTACK_SPEED) returns an attributeModifier with a negative value for some reason

echo basalt
#

There's a registerAttribute method

ornate patio
#

wdym

#

where

echo basalt
#

It should register an attribute with default values

worthy moat
#

Nope I cant go any further

ornate patio
#

i dont see the method

#

is it on itemmeta?

echo basalt
#

ugh let me help marvn real fast

echo basalt
#

(I should write a proper post about this)

#

No

#

not yet

#

Serialization is basically the process of converting your object to binary

#

Or in this case into data that goes in your YML file

worthy moat
#
        HashMap<String, Map<String, Object>> tempSerializeTeams = new HashMap<>();
        teams.forEach((key, value) -> {
            tempSerializeTeams.put(key, value.serialize());
        });``` Is this how they would transform a HashMap?
worthy moat
echo basalt
#

Basically it's the process of

Java Object -> Stored data
Stored Data -> Java object

worthy moat
#

yes

echo basalt
#

And usually what's read matches the original data of what went in

worthy moat
#

yes

echo basalt
#

With bukkit's YML system, we have this little interface called ConfigurationSerializable

worthy moat
#

ok

ornate patio
#

also i did /spark heapdump when memory was at 92% usage, it generated an hprof file which i have no idea how to open

echo basalt
#

And it specifies that we need to make a Map<String, Object> serialize method, as well as one of 3 things:

  • A constructor that takes the serialized map and creates the object from serialized contents
  • A valueOf method that does the same process
  • A deserialize method that does the same process
#

And here's a basic example

worthy moat
#

yes that stood in the docs of spigot right?

echo basalt
#
public class Person implements ConfigurationSerializable {

  private final String name;
  private int age;

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public Person(Map<String, Object> map) {
    this.name = (String) map.get("name");
    this.age = (int) map.get("age");
  }

  // Some fancy method
  public void growUp() {
    age++;
  }

  public Map<String, Object> serialize() {
    Map<String, Object> map = new HashMap<>();

    map.put("name", this.name);
    map.put("age", this.age);

    return map;
  }

}
#

This is your person class

#

Now I'll edit it so it conforms to the spec

worthy moat
#

ok

#

now it should have the serialize method

echo basalt
#

Now this class is "Configuration serializable", and we can yeet it in our config directly, or into any collections as well

lavish dock
#

Hey, so some villagers seem to be getting frozen, i think tho some mobs arent scaring them either?

echo basalt
#
FileConfiguration config = ...;

Person joe = new Person("Joe", 69);

config.set("person", joe);
FileConfiguration config = ...;

Person joe = config.get("person", Person.class);
#

This is for an individual

worthy moat
#

But what would it look like if you had a HashMap... I understood it as far as you explained it to me

echo basalt
#

We can also pass a list, for example

#
List<Person> city = List.of(
  new Person("Joe", 69),
  new Person("John", 420)
);

config.set("population", city);
List<Person> city = (List<Person>) config.get("population");
#

And bukkit's yml system will do all the fancy logic

#

Now, for maps

#

A map is basically a collection with a key and a value

#

And YML also works with a key-value system

#

As

number: 123
text: "Some text!"

Can be seen as a map {"number":123, "text":"Some text!"}

#

What if we do the reverse

worthy moat
#

yep...And in my case I have an Object which is needed to be serialized and in this Object there is a HashMap with String as key and another Object as value

echo basalt
#

And go from {"team-one":Team, "team-two":Team}

#

Team implements the ConfigurationSerializable class so we can yeet it directly

#

And the key in our map is a string too, which we can use as the team's name

worthy moat
echo basalt
#

You can make your arena object serializable and save all its contents

worthy moat
#

And now I have to serialize the teams in my ArenaObject

echo basalt
#

You don't

#

You can just yeet the team list

#

And bukkit will understand it

worthy moat
#
    @Override
    public Map<String, Object> serialize() {
        HashMap<String, Object> mapSerializer = new HashMap<>();
        mapSerializer.put("name", name);
        mapSerializer.put("maxPlayers", maxPlayers);

        mapSerializer.put("teams", teams);

        mapSerializer.put("bronzeSpawner", bronzeSpawner);
        mapSerializer.put("silverSpawner", silverSpawner);
        mapSerializer.put("goldSpawner", goldSpawner);
        mapSerializer.put("diamondSpawner", diamondSpawner);
        mapSerializer.put("emeraldSpawner", emeraldSpawner);
        return mapSerializer;
    }```
#

So this should work fine?

#

The teams thing?

echo basalt
#

Try and see, but seems fine

echo basalt
echo basalt
ornate patio
echo basalt
#

I use YourKit

#

And if you have a trial for it I'd recommend

#

It's pricy otherwise

#

I still paid for it

ornate patio
#

hmm

#

i mean im probably never gonna use it again

echo basalt
#

I've used VMs before for free trials

#

And had like a shared folder

#

But it was gimmicky

ornate patio
#

i might do that later then

#

anyways

#

how can i get this attack speed lol

worthy moat
#
PirateCraft:
  ==: de.marvn.alphablock.alphawars.util.objects.Arena
  maxPlayers: 6
  teams:
    RED:
      ==: de.marvn.alphablock.alphawars.util.objects.Team
      spawnPoint:
        ==: org.bukkit.Location
        world: PirateCraft
        x: -159.0
        y: 64.0
        z: -219.0
        pitch: 0.0
        yaw: 0.0
      spawnBlock:
        ==: org.bukkit.Location
        world: PirateCraft
        x: -153.0
        y: 64.0
        z: -219.0
        pitch: 0.0
        yaw: 0.0
    BLUE:
      ==: de.marvn.alphablock.alphawars.util.objects.Team
      spawnPoint:
        ==: org.bukkit.Location
        world: PirateCraft
        x: -159.0
        y: 64.0
        z: -328.0
        pitch: 0.0
        yaw: 0.0
      spawnBlock:
        ==: org.bukkit.Location
        world: PirateCraft
        x: -153.0
        y: 64.0
        z: -328.0
        pitch: 0.0
        yaw: 0.0
  emeraldSpawner:
  - ==: org.bukkit.Location
    world: PirateCraft
    x: -141.0
    y: 51.0
    z: -273.0
    pitch: 0.0
    yaw: 0.0
  name: PirateCraft
  goldSpawner:
  - ==: org.bukkit.Location
    world: PirateCraft
    x: -111.0
    y: 63.0
    z: -219.0
    pitch: 0.0
    yaw: 0.0
  - ==: org.bukkit.Location
    world: PirateCraft
    x: -111.0
    y: 63.0
    z: -328.0
    pitch: 0.0
    yaw: 0.0
  bronzeSpawner:
  - ==: org.bukkit.Location
    world: PirateCraft
    x: -111.0
    y: 63.0
    z: -219.0
    pitch: 0.0
    yaw: 0.0
  - ==: org.bukkit.Location
    world: PirateCraft
    x: -111.0
    y: 63.0
    z: -328.0
    pitch: 0.0
    yaw: 0.0
  diamondSpawner: []
  silverSpawner: []```
echo basalt
#

Yeah that looks ok

worthy moat
#

ok and now this happens

echo basalt
#

You'll need to make your read constructor that reverses the thing

worthy moat
#

1s

echo basalt
#

Ayy just got paid

worthy moat
#

So if the HashMap does work with Bukket without any problems

#
    public Arena(Map<String, Object> serializedArena) {
        this.name = (String) serializedArena.get("name");
        this.maxPlayers = (Integer) serializedArena.get("maxPlayers");
        this.bronzeSpawner = (List<Location>) serializedArena.get("bronzeSpawner");
        this.silverSpawner = (List<Location>) serializedArena.get("silverSpawner");
        this.goldSpawner = (List<Location>) serializedArena.get("goldSpawner");
        this.diamondSpawner = (List<Location>) serializedArena.get("diamondSpawner");
        this.emeraldSpawner = (List<Location>) serializedArena.get("emeraldSpawner");
        this.teams = (HashMap<String, Team>) serializedArena.get("teams");

    }```
#

Then this could work right?

echo basalt
#

Pretty much

ornate patio
#

actually nvm i think if figured out how to get the attack speed

worthy moat
ornate patio
#

looks like it's just 4 minus the negative value that i was getting

young knoll
#

Yes

echo basalt
ornate patio
#

4-2.799999952316284 ~= 1.2

echo basalt
#

But yeah try and see

young knoll
#

The default attack speed is 4

echo basalt
#

?tryandsee

undone axleBOT
ornate patio
#

for a pickaxe

#

thats so weird tho

worthy moat
echo basalt
#

Errors?

young knoll
#

That’s just how mojang programmed it

worthy moat
#

1s

young knoll
#

Since they wanted you to have an attack speed of 4 when holding nothing

worthy moat
#

nvm forgot something again

#

1s

#
Caused by: java.lang.IllegalArgumentException: Specified class does not exist ('de.marvn.alphablock.alphawars.util.objects.Team')```
echo basalt
#

Sounds like a corrupted jar to me

worthy moat
#

how to fix that?

#

THATS WHY I HATE FAT JARS

echo basalt
#

rebuild and reupload

worthy moat
#

ok just deleted the jar...Cleaned with my gradle and then rebuilt it

#

Still same error

echo basalt
#

@young knoll you seem like a smart guy

worthy moat
#

uhhh

#

What did I do wrong?

young knoll
#

What’s goin on

worthy moat
#

🤷‍♂️

wet breach
#

are you shading?

#

if so might want to look to make sure you are not excluding something

#

but you are using gradle so I can't help much with that

worthy moat
worthy moat
#

Maven?

sterile token
#

Does anyone know since when you can write html code into github markdown file?

placid moss
#

wasnt it always a feature

river oracle
sterile token
placid moss
#

are you using shadow plugin

karmic mural
#

Is there a way I can easily check if something like Cactus is placeable on X block?

#

Like given a location/type of block?

#

Basically, if vanilla behavior would have a right click place block of type X on the location they clicked?

young knoll
#

There are various methods in BlockData to do this

#

hadSupport I think? Or isSupported

carmine nacelle
#

Would anyone know why when I try to send an entity destroy packet to all online players, it only gets destroyed for one player?

carmine nacelle
#

        for(Player allOnline: Bukkit.getOnlinePlayers()) {
            cadiaBees.cadiaCore.hologramManager.despawnHologram(allOnline, holoManager.getHolosForHive(customHive).get(0));
            //CadiaCore.getInstance().hologramManager.spawnHologram(allOnline, holoManager.getHolosForHive(customHive).get(0));
        }
    public void despawnHologram(Player player, Hologram hologram) throws InvocationTargetException {
        List<Integer> holoIDs = hologram.getHoloIDs();

        for (Integer holoID : holoIDs) {
            ClientboundRemoveEntitiesPacket removePacket = new ClientboundRemoveEntitiesPacket(holoID);
            ((CraftPlayer) player).getHandle().connection.send(removePacket);
        }
    }
carmine nacelle
drowsy helm
#

looks fine to me

#

where are you handling thte InvocationTargetException

carmine nacelle
drowsy helm
#

because if it throws for one player the rest wont receive it

#

why not put a try catch block lol

carmine nacelle
#

actually, I just removed it and its not complaining now

#

so maybe it was for one of the other methods I tried.

#

im not deleting the ids from the object though so i dont think its an issue where deleting it from the first player deletes the actual id

drowsy helm
#

if you're just sending the packet that won't be the case

carmine nacelle
#

its so weird it only works perfectly if theres 1 player online

drowsy helm
#

so if theres multiple players it just doesnt work at all

#

or only works for one player?

carmine nacelle
#

If theres multiple players, it works for the first player in the player list it seems

#

or maybe its a random player, but it only works for one

drowsy helm
#

is the packet sending at all for the other players

carmine nacelle
#

Not sure

#

it should

drowsy helm
#

test it

carmine nacelle
#

How?

drowsy helm
#

just do a println in that for loop in despawn Hologram

#

see if its executing

carmine nacelle
#

Oh yeah if I send a message to all players in the loop it sends to everyone

#

I tested that

torn shuttle
#

I wonder how much of my life I've spent looking at some kind of progress bar

drowsy helm
#

my only idea is that the id is different for each player for some reason

#

for the spawn packet you are using the same id right

carmine nacelle
#

wait..

#

might be onto something..

carmine nacelle
#

this is my spawnHologram method

drowsy helm
#

yeah thats it

#

using random id

carmine nacelle
#

so I just need to create the id outside the loop

drowsy helm
#

yup

#

well ideally not have it per player

carmine nacelle
#

Any idea how I could cleanly do that so each player has their own holo? Not all players are supposed to see the holos at all times, sometimes has player-specific info etc

#

I think at one time I was just incrementing a value in the holomanager..

#

instead of making a random every time..

drowsy helm
#
class hologram{
  List<UUID> viewers;
  
  void displayAll(){
    for(UUID in viewers){
      add entity packet
    }
  }

  void hideAll(){
    for(UUID in viewers){
      remove entity packet
    }

  }
}```
#

i would do smth like this

#

where you keep track of all the viewers of a specific holo

carmine nacelle
#

Hmm, would it be good to have that in the holo itself or in the manager class?

#

I currently have an abstract Hologram class, and 2 sub-types InfoHologram and OwnableHologram. The InfoHologram isn't interactable/owned by anyone, and the ownable is, well.. ownable/interactable

drowsy helm
#

but yeah just keep the id as a final variable instead of random each time

carmine nacelle
#

tricky tricky lol

carmine nacelle
#

trying to make this clean

drowsy helm
#

but this sorta uses the same idea

#

it has children and iterates through each child, hiding or showing the respective entity

#
    default void hideEntity(Player player){
        removeShownPlayer(player.getUniqueId());
        getChildren().forEach(e -> e.hideEntity(player));

        ClientboundRemoveEntitiesPacket removeEntitiesPacket = new ClientboundRemoveEntitiesPacket((this).asEntity().getBukkitEntity().getEntityId());
        Util.sendPacket(removeEntitiesPacket, player);
    }
    default void showEntity(Player player){
        getChildren().forEach(e -> e.showEntity(player));

        if(this instanceof Invisible){
            hideEntity(player);
            return;
        }

        if(!canShow(player))
            return;

        addShownPlayer(player.getUniqueId());

        ClientboundAddEntityPacket addEntityPacket = new ClientboundAddEntityPacket(asEntity());
        ClientboundSetEntityDataPacket setEntityDataPacket = new ClientboundSetEntityDataPacket(asEntity().getBukkitEntity().getEntityId(), asEntity().getEntityData(), true);

        Util.sendPacket(addEntityPacket, player);
        Util.sendPacket(setEntityDataPacket, player);
    }```
#

These two methods are purely for packet sending, not instantiation or anything

carmine nacelle
#

looks like I just need to improve my way of storing/creating IDs

#

its weird to me that entities need an ID AND a UUID

drowsy helm
#

just use the default getBukkitEntity().getEntityId() method

#

then you don't need to create an id

carmine nacelle
#
ClientboundAddEntityPacket spawnPacket = new ClientboundAddEntityPacket(id, uuid, hologram.getHoloLocation().getX(), currentY, hologram.getHoloLocation().getZ(), 0.5f, 0.5f, net.minecraft.world.entity.EntityType.TEXT_DISPLAY, 1, new Vec3(0,0,0), 0.25);
#

This constructor wants an ID and UUID though

echo basalt
#

id is the entity id

#

You can just generate one

#

UUID can be random too

carmine nacelle
echo basalt
#

I just store it on the hologram object

carmine nacelle
shy forge
#

Hello, quick discussion: I like to use the @NotNull tag in my API code. However, I acknowledge that it's just a tag and won't actually force null, therefore I do validation checks. However my IDE keeps giving me warnings saying "Var is never null" because of the NotNull tag. Firstly, please reassure me that I'm not being dumb by keeping the validation in and secondly, is there a way to "ignore" warnings like you can with spell checkers on word because it's really annoying me

wet breach
#

you can supress warnings with another annotation tag

#

however if its telling you that var is never null, then it might be a case of that its nearly impossible that it could be null

#

or a situation where the value is never unset

drowsy helm
#

Pretty sure you can just toggle it in ide settings

#

But it’s good practice to always check nulls

wet breach
#

so for example, if you initialize a variable at the top of class, then it would be impossible when you initialize the class that variable would be null depending how its initialized

carmine nacelle
#

@drowsy helm Do I need to keep track of the hologram IDs, UUIDs or both? Ideally, id only like to track the entity IDs not uuids

shy forge
carmine nacelle
#

I assume they need to have the same ID for all players but not uuid?

drowsy helm
#

you can just use a random one

carmine nacelle
drowsy helm
#

like i said dolnt use that

#

just use getBukkitEntity().getEntityId()

carmine nacelle
drowsy helm
#

each entity should be their own class instance

#

which extends Entity

carmine nacelle
#

🤔

drowsy helm
#

look at the code i sent you earlier, thats how i did it in my implementation

wet breach
#

or even an ID if you just keep a list of already used ones

carmine nacelle
wet breach
#

no?

neon nymph
#

Hello! I got a question, did the NMS for 1.20.1 change or something? I can't seem to find the import for ServerPlayer

wet breach
#

don't think a lot of it changed, but NMS typically changes between updates

carmine nacelle
#

@drowsy helm I dont see how you're generating the initial entity IDs

#

should I just track the UUIDs, then get the entity by UUID then call entity#getBukkitEntity#getID?

#

that way im only tracking uuids

wet breach
#

probably just be best to let the server generate the UUID's for you

#

less for you to do

carmine nacelle
#

Yeah, i know that part..

#

when I initially create the hologram, the hologram itself gets a randomly generated ID
The hologram itself isn't an entity, but each line is its own entity.

So for each entity, I need to make a unique ID AND UUID, then need to track one or the other, or both so I can store them/reference them later

 private int holoID;
 private List<Integer> entityIDs;
 private List<UUID> entityUUIDs;
wet breach
#

because regardless holograms get UUID's

#

even if you add more entities for the hologram, if a hologram always has at least 1 entity, you can just use that entities UUID

carmine nacelle
wet breach
#

it should still have a UUID then, even if you are using multiple

carmine nacelle
drowsy helm
#

why not treat each hologram class as it's own entity

wet breach
#

^

#

as I said, you can't have a hologram without at least 1 entity

carmine nacelle
#

cause multiple lines and such

wet breach
#

thats fine

drowsy helm
#

yeah thats still possible

wet breach
#

you can make an entity that takes in a collection of entities

#

what do you think the ender dragon is?

#

ender dragon is nothing more then like 9 entities put together

carmine nacelle
#

wait wut

wet breach
#

yeah ender dragon isn't a single entity lol

carmine nacelle
#

tf

#

why

wet breach
#

because they couldn't make a single entity move in various ways

#

so they split it up

#

and all those entities move together

#

it is also why the Ender Dragon is the hardest entity to mess with too

carmine nacelle
#

sounds like doing that for my case would be overkill

wet breach
#

no, in your case its valid because you want all those entities to be associated with a single entity

carmine nacelle
#

each "line" my holo gets is its own entity ofc like this

ClientboundAddEntityPacket spawnPacket = new ClientboundAddEntityPacket(id, uuid, hologram.getHoloLocation().getX(), currentY, hologram.getHoloLocation().getZ(), 0.5f, 0.5f, TEXT_DISPLAY, 1, new Vec3(0,0,0), 0.25);
#

wait 1s

#

there

#

I just need a way to make sure "id" is different for each line, but the same for each player..

#

might have an idea..

wet breach
#

extend the text entity, and make it hold a collection of text entities

#

then you can just keep track of 1 uuid

#

all those other entities are associated with that 1 entity only

carmine nacelle
#

so modify my holo to extend TextDisplay..?

wet breach
#

I guess you would have to implement it instead, and then spawn it as a custom entity

carmine nacelle
#

reeee

wet breach
#

which isn't horrible

#

but in either case it should make what you are doing easier

carmine nacelle
#
public abstract class Hologram implements TextDisplay {
    private Collection<TextDisplay> holoDisplays;
#

so basically this..

#

and remove my entityIDs, entityUUIDs..

wet breach
#

yeah basically

carmine nacelle
#

hmm

#

maybe this could end up being even cleaner..

drowsy helm
carmine nacelle
#

tryna give me herpes

wet breach
#

personally I like using md's paste site

carmine nacelle
#

I dont wanna use armorstands now that TextDisplays exist

drowsy helm
#

yeah fair enough

wet breach
carmine nacelle
#

I like how TextDisplays can have transparent backgrounds, cant be seen through blocks, etc

#

?paste

undone axleBOT
wet breach
#

but he was more or less just showing you a way to do it

#

I am too drunk to do coding

carmine nacelle
wet breach
#

drunk coding is not something you want from me

carmine nacelle
#

no work in the morning? lol

wet breach
#

I work nights

#

weekends I am off

carmine nacelle
#

ahhh

wet breach
#

I only work 4 days out of the week

carmine nacelle
#

nice

drowsy helm
#

why you raw doggin the collection

buoyant viper
carmine nacelle
drowsy helm
#

private Collection<TextDisplay> holoDisplays;

wet breach
#

but that isn't something I rely on though lmao

carmine nacelle
#

I usually use lists but you guys said collection so I made it a collection

#

lol

wet breach
#

like when I am high on weed, I have in the past for some people come up with some like awesome solutions to random things lmao

#

I haven't quite yet done that while drunk, but who knows it could happen 😛

buoyant viper
#

but thatd most likely be... ArrayList<>

carmine nacelle
#
    private List<TextDisplay> holoDisplays = new ArrayList<>();
#

I changed it lol

wet breach
carmine nacelle
wet breach
#

lol

buoyant viper
#

?jd-j

drowsy helm
#

usually you only want to use collection for a param which could be any collection

buoyant viper
#

damn

#

@ mods can we get a command to send the Java Javadocs

carmine nacelle
#

I KNOW WHAT COLLECTIONS ARE

drowsy helm
#

?jdocs

wet breach
#

?jd

buoyant viper
#

no i wanted to see it for myself

wet breach
#

?jd-s

undone axleBOT
buoyant viper
#

i need ?jd-j

carmine nacelle
#

dont give me that ?learnjava shit 😭

buoyant viper
#

for Java javadocs

wet breach
#

those links are javadocs

buoyant viper
#

no like

#

for the java stdlib

wet breach
#

oh

#

got it

buoyant viper
#

yeah lol

wet breach
#

that would be hard given how often they keep releasing updates

buoyant viper
drowsy helm
#

pfft who needs java docs anyways

buoyant viper
#

?learnjava!

undone axleBOT
buoyant viper
#

jk

drowsy helm
#

just brute force your code

carmine nacelle
#

ihu

buoyant viper
wet breach
#

oh there you go winnpixie

#

theres the javadoc link

#

alright, time to down a couple of beers really quick

#

to get more drunk

carmine nacelle
#

✝️

wet breach
#

yeah god aint saving me

#

so since that is the case, might as well join the other side

remote swallow
#

Drunk weed

wet breach
#

well I don't have any weed at the moment

buoyant viper
#

damn, thats a lot of implementation classes

wet breach
#

but if I did it would be too late, you want to smoke before you get drunk

buoyant viper
#

wtf is a RoleList

drowsy helm
#

i have used maybe 6 of those lmao

wet breach
#

nothing you really need to worry about

buoyant viper
#

must be something more internal, references Beans

wet breach
#

no

#

it has to do with setting relations

#

more or less more to do with DB's more then anything

#

most of the time you won't really have a use for it

#

enterprise uses it more

#

it was introduced in java 11 I think

#

or 12

#

one of those two

buoyant viper
#

it was introduced in 1.5

#

..

carmine nacelle
#

This uh... seem legit? @drowsy helm @wet breach

    public void despawnHologram(Hologram hologram) {
        for(UUID viewerUUIDs : hologram.viewers) {
            Player viewerPlayer = Bukkit.getPlayer(viewerUUIDs);

            if(viewerPlayer == null) continue;

            for(TextDisplay holoDisplay : hologram.holoDisplays) {
                ClientboundRemoveEntitiesPacket removePacket = new ClientboundRemoveEntitiesPacket(holoDisplay.getEntityId());
                ((CraftPlayer) viewerPlayer).getHandle().connection.send(removePacket);
            }
        }
    }
buoyant viper
#

i wonder if the client will shit itself if u try to remove an entity that doesnt exist in its registry

carmine nacelle
#

😭

wet breach
#

unless there was no players

carmine nacelle
#

if a player leaves maybe

#

just a safety check

wet breach
#

oh true I suppose

buoyant viper
#

why not just remove them from viewers

carmine nacelle
#

I will

#

but just in case

buoyant viper
#

hmm

carmine nacelle
#

idk lmao

#

real question is

wet breach
#

I guess it doesn't hurt

#

anyways, it seems alright

carmine nacelle
#
                ClientboundAddEntityPacket spawnPacketInteraction = new ClientboundAddEntityPacket(interactID, interactUUID, hologram.getHoloLocation().getX(), currentY, hologram.getHoloLocation().getZ(), 0.5f, 0.5f, EntityType.INTERACTION, 1, new Vec3(0,0,0), 0.25);

How can I even get the entity for an entity spawned through a packet?

#

cause the entity only exists..on the clients..?

wet breach
#

or gracefully in the logs throw some kind of error

carmine nacelle
#

cause once the textdisplay is spawned, its gotta be referenced as an entity so I can store it in my list

wet breach
#

you wouldn't be able to use the server methods for it

carmine nacelle
#

"server methods"?

buoyant viper
#

NMS most likely?

wet breach
#

because the server is not aware about it

#

so you would need to maintain a global list of entities you spawned via packets

#

otherwise you wouldn't be able to reference it later

#

however do note that in this case you can end up with duplicate UUID's since the server doesn't know about it

echo basalt
#

Basically you're making your own entity system

carmine nacelle
#

would this work?

    public void spawnHologram(Hologram hologram) {
        if(!(hologram.getHoloLines().size() > 0)) return;
        double currentY = hologram.getHoloLocation().getY();

        for (int curHoloLine = 0; curHoloLine < hologram.getHoloLines().size(); ++curHoloLine) {
            int id = hologram.getHoloID();
            UUID uuid = UUID.randomUUID();

            ClientboundAddEntityPacket spawnPacket = new ClientboundAddEntityPacket(id, uuid, hologram.getHoloLocation().getX(), currentY, hologram.getHoloLocation().getZ(), 0.5f, 0.5f, TEXT_DISPLAY, 1, new Vec3(0,0,0), 0.25);
            Entity spawnedEntity = Bukkit.getEntity(uuid);
            hologram.holoDisplays.add((TextDisplay) spawnedEntity)

For each holo line, create a TextDisplay entity and add it to the list in the holo?

echo basalt
#

Make separate lines

wet breach
#

why do you need separate entities for each additional line?

carmine nacelle
#

you cant have multiple lines of text for 1 textdisplay

wet breach
#

oh interesting

#

I haven't messed with those entities yet

carmine nacelle
#

plus, I need to be able to reference each line separately

wet breach
#

seems counter intuitive if they are to take over holograms

buoyant viper
#

hmm.. someone should PR an API that lets us make per-viewer/entity entities that can be accessed w normal bukkit

carmine nacelle
#

Like, I need to update the 2nd holo down, the honey level

#

and update it independently

#

of the others.

wet breach
#

and in that Screen shot I assume that is 3 entities then?

carmine nacelle
#

Yes

wet breach
#

also, text display entities don't need to be client side only

#

on the server they are not ticked

#

and they don't count against the entity limit either

shadow owl
buoyant viper
#

hax

wet breach
#

have you not been reading?

carmine nacelle
#

If I spawned them as a normal entity, could they still say different things for each player? could still interact with them with metadata packets?

shadow owl
wet breach
#

as I said, haven't messed with them yet

carmine nacelle
#

left to right

wet breach
#

oh

shadow owl
buoyant viper
wet breach
#

well probably could if you used an entity per player

#

just hide the entity for all players except that one

#

XD

#

but probably not the best way

carmine nacelle
#
    public void setHoloData(Player player, Hologram hologram) {
        for (int curHoloLine = 0; curHoloLine < hologram.getHoloLines().size(); curHoloLine++) {
            PacketContainer metadata = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);

            List<WrappedDataValue> dataValues = List.of(
                    new WrappedDataValue(22, WrappedDataWatcher.Registry.getChatComponentSerializer(), CraftChatMessage.fromStringOrNull(ColorUtil.translateColorCodes(hologram.getHoloLines().get(curHoloLine)))),
                    new WrappedDataValue(14, WrappedDataWatcher.Registry.get(Byte.class), (byte) 3),
                    new WrappedDataValue(24, WrappedDataWatcher.Registry.get(Integer.class), 0),
                    new WrappedDataValue(26, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0)
            );

            metadata.getIntegers().write(0, hologram.getEntityIDs().get(curHoloLine));
            metadata.getDataValueCollectionModifier().write(0, dataValues);

            ProtocolLibrary.getProtocolManager().sendServerPacket(player, metadata);
        }
    }
#

im doing this rn to set the data

#

which can be per-player

wet breach
#

ok time to see what game to play

carmine nacelle
wet breach
#

naw, its not fun to play while drunk

#

think I might go buy battlefield

echo basalt
#

Adapt the metadata a bit

#

and that's your entity class

#

And maybe have a central listener

carmine nacelle
#

🙀

#

whats wrong with mine?

echo basalt
#

bit scattered

wet breach
echo basalt
#

But yeah this is how I use it to make a 3 second speech bubble

echo basalt
#

but you never said a pro made mine either so

wet breach
#

others disagree

echo basalt
#

¯_(ツ)_/¯

#

Sure it's my "day job"

wet breach
#

you don't get to decide when you become a pro 😛

echo basalt
#

more like my night job because I wake up at noon lmao

#

But I wouldn't say i'm an expert

#

well I kind of am

carmine nacelle
#

java programming is ur night job?

#

oof

wet breach
#

I am not an expert, I just know java really well

echo basalt
#

I made plugins like

wet breach
#

XD

echo basalt
#

15 hours a week

#

or lately close to 25 as I'm saving up

#

And that's about it

wet breach
#

7smile7 just knows me as the memory map guy

#

XD

echo basalt
#

7smile7 is a beast

#

only guy I look up to

#

other than my own dad

wet breach
#

yeah he is really good

echo basalt
#

But he's also like

#

1.8x my age

#

And actually knows math

#

unlike my stupid ass

wet breach
#

I know math too XD

echo basalt
#

I failed 8th grade trig

#

Still have to retake that test to this day

wet breach
#

but I will have to say, other then Alex he his my favorite German

echo basalt
#

Alex is germany's most qualified crackhead

wet breach
#

Alex is my favorite for other things but still lmao

echo basalt
#

well not crackhead more like junkie idk mans weird

wet breach
#

he would be more go to person about such things and opinions

#

because odds are he has done it

echo basalt
#

man can fly a plane, help you with your taxes, produce (dubious) music and make plugins

#

Also real estate

wet breach
#

all the while taking insane amounts of things

echo basalt
#

yet fails to build a wardrobe lmao

wet breach
#

lmao

echo basalt
#

Well he did it

#

it was slanted

#

I'm probably known as the "dude that knows it all" maybe

#

idk

#

I'm not known :p

carmine nacelle
#

So why wouldnt this work? @echo basalt

public void spawnHologram(Hologram hologram) {
        if(!(hologram.getHoloLines().size() > 0)) return;
        double currentY = hologram.getHoloLocation().getY();

        for (int curHoloLine = 0; curHoloLine < hologram.getHoloLines().size(); ++curHoloLine) {
            int id = hologram.getHoloID();

            Entity spawnedEntity = Bukkit.getWorld(hologram.getHoloLocation().getWorld().getUID()).spawnEntity(hologram.getHoloLocation(), TEXT_DISPLAY);
            hologram.holoDisplays.add((TextDisplay) spawnedEntity);
wet breach
#

You are known as the guy that hires people

#

and runs a business

echo basalt
#

I mean

#

I haven't hired someone in a while

wet breach
#

yeah don't want to hire me

#

you would have to fire me not soon after

carmine nacelle
#

soon or not soon?

#

did you mean not long?

wet breach
#

don't think it makes a difference

#

fired is fired

echo basalt
#

Like

#

I make plugins

#

and run a 3 person team

#

that's about it

#

Not a big thing

carmine nacelle
#

but u get paid enough for making plugins to pay the bills?

wet breach
#

He does

#

usually

#

until he comes asking for aide from the benefactor

#

which is rarely though

#

Which is good thing because that means he is doing good 🙂

echo basalt
#

in my defense I was getting paid a couple days late

#

and my dad refused to pay for shit he promised

wet breach
#

Lol, yeah that always sucks

echo basalt
#

and people owed me cash

wet breach
#

I think that is what me and Alex are known for, is being benefactors here

echo basalt
#

It's all good now

buoyant viper
#

cant wait 2 get a programmer job

#

idfk when thatll happen but

carmine nacelle
buoyant viper
#

it might

echo basalt
#

pretty sure that MikeTheShadow gave me nitro once

wet breach
#

maybe at first

#

but who knows they can get lucky

wet breach
#

I think between us both you ended up with quite a few months of nitro

carmine nacelle
wet breach
#

then its just hilarious

#

brb, ran out

carmine nacelle
#

this dude aint gonna wake up tomorrow 💀

echo basalt
#

I had 2 months

#

one was yours

wet breach
#

besides I don't need to be up until 6:30pm

#

its only 11:58pm right now

echo basalt
#

ehh

#

6am here

#

not sleepy

#

insomnia go brr

#

I'm running on sparkling water rn

wet breach
#

I drink 3 tall can monsters a day

#

XD

echo basalt
#

I got no caffeine on me right now

carmine nacelle
#

before I get too deep into this, yall think this would work?

 public void setTextDisplayData(Hologram hologram, TextDisplay textDisplay, String displayText) {
        PacketContainer metadata = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA);

        List<WrappedDataValue> dataValues = List.of(
                new WrappedDataValue(22, WrappedDataWatcher.Registry.getChatComponentSerializer(), CraftChatMessage.fromStringOrNull(ColorUtil.translateColorCodes(displayText))),
                new WrappedDataValue(14, WrappedDataWatcher.Registry.get(Byte.class), (byte) 3),
                new WrappedDataValue(24, WrappedDataWatcher.Registry.get(Integer.class), 0),
                new WrappedDataValue(26, WrappedDataWatcher.Registry.get(Byte.class), (byte) 0)
        );

        metadata.getIntegers().write(0, textDisplay.getEntityId());
        metadata.getDataValueCollectionModifier().write(0, dataValues);

        for(UUID viewerUUIDs : hologram.viewers) {
            Player viewerPlayer = Bukkit.getPlayer(viewerUUIDs);

            if(viewerPlayer == null) continue;

            ProtocolLibrary.getProtocolManager().sendServerPacket(viewerPlayer, metadata);
        }
    }

    public void spawnHologram(Hologram hologram) {
        if(!(hologram.getHoloLines().size() > 0)) return;
        double currentY = hologram.getHoloLocation().getY();

        for (int curHoloLine = 0; curHoloLine < hologram.getHoloLines().size(); ++curHoloLine) {
            TextDisplay textDisplay = (TextDisplay) Bukkit.getWorld(hologram.getHoloLocation().getWorld().getUID()).spawnEntity(hologram.getHoloLocation(), TEXT_DISPLAY);
            setTextDisplayData(hologram, textDisplay, hologram.getHoloLines().get(curHoloLine));
            hologram.holoDisplays.add((TextDisplay) textDisplay);

Spawning TextDisplays as normal entities, then setting their data with packets

echo basalt
#

but I've had days where I've chugged 7 red bulls

echo basalt
#

Just make a map

carmine nacelle
#

?

wet breach
#

eeew protocollib

#

should look into just hooking into the network yourself

#

you don't need protocollib for this

#

I think we are about to have a wall of text

carmine nacelle
#

yep..

#

@echo basalt breathe

echo basalt
#
public class HologramTracker {

  private final Map<UUID, Hologram> holograms = new ConcurrentHashMap<>();
  private int entityId = 50000;

  private PacketListener listener = null;

  public void addHologram(UUID id, Hologram hologram) {
    this.holograms.put(id, hologram);
  }

  public void removeHologram(Hologram hologram) {
    hologram.dispose();
    this.holograms.remove(hologram.getUniqueId());
  }

  public Hologram getHologram(UUID hologramId) {
    return this.holograms.get(hologramId);
  }

  public Hologram getHologram(int entityId) {
    for(Hologram hologram : this.holograms.values()) {
      if(hologram.getEntityId() == entityId) {
        return hologram;
      }
    }

    return null;
  }

  public Hologram createHologram(String text) {
    UUID id = UUID.randomUUID();
    Hologram hologram = new Hologram(entityId++, id, text);

    addHologram(hologram);
    return hologram;
  }

  public void registerListener(JavaPlugin plugin) {
    if(this.listener != null) {
      return; // Feel free to throw an exception
    }
  
    ... can't bother rn
}
wet breach
#

lol

echo basalt
#

This will be your tracker

grizzled oasis
#

something to ask, for one of my plugin i need to use a conditions system and handler system for actions someone has any like other plugin that is open source and does something like this?

wet breach
#

going to have to be more specific then that I think

grizzled oasis
carmine nacelle
#

working on simplying my cluster||fudge|| to make papa illusion proud

carmine nacelle
wet breach
#

if so, Alex reminds me of Klaus

#

if you haven't seen it recommend seeing it

carmine nacelle
#

Is there any way around this?

echo basalt
#
public class Hologram {

  private final UUID uuid;
  private final int entityId;
  
  private final Set<UUID> viewers = Sets.newConcurrentHashSet<>();

  private final PacketContainer spawnPacket;
  private final PacketContainer metadataPacket;
  private final PacketContainer removePacket;

  private WrappedChatComponent text;

  public Hologram(UUID uuid, int entityId, String text) {
    this.uuid = uuid;
    this.entityId = entityId;

    this.spawnPacket = prepareSpawnPacket();
    this.metadataPacket = prepareMetadataPacket();
    this.removePacket = prepareRemovePacket();

    setText(text);
  }

  public void setText(String text) {
    this.text = WrappedChatComponent.fromText(text);

    // Update the metadata packet here

    updatePlayers();
  }

  public void addViewer(Player player) {
    this.viewers.add(player.getUniqueId());

    sendPacket(player, spawnPacket);
    sendPacket(player, metadataPacket);
  }

  public void removeViewer(Player player) { // Call this onPlayerQuit unless you like memo leaks
    this.viewers.remove(player.getUniqueId());

    sendPacket(player, removePacket);
  }

  public void updatePlayers() {
    for(UUID viewerId : this.viewers) {
      Player player = Bukkit.getPlayer(viewerId);

      if(player == null) {
        this.viewers.remove(viewerId); // This is a concurrent collection so CMEs wont happen
        continue;
      }

      sendPacket(player, metadataPacket);
    }
  }

  public void dispose() {
    for(UUID viewerId : this.viewers) {
      Player player = Bukkit.getPlayer(viewerId);

      if(player == null) {
        continue;
      }

      sendPacket(player, destroyPacket);
    }

    this.viewers.clear();
  }

  // internal

  private void sendPacket(Player player, PacketContainer packet) {
    // You can do this
  }

  private PacketContainer prepareSpawnPacket() {
    // You can do this
  }

  private PacketContainer prepareMetadataPacket() {
    // You can do this, just init the values
  }

  private PacketContainer prepareRemovePacket() {
    // You can do this too
  }
}
carmine nacelle
#

dear jesus

echo basalt
#

Pretty much all you need

grizzled oasis
echo basalt
echo basalt
#

damn it's day outside

wet breach
echo basalt
#

phone code is something else

grizzled oasis
wet breach
#

naw its fun sometimes, impressive at times

echo basalt
#

I've altered bytecode while waiting at the dentist once

#

on my phone

wet breach
#

lol that is awesome

carmine nacelle
echo basalt
#

And each hologram can have many viewers

carmine nacelle
#

right

echo basalt
#

The tracker's function is to.. track

#

Not to prepare hologram-specific packets

#

Sure the hologram's function represents a hologram but we're don't have a separate player manager that's just a Map<UUID, Set<UUID>> for the sake of simplicity

#

It also makes it easier to destroy holograms

carmine nacelle
#

So the way you would use this, is each individual line would be its own hologram

echo basalt
#

Correct

#

You can then make a HologramChain class that's just something like

carmine nacelle
echo basalt
#

Oh yeah I still forgot to implement location data in the hologram class

#

Anyways the idea is to just have a linkedlist of holograms

#

And a hardcoded offset between each line

#

Top line would be index 0

carmine nacelle
#

The way I was doing it before, id take the size of the "lines" list which contained the strings that I wanted it to say, then did 0.25xcurIndex while looping so it would put 0.25 spacing between each line

grizzled oasis
echo basalt
#

Something like that

echo basalt
#

I've done that at work

#

It's a pain

carmine nacelle
#

So yeah, I do still need some kind of "manager" (or tracker) class to manage spacing and storing the "links" for these

echo basalt
carmine nacelle
#

True, true

grizzled oasis
carmine nacelle
#

What exactly do you mean by "chain"? btw

echo basalt
#

A linkedlist

carmine nacelle
#

oh boy, something I havent used yet 😳

echo basalt
#

It's like an arraylist

#

but instead of using an array and resizing it

#

It uses a Node object

#

That looks a little like

public class Node<T> {

  private final T value;

  private Node next;
  private Node previous;

}
#

And the list itself is just a

public class LinkedList<T> {

  private Node<T> head;
  private Node<T> tail;
  private int size;

}
carmine nacelle
#

what the hellll

echo basalt
#

To add an element you create a new node, add it as tail's next, set tail as its previous and that node is now your new tail

carmine nacelle
#

what would be the advantage of that over a normal arraylist?

echo basalt
#

Add and Remove operations are smooth

#

And the data structure just makes more sense

#

Getting by the index requires iterating up to half the list (shortest path from either head or tail) and it uses more memory

#

But it's a true chain where each link is only aware of what other links it is connected to

#

RIP chat

carmine nacelle
#

lol i had to take a piss

#

im back to ask stupid questions more

grizzled oasis
#

something to ask i have a comparison operator as a string can i translate it to the same i use for coding?
like in the config is written == and inside my code i just can use it

echo basalt
#

sigh

grizzled oasis
echo basalt
#

This should give you an idea