#help-development
1 messages · Page 1258 of 1
actually nevermind, I didn't think that one thorough lol
can you generate chunks async using World#getChunkAt(int, int, boolean) in another thread
nope
https://www.spigotmc.org/threads/scaling-and-rotating-a-display-entity-between-two-points.674095/
Could someone give me the complete code to achieve this?
Which event is fired on wither break block?
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)
check that a) starts with an I, b) the following letter is uppercase?
but afaik I interfaces are not convention in JVM world lol
that's why I said """convention"""
that's a .NET thing for the most part
BlockExplodeEvent probs
either that or EntityChangeBlockEvent
Yeah prob it's entity change block event, ty

i feel you 🫶
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
here there's bunch of I prefixed interfaces for you 😄
IAmSteve
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
cry
thought so
just restart intellij
or click this button
also did
how many ram do u have
that's really not related
??
really?
Why would that matter
That happened to me when I had a 2 RAM PC always
What do the errors look like
"2 ram pc"
lol 2 rams
Now I have my laptop and it doesn't give me any problems
haha i have 32 rams
me 16
(I am making fun of your usage of "ram")
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
Hello I'm looking for a person who knows minecraft to make a software related to a launcher (I pay of course) dm
what version are you on
maybe his intellij is just dumb
2024.3.4
I also have a 2 ram pc (I have two sticks of ram)
IJ is not related to gradle
what gradle version are you on
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
yes
1.9.4
not you
oh okay
1.21.1
also not you
?services
If you wish to request or offer development/art/building/administration services, please do so at https://www.spigotmc.org/forums/services-recruitment-v2.54/
lmao
why not me
because not you
damn
flipping deleting caches again worked now??
i might be going insane
Happens
but i 99% sure that tomorrow morning ill have the same problem
probably
and now my dependency is still not loaded wth
again, what gradle version are you using
oh didnt see your msg. 8.8
just change the gradle-wrapper.properties file right?
./gradlew wrapper --gradle-version 8.13
./gradlew wrapper
oh ty
okay lemme make something sure real quick
run ./gradlew tasks and lmk if it errors or prints the task list
prints the tasks list
so it's an IJ issue
maybe i should switch ide
embrace neovim
cuz these issues arent a rarity
embrace not having a working LSP
nvim has lsp
embrace there being zero good kotlin LSPs
Fuck
you can try fleet but it just uses IJ as a backend
how would i make the textdisplay follow the user? manually teleporting is easier going to be too slow or too laggy
add it as a passenger
nah
oh, thank you
or i could js give up java with all its crap
its back...
youre blaming java for kotlin?
blaming the java world
does java gradle not work either
oh i meant to say give up everything with jvm
it works better but also not perfect
well anyways. thx everyone
ill probably wait for some updates, god or learn java so i won't have to deal with kotlin/intellij
damn
give up everything
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..
}
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
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
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
but you can count virtual size of the list just by tracking add() and remove() methods
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
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"
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
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
isnt my example doing just that?
i guess .get() wouldnt work in remove()
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
the textdisplay mounts directly above my head, how do i push it up to match it with my nametag
add a translation
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
the old method was placing a named armorstand right?
yeah, and the old method of moving it up/down was to mount a bunch of them in a pile
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
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?
yeah this does appear to be an issue lmao
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)
you can implement PacketList#size() by list.size() - removeIds.size()
and take this example
the index of the last element is 2, yes?
and list.size() - removeIds.size() returns 2, yes?
yes
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
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 😄
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
well... that would also fix the issue you have with the davadoc comment
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
Yea
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
But isnt this getting back to square one because the whole point this was to have nonshifting indices lol
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
?whereami
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.
i genuienly didint think there would be any differences that major, regardless im trying with a spigot jar now
what's the goal here exactly? are you working on like a palette or something?
?tas I'd say
You'll have to apply the invisibility effect to the entity.
It'll only work if the entity supports potion effects.
I've been trying, dumbass.
I wanna know if I'm doing something wrong or if the item frame being set to invisible negates the glowing effect
That used to be the case with most things, but nowadays there are major differences in how paper does things compared to spigot.
Compatibility is the main reason why things just kinda work on both setups, but with paper's fairly recent hard fork announcement, there are things that just won't work.
Paper is becoming it's own standalone project.
then mention that you've tried it and it doesn't work
no need to be rude about it
curiosity
and also, crossposting in spigot and paper at the same time is crazy
https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/inventory/ItemFlag.html
Whoa, lots of new flags are being added.
Noice
tad bit jank
wow, yeah i was totally unaware thanks for filling me in, il update you once i get the spigot jar
That’s a lot of flags
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?
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
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
so then attempting to make nametags billboard vertically is pointless?
I mean, isn’t it able to do that by default?
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
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
yeah i see, it is very laggy. so there is essentially no way to set the player's nametag and have it rotate without lag?
wsg
i was thinking this, but i don't know what entity i would use to offset it
what do I use instead of the deprecated AnvilInventory? I need to set the cost text and stuff
The javadoc tells you what to use
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
also, i can't find a way to make said entity invisible without making it's passenger invisible, and i don't think there are any rideable invisible entities
I mean interaction entities are invisible
So are display entities with nothing set to display
you can't use addpassenger() on those
You should be able to. ALL Entities support passengers
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
all display types can be translated
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
that's the easiest solution with the least maintenance baggage
Does the size of an interaction entity affect the passenger position?
what's an interaction entity?
no
you can use air as a projectile, but it still wouldn't be scalable
last i asked this someone told me they're invisible armor stands
don't they work in the same way where size doesn't affect?
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
They are for detecting interactions
And can have a custom width and height
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
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
That was the old method.
The interaction entity was added specifically for this.
yes but i asked like 3 days ago or something and was told it's an armor stand under the hood
I don't know if that's even true.
Or do you mean armor stands with the marker flag
armor stands with the marker flag
it most likely wasn't true
i don't think they added interaction entities in the past 3 days
oh, bruh
Ofc not. They were added at the same time they introduced display entities
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
it still looks a bit janky, but i could just do this or the air projectile
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
can i use attributes to scale the invisible armor stand up and down?
sort of yes but that won't affect where the passenger sits i don't think
it doesnt, i tried
yeah you've got to put it on an armor stand
oh, small armor stands are too tall
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
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?
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
oh, alright, i'll try that thank you!
is there any way to remove components from items like consumable component from food?
no, you'll need NMS || or paper api ||
oh unfortunate, thank you
or WHAT api!?
idk what you are referring to
i can't manage to teleport the armorstand, i don't think you can teleport entities with passengers, or atleast i think
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?
Not currently. I think there is still an open PR about it.
You can dismount the entity, teleport the main entity to where ever you need it, then remount the passenger.
Are you sure that's an anvil inventory being opened
yeah. I'm getting the same error in my InventoryClickEvent when I click in the anvil in game toojava Bukkit.createInventory(null, InventoryType.ANVIL, ChatColor.RED.toString() + ChatColor.BOLD + "Enter Name");
is event.getView() not the right way?
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
You've reached the far lands
Ah yeah that’d do it
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
my condolences
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
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?
yml would be fine
I mean, you can use both async which eliminates most of the concern
So it doesn’t really matter
The nice thing w mysql is that u can sql to query top 10
true
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
Right
Bare minimum you should be using SQLite, MySQL would just be a nice optional thing if you want a remote database
after 1000 entries it'll be pretty slow im guessing
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
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)
still waiting for the day there's a proper db abstraction made for sql in java
something like jetbrains exposed
I mean there's jOOQ if you really want
I don't know how abstract it is to different DB engines though
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
Rule 4.1.6.1.1.1
obfuscation has never prevent pirating
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
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.
Is it the same key with the same namespace
kinda late but you're supposed to be using MenuType#create method nowadays, not that one
and that returns a view
PDC is plugin specific in their k,v pairs. In order to access the k,v pair of another plugin for pdc you need to obtain the plugin's instance in regards to the pdc. So all you need to do is get the plugin instance of the one you depend on and then using that instance get its pdc
Could also just use fromString
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
That too
I like Choco's suggestion better, but Epic's method should work too
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
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
Thanks
Nms isnt really something you can learn explicitly from a guide. Set a goal to achieve and then what nms can do to solve it
I'm in bed rn thinking about how I'd make an entire video series around different nms concepts
Are you trying to achieve anything specific?
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.
Nah makes sense. You’re sort of in luck as we have moj mappings now which makes nms a cake walk
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
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
Sure thing
I'm a bit confused on where to start
Do you have any starting point recommendation?
For now I'd say particles
oh right nms is veery version dependent
With Moj Mappings it doesnt vary much
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
how should I use MenuType to create an anvil view? MenuType#create doesnt seem to exist
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
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
declaration: package: org.bukkit.event.entity, class: EntityDamageEvent
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
What sound are people using for double jump I cant figure it out
its like a launching sound
I'm upset I didn't think of this before posting that's definitely an easy way of fixing my problem
Thanks
Have you tried entity.ender_dragon.flap
I thought it was another
There is one that sounds a bit more like something launching
i mean it would make the work totally harder, since i have a license system and i don't want to load my classes over HTTPS lul
Your plugin has to work offline without the reliance on any license otherwise you can't sell it on spigot's platform
yeah i know, thats why i would delay updates on spigot
since its the full resource and obfuscation doesn't do the job 100%
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
Only way to get around it is to host the servers yourself
And not let users choose what to install
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.
Some crackers might even see it as a fun challenge
just cracking it to see if they could
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
license can be replaced
but yeah as long as it's unique ig it's a good enough identifier
they can, but that assumes the cracker knows its there and knows how and cares to
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.
PacketType.Play.Client.GROUND i want to get data from this packet
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
its wierd. it was always true and was sended only sometimes
i worked with packets before. i made hack client in java and bot using socket in python
I was mainly talking about spigot serverside packets
i think i got it working. i only needed to use POSITION_LOOK packet type
I have an texture pack error someone who can help i will pay!!!
First off don't DM random people. Include your error in the request for help and use #help-server
I'll take 5€
- texturepacks are no longer a thing, it's a resource pack
- do what Olivo said
Im sorry guys
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?
hey i dont understand what either of these suggestions mean
i only kinda understand how fromString() works and dont see how it works cross plugins
and i dont understand what choco means by hiding the key
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
seems like you got some more researching and learning to do then 🙂
good news what you are wanting to do is possible
FILLED_MAP
yeah realized .6 seconds after posting
Happens every time 💀
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?
new Thread(() -> {
// ...
}).start();
?
most nebulous question challenge (impossible)
Or use a single-threaded executionservice, if the task is short lived and frequently called
Executors.newSingleThreadExecutor().execute(() -> {
// ...
});
like this, yes?
Clueless

