#help-development

1 messages · Page 1258 of 1

slender elbow
#

what is that implying?

sly topaz
#

actually nevermind, I didn't think that one thorough lol

rough drift
#

can you generate chunks async using World#getChunkAt(int, int, boolean) in another thread

sly topaz
#

nope

ancient vapor
kindred sentinel
#

Which event is fired on wither break block?

blazing ocean
#

say I have a string of an interface name, what would be the best way to check whether it's following the """convention""" of prefixing it with an I? Can't just check whether it starts with an I since it could be called something starting with I

(xy: writing a linter rule)

slender elbow
#

check that a) starts with an I, b) the following letter is uppercase?

blazing ocean
#

that is smart yeah

#

did not think of that

slender elbow
#

but afaik I interfaces are not convention in JVM world lol

blazing ocean
#

that's why I said """convention"""

slender elbow
#

that's a .NET thing for the most part

blazing ocean
#

I've seen people use them a lot and hate it

#

so, writing a linter rule

sly topaz
#

either that or EntityChangeBlockEvent

kindred sentinel
blazing ocean
slender elbow
mortal hare
#

weirdo is back 😄

#

lets say im trying to implement IContainer and IMutableContainer. Is it better to implement IMutableContainer and then downcast it to IContainer when returning IContainer from a method as a return type?

or is it better to extend IContainer implementation and implement IMutableContainer methods in a separate extended class, returning appropriate implementation in the use-case?

returningIMutableContainer and then downcasting it to IContainer sounds like less of a hassle in terms of maintaining it, but im not sure if there's any cons of it

mortal hare
remote swallow
#

IAmSteve

robust helm
#

what do i do if my gradle just breaks every few hours after changing something in the build.gradle.kts?

#

i could use maven, but with kotlin it kinda sucks

#

like the whole build file gets read and it complains with different errors, then randomly the next day it works again without any changes

blazing ocean
#

cry

robust helm
#

thought so

robust helm
#

thats what i did for 2 hours yesterday

#
  • deleting all caches
manic delta
#

or click this button

robust helm
#

also did

manic delta
#

how many ram do u have

blazing ocean
#

that's really not related

rough ibex
#

??

manic delta
#

really?

rough ibex
#

Why would that matter

manic delta
#

That happened to me when I had a 2 RAM PC always

rough ibex
blazing ocean
#

"2 ram pc"

rough ibex
#

lol 2 rams

manic delta
#

Now I have my laptop and it doesn't give me any problems

rough ibex
#

haha i have 32 rams

manic delta
#

me 16

rough ibex
#

(I am making fun of your usage of "ram")

robust helm
# rough ibex What do the errors look like

Cannot access script base class 'org.gradle.kotlin.dsl.KotlinBuildScript'. Check your module classpath for missing or conflicting dependencies
this was the last one, but i had others too

#

and i reinstalled a lot

limber apex
#

Hello I'm looking for a person who knows minecraft to make a software related to a launcher (I pay of course) dm

blazing ocean
#

what version are you on

manic delta
#

maybe his intellij is just dumb

robust helm
#

2024.3.4

blazing ocean
#

IJ is not related to gradle

#

what gradle version are you on

echo tangle
#

is the only way to change someone's nametag (the name above their head) hiding their original one and summoning a textdisplay to follow the user

blazing ocean
#

yes

limber apex
blazing ocean
#

not you

limber apex
#

oh okay

manic delta
blazing ocean
#

also not you

undone axleBOT
rough ibex
#

lmao

manic delta
#

why not me

rough ibex
#

because not you

manic delta
#

damn

limber apex
#

oh okay

#

thanks

robust helm
#

i might be going insane

rough ibex
#

Happens

robust helm
#

but i 99% sure that tomorrow morning ill have the same problem

manic delta
#

probably

robust helm
#

and now my dependency is still not loaded wth

blazing ocean
#

again, what gradle version are you using

robust helm
#

oh didnt see your msg. 8.8

blazing ocean
#

that's ancient

#

update to 8.13

robust helm
#

just change the gradle-wrapper.properties file right?

blazing ocean
#
./gradlew wrapper --gradle-version 8.13
./gradlew wrapper
robust helm
#

oh ty

umbral ridge
robust helm
#

it flipping crashes after invalidating caches

#

like after restarting

blazing ocean
#

okay lemme make something sure real quick

#

run ./gradlew tasks and lmk if it errors or prints the task list

robust helm
blazing ocean
#

so it's an IJ issue

robust helm
#

maybe i should switch ide

blazing ocean
#

embrace neovim

robust helm
#

cuz these issues arent a rarity

blazing ocean
#

embrace not having a working LSP

robust helm
#

nvim has lsp

blazing ocean
#

embrace there being zero good kotlin LSPs

robust helm
#

Fuck

blazing ocean
#

you can try fleet but it just uses IJ as a backend

robust helm
#

hmm

#

scala instead of kotlin?

echo tangle
blazing ocean
#

add it as a passenger

blazing ocean
echo tangle
robust helm
#

or i could js give up java with all its crap

robust helm
rough ibex
#

youre blaming java for kotlin?

robust helm
#

blaming the java world

rough ibex
#

does java gradle not work either

robust helm
#

oh i meant to say give up everything with jvm

robust helm
#

well anyways. thx everyone

#

ill probably wait for some updates, god or learn java so i won't have to deal with kotlin/intellij

manic delta
hybrid spoke
robust helm
#

yea maybe i should move to asia

#

and farm rice or smth

mortal hare
#

is there any data structure in java which is like linkedlist, but retains its index after some element in the middle of list gets removed.

here's my take on naive implementation of such data structure

class PackedArrayList<T> implements List<T> {
  private final Deque<Integer> removedIds = new ArrayDeque<>();
  private final ArrayList<T> list;

  public PackedList(ArrayList<T> list) {
    this.list = list;
    
  }

  public void remove(int index) {
    if (this.list.get(index) != null) {
      this.list.set(index, null);
      removedIds.push(index);
    }
  }

  public void add(T element) {
    if (!removedIds.isEmpty()) {
      this.list.set(removeIds.pop(), removedIds);
      return;
    }
    this.list.add(element);
  }
  // im not gonna implement whole List<> in Discord.. duh..
}
thorn isle
#

linked int -> object hash map

#

that's not really a list at that point however

mortal hare
#

what i want is to reuse ids from the elements which were removed

#

effectively reusing space that removed object took

#

without resizing arrays and for previous objects to retain that id

thorn isle
#

might as well use an array list rather than a linked list at that point if the goal is to avoid shifting elements on removal

#

a common approach to this is to shift the tail element into the hole caused by the removal; but this of course means that the id of that element changes and needs to be updated in the associated data structures

#

generally in java land a list is expected to become smaller (size() becomes smaller) on successful remove, and the last index of a list is expected to be list.size()-1

#

so what you are initially describing isn't really a list as understood in this ecosystem and probably shouldn't implement List

#

you are free to create an impl like that though of course, just, don't expect it to work with anything that takes a (mutable) List

mortal hare
#

for example:

0: Object
1: null
2: Object

PackedList#add() places element in index: 1
PackedList#remove(2) set the index: 2 to null and tracks removed id for use inside add() method

mortal hare
thorn isle
#

this would be achieved by set(1, null)

#

which is different from remove; remove is expected to either fail (with an exception) or change the size of the list

#

and if the size of the list changes, then the last index in the list should also change

#

set simply replaces the element at the index with another element, in this case null

mortal hare
#

what's stopping you to count length of the list by increasing and decreasing size field on add() remove() after if guards

#

basically virtual "size"

thorn isle
#

the issue is that you would end up with a list of size 2 but the last element would be at index 2, which is larger than 2-1

#

i.e. to get the last element in the list, you would have to do list.get(2)

#

but list.get(2) is expected to explode, because 2 >= list.size()

#

so your size would have to remain 3

thorn isle
#

which then means list.remove(1) didn't work as expected; the list didn't become any smaller

#

tldr use list.set(index, null)

#

this won't remove anything from the list but will substitute the element in that index with another

mortal hare
#

i guess .get() wouldnt work in remove()

thorn isle
#

well yeah but what that is doing is set, not remove

#

so you can't implement remove to do that

#

that's breaking the list contract

#

so like i said at first, you can do that, but don't implement List

echo tangle
blazing ocean
#

add a translation

thorn isle
#

