#help-development
1 messages · Page 1992 of 1
?ban @torn coyote very funny, didn't laugh
Done. That felt good.
nvm
Thanks, and sorry for ping
agreed
if its not about actually seeing the other player, what is the purpose..
whats that method?
ack just chill it's about if you're facing the other player
i need it
Its just to detect if the player is looking into the direction of the other player
livingentity.hasLineOfSight
thanks
declaration: package: org.bukkit.entity, interface: LivingEntity
thanks again i guess?
then just vector check ...
After a unit testing i have discovered its caused here:
Map<String, Object> object = new Gson().fromJson(new BufferedReader(new FileReader(this.file), Map.class);
lol
not with vision, just face
What do you mean after unit testing? You didnt really write a unit test to resolve a trivial NPE?
Yeah i did
hahaha
location gives you the facing vector directly
Hi! I have some questions about Spigot development, and is wondering if someone could help me out.
So I'm not at all new to coding or Minecraft datapack/resource pack creation, but I've been trying to get into modding the past few months and have been very interested. I've been using MCreator, but have found it very limited and I'm looking for something a bit more advanced. Is Spigot what i'm looking for?
if not could someone point me in the right direction
Spigot is for plugins, I'd suggest for mods Fabric
its way better than forge
Spigot is server-side mod development, they’re called plugins
and they have a friendly comunity
You can’t add assets to the game and it only works for servers
r there any benefits to fabric or spigot?
Spigot is strictly server-side
They’re not really that comparable
Fabric is full-on mod development
fabric is client side and server side, and is made for mods
plugins are just extensions of a server
plugins dont need updating every version
and fabric is full on editing of the game
Looks at LazyDFU for fabric:
check the fabric wiki
i'm not really sure where to start
and join their disc
Learn Java
its fine if i put fabricord link right?
Having a full understanding of Java is imperative
^
Fabric is also extra complicated compared to fabric as you may need to have some understanding of java bytecode
Though I think you can just skip that requirement
skip the java requirement?
The java bytecode knowledge requirement
You must have a good understanding of Java concepts before even looking at Fabric modding
Otherwise you’re going to be throwing yourself at walls
Java knowledge is imperative, and java bytecode knowledge is highly recommended otherwise you'll get confused with mixins (which is a hard-requirement for fabric modding)
Bukkit is thankfully much more beginner-friendly there
^
ok so imma be honest here, i have experience in coding, but no experience at all with java
im prepared to learn tho
Start there
Otherwise you could just start contributing to already existing projects (or just try to learn it).
However honestly said, fabric projects have terrible structure mostly and many fabric tutorials teach things that are mostly against common java conventions
wait start where? sorry
Learning unadulterated Java
The the most usefull concepts you should be familiar with before starting with modding is
a) reading & Understanding Compiler errors
b) Reading & Understanding Stacktraces
c) Reading & Understanding Javadocs
Geol, if I wanted to familiarize myself more with bytecode and how it works, where would you recommend starting?
More than half of the issues we solve in #help-development can be answered without consulting us if you were to be familiar with all three steps
I learned quite a lot from playing around with Recaf, Decompiling stuff, writing bytecode by hand and also by writing my own mod loader.
But https://cr.openjdk.java.net/~iris/se/17/latestSpec/java-se-17-jvms-fr-diffs.pdf is the most important resource you'll have (especially chapter 6.5)
I appreciate the advice, I’ll poke around there. I’d like to think I’m a pretty competent Java developer, but when it compiles it’s black magic to me beyond that point.
so would might it be best to start with Bukkit? I know there r some things u can't do with it, but would it be a good place to start?
Bukkit is impressively powerful.
Sure, you cannot add new blocks or mobs or anything without going into really complex territory, but you can get accustomed to minecraft basics.
Just note that bukkit is completely different to forge or fabric for example especially in the way it is built. Another alternative would be sponge, but that one is more complicated even though many contributors of bukkit are now working on sponge
cool, this sounds good!
i have a few questions tho
what's the difference between bukkit and spigot, and is this the wrong server to talk about bukkit?
nowadays they are the same thing
The bigger difference is spigot and paper (latter is a fork of spigot) but for starters they are mostly the same things until you get into the details
Bukkit is dead for half a decade now, there is no choice
oh ok
If you touch on a site claiming to distribute bukkit you are most likely on the wrong size
You shouldn't fork spigot either
wait so spigot or paper?
Yeah, though of course here we support spigot
?bt is the only legitimate way of obtaining it
ok so i dont wanna offend u guys, but imma start with paper. After reading a bit about it, it seems to be slightly better and have a larger community, so imma start there
unless theres something im missing
A few people find paper's community less welcoming but honestly as long as you are on online mode and on the latest version you are pretty much welcome anywhere while if you are not on either you aren't welcome anywhere (though here many are far more accepting towards 1.8 in particular)
Things written for Paper stand a good chance of not running on Spigot. Write for Spigot and it works on both.
In the end, it's a personal choice, just like choosing a linux distro
Also yeah, Elgar's advice stands true plus you cannot distribute paper-only plugins on spigotmc
Hey, I have a question that is probably from the java basics but if I had some checks with or (two of |) and then had an else does the else also work if one of the checks is true so doesn't have to be both true?
Example:
if(isPlayerFlying() || isPlayerCrying()) {
//Do something
} else { //If one of the checks above is true and the other is false will this run?
//Do something
}```
Will it only run if both are true?
I meant false**
well yes then
Alright thanks for the quick answer
no problem
How would I create a client-side lightning strike at a specific location?
Anyone has experience with parsing a json file to a Map?
Yeah
The closest packet i could find was the game state change
isnt lightning a particle effect as far is client is concerned?
So it’s probably the SpawnEntity packet
yea
Alright, thanks
Hi i have discovered, that im getting Null Pointer Exception on my json handler, when the file.json is empty. But if the file contains "{}" inside. It doesnt throw anymore the exception
So what do you recommend? I tried writing via code the "{}" inside the file. But still getting NPE
Do you wanna see my code?
what's the first function called of that?
is the error thrown when you create an object instance of the class
is there an interactwitharmorstand event?
prob only playerInteractEvent
playerinteractatentityevent
thanks
gotta check if its an armor stand tho
ik
My NPE its thrown when parsing the "this.object = this.gson.fromJson(bla bla);" and i discovered it was cause because the json file didnt contain inside any "{}"
wait
there's a good chance parsing '{}' to json results in an empty string
since it does not contain any values
stack trace please
Allright
Exception in thread "main" java.lang.NullPointerException
at dev.alex.net.utilities.file.json.JsonFile.set(JsonFile.java:44)
at dev.alex.net.utilities.file.testing.Main.main(Main.java:11)```
That happen when try to add a value to map
My test code
public static void main(String[] args) throws Exception {
FileHandler json = new JsonFile("C:\\Users\\Usuario\\Desktop\\Pruebas\\test.json");
json.set("test", "My test value");
}```
hm
what's the caused by say?
or rather
the full stack trace
thts probably a lot easier to deal with
how the fuck do you have a stack trace not saying 'caused by'
So i finally find that the problem its caused when the file inside doesnt contain any "{}"
told ya so
That what i have done
huh?
I'm amazed how that did not result in anything more
Yes i dont know too
well maybe it's because you're using that class in particular
but seriously getting an error without an caused by is a once in a blue moon thing in java
Just say me that something its null on line 44:
actually it says 'caused by null on line 44 which results in an error on line 13' if i read that right
Could be caused because im doing?
FileHandler json = new JsonFile()
Instead of doing JsonFile file = new JsonFile?
No it isnt, its the same
this is uncharted waters for me tho
Hmn
Im like okay hat happening them
But dont worry i just want to know how i can add "{}" inside the file?
if (this.file.length() == 0) new BufferedWriter(new FileWriter(this.file)).write(this.gson.toJson("{}"));
Cuz doesnt work
lemme check smth
ah
welllllll
considering this is what the docs say
i dont think you can just write "{}" to a file
im not 100% sure but i think toJson("{}") just returns an empty json tree
as such
it writes nothign to the file
just creates it
why not write {} without converting to json
Hmn, because if i write manually "{}" inside the json file. And then try to set values it doesnt throw error
So i dont understand
yea
I will try
and when json converts it back it should just be an empty json element
this is what i do to save json
@Override
public void save(IslandCache cache) {
try {
StackerPlugin.sendDebug("Island Cache " + cache.getUUID() + " has been unloaded and saved.");
createFileIfNotExists(storage.resolve(cache.getUUID() + ".json"));
Files.write(storage.resolve(cache.getUUID() + ".json"), GlobalGson.GSON.toJson(cache).getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
}
}
for example
but its so nice
Ah allright you are saving a custom object
yes
That what i dont want
in my case i am
I want to be able to save what ever i need, json element, json array, class object
yes but that should work practically the same
Where does GlobalGson came from?
Yeah
its just a class that holds the Gson object
public class GlobalGson {
private static GsonBuilder BUILDER = new GsonBuilder()
.registerTypeAdapter(StorageBenchmark.DataObject.class, new StorageBenchmark.DataObject())
.registerTypeAdapter(IslandCache.class, new IslandCacheTypeAdapter())
.registerTypeAdapter(StackerBlock.class, new StackerBlockTypeAdapter())
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.hasModifier(Modifier.STATIC) || f.hasModifier(Modifier.TRANSIENT)
|| (StrictCollection.class.isAssignableFrom(f.getDeclaringClass()) && (f.getName().equalsIgnoreCase("cannotRemoveMessage") || f.getName().equalsIgnoreCase("cannotAddMessage")));
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
})
.disableHtmlEscaping();
public static Gson GSON;
static {
GSON = BUILDER.setPrettyPrinting().create();
}
}
So method ceateFileBlabla() just do: file.createNewFile()?
not sure what you mean
Is there any way to modify an entity's data without NMS or executing vanilla commands?
what kind of data
like its name or health?
the kind you get from data get entity @e[type=!player,limit=1]
pretty sure that gets you all data
For most of this data spigot has api methods
This particular data key does not have an existing method in paper or spigot -- would prefer not to use NMS or PR
well, what is this particular data key
Which data key?
PushX and PushZ
What entity is this from?
org.bukkit.entity.minecart.PoweredMinecart
I think you can edit tags like that with Bukkit#getUnsafe
😮
Yeah i dont see any method corresponding to that data.
Unsafe sounds like the best option, if we can get that to work.
Otherwise, NMS or PR time... hurray
There is also the super sketchy option of dispatching vanilla commands.
But that is too sketchy for a major plugin, so yeah... PR time with NMS or Unsafe in the interim
disgusting
@lost matrix would you have time to talk about Evenly distributed workloads?, you send your link to me. & i tried to implement that. but i think your implementation is meant for if you have a set number of workloads and you can run them evenly distributed but in my case i have a workload every 5 ticks so im kind of confused on how to implement that. unless im wrong and yours is suitable for looping like that.
Btw, how likely do you think this would be to get approved as a spigot-level PR?
Is it too niche? Would it be more suited to a downstream PR?
Every 5 ticks for every player online?
pretty likely
no, its an object its looping over
but ofc when evenly distributing it would proccess 1/5 every tick
Usually, I think they cover anything they agree should be covered by the api
could show you my shitty implementation if that helps
but I don't really follow up with it. The only features I ever got added to spigot were from conversations with Choco lol
im kinda tired. Ill have a look tomorrow 👍
that's okay. thanks
What is the usual response time for Jira tickets? How does that compare to PRs?
For that matter, how does it compare to downstream PRs?
if we have to do NMS in the interm, would prefer not to have to update to 1.19
couldn't give you the answer to that honestly
I don't really keep up with it all
Thanks anyways!
But: why not both? Get a JIRA ticket out there and if you have time throw together a pr
small PRs have been accepted pretty quickly in my experience
i haven't played mc in a while
how do i update my 1.17 to 1.18
i dont think the plugin it's self would be broken but how do i make it normally 1.18
Change the dependency in maven or gradle or whatever
currently it's set to 1.16.5-R0.1-SNAPSHOT what is it for 1.18?
but is it necessary? if im not changing the code
the only thing i could think of is
in the code it makes a list of all blocks and items. would it do it on the plugin version or server version
Should be the server version
how would i regenerate just 1 chunk with a specific chunkgenerator (different from the world's)
World has a regenerateChunk method
Build tools rev 1.18.x?
Maven or gradle?
How does the plugin messaging channel work? Can a plugin just send some text to another plugin for it to process and do something depending on it
You could
Probably easier to just hook the plugin directly though
Plugin messaging is good for communicating between servers or for talking to client mods
does it matter if I send conole chatColor.red type stuff?
idc if it actually appears or not
minehut lol
It doesn’t matter, no
kk ty
You may see the raw color codes though
Now, I am using Kotlin in my plugin and, dependency plugin is also Kotlin plugin
and if i depend Kotlin plugin and using libraries function in plugin.yml(libraries are for Kotlin), plugin throw LinkageError
@tender shard btw I just did the compile
the unobfuscated client is 21017 kb, the obfuscated client is 19789 kb
so you save about 1000 kb by obfuscating, saving a fraction of a second on download time
Minehut supports it
oh cool, the more you know ¯_(ツ)_/¯
Indeed :}
how low is your download speed
10 megabits
puts you close to a second i suppose
Isn't BuildTools for creating spigots? I want to use it for plugin development lol
It adds the NMS mapping to maven
Add spigot via maven or gradle
Ehh not about that life, just wanna add the JAR as a depend
So where do I obtain a JAR with NMS?

it's in your local maven repo
NoT ABoUt ThAT liFE
Bootstrap Jar
The main spigot-1.18.jar is now a bootstrap jar which contains all libraries. You cannot directly depend on this jar. You should depend on Spigot/Spigot-API/target/spigot-api-1.18-R0.1-SNAPSHOT-shaded.jar, or the entire contents of the bundler directory from your server, or use a dependency manager such as Maven or Gradle to handle this automatically.
Please read the release notes for further information: https://www.spigotmc.org/threads/9-years-of-spigotmc-spigot-bungeecord-1-18-1-18-1-release.534760/#post-4305163
Actually that’s just for the API
Yeah I found that but NMS :}
NMS is probably in spigot-server
in the event EntityBreedEvent
is the breeder the player?
alr thx a lot,i will assume its the player then
if it doesnt work imma sue bukkit for scam
what can possibly be the breeder besides Player
How would I set a custom skull head using Base64 situation with 1.18?
Seems GameProfile doesn't exist anymore
I don't wanna use getTextures().setSkin either because it's Base64 and that requires a URL :>
What!?!
Wtf is a herder villager
It still is
???
I have spigot-api and spigot-server as depends, which one is it cuz I cannot find GameProfile?
In 1.18
A villager that herds
use the spigot artifact instead
Hm alright
Oh! Aka shepherd
Yes sheep-herds
you can't specify a new generator
how would i regenerate just 1 chunk with a specific chunkgenerator (different from the world's)
how do i do this since getUnsafe() is depricated
return Bukkit.getUnsafe().modifyItemStack(skull,
"{SkullOwner:{Id:\"" + hashAsId + "\",Properties:{textures:[{Value:\"" + headId + "\"}]}}}"
);```
Dude I was just wondering that same thing lol
that doesnt exist
if you mean shepherds they just sell wool stuff they dont interact with animals
What is minecraftHash in BuildData/info.json? What is it a hash of?
It doesn't seem to match any hash in the version's manifest
I'll look at the uses of this value in specialsource or buildtools later then
Thx anyway
good idea
it still works
ignore the deprecation warning but beware that there be dragons
Why isn't there .getProperties() in PlayerProfile?
I know this is extremely dumb but how do I access this plugin thing
plugin is the class you extend JavaPlugin
So I do JavaPlugin.saveDefaultConfig();? lol
No
smh
Because I tried using my class name and it doesn't have that function
No offense, but I suggest you learn a little bit of Java before entering plugin development.
And getPlugin() has some red squiggle I don't understand'
Yeah I probably should have lol
I haven't had any issue with actual java knowledge until rn
Oh well
It makes it a bit difficult without it
Just a little, and learn as you go.
That's what I did :>
@short raptor the plugin there is a variable which probably references your plugin instance/object
how do you detect when player successfully tame horses
its not notified in entitytameevent
for some reasons
Sounds like a bug then which should be reported on the JIRA
Do you how how to implement this type of scenario?
playerProfile.setTextures(new ProfileProperty("textures", base64));
Or something like that
Ehm
Okay, and if I want skulls from this? https://minecraft-heads.com
I am not sure but I guess you dont need the signature
{
"type": "item",
"name":...
@ebon coral
So i gotta use this and somehow get a signed one
playerProfile.getTextures().sets
skullMeta.setOwnerProfile(playerProfile);```
Yeah I know
I just can't figure out the setting base64 part
Oh
Well the base64 is just an url iirc
And I do not want to use Mineskin's API and do some magic stuff for no reason if there's a way to impl it through basic Spigot API.
Yes, it just returns the texture though.
Unsigned
I'm not sure if the setSkin wants it signed
Try and see
Alright one second
So decode the base64 and use the URL
From the decoded base64 json
Let's see if dis works
Like I didn’t know this api existed until like a week or so, so I’m not really experienced regarding this btw lol
Yeah hopefully
// This is the most important method when registering an expansion from your plugin
public boolean persist() {
// This tells PlaceholderAPI to not unregister this hook when /papi reload is executed
return true;
}
Oh god that's scary
That's why I cant figure it out XD
Its already true
I feel like you should ask in HelpChat where the placeholder api maintainers are, they probably know their api much better than people here genuinely speaking
Nobody replied there 🥲 but true
Ah rip
I actually don’t know much about the new way papi implementation works
But is that marriage plugin yours?
yeah it's a fork of another marriage plugin that got outdated
Because it’s a pretty unorthodox way of registering your papi expansion
Ah
But it works fine until you use papi reload from the command line interface of papi?
im working my way around it
And i may not report if it somehow works with alternatives
if anyone else has the same problem you can help me report
yup
It all works fine until /papi reload in which case I need to reload my plugin for it to work again
So maybe I need to re register them but there's no papireloadevent or such and I thought persist took care of that but apparently not so I'm not sure what to do
yep 100% a bug
no alternatives should work because the tameable interface refuses to work
Thing is
If you have a persistent papi expansion
Then reloads should be up to you to control
Uh how exactly
But what if you moved the register part into onEnable
As opposed to having that listener
Oh god
The plugin has a weird way of handling stuff I'll have to see if that's possible
Yeah good luck
I think there's a custom plugin system on top of it
🥲
i'm wondering if i'm doing this, will the connection be opened twice?
try (Connection conn = connectionFactory.getConnection()) {
// do something with it
try (Connection conn1 = connectionFactory.getConnection()) {
//
}
}```
Do you still need help?
that'll open 2 connections, what are you trying to do?
its called connection in EntityPlayer
Nope
Are you using mojmappings?
I changed up some command code in an opensource spigot plugin and when I build the .jar and drop it in my server it tells me it is missing plugin.yml even though it is in the hierarchy
Then its just connection
How can I manually add existing plugin.yml in jar via IDEA then?
It's just a dependency, I just built the JAR with BuildTools
hmm
I have both spigot-server and spigot-api
I dont see pom.xml
its a gradle project
oh thats gradle
Compile it as a gradle project. Dont build artifacts.
Just run the gradlew thing? or is there spigotmc instructions on this
I tried rebuilding via idea or whatever, it told me its missing target "16" even though I have java 16 and 17
not sure if this is it
just call ./gradlew build
Okay
It uses the wrapper provided by the project.
same
Not sure what that means, any way around it?
Yes. But you wont have fun working with obfuscated nms
What do you suggest? ProtocolLib's API wasn't working for me in my application so I just wanted to go more direct.
Depending on what you do: ProtocolLib or apply the mappings in your maven project.
ProtocolLib will assure some compatability with other versions. Using nms will only work for your exact version.
What does the settings.gradle contain regarding the java version?
Not worried about version support, this is a custom application.
I think me changing to java 17 target just fixed it, 1 sec
nvm, checking gradle file
this?
alright and then build.gradle
Well I didnt change anything, but both java 16 and 17 seems to be having same error
I also found these
The remapped JAR is the correct one right?
^
Gonna try to build it again on BuildTools with --remapped
Hope that does the trick
Yeah that did the trick :>
public void onEntityHit(EntityDamageByEntityEvent event){
Entity entity = event.getEntity();
}
Required type:
net.minecraft.world.entity.Entity
Provided:
org.bukkit.entity.Entity
how can i make this work?
Import the right entity class?
is it worth to do something like Map<name, object> when that object already holds the name internal? for more easy lookup
Absolutely not
Unless
You are in a situation where you have a lot of objects of different names
And must convert between name and object
But if it's just to remove a getName() call, no.
Absolutely not.
it was to use a map instead of a set 👉👈
so i dont have to use .stream().filter() and i can just use Map#get
SetMultimap :3
assume i have something liek this
so i could do a Map<String: name, Home: home> if i dont have a field for the name in the home obj
instead of a set
That looks scary
Eh it's probably fine
🤷
why would that matter
Safety ✨
Specifically thread-safety and state validity.
Ugh it doesn’t matter to you but well immutability 🙌

In the world of Java
If you don't need mutability, don't use it
(Although it's a lil hard to know when you need mutability)
so would i put it in a map or not lol
How often are you getting the objects?
only when sending the whole list of homes to an user
so thats just looping over them
Couldn't you just iterate over the list of homes then?
mye
was just thinking for easier lookup
and Map#remove with returns the object itselfs vs Set#remove which returns nothing
boolean iirc
That boolean is also very implementation-specific
I'm pretty sure most sets don't ever return false
when the thing was already present?
how could I make something above a players name
a plane?
ah
hey im trying to create a cooldown manager class for my custom item abilities.
how would i store multiple cooldowns for one player and then send a message when the cooldown is over? would i have to use a scheduler/timer if i wanted a message sent?
HashMap<UUID, <ItemStack, Long>>
and whats better to use in a set with about 5 elements? foreach or Stream#filter?
Performance-wise, always the latter.
Streams on collections are eagerly created (as is the nature of a collection), so there's not great gain.
👍
any1 know?
Multimaps
Yeah you want to use the scheduler, most likely.
wdym
(And also a pair class :3)
Multimap is <K, V, V> right?
(Also: Why does Guava not have Pair- fuck that, why does Java not have Pair?)
Hello, should I keep all event listeners in one class and register only once? Because my plugin have some minigames, tools with stuff happening after interaction to block or entity and etc. And almost every one of them have Listener implementation and they are registered. My question is: Will this impact the server? Like I'm not sure if I should do this or not. The reason I'm doing this because I don't want to have a mess, like tools interaction with minigame interactions in same method.
No, that is uhh... Table iirc
create it yourself lol
its K, V but V takes multiple
oh right
Don't worry about it.
itemmeta uses that iirc
Having multiple listener classes vs. one is basically the same afaik
Only difference is the small classloading overhead
But like, don't fuckin' micro-optimize to the point where your code is worse.
ye
Thats a hash table. Multi map is just a wrapper for Map<K, Set<V>>
Technically Guava's Multimap supports multiple collection types
Collection iirc
Yes
SetMultimap would be Map<K,Set<V>>
Yes really
MultimapBuilder.hashKeys().arrayListValues().build() ;)
wait what are you talking about
Multimap is just Map<K,Collection<V>>
this or hashtable
Then we have ListMultimap<K,V> which is Map<K,List<V>>
*Was referring to the default HashMultimap
ok so ive read the documentation, should it be
Multimap<UUID, Long>
and then put multiple in the Long part
iirc yeah
I think multi map is badly designed. It hides a nested collection that deserves its own class.
but then how would i check for itemstacks
i would have to use strings to check and thats a bit weird
or some kind of key
check for itemstacks?
Myeah it’s sort of is too tightly coupled
custom ItemStacks should be identified using a pdc
I slightly disagree.
oh yeah PDC
But I can see it being a good abstraction to provide in apis
There is no point in not hiding the collection when you shouldn't be caring about the collection type from an API standpoint
@sacred mountain make a namespaced key, then on use add that namespaced key with a certain cooldown to the item, and decrease it/check if enough time passed
so is it better to use Hashmap<UUID, <ItemStack, Long>> or the multimap
use PDC
My problem with Multimap (and other Guava types) is the lack of Gson support.
Maow don’t they ship type adapters for those
Nope :)
wrong one
(Then ofc you need to use it with type tokens)
Not even in their type adapter repo
its this @sacred mountain https://www.spigotmc.org/threads/a-guide-to-1-14-persistentdataholder-api.371200/
Oh that’s odd
The problem is that you are passing data around that might lose context somewhere. Its a big difference if you have a List<Long> or a ChunkKeyContainer somewhere.
I mean I can see what you mean
Thought I read some code where they registered guava coll type adaps
i never understood that guide when reading it lol
But I think that they didn't design Multimap for that purpose or smthn
Yeah
True that the second type should be specified properly tho
SetMultimap/ListMultimap would fix that
For instance it can be very nice as when you pass an argument to a function
Where you just need a generic one to many
Oh yeah also it's obnoxious to do certain operations on a multimap
I don't remember which ones
But-
ah right
getting a key from a value
Quite a bit of code in guava is outdated. Example Maps.newHashMap(). This was designed because java 7 didnt allow empty diamonds for generic types.
Ye
The versions with arguments are better tho
ye
Since they allow you to declare maps in single lines
As opposed to the fucking
create map
put
put
put
put
return map
behemoth
I think we lost someone on the way that needed help...
What are you trying to do? Explain a bit please.
yep
ImmutableMap.<K, V>builder().put().put() 🥲
ImmutableMap builders are cool
except for the fuckin'
type parameters...
those... type parameters
Eh, Rust has it worse
fuckin' uhh
turbofish
MyStruct.help::<&str>()
I think that's it I'm not sure
uhm so basically, i have some abilities that ive made, but i want to add cooldowns to them. I thought to make a hashmap that stores the uuid, and the abilityitem and the cooldown associated with that item
Use pdcs for that.
100%
Wait... are the abilities on the ItemStack?
yea kind of
If you have the same ItemStack 2 times, should you be able to cast the spell 2 time in succession?
private final Map<ItemStack, Long> cooldownInnerHash = new HashMap<>();
public void getCooldown() {
cooldowns.put(UUID.randomUUID(), cooldownInnerHash);
System.out.println(cooldowns);
}```
the first one would set off the cooldown so you couldnt use the second one
until that cooldown is up
this is just a test btw
So the ItemStack does not contain the spell at all? It just triggers it.
yeah thats right
Then you should not used PDCs nor ItemStacks.
Something like
Map<UUID, Map<SpellType, Long>>
Would be the cleaner approach.
And even wrap the Map<SpellType, Long> in a serializable SpellCooldownDomain or SpellCooldownContainer
SpellType would be my own class right
Yes it would be an enum. Ive chosen an enum because its easily serializable.
You could also make this a bit more dynamic if you wanted. But then serialization gets really complicated.
public enum SpellType {
FIREBALL,
TNT,
}
right
how do i like those enums to the correct items
link*
i would guess something like this
You add a pdc to the ItemStack.
Key: Spells
Value: SpellType[]
Then in the interact event you check if the ItemStack has this key and then you get all
values and let the player cast it.
The cooldowns should probably be properties of your SpellType enum
i dont get what you mean by that sorry
public enum SpellType {
FIREBALL(1000L),
TNT(2500L);
SpellType(long coolDownMs) {
this.coolDownMs = coolDownMs;
}
private final long coolDownMs;
public long getCoolDownMs() {
return coolDownMs;
}
}
ohhh right i did that for strings before
How do I make a event like onServerLog so like when the console adds a log to the console i get it as a string
And do something with it
.put(SpellType.FIREBALL, SpellType.FIREBALL.getCoolDownMs())
probably write your own logger
Probably by hooking into the stdout stream
Nope. You dont need the map at all
Because the enum is basically a map already
uh
When I try to search up what is a logger or how can s logger be made I can't understand how a logger works? Can you explain how a logger can work?
uggggh
it basically logs string output to a console/ file
im not the best explaining this lol
7smile you can help me 🦈
Take one step at a time. Try to quantify your problem.
First: How do i "map" an ItemStack to a SpellType
So define 2 methods:
public List<SpellType> getSpells(ItemStack itemStack) {
}
public void addSpell(ItemStack itemStack, SpellType spellType) {
}
And think of them like a closed system. (Meaning those methods are not concerned about anything else but their single task)
I think what 7smile said about the stdout data might work I will learn about it
If you still have problems defining the problem then try to first define the responsibility of this method with a doc comment:
/**
* This method returns all SpellTypes on this ItemStack.
* If there are no SpellTypes present then an immutable
* empty List is returned.
* @param itemStack the input ItemStack
* @return A List of SpellTypes
*/
public List<SpellType> getSpells(ItemStack itemStack) {
}
Now we just need to think on how to implement this properly
Hint: A PDC entry can contain several Strings and therefore several Enums
How does logging data work?
PrintStream yourCustomPrintStream = ...;
System.setOut(yourCustomPrintStream);
This would be one approach. Its not a logger but replaces stdout.
Probably a good idea to just wrap the original stdout and delegate its data.
Thanks I will try to go from here and some more research about this topic I am creating a nice php website that uses rcon to send commands and a plugin to get the console data
php

thanks
wong reply
thanks
Was about to say
llol
i was gonna ask this previously, but is there a difference between the NMS itemstack and the org.bukkit one
What's wrong with php lol?
when i import it it askes me
oof
It exists
Some people like php I don't think anything is wrong with it its actually quite nice when u use it for making stuff like a simple task
I feel like a common trend for very like
divided languages
where a lot of people hate them but a lot of people love them
is that they're always
I know it had some major flaws, and ever since, it is sort of notoriously known for those very aforementioned things
"quite nice for simple tasks"
but then nobody uses them for just simple tasks
cough cough Skript

When a language is "quite nice for complex tasks" but then "real terrible for simple tasks," that's when you've reached Java territory ;)
I find it decent if you’re just doing something small
If you want to quickly write a simple task then you can just write a SpringBoot app in no time. Or Quarkus.
Or if you feel really extra then even a nodejs app. Or Python Flask. Or a quick rails app.
I think all of those things are quicker written for simple tasks than php.
Yeah of course, but kids making servers off of it make me cringe.
Like straight up prison servers, jesus christ.
But the implementation of Skript is probably not very solid in terms of performance I’d presume
Why do I think Java isn't good for simplicity? Well...
An actual nightmare.
Lol
It is not
ok for the first method, is it getting the spell type from the itemstack?
I did Skript for 4 years
Prison Core Skript, all inclusive 💯
Totally agree

$$ but still gross
Java > any day
Kids still try to argue you can use Java in Skript with addons and stuff but just why
Literally just learn Java
:(
Myeah, but you have to recompile it just every so often
XDD no way
Swear to god
I encountered many arguments back in my Minehut era
About it
And for that reason, I left.
if the List<SpellType> just returns a list of spells then why do i need the itemstack param
Alright, time to make an NMS tablist... I might cry.
This method exists to determine if an ItemStack is a trigger for certain spell types.
You basically extract the SpellTypes from that ItemStack
There is no way to use it as a small scripting language, although java MyClass.java exists and we have jshell as of 9.
...although it's also still a shithead to run since classpath + version management (praise our lord SDKMAN!).
(Also you have to declare a full class)
I know this isn't what it was meant for, but Java has a strong ecosystem that would be great with some proper scripting support.
My other reason is personal opinion: Too much ceremony.
so if (itemstack.getType().equals(Material.FIREBALL) && itemstack.getItemMeta.getdisplayname(fireball) blahblah )
THEN
return spelltype.firebal
At this point you dont care where its gonna be called. Could be in the PlayerInteractEvent
Or the InventoryClickEvent if you want to prevent letting the player move it.
Or in any other event that has access to ItemStacks,.
i dont need a list beacuse theres only one per item
im not going onto adding multiple abilities yet
Then its a bit simpler
My point is, if PowerShell can do it, Java can too :)
Nope. You want to return the exact SpellType on this ItemStack or null if it has none
And you should do that using pdcs
Is it possible to create a fake CraftPlayer or something (trying to make fake tab entries)
I haven't worked with NMS since 1.8 and this may not be so fun adapting to 1.18
i dont need addspell anymore right, as its only one per
You still need the method. You just rename it to setSpell
but the spells never change
theyre fixed on one item
The power of Java
I am losing braincells
Essentially IDEA recognizes that the type exists in the source file
Yeah yeah but I have both spigot-server and spigot-api implemented
Buuut it also has no idea where the fuck it is
Where would the authlib library be then lol?
Probably under Mojang's repo
Which I think is where GameProfile is
Ok ily
Yes but how do you bring them on the ItemStack?
i just use an interact event and check if the item name is the custom one and the material is the correct item
i guess its a bit of a bad way
i should store the data but eh its not like players can abuse it in my game
You shouldnt care about anything else but implementing those two methods
private final NamespacedKey spellKey = Objects.requireNonNull(NamespacedKey.fromString("spells:itemkey"));
public SpellType getSpell(ItemStack itemStack) {
if (itemStack == null) {
return null;
}
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
return null;
}
PersistentDataContainer container = meta.getPersistentDataContainer();
String spellStr = container.get(spellKey, PersistentDataType.STRING);
if (spellStr == null) {
return null;
}
return SpellType.valueOf(spellStr);
}
public void setSpell(ItemStack itemStack, SpellType spellType) {
Preconditions.checkArgument(itemStack != null && spellType != null);
ItemMeta meta = itemStack.getItemMeta();
Preconditions.checkArgument(meta != null);
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(spellKey, PersistentDataType.STRING, spellType.toString());
itemStack.setItemMeta(meta);
}
🥣 
hey @lost matrix i talked to you yesterday about evenly distributed workloads & i think i've wrapped my head around how it works and im very pleased with it. thanks again for a great explaination.
why people using Preconditions.checkArgument(obj != null) instead of Validate.notNull(obj) kekw
google supremacy
owo
hah furry
There is also Preconditions.checkNotNull(obj);
But checkArgument makes it more clear that the passed method arguments are invalid
💀
Okay but why are people using either when Objects.requireNonNull(obj)?
Oh yeah also
returns the obj if notnull instead of just throwing
Kotlin magic is just, the type by itself, and it's immediately non-nullable
Alongside the methods check and assert :)
fakePlayerProfile.getTextures().setSkin(new URL("http://textures.minecraft.net/texture/847b527998465154ad6c238a1e3c2dd3e32965352e3a64f36e16a9405ab8"));
Is there an easier way to do this besides this?
Like back in the day I could do .getProperties().put("textures", blah blah
Or does it have to be this way now?
I wish Java had better precondition handling :p
Postcondition is easy enough to do if you create your own Result/Option classes (also yes, Option, because Optional would be lacking support for your new Result class)
And what would result be? Why is this better than Optional?
Result is an Either type
Typically...
Result<T, E extends Exception>
It's a replacement for checked exceptions that, imo, gives devs more control
I created a lib for this kinda shit
is Command#getAliases a mutable collection? im trying to add an alias
"LazySupplier"
Suppliers are always lazy 😄
Not true
They are not evaluated once
They are evaluated per call
While their code is lazy
Their result is not
Hey, my PlayerAdvancementDoneEvent is being fired multiple times, when someone makes an achievement. any idea why or a fix?
I use the word "lazy" to describe the one-time caching of values too
@RequiredArgsConstructor
public class Lazy<T> {
private T value;
private final Supplier<T> supplier;
public T get() {
return this.value == null ? this.value = this.supplier.get() : this.value;
}
}
I just called it "Lazy"
And yes suppliers are per definition always lazy. They just dont cache the result.
I don't call it Lazy bc of LazyFunction
i see
In fact actually
It would be more accurate to call it like
SupplierLazy and FunctionLazy
but honestly that looks worse so no
Yes it looks weird
Surprised you didn't comment on Erie's most controversial feature :)
Nah that'd just be the same class as MaowImpl
You mean sneaky throws?
Yes
So if the dev isnt careful you shoot him in the knee basically
Yeah exactly
lul
The idea behind it is:
- Use
unwrapfor shit where you know the value will never fail - Use gracefully handling for everything else
It's also just good for prototyping
Yes I stole the design of that entire library from Rust
Exactly ✨
looks interesting. But sadly its not compatible with all the Optionals currently used
Actually you make a good point
I never thought about Optional -> Option compat (and vice-versa)
Maybe some conversion functions to easily pipe one into the other would be a good idea
Yeah that was the idea
e.g. uh
Option.from(Optional) and Option.toJava() // Optional/toOptional()
uh can i throw in two questions of my own, before you guys keep talking the next hour about code design?
Yeah
so 1) to write a library, do i need to do more than define public functions and import said library into a project?
I
suppose so?
I mean libraries aren't just public functions
Unless they're like a collection of interfaces
like uhh service providers, adapters (like Bukkit), etc.
Usually under the public stuff, you have some private implementation, which is where encapsulation comes in handy.
I mean my full username is an encapsulation joke
See uhh on GitHub my profile says
oh wait nvm
but anyway so MaowImpl but I usually go by Maow
Shit Java joke, yes
Anyway so yeah libraries can be kinda complicated
i think i know what you mean tho
At most you need basically
An entrypoint
That can be like, an abstract class, or maybe a final, uninstantiable class containing static methods.
does setting a class final make it unable to be extended/implemented?
Yeah
Uninheritable is the word you're looking for
Although you can't make a final interface
considering interfaces are meant to be inherited
is there any simple code to send an action bar to player? like
player.sendActionBar(...args...)
I suppose that makes sense
I have this common pattern in my project for util classes:
public final class FuckUtils {
private FuckUtils() {
throw new UnsupportedOperationException():
}
public static void util() { ... }
}
player.spigot().sendMessage(MessageType.ACTION_BAR, textComponent) or smth
You don't need to do this, I'm just a perfectionist.
huh manually throwing an exception might be useful tho
wait why throwing an exception in a private constructor
Stops reflective instantiation.
cant be created
grr reflection
It literally cannot be created unless you use Unsafe
But at that point I give up lol
eh fair
my second question is a bit more complicated tho
is there a simple way to check if a structure (resources/structure.nbt) is present in the world at specific coordinates?
if yes how
i found
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent("text"));
but error says
'TextComponent(java.lang.String)' is not public in 'java.awt.TextComponent'. Cannot be accessed from outside package
Structures? Hmm
well
Definitely not schematics
either would be fine
You'd have to ask someone else I know fuck all about structures