#help-development
1 messages ยท Page 823 of 1
idk if the API is updated for that tho
set implies it overwrites
are you running paper ?
from the looks of it, spigot just consideres "set" to be "add" now
paper drops any other resouce pack when running set
Uhh ? yeah I have paper, I thought it worked the same as Spigot, I will test ty
Yea I mean, difficult discussion on those methods
spigot basically breaks their old API by not "unsetting" old resource packs.
Paper breaks their spigot API compat by not breaking spigots old api
I see :/
yea its annoying
could have just added addResourcePack and dropResourcePack but welp
I think they will https://hub.spigotmc.org/jira/browse/SPIGOT-7530
I mean, yea that is unload
setResourcePack is still technically incorrect now, naming wise at least
and obviously behaviour wise
like, most simple breaking is like a /resourcepack command or whatever that allows a user to pick their pack.
When they switch from one to another, plugins using SetResourcePack before 1.20.3 would be fine, properly unloads the old one.
Now it keeps the original one and you gotta pray that the second one is fine merged on top of the first one.
Which like, yea gg breaks the behaviour.
.
We are discussing this :p
Yea I know there was an issue for this
Idk if it;s worth deprecating just to change it to add
surely there should be two now
I mean, set is not obsolete
there is 100% a need to just "hey, this is ALL you have now"
its a bit annoying with all the overloads tho
maybe worth to look into something along the lines of ResourcePackAdditionRequest that just holds all the values
true
?paste
https://paste.md-5.net/ajurasaxaw.xml how i can resolve it?
Hello. I need help on spigot 1.19.4:
online.setDisplayName(team.getTeamEnum().getChatColor() + player.getName());
When applying ChatColor to my player's displayName I get an exception (any ChatColor for that matter). Following is the error:
Chain link failed, continuing to next one
java.lang.IllegalStateException: Missing key in ResourceKey[minecraft:root / minecraft:chat_type]: ResourceKey[minecraft:chat_type / minecraft:raw]
at net.minecraft.core.IRegistry.e(SourceFile:88) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
at net.minecraft.network.chat.ChatMessageType.a(ChatMessageType.java:59) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
at net.minecraft.network.chat.ChatMessageType.a(ChatMessageType.java:49) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
at net.minecraft.server.network.PlayerConnection.chat(PlayerConnection.java:2121) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
at net.minecraft.server.network.PlayerConnection.b(PlayerConnection.java:2189) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
at net.minecraft.server.network.PlayerConnection.lambda$17(PlayerConnection.java:1895) ~[spigot-1.19.4-R0.1-SNAPSHOT.jar:3763-Spigot-7d7b241-5a5e43e]
when I do not set a color in the displayName the error disappears
how come its saying it will produce a nullpointer if im checking if theyre online beforehand
Your IDE does not know that "isOnline()" is the same as "is not null"
Rip
if I add a nullcheck the IDE says that its redundant since OfflinePlayer is never null
you can just call target.getPlayer()
Id prob throw AssertionError or sth if said thing is null
That is what you gotta be nullchecking
that will convert offlineplayer to player?
ok thx
That will return Player if is online, null if is not online
Iirc
The docs should say that
yes, whats "what" about that?
in theory, Bukkit::getPlayer ought not to be null at that point, or am I missing something?
how about converting PLayer to OfflinePLayer?
Why
.getOfflinePLayer doesnt exist
Precisely why
you mean OfflinePlayer::toPlayer ?
because my hashmap uses OfflinePlayer
(OfflinePlayer) player
so I cant use command sender
ehm
uuid shivering in fear
you should really use UUID
^^^^^^^^^^
true
very true
I didnt use Player because Player becomes null once they log off
no it doesnt
Just use uuid dude
I guess I could use uuid
The reference is dropped iirc
but the Player object gets a lot of invalid state
https://paste.md-5.net/uyacefeday.java
yo anyone experienced with streams understand why the output is coming out unsorted? when i call findAll on the datastore it will stream the current list of cached items. it will then request mongodb for an iterable matching the given query and stream that, then concat that to the stream of cached items. when sort is called, it instructs mongodb to sort the iterable on the server but also the stream to be sorted as a whole through CachedStreams.sortStream. this should now give us a sorted stream when a terminal operation is called but calling forEachOrdered gives a mostly unsorted result. i have confirmed the getFastOrderCoefficients method works as intended on cached items
ok interestingly removing the projection(...) call it works so it might have something to do with the fact that the data is partial
when should I use UUID and when should I use OfflinePlayer
if you store something, i would always use uuid
If you are storing it use uuid
I'm currently trying to create custom items, i cannot implement an interface to the already existing itemstacks to mark them as a custom item. Is there a good way to mark them other than marking them in the persistentdatacontainer of the item and checking each event whether its custom or not?
what is wrong with pdc ?
theres nothing wrong with it, it just feels nooby to me to check on every event if theres a specific item container attached
if its the best way im fine with it, i just felt like a noob doing it like this
Using PDC is the best way
far from nooby
pdc is the best
it's what you should be using to identify items
it makes me whole inside
almost as whole as Inventory PR it's that great!
Inventory PR?
00000000-0006-02d3-0000-000001e89640, deaths: 3 = fetched(DataItem(00000000-0006-02d3-0000-000001e89640 = MongoDatastoreExample.Stats(uuid=00000000-0006-02d3-0000-000001e89640, kills=0, deaths=5)))
wtf?
the stupid deaths field changed
how
OH
WAIT
i
im sutpdi
don't worry about it son. I dream of the future
i dont understand i thought pr is hitting 1 rep bench in the gym?
pull request
pull request?
pull request
Google your question before asking it:
https://www.google.com/
?bing
Bing your question before asking it:
https://www.bing.com/
why?
to not waste time perhaps
but if you bring it up and know the answer why do i need to google it
https://letmegooglethat.com/?q=What+is+a+Pull+Request%3F!
Because I am too lazy to explain and you can google it in 4 seconds
i dont know what to google when you just say "pull request"
"what is a pull request" is a great starting point
it proposal to add some changes or additions to existing codebase
ok
https://paste.md-5.net/egopacabef
HOLY SHIT FINALLY
this took so long
and its probably so slow
but it works
Does anyone happen to know if you can call constructors explicitly via unsafe?
you dont wanna use reflection?
Or, worse yet, whether
NEW MyObject
DUP
DUP
INVOKESTATIC OtherClass.consume(LMyObject;)V
INVOKESPECIAL MyObject.<init>()V
[...]
works
Writing a DI lib since I am not really satisfied with the already existing ones
I probably didn't grasp what DI is, but whatever.
And no, reflection does not allow such behaviour last time I checked
uh that looks very sus, why pass an unconstructed object around? that isn't exactly legal afaik (e.g. if you're gonna call methods or access fields)
May I ask what you need that for?
I know that I cannot use uninitialized objects in the constructor until I invoke the constructor of the superclass (unless it is for putfield).
well no, not even for putfield because it requires this which doesn't really exist yet
What exactly do you want to achieve with just calling the constructor, when the object itself must be existing so the this pointer can be passed
I don't understand
You need to allocate the object before calling the constructor, otherwise you'll get messy results
Well
public org.stianloader.test.smatterdi.generated_ExampleInjectionTarget_0(org.stianloader.smatterdi.InjectionContext);
descriptor: (Lorg/stianloader/smatterdi/InjectionContext;)V
flags: (0x0001) ACC_PUBLIC
Code:
stack=3, locals=2, args_size=2
0: aload 0
2: aload 1
4: putfield #7 // Field generated_context_1702214921568:Lorg/stianloader/smatterdi/InjectionContext;
18: aload 0
20: invokespecial #24 // Method org/stianloader/test/smatterdi/ExampleInjectionTarget."<init>":()V
23: return
does work
It isn't valid java source code, but it is valid java bytecode
sounds like a bug
although you'd think they'd catch that like every other thing that requires this before the super call
unless you're running with noverify which lulw
Well the verifier does complain about
7: aload 1
9: ldc #2 // class org/stianloader/test/smatterdi/generated_ExampleInjectionTarget_0
11: aload 0
13: invokeinterface #28, 3 // InterfaceMethod org/stianloader/smatterdi/InjectionContext.autowire:(Ljava/lang/Class;Ljava/lang/Object;)V
18: aload 0
20: invokespecial #24 // Method org/stianloader/test/smatterdi/ExampleInjectionTarget."<init>":()V
So I do not think that I have somehow disabled it
I basically want to create an instance of the object (Unsafe would handle that just fine), then "register" the instance so it can be used in other constructors
Basically what I intend is follows:
final class generated_MyRootObject extends MyRootObject {
private final InjectionContext ctx;
public generated_MyRootObject(InjectionContext ctx) {
this.ctx = ctx;
ctx.autowire(this);
super();
}
public final MyChildObject getChild0() {
return this.ctx.getInstance(MyChildObject.class);
}
}
@Autowire
abstract class MyRootObject {
private final MyChildObject child = this.getChild0();
@Inject
protected MyChildObject getChild0();
}
class MyChildObject {
MyChildObject(MyRootObject root) {
}
}
Basically the issue is that I have a circular dependency. Most would say "don't have circular dependencies", but I personally find that not very user-friendly and a system should have a way to resolve most benign circular dependencies.
Imagine using numbers when naming methods
Appending methods with 0 is convention for "this is internal" or "this thing is stuff in native space" or "this relies on magic"
I think people use it to fit team lead's dumb rules.
Java often uses method0() for uncached calls. Where a call to method() is cached
Why I do have to learn this if I can write getNativeChild()
So, native call method0 instead of method?
i mean, simple and understandable solution is, given A depends on B and vice versa, either a) A creates B in its ctor and passes itself, or b) let A take and use a Supplier/Lazy/Memoized/whatever around B
Neither a) nor b) Isn't possible unless I were to modify the constructor of the original class, at which point we wouldn't have this discussion. But it appears as if that is the only real solution unless I go nuclear with nonstandard ways of solving this problem
Imagine blaming someone to write numbers on their functions
It's not even against java name convention
Hi, does anyone have an idea why event.isShiftClick() of the InventoryClickEvent doesn't return true, even if it was a shift click?
Actually - I could just run autowire in getChild0()
event.getClick() == SHIFT_RIGHT or SHIFT_LEFT
Wait
let me try that
hey is anyone available to help me? (bungeecord problem)
so that I don't pose my problem unnecessarily
?ask
If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply. Make sure you use the right channel regarding the topic of your question. Create a thread in case the channel is already in use!
"so that I don't pose my problem unnecessarily"
Make sure you are in survival mode
just ask lol
not working
oh
hmm
I have already prepared the explanation of my problem I don't just want to send it if no one is available to help me
creative guis bane of the existence
I am currently sending a plugin message from bungeecord to spigot this way. The spigot server receives the message but from a player (I suppose random)
I was wondering if there was a way to specify the player to whom we would like to send the message plugin
Bungeecord Sending Message Code :
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
try {
dataOutputStream.writeUTF(swiftLoginBungee.getMainConfiguration().getToken());
String type = swiftPlayer.isLogged() ? "AUTHORIZED" : (swiftPlayer.isRegistered() ? "LOGIN" : "REGISTER");
dataOutputStream.writeUTF(type);
dataOutputStream.writeUTF("none");
dataOutputStream.writeUTF("");
serverInfo.sendData(SwiftLoginImplementation.CHANNEL_MESSAGE, byteArrayOutputStream.toByteArray());
return true;
} catch (IOException e) {
player.disconnect(new TextComponent("An error occurred! cannot send your data to the server!"));
throw e;
}
Spigot receiving mesage code :
@Override
public void onPluginMessageReceived(String s, Player handler, byte[] bytes) {
Basically when I receive my plugin message from spigot I would like the player of the onPluginMessageReceived function to be the one I specified on bungeecord
That would help me a lot
why's that?
Creative mode guis are a fucking mess
You can't handle them like you want to handle them in 90% situations
In particular player inv gui
It does not.
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
org/stianloader/test/smatterdi/generated_ExampleInjectionTarget_0.$generated_smatterdi_getInstance$(Lorg/stianloader/smatterdi/InjectionContext;)V @8: invokeinterface
Reason:
Type uninitialized 4 (current frame, stack[3]) is not assignable to 'java/lang/Object'
Current Frame:
bci: @8
flags: { }
locals: { 'org/stianloader/smatterdi/InjectionContext' }
stack: { uninitialized 4, 'org/stianloader/smatterdi/InjectionContext', 'java/lang/Class', uninitialized 4 }
Bytecode:
0000000: 1900 1202 bb00 025b b900 1f03 0059 b700
0000010: 09b0
Include the uuid of the player in your message
and parse it
hi, im not sure if this is a good place to ask but, how can I have different textures for each tnt stage?
or would I just use different blocks
You could hide the tnt and display a display entity instead
scheduler.runTaskLater(plugin, () ->{
Bukkit.broadcastMessage("aa"); }, 40L);```
why its not working
give the whole code
public record Example(List<String> arbitrary){}
If you put a list in a record like above does it return a copy?
e.g.
List<String> arbitrary = example.arbitrary();
arbitrary.add("some string"); // this doesn't modify the record's list but the copy returned??
override getter method i think
or you can add the initializer thing and copy it from the input param, so that it stores a copy
the
public Example {
arbitrary = List.copyOf(arbitrary);
}
thing
wow didn't realize you could do that :P
but depending on what you are doing, creating a fully copy on each invocation of the method might not be needed. making 1 copy at the start could be enough
(and its immutable)
yeah gonna go with the single copy
won't need to add anything to these lists anyways so returning an immutable copy should do
the thing with this is.. remember that you are modifying the parameters, not the field. So you can't do this.arbitrary = List.copyOf(arbitrary)
how does that work so java runs the constructor and the initializer runs after or vice versa
well it just runs the initializer (idk if that's what it is called) and uses the paramters afterwards for the constructor
ahhhk
this is where you would put Preconditions or Validates as well
stuff you want to run on all creations of the record
using allocateInstance and then calling it using a method handle?
idk if i understand what u mean
prob not with unsafe but methodhandles maybe
lmao this font
You can just call it via a methodhandle?
resolve the method with invokespecial
idk tbh
maybe using the internal lookup
you mean the java Unsafe?
sun.misc.unsafe my beloved
idk of a way to call methods via unsafe but method handles would be the closest thing prob
u could try it
You cannot use findSpecial as per it's javadocs and findConstructor does not allow to set a specific instance to call it on
Yeah
what do you need it for?
interesting
do you
know about
Dependency injection stuff
Class#getDeclaredConstructors?
https://github.com/slatepowered/veru/blob/master/veru-java8%2Fsrc%2Fmain%2Fjava%2Fslatepowered%2Fveru%2Freflect%2FUnsafeUtil.java i have code here for using the internal method handle lookup maybe u could try it
he literally doesn't want to call the constructor, he wants an uninitialized object and then call it later
you don't need to call the constructor
Well I think it is pretty confusing for most if you suddenly remove the constructor
?
he literally doesn't want to call the constructor
.
and how does that help him
I don't really understand this sentence
I want to call the constructor at a later date basically
cache
the Constructor object
he wants an uninitialized object that was made without calling a constructor, and then call the constructor later when stuff is autowired I presume
I want to basically do follows:
MyClass instance = Unsafe.allocateInstance(instance);
consumer.accept(instance);
instance.<init>();
so he wants to avoid loading the class?
you can load an instance without using the constructor my mans
Idk how to do it with Unsafe but ik its possible
No, I just want to perform logic before calling the super-constructor
Yeah, Unsafe#allocateInstance
But I still wouldn't be able to call the (super-)constructor later on
Yes I could bypass the constructor in it's entirety, but at that point I might use class redefinition shenanigans instead to inject the logic at the head of the super-constructor
I would not have this available.
I think just redefining the class would be the least cursed way
yeah redesign what you are doing
an initialization blocks run before the constructor too
Does it run before the super-ctor though?
no
no
Well I figured that I could simply notify the injector that the object is being initialized and if the @Inject-annotated methods of that class get called while super() is called I could autowire it also
only a child/parent static and parent initializer run before parent constructor
It catches like 70% of usecases, but those are enough for my needs - now.
At worst I'll go with classloader mayhem, thankfully I am quite experienced with it but would like to avoid it for the moment.
DI frameworks are impressively impossible to understand
Well there are some that I do semi-understand (Dagger & co.), but those are based on annotation processors which in turn I don't trust.
feather is pretty simple
Currently my API for creating objects is basically <T> T allocate(Lookup lookup, @NotNull Class<T> type, InjectionContext injectCtx, Object... args), other frameworks seem to overcomplicate it beyond anything
annotation processors which in turn I don't trust
yeah so, instead of trusting an AP which produces legal, normal, readable and debuggable source code, you want to hack all around internals and illegal states to find yourself in non standard situations
๐
Hey, at least I wrote it so I'll know what is wrong when it's wrong
dagger is the least intrusive DI framework i've used and it's pretty pleasant to use
but, you go
๐ค
The thing is as long as I cannot specify which constructor to call I am pretty lost
I have been working far too much with a nonstandard technology stack the last few years that I am absolutely foreign to the "standard" stack
Basically the only DI framework that I really understood is gradle's one, given that it had class transformation powers I'll follow it in it's footsteps
it doesn't modify your classes afaik
it just subclasses them
but they are able to do whatever they want in their own environment ofc
I am quite sure it would not be able to inject stuff with just subclassing
why not
Actually you might be right. I was thinking about getProject(), but that could very well be injected through standard means
stuff like
abstract class MyThing {
@Inject protected abstract ObjectFactory getObjects();
}
is just a field in the subclass
TIL this is valid initializer syntax
Right because an initializer doesn't make too much sense
Well ya learn something new every day
no i don't
nerd
Some people learn something new every day
Gradle seems to do it's stuff via
private static final ThreadLocal<TaskInfo> NEXT_INSTANCE = new ThreadLocal<>();
Well I suppose I could make subclassing work out after all. For most common usecases I already have found a solution, for the others I guess I'll throw an error as needed
Balkanize some random chars noone uses anyways
well you'd need to send a component with the font for that bit
otherwise, little code is needed
no idea
k
Ah right, fonts. Those exists these days
gotta search
i mean custom fonts have been a thing for, like, over a decade lol
but yeah, plenty of resources
Yeah, but afaik they used to balkanize stuff from the original (default) font [kinda like how people do with blockstates]. Or at least that is what I was taught was conventional back then
anyone nows good yt tutorials to learn java minecraft plugins?
Do you know Java?
is a hashcode of for example and item stack unique or would 2 itemstacks that are exactly the same have the same hashcode?
any one can rcommend some lib for making command without adding it to plugin,yml
commandapi, cloud, acf
by definition item stacks that are the same have the same hashcode
that is halal
A wise man once said there is a special place in hell for those who subclass ItemStack
Does anyone know how I would go about loading in schmetics with my plugin?
(The file I create with WorldEdit, but I need to load the schmetic through my own plugin, and I can't figure out how to do it)
or, y'know, just use the WE API
don't structures have an absurdly low size limit
i am now insulting anyone, mocking is different from insulting
but that's a conversation for another place
Does anyone know how to set the Head rotation of an armor stand to a vector?
mocking and insulting are 2 very different things
i can take a light hearted joke about any particular culture
Or the head rotation of a player? So basicly how to get the right yaw and pitch from a vector?
not an insult
i dont have the paitence for this
get a life and stop trying to be offended
,
Talk to the hand ๐๏ธ
i'm surprised there isn't a way to convert a Vector to an EulerAngle :thonk:
there is, math, but it's annoying
for starters, when you have a vector you can;t calculate a yaw without knowing another direction
you need to know what is zero to calculate a yaw
Hey i wanna show all Players but i it dont shows any, i get all CraftPlayers as a message
List<Player> list = new ArrayList<>(Bukkit.getOnlinePlayers());
for (Player player1 : list) {
player.showPlayer(Main.getPlugin(), player1);
player1.showPlayer(Main.getPlugin(), player);
player1.sendMessage(String.valueOf(player));
}```
and how do I calculate the yaw when I have 2 vectors?
what is the equivalent of Block.getbycombinedid in 1.20
what are you trying to do?
how do i get the contents of a decorated pot
idk if we have api for that yet
can you speak binary?
wwhat
im just joking
public static void setBlockInNativeDataPalette(World world, int x, int y, int z, int blockId, byte data, boolean applyPhysics) {
net.minecraft.server.v1_14_R1.World nmsWorld = ((CraftWorld) world).getHandle();
net.minecraft.server.v1_14_R1.Chunk nmsChunk = nmsWorld.getChunkAt(x >> 4, z >> 4);
IBlockData ibd = net.minecraft.server.v1_14_R1.Block.getByCombinedId(blockId + (data << 12));
ChunkSection cs = nmsChunk.getSections()[y >> 4];
if (cs == nmsChunk.a()) {
cs = new ChunkSection(y >> 4 << 4);
nmsChunk.getSections()[y >> 4] = cs;
}
if (applyPhysics)
cs.getBlocks().setBlock(x & 15, y & 15, z & 15, ibd);
else
cs.getBlocks().b(x & 15, y & 15, z & 15, ibd);
}
How can this be converted to 1.20
it seems the mappings have changed and i have no idea how to get the equivilant
?nms
Just use Mojang mappings
https://mappings.cephx.dev/ also you can see all mappings here
I want to make ender dragon movement but REALLY dont wanna do it with NMS in 1.8 so I have no clue what to do.
If you don't want to do nms you'll have to find a lib or smth
because you'll need it otherwise
So if this is really the only option... I will have to stick with it, the only downside is that this is the only thing I need nms for...
I need help with a command that enables and disables fall damage
Go ahead. Anything specific? ๐
I donโt know where to get started like Iโve tried but I canโt you know
You need to start to find out how to disable any fall damage first.
This can be done by listening to the EntityDamageEvent and checking if the cause is FALL_DAMAGE.
After that you need to only disable the fall damage on a condition. This condition can be a simple boolean
either set to true or false by a command.
Show some code after you found out the start.
Can i use Hex Color in 1.8.8?
Nope
If you wish to request or offer development/art/building/administration services, please do so at https://www.spigotmc.org/forums/services-recruitment-v2.54/
okay
most tolerant spigot user /j
That's a optimal core plugin cpu percentage on spark?
If I really need to optimize I will
My plugin is sitting at 1.43% with 1 player so I'm kinda concerned a bit but I can always optimize
error: ```Skonic:main: Could not find com.mojang:authlib:5.0.51.
Searched in the following locations:
- https://repo.maven.apache.org/maven2/com/mojang/authlib/5.0.51/authlib-5.0.51.pom
- file:/C:/Users/nagasonic/.m2/repository/com/mojang/authlib/5.0.51/authlib-5.0.51.pom
- https://hub.spigotmc.org/nexus/content/repositories/snapshots/com/mojang/authlib/5.0.51/authlib-5.0.51.pom
- https://oss.sonatype.org/content/groups/public/com/mojang/authlib/5.0.51/authlib-5.0.51.pom
- https://repo.skriptlang.org/releases/com/mojang/authlib/5.0.51/authlib-5.0.51.pom
- https://maven.citizensnpcs.co/repo/com/mojang/authlib/5.0.51/authlib-5.0.51.pom
- https://repo.dmulloy2.net/repository/public/com/mojang/authlib/5.0.51/authlib-5.0.51.pom
Required by:
project : > org.spigotmc:spigot:1.20.4-R0.1-SNAPSHOT:20231209.201618-1
Possible solution:
- Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html```
im using gradle
Cancel the event and broadcast a message
I believe there is also setFormat(), but if it works already thatโs alright
you'll find the real and proper answer in the paper discord
someone knows about Github -> Discord webhooks?
i did it one time and now it doesnt work
i used them once
nvm just worked out
lol
now /github has to be added to the final of the URL
weird
How fast does giving an entity a velocity of like 0, 1, 0 actually move them? 1 block per tick?
I don't think there's any direct correlation to a real unit
At least nothing meaningful enough for you to be able to predict anything
It's compilcated
It most probably uses it's own physics formulas
After setting/adding their velocity
So for gravity it's probably:
Vy(t) = (Vy(t-1) - 0.08) * 0.98
Which I think is the universal formula, probably used for most entities
Bear in mind this is up until the 6th tick but only sometimes, cuz minecraft physics
Air tick
TL;DR: It's a crap shoot. Trial and error. Set a value, if it's too slow, increase it. If it's too fast, reduce it.
But if your goal is to predict it
Find the physics formulas for your entity type online
And apply them
Generalised Y velocity formula for the player /\
https://www.mcpk.wiki/wiki/Nonrecursive_Movement_Formulas
Actual formulas /\
Since arithmetico-geometric sequences have explicit formulas, we can build non-recursive functions to calculate simple but useful results, such as the height of the player on any given tick, or the distance of a jump in terms of the initial speed and duration.
Definitions:
v
0
...
how can i add only the enchantment glint to the item but not an enchantment?
you cant you would have to add an enchant and give it hide enchants item flag
or packets
could probably do it with packets
Either add an invalid one
if its a block i give it mending
Or use commands and just do
{Enchantments:[{}]}
k thanks
i can do a fake ItemStack object btw
like from GSON
and do well
"enchantments":[{}]
maybe?
i'll try
thanks
Np
throwback to the ps3 version where you could just grab a fire aspect book
and slap ppl with it
BROO
i miss so much ps3 minecraft
in general old minecraft
now i can't even mantain a survival 3 days cause i get bored
how can i use packets to change a player's skin? i saw a thread at https://www.spigotmc.org/threads/changing-player-skin-with-packets.575531/ but it is outdated and the PacketPlayOutPlayerInfo does not exist anymore
For a while in java you could use a silk touch book to harvest grass
the packet is now ClientboundPlayerInfoUpdatePacket
thanks
how do i create custom entity instance
isn't that entities that already exists?
How would I go about loading in schematics using the Worldedit API? Cause everything I found online was outdated and worldedit-bukkit aswell as worldedit-core both don't seem to contain everything with schematics
Try their discord
good luck
a clazz is a class as teh name class is protected you can;t use it
what kind of a class is clazz
a clazz is just a arg name used to refer to any class
how do i use spawn then
the same as using any method in the API
its asking for a class
like Zombie.class
doing this CraftPlayer player = (CraftPlayer) playerExpression.getSingle(e); GameProfile profile = player.getProfile(); ReflectionUtils.sendPacket(p, new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.a.a, player.getHandle())); String skin = Skin.STEVE.value + "\", \"" + Skin.STEVE.signature; profile.getProperties().removeAll("textures"); profile.getProperties().put("textures", new Property("textures", skin)); ReflectionUtils.sendPacket(p, new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.a.a, player.getHandle()));
how can i fix?
ask in Skript discord
the error is not because of skript, its because the plugin can't find the class.
its a Skript error unable to find the class
Spigot uses obfuscated craftbukkit
Since CraftPlayer has a different name in the jar, it cannot be found.