add a translation offset to the transformation

#

will look kind of funny if it also billboards vertically however

#

since it'll pivot around the player's head rather than itself

manic delta
#

the old method was placing a named armorstand right?

thorn isle
#

yeah, and the old method of moving it up/down was to mount a bunch of them in a pile

mortal hare
# thorn isle well yeah but what that is doing is set, not remove

there's no constraints on javadoc that would mention that List<>.remove() implementation should effectively remove element from the backing collection/array. it mentions that remove() should affect size(), but you can calculate that by adding or decreasing size private field inside PackedList

thorn isle
#

you can do whatever you want with it but don't expect it to work when plugged into anything that expects a mutable list

#

do you really need it to implement List specifically?

echo tangle
thorn isle
#

a more appropriate data type would be an int -> object map

#

which can still be implemented with e.g. an array

#

alternatively you can use a regular old array list and just call set(idx, null) instead of remove(idx)

mortal hare
#

you can implement PacketList#size() by list.size() - removeIds.size()

thorn isle
#

the index of the last element is 2, yes?

#

and list.size() - removeIds.size() returns 2, yes?

mortal hare
#

yes

thorn isle
#

so PackedList::size returns 2

#

but the last index is 2

#

this is illegal

#

that is, to get that last Object, you would have to call get(2)

#

which according to the specification explodes because that exceeds the list's size

#

you can make it not explode, but everyone will expect it to explode

#

e.g. compilers/linters will emit warnings about "index out of bounds exception"

#
    /**
     * Removes the element at the specified position in this list (optional
     * operation).  Shifts any subsequent elements to the left (subtracts one
     * from their indices).  Returns the element that was removed from the
     * list.
     *
     * @param index the index of the element to be removed
     * @return the element previously at the specified position
     * @throws UnsupportedOperationException if the {@code remove} operation
     *         is not supported by this list
     * @throws IndexOutOfBoundsException if the index is out of range
     *         ({@code index < 0 || index >= size()})
     */
    E remove(int index);

also, that the subsequent elements shift down on (successful) remove is specified in the contract

mortal hare
#

ok

#

yeah, this sucks

#

but its ok

thorn isle
#

just don't use a List

#

because it isn't one

mortal hare
#

well it is, just a nonstandard one

#

you can probably get away with get() by doing linear search by skipping null values

#

but this javadoc comment ends this debate 😄

thorn isle
#

it can still be e.g. a SequencedCollection or Iterable or whatever interface you actually might need that does describe what it is, but List isn't one of them

thorn isle
#

because then you can get the last object with get(1) as the null is skipped

#

and hence the subsequent elements' indices were indeed shifted down by 1; 2 -> 1

#

index doesn't have to correspond to where the element physically is in the data structure, it's purely an abstract ordering thing

#

for example in an ArrayDeque, the start and end (0, size()-1) continuously shift in the underlying array

mortal hare
#

Yea

thorn isle
#

removing the first element in the deque doesn't actually physically shift the subsequent elements down; it just moves the starting index up

#

and the end index can have a lower physical address than the start index because it "rolls over" from the end of the array back to the start

mortal hare
#

But isnt this getting back to square one because the whole point this was to have nonshifting indices lol

abstract totem
#
You are running the latest version```

I just updated and am still facing the same issue

I have found a "fix" involving NMS but it is quite messy
kind hatch
#

?whereami

lime stump
#

Can I make an invisible entity have a glowing outline?
Like something like this

entity.setVisible(false)
entity.setGlowing(true)```

will this entity be see-through but be visible by it's glowing outline?
Because I'm trying this on an item-frame and it does not have a glowing outline. Although I could be doing this wrong, because for a while, it was the item-frame that was invisible, but a glowing outline would be applied to the item displayed inside the item-frame.
abstract totem
# kind hatch ?whereami

i genuienly didint think there would be any differences that major, regardless im trying with a spigot jar now

thorn isle
undone axleBOT
kind hatch
lime stump
#

I wanna know if I'm doing something wrong or if the item frame being set to invisible negates the glowing effect

kind hatch
blazing ocean
#

no need to be rude about it

blazing ocean
#

and also, crossposting in spigot and paper at the same time is crazy

kind hatch
blazing ocean
#

tad bit jank

abstract totem
young knoll
#

That’s a lot of flags

echo tangle
#

would the only way to fix textdisplays with translations rotating around the origin (for nametags) to spawn a clientside textdisplay for each player and rotate it based on said player's pitch?

thorn isle
#

i would just disable vertical billboarding so it only faces the camera horizontally

#

it's not exactly perfect i suppose but it'll be a lot easier than the alternatives

sly topaz
#

Doing billboarding manually when it is a feature of display entities is a waste and doesn’t work as well when latency comes into play

echo tangle
sly topaz
echo tangle
#

to make the text display be in the same position as a regular nametag, you need to translate it up, which then makes it rotate around the origin so if you are looking at it from above it's off to the side

sly topaz
#

Ah I see what you mean now, in that case, your only option is to do billboarding manually however I wouldn’t recommend it. Just disabling vertical billboarding sounds like a good compromise to me but I don’t know your setup so I wouldn’t be able to say how necessary it is

echo tangle
short pilot
#

wsg

young knoll
#

Can you use another entity to offset it instead

#

Maybe an interaction entity

echo tangle
earnest girder
#

what do I use instead of the deprecated AnvilInventory? I need to set the cost text and stuff

chrome beacon
#

If you're using Intellij you can get them in your IDE by opening the maven/gradle tab and click the little download icon and choosing sources and documentation

#

Alternatively use the web version

#

?jd-s

undone axleBOT
echo tangle
young knoll
#

I mean interaction entities are invisible

#

So are display entities with nothing set to display

echo tangle
#

you can't use addpassenger() on those

eternal oxide
#

You should be able to. ALL Entities support passengers

echo tangle
#

you're right, but i don't think any of the invisible entities are able to be scaled so that the text display could be higher

eternal oxide
#

all display types can be translated

thorn isle
#

the translation doesn't affect where the passenger goes

#

you're stuck with an invisible scaled armorstand or something

#

...or make it not billboard vertically

thorn isle
#

that's the easiest solution with the least maintenance baggage

young knoll
#

Does the size of an interaction entity affect the passenger position?

thorn isle
#

what's an interaction entity?

echo tangle
#

you can use air as a projectile, but it still wouldn't be scalable

thorn isle
#

last i asked this someone told me they're invisible armor stands

echo tangle
thorn isle
#

with them you have 3 possible sizes you can use

#

large, small, and marker

#

marker is very small

#

iirc you need half a dozen to make up a row of text worth of vertical distance

#

putting them together with muh combinatorics will get you somewhere close enough

#

alternatively, setting teleport interpolation to 1 tick and manually moving the position of the text displays every tick to match the player's should look correct for other players; then use the hideEntity api to hide it from the player themselves

#

alternatively, use horizontal billboarding only

#

these are your 3 options basically

umbral ridge
young knoll
#

And can have a custom width and height

thorn isle
#

what's the entity type?

#

EntityType.INTERACTION huh so there is a specific entity type for them, last i was told they're invisible armor stands

echo tangle
# thorn isle marker is very small

how small are they? if i stack a couple small armor stands, the text display is pushed up, but with markers it doesn't move up at all despite how many i put down

kind hatch
thorn isle
#

yes but i asked like 3 days ago or something and was told it's an armor stand under the hood

young knoll
#

Markers can’t be used with passengers

#

Because they don’t get sent to clients

kind hatch
young knoll
#

Or do you mean armor stands with the marker flag

echo tangle
#

armor stands with the marker flag

thorn isle
#

it most likely wasn't true

young knoll
#

They have a 0 size bounding box

#

So they don’t add any offset

thorn isle
#

i don't think they added interaction entities in the past 3 days

echo tangle
#

oh, bruh

kind hatch
thorn isle
#

i vaguely remember someone saying that a marker armor stand will still lift up its passenger by some small amount

#

it's possible they were wrong i suppose, they definitely have zero volume hitboxes

#

other nonsense has been attempted over the years including invisible silverfish, dropped air items, experience orbs, projectiles, what have you

echo tangle
thorn isle
#

i'm not sure if it works with a text display directly since they can't have velocity

#

try mounting it on an invisible armor stand or other physics capable entity

#