thanx bb
MenuType.ANVIL.create(player, "title")
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
How do I tell the thread to handle the method when it gets called tho
what are you trying to do
because what you're describing seems like a solution to a leading problem rather than the actual thing you're trying to solve
Put stuff on a worker thread
but why, what do you need to put in a "worker" thread
Not to use main threads resources
are you being dense on purpose, what are you not trying to run in the main thread, a calculation? a database query?
mine crypto, ofc
putting lines in a scoreboard can't be done asynchronously, at least not with the API
then use the async scheduler
ah so you mean the strings that go into them are calculated asynchronously
Yea
you could use a CompletableFuture#supplyAsync then do thenAcceptAsync with BukkitScheduler#runTask as Executor
I was contemplating whether to whereami
What does thenacceptasync do??
BukkitScheduler#runTaskAsynchronously
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);
Bukkitscheduler#runtask as executor??? What??? You can do that??
Okay so it thinks that it accepts async
But its secretly the main thread?
Xd
the issue with that is that going back to the main thread schedules another task and it's kinda annoying
heh I just use coroutines 
yet another day of the word "async" being misinterpreted by people in the spigot ecosystem
I think I am having a dejavu about this topic lol
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
"but async means not on the main thread, huh?"
isn't there a BukkitScheduler::getMainThreadExecutor(Plugin) specifically for this?
this is probably due to the fact in regards to spigot, async does use another thread in the implementation
😔
but you are correct nonetheless about it
paper method
papir
papièr
paper sex
https://paste.md-5.net/decajulisu.cs
Nothing serious here just curious, is this correct in applying metadata to an entity?
I also figure in this example I could have used a FixedMetadataValue but other than that not sure if it really matters
pdc when
allegedly, metadata causes memory leaks so you shouldn't use it
I literally just saw entities have pdc smh
it is a broad statement which doesn't really hold value to all scenarios but it certainly can happen
PDC is permanent tho, I'd just use a hash map
I mean pdc imo is easier to manage, although I would assume the pdc is cleared when the entity dies no?
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
it is most likely cleared though
hey guys how can I open a sign in front of the player for input?
i think the mob just gets marked as invalid and dead and little else is done on its data
destructors get called when an entity dies, I don't assume they don't clear nbt on purpose
there is background tasks that eventually clear it out
place a sign somewhere then use Player#openSign
It just feels weird mapping entities and holding them from spawn -> death
I don't really see what's wrong about it
most plugins before PDC just used hashmaps which they dumped into yaml or whatever
i can't find it being cleared anywhere
the reference on CraftEntity isn't a weakref either
let me pull up the spigot source, I could be wrong since my memory is quite fuzzy about these details lol
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
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
PDC sounds fine for that, as long as you don't need mob stacking data offline for whatever reason
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
Yeah fair
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
yeah, this is why i kind of dislike the pdc
hi kat
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
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
There's no way to directly clear all pdc entries is there
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
Hi rad
javier chambea
I'm surprised there's no clear method on the PDC tbh, you have to loop through keys and remove each one manually
yea
leave me and my unemployment alone smh
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
agarra la pala
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
i could maybe see a clear(Plugin) method that clears all the key-values where the key namespace belongs to the given plugin
that sounds reasonable, free PR also
doesn't that like involve like, looping over all entities and tile entities that exist in all worlds
it'd just be for the single pdc
oh right
what if pdc is the friend we made on the way
i don't think there is any sane way of clearing them all in all the world
yeah exactly
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
Bukkit#getOfflinePlayers 🤑
i.e. entries with that key and a timestamp older than when the clear was issued
now do that for all tile entities
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
at that point it's just better to manually parse the region files
proceeds to block the main thread for a minute
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
ideally you would do it either when a chunk loads or unloads
I have never been a fan of saving data directly into the world files though
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
well it could easily be changed where it just kept separate with a way pointing where that data goes
in this manner clearing out old plugin data in the world is a matter of clearing a directory
sounds roughly like what we already do but with a tighter integration into the api
wouldn't mind having that to be honest
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
it could be abstracted quite far to not be limited to region files i suppose
inb4 PDC just ends up being backed by a sqlite database with a table per plugin
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
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
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
I do wonder if that'd work at all on spigot given how differently the platforms handle chunk loading lol
i think its somewhat async in the mojang server already but i'm not sure
on vanilla & spigot chunk loading is async but the server stops ticking until the chunk is loaded anyway
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
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
the patch is borderline illegible because there are no imports and everything is ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData.someNmsMethod$someMoonRiseOverloadWithReallyLongName
you forgot $moonriseNmsMethodName0_moonrise
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
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
moonrise will be so fkn hard to maintain if it was not mixin first
you do realise moonrise was used in paper before it was called moonrise
well i don't
its not good to know the history too much
what
it even had a history before it was added to Paper!
What
According my understanding of moonrise, it is currently a fabric mod which is then ported into paper
Yes but like, updating it in paper would not be more difficult than mixins
if anything mixins are harder / more annoying to update
"Moonrise" was in tunity first then moved to paper then moved to a mod
moonrise my beloved
lets us do async entity lookups without blowing up the server
really useful for packet manipulation
and block lookups
is there seriously no good method of detecting when an item is "put in a chest"
I have to do all this BS emulation
what do you mean
are the inventory events not enough? What do you need to do emulation for?
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
there is no before and after state in a chest though lol, let me check the code ig
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
it's literally just a quest where you need to put an item in a chest
I don't get why it is doing specific checks
That's only checking if players put something in a chest. What about hoppers and minecarts as well?
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
just listening to the inventory click event and checking whether the item they clicked ended up in the chest view should be enough
if you look I don't have a check for container type
but the quest is literally "put your ball in this chest"
shift clicks and such make that nontrivial
since whether something ends up somewhere is completely up to the click type and inventory state
basically a diff of what changed
too bad InventoryMoveItemEvent doesn't quite work for this concept
item went from slot A to slots B, C and E
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 🤡
hella work I don't get paid enough to bother
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
just loop the inventory a tick after and check if the clicked item is there
I once tried to do a plugin where you could uh
it should work well enough™️
what if two players put items in it the same tick?
put whatever item you want on a beacon
because you can do it with events and enough emulation
they wouldn't put the exact same item
i guess you can cancel all inventory events from the other player during the same tick 🤡
even if they did, you could just check for that as well
but how do you know which one placed which item?
any information from the event can be passed to the task afterwards, you'd just need to check for it if it is necessary
and the event would have information of who clicked what
atp you might as well emulate it
since what the information on the event means depends entirely on the click type and inventory state
reactive inventories
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
@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
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
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
lol turns out this isn't a chest but instead a custom menu from another plugin
I mean that’s just a chest menu without the chest
that makes it easier tho, since most plugins make a view per player instead of sharing one
An orphan chest menu if you will
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 ?
serializing the item to bytes
The api way is to use BukkitObjectInput/OutputStream to convert it to bytes
and a db
Tho with NMS you can serialize the NBT directly for a smaller byte array
And also add DFU support
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
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
it is GameprofileSerializer in spigot mappings
I was handling that manually
could probably remove some of the imports since I used var in most places
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
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
the good thing about var is that it was specifically limited with that in mind
var dataFixer = ((CraftServer) Bukkit.getServer()).getHandle().getServer().fixerUpper is absolutely haram
it is mostly because you don't need to know the type to infer what it returns here, if you know anything about the code in question anyway
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream() is peak java and code that everyone should write
it's not worth saving the 15 or however many characters the actual class name would be
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
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
with the sole exception of assignment from constructor like this
it is worth it if you consider consistency
being consistent in being vague isn't a benefit
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
They should have just made it v to truly save characters
var is no different than explicitly typed lambda parameters, and yet you very rarely see that
i type my lambda parameters
:doubt:
i also put nullability annotations on them
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
I mean, you're just moving Integer from one place to the other
it's not like you are hiding any information
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
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
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
i liked it until i had to read an old piece of code on github without ide support
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
Or you could just not use var and everythign is instantly understandable at a glance
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
I have yet to see an example where it isn't understandable at a glance while using var, or rather an example where it matters. In most cases you don't really care about the type of a variable in the middle of a method, just what they do with it
some if its navigation has gotten better but it is certainly not an IDE replacement
even more so for codebases like spigot/paper where you have to navigate through patches
used to be way worse with paper before hardfork
i don't have any example to give you off the top of my head but it happens every time someone here uses var in their code that i need to look up javadocs for
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
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
I honestly find it surprising just how many people we have around with that kind of knowledge lol
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
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
while var does not aid badly written code, not using it doesn't exactly save it either
bad code is bad
for sure
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
by that logic dynamically typed languages shouldn't exist and we can't have any type of inference since it makes things unclear
i read brits and giggled
bad code? Blame the British
that was an unfortunate typo lmfao
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
"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
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) -> ...)
yep
I disagree
I just don't use var as I would not trust myself to make unreadable code 5 years down the road
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
Real peeps know, var is the ultimate abstraction technique
It is the perfect interface replacement
Heh
text and uuid will work for this simple example but for less known types that will quickly fall flat
Sorry Epic it's my fault I exposed you
I really don't see the case where it won't, if you don't then you are being sloppy
no, name is not equivalent to type
since if the method is long enough, type is also lost in the sauce
not the same, but indicative
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
would you prefer (playerSender, playerReceiver) -> ... or (Player sender, Player receiver) -> ...?
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
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
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
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
you have yet to bring a non-hypothetical situation where it is unclear though
i can resend the code block to you next time someone asks for help with code and it has vars in it
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
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
well, that'd be hard to judge given I know anything related to Spigot API and a good chunk of the server as my palm, but if it is anything outside that I'll try to be unbiased
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"
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
if i don't have a class definition with a javadoc in front of me it might as well be single-letter variable names
Doesn’t that depend on the scope in which the lambda is declared in?
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
tbf I think its a bit unfair to call it bs- I mean java enterprise has its good reasons for why things become so verbose, you may not like those reasons, but they still persist valid
I personally stick to single letter variables and method names
if proguard does it so do I
because I'm pro
I don't believe it is all that valid honestly
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
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
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
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
how do i change the light level of all blocks (basically full bright)
That is for a light block.
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
have you tried setting the pose to USING_TONGUE
i'll try when i'm back on. honestly i haven't completed the game since beta 1.8 so i don't really know how things work lol
to be fair, nobody knows how frogs work, nobody has done anything with them yet
would suck if i need to make a slime spawn
they use the new brain system for AI which only makes things more complicated since nobody knows how the brain system works
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...
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
will do i didn't know this was a thing
i'm guessing there's some way to just mock the memory to make it want to eat lol
just setting the memory and then the tongue target may just work honestly
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
you can read this fabric example https://wiki.fabricmc.net/tutorial:villager_activities which more or less gives one some idea on how it works (Task is yarn lingo for Behavior in mojmap)
the behaviors can also change memory like a target task that remembers the "target" memory
i need to just see how memories work i guess
memories are just values shared between all the tasks and brain of an entity
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
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
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
you can set the memory using the API I sent above
a find target task has the prerequisite of a target memory slot being empty
for the shoot tongue behavior, you'd set the ATTACK_TARGET memory key
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
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
brains are completely server-side, yes
p sure its just the attack target
by setting the attack target you indirectly set the tongue target as that is set & controlled by the ShootTongue behavior
usually entities attack by swinging their arms, the frog attacks by using its tongue on the target
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
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
well sounds like you just want to change the way it targets entities
there is probably a task responsible for setting the attack target
entities with brains do not use goals at all
oh wow ok
yeah but I also mean that they're inherently incompatible
yes
entities which use behaviors do not interact with goals and viceversa, which makes things annoying for anyone used to goals but it is eh
oh well, I like the brain stuff
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
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!
🤡
?services
also $100-150 is like a few hours of work.
?services
If you wish to request or offer development/art/building/administration services, please do so at https://www.spigotmc.org/forums/services-recruitment-v2.54/
teach me how to
?
how to what lol
how to
md how do I do the
💀
I mean how $100-150 is few hours of work
assuming the person is charging minimum wage (let's say $20)
thats 5-7.5 hours
Highly doubt that they're actually gonna pay $100 for this
Up to 300 players
I always giggle when i see people planning a server and expecting insane numbers like that
-281 active players
how much they paying for advertising
Yeah 1.17 was the first one iirc
yes
but spigot didn't use them until 1.17
Ah, that's quite annoying.
Alright makes sense, thanks for the help
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
You could just have them never despawn
Or just store the location, remove any existing holograms at that location and then spawn them again
or you could setPersistent(false) them and respawn them when the respective chunk loads
this is actually genius
Yeah that's also an option
Yeah using PlayerChunkLoad / Unload
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}]]`
just use getHoverName() instead of getDisplayName()
oh thats a thing
it worked, thank you!
Player#setShoulderEntityLeft/Right
says deprecated
i read its bc it doesnt work
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
oh so other people cant see it?
gonna put a zombie on the shoulder
have you even tried calling this method?
ohhh
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
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
try disabling its AI
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
not really
ggwp