I thought cb stays the same and nms gets obfuscated
it gets relocated
but yea, not obfuscated
just, _R3 is 1.20.3/1.20.4
you are running 1.20.2
update your server or downgrade the plugin to 1.20.2
I like how mc is obfuscated as fuck and people still turn it into readable code
ok
is there a way to get it to automatically import the right version?
no
well
via reflection
but like, for NMS access you want a multi module setup anyway
yeah im using https://github.com/CryptoMorin/XSeries/blob/master/src/main/java/com/cryptomorin/xseries/ReflectionUtils.java but you cant import it
like i need to use it like that but using the getCraftClass("entity.CraftPlayer you can't access the GameProfile
what do you mean you can't access game profile
im prob doing it wrong but
I mean, you are in reflection land
so you have to use reflection to grab the gameprofile field/method on the craft player
you don;t need GameP{rofile in 1.20 to mess with textures
use PlayerProfile in the API
GameProfile profile = ((ReflectionUtils.getCraftClass("entity.CraftPlayer")) player).getProfile();
wtf
Yea I mean, that is completely wrong
again
you are in reflection land
you don't get to go back to normal types
ALL textures for skins are set by url
yeah but its easier to use GameProfile
No, this is exactly what PlayerProfile was added for
it is the API access to GameProfile
GameProfile is Mojang AuthLIb. PlayerProfile is Bukkit API
IDK HOW IM BAD
how would you edit the textures using value and signature?
the value and signature is just a URL and a checksum
you add it as a Property
of if using PlayerProfile you setSkin
wdym by checksum?
its a checksum provided by Mojang to validate the skin
Changing a Player skin is not as easy as just changing teh skin and sending a packet
it seems like Zombie#setHealth cannot exceed 20
is there a way to make it exceed to 20
yes attributes
what are those
?jd-s search attribute
ok ill check those
Anyone knows how to read .mca files using php?
no
oh so those requires nms now
how about disabling some of their ai like making it so that zombies do not attack villagers but only players etc
https://github.com/aternosorg/php-nbt something like this should work then?
A full PHP implementation of Minecraft's Named Binary Tag (NBT) format. - GitHub - aternosorg/php-nbt: A full PHP implementation of Minecraft's Named Binary Tag (NBT) format.
so not all zombie mobs will be affected?
place a flag in the mobs PDC that you want to be special
then detect that flag in the event
PDC?
?pdc
i need to do packets cause the point of what im doing is to change a player's skin, but it only looks changed to the specified players
if you want to get CraftPlayer dynamically you can
I actually avoid all versioned imports and jump stright to NMS
?paste for me
this was for 1.19 but you can update it easily https://paste.md-5.net/xosahinaca.java
NMSUtils.java https://paste.md-5.net/osirefexiw.java
Still needs to be remapped which makes the code version dependent
So just be aware of that
yes, I only avoid the Bukkit versioning
ok
all nms is version specific so you can;t easily avoid that
So have you tried using the PlayerProfile API?
Yeah I told him to usae it instead of GameProfile
im just gonna keep using GameProfile since it goes better with my other code, tho thanks for the suggestion
yeah and i can just work that to send the packet to all the specified players
whats the new version of ServerPlayer and ServerLevel?
They're still called that
why can't i access them
oh i did the build tools, but do i need to remap it?
also how do i implement the remapped repo into gradle?
What's the best way to get rid of this warning
I'm 100% sure that under any circumstances this value will be List<Integer> in this case
My IDE doesn't know that and it's annoying
modification.getValue() is Object
@SuppressWarnings ig
WGHPModification holds WGHPModificationType type and Object value
Unfortunate
Is there a better way?
listToString takes List<T>
Technically if I cast to List<?> it should also work but it looks dirty
did u try @SupressWarnings("unchecked")
what's the listToString method signature
I know it's a solution, it's just an awkward one
public @NotNull <T> String listToString(final @NotNull List<@Nullable T> list, final @NotNull String delimeter)
How so?
you can just use List<?>
ah i see
anyone know how to do this?
im prob not experienced enough with streams to do this
basically i want to combine two sorted streams and remove duplicates (preferably prioritizing one stream)
one stream is sourced from the mongodb server cursor where it has already been sorted
the other stream comes from the local cache which i will sort with the fastComparator individually
Can't you collect the two streams into lists, join them and then get the resulting stream?
Or does it have to be done with streams only
here is an example of what you want
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class A {
public static void main(String[] args) {
List<Dog> dogList1 = Arrays.asList(new Dog("a", 1), new Dog("b", 2), new Dog("f", 3));
List<Dog> dogList2 = Arrays.asList(new Dog("b", 4), new Dog("c", 5), new Dog("f", 6));
List<Dog> dogList3 = Arrays.asList(new Dog("b", 7), new Dog("d", 8), new Dog("e", 9));
List<Dog> dogs = new ArrayList<>(
Stream.of(dogList1, dogList2, dogList3)
.flatMap(List::stream)
.collect(Collectors.toMap(Dog::getName,
d -> d,
(Dog x, Dog y) -> x == null ? y : x))
.values());
dogs.forEach(System.out::println);
}
}
class Dog {
String name;
int id;
public Dog(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}
have fun

streams only preferably as one stream is coming from the mongodb server cursor
removes duplicates but i want the result in stream form and i dont see anything sorting it here
i mean ig i can stream a temporary set yeah, but it would collect everything which i want to avoid
yh
well, idk if you will be able to sort and collect at the same time in an efficient manner you can turn this into a sorted list and then turn it into a stream, but not entirely sure why it needs to be a stream specifically
bc i dont want to request all the data from the server
imagine i have an operation on a database of 100k items
and 1000 items are cached
its a sorted findAll operation, so the server sorts the items on the database
and the cache is sorted locally
how would i zip those two streams together into one sorted stream without duplicates without requesting all items from the server
what DB server are you using?
idk what mongo is cable of, but MySQLcould easily do this no problem without anything additional to include removing duplicate entries
in fact not only can it do that but you can even have it store such things in a memory DB as well as a cache
i have a cache locally
idrc what the db server does
i just dont want to load 100k items into memory
sure but why sort your cache when you can just pull from a sorted cache ahead of time
bc my local cache is mutable
so has the latest changes
mongo probably does those optimizations too
but i want to include local changes made in memory which have not been saved yet
which works currently but i dont think its very efficient because its basically doing Stream.concat(cachedItems, remoteItems).distinct().sorted(comparator)
sounds like // TODO: overcomplicate to me
bro hit me with the k
you seem to keep adding more and more rules to this that don't seem necessary
that was exactly my original request
yes, but if your cache is mutable, why bother sorting it
wdym
im sorting a stream from the local in-memory cache on the client when i need it to be sorted
im not sorting the cache
why sort it at all?
tfdym
bc i need it for a sorted operation
datastore.findAll(..., /* useCaches */ true)
.await()
.sort(...)
``` should be sorted no?
ok so you are doing the sorting during a stream which is ideal, but now why do you need to combine two streams?
because, idk if this is true, but i can imagine that if i have two streams sorted with the same sorting i can efficiently zip them
instead of doing the whole sorting on the entire contents of the whole stream
which could be like 100k items
while its already 99.99% sorted
because the database did that
cache: [4, 5, 7, 9]
dbres: [1, 2, 3, 6, 8, ...]
why do you need the cache for this?
imagine im making a leaderboard
on a server
players are playing so their data is being edited in the cache
but not immediately saved to the database
now i want to display the leaderboard
it wont have the updated info until the data is saved by an autosave or a player leaving
there is an option to disable the use of caches in a bulk find operation and it is by default but i made it an option and now i want to optimize it because its fun
https://github.com/slatepowered/inset idk if this context is useful to you but this is the project its for
my datastore library
the docs are outdated but https://github.com/slatepowered/inset/blob/master/inset-mongodb/src/test/java/example/slatepowered/inset/MongoDatastoreExample.java has up to date 'examples'
and the leaderboard is going to display all 100k?
the leaderboard needs to sort the data to know what the top x are
yeah
which it is already almost because the database did it
but not completely because the cache is included
db can do this already, all there needs to be done is a range implemented
(i was joking)
it doesn't need it
how can it sort data it doesnt have wtf
so, not very likely. Then all that needs to be done is pull the relevant data in question for the positions
give me a reason not to do it
i already did it
but its slow probably
so im looking for a way to optimize it purely for fun
its disabled by default but streams have luckily made it pretty straightforward
so i implemented it
doesn't mean they are always the best
everything has limits you know, and when you hit those limits you have to change or add to what your are doing or sometimes remove
it may be best to leverage the DB software here
streams are not the only thing either that exist, sometimes the most basic things are far better ๐
if it doesnt use cached items it just uses the iterable returned by the database
such as
well, you already said you can't use lists for an arbitrary reason, which I assume means hashsets are out? But both of those could be streamed even though you can sort either one with relative ease
it seems you just want an all in one solution which I don't think exists
Any idea how to create a cube of particles? This is probably really easy but my brain is refusing to brain
I'm trying to surround a wg region with patricles
if you have two opposing corners, you can find the others, then you can find the center point
if you have the corners and center you have all the locations
I do have two opposing corners. My problem is that I'm for some reason struggling to understand the logic of getting the others
but, there is a I think utility method in bounding boxes for borders
I think if I get a pen and paper I'll figure it out
if you have two opposing corners you use triangles to find the others ๐
the triangle is still 2d just it slices the box
you can use that to find a 3rd corner, and then rotate
Ok that makes sense yeah
until you have all 8 points, but you only need half the points to cover the box though
since the other half is mirrored
I'm also thinking about the BoundingBox solution and checking the docs rn
just min/max on x,y,z
Does that seem good...
you only want faces
or borders depending on how they want it displayed
it will take a few loops, likejava plot xMin and xMax for loop y and z min to max
faces if they want the particles to show the entire cube, borders if they want just an outline
so 2 for loops
woudl plot you two faces in that example
are you only doing 4 sides, or 6?
I'm doing all sides. I'm currently trying to figure this out with pen and paper also
plot at min and max Z while for loop x and y
plot at min and max Y while for loop z and X```
that does all 6 faces
Well, 4 sides makes sense if the region extends from both limits otherwise 6
So if I have this, I can find the coordinates of the lower left front corner as {maxX; minY; minZ}, then I can find the upper left front corner as {maxX; maxY; minZ;}, then I can find the upper right front corner as {minX; maxY; minZ}. For the back side, top right back corner is {minX; maxY; maxZ}, bottom right back corner is {minX; minY; maxZ} and bottom left corner is {maxX; minY; maxZ}.
Now I have all 8 corners but now what
I'm overthinking something am I not
for (int y = yMin; y <= yMax; y++) {
for (int z = zMin; z <= zMax; z++) {
player.spawn minX, y, z...
player.spawn maxX, y, z...
}
}
//do same for other two```
Oh sorry I did not notice your answer. What is plot, is that iterating through the coordinates?
Uh huh
Hey,
I am trying to send plugin messages from bungeecord to paper and back. Paper receives the messages without problems but bungeecord does not.
I use this on spigot for sending:
main.getServer().getMessenger().registerOutgoingPluginChannel( main, "friends:bungee" );
try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(stream);
out.writeUTF("amount");
out.writeUTF("refresh");
player.sendPluginMessage(main, "friends:bungee", stream.toByteArray());
} catch (Exception e) {
System.out.println(e);
}
I currently just log every reveiced message on bungeecord. There I can see many default messages like register and so, but not a single of mine.
And I registered it on Bungeecord:
getProxy().registerChannel("friends:bungee");
Has anyone any idea why this is not working?
?whereami
if you have all 8 corners, and the goal is just the boarder then you can easily draw lines from one corner to another
you just find the points that are on the same axis to draw the lines
so, a point that shares an x and y axis with another, is an opposing corner
I want to cover the faces fully. I'm currently looking at my and Elgar's approach to figure out what I can do now
you just do that three times for the plots I showed above
where are you sending it? in an event?
you cannot send a message at the same tick as the player join
you must use the scheduler to delay it by one tick
ok, is ther a PostJoinevent?
no just use the scheduler
ok, thanks!+
plugin.getServer().getScheduler().runTaskLater(plugin, () -> <your message sending here>, 1L);
just runTask if you are doing it next tick
Btw, would spawning a bunch of particles every second be performance-heavy? I mean I'm gonna test it now anyway but maybe I should like increase the delay between spawning them or something
for teh client its bad
depends how many as it can be an issue with network bandwidth
Alright then, hope all goes well
if you've got some mad cpu, lower the compression threshold and it will compress packets a lot smaller than usual, but it will increase cpu usage for both server and client. otherwise, if the network can handle it, fire away
technically they are different, runTask = runTaskLater(..., 0), which causes some fun things where if you keep adding runTasks (and not runTaskLater(... 1)) inside the task itself it'll also run the newly added tasks on the current scheduler loop
definitely didn't have to learn that the hard way :D
you can not runTaskLater with 0, it will always be at best 1 tick later
all scheduled tasks will be at best on the next tick
you are mistaken
Nope
yes
Nope
and this happens if you add a runTask inside a runTask, if you do that expecting it'll run on the next tick
except that it won't
it will
literally look at the source code lmao
the docs are wrong
the docs are just wrong
it does exactly what the javadoc says
no it does not
it clearly doesn't, the source code says so
show?
yes, it adds to teh queue to run the next tick
I have one more question about pluginmessages, I send a message from bungeecord to player 1 with a payload. I console it there and when logging it on the spigot receiver server, the payload is received but for another player...
I have both mincrafts on the same laptop and therefore with the same ip but I think that shouldn't make a difference right?
which causes some fun things where if you keep adding runTasks (and not runTaskLater(... 1)) inside the task itself it'll also run the newly added tasks on the current scheduler loop
internally it calls teh runTaskLater with is basically overloading
it literally just adds it to teh scheduling queue
it sets delay = 0, and if you follow all the overloads down it ends here
private CraftTask handle(final CraftTask task, final long delay) {
task.setNextRun(currentTick + delay);
addTask(task);
return task;
}
which the current scheduler loop pulls from
so it is set to run on currentTick
no, addTask adds it to the queue
whether the server actually is capable of doing that, idk, but the actual setNextRun is set as currentTick
which will not get processed until the next tick
except that it will
"queue" 
I have never in many years of weorkgin with Bukkit and Executors seen a task run teh same tick it was scheduled.
might as well try
the spigot on the left and bungeecord on the right
i guess it depends where in the tick loop the addTask is actually called while it's processing plugin junk
(conjecture)
if its called right before the tasks get polled out of the "queue" then it will run same tick
otherwise, get fucked i guess it'll wait
@sterile axle any Idea with this problem? ๐
the scheduler keeps pulling from the queue on every task for whatever reason
Bukkit.getScheduler().runTaskLater(this, () -> {
getLogger().info("Outer on tick " + Bukkit.getCurrentTick());
Bukkit.getScheduler().runTask(this, () -> {
getLogger().info("Inner on tick " + Bukkit.getCurrentTick());
});
}, 10L);

spooky things
never seen. before
what is this getCurrentTick method ๐ง
hmmm
so what's your new code on your spigot server
maybe 1 tick isn't enough lmao
whats the output from this?
[12:39:30 INFO]: [Paper-Test-Plugin] Outer on tick 9
[12:39:30 INFO]: [Paper-Test-Plugin] Inner on tick 9
but this has nothing to do with the problem
but yes, it does this, and if you push a task within a task it will run that on the same scheduler tick loop
im too lazy to boot up spigot
idk what the problem is now then you're gonna have to spell it out for me
oh i see it
hold on
@sterile axle here
. putting this here so i can stop scrolling
yeah, as the scheduler should run at the beginning of a tick it should be impossible to insert and run on teh same tick

what
it literally isn't
the schedule runs through a shitty version of linked list
if your task is at the front
and you schedule another task to run on the same tick via runTask
that is appended not prepended to the shitty version of a linked list
um
so the scheduler pulls it
what's the code where you process the bungee message? the same?
I literally have never once seen a runTask ever run teh same tick
okay so, try
err I have. if it did much code would fail which requires it to run next tick
i s2g
I literally ran this
you can literally look at the source code
here new tasks are appended to the tail
the queue is the thing the main heartbeat consumes
Don;t know what to say. If what you are saying is correct it would break so many plugins.
@sterile axle I use this on bungeecord to send the message:
Collection<ProxiedPlayer> networkPlayers = ProxyServer.getInstance().getPlayers();
if ( networkPlayers == null || networkPlayers.isEmpty() ) return;
JSONObject payload = new JSONObject();
payload.put("online", main.getFriendshipManager().getOnlineFriends(player.getUniqueId()).size());
payload.put("total", main.getFriendshipManager().getFriends(player.getUniqueId()).size());
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF( "amount" );
out.writeUTF( payload.toJSONString() );
System.out.println("--sending:");
System.out.println(player.getName());
System.out.println(payload.toString());
player.getServer().getInfo().sendData( "friends:hub", out.toByteArray() );
it is correct
Clearly not given that is how it works lol
@sterile axle and receives the message on spigot:
if (!channel.equalsIgnoreCase( "friends:hub"))
return;
ByteArrayDataInput in = ByteStreams.newDataInput( bytes );
String subChannel = in.readUTF();
if (subChannel.equalsIgnoreCase("amount"))
{
JSONParser parser = new JSONParser();
JSONObject payload = null;
try {
payload = (JSONObject) parser.parse(in.readUTF());
} catch (ParseException e) {
System.out.println(e);
return;
}
System.out.println(player.getName());
System.out.println(payload.toString());
main.getScoreboardManager().updateLobbyScoreboardForPlayer(player, (Long) payload.get("online"), (Long) payload.get("total"));
}
we need a development-meta channel
is that in some sort of event?
the scheduler will tick at (almost) the very beginning of the mc tick, so tasks added during events/commands will run on the next tick, but tasks added inside a scheduled task itself will run on the current tick
I wonder if it's to do with running a task inside a task
Well WTH, that has nothign to do with what the original question was!!!
which causes some fun things where if you keep adding runTasks (and not runTaskLater(... 1)) inside the task itself it'll also run the newly added tasks on the current scheduler loop
that was literally in emilys initial statement ๐ญ
it had NOTHING to do with running a task inside a task
that's literally what i said lmao
it was LITERALLY using runTask over runTaskLater
i have no idea sorry, idk how it determines the player to receive the message
a single task not nested
i was pointing out that runTask is different from runTaskLater(1)

ONLY if nested
@sterile axle :c ok.
which is what they kept saying this entire time
still thanks!
lmao
which causes some fun things where if you keep adding runTasks (and not runTaskLater(... 1)) inside the task itself it'll also run the newly added tasks on the current scheduler loop
which causes some fun things where if you keep adding runTasks (and not runTaskLater(... 1)) inside the task itself it'll also run the newly added tasks on the current scheduler loop
which causes some fun things where if you keep adding runTasks (and not runTaskLater(... 1)) inside the task itself it'll also run the newly added tasks on the current scheduler loop
ok
stop spamming nerd
they didn't use the term of nested you are correct
true fuck
which is where your misunderstanding is at
So my previous statement is still factually correct
so is mine
perfection 
my description explicitly talks about scheduling tasks inside tasks
literally nesting
puts down popcorn and goes to get firehouse to wash y'all down
hoe lee
alright now that is settled we can move on from this lol
frost you can now use the room to help @torpid blaze bc idk what's wrong with his stuff
ok bye
yeah I looked back. I never saw you mention running inside a task, so I was arguing about non nested, you were arguing about nested
ok, still thanks!
This also happens with TaskExecutionServices
funny
you want it sent on a specific connection?
I want to send some json data to a specific player
I don't really know the bungee api as well as I do bukkits, but pluginmessage doesn't specifically use a particular connection to send a message as it isn't necessary or relevant just as long as its sent to the appropriate server
but the spigot always receives it for the first player that joined I think
I would rather use a websocket or redis if I have the choice though
when you receive the pluginmessage it is up to you to then send the message from in it, to the appropriate player which I don't see why this is an issue
but on spigot I use a player to send a message. But this doesn't matter. It always takes any player?
So you don't depend on a player to receive and send data
ok, so I should send the uuid of the player with the content?
the only difference with using a websocket is that its a bunch of strings instead of packets etc
that may be wise ๐
And you don't depend on a player
Plus ws allows you directly to send json
no, I think that is not worth it yet
Ye, for small communications you don't need to
while it is the difference and can be easily refined with your own system, I too favor this as well
I only need to send the message if a player is online as it should display stats for the play in the scoreboard
if memory serves yes this is how it has always worked exception being when communicating with the client but bungee and spigot take advantage of this protocol in a different way since communicating with the client in this way is mostly useless with spigot as it is only applicable with mods really.
websockets would be good as I would also send like mesages from my webinterface to the server.
it uses any player connection as long as the destination is the intended place you specified
ok
but as you said earlier the solution is simple
include the player UUID you want the message for ๐
because on bungeecord I can get the receiver player and this is working. so I thought it would be similar on spigot
that's what I will do. Thanks!
Hello, is there someone in here, who wanna learn me about implementing and using the Vault API?
?ask
If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply. Make sure you use the right channel regarding the topic of your question. Create a thread in case the channel is already in use!
?? Isn't that obvious? I wanna learn how to implement and use the Vault API?
That is too vague for us though
If you have no questions, just do dive in using it and ask the questions that arrive when they come
Alright... (wth)
How can i implement the Vault API?
How can i then check if the player has x money?
How do i remove x money from player, IF the player has?
Though - it you use Vault: please use the service events
...service events?
Read the documentation?
Also, please read all other issues before creating an issue over at the vault issue page(s). We get a LOT of duplicate questions
Vault's readme literally shows you how to use it tho
if you fail to understand something in there, then you can bring that up
For the second question: Use https://github.com/MilkBowl/VaultAPI/blob/master/src/main/java/net/milkbowl/vault/economy/Economy.java#L157
PLEASE Use the Service events though
The examples provided by vault will blow up one day or the other
That is, use https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/server/ServiceRegisterEvent.html instead of getting the economy service eagerly
you'd have to loadbefore vault for that to work as expected
Isn't the idea to load after vault tho
if you load after vault, there is a chance that the plugin providing the impl loaded before your plugin and has already registered the service
so your handler for that event will never be called for that service
Hence why they don't use that even in the examples I guess
Also, either you implement the Vault API or you use it, but rarely both (exceptions are plugins like EssentialsX).
And to withdraw if the player has the money, use https://github.com/MilkBowl/VaultAPI/blob/master/src/main/java/net/milkbowl/vault/economy/Economy.java#L189. Use the return value to check if the call succeeded.