the reason why it looks janky is because the player and the display physics aren't quite in sync, presumably because one has velocity and the other doesn't

echo tangle
thorn isle
#

sort of yes but that won't affect where the passenger sits i don't think

thorn isle
#

yeah you've got to put it on an armor stand

echo tangle
thorn isle
#

and then apply velocity/teleports to the armor stand

#

i'm not saying to mount the armorstand on the player

#

the armorstand exists purely so the client can tick velocity + physics on it so the text display that's mounted on it doesn't desync with the player

echo tangle
#

ohh, you mean mount the text display on the armor stand to sync. so i would just set the velocity of the armor to 0, and teleport it every tick to the player?

thorn isle
#

you'll want to copy the player's velocity to the armor stand rather than setting it to 0, but yes that's the idea

#

then every tick teleport it to some offset from the player (to get the height right)

#

e.g. offset by +1.9 on the y axis or whatever magic number looks right

echo tangle
#

oh, alright, i'll try that thank you!

wide viper
#

is there any way to remove components from items like consumable component from food?

eternal night
#

no, you'll need NMS || or paper api ||

wide viper
#

oh unfortunate, thank you

blazing ocean
#

or WHAT api!?

eternal night
#

idk what you are referring to

echo tangle
earnest girder
#

InventoryOpenEvent:java AnvilView view = (AnvilView) event.getView(); this is causing this error:java.lang.ClassCastException: class org.bukkit.craftbukkit.v1_21_R3.inventory.CraftContainer$1 cannot be cast to class org.bukkit.inventory.view.AnvilView (org.bukkit.craftbukkit.v1_21_R3.inventory.CraftContainer$1 and org.bukkit.inventory.view.AnvilView are in unnamed module of loader java.net.URLClassLoader @77a567e1)What am I doing wrong?

kind hatch
#

You can dismount the entity, teleport the main entity to where ever you need it, then remount the passenger.

chrome beacon
earnest girder
#

is event.getView() not the right way?

echo basalt
#

any OG aware of why this same exact code causes the horizontal slices to be "inverted" on 1.8?

#

Same exact code, happens consistently across all images and restarts

#

Facing the same exact orientation and this happens at the same coordinate

#

I've also gone ahead and checked, the coordinate direction system is the same, yaw 0 is when facing south and that's +Z

#

Might have to do with what direction it faces but even then it's a bit weird

#

because this makes sense for 1.9+ where item frames can look up/down but not on 1.8? not sure, will mess around with

slender elbow
young knoll
#

Ah yeah that’d do it

echo basalt
#

hm

#

how is itemframe rotation set on 1.8?

#

because passing in that short or whatever on the spawn packet seems to do absolutely nothing

#

and the image could actally work if we rotated every item frame to face south instead of north

#

please tell me it's not yaw/pitch based

#

ah shit I need to look at obfuscated 1.8 code

#

been years since I've done this I feel old

slender elbow
#

my condolences

echo basalt
#

ah shit CraftEntity#getEntity is ass

#

@alpine urchin I suspect this is a packetevents bug

#

the spawn entity packet's straight up ignoring the data

#

which it does use in later versions.. so why not the older one

#

might need to set a velocity

fierce salmon
#

I am making a plugin for my server that times a parkour course and lists the top 10 times on a leaderboard. Would it be faster to store the times in a yml file within the plugin folder or should I use a MySQL database to store the times?

young knoll
#

I mean, you can use both async which eliminates most of the concern

#

So it doesn’t really matter

fierce salmon
#

MySQL would be more work but it would look cooler imo

#

I might just do MySQL

ivory sleet
#

The nice thing w mysql is that u can sql to query top 10

fierce salmon
#

true

worldly ingot
#

Issue with YAML is that you have to load the whole configuration into memory

#

Then reading and writing becomes slower and slower the more entries you have

fierce salmon
#

Right

worldly ingot
#

Bare minimum you should be using SQLite, MySQL would just be a nice optional thing if you want a remote database

fierce salmon
#

after 1000 entries it'll be pretty slow im guessing

worldly ingot
#

Depends on your system but either way it has to parse through 1,000 lines and validate it as YAML, :p

#

A proper database is just better suited for lots of repetitive structured data

kind coral
#

I have a question regarding the premium resources, for the past year i have been developing a plugin mostly aimed at prison servers, which is in really high demand, my only problem is with Spigot, they don't directly allow Obfuscating your code, (because i want to publish my resource on multiple marketplaces), so i was left with the decision of publishing first on other platforms and then some time later on spigot, but with an older version,

this is because i really don't want my plugin pirated on the first week and dropping my sales, considering i have worked on it a ton.

is there any other way? like getting an authorization to use some special obfuscation tools? I am planning on using Zelix Klassmaster,

TL;DR
I want to obfuscate my code, spigot wont allow it, i publish my resource on other platforms (which allow obfuscation) and delay as long as i can updates on spigotmc (or i get authorization to use obfuscation tools)

echo basalt
#

something like jetbrains exposed

worldly ingot
#

I mean there's jOOQ if you really want

#

I don't know how abstract it is to different DB engines though

echo basalt
#

exposed works for different db engines

#

I should make a java port some day

#

but it's such a monumental task

#

eh jooq looks like a java exposed thing yeah

wet breach
#

MC is a prime example of that

#

MC is even to this day is obfuscated and despite that custom server implementations have still come about regardless

#

and consistently updated

left jay
#

ok i have an odd error going on
so i have this method in a class in a plugin that creates a key value pair in an items meta, and a method that checks for the value of that pair.

in another plugin that depends on the first one, i have a method that does something based on the value of that key-value pair. however when i try to do this via the method from the first plugin, this plugin doesn't regonize that the key-value pair exists at all in the items pdc, but the original plugin does.

im wondering if theres anyway item metadata could leak in between plugins or if pdc changes can only be regonized by the original plugin.

remote swallow
#

Is it the same key with the same namespace

sly topaz
#

and that returns a view

wet breach
remote swallow
#

Could also just use fromString

worldly ingot
#

Or, more abstractly, have a method that doesn't require a key at all, just a utility method that hides the key as an implementation detail

remote swallow
#

That too

wet breach
#

I like Choco's suggestion better, but Epic's method should work too

echo basalt
#

if I'm doing a core plugin and let's say a secondary plugin I just use the core plugin for all the pdc

#

(I have pdc wrappers that just do that for me)

#

But yeah your issue is that while the string keys are the same, their namespaces are different

#

if you don't care just use minecraft's namespace for everything

gaunt pollen
#

Good resource for learning nms code?

#

:D

echo basalt
#

uh

#

Just run mappings on it and explore whatever

#

I wrote a guide forever ago but it was really superficial

#

Bit hard to teach someone on how to navigate a codebase

drowsy helm
gaunt pollen
#

Ic

#

Very new to nms so I'm pretty much clueless

echo basalt
#

I'm in bed rn thinking about how I'd make an entire video series around different nms concepts

drowsy helm
gaunt pollen
#

Hm... Right now I'm relearning all the prerequisites so that I can start speedrunning my plugin.
But a few years back, I remember I was working on a player tag plugin where I wanted to set the player tag blue colored for only the red team and vice versa. I think my only option was playing with nms code back then, but I don't quite remember the specifics. Sorry, it's a bit vague.

drowsy helm
#

It’s sort of just a matter of finding and sending the correct packet

#

And sometimes intercepting a packet with a listener, but for that I would recommend a library like PacketEvents

gaunt pollen
#

During my break from bukkit, I had to deal with datagram packets while I was working on a game server in java 🤢
So maybe I won't fully be clueless while dealing with nms this time

gaunt pollen
#

I'm a bit confused on where to start

#

Do you have any starting point recommendation?

#

For now I'd say particles

drowsy helm
#

Sec I’ll get some links

gaunt pollen
#

oh right nms is veery version dependent

drowsy helm
#

The wiki might be a lil outdated for 1.21.5 but should be mostly same. I usually just Ctrl-f keywords im looking for and can usually find the packet I want

#

The problem with the wiki is that the names they give for packets usually dont match with the spigot names

earnest girder
minor otter
#

In order to bypass a shield (blocking) I check if the player is blocking on entitydamagentity then player.damage, however this retriggers the event and that can lead to some issues so instead I can change the player health and play a sound but knockback/armor and damage reduction is lost unless I simulate it. Is there a more clean way to do this?

#

