#development
1 messages Β· Page 26 of 1
this is whats causing the issue
that class is way too big imo
consider separating all the send methods into a separate class which would also fix your subtyping issue
You can create an interface MessageSender, then instead of using CommandSender#sendMessage, have a method like
public void sendMessage(MessageSender messageSender, CommandSender commandSender) {
messageSender.sendMessage(commandSender, "some-message-here");
}
that would also work yeah
Then create a DiscordMessageSender in your discord module
And just have people use that
I agree that the class is way too big lol
what nooooo
For a Message class that is a giant
its just cause of the javadocs i think
Honestly I wouldn't even have the Message class handle the sending of messages
yeah this is what i was saying
I would invert this and have MessageSender have a method
public void sendMessage(AnnoyingMessage message, CommandSender sender) {
// implementation here
}
i agree
i already have AnnoyingSender
and keeping things as a POJO with a separate service/manager class is usually a lot better
That looks like it represents a CommandSender object though
Yeah listen to BM
follows SRP more strictly, makes things easier to test and keeps your classes small
hello i wanted to create plugin that let's my pickaxe level up and it would give it like efficiency enchantment but it's not working does anybody know what i'm doing wrong? My class https://paste.helpch.at/oxoluzigap.java
Instead of using lore, you should use persistent data containers, to keep track of data on items
Also, did you make sure to register the listener? And are there any console errors?
there are no console errors and yes i registered the listener (i think properly) here is my main class https://paste.helpch.at/ixucunusus.java
Which part doesn't work? Also try adding print statements
you're overriding the meta
iirc enchantments are on the meta
also if you use a regular diamond pickaxe your code will give an error
i use pickaxe that is given to me by a command that i set up
i thought that it is overriding meta but i'm kind of new and thought it would be better to ask
could you show me how to fix it because i'm doing something wrong or i can't understand something i'm trying to make it work but same thing happens?
nvm i fixed it thanks for help
if my plugin is using spigot api 1.11, should i not have api-version defined in my plugin.yml?
What was the point of that again?
what? the api-version or the flattening?
Api version
backwards compat
spigot does some hackery to make sure that old material names still work
api-version being above 1.13 skips that hackery
since it's guaranteed to be compatible
Ah. I have my own mats class for backwards compatability. Thought it blocked methods in the api that were higher then the version listed.
no, defining the api-version makes spigot trigger some bytecode modifying classloader shit show to ensure old (legacy) plugins (where api-version is not present) work fine in newer versions
yeah it's mostly just a thing for Material and MaterialData I think? either way it's jank af
biomes too ig
damn..
Paste Services
When asking for help with a config/menu/code issue please use our paste bin:
(we prefer it over pastebin.com)
β’ HelpChat Paste - How To Use
Hello, I've been coding a plugin for sorting group stats.
I've made a PlaceholderExpantion for it
but when I test it, It gives out nothing
just spaces
I've not even added any code that will give out space in output
Is there a way to put 4 values into a Hashmap? I need to put 2 Strings and 2 Integers per player into a config. What would be the best way to do that?
An
object 
someone who knows how to revert this commit?https://github.com/ZombieStriker/QualityArmory/commit/4cc371f1faea1063d026943455a027dcef076179
You have to use commands to do it. They really don't make it easy.
Idk the commands though.
I know, I tried doing it for like 30 minutes but it doesn't work
it is a merge commit so it makes the situation harder
GitKraken
i tried with gittower and it is a mess since it's a merge commit. do you think gitkraken would work?
It also depends if you want to revert or delete the commit...
You can use gitkraken, githubdesktop etc...
git reset --hard <commit-id> Resets repo to this commit don't recommend if it's more then 5 commits before your current.
Not sure what mess you mean, but works fine to me
doesn't work with all the files, the pom.xml is not reverted for example
is there just a way to delete these commits? i need to return to 5e3220483d4d19818c32b23863104802d5a37bff ( "Various changes" )
On that commit the pom doesn't seem to be changed, another thing you can do is reset head to the specific commit you want and force push it, but be careful as you will lose all commits above it
in this way ig?
will do
reverting commits is also scary for me xD
which one?
it worked, thank you
Why is it that you can't use modified variable in a lambda
int variable = 0;
if(query)
variable = 1;
list.forEach(obj -> secondary.put(obj, variable));
```But if the variable isn't nested in the same method/constructor its fine?
```java
int variable = 0;
public void setVariable() {
if(query)
variable = 1;
list.forEach(obj -> secondary.put(obj, variable));
}
```I know its suppose to be final for "concurrency" but why does one of these methods work? Shouldn't both not work?
because once the method is exited, the variables are removed from memory while class fields are kept in memory as long the object exists
actually, im curious about what @lyric gyro is going to say 
Why would that affect the usage? (Maybe I'm not reading into it right)
fields are accessed through this, not the field variable directly, this is final which is the requirement for lambda captures (and then a getfield is emitted inside the lambda)
making lambdas be able to take variables that are reassigned would be a mess to reason about, both in terms of "how do we implement this into the compiler" and "how does the lambda user think of lambdas"
basically, the lambda is separated into its own method, and the local variable you use inside of it is one of the parameters for it, making it only take "effectively final" local variables is easy to reason about because you know what the exact value will be when the lambda code is called, remember that lambdas can be called anytime, not immediately like in a foreach, futures and stuff run it later, if the time at which the lambda will run is uncertain then you also can't always know for certain what the actual value will be
it would also be extremely annoying and difficult to implement in the compiler
π
Hi, how can i create an ItemStack[] that fills all the player slots with air?
Why not just clear the players inventory?
cause i'm working with a plugin api, and it needs an ItemStack[]
i tried with new ItemStack[]{} but it doesn't fill all the slots
maybe new ItemStack[36]? as ItemStack[]{} is an empty array with size 0, which is different from an empty array with size 36
If that doesn't work you can use Arrays.fill
how would that work
you mean fill the 36-sized array, right?
yes
Yes
Arrays.fill
Whats the best way to store a players inventory in a MySQL database?
serialize as base64 is a good way to do so
if you can use latest version of paper, they have a better system for serialization
Hey, I was wondering, is it possible to join a server with same Premium account? Is there a way like changing the UUID of first player? Can you @mention me for the answer? Thanks
what
what
what
what
i think they are asking if you can double login to a server
what do you mean?
How can I achieve a command like this? Like actually get the c and m string. I know I need to use regex but I'm not familiar with regex.
/cmd player c: eco give player 1000 m: &aCongrats, you got 1k
it is possible with regex
I'd probably just use my own parser but for fun I'm gonna try making a regex lol
actually might not be that hard now that i think about it
is it just c and m?
/cmd player c:eco give player 1000 m:&aCongrats, you got 1k I'll try making something for this
Yes, exactly like that.
oh wait
oh wait is it always going to be c and then m?
i didn't really read what the command was lol
It shouldn't matter I guess?
ok i suck at regex
lol
Anyone know if its possible to override the default bungee commands within a bungee plugin?
I'm aware you can disable them in the modules.yml, but it doesnt seem to let me register any new commands with those accessors
haha, i appreciate the help bro
How do I set Main-Class manifest attribute in kotlin? Not sure why this doesnt work
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
manifest {
attributes "Main-Class": "RSA"
}
}
if you add the application plugin and set the mainClass property, it will generate the manifest I think
And it might be attributes.add() or something similar, the kts syntax is not the same
manifest {
attributes["Main-Class"] = "com.example.MainKt"
}```
If two players use same Premium account, naturally they will have the same UUID and I believe which is why they can't play together. I was thinking if there is a way to bypass the UUID system in order to play with same account.
You can not be connected twice with an account, not even to two different servers
have you solved it yet?
.* c:(?<c>.*) m:(?<m>.*)
i bet there are better ways but thats what i came up with
Or use a command lib that accepts "greedy parameters"
common XY problem
Like /cmd player "command here" "message here"
im just not sure if those would handle it perfectly as it would need these things "
yea
Damn, that's perfect.
Thank you so much bro.
If the framework supports brigadier, even better, you can always know what the parameter is
ah rip https://github.com/HelpChat/DeluxeMenus/ is closed source
was gonna make a pr π©
no you won't 
You can always make a suggestion and hope someone is listening :))
Why does the first Sysout print return true but the second one return false?
The boolean should be set to true, and it should never go back to false
is the command run by two players by any chance?
Nope, I'm the only one testing it
did u make two instances with the command and listener
im very sorry i replied to the wrong person
if you have setExecutor(new Class()) and registerEvents(new Class()) that's why
CommandHiddenPresents chp = new CommandHiddenPresents();
registerEvents(chp, plugin);
setExecutor(chp);
save the instance of one class locally wherever you're registering them and then use that for both
welcome to oop π
@proud pebbleSo do you know or not?
any ideas what can cause this? https://github.com/JoseGamerPT/RealScoreboard/issues/53
https://paste.helpch.at/pukedusuko.less related lines from menu
since it's annoying to users that use our plugin
users are getting this error when we renamed main class from RealScoreboard to RealScoreboardPlugin
idk where's problem so I decided to ask here, anyone?
java.lang.ClassCastException: class josegamerpt.realscoreboard.RealScoreboardPlugin cannot be cast to class josegamerpt.realscoreboard.RealScoreboard
The error is clear
These are two different classes and RealScoreboardPlugin cant be casted as RealScoreboard
Also, just so you know, you are distributing a premium plugin trough that repo, mcmmo @split stump
We temporary added it and I forgot to add .gitignore since their maven repo doesn't work
this still don't explain me where problem is
We only renamed RealScoreboard to RealScoreboardPlugin, anything else was not changed
How can you rename the class if have you have classes with these names?
Just look in source how it works
I cant find Expansion
??
at Expansion.onRequest(Expansion.java:108)
Where is this class?
We don't have any class called Expansion and we never had
@still thicket who made that expansion?
Yes I asked him about that
since I couldnt find it in eCloud
so I suppose it can cause issues
There's nothing in the ecloud with that name though
yeah
@still thicket if it is a custom expansion, it needs to be updated
Now it makes sense what you were saying, sorry Techno
Yes I noticed him about that because I supposed before that %state% is official expansion but didn't find in ecloud
Deleted, now I need to find working maven repo
Thanks β₯οΈ
np
is it efficient to use PlayerMoveEvent to check if player entered a specific region with WorldGuard API ?
is probably the only way to do so
Maybe worldguard has an option to notify you when that happens?
https://worldguard.enginehub.org/en/latest/developer/regions/events/ there's only one π¬ DisallowedPVPEvent
Interesting
No, it is not possible to do what you want to do
Technically you can change the UUID, however it is likely to break many things and so I'd highly recommend against it
the only reason anyone would ever want to change the uuid of a player so you can allow 2 instances of that player account to exist on the server is so that you can allow for 2 people to join while using one account license which suggests one person doesnt want to pay for the game which suggests piracy
You can connect to two different servers with one account?
From my experience you will get an error saying you are already connected somewhere
You can join multiple servers with 1 account. Just can't be the same network
ah yeah I see, well iirc this was the case at some point
ty it helped me a lot
is there a way to add additional logic to an existing flag?
for ex. I want to allow only 3 people in a region, if it's name is X
So in the end, we can play together?
How the hell do you change your account's UUID? I never heard of this.
No
Modifying packet info ig
If that doesn't work then reflection
If that doesn't work then custom server jar
π₯²
Pretty sure they want to do this on other servers not theirs
I created this program that can encrypt and decrypt a text using RSA. But I'm running into an issue, messageNum should always equal decryption but it only does sometimes, not sure why. https://paste.helpch.at/upepiruqad.java
what does "sometimes" mean? For specific input? Totally random? When running on a toaster?
I don't think he can run on a toaster
Seems totally random, when using the same input
and how does it differ?
Like if args[0] = 16 and args[1] = te it will be wrong maybe 1/5 times
Like this, if it makes sense
Same input, but in the last one, the decrypted number is wrong
for debugging, you could replace the secure random with a random with a fixed seed
Do you have an example?
aight
new Random(0)
When using this instead, it works
Or well the decryption is always equal to the original message
But it doesn't seem very random
yeah it will always give you the same results this way
Does the seed mean it gives a specific sequence? That will be the same everything I run the program?
When using the same seed ofc.
yes
but you can now make some of the things that depend on randomness predictable/repeatable and figure out which of them causes the issue
I see, but SecureRandom itself should not be the issue I assume?
nope, but it makes debugging harder I guess
True, seems like it
Thank you! I will try and debug it then
Random is only used here, and it gives a wrong answer sometimes even though both are prime ```java
BigInteger p = BigInteger.probablePrime(N/2, sRandom);
debugging += "p = " + p + "\n";
BigInteger q = BigInteger.probablePrime(N/2, sRandom);
debugging += "q = " + q + "\n";
Not sure why tho
Using this gives a wrong result as well final Random random = new Random(2);
With 2 as the seed
GOT IT
If you wanna know why it's because the modulus has to be a higher number than the number that is being encrypted, which it wasn't for some random numbers
ah yeah, you'd need to split it up into multiple blocks otherwise
but you said "Technically you can change the UUID"
im saying it is possible but I don't recommend it and I won't tell you how to do it because doing it will probably cause 10000 bugs
I just wanted to know the possibility, not how to do it
id assume its possible
most things are possible
the amount of pissing out you would have to do it would be more worth it to just buy another account
^
it is possible, I've mentioned that above, that's what I meant by "technically" but it might've been hard to understand through Discord
two players being able to play on the same account
but with different stats
Yeah, instead of doing this hackery, implement a profile system
All you need to do is to make everything on your server custom D:
I was assuming they are playing at the same time
You can not do that
You can not connect to a server twice
ok
oh this isn't possible
I thought you meant at separate times
actually
technically it's possible
with hackery
π
everything is possible with hacks π
How?
And even if you can do so, it is not worth
Just play in offline-mode at this point LOL
you cannot decide that
intercepting packets
oh wait is this online or offline mode
...
ye but i was just saying
why would I want two players to join with same premium account in offline-mode lmao

ahhhhh my mistakes
so it is not possible...
why it is possible on offline-mode though?
In offline mode you can have as many accounts you want
problem solved
It is, but since two players would have the same username but different uuid, it would cause issues
Are you trying to solve a problem you dont face, or whats the reason you want to allow several people to use one account at the same time? Im curious
okie thank you
umm I would like to keep it private
and profile system can solve the username thing
no it cannot
well that's odd
for example luckperms doesn't like it when a player logs in with a different uuid but same name
another example is minecraft's own advancement system
"dkim19375 got an achievement"
"dkim19375 got an achievement"
anyway my problem is solved thanks
I've been working for some time on this api now and I've a few questions
When is it better to call Mono#block() compared to Mono#subscribe()
If I use Mono#subscribeOn(Scheduler) will the object require a Mono#publishOn(Publisher) call somewhere along the chain before it can actually emit its element?
If I'm using a Schedulers#boundedElastic(), do I ever need to destroy the thread when I'm done with it or does it recycle automatically when the thread is finished with its tasks? Also, if the thread is constantly running, will I need to shut everything down and destroy the thread manually to avoid issues or does it have the ability to do so automatically?
Related to the Reactor API
Sounds like an Emily question

Well to start with, publishOn takes a Scheduler, it's basically how you can jump between threads on a sense (if.. used correctly), a Publisher is the source of data; you probably just got confused there but just in case you didn't I'm trying to clear things up in that subtle thing
If I use Mono#subscribeOn(Scheduler) will the object require a Mono#publishOn(Scheduler) call somewhere along the chain before it can actually emit its element?
subscribeOn will set the scheduler on whichrequestwill happen, without subscribeOn the thread will be whichever thread you call the final subscribe on.
This has nothing to do with in which thread the elements are emitted (the source might jump to another thread of its own to take elements from, though if it does not do that then it will be that one), if you want to control that then that's where you use publishOn, when its onNext is called, it calls downstream onNext on the thread of the scheduler you tell it to
When is it better to call Mono#block() compared to Mono#subscribe()
When you for whatever reason need the result at the spot and cannot change that (e.g you need to return the Value as opposed to being able to return a Publisher<Value>), but if you can return the publisher just return the publisher, if you only need to process an element (not return it, e.g. set a field or update other stuff) .subscribe(e -> ...) is far more appropriate as it will be called when it's needed
If I'm using a Schedulers#boundedElastic(), do I ever need to destroy the thread when I'm done with it or does it recycle automatically when the thread is finished with its tasks?
it's all handled internally; if you do create a worker from the scheduler to handle it yourself you do need to dispose of it accordingly tho
if the thread is constantly running, will I need to shut everything down and destroy the thread manually to avoid issues or does it have the ability to do so automatically?
the default Schedulers spawn daemon threads, they are disposed by the jvm on shutdown
@lyric gyro and does that mean the Disposable generated by the Mono#subscribe() method is also handled internally? Or do I need to call Disposable#dispose()
The Disposable returned by subscribe is the subscription itself, calling dispose basically calls cancel() upstream
Thanks very much π
I don't think it's a guarantee it's the subscription itself so that's not something to rely upon, but the javadoc says that the disposable can be used to cancel the subscription
(Repost cuz I put it in the wrong channel I think)
I've run into a complete wall trying to modify Frosted Ice. I want to set a block to be a specific level of Frosted Ice but I can't find anything online about how to do it. It doesn't seem to be BlockState or BlockData and it doesn't have it's own class like Slab does. Any advice?
I do not understand why Bukkit contains so many interfaces that hold only one or two methods
That is good actually
Interface segregation principle
Smaller interfaces = more composable = more testable

Precisely!
It does make it a lot easier to change things, and keep track of what each individual thing does
Better implementation
And like Mitten said, segregation principle
its not much better when saving the data
it loads player data from their yaml files
the first obvious step is to split it into multiple methods
have smaller methods to load a specific bit of data from a section
oh lord
by nf
In my bungeecord console it says i am connecting then disconnecting from a server conected but wont send me to it.
A member of staff has requested I move your message to a paste,
Most likely because it contains a config/error/code snippet.
Lol
Thanks Barry
It completely ignored the actual code
@proud pebble if you can post the code again, this time on a paste instead, the bot killed it
noob
Because you made the methods package-private instead of public (aka it's missing the access modifier)
So why does it work in my main class? https://i.imgur.com/DibSdrK.png
Ohh you're right. So how do I change that? I've never had that problem before
Add the public keyword to the methods
@dusky harness
Omg I thought they already were lmao Thanks for the help
It happens ;p
when i originally made the loadplayers method it was my first time saving to file with yaml
Hi! Does anyone knows what going wrong? I try to get a texture on a player head it works before but suddenly doesn't work anymore for some textures. The examples are findable in the code -> https://paste.helpch.at/eliqacoxot.java. I also tried to set the Base64 data from the given examples inside the textures property but same result. I hope someone knows what is wrong, my server is running on Paper 1.16.5 by the way. As you also can see in the examples the url are both just findable when typing in on the browser.
Sooo this is quite apparently a simple thing, was messing with JPanels, etc. and was doing a grid that can be modified with a variable... this is the code/math I used:
public void paintComponent(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.black);
g.drawRect(0, 0, getWidth(), getHeight() - 1);
for (int i = 1; i < rows; i ++) {
g.drawLine(0, i * (getHeight() / rows), getWidth(), i * (getHeight() / rows));
}
for (int i = 1; i < columns; i++) {
g.drawLine(i * (getWidth() / columns) + 1, 0, i *(getWidth() / columns) + 1, getHeight());
}
}```
This is the issue, it appears to have an error somewhere...
is it I do this wrong or client bug? Is on 1.12.2 paper, create an door with the name ACACIA_DOOR_ITEM (old version seams to not use ACACIA_DOOR). I set right data also ofc (it should not show the item at all).
Pretty sure you are doing it wrong, I could be incorrect about the following but it's worth checking.
Try doing /give [user] [item] and then if it work successfully then copy paste the whatever you wrote down as the item into your config file.
What version is your server on btw?
1.12.2 turns out it not use the data value on doors. As they are not consistent in the spigot api, some items do you need set data and some you not have to.
It has lots of inconsistency in the api (even in latest versions). They should rewrite there code or add warn this method/event not always do logic things π
Some events alter the inventory, without mention that in the java doc (when it should get contents and modify it after clone items).
Why was the constructor PacketPlayOutSpawnEntity(EntityLiving var0) removed in 1.19.3?
I find it odd that I can't pass EntityLiving to PacketPlayOutSpawnEntity(Entity var0)
what does it say?
One sec
cus EntityLiving extends Entity so it should be passable
Exactly lol. But I think I found the problem one sec testing it.
Yeap. I was still using EntityLiving in the constructor instead of Entity
Before: cache.getSpawnPacket().getConstructor(cache.getEntityLiving()).newInstance(stand);
After: cache.getSpawnPacket().getConstructor(cache.getEntity()).newInstance(stand);
Yeah. Kinda weird they removed removed the original though.
maybe it so you can spawn entities that arent living or smth
They had both constructors before
oh
Huh.... PacketPlayOutEntityMetadata constructors don't require the entityId anymore
fun
Wait... they changed it from class to record?
So still takes the id just created differently
Well, i = 1, i < rows means it will go from 1 to rows-1, is that what you want?
Also you need to use DataWatcher.packDirty() to create the PacketPlayOutEntityMetadata class.
Ex;new PacketPlayOutEntityMetadata(armorStand.getId(), armorStand.getDataWatcher().packDirty())
eh found out the issue already, ty though
the issue was the fact sometimes I was getting decimals and it was converting them to ints
hence creating an error margin
which grew bigger if I increased the number of rows or columns
so I had to use doubles all the way until the last part and then convert it to int
If anyone has experience with mythic mobs, is possible to remove a mob without playing the despawn animation? Like Entity#remove
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
Inventory inventory = event.getInventory();
if (inventory == null || !inventory.getTitle().equals(INVENTORY_TITLE)) {
return;
}
event.setCancelled(true);
}```
seems to be a problem with `if (inventory == null || !inventory.getTitle().equals(INVENTORY_TITLE)) {`
any ideas on how i could fix this? or preferably make a better way to cancel inventory click events in a specific gui named `Kit Editor βΊ Kit Selection`
i do have ` private static final String INVENTORY_TITLE = "Kit Editor βΊ Kit Selection";` btw
Dont use titles, use InventoryHolder
d;bukkit#createinventory
@NotNull
public static Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type)
throws IllegalArgumentException```
Creates an empty inventory with the specified type. If the type is InventoryType.CHEST, the new inventory has a size of 27; otherwise the new inventory has the normal size for its type.
InventoryType.WORKBENCH will not process crafting recipes if created with this method. Use HumanEntity.openWorkbench(Location, boolean) instead.
InventoryType.ENCHANTING will not process ItemStacks for possible enchanting results. Use HumanEntity.openEnchanting(Location, boolean) instead.
a new inventory
owner - the holder of the inventory, or null to indicate no holder
type - the type of inventory to create
IllegalArgumentException - if the InventoryType cannot be viewed.
You make a class that implements inventoryholder and on InventoryClickEvent you check if the holder of the inventory is an instance of yours
@Nullable
public static Player getPlayer(@NotNull String name)```
Gets a player object by the given username.
This method may not return objects for offline players.
a player if one was found, null otherwise
name - the name to look up
@dense drift
it actually does but why isnt it working
Get title is a bad way to handle inventories
elaborate
Multiple inventories can have the same title, and your system will be broken.
And as you can see, it works perfect π
i'm not trying to find the person opening the inventory but the title of the inventory / the name of it
and cancel the inventoryclickevent
now the actual question i shouldve asked is what you think could be causing the getTitle() to not work
public void onInventoryClick(InventoryClickEvent event) {
Inventory inventory = event.getInventory();
if (inventory.getTitle().equals(INVENTORY_TITLE)) {
return;
}
event.setCancelled(true);
}```
can't post a screenshot but getTitle() is underlined in intellij (because theres likely a error)
You won't be able to upload images here directly to avoid spam, so please use https://imgur.com/upload or similar service to upload images/screenshots.
public static Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type)
This is the method you want to use. After you have created the class that implementes InventoryHolder you pass an instance as first parameter
createInventory(new CustomInventoryHolder(), InventoryType.CHEST)and on InventoryClickEvent you simply doif (inventory.getHolder() instanceof CustomInventoryHolder)
It's e.getView(). getTitle() in newer versions
oh.
wait but is it e.getTitle(0 or only for getview
lmao
The title is inside of the view
Yes
Though as Gaby mentioned, you shouldn't use titles to check if the inventory is the correct one
so i replace inventory.getTitle()
with e.getView().getTitle()
i don't have any other guis named the same thing
Renaming a chest will also rename the inventory's title, which players can do, depending on the plugins on the server they can even have colors and match 1 to 1 your title
Store the inventory instance and compare instances, or make an inventory holder and check if the correct iventory's holder is yours
Yes
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
Inventory inventory = event.getInventory();
if (e.getView().getTitle().equals(INVENTORY_TITLE)) {
return;
}
event.setCancelled(true);
}```
now what do I do with `Inventory inventory = event.getInventory();`
A member of staff has requested I move your message to a paste,
Most likely because it contains a config/error/code snippet.
You write in the equals method what the name is you wish it to be
"Inventory"
As a string
INVENTORY_TITLE is already doing that tho
private static final String INVENTORY_TITLE = "Kit Editor βΊ Kit Selection";```
Ok the you're good
dont make it static i think
nvm ur right
Yeah no reason for it to be static
if (e.getView().getTitle().equals(INVENTORY_TITLE)) {
now e is getting underlined
It's a constant, it's correct to be static
Unles you want to access it without any instances
i should do that yeah prob
can someone help with my issue?
the source is here:
https://paste.helpch.at/apacikozac
my plugin does not hook with the economy and chat plugins per vault
Yeah cuz you named Ur event event not e
what is it
private ItemStack createPotionItem() {
ItemStack item = new ItemStack(Material.SPLASH_POTION, 1);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName("Potion");
meta.addCustomEffect(new PotionEffect(PotionEffectType.HEAL, 100, 1), true);
item.setItemMeta(meta);
return item;
}
meta.addCustomEffect(new PotionEffect(PotionEffectType.HEAL, 100, 1), true);
specifically ^
what type of error
wait i try to reproduce
ItemMeta doesn't have addCustomEffect, that is part of PotionMeta, you need to check if your meta is instance of PotionMeta then cast it, then you'll have access to the method
i have all the imports necessary i'm 99% sure
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
potionMeta#addCustomEffect
oh
got a error again
non-static method addCustomEffect(org.bukkit.potion.PotionEffect,boolean) cannot be referenced from a static context
yes
private ItemStack createPotionItem() {
ItemStack item = new ItemStack(Material.SPLASH_POTION, 1);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName("Potion");
PotionMeta.addCustomEffect(new PotionEffect(PotionEffectType.HEAL, 100, 1), true);
item.setItemMeta(meta);
return item;
}
uhh lemme try check
It's because you are not casting it, you're just calling it wrong
You're missing this entire step ^
oh now i see π
i dont at all
you didnt define potionmeta
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
add this
Like this
private ItemStack createPotionItem() {
ItemStack item = new ItemStack(Material.SPLASH_POTION, 1);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName("Potion");
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
potionMeta.addCustomEffect(new PotionEffect(PotionEffectType.HEAL, 100, 1), true);
item.setItemMeta(meta);
return item;
}
nonono i fixed now
you're making extra steps there, no?
by creating two different instances of meta
yeah i just copied and pasted
ah
Yes the potionmeta won't be put in the imtestack like ths
It doesn't really matter, it's just a cast, it's not creating any new instance
Oh yeah didn't see
another problem
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
well new instance is not the right wording
item.getItemMeta
new variable is more specifically
cannot find symbol
for me it works
?
does this show an error?
private ItemStack createPotionItem() {
ItemStack item = new ItemStack(Material.SPLASH_POTION, 1);
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
potionMeta.setDisplayName("Potion");
potionMeta.addCustomEffect(new PotionEffect(PotionEffectType.HEAL, 100, 1), true);
item.setItemMeta(potionMeta);
return item;
}
lemme see
it does work but im not talking about the item stack
i put PotionMeta potionMeta = (PotionMeta) item.getItemMeta(); in public class outside of the gui stuff'
i dont get what you mean there
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
item is underlined
im using
private ItemStack createPotionItem() {
ItemStack item = new ItemStack(Material.SPLASH_POTION, 1);
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
potionMeta.setDisplayName("Potion");
potionMeta.addCustomEffect(new PotionEffect(PotionEffectType.HEAL, 100, 1), true);
item.setItemMeta(potionMeta);
return item;
}
what does it say when you hover
Cannot resolve symbol 'item'
cannot find symbol in the run console log thingy thing
what the hell
I can see anything wrong with this right away, is hookVault called on enable? Do you have vault as a depend on your plugin.yml?
Yes, it is called on the onenable and in the plugin.yml it is softdepend: [ Vault ]
i feel like it has something to do with the complier
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /C:/Users/Delta/IdeaProjects/DefuseKitCore/src/main/java/defusekitcore/defusekitcore/DefuseKitCore.java:[26,42] cannot find symbol
symbol: variable item
location: class defusekitcore.defusekitcore.DefuseKitCore
[INFO] 1 error
[INFO] -------------------------------------------------------------```
maven moment
ahahahaha
intellij
maven
i run
the thing
idk im a newbie i have no idea how this all works i'm learning java
they run the thing
how do you get the bukkit api
with a jar or with maven in the pom.xml
put the whole class here
Well if it works on other places that isn't a compilation or dependency problem
Can you show exactly where the error is? A screenshot or something
And yes you can't send images yet, but you can put it on imgur or something
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
where can i paste my code into
who do you mean here? him or me
Him
oh ok
Still trying to think why yours doesn't work
i am recoding my plugin. i did the same thing with the 1.8 version and there it works. here is spigot 1.18.2 and it does not hook...
Only thing I can think of is that your plugin might be enabling before vault does, but if it's dependent it shouldn't happen
There is your issue, for what ever reason you're throwing the item meta code outside of the method?
Why?
wdym
wait
dont i already have that in the
private ItemStack createPotionItem() {
OH
wow i just realized
bruuhuhhh
do it on the method
and use this for the potion:
private ItemStack getPotionItem(PotionEffectType type, String name) {
ItemStack item = new ItemStack(Material.SPLASH_POTION, 1);
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
potionMeta.setDisplayName(name);
potionMeta.addCustomEffect(new PotionEffect(type, 100, 1), true);
item.setItemMeta(potionMeta);
return item;
}
this here you can define the potion while you call the methond in your inventory setter
i use that already im p sure
i fixed it now
it works
gonna go get a minehut server to test cause i dont wanna test it on my actual mc serv
just create a local serer
you can test the plugin everytime you compile it
just compile, copy, reload server
Iβm working on a duels minigame and It requires for me to generate a copy of the original duels map and then tp players to it and delete the world when the game finishes. What is the efficient way to regenerate worlds and load them without it impacting serverβs performance
Yes
Slimeworldmanager
public void hookVault() {
getServer().getPluginManager().registerEvents(this, this);
}
@EventHandler
public void onServiceRegister(ServiceRegisterEvent event) {
if(!config.isVaultEnabled()) {
return;
}
Plugin vault = this.getServer().getPluginManager().getPlugin("Vault");
if (vault == null) {
return;
}
if(event.getProvider().getService().equals(Chat.class)) {
chatSystem = getServer().getServicesManager().getRegistration(Chat.class).getProvider();
System.out.println("[KnockbackFFA] VaultHook: Hooked with chat system");
}
if(event.getProvider().getService().equals(Economy.class)) {
economySystem = getServer().getServicesManager().getRegistration(Economy.class).getProvider();
System.out.println("[KnockbackFFA] VaultHook: Hooked with economy system");
}
}```
i have dont it like this now, and the event does not even call ...
the hookVault Method is called in the enable, so this is not the issue. but the event does not get triggered. vault is enabled in the config too
Did you register the event?
yeah, in the method above
Does it work on 1.18.2?
Yes
i would probably use java.nio.file.Files
import that and make it work
is there any plugin to list all registered service providers of vault?
the thing is would cloning be like creating a new world and then somehow getting the like region files into it or just cloning it via like completley copy pasting it
Swm is mega fast btw
Alright ill try it
when i run this:
System.out.println(getServer().getServicesManager().getKnownServices());
System.out.println(getServer().getServicesManager().getRegistration(net.milkbowl.vault.chat.Chat.class));
System.out.println(getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class));
It puts out this:
[15:04:25] [Server thread/INFO]: [class net.milkbowl.vault.metrics.bukkit.Metrics, class net.milkbowl.vault.chat.Chat, interface net.milkbowl.vault.economy.Economy, class ru.tehkode.permissions.PermissionManager, class net.milkbowl.vault.permission.Permission]
[15:04:25] [Server thread/INFO]: null
[15:04:25] [Server thread/INFO]: null
@pulsar ferry Do you have an idea?
It looks like the getRegistration method is returning null for both the Chat and Economy classes. This suggests that there is no registered service for these classes, which means that Vault is unable to find a plugin that provides chat or economy functionality.
There are a few possible reasons for this:
The required plugin (e.g. a chat plugin or an economy plugin) is not installed on the server.
The required plugin is installed, but it is not properly registered with Vault.
The required plugin is installed and registered with Vault, but there is a conflict with another plugin that is preventing Vault from accessing the service.
To troubleshoot this issue, you can try the following:
Check that the required plugin is installed and enabled on the server.
Check the server logs for any error messages that might indicate a problem with the required plugin or with Vault.
Check that the required plugin is properly registered with Vault by running the /vault:debug command (if available) or by checking the plugin's documentation.
If you are using multiple plugins that provide similar functionality (e.g. multiple chat plugins or multiple economy plugins), try disabling or uninstalling one of them to see if it resolves the issue.
I hope this helps! Let me know if you have any questions.
I have a domain redirect on cloudflare but it stops working shortly after setting it up.
did you put the code in the ChatGPT? π
i tried all steps there except vault:debug, it does not exist
xD
is that chatgpt
oh yeah is chatgpt even allowed here
im using it rn for the kit editor plugin im making lmao
Is there another way of doing it
why is everything in the main class
why did you have a subclass in the main class that should more then likely be in another class
also all your methods for your Kit class are static which they shouldnt be
all your variables are static aswell
yeah cause im trying to solve a problem
also on lines 129-132 your doing Kit.method instead of kit.method
bro don't bully me lmao i'm new to java
im not bullying you im telling you whats wrong
broboro ik
i'm not very experienced with java
this is literally my second plugin
and im already trying to do more advanced stuff
you mean your not very experienced with OOP
mhm
Move everything in the Kit subclass to its own class
remove static from all of the variables and methods in that class
you mean make a new .java file right
cause you can only have 1 class per file if im correct or smth
move your onInventoryClick method to another class named something like PlayerEvents
thats kinda correct
you can only have one class per class file but you can have a subclass inside of the class like you have done with this class
ik what u mean
tho the practice isnt to fill 1 class with every piece of logic
for the entire project
usually its better to seperate stuff into smaller pieces
move your OnCommand method to its own class
also when it comes to inventories its better to identify the class by its inventoryholder
so far i've only had 6 more errors come lol
then its title
ever since now i've made kit class
ok i have 5 errors now narrowed it down
from 9
i would personally make a class for the inventory related stuff aswell
also on line 109 instead of doing if (!sender.isOp()) do if (!sender.hasPermission("your.permission.here"))
74 kit.setItems(Player.getInventory().getContents());
75 kit.setArmor(Player.getInventory().getArmorContents());
76 kit.setPotionEffects(Player.getActivePotionEffects());
94 Kit kit = Kit.load(kitName);
these get errors,
and the errors are in the imgur file
again, your using Player instead of player
also your load method should be outside of the kit class
because what you would probably do is load all the data. then create the kit object
now it says "Cannot resolve symbol 'player'
you havent defined player as a variable
and how do i do that...?
Player player = (Player) sender;
also id suggest you make multiple command classes for each commmand
ah it fixed lol
means you wouldnt have to do if (cmd.getName().equals("kiteditor")) {
i'd rather do it the way it is rn
don't ask me why just yse
yes*
anyways now it says "Cannot resolve symbol 'sender'
i likely have to also define it
well so basically i've put it in the wrong place right
yeah
fixed it now
just 1 hour left
what
myy brain hurts from all this OOP wtf
1 error left
lemme guess, the kit.load
private Kit loadKit(kitname) {
//your load kit code here
}
dont have your load code in the kit class
because to load the kit you have to instance the Kit class and to instance the Kit class you need to have the information and to get the information you have to load the kit
which you can only do if you have already instanced the class
its a catch 22
heres kit.java
heres the other one
https://paste.helpch.at/qobopofaqa.java
kit.java has 3 errors and the other one has 2
another suggestion is to load all kits at once on plugin load, put all the kit objects in a hashmap with their name as the identifier
ofcourse the id should be all lowercase or all uppercase
i dont even have any kit system yet lol
when tf was it static
@proud pebble can we go to dms cause i have to upload a imgur ss like every second
bro i aint running it every second to compile it im using this
oh right i have to
brouh
you cant copy paste from that
you can click it
it then gives you a list of errors
then just right click the eror
copy problem description
done
BRUH
'Kit()' cannot be applied to '(java.lang.String)'
Cannot resolve method 'load' in 'Kit'
Non-static method 'delete(java.lang.String)' cannot be referenced from a static context
Non-static field 'items' cannot be referenced from a static context
Non-static field 'armor' cannot be referenced from a static context
Non-static field 'potionEffects' cannot be referenced from a static context
Kit has no constructor
public Kit(String name, ItemStack[] items, ItemStack[] armor, Collection<PotionEffect> potionEffects) {
this.name = name;
this.items = items;
this.armor = armor;
this.potionEffects = potionEffects;
}
im assuming somewhere its doing Kit.delete instead of kit.delete
your doing Kit.items instead of kit.getItems()
same with the other 2
also the delete method could be moved from the kit class to your main class since then you can delete the kit from file and from the kit hashmap at the same time
since loading from file is more expensive and slower every time you want to query the kit then to load them all at once and store them in ram
alr
ive fixed the defusekitcore.java but not the kit.java yet
Non-static field 'items' cannot be referenced from a static context
Non-static field 'armor' cannot be referenced from a static context
Non-static field 'potionEffects' cannot be referenced from a static context
so far
fixed everything
good
Hey guys! π
Can somebody help me out, we're struggling 
My friends and I just want to chill on our own SMP with some plugins.
We found a plugin without a jar file but with the open source.
Can somebody help us create a jar file from github source, none of us have any idea how to do it.. π
U can @ me here or dm me!
Thanks a lot in advance!
send the github link
Thats not 1.19 tho :/

Does anyone know how to listen to when someone equips/unequips armor?
Gotta check a few events such as InventoryClickEvent, PlayerInteractEvent etc.. and check if the item is placed into the armor slots.
If someone could help me understand config better (if there's a link to a doc that'd also be helpful) cause i'm confused on what's wrong with this code which is supposed to check if someone typed in "h2" into the config
Bukkit.getLogger().info(plugin + "Starting Database Connection..."); if (config.getString("Database") == "H2") { Bukkit.getLogger().info(plugin + "H2 Databse Selected"); }
use .equals to compare strings
Hey everyone! I am trying to run some code in a while loop every x minutes (where x is a random number between 10 and 20 minutes).
this is my code:
while (running) {
randomTicks = Min + (int) (Math.random() * ((Max - Min) + 1));
Bukkit.getScheduler().runTaskLater(Main.getInstance(), () -> swapPlayers(), randomTicks);
}
i know this is as wrong as it could be because i put a bukkit scheduler inside a while but its just to show what i am doing. i'd appreciate any help! thanks
You could get rid of the while loop by moving the re-schedule logic into the swapPlayers method, just make the swapPlayers method re-schedule itself using your current logic
runtasktimer every minute, so 20*60L
create a task variable inside of the timer
runtasklater, check if the task is either null or cancelled, if true then use Rand.int or whatever and have it pick a number between 10-20 and then create a runtasklater that does whatever code you want it to do
runTaskTimer(plugin,() -> {
BukkitTask task = null;
if (task == null || task.isCancelled()) {
int yourrandommethod = 10-20;
task = runTaskLater(plugin, ()->{
//your run code
},yourrandommethod * 60 * 20);
}
})
something like that
or store the task somewhere else that isnt inside the task but i dont think it matters
Hey guys, I currently have this piece of GUI code: https://pastebin.com/3M9Qq66H, but I need to make it paginated since I want to add more items but due to the items not fitting into to gui it gives an error, so need to make it paginated but I have no idea how, new asf to java but need to edit this plugin since I need it for my server\
what ive done is had the inventoryholder have a page variable
then on clicking the button to move to next page increase that value by one and then adding an offset of the inv area size * page
so if the total slots it could take up
Mmh, is there like any resource online talking about this which examples? since my java knowledge is basicly close to 0, I don't know why I'm even doing this myself-
https://github.com/lunaiskey/LunixDev/blob/master/src/main/java/me/lunaiskey/lunixdev/lunixshop/ShopGUI.java
look at my onClick method
also the for loop should end at either the inventory's size in this case 54 or the last slot that an item can be placed
in my case i do everything through the same for loop
probably look line 114 to 149
Yeah, that makes no sense to me XD
basically i have a go back button in slot 0, a next page button in slot 8, if i click either of them they get the page number and either -1 if go back and +1 if its the next page, then it updates all the items in the inventory to be what the next page would be
lets say you have a list of 10 items, you only showed 7 of them per page, you would then go through 0-6 on page 1 and then on page 2 you go through 7-10 then stop since you have gone through the entire list
so the offset would be maxItemPerPage * (currentPage-1)
so if your on page 1, it would be 7*(1-1), so 7 would be the max place in the list
wait.. i think that math was off
oh i see what i did wrong
it would be 0
so the for loop would actually be
for (int i = offset,i<(maxItemPerPage+offset);i++)
then do if (i >= filterableItems.length) break;
probably very complicated for no reason idk
theres probably a very simple tdlr that could exist
wait whats the question
π₯²
for (int i = offset; i < Math.min(maxItemPerPage + offset, filterableItems.length); i++)
```?
they want to make their gui be paginated
use
mf-gui

Hello everyone, please tell me what could be the problem?
`[13:31:42 WARN]: [DeluxeMenus] Plugin DeluxeMenus v1.13.5-Release generated an exception while executing task 10584
java.lang.NullPointerException: Cannot invoke "com.gamingmesh.jobs.container.Job.getDisplayName()" because the return value of "com.gamingmesh.jobs.Jobs.getNoneJob()" is null
at com.gamingmesh.jobs.Placeholders.Placeholder.getValue(Placeholder.java:478) ~[Jobs5.1.1.1.jar:?]
at com.gamingmesh.jobs.Placeholders.Placeholder.getValue(Placeholder.java:379) ~[Jobs5.1.1.1.jar:?]
at com.gamingmesh.jobs.Placeholders.PlaceholderAPIHook.onPlaceholderRequest(PlaceholderAPIHook.java:21) ~[Jobs5.1.1.1.jar:?]
at me.clip.placeholderapi.PlaceholderHook.onRequest(PlaceholderHook.java:32) ~[PlaceholderAPI-2.11.1.jar:?]
at me.clip.placeholderapi.replacer.CharsReplacer.apply(CharsReplacer.java:161) ~[PlaceholderAPI-2.11.1.jar:?]
at me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(PlaceholderAPI.java:70) ~[PlaceholderAPI-2.11.1.jar:?]
at com.extendedclip.deluxemenus.menu.MenuHolder.setPlaceholders(MenuHolder.java:95) ~[DeluxeMenus-1.13.5-Release.jar:?]
at com.extendedclip.deluxemenus.menu.MenuItem.getItemStack(MenuItem.java:677) ~[DeluxeMenus-1.13.5-Release.jar:?]
at com.extendedclip.deluxemenus.menu.Menu.lambda$openMenu$5(Menu.java:388) ~[DeluxeMenus-1.13.5-Release.jar:?]
at org.bukkit.craftbukkit.v1_19_R1.scheduler.CraftTask.run(CraftTask.java:101) ~[purpur-1.19.2.jar:git-Purpur-1796]
at org.bukkit.craftbukkit.v1_19_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:57) ~[purpur-1.19.2.jar:git-Purpur-1796]
at com.destroystokyo.paper.ServerSchedulerReportingWrapper.run(ServerSchedulerReportingWrapper.java:22) ~[purpur-1.19.2.jar:?]
Hey I'm looking to open a ecloud account who do I speak to about this?
@robust crow@jade locust
Have you got an expansion ready?
Yes
Mind linking me to the github?
Anyone can help me with opengl ? (stencil)
Does PlayerMoveEvent triggers when a player is swimming?
yes
NBT.modify(item, nbt -> {
nbt.setBoolean("Mission", true);
nbt.setString("MissionId", id);
nbt.setEnum("MissionType", type);
nbt.setInteger("MissionMax", max);
nbt.setInteger("MissionCurrent", 0);
});
}```
Why does this not set the nbt data for the item
What library are you using?
NBTAPI
What MC version?
1.18.2
Why not use persistent data containers?
But whats the problem with this method
alright then let me try using persistent data container
Does anyone know of a way with Configurate to make this work?
final List<AnimateEntityData<?>> blockData = node.node(BLOCK_DATA_FIELD).getList(AnimateEntityData.class);
I need to have the list have <?> because it is used for the object being deserialized
Well I guess this works but it's annoying lol
final List<AnimateEntityData<?>> blockDataList = new ArrayList<>();
for (final AnimateEntityData<?> animateEntityData : blockData) {
blockDataList.add(animateEntityData);
}
Any update?
1.19.3 is the latest I think
Ah, didn't see ur link originally. Dm me a username and email and I'll create the account
ngl why not just use nms to modify the nbt of the item?
harder to make multi version support
no need to reinvent the wheel π
but if they dont care about multi version support and NBTAPI isnt functioning correctly or whatever then why not just use nms
because nbtapi has documentation
also in this specific case, PDC works best anyways
and if they aren't using paper api and/or a later version, it is more difficult to use nms since you have to run buildtools and there's no spigot remapping plugin for gradle
then if you want to make it open source, everyone who wants to build the plugin has to have those installed too
then ig diagnose the issue with the itemstack not getting modified
yes but in this specific case, PDC is the best choice
since it's supported by spigot
hi it me srnyx again and srnyx needs help
soooooooo im using testImplementation but its not adding the classpaths to the test JAR, what am i doing wrong?!?!?
test jar?
gradlew test π
no my test jar is a plugin
or
classic start server testing π
its an api and the test jar uses the api
yes and? use mockbukkit
I didn't even know it was possible to generate a test jar
L noob
ok even if i use mockbukkit there is still issue
im also generating a javadocs jar file, and by using gradle shadowJar, it doesnt generate the javadocs file
hopefully uve alrdy figured it out, but run the javadocJar task
also dont use mockbukkit
Ye I probs wonβt cause Iβd rather be able to run it on an actual server environment
But how can I do it when I run gradle shadowJar? Id prefer to not run 3 commands every time I build (cause itβs also not generating test jar)
does the test plugin actually contain automated tests? or is it just so you can try out the api in game?
2011 β οΈ
mockbukkit is fine from my experience
Did u even read it?
SOLID is from like the 2000s, does that mean its irrelevant?
Feels like the problems this article talks about are when you mock on the integration layer
Whichβ¦ well, if youβre doing integration tests, maybe use sth like https://github.com/MiniDigger/MiniTestFramework
Looks nice
No it doesnt
I think acceptance tests are more suitable here because setting up integration tests with bukkit is probably a pain
And it makes more sense to test behaviour as a client rather than the server
What type of acceptance tests are you referring to now more concretely?
Idk, I mean integration tests can be valuable even though you consider them painful to write and setup, same with unit tests, and yeah I would avoid mock bukkit if possible, but Iβve found it to be one of the better tools to unit test bukkit with.
Or well, paper more specifically since bukkit/spigot is a bit β¦ myes
even if u did get through the pain of setting them up, you would still have a tough time asserting the expected behaviour
How so?
how do you test if you've sent a message to a player with Player.sendMessage?
thats exactly why it would be better to do the tests as a client
With MockBukkit?
What do you want to test? That the message got sent to x player, and x receives it?
yes
Well, for unit tests, you really wanna avoid depending in external stuff such as remote DBs, thatβs why you sometimes mock stuff, as to presuppose βassuming this works with said expectations, will this unit work also?β
i just said its an integration test?
was that not in response to my question lol
Well, what exactly are you testing? When you ask this question? That the player receives the message? That the sendMessage was invoked successfully? If you want to test the entirety sure, you can lift the tests up to a higher layer. If it is an integration test between your plugin and spigot api on that level, stubbing is probably fine, or spying for sendMessage. Really depends on what youβre testing.
that the player receives the message
if you stub it you wouldn't be testing the integration
Thatβs much more though, you end up having to test in principle the entire system, and the client.
There are a lot of factors that depend on whether the player at the end would receive the message
thats the whole point
if the client was broken and couldnt receive the message, wouldn't you want your tests to fail?
But that isnβt what youβre testing if youβre doing an integration test between letβs say your plugin and spigot api. Youβd just test whether the your plugin invoked sendMessage (and possibly that the interacting module handles it non erroneously) and since we donβt really own the type Player, we on the service layer could for instance eliminate the arbitrary randomness as in the terms of presupposing certain behavior works the way it should thus mocking spigot could make sense. And btw sendMessage is a terrible example. No?
What's going on hereee
but thats not an integration test
an integration test would use a real player
and "setting up integration tests with bukkit is probably a pain" so thats why i suggested acceptance tests instead
No not necessarily but most likely, again depends on what youβre testing
we're talk abt mock bukkit and mocking external types lol
Noice
Yes it isnβt really an integration test whatβve described above, but youβre often not interested in integration tests between your module and some other external module namely spigot api
Personally I think hamburgers and cheeseburgers fit very well with fries.
Because well, you did not write spigot api did you?
cant remember if i did
But the spigot API sucks ass tho
^^^^
Same with all due honesty
lmao
Concur
Its asif someone put the milk in before the cereal. That's how I would describe it.
yeah, things like ItemStack and concrete classes can be tested with an integration test, but most things can't
can someone explain sponge to me lol
cuz apparently its like a server-side plugin api thats good yet no one uses it
porous elastic material with a strong affinity for water
sponge is used much more in the modded server scene
Think the dev team is pretty small, and since its all written from scratch it takes more time
or isnt used
just ecosystem and popularity
is it missing a bunch of features or smth?
sponge vanilla isn't also a direct replacement for something like paper
Perhaps, I donβt know tbh, but would assume that may be the case additionally
I bet it isn't
bruh
it's just todo with popularity
and ecosystem
more paper plugins
paper more popular
more guides for paper
no need to switch to sponge
Paper better than spigot 100x over.
Cool thing about sponge is mixins tho, very nice sometimes
heres my epic solution to bad spigot api:
keep spigot/paper api
allow a second api thats good and is just a wrapper around the original spigot/paper api
and,
- deprecate spigot api
- yeet spigot api
= paper
sponge api is generally considered to be better
sponge api also breaks though every major update
no backwards compat like spigot
how bad are the breaking changes for sponge?
is it like they remove some zombie methods when they cut off its legs in 1.18 or do they like remove some random plugin method for no reason except because they can and its alrdy a major release
or not sure
they see areas of improvement, and improve
it's as simple as that
that may involve removing, rewriting
thats kinda annoying
i feel like plugins should be backwards compatible
mainly cuz theres gonna be multiple plugins on 1 server that all depend on the same api
Oh btw https://docs.spongepowered.org/stable/en/about/introduction.html that should maybe clarify the goals etc
check #placeholder-api
Wow, you are highly impatient... Maybe learn to have some patience if you're wanting someone to actually help you.
And stop pinging staff members.
Gave him a little bit of support but i agree with you.
Itβs just so I can try it out ingame
Yes and MockBukkit checks the flags that article says are okay with mocking types that aren't yours
The important thing is to verify that our calls to the fake are compatible with the real classes, and where possible check that the behaviour matches what we expect. Martin Fowler calls these Integration Contract Tests. The idea is that if we pass a certain range of values to our fake, the real version should also be able to handle these values. If we assume the real version behaves in a certain way and replicate that in our fake, we can write a test to try and verify that assumption.
MockBukkit isn't just quasi-arbitrary code-gen interface implementation like mockito (which is what this article is very clearly talking about, mock types without valid parametrisation), it's a very specific Bukkit implementation to be used in unit tests that works just as the API intends the server to
hey guys, anyone know how to make javascript placeholders for StaffPlus
(( Example: ))
can anyone help me with this please trying to get a command isued via console insted of it beaing isued via the player https://paste.helpch.at/akohilelev.yaml
also from looking at it all of them do get ran by the console
but it isnt isuing the cmmd tho
in the console when the button is pressed does it say unknown command or something like that?
nothing shows up in console
Is there a way to create a website that uses node.js libraries without having to use a framework like react?
I need to add some functionalities to a plain html website and I have to use a node.js library for that, more exactly to save some data to a excel file
Can you compile it to plain js?
compile what? π¬
Actually I sorted this out by sending the data to an endpoint from the express app, all good
Oh were you talking about backend?
That's in the What about when I just canβt use the real type? section. As the article says in the previous section, you should use acceptance tests.
As an alternative (or ideally complimentary) approach, we can use acceptance tests to make sure the entire feature works as expected (i.e. not just covering the call over the integration boundary, but exercising as much of the real feature as possible). Again, weβre checking behaviour, not implementation specifics for types where we donβt have a constant, transparent view into those implementations.
He also says to write integration contract tests because otherwise you wouldn't know if the fake implementation (in this case mockbukkit) is a good representation of the real implementation.
The important thing is to verify that our calls to the fake are compatible with the real classes, and where possible check that the behaviour matches what we expect. Martin Fowler calls these Integration Contract Tests.
MockBukkit isn't just quasi-arbitrary code-gen interface implementation like mockito (which is what this article is very clearly talking about, mock types without valid parametrisation), it's a very specific Bukkit implementation to be used in unit tests that works just as the API intends the server to
It's barely a real implementation. It calls a few events, but it mostly just provides ways to verify method calls in a type-safe. For it to be any more valuable than mockito you would have to write several integration contract tests which would mostly fail because of how bare of an implementation of the bukkit api MockBukkit is. Even if you did write all those integration contract tests, you still can't be certain that those tests are even good since there are no code coverage metrics.
okay
the article also says it's a guideline, not a rule, it is not the holy grail
so it is fine to do at times
no ones forcing you to, but the tests won't be that valuable
In that case ignore all the mockbukkit talk lol
if I need to test a little bit of something that a unit test fits perfectly, then that is valuable enough to me to rely on the integrity of the bit i'm testing
also i don't care
good 30 minutes spent writing that
you spent a good couple of mins reading the article so
yes, and it was worth it
