#help-development
1 messages · Page 393 of 1
Ahh now it works
no way
AI saved my ass once again
So what was happening (I think) is something is reloading/resetting the variable each time, making it kinda empty
using static prevents that.... apparently
Yeah i think you should learn Java before using IA
Do note that mods would have evolved differently - reflection wouldn't be based on signatures for example.
People would quickly design deobfuscators such as the one I mentioned above, which is able to guess the generics of collections in a fairly safe manner.
Talking to me or someone else?
nah - you're reinitializing the class each time for some reason
Yes, but where and why
You, it initialize a new variable because it might create a new instance, making it static means that the variable will be the same for any created instance
Somewhere else - you didn't give the necessary code to give a better explaination
So you would follow the AST around to find out what types are used when operating on - let's say - collections, to find out their "common denominator"? Static code analysis is the only way I could imagine being able to restore information like that.
I think it might have to do with ```java
public void spawnParticlesEverySecond(Particle particle, Plugin plugin) {
BukkitRunnable runnable = new BukkitRunnable() {
public void run() {
for (Location location : scrapLocations) {
location.getWorld().spawnParticle(particle, location, 7, 0.2, 0.4, 0.5);
}
}
};
runnable.runTaskTimer(plugin, 0L, 20L); // run every second (20 ticks)
}
}
hold on
I think it might be doing something
Ah it's doing something!
Exactly. And it's simpler than that since in 60% of cases we can just listen for
INVOKEX owner.name()Lreturn;
GETFIELD x.y:Lz;
INVOKEINTERFACE collection.add(Ljava/lang/Object;)
or similar
hmm does anyone knows what the dif is between Char2ObjectArrayMap and Char2ObjectOpenHashMap?
nope
Could not find io.netty:netty-transport-native-epoll:4.1.82.Final.
Searched in the following locations:
- file:/Users/249438/.m2/repository/io/netty/netty-transport-native-epoll/4.1.82.Final/netty-transport-native-epoll-4.1.82.Final.pom
If the artifact you are trying to retrieve can be found in the repository but without metadata in 'Maven POM' format, you need to adjust the 'metadataSources { ... }' of the repository declaration.
Required by:
project : > org.spigotmc:spigot:1.19.3-R0.1-SNAPSHOT
Possible solution:
- Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
Hey does someone know why it gives me that error with Maven Local. I've downloaded latest spigot with BuildTool
Then I dont have a single clue
We're looking for a new keyword that shouldn't be there
Ideally you would need to send the whole class file(s) so I could pinpoint it directly
One is array-based and the other one based on a hashtable
Send your build file
Buildtools
?paste
I think this is it ParticleHandler particleHandler = new ParticleHandler(); particleHandler.spawnParticlesEverySecond(Particle.SCRAPE, this) in my main class
Honestly if you only have a single of such a map in storage I'd just use a array of size 65k (2^16) - it's not all too large to be an issue to initialize at full size outright
hmm i need a Map<char, List<ItemStack>>
Does it need to be fast? xD
it will hold 9 elements at most so doesnt really matter
jsut wanted to try out those fastutil stuff
always fun when i get it as a transitive dependency
but i just need it to do 1000 times
If I want to cancel blockPlaceEvent and instead of the block. Place my own custom block
How can I do so
Have the Map a thousand times or perform a thousand lookups?
max 9 lookups per map and that max 1000 different times
So use ArrayMap
ok
Is someone free to help now?
?ask
If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply. Make sure you use the right channel regarding the topic of your question. Create a thread in case the channel is already in use!
Don't ask to ask or ask if people are awake or available
deserializing those mojang recipe jsons is a pain in the ass lol
But how would i get "material" and "antal"
repositories {
mavenLocal()
}
dependencies {
compileOnly 'org.spigotmc:spigot:1.19.3-R0.1-SNAPSHOT'
}
All the rest is by default.
deserializing mojang stuff be like
oh and to keep it interesting, mojang sometimes uses an array and sometimes a single object 💀
damn im atleast able to deserialize one recipe
545/1xxx lol
Try adding maven central as a repo
It works perfectly thanks !
when i have three methods @eventhandler for playerjoinevent then first is runned with the highest priority?
Warning: Pesudocode!
ConfigurationSection sect0 = config.getSection("casino.crates");
for (String id0 : sect0.getKeys(false)) {
ConfigurationSection sect1 = sect0.getSection(id0 + ".rewards");
for (String id1 : sect1.getKeys(false)) {
String material = sect1.getString(id1 + ".material");
String antal = sect1.get(id1 + ".antal").toString();
}
}
if you did not specify the priority explicitly, you should assume that there is no order
ok thx
"sect0 is null"
Do a shitton of null handling then
hello i was wondering if anyone could help me with this code
the first part work that says "this is a sheep but after that "else" doesnt work and it doesnt say this is not a sheep when trying to sheer another entity
- there is a reason why I never use nullability analysis with minecraft
Trying? You must actually shear them otherwise it won't register
Instead a PlayerInteractEvent will be logged, which you likely want to listen for
oh so if the entity cant be sheared it wont register
Yep
ok well thanks for the help
Problem is its null no matter what
Could it have something to do with it saying null here?
why is this not working? It is registered then what is the problem, please help me.
https://paste.md-5.net/feligonati.cs
its not annotated with @EventHandler
and == for enums
Guys, help!
I can't find this packet:
@lost matrix
You sent me a screenshot earlier
ordinarily - no
it still doesn't work
https://paste.md-5.net/iziyawayoy.cs
This would be a concern for the plugin you are using for this, which appears to be ProtocolLib. You wouldn't get much support here and should ask here: https://github.com/dmulloy2/ProtocolLib/discussions
an event cannot take 2 arguments?
huhhh
lmfao
it can only take the event
ok, thx
Try
for (Object o : config.getList("casino.crates")) {
ConfigurationSection sect1 = ((ConfigurationSection) o).
getConfigurationSection(id0);
for (Object o2 : config.getList("rewards")) {
String material = ((Map) o2).get("rewards").toString();
String antal = ((Map) o2).get("anatal").toString();
}
}
But I am sure that won't work like that
so how do i fix it, sorry im a begginer
Something is broken but I cannot tell what given that it has been years since I've last used configuration sections @analog thicket
remove the player argument
and get the player from the event.
like this?
https://paste.md-5.net/gexakotane.cs
yes
Fair enough ill try what you send, and if that works it would be nice, but i maybe found another fix but its a very long fix, so if yours work that would be nice.
Nah, one of the two casts is invalid
If the configsection cast is invalid, the map approach is the right one. Otherwise it is the configuration section one
Well i tried maps before too, those were null as well
Is anyone familiar with MorePDC by alex?
then you may want to dump that section - something feels wrong
?stash alternatively I could stop guessing and look at the actual sauce
How can I have fields in my serializable class that don't need to be initialized or can be null?
With more pdc you can't just do that
?paste
That's the file that's getting serialized
ultraChest.setLocation(chest.getLocation());
Before it tries to serialize
49 -> this.world = world
26 Location location
Back to this
ultraChest.setLocation(chest.getLocation());
PDCUtils.set(chest, NBTTags.ULTRA_CHEST_STORAGE, getDataType(), ultraChest);
not valid
Well my solution didnt work either -.-
Dammit
first you are using paper and not Spigot. Second you are likely attempting to deserialize before worlds are loaded so the world will be null
No. this is on block place
Hey... again. Im making a system that allows you to specify blocks as loot sources, which you can right click to get loot. The block then has a cooldown of lets say 1 minute, until it can be looted again. I got the particles working and I can detect if I right clicked an available block, but now I need to be able to loot the blocks. So far I have this:
public void LootBlock(Player p, Location loc){
scrapLocations.remove(loc);
lootedScrapLocations.add(loc);
}``` This moves the location of the lootsource to the lootedScrapLocations. I'm wondering however, how I'm supposed to add a cooldown, so that the loc in lootedscraplocations goes back to scraplocations after one minute
It sounds quite easy but idk where to start
?conventions
Having more trouble with my code. I get this error when I try running it[23:15:46] [Server thread/ERROR]: Could not pass event PlayerInteractEvent to ScrapCollection v1.0 org.bukkit.event.EventException: null
This script checks if I right-click a block that has been registered as scrapLocation.
public class EventListener implements Listener {
public EventListener(main plugin) {plugin.getServer().getPluginManager().registerEvents(this, plugin);}
private final ParticleHandler pHandler = new ParticleHandler();
@EventHandler
public void onRightClick(PlayerInteractEvent ie){
Action action = ie.getAction();
if(!action.equals(Action.RIGHT_CLICK_BLOCK)) return;
Player p = ie.getPlayer();
Block b = ie.getClickedBlock();
Location blockLoc = Objects.requireNonNull(b).getLocation().add(.5, 1.4, .5);
if(!pHandler.CheckLoc(blockLoc)){ // check if the block is in scrapLocations
return;
}
pHandler.LootBlock(p, blockLoc);
}
}```
https://paste.md-5.net/ikoqugezej.java - ParticleHandler
Just add the Location to a map and the last time it was used
Yeah I think I got it
But it's just not working
lol
or like a Cache from Caffeine or something would actually be pretty good too
what event occurs when a ground item is burned or exploded?
how would one call smth like this: minecraft:sand, a namespace?
When a ground item is burned or exploded in Minecraft, the EntityExplodeEvent or EntityCombustByEntityEvent is triggered depending on how the item is destroyed.
did you get that from chatgpt?
why ask
I mean sure the formatting and choice of words is weird
but the answer it gives is correct
I made sure to check them of course
Material Names or Material Keys
afaik
but maybe Im wrong
NamespacedKey, isn't it?
I just checked if location was null
Where the namespace is minecraft and the key is sand.
And it isn't, but serializable is still null
Who are you talking to?
others
https://paste.md-5.net/ehebicucef.bash
https://paste.md-5.net/ibaxagifaf.cpp
I checked and setLocation(chest.getLocation()); is not null. Yet I still get the serializable error
It looks like the Hologram class isn't being recognised by the compiler, so it's probably not imported correctly or not included in your project.
player p 😦
Tell me what fixed it
😂
block b 😐
That location error is not from the serializable class but the hologram field that is location?
me.tomisanhues2.ultrastorage.shaded.me.tomisanhues2.morepersistentdatatypes.datatypes.serializable
Damn, what a package name, holy

lol
Shading be like}
You got it working?
nah its just wrongly shaded
Good luck zipping that folder
how did the second package get there
ok moment
Well I got specific problem I am making my LibPlugin with all libs which I am using in the rest of my other plugins.
I am shading them and now when I use my lib as dependancy I can still access original lib and import them looks like from some reason my plugins can access lib pom files with list of dpendencies and that allowes me to import original not shaded libs
How would I avoid that so I have only imports for shaded ones in my lib?
I am doing that with maven
Xd
No one is ever gonna be able to unzip this
4 minutes scrolling through folders
That's almost a zip bomb
not sure if i understand
but uh
you mean that they still want the dependency?
here to be more specific
Make sure that you have the Maven Shade Plugin configured in your pom.xml file.
Verify that you are shading all of the necessary dependencies, and that they are being properly relocated. You can check the relocated classes by opening the shaded JAR file and looking for the package names in the class files.
Check that the original dependencies are not being included in the classpath of your application. You can do this by checking the output of mvn dependency:tree.
Finally, make sure that your application is using the shaded JAR file as its dependency, and not the original JAR file.
If that doesnt work, dont ask me because idk
Ok I fixed the path
But either way
Let me see if removing hologram makes it work
imma call you chatgpt man
?
Go ahead 😉
If only I could change nicknames
on this server
all done it only contains shaded paths
and using shaded jar
ah maven
you might want to try using the Maven Enforcer Plugin to enforce the use of shaded dependencies, or to exclude the original dependencies from the build entirely.
I actually did a 'How human are you' test and it turns out I'm an android, and can only get a girlfriend if they're severely disabled and blind
Typical decompiler moment, xDD. Man, that thing butchered my library. I need to get into the habit of sources jars.
What's your updated code
Is that because you can't set pdc data onto a chest?
Nothing changed besides removing hologram from serializable class
To test
a chest is a tile entitty so it should have pdc
Placed, right?
What does it want here?
List<Map<?, ?>> rewardList = (List<Map<?, ?>>) name.get("rewards");
I have a feeling I'm messing up when I get the block from the BlockPlaceEvent
yeag
@SuppressWarnings("unchecked")
(Chest) event.getBlock().getState()
Thanks
Maybe it can't give me a chest object at that moment?
Chest chest = (Chest)block.getBlockData()
i think
might want to do a instance of check
its blockstate
Just the 1 line where I call it
This is correct then according to fourteen
this works
So why am I getting this error
Bruh my server suddenly doesnt see my plugin anymore. All I changed was this
never do that
public Block block;
and naming conventions where
Yeah I have no idea what that means. Glad you got it working though!
A Block might not be serializable
It didn't work so I just tried random shit
why not do that?
dont call main class man, use YourPluginName and use upper camel case
Exclude all transitive dependencies
you are creating a 2nd instance of your plugin doing that
Good to know
Is a Block serializable then? Anyone know?
Instead of instantiating it there, you can do it either onEnable or onLoad
Block is not serializable, no
use di or
public class MyPlugin extends JavaPlugin {
private static MyPlugin instance;
@Override
public void onEnable() {
instance = this;
}
public static MyPlugin getInstance() {
return instance;
}
working with mojang stuff go brr
?morepdc
You can create custom persistent data types on your own, or use one of the many libraries available which have implemented those which match your needs. Learn about more persistent data types here: https://www.spigotmc.org/threads/more-persistent-data-types-collections-maps-and-arrays-for-pdc.520677/
i wonder if that allows it
oh that one
That might allow a block to be serialized
that allows you to save pdc onto any blocks
not needed for chests, been as they are tile entities
Probably just remove block from the serializable class instead
If I want to reference my plugin, for example here: runnable.runTaskTimer(plugin, 0L, 20L); how should I do it?
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
that too
already wrote 300 lines just to deserialize the client recipe jsons 🥹
what's that?
how is it that bad?
I was joking
but to be fair
my code is usually pretty shit
Player p = ie.getPlayer();
Block b = ie.getClickedBlock();
p and b
What are you going to do with these recipes?
lemme send a support mail to ask whether they can cleanup the code
oh its for minestom, recipes dont work out of the box there
Ah, right, that's cool! :). Getting right into the things we all take for granted, xD
fabric yarn is probably better
i also found out just registering recipes to the server does nothing, there was a huge TODO which i didnt see
🥹
more packets lets go
Yeah, it's funny what you face when you try to build something from scratch. Mojang just inlines their recipes into the server jar, a custom server is going to have to parse client info, xD
got a free today tmrw so i hope i can implement the whole shaped recipe thing
currently i only get 11 illegal state exceptions
Uh, btw, what was that in reference to?
i believe it was actually able to load 545 recipes
That's pretty nice work, I know since I implemented my own workbench once, lol
oh ye it was able to load a bunch of recipes
dont ask me if the data is correct cuz mojang finds it funny to sometimes include the "group" key in the json and sometimes not
Hey, I have a very large text file I'd like to store(10k lines), what algorithm can I use in order to convert it to a small chunk of text and then decode it back?
oh you gotta be kiddin me
Do you mean what you can use to compress it?
what data does it contain?
Yeah, I think that's the correct term
Wrap the OutputStream in a GZIPOutputStream and call it a day, lol
Song names
I'm limited by space so I need to some kind of manipulation on the names instead of simply using a txt file
thank you, I will try!
no idea if writing the binary data to it will save more space than using ascii characters?
Here's an example of how I used it to encode binary data: https://paste.md-5.net/qitumehoce.cs
Text is nothing but bytes, I'm sure it will also do fine on compression there.
What algorithm does this use?
if you remember
real men just use a record inside of a tuple
Deflate, I think
thank you very much 🙂
I'll let you know if I have any problems
is there any way to check if something is a valid playername or the name is associated with an account
Or? It's kinda only valid if it's associated with an account. Do you mean still available by valid?
it would work if i didnt realise the other variant of this would be way longer
How to compare 2 UUID
Well it's not working
Wait
Is a unserialized UUID object the same as a player UUID object if it's the same player?
No, right?
It should contain the same bits, so it should be equal, but it will not be at the same memory address (==)
Ok that's fine then
So no clue why it says false
if (!ultraChest.getAllowedPlayers().contains(p.getUniqueId()) || !p.hasPermission("ultrastorage.admin") || ultraChest.getOwner().equals(p.getUniqueId()))```
Have you printed out both the left as well as the right hand side of equals and checked them visually?
Yes
Nono
Mistake
Still not fixed
getUUID() returns a UUID
Other ideas @dry yacht ?
Messages.send(p, "Owner: " + Bukkit.getOfflinePlayer(ultraChest.getOwner()).getUniqueId());
Messages.send(p, "Your UUID: " + p.getUniqueId().toString());
hey guys should I use protocol lib's packet events for signs (where you put like [Click] and when it clicks it sends you a message or smth) or should you just use spigot events
wtf
which would be better
Why did you go through Bukkit#getOfflinePlayer for the log? xDD
copilot moment
Also, have you printed out the equals result? This if statement could maybe not even call the comparison, as it's inner expressions are joined by or
This
Is ultraChest.getOwner().equals(p.getUniqueId())
if (!ultraChest.getAllowedPlayers().contains(p.getUniqueId()) || !p.hasPermission("ultrastorage.admin") || !ultraChest.getOwner().equals(p.getUniqueId())) {
Messages.send(p, plugin.messages.MSG_NOT_ALLOWED_TO_OPEN_ULTRACHEST);
Messages.send(p, "Allowed: " + ultraChest.getOwner().equals(p.getUniqueId()));
Messages.send(p, "Owner: " + ultraChest.getOwner());
Messages.send(p, "Your UUID: " + p.getUniqueId().toString());
return;
}
How tf is my if broken lol
Well, I don't understand the logic because I don't know your plugin, but the UUID comparison works, xD.
Spigot events, most definitely.
Well if you look at the if
It's an OR if
Oh I know what it is
Bruh
XD
I want to die
ok
So... what is it?
Uhm, there is, it's ^
Did they say there's none? xD
Car car = Car.dieselAndManualCar();
boolean dieselXorManual = (car.isDiesel() && !car.isManual()) || (!car.isDiesel() && car.isManual());
XDDDDDDDDDDDD