I could also add a cooldown to the shield to prevent the event from constantly re triggering but that defeats the purpose of the system im trying to make

worldly ice
#

i believe you can do something with damage causes to remove the blocking from a shield

#

damage modifiers*

#

iirc it's deprecated, but there's no other alternative besides what you said

worldly ice
#

if not you could flag the player before you apply the damage, and in the event handler just do an early return if the damaged player is flagged

cursive kite
#

What sound are people using for double jump I cant figure it out

#

its like a launching sound

minor otter
#

Thanks

minor otter
cursive kite
#

I thought it was another

#

There is one that sounds a bit more like something launching

kind coral
warm mica
kind coral
#

since its the full resource and obfuscation doesn't do the job 100%

thorn isle
#

nothing will, even if you load them in over https from a remote server owned by you and they never touch the user's disk, someone is just going to dump them from memory, put them in a jar, and upload them on some black market site

chrome beacon
#

Only way to get around it is to host the servers yourself

#

And not let users choose what to install

thorn isle
#

all it really achieves is making it higher-hanging fruit (more money for the person cracking it; paradoxically more demand for it to be cracked) and making your end users's lives worse for relying on your remote server and licensing and not getting legible stack traces etc.

chrome beacon
#

Some crackers might even see it as a fun challenge

#

just cracking it to see if they could

thorn isle
#

tldr bake in a license number or something and make it difficult to identify & remove, and if you see it being leaked, pursue legal action with the buyer that license is associated with

#

crackers generally are too dumb to notice and/or won't give a shit about the baked in license number

chrome beacon
#

license can be replaced

#

but yeah as long as it's unique ig it's a good enough identifier

thorn isle
#

they can, but that assumes the cracker knows its there and knows how and cares to

gaunt vortex
#

hi i am making anticheat and i use ProtocolLibrary. i dont know where is some documentation on packets and how to read data from the packets.

gaunt vortex
#

PacketType.Play.Client.GROUND i want to get data from this packet

thorn isle
#

no clue what the actual name of that packet is

#

what data does it have?

chrome beacon
#

If this is your first time working with packets I do not recommend making an anticheat

#

especially so if you need us to spoon you how to read that

gaunt vortex
gaunt vortex
chrome beacon
#

I was mainly talking about spigot serverside packets

gaunt vortex
#

i think i got it working. i only needed to use POSITION_LOOK packet type

nocturne mirage
#

I have an texture pack error someone who can help i will pay!!!

chrome beacon
smoky anchor
nocturne mirage
#

Im sorry guys

wet breach
# kind coral i mean it would make the work totally harder, since i have a license system and ...

just like what is done with MC, all it takes is to just replace the classes and methods involved with your so called licensing. And it isn't really that much effort to do it. Also you wouldn't even need to deobfuscate to do this either. Again, we have minecraft which contains hundreds of classes and it stopped no one from deobfuscating it and making implementations, why do you think your small plugin is any different?

left jay
rough drift
#
final var mapStack = new ItemStack(Material.MAP);
final var mapMeta = (MapMeta) mapStack.getItemMeta();
assert mapMeta != null;
mapMeta.setMapView(view);
mapStack.setItemMeta(mapMeta);

itemFrame.setItem(mapStack);
aused by: java.lang.ClassCastException: class org.bukkit.craftbukkit.v1_21_R4.inventory.CraftMetaItem cannot be cast to class org.bukkit.inventory.meta.MapMeta

Am I forgetting how to make map items?

#

ignore

#

got the wrong material

wet breach
#

good news what you are wanting to do is possible

rough drift
#

yeah realized .6 seconds after posting

chrome beacon
#

Happens every time 💀

rough drift
#

there is a teeny tiny magenta pixel

#

some more magenta

glossy laurel
#

Not necessarily spigot related, but I want to create a single thread which would handle the code of a method that gets called. How would I approach this?

blazing ocean
#
new Thread(() -> {
  // ...
}).start();

?

thorn isle
#

most nebulous question challenge (impossible)

warm mica
slender elbow
#
Executors.newSingleThreadExecutor().execute(() -> {
  // ...
});

like this, yes?

#

Clueless

eternal night
slender elbow
#

thanx bb

sly topaz
#

note that this just creates an inventory view, you still have to open it yourself with HumanEntity#openInventory(InventoryView)

#

that way you can take an inventory view and place items before opening it though, which is nice

glossy laurel
sly topaz
#

because what you're describing seems like a solution to a leading problem rather than the actual thing you're trying to solve

glossy laurel
sly topaz
glossy laurel
sly topaz
slender elbow
#

mine crypto, ofc

glossy laurel
#

^

#

Jk, lines to put on scoreboard

sly topaz
#

putting lines in a scoreboard can't be done asynchronously, at least not with the API

glossy laurel
#

Yeah im calculating them

#

Async

blazing ocean
#

then use the async scheduler

sly topaz
#

ah so you mean the strings that go into them are calculated asynchronously

sly topaz
#

you could use a CompletableFuture#supplyAsync then do thenAcceptAsync with BukkitScheduler#runTask as Executor

sly topaz
glossy laurel
blazing ocean
sly topaz
#
public static final Executor MAIN_THREAD_EXECUTOR = task -> Bukkit.getScheduler().runTask(YourPlugin.instance(), task);
CompletableFuture.supplyAsync(() -> {
  /* Calculate scoreboard lines */
}).thenAcceptAsync(lines -> {
  /* set scoreboard lines */
}, MAIN_THREAD_EXECUTOR);
glossy laurel
glossy laurel
#

But its secretly the main thread?

#

Xd

sly topaz
blazing ocean
#

heh I just use coroutines run

slender elbow
#

yet another day of the word "async" being misinterpreted by people in the spigot ecosystem

sly topaz
#

I think I am having a dejavu about this topic lol

sly topaz
# glossy laurel Okay so it thinks that it accepts async

in this case thenAcceptAsync is refering to itself being asynchronous from the previous step in the future, not necessarily from the main thread, supplyAsync is asynchronous to the main thread and so the reverse is the same for thenAcceptAsync

slender elbow
#

"but async means not on the main thread, huh?"

thorn isle
#

isn't there a BukkitScheduler::getMainThreadExecutor(Plugin) specifically for this?

wet breach
glossy laurel
wet breach
#

but you are correct nonetheless about it

slender elbow
#

papir

blazing ocean
#

papièr

jagged thicket
#

paper sex

worthy yarrow
#

I also figure in this example I could have used a FixedMetadataValue but other than that not sure if it really matters

echo basalt
#

pdc when

sly topaz
worthy yarrow
#

I literally just saw entities have pdc smh

sly topaz
#

it is a broad statement which doesn't really hold value to all scenarios but it certainly can happen

sly topaz
worthy yarrow
#

I mean pdc imo is easier to manage, although I would assume the pdc is cleared when the entity dies no?

thorn isle
#

i doubt it's cleared but the entity reference definitely becomes unreachable

#

so unless you're referencing it somewhere yourself it's as good as cleared

sly topaz
#

it is most likely cleared though

slate siren
#

hey guys how can I open a sign in front of the player for input?

thorn isle
#

i think the mob just gets marked as invalid and dead and little else is done on its data

sly topaz
#

destructors get called when an entity dies, I don't assume they don't clear nbt on purpose

wet breach
sly topaz
worthy yarrow
#

It just feels weird mapping entities and holding them from spawn -> death

sly topaz
#

I don't really see what's wrong about it

#

most plugins before PDC just used hashmaps which they dumped into yaml or whatever

thorn isle
#

i can't find it being cleared anywhere

#

the reference on CraftEntity isn't a weakref either

sly topaz
worthy yarrow
#

I suppose my eventual use case would turn into a sort of mob stacking system, so it's not really even an issue I'd only be mapping a single entity anyway... I think

#

A single entity in the sense of one per stack as it were

thorn isle
#

i'm fairly sure the entity data stays available indefinitely (as long as it isn't gc'd, i.e. you're referencing it) but you can't do certain things like teleport it or use its pathfinder

sly topaz
#

PDC sounds fine for that, as long as you don't need mob stacking data offline for whatever reason

thorn isle
#

but like all of this is much besides the point; you probably shouldn't be using the entity pdc if you need to access the data beyond the entity's lifecycle

worthy yarrow
#

Yeah fair

sly topaz
#

it's often hard to gauge that as when you expand whatever you are making, you do end up needing that data offline lol

