#help-development
1 messages · Page 396 of 1
fucking lmao get rekt kid you thought crossProduct and getCrossProduct were the same method
lmao loser
have fun wasting 4 hours
I see
where do i need my config.yml file in? in my resources folder?
doesn't really matter but that's the place for it these days ig
I mean its the convention, so it does matter in that aspect
help
Is it really necessary to use Objects#requireNonNull() to get rid of the warning in intelliJ
??
@SupressWarnings("null") iirc
What's better? Using that or Objects#requireNonNull()
Objects.requireNonNull should only really be used in apis or libs, suppressing is better or just ignoring it
intellisense more like intellinnoying
true
You can use also use //noinspection NullableProblem
Could also be ConstantConditions instead of NullableProblems idr but one of those, and then you put that directly above the statement
I actually have this code inspection as strong instead of weak cause null in Java sucks
And no, it can sometimes be fine to use to implement fail-fast non-null behavior
@SuppressWarnings("ConstantConditions")
how do i cancel scheduleSyncRepeatingTask from inside?
dont all tasks have .cancel()?
yeah but how do i
i dont save BukkitTask variable
can i do that???
is there a default port for http to check on, like if i had http://198.168.0.2/ what port would it check for it attempt to resolve
443 iirc
80?
That's https
resolve?
like attempting to load the page
no port is used to resolve an address, thats DNS
the port used for communications is down to which protocol
this is very tragic
im testing how reposlite works before i get my domain so im not just fucking about trying to get it all working and if im even gonna stick with reposlite
and gradle doesnt like the port on the ip
ive got that done
gradle just doesnt like the port and i dont want to setup its proxy to work
ye shells 8080
i cant
maven requires https and probably ssl so port 8080 and 443?
runTaskTimer
whats difference
they havn't removed it but in many instances providing just http will fail with an error
i doubt ssl runs on 443
scheduleSyncRepeatingTask is old and arguably legacy
nvmind im dumb
runTaskLater, runTask and runTaskTimer are superior options 99% of the times
on a completely different topic, does anyone know why Blob::getBytes(long, int) doesnt take a long as 2nd argument if Blob::length() returns a long? Blob::getBytes args are int position, long copycount
thanks
it does
🙂
anyways do u know this by chance?
Blob?
Ah
like it will work if i just put an int there
but it feels wrong
if a blob can have a long size why can it onlny spit out int bytes of that
Yeah that’s a bit counter intuitive
i mean that also means a DB can, at max, store a 2.1GB object
whic
well i wont reach
but if you want to store images or video files
Seems like you otherwise have to retrieve the blob part by part
luckily i really doubt that a serialized anything from minecraft reaches gigabytes in size
Retrieves all or part of the BLOB value that this Blob object represents, as an array of bytes.
(getBytes)
part of the BLOB value
Tho in that case I assume you have to manually keep track of the parts, sounds like a hassle
Poor api :>
i mean
Lol ye
🥲
though my documentation is my problem lol
/**
* Black magic out
* @param data
* @return
*/
So useful
i mean
i just use the code
i dont understand it
byte[] blobData = data.getBytes(1,(int) data.length());
ByteArrayInputStream bis = new ByteArrayInputStream(blobData);
BukkitObjectInputStream ois = new BukkitObjectInputStream(bis);
int length = ois.readInt();
ItemStack[] stack = new ItemStack[length];
for (int i = 0; i < length; i++) {stack[i] = (ItemStack) ois.readObject();}
ois.close();
return stack;
nice path
i question how ive managed to get this far a lot
wait a moment why does the compiler complain about the first argument of getBytes not being a long only if the second isnt an int
?????
does maven like http domains
Also moterious
getBinaryStream exists, just saw that
Which takes length as a long data type
(Cause I assume you can just go with InputStream::readAllBytes, altho u might wanna avoid that as if the array is large enough it could cause the system to hang)
i mean
the only reason to use getBinaryStream is if you either read ur data one by one or a large amount at once
so i expect lag with that one either way
what does spigot() do?
It provides the player’s Player.Spigot object
Which has a set of methods involving bungee chat api amongst other stuff
ok
oh god mojang thought it was fun to put references to other groups in a group file
anyone got or know of a doc that explains how to get java docs jar from a repo and convert that to the javadoc site automatically
@ParametersAreNonnullByDefault
public NewAbstractMachine(ItemGroup itemGroup, SlimefunItemStack item,
RecipeType recipeType, ItemStack[] recipe) {
super(itemGroup, item, recipeType, recipe);
createPreset(item.getItemId(), getItemName());
addItemHandler(onBreak());
}``` This is the constructor of an abstract class. The createPreset() method has already a default implementation. If I create an instance of a child class which has its own implementation of that method, when the super() is called in the constructor of that child instance it will use its implementation of the method createPreset(), right?
Yes
im guessing i just decompile the latest jar every X hours and run it from index.html
createPreset() is effectively equivalent to this.createPreset() which refers to the most concrete implementation of the method, so if you were to have class FinalNewMachine extends NewAbstractMachine and assuming FinalNewMachine::createPreset is defined in the class itself then that would be the method used.
okay, ty : )
Most object oriented languages usually work like this speaking of which fyi (:
I'm in rehab, I don't have time to explain people how to read blog posts lol
I read it tho, put everything that needed, does not work, unless im missing something dunno
Rehab from using maven?
Gj
Alex is our resident hobo
@lost matrix I am making a "panel-type extension" to your GUI implementation which you showcased in your guide. So you can keep specific parts of the GUI "loaded" while you need it.
Like for example if you always want to have a "go back" button in every inventory that you would need it
Once I'm done I'll take some criticism
Poor alex 
This is interesting
Mind if I ask you some questions regarding it smile?
In your example
this.guiManager.openGUI(new PianoInventory(), player);
is how you create a new inventory for piano.
But what if you need another variable inside the PianoInventory class?
for example:
this.guiManager.openGUI(new PianoInventory(int inventorySize), player);
Do you need to adapt the GUIManager or just change stuff inside the PianoInventory?
Just the inventory. The manager doesnt need to change for that
But I made a new constructor for it and I'm getting NPE
private UltraChest ultraChest;
public MainMenuInventory(UltraChest ultraChest) {
this.ultraChest = ultraChest;
}
Either I'm messing up with something basic that I shouldn't be or I am a bit confused
Nothing here can throw a NPE
Ah so that answers it
createInventory() gets called first, right
That means changing the title of the inventory to something that comes from the parameter is not possible
Because it hasn't been assigned yet
So doing ultra.getName() throws NPE
Makes sense
If MainMenuInventory extends InventoryGUI then you need to call super() in your constructor ofc
Yes I did that
In my next debugging test
But still throws npe on return Bukkit#createInventory
Cause of the name
I'm thinking how to do dynamic inventory names then
I see the problem. Then move the createInventory from the constructor somewhere else
makes sense
Won't look as pretty but that is a good solution
Thanks
Not the prettiest but can't I just take it out of the constructor call it manually in each Inventory.java constructor?
public MainMenuInventory(UltraChest ultraChest) {
super();
this.ultraChest = ultraChest;
createInventory();
}
Eh maybe in the open method or in the manager. Else you will just pass the problem to the next
extension of your class.
how do i get rid of this warnings without object.requirenonnull?
Objects.requireNonNull() is not as horrible as people make it look like.
Its a simple fail-fast tool which is totally fine in some places. Usually you should do
proper null checks but when registering commands then this is absolutely usable
to give a quick indication that you forgot something in your plugin.yml
Supresswarnings or disable it in ijs settings
i think my plugin.yml looks fine
I use it internally with lomboks NonNull annotation
suppresswarnings?
which one
Internally i use guavas Preconditions
which suppresswarning
???/
@SuppressWarnings("null")
i tried this
but warnings are still there
whats wrong
It should be more like
{
"locationX":5,
"locationY":5,
"locationZ":5,
"locationYaw":5.0,
"locationPitch":5.0,
"identifier": "bedwars:position"
}
Right?
Yeah just create a custom TypeAdapter for whatever Object your "identifier" is
You should create one adapter which implements JsonSerializer<YourObject> and JsonDeserializer<YourObject>
Then register this adapter for your class
TypeToken will make this pretty easy
@SuppressWarnings("ConstantConditions, NullableProblems") i think? Havent been on intellij for quite a while now
I have a question
How would you extract duplicate code for this method?
What if you need 10 different ones, there has to be a better way to do this
https://paste.md-5.net/nininikoka.cs
Each one of these items should have a different consumer event, and as you can see the data used to create the metadata is different. Otherwise it's exactly the same
?paste
You could make an enum and a single function that takes the enum, and other additional arguments and process it through some switch cases, or put values into the enum that get pulled inside that one function
I was thinking on that
Since these items are always gonna be there, just their itemmeta is configurable but an enum would help
But how would I diferenciate the stuff.. hmmm
I could make an enum with a bunch of parameters for each item
Can anyone please help me save this variable? Because it's a map and uses Location, it needs to be serialized and deserialized (I think), but Ive already spent so many hours trying to fix it but nothing worked.
public Map<Location, ChestObject> chests = new HashMap<>();
https://paste.md-5.net/olujoqoqux.java the code
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.bukkit.Location
That still doesn't allow me to have different consumer methods I think
I mean I think I can simplify the item creator part but I still need to do the cases 1 by 1 obviously
its ConfigurationSerializable not Java Serializable
elgarl try this if you got a moment plz
if you want to save a location to config you simply do java getConfig().set(path, location);
and to retrievejava getConfig().getLocation(path);
Unless I misunderstand your code, you're misunderstanding my question I think? I dont need to get a location of a config or anything, but what everyone has told me so far is that the problem is the Location object
I mean, copilot just really wants me to amke them 1 by 1 hehe
But anyways Ill try what you recommend
you are trygin to use a byte stream which is not appropriate for a config
yes
hmm alright, thanks. Ill give it a try
you could make this very simple by making yoru ChestObject implement ConfigurationSerializable
How would that work
What if I use the YamlConfiguration class?
add teh apropriate methods it requires, register the class and yoru save code would be java getConfig().set("chests", choests);With load being a reversal
So that would turn into something like this
public void saveChestData() {
File file = new File(plugin.getDataFolder(), CHEST_DATA_FILE);
YamlConfiguration config = new YamlConfiguration();
int i = 0;
for (Map.Entry<Location, ChestObject> entry : chests.entrySet()) {
Location loc = entry.getKey();
ChestObject chest = entry.getValue();
config.set(i + ".location", loc);
config.set(i + ".particle", chest.getParticle().name());
config.set(i + ".items", chest.getItems());
config.set(i + ".cooldown", chest.getCooldown());
i++;
}
try {
config.save(file);
} catch (IOException e) {
e.printStackTrace();
}
}```
when i quit the server my opponent still cant execute commands. https://paste.md-5.net/bapebamane.cs
any ideas why?
Remove him from the list too
This would override the previously saved file, so unless all the previous data is cached already
Well, they are GUIitems events
So they just do stuff internally
Haven't been able to get the ItemAdapter working just yet
https://paste.md-5.net/azavenizik.java
cause currently #getBack returns an ItemStack which is fine. Just the parameters is the ugly part
guys does someone know how I can make an item which name colors are constantly changing in gradient way?
But don't I still need to specify each parameter like I'm doing it rn?
It'll still require 10 methods for 10 different custom items
I'm mostly confused in the way of how I can make the gradient flow
I am using configs
basically the gradient animation
For these 10 items, cause the metadata is customizable
Hmmm
That might be the only way
But still will need 10 methods then
I was wondering if maybe doing stuff with an enum would allow me to simply it
Lik
@quaint mantle do you have an idea about the gradient animation?
If I have an enum containing all the stuff I need for each item, getConfig# and everything
I can just do a loop on all the values and make the items accoringly
It'll be long code but somewhere else not 10 different methods
No clue how to implement that tho, was just an idea, could easily not be good practice
I understand about the Builder and thanks for showing it to me. I know what a Builder is, but I didn't knew really the deep details about it. I'm just confused about the String Gradient Animation
alright
Do you know how I can make it look like a wave?
for what creating next class to create itemstack from builder, just method build which return itemstack
@lost matrix Using your gui implementation, how would you make a button open another GUI, would you do it just like the first one? GUIManager#openGUI(new Inventory())?
@eternal oxide is something like this what you mean? It still doesn't completely work, but it does generate a yaml file with correct syntax. To be honest I don't completely understand what every line does in the save/load system, but I need to get this part done to finish my plugin 😕
https://paste.md-5.net/lacikunixe.java - ParticleHandler
https://paste.md-5.net/uvasonupor.java - ChestObject
The same error I get each time (most likelycaused by calling the save method) is: Cannot load plugins\ScrapCollection\chest_data.dat org.bukkit.configuration.InvalidConfigurationException: could not determine a constructor for the tag tag:yaml.org,2002:me.JustinS_2006.particles.ChestObject in 'string', line 2, column 3: - !!me.JustinS_2006.particles.Ches ...
(full error: https://paste.md-5.net/cuguzimiro.sql)
Do you have an example of what you're trying to build? Is it a static or a changing wave? If it's the latter, it's likely some resource pack stuff, which I have no idea about. It wouldn't be hard to calculate gradients and update them on every tick, for example, but that would be expensive.
yep thats because yoru object type is not registered nor implementing ConfigurationSerializable
one sec
Thanks so much for the help so far btw. I appreciate it 🙂
Something like that:
He meant an ingame example loll
Yeah, I mean how fast does it have to change
didnt i?
If I can make it loop smoothly
I don't know how fast it could be
There are some plugins who does that kind of name formatting in their GUIs
ok start a thread
There are many ways you can do this. Just opening a new inv like this shouldnt be a problem.
But then, pressing esc won't take you to the back the the previous menu
I have made a PlayerGUIManager system where I store GUI history for every player
And overriding the inventoryCloseEvent to make it open a new inventory of the previous one is a nasty infinite bug loop
Something like that? I did that a while ago. It's basically a gradient who's center point is just animated. If you want to do that with items, you need to update the items all the time, so it would be more work tracking them if the player can also pick them up and use them.
ElgarL 3528 is something like this what
and I remove them when they close the inventory, but it's not easy to do the checkings
I don't really really need history because when the player goes "back" it's actually an updated inventory not the exact same one
@Override
public void onClose(InventoryCloseEvent event) {
super.onClose(event);
plugin.guiManager.openGUI(new MainMenuInventory(ultraChest), (Player) event.getPlayer());
}
``` but doing this is not working
You can make it to update the items too
code not working as expected
You need to run it 1 tick later
Yes I want something like that, but going from the left to right and vice versa
Can you explain to me how you have animated the gradient?
new BukkitRunnable(){
@Override
public void run() {
plugin.guiManager.openGUI(new MainMenuInventory(ultraChest), (Player) event.getPlayer());
}
}.runTaskLater(plugin, 1);
Looks so ugly to make it run 1 tick later
Annoying
Why is there not a 1 liner
dont instantiate bukkitrunnables, use the scheduler
i can get all entities inside of a chunk async?
@Override
public void onClose(InventoryCloseEvent event) {
super.onClose(event);
Bukkit.getScheduler().runTaskLater(plugin, () -> {
plugin.guiManager.openGUI(new MainMenuInventory(ultraChest), (Player) event.getPlayer());
}, 1L);
}
now that looks a lot better
wtf my mans has a chili in his name
tf what?
Don't think you can to be honest
hm can u explain me why? because if i cant get entities inside of a chunk why i can get a chunk snapshot of a chunk?
i know these are two completely different things but i would need this for read only
Do you know how to apply hex colors to things? I have written my own components at the time, do you already have a way? I could show you how to animate the hex colors, if that's what you mean.
You mean if I know how to apply hex colors to Items and etc?
I'm sure you can, using reflect and NMS. But not by just using the bukkit API, as they have thread checks
For now I don't really know because I haven't tried and I haven't researched a lot about it
how does bukkit detect if im accessing this data async?
I know that you can add hex colors by using of() in ChatColor class from md_5
Because I never got it to work properly with bukkit, which is why I wrote my own component system. But that's rusty and not ideal, as it's quite old, which is why I'd prefer to only show you the actual color generation. I think you could make the rest work out.
when i quit the server my opponent still cant execute commands. https://paste.md-5.net/bapebamane.cs
any ideas why?
By checking what the current thread is and if that one is the main thread if I remember correctly- if not then it probably checks the group of the current thread, either way it checks based on the thread the function is executed on
some one know how i can change the combat pvp on 1.19 to 1.8.9
remove shields and cooldown for attacks and modify weapon damage i guess
On a different topic
CREATE TABLE IF NOT EXISTS uuid (
inventoryNumber INT NOT NULL,
inventory BLOB NOT NULL,
PRIMARY KEY (vaultNumber),
CONSTRAINT constraint UNIQUE (inventoryNumber), --Error here
);```
SQL error or missing database (near "constraint": syntax error)
well yes im trying to create said database. Can someone explain why this isnt working here?
Alright I'll see
exaclty
- Dont call a table uuid
- Whats up with the colon at the end? Remove that...
I believe this is really hard to be done
- 'uuid' is a placeholder for player uuid
- with or without colon, it doesnt work, i tried that already
Try again. Without is the proper syntax
[SQLITE_ERROR] SQL error or missing database (near "constraint": syntax error)
i told you i already did and it didnt work
and it once again didnt work
Wait you are creating a table for each player?
Wouldn’t be one table enough?
Like you can have multiple uuid-inventory number pairs
Okay, I'm going to dig out some code, give me a few minutes, xD.
lol i hope he doesnt do that XD
that suggestion has multiple issues
He said „uuid is a placeholder for the player uuid“ therefore I assume he does
No it doesnt
alright ill start. 1: you cannot easily isolate a player
Yes you can
well i mean you cant just open it and check
That’s why you have query statements
you need to do more sql
Sure. Every proper db tool lets you filter by column values
You have to use a SQL client either way like what?
even on Modding aspect this is also hard to be done. I have an MCP setup and there are many methods to look for Attack Cooldown and that kind of stuff. I know that there is one plugin which claims to do that called DeluxeCombat, but I don't how accurate it is for 1.8 PvP.
You can't really bring back the 1.8 PvP in 1.19 to look exactly the same with plugins
About this, you need to name your contraint with SQLite if I remember correctly
CONTRAINT <constraint_name> UNIQUE (<keys>)
Alright ping me when you have found it.
constraint is a keyword, I don't think you can name things after keywords
You are using a keyword as a name
Sql isn’t case sensitive
You could use it if you quote it probably
new issue tho
'java.sql.SQLException: not implemented by SQLite JDBC driver'
apparantly im missing libraries?
I've seen that error before, but I have no memory of how I personally fixed it. It's been too long since I tried to mess with databases
I think PRIMARY KEY itself doesn’t exist with SQLite
You need to define it as a constraint
i mean it works now
but apparantly my sql doesnt have the PreparedStatement::setBlob function
wtf am i supposed to do then
store it as LONG TEXT
Use binary instead?
It does
BINARY(<size>)
Use <size> as a max size?
Each entry doesn’t have to be exactly that size
It’s just how much can be in one entry
urgh i wrote all my code for blob
Quick question about that, wouldn't the database still append zeros (or whatever) to the end to read the required size, or would the database provide the correct amount of data when queried?
Isn't blob just byte array?
I dont think it will append anything in your query - I don’t know about the internals though
Sqlite ^
Its SQLite not MySQL
Sqlite also supports blobs
Well doesn’t seem like the JDBC driver does though
@molten hearth
trace:
java.sql.SQLException: not implemented by SQLite JDBC driver
...
at io.github.moterius.vaults.SQLite.VaultDatabase.insertInventoryAt(VaultDatabase.java:188)
code:
ps = getSQLConnection().prepareStatement("REPLACE INTO " + uuid + " (vaultNumber, inventory) VALUES(?,?)");
ps.setInt(1, position);
ps.setBlob(2, stackToBlob(inventory));//error here
I just have to ask, are you using different table for each player?
Yes he does
Tf is blob in sql
If you're going to use prepared statements, should uuid also be a secure replacement? I get that a uuid probably wouldn't enable sql injection but it's always better safe than sorry
Binary data
So whats use of this?
you shouldnt be able to considering these uuids are type 4
To store binary data? Lol
You cannot use ? on table names, IIRC
Oh
But you surely should be using table for each player
You might wanna store icons or some binary buffer that you wanna reuse or such
Really? I have memories of doing this exact thing with PHP... Or am I tricking myself?
It might work with Php but not with java
Strange
I think it substitutes strings to '...', where the single quotes would mess up the query. That's up to the implementation of the prepared statement library.
My bad then
You need to expose your code to sql injection format the string yourself
Just enclose it in backticks and call it a day, xD
Unless somebody injects backticks into the property being replaced
And remove all backticks from the parameter, I forgot, xDD
But other than that, I think you're out of luck in Java
PreparedStatement#setString always adds single quotes, and there's no setIdentifier or what it would be called.
I hate that the PreparedStatement set methods all use indexes starting at 1
I might be tricking myself anyways, I don't have the PHP code I wrote on my anymore since it was just a random thing I did when I was helping a friend with his CS homework. I'm starting to second guess weather or not I actually did this.
Yet another reason to write your own! :p
urgh
No thanks x)
nice javadoc mate
*Writes wrapper methods that take in a zero based index and calls the underlying function with 1 added to the index.
I mean... could've very well been that way, as it's entirely up to the implementation. Maybe PHP has some fancy features we're just missing out on.
I recently wrote a file storage system based on ids - for quick access storage using the RandomAccessFile api, I‘ve done enough data storage for the next months xD
Tbh, I almost never notice that, as I usually do batch inserts/updates anyways and thus set these in a loop. Whether I set the argument index to 0 or 1 initially really doesn't hurt.
I didn't actually write wrapper methods, I was making a joke.
anyways is the only solution using a different method? How do i know which methods work and which dont?
That's just how I felt after I wrote my own SQL mapper, xD. I really needed a break from that kind of work for a while.
As we said, try setBytes
can i use that on BLOB or do i need to change that?
Just try if it works
If it doesn’t you need to change the type otherwise you got a solution
Information that is easily obtainable via the javadoc (or as @sinful kiln already said, trying it yourself)
How can I make a optional, default parameter for a function
mate the javadoc contains no method descriptions
Create another function without that parameter
Look for a method with setBytes as the name that contains Blob as a parameter
For example:
public ItemStack getButton(final String materialOrBase64, final String name, @Nullable final List<String> lore) {}
I want to have
public ItemStack getButton(final String materialOrBase64, final String name, @Nullable final List<String> lore, OPTIONAL BOOLEAN DEFAULT TO FALSE) {}
You don't need descriptions for that
That function should call the other function with the default value
the only blob method in preparedstatement is setBlob
But then inside the methods is duplicated except for like 1 line
the one that says 'not supported'
Then you probably need to use a byte array (or whateveer setBytes uses) then
Methods aren’t duplicated if their parameters don’t match
2 lines aren't but the other 20 are
It's just like a flag to add an enchantment or not
That's it
still waiting for java to introduce C++ style default args
What you could do is have the function without the optional parameter call the function with the optional parameter passing in the default value
PLZ
Maybe one day
example:
method(int a, boolean b)
internalls call method(a, b, false)
Which will call
method(int a, boolean b, boolean c)
How? Just call the second method inside of that method and just provide the parameters. It's more like 3 lines instead of 20
Laughs in C#
void methodWithOptionals(string a, int b = 0, double what = 0.5d)
so what i want to know now is why BLOB allows bytes to be set lol
it just looks like it shouldnt work
Ah well people usually do it for constructors, but it can also be applied to normal methods as well.
Why shouldn’t it work?
Blob storage is just bytes
It's just not as common to see it done that way.
yeah fair
i know that but it just feels wrong
declaring one data type and stuffing in another
Not really
what are you doing this whole day for me with your blobs now?
There is no byte array or bytes type in SQL if I remember correctly
blobs dont exits
Can I not enchant items that are not supposed to be enchanted?
There’s only Binary and Blob
For example, heads?
yes
its just itemmeta.addenchant or smth like that
if (doEnchant) {
meta.addEnchant(org.bukkit.enchantments.Enchantment.DURABILITY, 1, true);
meta.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_ENCHANTS);
}
Is there a way to make commands (and its tab completer) that take a double quotes argument in ?
e.g.
/myplugin thing create "This is a name" "This is a description"
With the tab completer working a little bit like the /title command when you need to put the <text> value
Does HIDE_ENCHANTS remove the glow?
Try using environmental protection instead of durability
iirc hideenchants hides the names but not the glow
I think I remember something about that
also is 60ms write to db slow or fast?
Testing rn
Either inject the command into the Brigadier of minecraft directly or write your own system based on bukkit
There are probably libs for that already
reflection my beloved
I'm not sure then
Brig >>>
Isn’t there like a addUnsafeEnchant or something like that?
Nope
There is
Its on the ItemStack
tf
Not ItemMeta interface
How does that make any sense
This is Minecraft
No its Bukkit, not Minecraft
yo wtf
where my error at
Yes, my bad
But at any rate, if you just want glow, and have nms on ur side, just inject an empty compound into ur stack for the enchantments key :>
Eaten by the command monster
any idea why
Nope
@frail gale
Ugh, that was quite the journey through some old code. I've now created a little playground project which just animates the name on the item you're holding in your main hand: https://github.com/BlvckBytes/AnimatedItemPlayground
I hope you can extract what you need from this. It shows you how to calculate gradients and how to apply components to items. If you already have a component system which can convert itself to json, you can use that too, of course. I don't know if I'd use my old components even myself, xD.
Go to AnimatedItemTest.java and then just traverse from there.
so i did have an error
console just decided to not show it until i started typing in it
wtf
Now to figure out how to do enchantment glow using jefflib
Do you really need a lib to add enchantment glow to an item? :-:
Maybe u clicked somewhere and therefore blocked the windows command line from continuing
Alrighty, I see
Actually using a combination of my lib and jefflib
i mean i have to tab out to enter the command
But he has nms support as well so
Thank you I'll see what I can do with that
If you don't understand anything I'm doing there, just ask ahead. It uses my own libraries, so it would be best to just understand it's working principle and then write it yourself based on your needs.
People use libs to do literally anything nowadays tbh
I just really dislike blackboxes, which is why I usually don't use foreign libraries at all.
i do most my stuff myself. I'm not using a library for my current two projects
well
spigot is debatably one
One thing I don't understand is AnimationState class
it's more of a framework, but I get what you mean. Within reason, of course
Make an entire plugin using nms
Most libs don’t provide any guarantee hence not a big fan of it
For instance how many libs do u see with intergration, or well unit tests
whats integration
Integration tests
(i know what unit tests are but idc, i test in prod)
It's the animation state used per player, which stores the gradient information as well as a boolean whether the center point that's shifted currently moves forwards or backwards. It's basically a little state machine that shifts this point left to right and right to left forever, xD.
Or any other suggestions
I actually wrote a shit ton of tests already, and there's still so much that needs testing, :-:
So it's needed for the Gradient
Well, I don’t think the quantity of tests is important unless you’re religiously committed to tdd, but def the quality and what your tests validate.
Yeah, it's used in advanceAnimation
arent gradients hard coded to always have a minimal size of 4³?
That won't fly in big tech
🥲
I'm not at all a TDD guy, but the stuff I write usually is complex as hell and has so many cases that I really need to invest a lot of time into testing, to actually be able to refactor with confidence.
considering my luck with libraries it'll probably literally be a case of 'it works on my machine' cuz i have the correct libraries and they dont
Can you explain this again in more idiot words plz
Myeah, that sounds good tho
TDD makes me want to commit self-die
whats that short for?
Test driven development
Basically write tests before you write any code, then write the code that makes it compile
i mean
It is a standard almost in most companies to ensure quality code
Yeah, but it's not included in your project so I can't really see it
90% of my code is spigot stuff u can only see on the server
good luck writing tests for that
TDD is only good for strictly defined algorithms. If you're trying to figure out the best way to implement/architect something, it's for the birds.
I myself plead to use design driven development or behavior driven development if companies allow that
It's an inner class in AnimatedItemTest, xDD. It's easy to miss.
Ohhhh alright then
most of us just write the code to barely work dont we
That's not how this should work tho, xD. But I am actually planning on a proper test system to really end-2-end test plugins, haha
How can I add the enchantment glow to an item using nms
enchant it with something consequenceless and hide the enchant? Why wouldnt that work
What item are we talking about that you need NMS to do so?
Is there a event that checks when you like hold right click on a bow?
its a right click event where it says someting like start charging iirc
kiss mate
I want to do it using nms
You know that that's the only way, right?
It can't be
What do you think NMS does? it also adds this to the NBT data, I bet
actually nms would do it
There's no "glow funnily" flag
nms does do it
but you could use protocollib to fake it
Sounds interesting, system test or just integration tests?
by doing what i suggested but to just pretend its enchanted
I can't give enchantments to a player_head so nms is the best way
That's a good idea
Well yea, heads are incompatible with the enchantment glint.
You can give enchantments to player heads but the glint will not display. That's a client limitation
Regardless of whether or not you use NMS, it will not make a difference. Bukkit interfaces with NMS
I want the glow not the enchantment
client limits are dumb in a few ways
the glint will not display. That's a client limitation
Don't know the exact terminology. System tests, probably. I'm thinking about the following: Compile a server jar for each available version, set up a firecracker VM with the right java version installed, boot up the vanilla server, take a snapshot of each to later be able to rapidly spawn up "warm" instances. Then, write a plugin that loops all loaded plugins and calls their testing interfaces and writes the report into a test-file. There could be some sort of orchestration software on top of that, which even lets fake players join and analyzes packets and the like. No idea how I'm going to pull all of that off, as I'm actually literally drowning in other projects to finish at the moment. But I think you get the idea. Since my reflection library disables the plugin if it didn't work and exactly describes the errors, I could rapidly implement massive version support this way. Ugh, wall of text.
gods culling
What is glint am I dumb?
It's the glow you are referring to
Is that the glow?
can anyone help #1081219497140158485
Oh
So there's no real way to display glow on a player_head
Not even with protocollib
You cannot give a glint without an enchantment. The client has a isFoil() method (or something similarly named) that determines whether or not an item has an enchantment glint. By default it returns true if the enchantment tag is not empty. The only items that override that are the ones that are glinted by default (like golden apples)
Does sound like a system test
Nope
Or well, maybe acceptance tests
shouldnt it work then?
the head glint i mean
you could fake the glint by continuously changing the skin to reflect the enchantment glint going over it
...
If I can't put an enchantment on a player_head normally, using nms would allow me to force an enchantment on it
No?
Therefore it would actually display the glow
I don't know why you're not understanding this
it would work but not well
As if you could create all of those permutations for each displayable skin within reason
you dont need to
shouldnt u use the getIteminHand methode?
I was looking for possible workarounds
@dry yacht It seems for me that making animated gradients is really hard
But I guess there is none
There is no workaround. You can't workaround the client when you're working on the server
you can just cycle through the glint and keep the skin in memory, then add the current glint rgb values to the skin values
If you want to work around this, you're going to be writing a client mod with Fabric or Forge
and thats what you send as the displaying skin
It's non trivial to be honest, but not hard. It takes some time of wrapping your brain around it, but it's most definitely not something you'll do on an afternoon in half an hour.
the problem is idk if you can tell the client to update skins
Uhm, that actually confused the hell out of me
You do know how skin data works, serverside, right?
Can I test all the code you posted on a seperate project?
is it valid?
NMS isn't black magic that can do things that Bukkit can't. Bukkit calls upon NMS. It exists so that you don't have to do it and be version-dependent
i know that skins can be created server side for heads
It heavily relies on my libraries, but they should all be on github.
thats about it
wdym
You can, using some sort of API that uploads your pixel data to their account to invoke a new skin generation on mojangs API, but that's about it
ive seen binary data strings getting converted to skins
You don't send pixel data, you send skin sprite URLs
Bahaha, I love this answer, I'll will use later haha
I'll see after some minutes. And I could try to see how everything works and implement it
well for skins, arent heads different
I mean it's true. The people that continue to make scoreboards using packets are just stupid. Bukkit has API for all of it
if(e.getItem() == Material.ENDER_PEARL) {} whats wrong here?
I know that it can be really hard to work with somebody else's code, but I still hope that it at least helps out a bit. You have all the information you need in there, guaranteed, the question is if it's of any worth to you and if you can actually make use of it. That's the hard part, :/
I really don't think so. Do you have an example of this
/summon minecraft:armor_stand ~ ~1 ~ {ShowArms:1,NoBasePlate:1,ArmorItems:[{id:leather_boots,Count:1b},{id:leather_leggings,Count:1b},{id:leather_chestplate,Count:1b},{id:skull,Damage:3,Count:1b,tag:{SkullOwner:{Id:"b821f12f-8e14-44bb-9015-0df0a6055288",Properties:{textures:[{Value:"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZjc4ZTM5ZTNhYTE0ZGFiNzdlYTNiNTFmMGE3MmZiMGNhNTU1ZDdlYjE2ZGM1OTJmNzBmYTEwYzQzMDI5ZDczNCJ9fX0="}]}}}}]}
I know. Reading someone else's code is hard at first, but not impossible. 1 year before I implemented some complex entity rotation from 1.7 mod to my 1.12.2
I agree
head skin is B64 encoded string
ItemStack will never be a Material
e.getItem().getType()
so it stands to reason you can unpack and manipulate the texture to repack it as a 'glint skin'
I don't know what event you're using but check to see if you have to make a nullability check on getItem() as well
It's just the same as with skins, please ignore the fact that this is german text, xDD. The base64 is encoded json which just contains the skin sprite URL. No pixel data whatsoever. Sorry to tell you, but you've been told a lie, :((
Glint is animated though. You'd have to make a texture for every frame. Not to mention that implementation would now be inconsistent considering the upcoming client settings for glint strength and glint speed.
Here is your "binary" string. Its just the mojang texture link but base64 encoded
ty ^
If it would actually be binary image data, the world would be a different place, xD.
But with something like MineSkin you can upload and use whatever texture you like
couldnt you generate the skins and do the api calls to then display them?
You could upload all glint permutations of a skin to some API, but dude... that's gonna explode in the amount skins you'll have to upload real quick. Those APIs are rate limited, for good reason.
I totally get the idea tho, haha :,D
Wouldn't you have better luck with a resource pack?
Still waiting on Mojang to add a Glint NBT tag
still waiting for mojang to clean up their mess
private void addGlow(org.bukkit.inventory.ItemStack stack) {
ItemStack nmsStack = (ItemStack) getField(stack, "handle");
NBTTagCompound compound = nmsStack.tag;
// Initialize the compound if we need to
if (compound == null) {
compound = new NBTTagCompound();
nmsStack.tag = compound;
}
// Empty enchanting compound
compound.set("ench", new NBTTagList());
}
What's the up to date version of NBTTagCompound
Is that NamespaceKey?
TagCompound
But again... just add an enchantment...
You can do that with the Bukkit API and you're doing the exact same thing
You're still not convinced? :(
It's not for production
I am, you both know a lot lot more
But nothing wrong in practicing it
https://minecraft.fandom.com/wiki/Player.dat_format#Item_structure
You can see what you'd need to add to the compound to add an enchantment here. The NamespacedKey is probably the enchantment id.
when i quit the server my opponent still cant execute commands. https://paste.md-5.net/bapebamane.cs
any ideas why?
Something like Enchantment.ARROW_DAMAGE.getKey().getKey();
jesus it's confusing, not that part just overall
These parameters lol
i'm pretty sure I'm using this wrong
Sorry, can't help with that, I have a big phobia of foreign reflection libraries, xD.
Wait why reflection?
How to make a fern grow in 1.12.2? Keep in note that growed fern is a double plant and not a long grass type
PDCUtils.set(item, Enchantment.ARROW_DAMAGE.getKey(), DataType.INTEGER, 1);
}
Pretty sure that would work but obviously since the item is a player_head it won't show
Wasn't as bad as I thought
That won't work. That makes use of the PDC which isn't on the root tag
Oh
Question, what class does Particle::getDataType return when the Particle requires no data?
Void.class iirc
ok thanks
Yeah, it's Void
k
Giving the item itself isn't a problem, but placing it seems impossible
There is actually the LongGrass cast, but not in my case 'cause the large fern is a double plant, and I can't find a class tho
@vast raven you need to set the lower half first, then the top part
💀 ..how?
iirc you can use block data
Material.FERN or Material.TALL_FERN and see if you can set it's half
like a door
oh yeah it probs is a LongGrass
actually there isn't a class like LongGrass to cast the block state / material data
^
You're looking for Bisected
choco the savior
It's a BlockData
Set the bottom half, then set the top half. Don't set them with physics though
Bisected
Did you counted the legacy version in my case?
oh you said 1.12
lol, well, you're kind of SOL because the MaterialData API was very much incomplete
You'll have to figure out what the byte data for those two blocks are
The real solution is to find a class where you can cast the block data / state
For regular short fern is just LongGrass
so Im getting a message when I try to login to our server saying you're not that awesome to be whitelisted and yet I am whitelisted and we turned whitelist off
Since we're speaking of long fern, idk then
I don't know if there is an actual MaterialData implementation for that
Again, it was incomplete
I think there isn't then, searching through spigot docs / ide implementation didn't help
Setting the Block type to DoublePlant, and then setting the data to 3, spawns a short fern block 💀
Question
public Map<String, Integer> items = new HashMap<>();
This is how I am serializing a map of Itemname -> amount
I was thinking of switching to
public Map<ItemStack, Integer> items = new HashMap<>();
But I wonder if when I do
items.containsKey(itemstack) the amount of the item will also be included therefore unless it's the exact amount it won't match
Correct?
Use Material,Integer maybe?
Should I keep saving as Map<String, Integer> or switch do material,integer
Oh, sniped me
Is material, integer better than string, integer then?
Yes
Alright, ty
It represents more accurately what you’re trying to do
String based design in programming should be avoided, at least regarding scenarios such as these ones
Understood, thanks for detailed explanation
Also, you might wanna use an EnumMap<Material,String>, dunno how far spigot has gotten regarding that pr
What even is an enum map
Its another Map implementation as opposed to HashMap
But it acts like an enum right? values can't change
This is a list that needs to change a lot
Ah yeah nvm tomi, listen to choco and zacken
(a) The Material enum is probably way too large for you to even get any benefit over a HashMap (unless you're mapping all entries in an enum for some reason), and (b) there are plans in the future to have Material not be an enum anymore
I actually used a HashSet internally in Bukkit recently lol
For both of those reasons
EnumSet
It's within the standard java lib
oh wait nvm
I am a dumbass
How can I force an inventory to be closed?
player.closeInventory()
Why was I overcomplicating this we will never know. thanks voodoo
using a record or a class
Are you getting a value from JSONObjects
or whatever they are in gson
oh, I understand lmao
When working with Custom PDCs, if I make a change to the data inside the class that's being serialized, do I need to resave it?
iirc yes
I need to update a lot of the data that's being stored, constantly
why do you need to do that
Will saving the pdc every time I make the change screw up performance wise
Because my pdc has item storage data
not that slow actually
Maybe I have a cache and save the data into the pdc every minute or 5 minutes
explain your use case
The class i'm saving as a PDC contains
public Map<Material, Integer> items = new HashMap<>();
Among a lot of other properties
why are you doing that
Also
EnumMap
If all you need is to convert a JSON string and start pulling from it
String json = "{identifier: 5}";
JsonElement element = JsonParser.parseString(json);
//prints "5"
System.out.println(element.getAsJsonObject().get("identifier"));
They said not for now
why not?
Read above
^
ah yeah
Allright fair
forgot it loads everything
But still
.
I want to edit constantly stuff in there
Maybe I have a cache and save the data into the pdc every minute or 5 minutes
Anyways, you should edit in there, and save every time it is closed or the server is shutting down
save only if it didn't change
so have like a dirty boolean
It's a list of materials and the amount
But still, it's about PDC and serialization
it's much more effective to have a global flag for the entire container
that way you avoid any saving if the container didn't change
Is there a global server PDC?
Edit the map, save on plugin shutdown or container closed
Like if I want to save a list of something
no of course not
Why do you need a file

Well, I want to store the location of each item which has this custom PDC and when the server loads, I want to add them all to a list
Why not just add them when the chunk that they're in loads
Oh yes that works
I actually have a chunkpdc data already set
How do I even do that part tho
ChunkLoadEvent I think is a thing
❤️
I like that idea a lot I completely forgot
It's perfect
Except
Offline mode
And I think it should let you get TileEntities and maybe entities? 
I rarely use that event so I don't remember exactly but you should be able to get what you need
?paste it
How can I get a specific block (placed chest) from ChunkLoadEvent() if I have the exact location value of the block
i cant believe no one can really help #1081219497140158485
can anyone look in my thread please
You're deserializing to get the identifier, then deserializing again using that identifier as the type to deserialize it as
I don't really know why that identifier is there to begin with though
Why? What else do you expect it to be?
{
"x": 0,
"y": 0,
"z": 0,
"pitch": 0.0,
"yaw": 0.0
}```
That should be the extent of your position
You should know what the type is. You're the one serializing it to begin with
Well I still think your structure is a bit backwards. Deserializing twice is kind of a no-go. imho I think adjusting your design to where you can have something along the lines of this is better:
{
"id": "location",
"data": {
"x": 0,
"y": 0,
"z": 0,
"pitch": 0.0,
"yaw": 0.0
}
}```
Then you can deserialize it once, get the id, then pass the data as a JsonObject to some registered deserializer
They're cringe
can anyone tell me whats wrong with my code? after i quit the server my opponent still cant use commands
Patient bruh, this Is a community and no one Is getting paid to helping you instantly. So if you dont like to wait just dont disturb on this community
Chest chest = (Chest) event.getChunk().getBlock(location.getChunk().getX(), location.getBlockY(), location.getBlockZ()).getState();
So, #getBlock requires a number between 1-15 for coordinates, which makes sense cause it's the individual chunk
i have been waiting since 6pm
If I have my location stored as an entire location tho
Would I use location.getChunk().getX() or is there a better way
Cause location.getX() returns the entire world location
I mean if you dont get helped it's for a reason, so you must wait and Wait
its very easy to tell me reason
That why Chunk#getBlock() Is know as an intensive operation if I'm not wrong
You cannot abuse over it
But what are you doing Tomy?
then he says my code is ugly 🙄
That’s debatable
))
How can i get a block from a Location on ChunkLoadEvent
?jd-s
Doesn't help which is why I'm asking
#getBlock requires a number between 1-15 for coordinates, which makes sense cause it's the individual chunk
If I pass it location.getX() it'll be for the world not for the chunk therefore IllegalArgumentException
I mean % 16
#getBlock requires a number between 1-15 for coordinates, which makes sense cause it's the individual chunk
in the past what? 3 hours? Have you tried solving it on your own? It's not that much code. Also you asked in your thread why your opponent can't use commands when you're offline. Isn't that supposed to happen?
Between 0-15 sorry
and what is your problem then
location.getX() it'll be for the world not for the chunk therefore IllegalArgumentException