Quite literally, huh
I'm also working on UIs right now, xDD. What a coincidence. Haven't touched them in months.
smile inspired me with his guide, xD
If you want a bit more of an explicit XOR, there is a Boolean.logicalXor() method
https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/Boolean.html#logicalXor(boolean,boolean)
Though that's best used as a method reference
It's fine just dumb websites saying there is no XOR
The baeldung website you linked definitely mentions ^
:,D
Now i'm trying to think
baeldung da 🐐 no 🧢
So
What are some ways to make a item selector
Fancy ways maybe
I was thinking anvil selector but then the user needs to know the exact name of the item
Putting all items into another GUI and just return the itemname? Seems a lot
Ideas/
Uhm, what kind of selector? Like, what's the palette of choices? Are there many items?
Yeah like
For example
Like I want the user to be able to chose an item to add to a filter, ignore the filter part I just need a item pallet
Is gui the fanciest way? 😦
Yeah, I usually use a live anvil search for that, where the search term can be either something in the name, lore or material of the item
But that's not that trivial
But anvil search does not autocomplete
So they have to have an idea of what it is
Doesn't need to. Usually you've narrowed it down to a few after like 5 letters
Yeah, you should have an idea of what you want, xDD
Ah I see, I mean I have AnvilGUI
I could do that
Or I could use an anvil and just make them place the item instead
Requires them having 1 of the item
Fuck it I'm doing that
Hey guys! I'm making a resource pack and I'm trying to make a custom sound for when you open/close your chest
I made a .ogg called "chestopen" and put on minecraft/sounds/random
I thought It would work, since I did the same with the click sound and It worked (both are located at random)
Material::isItem
How can I make a custom Material list with this format
Predicate<Material> itemFilter
iirc Map/List.stream().filter(Material::isItem).toMap/List()
Wait
So you say make a List of all the materials I want to use
And then use that above
yeah, theres probably a way to you can do it with 1 list/map
i think thats right anyway
that might only exist for lists
this.itemFilter = itemFilter.and(MATERIALS::contains);
Was even easier
But you had the right idea
I found out
You have to edit sounds/block/chest
to make It work
not sure why the ambiguous file system
but It works!
Someone updated Minecraft Development plugin in IntelliJ?
I currently have a HashMap with keys as the spaces (0 - 8) and values as the itemstack for a custom crafting recipe being checked in the PrepareItemCraftEvent. Just was wondering if there is a better way to do this because it seems weird but its the only way I could find from what I was looking up.
Hi guys, i was coding my first plugin and got a little problem. I was coding a sethome plugin that is working but I don't know how to create a /homes command that shows you all your homes. So if you can help me guys plz.
That's how i coded the sethome :
Main.getInstance().getConfig().set("home." + player.getUniqueId().toString()+"."+args[0]+".x",player.getLocation().getX());
Main.getInstance().getConfig().set("home." + player.getUniqueId().toString()+"."+args[0]+".y",player.getLocation().getY());
Main.getInstance().getConfig().set("home." + player.getUniqueId().toString()+"."+args[0]+".z",player.getLocation().getZ());
Main.getInstance().getConfig().set("home." + player.getUniqueId().toString()+"."+args[0]+".pitch",player.getEyeLocation().getPitch());
Main.getInstance().getConfig().set("home." + player.getUniqueId().toString()+"."+args[0]+".yaw",player.getEyeLocation().getYaw());```
Well wherever you are storing the homes you would have to get the specific player and loop through the list of the names of the homes I would recommend making a list so you could print the list out in a message to the player
yes but the list is temporary
like how do i put it in the config doc
and the problem is that i don't know how to loop through the names of the homes, like i don’t know how to separate them
from the other info
Can you show me how your config is storing the data right now in a pastebin?
or if its not a lot of data just throw it in here
I'm trying to understand the new world generation API. ChunkGenerator has the methods generateNoise(WorldInfo, Random, int, int, ChunkData) and generateSurface(WorldInfo, Random, int, int, ChunkData). My understanding of world generation is that noise is used to determine the height of various parts of the terrain. The generateNoise method will generate a height value for a given x,z location then use a filler block to populate up to that height. Then generateSurface will go over those locations and modify the surface blocks to make it look pretty. So how does generateSurface know that the height values are that were generated by generateNoise? The latter method does not save those noise values anywhere as far as I know.
gonna kill myself its not working anymore
and dont know why
like everything works but when I try to teleport to the home it sends me an error
;((
rip
If I want to declare a List<String> in a statement and I want to set the elements, how can I do so
setLore(#Make new list here and set the lore in the same statement)
Is List.of(Strings...) the best?
What is the difference between R1 R2 R3 ?
Hi I'm trying to parse YAML with snakeyaml. I want to store a bukkit vector like this
offset:
x: 1.0
y: 1.0
z: 1.0
But I'm getting an error
No writable property 'x' on class: org.bukkit.util.Vector
I don't understand why because I'm allowed to do
Vector().x = 1.0
and vector seems to have a public setter
Hi I m trying to parse YAML with
Anyone know how to use hex codes on scoreboard? Normal color codes work fine and I know it has to do with md5's bungee api for chat color, but im still not entirely sure what to do with it
which version ?
1.19.2
&x&R&R&G&G&B&B
but replace & with section sign :v
this didnt work no matter how i tried it
This runs every time I place a block.
val relativeLocation = when (counter.relativeTo) {
Move.RelativeTo.LAST_ACTION -> lastMoveLocation!!
Move.RelativeTo.ACTION -> placeLocation
Move.RelativeTo.PLAYER -> playerBlockLocation
}.add(counter.offset.toVector())
player.sendMessage("x: ${relativeLocation.x} y: ${relativeLocation.y} z: ${relativeLocation.z}")
If I break and place blocks it should send the same location with a specific, but it keeps adding the offset every time
any idea what could be causing this?
whats counter.offset?
Okay ! (This is gradle stuff, so if you've never used gradle please pass your way)
So I try to create a "parent module" which will use sub modules (depend on the server version), but I can't compile correctly !
So here's my structure
RisenCore (parent module)
- src (parent src with all the stuff no depend on the child modules)
- build.gradle
- module1
- build.gradle (dependence on parent module)
- module2
- build.gradle (dependence on parent module)
So I want to compile all that stuff in a single jar file.
But when I compile with the jar task from the parent build.gradle it compile only the "parent", I would like to compile the whole stuff
So here's my 3 build.gradle
(parent)
plugins {
id 'java'
}
group 'net.krisp'
version '1.0.0'
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
compileOnly 'org.spigotmc:spigot:1.19.3-R0.1-SNAPSHOT'
}
setLibsDirName("../exports")
module1
plugins {
id 'java'
}
group 'net.krisp'
version '1.0.0'
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
implementation project(path: ':')
compileOnly 'org.spigotmc:spigot:1.8-R0.1-SNAPSHOT'
}
module2
plugins {
id 'java'
}
group 'net.krisp'
version '1.0.0'
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
implementation project(path: ':')
compileOnly 'org.spigotmc:spigot:1.8.3-R0.1-SNAPSHOT'
}
Thanks again for reading 😭
(Srry btw)
@tender shard hey, you available for a MPDC question?
Hey, I'm trying to put a custom font on a placeholder any idea how?
Gl @opal cedar
is that like not doable? 😂
Jan, help me out with some serializable stuff
The error is because the Hologram field on my Serializable class starts as null and it doesn't like that.
https://paste.md-5.net/alawabisax.bash
https://paste.md-5.net/kewudafuso.cpp
Should I figure out a way to make a default hologram? Maybe use a static hologram with no data at 0 0
I could make a fake hologram at the loaded world 0 0 with no data, make every single instance of UltraChest default to that hologram and then once it's setup it will change it?
Sure, that’s one way to do it. Other way would be to not serialize the object if it’s null.
Can i see the createNewStorage method?
public static void createNewStorage(Player player, Chest chest) {
UltraChest ultraChest = new UltraChest();
ultraChest.setOwner(player.getUniqueId());
ultraChest.setLocation(chest.getLocation());
System.out.println(chest.getLocation().toString());
PDCUtils.set(chest.getLocation().getChunk(), NBTTags.ULTRA_CHEST_LOCATION_KEY, DataType.LOCATION, chest.getLocation());
PDCUtils.set(chest, NBTTags.ULTRA_CHEST_STORAGE, getDataType(), ultraChest);
plugin.ultraChests.add(ultraChest);
chest.update();
}
Yeah
Show me that class.
That's the serializable
Oh wait
I just figured it out
I think
lol
Just take it out of serialize() and deserialize()
That’s not NBTUtils.ULTRA_CHEST_STORAGE
I see
Would this not do the trick?
You can just make a new one hasHologram boolean and set that to false if hologram is null. Don’t add hologram if it’s null.
Oh
That's actually a better idea
I was thinking removing the hologram like you said and then having to add it back every time I load it
But I think your way is better
if you had to chose between hasHologram boolean and default empty hologram at 0 0
Which one would you chose
The one without smth at 0 0
Dope
Bumpy
Time to test!
Location spawn = new Location(world,0,1000,0);
what can i put in "world" (not player.getLocation().getWorld())
like to setup a spawn
Bukkit#getWorld
yes but like there is no name for like the overworld or something like that ?
It's the default world?
yes
?paste erroor
That's not what I said to do...
I said Bukkit#getWorld(String worldname);
You cant pass a String there. You need a World object.
selfrole Add or remove a selfrole from yourself.
cleanup Base command for deleting messages.
embedset Commands for toggling embeds on or off.
info Shows info about CafeBabe.
licenseinfo Get info about Red's licenses.
mydata Commands which interact with the data CafeBabe has about...
set Commands for changing CafeBabe's settings.
uptime Shows CafeBabe's uptime.
findcog Find which cog a command comes from.
names Show previous names and nicknames of a member.
userinfo Show information about a member.
listcases List cases for the specified member.
reason Specify a reason for a modlog case.
permissions Command permission management tools.
declaration: package: org.bukkit, class: Location
^ not allowed
XD
'bout that i've just found myself
So i just tried to add smting to jar task
I've read the doc, and you just have to add the "location" of the sources
soooo
I've done that
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
for (final def module in subprojects) {
from module.name + "/src/main/java"
}
}
buuuut
it's
.java
not .class
😭
Of course lol
yeah
Then you gotta explain your issue better
Gl getting someone to help you now "senior java developer"
"/src/main/java" is a source path
My issue is that I need to "compile" all my subproject, than put all the compiled file in my final jar
yea
so i decided to change that
/build/classes/java/main
xd
why are you even manually trying to specify classes to include?
Because I don't know how to do it automaticly without creating a "circular dependency"
I don;t use Gradle but probably the shadow plugin
I already tried that
Yeah I'm not going to guess anymore, you provide so little information
Ask a complete question
.
that was my initial question
that no one red
ok you never specified yoru modules in your parent
...
actually this is probably better for you https://docs.gradle.org/current/samples/sample_java_modules_multi_project.html
java.lang.NullPointerException: Cannot invoke "me.tomisanhues2.ultrastorage.mechanics.AUChestHologram.updateHologram()" because the return value of "me.tomisanhues2.ultrastorage.data.UltraChest.getHologram()" is null
Would you explain it to me please, I don't understand how it is formatted, I would be appreaciated
Why am I getting that if I specified my method is nullable
@Nullable
public AUChestHologram getHologram() {
hasHologram = hologram != null;
return hologram;
}
I don;t use Gradle, I use Maven so it's different
Duh
already listen that
but it's really not the samething I did
I don't want to edit my whole structure
multi-module requires a specific format
Well, then I will use my "blr" setup which is very bad, but works
Nullable does not make it so you can just call it an expect it to handle null
Seems so
Is there a way to simplify checking whether 2 locations are within the same block? instead of i.e.:
if (loc1.getBlockX() == loc2.getBlockX() &&
loc1.getBlockZ() == loc2.getBlockZ() &&
loc1.getBlockY() == loc2.getBlockY()) {
// ...
}```
Does BukkitRunnable#runTaskTimerAsynchronously() also run BukkitRunnable()#run()?
yes
I can't use that to tell if it's at the same block location though. The distance could be 0.2, but it could still be in a different block.
<1 is still the same block
If the location is set on a block itself
If you get the location of a block
It will always return X.00
Meaning any change will be a different block
Just round it
Or
nvm that's the best
¯_(ツ)_/¯
What would be a better way of writing this? java public void RemoveLoc(Location loc, CommandSender sender) { loc.add(0.5, 1.4, 0.5); if (!scrapLocations.contains(loc) || !lootedScrapLocations.contains(loc)){ sender.sendMessage("That block is not a previously added location and therefore cannot be removed."); return; } if(scrapLocations.contains(loc)) scrapLocations.remove(loc); if(lootedScrapLocations.contains(loc)) lootedScrapLocations.remove(loc);
Ignore the second line
You can just remove
It returns boolean
True if that list already contained element
Ok first of all: Locations are very very precise.
If you have a location at
(1.5, 1.0, 1.5)
Then a location at
(1.5, 1.00000001, 1.5)
Is already completely different.
So using Locations as Block identifiers is a pretty bad idea.
Next:
Collection#remove(Object) returns either true if the Object was removed or false otherwise.
So checking for contains before removing an Object is not necessary.
if(!list.remove(something){
sendMessage(Sorry, can't be removed because it doesn't exist)
}
- the locations won't ever become 1.0000000001 y, because of how the code works. I'm pretty sure it'll always work properly when it comes to locations.
- Oh that's cool I didn't know that
But then how would I do that if I had two lists, and a single lloc can be in one of them?
private final Set<Location> scrapLocations = new HashSet<>();
private final Set<Location> lootedScrapLocations = new HashSet<>();
public void removeLoc(Location loc, CommandSender sender) {
loc.add(0.5, 1.4, 0.5);
if (scrapLocations.remove(loc)) {
sender.sendMessage("A scrap location was removed.");
return;
}
if (lootedScrapLocations.remove(loc)) {
sender.sendMessage("A looted scrap location was removed.");
return;
}
sender.sendMessage("That block is not a previously added location and therefore cannot be removed.");
}
if(!list1.remove(smth) | !list2.remove(smth)) {
sendMessage(Sorry can't remove because both locations didn't exist);
}
This is closest to your previous code
As you send message only if both lists/sets didn't contain loc
Ohh that's smart, I get it now
I would not use a bitwise or here
Isn't that only way that it's guarantee that both operations would be ran
Yes but it introduces ambiguity about which of those operations executed.
Oh yeah, that is right, but it's just what his original code did
I meant i would separate the conditions. || wouldnt work ofc.
Unless the sets have exclusive access to locations
round the x,y,z of the location before all operations, if you are workgin with blocks.
or construct yrou own Location object using ints
Alright so now I have this code that allows you to add, remove and list blocks to a list, and adds particles above them. If you right click the blocks, the particles disappear for a few seconds.
The thing is, I want it to be more customizable, so that players can do /sc add [particle] [cooldown] [loot]. The loot should be a list of some sorts because it should give you a random item from a set of items (specified by [loot])
Im using the exact block location method thingy, that always returns a rounded (Specific) block location.
Got something to show
good
looks good
Thanks
What does notscheduledYet error mean
Like I know what it means lol but like
two things MC really needs... Billboards and my mind went blank and I can;t remember the second 🙂
occurs when you attempt to cancel a BukkitTask that has not yet been scheduled to run.
🤔
you must be somewhere
yea
public void attemptStartSell() {
if (this.sellUpdateTask != null) {
return;
}
this.sellUpdateTask = (new SellTimerTask(UltraStorage.getInstance())).runTaskTimer(UltraStorage.getInstance(), 20L, 20L);
}
public class SellTimerTask extends BukkitRunnable {
private final UltraStorage plugin;
private List<UltraChest> ultraChests;
private Map<UltraChest, SellTask> sellTasks = new HashMap<>();
public SellTimerTask(UltraStorage plugin) {
this.plugin = plugin;
ultraChests = plugin.ultraChests;
}
@Override
public void run() {
if (ultraChests.isEmpty())
return;
for (UltraChest ultraChest : ultraChests) {
if (sellTasks.containsKey(ultraChest)) {
sellTasks.get(ultraChest).cancel();
sellTasks.remove(ultraChest);
}
sellTasks.put(ultraChest, new SellTask(ultraChest));
}
}
}
no cancel anywhere
sellTasks.get(ultraChest).cancel();
They should be tasks
But does this code even remove them from the list? When I try to remove a loc that has been looted, it says it removed it, but it just reappears after the cooldown.
Or does it have to do with the scheduler
That means I would also have to cancel the task of that loc
I hope you just have one task for all locs and not one task for each loc
One task for each loc
Because otherwise they all cooldown at the same time
and that wouldnt work right
and a specific particle for each too
So what does a map do
There are a lot of approaches for cooldowns like this. The most sophisticated would be to use a PriorityQueue for this.
But creating one task for each Location seems like a logistical nightmare. Every time i see people manually
starting and cancelling hundreds of tasks i can smell the problems emerging.
then create an Object
an Object which contains teh location, the cooldown, particle and anythgin else you need
And a priorityqueue would do the same as tasks?
I feel like you should create more classes. It looks like you are using a lot of raw dangling Collections with
Objects like Location, Block etc.
Hmm alright, but how would I pass that information when calling one of the functions from the commandListener class
all you do is pass the location
?
as thats all your command sets?
No?
It does now
But I said I want to add arguments that let a player specify, cooldown, items, and particle
then you create a method which accepts a new YourChestObject
Then that also has to be passed right?
my item cooldown manager just stores and uses system time haha
might not be the best solution for laggy servers but it works
new YourChestObject(Location, Cooldown, Particle)
Hmm alright, but what do you mean with the YourChestObject?
a class you create to store all these things
👍
So I guess I should pass down all the parameters in the Add(loc, cooldown, particle, items) method, then make a new YourChestObject in the addmethod as well, that globally stores those variables
Here is an idea of what a scrap pile could look like:
public class ScrapPile {
private final long cooldown;
private final List<ItemStack> loot = new ArrayList<>();
private final Particle particle;
private long respawnTime;
public ScrapPile(long cooldown, Particle particle) {
this.cooldown = cooldown;
this.particle = particle;
}
public void addLoot(ItemStack itemStack) {
this.loot.add(itemStack);
}
public long getCooldownLeft() {
long now = System.currentTimeMillis();
long timeLeft = respawnTime - now;
return timeLeft;
}
public void startCooldown() {
long now = System.currentTimeMillis();
this.respawnTime = now + cooldown;
}
public Particle getParticle() {
return this.particle;
}
}
In it's constructor you can auto assign values if any of the values are null, and normalize your location
Honestly: Create more classes. It will help you build very powerful systems in a fraction of the time eventually.
But this is a really small plugin and creating a billion classes for like 4 methods seems too unnecessary and too unorganized for this
you are usign holograms, particles, cooldown and chest. Not so small
If you are using a scheduler and keeping track of locations etc then what you are doing is borderline chaotic.
Classes is what makes a project organized in the first place.
my class count usually averages out to 2-3 classes per logical system of my plugin
Hmmm alright
Cant say that for mine...
....
yeah well you are a little insnae
When I make that many classes I need to look 5 hours before I find the class I need to work with
and too good at what you do
thats what packages are for
That's a work of art right there
structuring a project is also a skill to learn
How many lines main class?
But how would I store this information? I get the information initially from my commandListener class, that sees if I used /sc add [loc], [particle], [cooldown], [items]. I can't just say Particle particle = args[1]
Is there a "getAdvancementManager" method ? ChatGPT tells me that I shall use this but I can't find any document about it
How do I get the display name of an item in a created inventory using the InventoryClickEvent?
Isn't that on the meta?
Yes but does it affect performance? 1 class that does everything or 100 classes that split it up? Im the kind of guy who'd write 20k lines in one class, because it's organized imo
Start by creating yoru object to accept yoru location, as thats all yoru command does right now
Yes but the whole point of creating this object is so that I can pass in more arguments
yes, expand it later
learn how to create and store teh object first
instead of your current method of add(Location) you would use add(YourChestObject)
No it wont affect performance. Also: Organisation >> Performance
Structured code will lead to well performing code.
Java/oop is all about classes
And if you write everything in one class then you will fall on your nose really fast. You will run into seemingly unsolvable problems and just stop programming.
hmm mkay
At least trust Elgarl on this. He has a lot of experience.
Idk how long actually XD
Does this look good? ```java
import org.bukkit.Location;
import org.bukkit.Particle;
import java.util.List;
public class ChestObject {
private final Location location;
private final Particle particle;
private final long cooldown;
private final List<ItemStack> items;
public ChestObject(Location location, Particle particle, long cooldown, List<ItemStack> items) {
this.location = location;
this.particle = particle;
this.cooldown = cooldown;
this.items = items;
}
public Location getLocation() {
return location;
}
public Particle getParticle() {
return particle;
}
public long getCooldown() {
return cooldown;
}
public List<ItemStack> getItems() {
return items;
}
}``` Im not sure if the last 4 methods are really necessary though, I added them to be safe
I guess theyre useful if you want specific info
Could anyone answer my question? I suspect chatGPT is wrong🤔
Im pretty sure it is
Tell it that thats not correct
and ask it what version of the docs he's using
Yes make all your fields private and let your IDE generate getters and setters for them.
Fields that never change can be also final.
looks good
Why make them private? And what do getters and setters do
Theyve always confused me
always private, only enums should be public (mostly)
Doesnt making them private make it harder to access them in other classes?
I tried generating the getters but it doesnt work anywhere
if code has to access them via getters they can't be accidentally re-assigned
It keeps saying this
you already have getters
where
public Location getLocation() { etc
getters
So how do I get the setters
You have final fields so you cant generate setters
I mean, if someone wants to change a location, they just remove it and make a new one
Ahh alright, thanks
wait intellij can generate them
you probably want to alter your cooldown?
Apparently
Then Ill just remove it and make a new one
I dont want to make it too complicated lol
It should be a simple plugin
just use lombok
if you want to be able to chage your cooldown take final off it's definition
Yes but why would I want to change cooldown?
It's a standard number let's say 60 ticks, then that's how long the cooldown is
I assumed it was a cooldown counter, is it just a fixed value?
do you guys know if it is possible to tell to shadowJar task to relocate everything?
with some exceptions
It should be a fixed value. At least, thats what I imagine it should be
It specifies how long it should take
ok if its a fixed value then keep it final and no setters
first off, chatgpt is outdated by like 1-2 years, and secondly, why do you need an advancementmananager?
relocate() and exclude() methods maybe
Chatgpt's data only goes to 2020 or so
make it a record if you want
exposing collections goes brr but its needed here as far as i see
he is basically creating a Record but he's only just starting with multiple classes so lets go one step at a time 🙂
thats dumb, might aswell teach the best way to do this stuff from the start
Alright so now that I can make a ChestObject, how would I pass in the arguments from the command? As I said earlier, I can't just say Particle particle = args[1];
no Records are a next step
just make a record, that will turn this object into like 3 lines if code
it would, and he'd learn almost nothing
you construct the object in yrou onCommand
new ChestObject(Location, etc
Yes I have this, and I can pass in blockLoc fine, but what about the other arguments?
Such as particle, cooldown etc.
new ChestObject(blockLoc, args[1], etc.) wont work
if you want an actual Particle you can Particle.of(String) or somethign close
Particle.valueOf(
that does require them to type the correct particle value though
you can make that easier later with TabComplete
chatGPT is cheating me. I told it that unsafe() is deprecated, and it tells me that I shall use Bukkit.getUnsafe().fromSpecificServer(AdvancementManager.class);
🤔
Because it's outdate
d
only gets info from before 2020
so changes after that are not recorded in chatgpt
bad news
How do I implement the TabComplete? I looked at an example but it looks like it would break everything I have so far
get everything working first
TabComplete is an enhancement you add once you have it all working
alternatively you can use a command framework
God no, don;t use a framework for a beginner
fair enough
But what would someone have to type for the Particle argument? /sc add SCRAPE ... or /sc add minecraft:SCRAPE, or something else?
if SCRAPE is a particle then just that
Ugh this stuff is so confusing sometimes. Now I have the chestObject and I passed it on in the Add(ChestObject chest) method, but how can I now access this chest in other methods? And how can I store multiple chests and check which is which using the location?
I wonder how I can insert my customized advancement to a proper location in the advancement tree, for example, between Tactical Fishing and The Cutest Predator.
You store them in a Set, just as you were before with Location
So I just add the chest to a set
and when I want to remove a location I just remove the chest from the set
OR you can use a Map<Location, ChestObject>
Sounds alright, but then how can I check which chest is which using the location
And what does that do
to make it easy to pull the correct one based on Location, if you need that
it really depends on what you need to do with them
Ill go for a map then, I think
if you are just looping over them to do the particles, then a Set is all you need
if you want to pull a specific ChestObject then you need its Location so a Map
I also need to remove specific ones
then a Map
and get loot from specific ones so map it is
Map or HashMap?
Map<Location, ChestObject> yourCollection = new HashMap<>();
they will be stored using teh Location as a Key so be sure you are normalizing it
normalizing?
I'm not going to be about for a while, Wife is coming home from Hospital today so if you get stuck I'll be unavailable.
:(
Ah alright, thanks a lot for the help so far though! Hope your wife's doing alright
can anyone help me?👀
Theres a few videos on youtube, i don't know if they show it, but you could maybe take at look at them.
ok thanks
I get this error when I run my command that keeps on looping itself. Can someone please help?https://paste.md-5.net/ucoresavur.cs
I don't get why the return value of "java.util.Map.get(Object)" is null
whats on ParticleHandler line 106
public void spawnParticlesEverySecond(Plugin _plugin) {
Particle particle = Particle.SCRAPE;
plugin = _plugin;
BukkitRunnable runnable = new BukkitRunnable() {
public void run() {
for (Location location : scrapLocations) {
Particle particle = chests.get(location).getParticle(); // line 106
Objects.requireNonNull(location.getWorld()).spawnParticle(particle, location, 7, 0.1, 0.2, 0.1);
}
}
};
runnable.runTaskTimer(plugin, 0L, 20L);
}
normalize teh location in yoru onCommand of the construtor of CHestObject
probably that
Normalize = round it off?
yes
But if I do that, the spawn location of the particle is messed up
adjust the particl in the spawn method
k
Ill remove all the location.add thingies and Ill normalize it
How do I normalize it?
the .normalize() doesnt work
it doesnt exist
set x,y,z to the getBlockX() getBlockY() getBlockZ()
I can also do ```
public static Location normalizeLocation(Location loc) {
float pitch = loc.getPitch();
float yaw = loc.getYaw();
// normalize pitch
pitch = pitch > 90 ? pitch - 180 : pitch < -90 ? pitch + 180 : pitch;
// normalize yaw
if (yaw < 0) {
yaw += 360;
}
yaw %= 360;
loc.setPitch(pitch);
loc.setYaw(yaw);
return loc;``` but that seems like overkill
or Math.floor
but then how do you put those 3 back into a location
loc.normalize()?
.
👍
mappings are fun
[10:51:48] [Server thread/WARN]: [ScrapCollection] Task #2 for ScrapCollection v1.0 generated an exception
java.lang.NullPointerException: Cannot invoke "me.JustinS_2006.particles.ChestObject.getParticle()" because the return value of "java.util.Map.get(Object)" is null
at me.JustinS_2006.particles.ParticleHandler$1.run(ParticleHandler.java:104) ~[?:?]
at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftTask.run(CraftTask.java:82) ~[server.jar:3284a-Spigot-3892929-0ab8487]
ughh why wont this stupid code work
Still the same error, even though Im normalizing it
ok delete yoru scrapLocations
you don;t need that set at all now
you can chests.getKeySet()
But it stores the locations that havent been looted
why not add a flag to your ChestObject for looted
isLooted
then you don;t need either of yoru two Sets
🙂
But for one of the if checks I go from if(scrapLocations.remove(loc)) to if(chests.remove(loc)) which arent the same right? And dont do the same. So what should I do here?
The locations that arent looted
yes
So basically unlootedLocations
but wait cant I simplify this entire method to 1 if check?
yep so if (chests.get(location).isLooted()) chests.get(location).setLooted();
I was trying to relocate sqlite jdbc drivers but that just broke the plugin. I saw this issue https://github.com/xerial/sqlite-jdbc/issues/145 where MD5 says that you can't relocate classes that contains invocation of native methods. So I was wondering how should we handle sqlite jdbc relocation to not clash with other plugins?
Im not setting it looted here
remove becomes setLooted()
once looted do you remove the chest?
Like, remove the location
dont make it looted or unlooted or anything
just remove it from existance
Use the driver provided by spigot?
thats what the remove function does
if you want to remove it when looted just remove from chests
chests.remove(location)
I want to remove it no matter if it's looted or not
So Ill just remove it from chests, yes
Wait is the goal to create lootable chests?
got to go, wife is home
Totally missed from the depend tree, ty
By adding that single boolean I reduced all my code by like 25% lol. So much space has freed up
Does the ! make sure it returns the reverse value?
return !chests.get(loc).isLooted();
So if chests.get(loc).isLooted(); is true, it returns false?
Coming back to this, can you explain how that cooldown works? Now I've got a lot of code working, but Ive arrived at the cooldown which needs some fixing. Rn I have:java public void spawnParticlesEverySecond(Plugin _plugin) { plugin = _plugin; BukkitRunnable runnable = new BukkitRunnable() { public void run() { for (Map.Entry<Location, ChestObject> entry : chests.entrySet()) { Location location = entry.getKey(); Particle particle = chests.get(location).getParticle(); Objects.requireNonNull(location.getWorld()).spawnParticle(particle, location, 7, 0.1, 0.2, 0.1); } } }; runnable.runTaskTimer(plugin, 0L, 20L * chests.get(location).getCooldown()); } though at the last line it asks for a cooldown which I don't have because it's different for each location.
So, what did you say was a better way of doing this?
How to place an head with a custom texture?
This looks ok
I tried casting the block state to Skull, but it didn't work
yes, its "not" operator
- Get BlockState of Block
- Cast to Skull
- Create PlayerProfile with Bukkit class
- Get PlayerTextures from it
- Set the texture URL on the PlayerTextures
- Set PlayerTextures on PlayerProfile
- Set PlayerProfile on Skull
- Call .update(true) on Skull
Make sure you have the right import and that the block actually is a skull
no wait
I didn't used "update(true)"
Hoping it wasn't the problem
Hello
Why couldn’t i find DiscordSRV plugin in aternos ?
We aren't aternos... also this is help development
Like I couldn’t find the plugin
Ask Aternos