#

be it for migrations, or other unrelated things

thorn isle
#

yeah, this is why i kind of dislike the pdc

blazing ocean
#

hi kat

sly topaz
#

and Spigot doesn't offer any access to DFU so it isn't like you can just make a datafixer when it comes to data migration

thorn isle
#

there is also no good way to clear out data when your plugin is "uninstalled", which becomes an issue for players where inactive pdc entries pile up over time

#

basically every single time i've used the pdc on players especially i've had to migrate to something better later on

#

it's good on blocks though

worthy yarrow
#

There's no way to directly clear all pdc entries is there

sly topaz
#

yeah, players are good example of a place where PDC is just the lazy solution, a database always end up being the final form for whatever data you're holding

worthy yarrow
blazing ocean
#

of one container? sure

#

of all? no

worthy yarrow
#

I would want to clear them all

#

so rip to that

manic delta
#

javier chambea

sly topaz
blazing ocean
#

yea

sly topaz
thorn isle
#

i suspect it's kind of intentional, since you really can't account for what other plugins have stored on it or know whether it should be deleted or not

manic delta
#

agarra la pala

worthy yarrow
#

I really don't think I'll ever use the data offline, I think my only goal would be to stack mobs and even then I don't really wanna deal with recreating stacks on restarts and what not

thorn isle
#

i could maybe see a clear(Plugin) method that clears all the key-values where the key namespace belongs to the given plugin

sly topaz
#

that sounds reasonable, free PR also

blazing ocean
#

doesn't that like involve like, looping over all entities and tile entities that exist in all worlds

thorn isle
#

it'd just be for the single pdc

blazing ocean
#

oh right

manic delta
#

what if pdc is the friend we made on the way

thorn isle
#

i don't think there is any sane way of clearing them all in all the world

blazing ocean
#

yeah exactly

thorn isle
#

except maybe to associate a timestamp for each pdc entry and then store "deletion rules" somewhere in the server internals forever on clear, that get iterated through on pdc load and delete matching entries

sly topaz
thorn isle
#

i.e. entries with that key and a timestamp older than when the clear was issued

blazing ocean
#

now do that for all tile entities

thorn isle
#

yeah this'd be for tiles and entities that you can't realistically iterate over in one go

#

i mean you can but you really don't want to and god knows how long it'd take for large maps

sly topaz
#

at that point it's just better to manually parse the region files

blazing ocean
#

proceeds to block the main thread for a minute

thorn isle
#

the downside then is that now you have an indefinitely piling up list of deletion rules that all have to be checked each time any tile/entity loads

#

so it isn't really feasible either

wet breach
#

I have never been a fan of saving data directly into the world files though

sly topaz
#

yeah, it just kinda sucks it has to be that way, since it often becomes too late when you realize you could've done a better job at keeping track of the data

wet breach
#

in this manner clearing out old plugin data in the world is a matter of clearing a directory

thorn isle
#

sounds roughly like what we already do but with a tighter integration into the api

#

wouldn't mind having that to be honest

sly topaz
#

it would be nice but I doubt Spigot would favor such a thing, also taking into account how much of a mediocre storage format region files are anyway

#

but one can dream

thorn isle
#

it could be abstracted quite far to not be limited to region files i suppose

sly topaz
#

inb4 PDC just ends up being backed by a sqlite database with a table per plugin

thorn isle
#

well yeah that's how it'd end up

#

e.g. imagine if PersistentDataType also had a, say, Z load(UUID) and a void save(UUID, Z) and the default impl for them would be to dump the data in the nbt

#

but they could be overridden to, say, query a database

#

they would then have to be called before the chunk containing the pdc holder is actually added to the world, so as to not block the main thread

sly topaz
#

it's a nice thought experiment though I believe it'd take a bit too many NMS patches for it to be considered a worthy undertaking

thorn isle
#

myeah

#

iirc paper recently-ish had a pr for async chunk preload event that can be used for this, without having to mess with pdc types

#

the idea is that you block the event and do your db queries async, and once it's all done, the chunk gets popped into the world with your data in it

sly topaz
#

I do wonder if that'd work at all on spigot given how differently the platforms handle chunk loading lol

thorn isle
#

i think its somewhat async in the mojang server already but i'm not sure

slender elbow
#

on vanilla & spigot chunk loading is async but the server stops ticking until the chunk is loaded anyway

thorn isle
#

spottedleaf has been tearing everything apart with massive diffs rewriting chunks and light and everything else so i can't really tell how it works anymore

sly topaz
#

I mean, it's just moonrise made into a patch in the end so ultimately you'd have a better picture by looking at the mod

#

it's still hard to grasp if you don't already understand vanilla's chunk loading system and it isn't like anyone has made much effort into explaining it

#

I do hope it doesn't end like Aikar's changes if anything lol

thorn isle
#

the patch is borderline illegible because there are no imports and everything is ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData.someNmsMethod$someMoonRiseOverloadWithReallyLongName

blazing ocean
#

you forgot $moonriseNmsMethodName0_moonrise

sly topaz
#

yeah, every time I find myself digging paper source, I just stop whenever I see any relation to moonrise as the decompiled code is just shit to read

#

but it is decompiled code so it is what it is

thorn isle
#

it isn't even decompiled, it's the actual patched & mojmapped source

#

they just avoid imports because of diff conflicts

#

so everything is always fully qualified

#

ironically if it were decompiled the decompiler would import it and use the short class name

#

so it might be more legible after compilation+decompilation

#

which is fucking 🤡 but here we are

jagged thicket
#

moonrise will be so fkn hard to maintain if it was not mixin first

remote swallow
#

you do realise moonrise was used in paper before it was called moonrise

jagged thicket
#

its not good to know the history too much

blazing ocean
#

what

slender elbow
#

it even had a history before it was added to Paper!

jagged thicket
# eternal night What

According my understanding of moonrise, it is currently a fabric mod which is then ported into paper

eternal night
#

Yes but like, updating it in paper would not be more difficult than mixins

blazing ocean
#

if anything mixins are harder / more annoying to update

remote swallow
#

"Moonrise" was in tunity first then moved to paper then moved to a mod

echo basalt
#

moonrise my beloved

#

lets us do async entity lookups without blowing up the server

#

really useful for packet manipulation

thorn isle
#

and block lookups

echo basalt
#

is there seriously no good method of detecting when an item is "put in a chest"

#

I have to do all this BS emulation

sly topaz
#

are the inventory events not enough? What do you need to do emulation for?

echo basalt
#

I need to emulate how the chest behaves to figure out the before and after state

#

events are enough but it's a pain in the ass to do this

sly topaz
#

there is no before and after state in a chest though lol, let me check the code ig

thorn isle
#

i don't know what you're doing but if it's a gui, i've found implementing them through nms to be much easier, since that gives you access to oop style Menu and Slot objects, and the server internals will actually ask your Slot's whether something can be taken from/placed in them, rather than you having to emulate the 100 different click types yourself

echo basalt
#

it's literally just a quest where you need to put an item in a chest

sly topaz
weak wasp
#

That's only checking if players put something in a chest. What about hoppers and minecarts as well?

thorn isle
#

the trivial way of doing it would be to scan the inventory before and after each interaction, but then there exists an edge case where two players could insert things in the same tick and you couldn't tell which one inserted what

sly topaz
#

just listening to the inventory click event and checking whether the item they clicked ended up in the chest view should be enough

echo basalt
#

but the quest is literally "put your ball in this chest"

thorn isle
#

shift clicks and such make that nontrivial

echo basalt
#

provide a context object?

#

saying like

thorn isle
#

since whether something ends up somewhere is completely up to the click type and inventory state

echo basalt
#

basically a diff of what changed

sly topaz
#

too bad InventoryMoveItemEvent doesn't quite work for this concept

echo basalt
#

item went from slot A to slots B, C and E

thorn isle
#

reflect into the container and wrap each Slot with a wrapper that reports canPlace(Player, ItemStack) to you so you know who placed what in which slot 🤡

echo basalt
#

hella work I don't get paid enough to bother

thorn isle
#

i really wish we had a proper menu/slot api in bukkit

#

the inventory api is okay but trying to do things like these is profoundly ass

sly topaz
#

just loop the inventory a tick after and check if the clicked item is there

echo basalt
#

I once tried to do a plugin where you could uh

sly topaz
#