i don't get what's the problem
Huh?
idk maybe my eng is bad but
I'm trying to get a block at a specific Location location which was already saved
If I do location.getX() it returns the full world location

Meaning #getBlock will throw an exception cause it doesn't work
Chunk.getX() * 16 + block x in chunk
Chunk.getZ() * 16 + block z in chunk
y
Ummm
mod 16
Yeah how dare you suggest modulo
% 16
Yeah Im not gonna lie I had a autismo moment apologies
Uh I assume I need to do absolute values
idk
you can store chunkX + chunkZ
- relative block xz in a chunk
and absolute y of block
You need one long for the chunk coord and one int for the relative block coord. So 96 bits in total.
heehee java @SuppressWarnings("unchecked") private <T extends AutoCloseable & Iterable<E>, E, EX extends Exception> void loopAutoClosable(T autoClosable, ThrowingConsumer<E, EX> consumer) throws EX { try (autoClosable) { for (E item : autoClosable) { consumer.accept(item); } } catch (Exception e) { throw (EX) e; } }
kinda neat
Yep
Caffeine
That would be very nice
Whilst its certainly true one can take advantage of guava’s caches, that cache impl is not nearly as up-to-date and well designed as caffeine
Well, I'm just trying to avoid doing bad memory stuff
Anyway, assuming you do end up using Caffeine, what type of caching are you going for?
Like setting a PDC every single time an action is done
I think i want to make my own even tho it won't be as well optimized as that
An expiring cache?
So here's the thing
*how often are you mutating the PDC for there to be a need for a cache
*
protocolManager.addPacketListener(new PacketAdapter(
this,
ListenerPriority.NORMAL,
PacketType.Play.Server.ENTITY_EQUIPMENT
) {
@Override
public void onPacketSending(PacketEvent event) {
PacketContainer packet = event.getPacket().deepClone();
ItemStack stack = packet.getItemModifier().read(0);
ItemMeta meta = stack.getItemMeta();
((Damageable) meta).setDamage(0);
stack.setItemMeta(meta);
packet.getItemModifier().write(0, stack);
event.setPacket(packet);
}
});
}
I'm trying to hide durability of items by modifying packets using ProtocolLib, but it doesn't work.
Not at all just yet didn't get to implement that just yet
But I don't want to get to that point
But hear me out
Yeah lynx question isn’t totally impertinent
There are several packets that you need to cover
I see
I use PDC as my storage, meaning all the data for a specific class is saved in the block data itself.
I need to constantly access that data. read/write a lot, therefore I don't want to have to save it to the PDC every single time to then be able to read the updated version of it from other places.
So I was thinking on making a local storage system in the plugin. And only save the data to the PDC once every 5 minutes or once every restart
This is the class that is the core of the plugin
?paste
When block loads -> put in map
When block unloads -> save back into PDC
But its slot in a window?