it should work well enough™️

thorn isle
#

what if two players put items in it the same tick?

echo basalt
#

put whatever item you want on a beacon

#

because you can do it with events and enough emulation

sly topaz
thorn isle
#

i guess you can cancel all inventory events from the other player during the same tick 🤡

sly topaz
#

even if they did, you could just check for that as well

thorn isle
sly topaz
echo basalt
#

this is NOT accurate

sly topaz
#

and the event would have information of who clicked what

thorn isle
#

atp you might as well emulate it

#

since what the information on the event means depends entirely on the click type and inventory state

echo basalt
#

reactive inventories

thorn isle
#

suppose for example one player doing COLLECT_TO_CURSOR and the other one putting that same item type in the chest; you can't tell just based on the clicked item or cursor item who placed vs who took the item

sly topaz
#
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onInventoryClick(InventoryClickEvent event) {
    var containerInv = event.getClickedInventory();
    var player = (Player) event.getWhoClicked();
    // momentarily put a PDC on the item to know who placed it or something
    Bukkit.getScheduler().runTask(plugin, () -
        for (var item : containerInv.getContents()) {
            if (item != null && filters.test(item) /* check that pdc here as well*/) {
                setProgress(player, getProgress(player) + 1);
                break;
            }
        }
    });
}

naive but it'd work

thorn isle
#

but now that i mention it, you could mark each container view as "locked" for a specific player after the first interaction with it, and prevent others from interacting with it in the same tick

#

in this way all of the changes in the inventory can be accurately attributed to the correct player, because there can only be one player

#

well, minus hoppers and shit

sly topaz
#

I think it's severely overcomplicating this lol

#

it is just a quest, there is no need for it to be extremely precise and efficient

echo basalt
#

lol turns out this isn't a chest but instead a custom menu from another plugin

young knoll
#

I mean that’s just a chest menu without the chest

sly topaz
#

that makes it easier tho, since most plugins make a view per player instead of sharing one

young knoll
#

An orphan chest menu if you will

floral pond
#

Hello, what is the best way to store an Item Stack with his metadata (colors of a banner, writings of a book...) in a json (or DB) ? Should they all be saved with their own logic ?

young knoll
#

The api way is to use BukkitObjectInput/OutputStream to convert it to bytes

sly topaz
#

and a db

young knoll
#

Tho with NMS you can serialize the NBT directly for a smaller byte array

#

And also add DFU support

floral pond
#

ok i will try serializing it first

#

seems like what i need

#

Thanks !

sly topaz
#
public byte[] serializeItem(ItemStack item) {
  Preconditions.checkArgument(item != null, "The given ItemStack must not be null");
  var nmsItem = CraftItemStack.asNMSCopy(item);
  var compoundTag = (CompoundTag) nmsItem.save(((CraftServer) Bukkit.getServer()).getHandle().getServer().registryAccess());
  return writeCompound(compoundTag);
}

public ItemStack deserializeItem(byte[] bytes) {
  Preconditions.checkArgument(bytes != null, "The given bytes must not be null");
  var compoundTag = readCompound(bytes, References.ITEM_STACK);
  return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(((CraftServer) Bukkit.getServer()).getHandle().getServer().registryAccess(), compoundTag));
}

private CompoundTag readCompound(byte[] bytes, DSL.TypeReference reference) {
  try (var bais = new ByteArrayInputStream(bytes);
      var ds = new DataInputStream(bais)) {
    // should this stay unlimited heap??
    var compound = NbtIo.readCompressed(ds, NbtAccounter.unlimitedHeap());
    var dataFixer = ((CraftServer) Bukkit.getServer()).getHandle().getServer().fixerUpper;
    var result = dataFixer.update(reference, new Dynamic<>(NbtOps.INSTANCE, compound), NbtUtils.getDataVersion(compound, -1), Bukkit.getUnsafe().getDataVersion());
    return (CompoundTag) result.getValue();
  } catch (IOException e) {
    throw new RuntimeException(e);
  }
}

public static byte[] writeCompound(CompoundTag base) {
  NbtUtils.addCurrentDataVersion(base);
  try (var bais = new ByteArrayOutputStream();
      var ds = new DataOutputStream(bais)) {
    NbtIo.writeCompressed(base, ds);
    return bais.toByteArray();
  } catch (IOException e) {
    throw new RuntimeException(e);
  }
}
#

this is a direct copy of Miles PR where I just translated stuff to mojmap, unsure if it needs any changes

#

oh addCurrentDataVersion adds the current data version to the compound tag, TIL

young knoll
#

Yeah that’s pretty much all you need

#

Is NbtUtils a Mojang class?

sly topaz
#

these are the imports:

import com.mojang.datafixers.DSL;
import com.mojang.datafixers.DataFixer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.NbtAccounter;
import net.minecraft.nbt.CompoundTag;

can't put them on the same message since I don't have nitro

young knoll
#

Huh it is

#

TIL there are helper methods for the data version

sly topaz
#

it is GameprofileSerializer in spigot mappings

young knoll
#

I was handling that manually

sly topaz
#

could probably remove some of the imports since I used var in most places

young knoll
#

Var

#

Banned

sly topaz
#

I use it a ton so that people use it more

#

it's even more useful in these cases where you don't want to import things

thorn isle
#

i dislike excessive use of var because it makes it difficult to infer what everything is

#

try (var bais = new ByteArrayOutputStream(); is fine; the type is clear

#

var compound = NbtIo.readCompressed(ds, NbtAccounter.unlimitedHeap()); is edging the line

sly topaz
#

the good thing about var is that it was specifically limited with that in mind

thorn isle
#

var dataFixer = ((CraftServer) Bukkit.getServer()).getHandle().getServer().fixerUpper is absolutely haram

sly topaz
slender elbow
#

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream() is peak java and code that everyone should write

thorn isle
sly topaz
#

java people were very worried var would hurt readability, but I've found that it rarely does so, even less when taking into account the majority of the time you're reading your code in an IDE which will tell you the type in a inlay hint anyway

thorn isle
#

var excels at hiding hideous and redundant generics, e.g. an enhanced for loop over a map's entry set

#

hardly ever do i see it warranted for types without type parameters

thorn isle
sly topaz
thorn isle
#

being consistent in being vague isn't a benefit

sly topaz
#

if you don't use var just because it makes the type a teeny bit unclear (which, your variable name should help with anyway) when reading the code outside an IDE, then you probably shouldn't use it at all at that point

#

I don't believe that to be the case

young knoll
#

They should have just made it v to truly save characters

slender elbow
#

var is no different than explicitly typed lambda parameters, and yet you very rarely see that

thorn isle
#

i type my lambda parameters

slender elbow
#

:doubt:

thorn isle
#

i also put nullability annotations on them

sly topaz
#

now that's just crazy work

#

even if the type isn't already inferred within the same line of code, reading the rest of the code should make that clear enough

#

if it doesn't, then read more code

#

only case I do agree that var shouldn't be used is when you lose the benefit of type inference in the type definition, making it redundant as now you have to be specific on the method call/instantiation

#

i.e. var list = new ArrayList<Integer>();vs List<Integer> list = new ArrayList<>();, in this case I prefer the latter

slender elbow
#

I mean, you're just moving Integer from one place to the other

#

it's not like you are hiding any information

sly topaz
#

it isn't about information at this point, just that I feel it is redundant at that point, but either choice is fine honestly

#

if anything one can do var for sake of consistency

thorn isle
#

doing anything all the time just for the sake of consistency is missing the point imo

#

for the record i was joking about the lambda nullability annotations, that is 🤡 as a baseline, though i do use them when they're actually warranted; case in point

sly topaz
#

I mean, it is really down to whether you like the feature or not, because the readability argument was extensively discussed in the mailing list when it came to accepting this feature, and it did end up getting accepted nonetheless so I don't personally consider it to be as much of a problem as people make it to be, rather people just find it strange for Java

#

I like the feature so I use it, is my bottom line

thorn isle
#

i liked it until i had to read an old piece of code on github without ide support

sly topaz
#

I used to do that a lot with paper/spigot code, I learned it is just easier to have the IDE open at all times with the code lol

#

I always end up being frustrated by github's navigation, even if it is far better than bitbucket's with its symbol recognition feature

eternal oxide
#

Or you could just not use var and everythign is instantly understandable at a glance

thorn isle
#

github's navigation is and always has been ass

#

and in the latest update they completely fucked ctrl-f; the browser search highlight now appears in a completely disjointed place from the actual search match

sly topaz
slender elbow
#

some if its navigation has gotten better but it is certainly not an IDE replacement

sly topaz
#

even more so for codebases like spigot/paper where you have to navigate through patches

#

used to be way worse with paper before hardfork

thorn isle
#

rather than entering the type name in javadoc search it becomes a search to the n'th order

#

where the first thing i can search is class X which has method Y whose return type I have to check to get its javadocs to find method Z to get its return type to get its javadocs to find method W to ... to figure out what the fuck var entity actually is and why entity.remove() doesn't do what the guy expects it to do

#

having encyclopedic and exhaustive knowledge of the entire bukkit codebase does speed this up quite a bit but that's quite a tall order for someone to have

sly topaz
#

it is definitely more annoying when the method name itself is unclear and the variable name isn't indicative of anything, but that is only really true in sloppy code, so I don't suffer with it as much

sly topaz
#

in comparison to other communities anyway, at least wasn't my experience with other languages

#

I do wonder if some of it can be attributed to OOP

thorn isle
#

i don't think method names being somewhat vague is really sloppy code, half of the information on what a method is expected to do is its association with the class it's declared on

#

like sure rem() is sloppy code, but remove() certainly isn't, nor is say close(); but these words can have a completely different meaning depending on what is being "removed" or "closed"

#

this is why i disagree with dynamically typed languages in principle, just because you get something that has some method with some name doesn't mean it will (or can) do what you expect it to do

slender elbow
#

while var does not aid badly written code, not using it doesn't exactly save it either

#

bad code is bad

thorn isle
#

for sure

eternal oxide
#

In a world where 70%+ of code is bad, encouraging the use of var is probably a bad idea.

#

It would be OK if we could remotely slap wrists when bad code is written

sly topaz
#

by that logic dynamically typed languages shouldn't exist and we can't have any type of inference since it makes things unclear

slender elbow
#

i read brits and giggled

sly topaz
#

bad code? Blame the British

eternal oxide
#

oh typo 🙂

#

wrists

sly topaz
#

that was an unfortunate typo lmfao

thorn isle
#

a rule of thumb i use is that if you can infer the type without having to look more than a few lines up or down, var is fine, e.g. the following is good:

for (var e : this.someMap.entrySet()) {
    String k = e.getKey();
    UUID v = e.getValue();
    //do something
}

And the following is also fine:

Map<String,UUID> map = ...;
for (var e : map.entrySet()) {
    var k = e.getKey();
    var v = e.getValue();
    //do something
}

But the following is absolutely haram:

for (var e : this.someMap.entrySet()) {
    var k = e.getKey();
    var v = e.getValue();
    //do something
}

because the type declaration for k and v is probably 500 lines up where the map field is declared

young knoll
#

@remote swallow is responsible for all the bad code

#

I knew it

slender elbow
#

"dynamically typed languages shouldn't exist" is certainly a statement, they can have an entirely different grammar mechanism where the lack of typing does not hinder it

thorn isle
#

in the same vein

this.someMap.forEach((k,v) -> ...)

is also absolutely haram, and I would do the 🤡 and type the lambda parameters with:

this.someMap.forEach((String k, UUID v) -> ...)
eternal oxide
#

yep

sly topaz
#

I disagree

eternal oxide
#

I just don't use var as I would not trust myself to make unreadable code 5 years down the road

sly topaz
#

in reality instead of calling it k, v, you should call it text, uuid (or whatever text alludes to, i.e. name) and it is immediately clear

eternal night
#

Real peeps know, var is the ultimate abstraction technique

#

It is the perfect interface replacement

thorn isle
#

text and uuid will work for this simple example but for less known types that will quickly fall flat

eternal oxide
#

Sorry Epic it's my fault I exposed you

sly topaz
#

I really don't see the case where it won't, if you don't then you are being sloppy

thorn isle
#

no, name is not equivalent to type

sly topaz
#

since if the method is long enough, type is also lost in the sauce

sly topaz
thorn isle
#

multiple variables of the same type can represent different things and be named differently

#

e.g. suppose a player -> player map where the key represents a sender and the value represents a receiver

remote swallow
#

Defamation on my name

thorn isle
#

would you prefer (playerSender, playerReceiver) -> ... or (Player sender, Player receiver) -> ...?

sly topaz
#

I would prefer (sender, receiver) ->, given it is used in a context where the types of sender and receiver are clear as it'd be by something that takes a Player, Player lambda

thorn isle
#

it's in no way guaranteed that they are players

#

when I see receiver I probably think of Audience

#

when i see sender I probably think of CommandSender

#

so unless those type declarations are less than a few lines away I'd declare them here

#

again on the principle that name doesn't and can't indicate what exactly something is; be it method or variable

sly topaz
#

if it isn't clear by type, it is clear by name, if it isn't clear by name, it is clear by the method call, if it isn't clear by the method call, then maybe the class name, if it isn't clear by the class name then the surrounding code. Context is important and if we start to analyze these situations in a void, we can reason ourselves into thinking it is unclear however in any practical examples it's very unlikely to be the case

thorn isle
#

type it and it will always be clear

#

no need for ifs and buts and thens and wherefore maybe if by the method name i can roughly guesstimate what this is

sly topaz
#

you have yet to bring a non-hypothetical situation where it is unclear though

thorn isle
#

i can resend the code block to you next time someone asks for help with code and it has vars in it

sly topaz
#

I stand by the fact the feature was accepted at all, and we're really just repeating what the java devs discussed in the mailing list lol

thorn isle
#

well yes, but the consensus the mailing list ended up at isn't "use it everywhere all the time"

#

it was accepted because it is conditionally & situationally acceptable

sly topaz
thorn isle
#

it's not categorically acceptable nor categorically unacceptable

#

so we have it and we can use it where it does the job

#

preferences vary of course but personally i absolutely detest having to guesstimate things about my code based on soft associations like "hm this is called that maybe it does this"

sly topaz
#

I can understand that, however I dislike even more how it generates very stiff code style rules which you'd only see in bs enterprise code

thorn isle
#

if i don't have a class definition with a javadoc in front of me it might as well be single-letter variable names

ivory sleet
#

for example auxiliary index variables like i, j and k don’t need to be much longer

#

for one they live a relative small scope

#

when it comes to lambdas, its ofc nice to have shorter names if code won’t suffer its readability too much, sometimes when currying or use some other functional pattern in java (especially if u get very functional) the verbosity is sometimes quite necessary

#

but yea sometimes u can also just make it point free and avoid the hassle in the first place

ivory sleet
echo basalt
#

I personally stick to single letter variables and method names

#

if proguard does it so do I

#

because I'm pro

sly topaz
#

so much of enterprise code is just bs abstractions made by a junior dev who didn't understand what they were doing when creating that one FactoryBeanFactoryProvider

ivory sleet
#

Not at all

#

you have to understand enterprise java can consist of multiple modules, and millions of lines of code

#

you have tight deadlines because one u may work with some dev practice like test driven development

#

which means u'll be sitting writing tests, not actual prod code

#

secondly

#

you have deadlines

#

sprint deadlines, in lets say agile if u do some scrum or kanban shit

#

additionally, u have to code things in such a way that if business requirements (or tech requirements change) that change should be relatively easy to incorporate

#

devs get stressed, devs arent all super pals with one another on the team

#

50% of the devs might not even be motivated to work their life enthusiasm on the project

#

in all of this, explicit, super clear, verbosity, with a rigid set of rules and conventions - it does help

sly topaz
#

I mean, yeah I was just bringing up an example of where the code rules don't necessarily bring out any benefit other than making the code itself more verbose, but if we go into specfiics, there's of course many reasons for that to be the case. All in all, losely defined code style rules often end up being of more utility than an entire 12-page document detailing things some product manager considered after consulting the scrum master

ivory sleet
#

Yea no- Im just saying that its not entirely fair to call it bs, or say its invalid when these practices, styles and conventions stem from so much failure and an effort, a reason to address such sources of failure

dawn flower
#

how do i change the light level of all blocks (basically full bright)

rough ibex
#

That is for a light block.

mighty wind
#

anyone know if its possible to fake trigger frogs tongue animation in NMS

#

tried frog.setTongueTarget(targetPlayer); and frog.tongueAnimationState.start(0); to no avail but i think it might not be that simple

sly topaz
mighty wind
sly topaz
mighty wind
#

would suck if i need to make a slime spawn

sly topaz
#

they use the new brain system for AI which only makes things more complicated since nobody knows how the brain system works

mighty wind
#

yeah i tried to dig into it

#

are we able to access it at all or change it

#

i mean you can use reflection but like...

sly topaz
#

as far as acessing it goes you just call getBrain on the handle then you may set a memory which should trigger the action in question, though that's already possible via the API

mighty wind
#

i'm guessing there's some way to just mock the memory to make it want to eat lol

sly topaz
#

on a high level, brains are composed of sensors, which are responsible for changing memories, memories which should be self-explanatory and behaviors which make use of these memories to do their actions. The behaviors are coupled to activities which are just a set of behaviors that the entity might do

pseudo hazel
#

the behaviors can also change memory like a target task that remembers the "target" memory

mighty wind
#

i need to just see how memories work i guess

pseudo hazel
#

memories are just values shared between all the tasks and brain of an entity

mighty wind
#

i don't have my laptop on me to test rn

#

do you have an example of how you'd change this

#

or mock memory

pseudo hazel
#

wdym, change existing memory values?

#

sadly i dont know the spigot api for this

mighty wind
#

oh its like one object each mob has

#

with a bunch of flags

#

ah nah i mean the NMS

#

unless u cant discuss that here

pseudo hazel
#

the brain has memory, which consists of variables with values of varying types

#

like an allay stores the liked player for example

#

which is used be several tasks like following the player

#

that follow task has a starting condition of needed the liked player memory slot to be filled for example

#

like each task has a pre requisite

sly topaz
#

you can set the memory using the API I sent above

pseudo hazel
#

a find target task has the prerequisite of a target memory slot being empty

sly topaz
#

for the shoot tongue behavior, you'd set the ATTACK_TARGET memory key

pseudo hazel
#

but iirc brains are mostly serverside are they not? it would be hard to fake a tongue animation without the frog actually targeting that entity

sly topaz
#

well it seems like the MemoryKey class is missing a bunch of memory keys so you'd use frog.setMemory(MemoryKey.getByKey(NamespacedKey.minecraft("attack_target"))) for it

sly topaz
mighty wind
#

theres attacktarget in the frog nms iirc

#

as well

#

tongue target?

#

that one ^

pseudo hazel
#

p sure its just the attack target

sly topaz
#

by setting the attack target you indirectly set the tongue target as that is set & controlled by the ShootTongue behavior

pseudo hazel
#

usually entities attack by swinging their arms, the frog attacks by using its tongue on the target

mighty wind
#

oh ok

#

what if i remove all their goals and pathfinders

#

i assume it will work

#

otherwise i guess i can write my own attack one if its necessary

#

would probs need to know which one it is to see

sly topaz
#

super(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED, MemoryModuleType.ATTACK_TARGET, MemoryStatus.VALUE_PRESENT, MemoryModuleType.IS_PANICKING, MemoryStatus.VALUE_ABSENT), 100)
ShootTongue has all of these activity requirements, the walk target has to be absent, look target registered, attack target present and is panicking absent

pseudo hazel
#

well sounds like you just want to change the way it targets entities

#

there is probably a task responsible for setting the attack target

sly topaz
mighty wind
#

oh wow ok

pseudo hazel
#

they have tasks

#

which is pretty much a goal but it works with the brain system

sly topaz
#

yeah but I also mean that they're inherently incompatible

pseudo hazel
#

yes

sly topaz
#

entities which use behaviors do not interact with goals and viceversa, which makes things annoying for anyone used to goals but it is eh

mighty wind
#

i see

#

i will have to learn

pseudo hazel
#

oh well, I like the brain stuff

sly topaz
#

I mean, you don't have to do anything besides just setting the memory keys to these values and then triggering the activity by calling customServerAIStep on the entity or whatever the method is called

#

there's probably more forceful ways to trigger a behavior however that works fine in my experience

charred lagoon
#

Hey! I’m working on a Lifesteal server for up to 300 players and need someone who’s great with plugins and configuration.

Server type: Lifesteal.

Tasks: Plugin setup, advance configuration

Budget: $100–$150

If you’ve got experience with similar servers and want to help bring this to life, shoot me a DM with your past work or questions!

thorn isle
#

🤡

drowsy helm
#

also $100-150 is like a few hours of work.

#

?services

undone axleBOT
tranquil pecan
blazing ocean
#

?

drowsy helm
#

how to what lol

sullen marlin
#

how to

blazing ocean
#

md how do I do the

tranquil pecan
#

💀

tranquil pecan
drowsy helm
#

thats 5-7.5 hours

quaint mantle
#

Highly doubt that they're actually gonna pay $100 for this

young knoll
#

Up to 300 players

drowsy helm
young knoll
#

Well they said up to

#

0 is also up to 300

blazing ocean
#

-281 active players

dawn flower
plucky skiff
#

Why does BuildTools remapped not actually install for 1.16.5?

slender elbow
#

i believe remapped wasn't a thing until later down the line

#

1.17 or 1.18

young knoll
#

Yeah 1.17 was the first one iirc

plucky skiff
#

The Mojang Mappings were released on 1.14.4

slender elbow
#

yes

slender elbow
#

but spigot didn't use them until 1.17

plucky skiff
#

Alright makes sense, thanks for the help

dawn flower
#

how do i make a hologram system (display entities) where the holograms (or display entities) are respawned every server restart without creating a billion display entities, i could also use packets if it's better

young knoll
#

You could just have them never despawn

#

Or just store the location, remove any existing holograms at that location and then spawn them again

slender elbow
#

or you could setPersistent(false) them and respawn them when the respective chunk loads

young knoll
#

Yeah that's also an option

slender elbow
#

A genius one at it too

#

That is quite the bar

manic delta
#

Yeah using PlayerChunkLoad / Unload

mental frigate
#

hi guys, I've got this code

net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);

net.minecraft.network.chat.Component displayName = nmsItem.getDisplayName();

System.out.println(displayName);```
which returns me something like that
```translation{key='chat.square_brackets', args=[empty[style={italic}, siblings=[empty[siblings=[literal{Netherite Chestplate}[style={color=#FF00FF,!bold,!italic,!underlined,!strikethrough,!obfuscated}]]]]]]}[style={color=white,hoverEvent=TypedHoverEvent[action=<action show_item>, value=net.minecraft.network.chat.HoverEvent$ItemStackInfo@58531c7e]}]```
and im trying to access the siblings, however `Component#getSiblings` returns an empty array, how do I get to this part `[literal{Netherite Chestplate}[style={color=#FF00FF,!bold,!italic,!underlined,!strikethrough,!obfuscated}]]`
slender elbow
#

just use getHoverName() instead of getDisplayName()

mental frigate
#

oh thats a thing

mental frigate
mighty wind
#

can you make parrots sit on ppls shoulder

#

server and client side

slender elbow
#

Player#setShoulderEntityLeft/Right

mighty wind
#

i read its bc it doesnt work

slender elbow
#

where did you read that?

#

the javadoc itself?

#

the javadoc doesn't say it doesn't work

#

it says to use with care, and the client will only render parrot entities

mighty wind
echo basalt
#

gonna put a zombie on the shoulder

mighty wind
#

why tf cant u server side a parrot on sum1s shoulder

#

can u do it with NMS?

echo basalt
#

you can but the game will only render it if it's a parrot

#

bruh

slender elbow
#

have you even tried calling this method?

mighty wind
#

oh yeah i have

#

it doesnt work rn im gonna see if i messed anything up

slender elbow
#

you can only put a parrot

#

basically

#

you asked "can you make parrots sit on ppls shoulder", the answer is yes, use that method

#

any other entity does not work, but you didn't ask about other entities

mighty wind
#

um also does anyone know how to stop parrots from hopping off shoulders if a player is hit

#

apart from a scheduler perma setting it to ride

eternal oxide
#

try disabling its AI

mighty wind
#

is that just setAI(false)

#

i thought ai was like for armour stands or smth if u want them to be invis or smth

#

didnt work if so 😭

#

oh serverplayer has this.removeEntitiesOnShoulder();

#

i dont think u can override this? unless anyone knows how

slender elbow
#

not really

mighty wind
#

ggwp