#help-development
1 messages · Page 2142 of 1
where inner static classes seems to be a way to solve some problems
imajin having a stroke
?paste
I mean its nice for iterators etc
why do I hate this code so much
it just looks weird
thats all
but sometimes inner classes are a good way to encapsulate some parts of the code
which you wouldnt want to expose
public static Nameable CHEST_9X1 = Nameable.CHEST_9X1;
public static Nameable CHEST_9X2 = Nameable.CHEST_9X2;
public static Nameable CHEST_9X3 = Nameable.CHEST_9X3;
public static Nameable CHEST_9X4 = Nameable.CHEST_9X4;
public static Nameable CHEST_9X5 = Nameable.CHEST_9X5;
public static Nameable CHEST_9X6 = Nameable.CHEST_9X6;
someone should make a lombok generator for stuff like this
@Wrapper
we can tell
Why no final
^
I mean you can just write with lombok and call delombok whenever you start to lose touch with reality
thank you
Why does Player.Spigot.sendMessage say that the symbol of sendMessage isn't found?
probably because it cant be found
well yes but shouldn't it be found?
https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/Player.Spigot.html Cause this says it should
are you providing a basecomponent?
Player#spigot().sendMessage
or a vararg basecomponent
you might be calling the static class
or a chatmessagetype and basecomponent
or a chestmessagetype and a vararg basecomponent
Lowercase doesn't showup
sendMessage() is a method not a field, if you wrote it like that, ofc it wouldnt work. Just saying
I mean like
= instance call
Player player = ...;
player.spigot().sendMessage
thats not how it works dude
yes i know i need to provide fields to send message but send message doesn't exist
ah
notice the hashtag meaning an instance call
spigot() method is not necessary here, public inner class exposed to that (nvm)
I know that, but are there any other benefits? I always make them static, but why can you make them non static
I have like one occasion where I "need" non static
I'm just trying to figure out how to do an action bar :P
yes
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(message));
seems not to not work for me, my yml is still empty
Thanks. I was sure i tried that earlier but i must have made a typo
i haven't used non static class that much myself, so i can't really tell you why, as I said previously i think that feature exists for you to provide outer class private fields to the inner class, without using the getters of the outer class
Yeah, that is the only reason I make them non-static
do i do config.save(new File(path))
get your plugin instance and call saveConfig
path
Use a config manager ;)
public class Foo {
private final id;
public Foo(int id) {
this.id = id;
}
class Bar {
private final int barId;
public Bar() {
this.barId = Foo.this.id;
}
}
}
this should be legal
afaik
even if the field of outer class is private
you could still access it via inner class
You don't need Foo.this.id, or do you?
I mean thats not the point of it
Am i dum
you're supposed to access the outer class field directly
that's an example
thats the benefit
I mean, you only need id
that is what I was trying to portray
When I have a String str = ChatColor.BLUE + "something";
That's an EXAMPLE. This is not real code
i'm not going to implement
how can i remove ChatColor.BLUE
Windows 11 just for an explanation
just by str
Yeah I get it, it was a badly formulated question
Day 158. I still have a fobia for Object @NotNull []
lmao
public static Object @NotNull myArray[];
when i dont now what that "something" is
oh my... this is unholy
ew
:)
(:
i wonder if this is possible to do with C style notation
die
fun
Object foo[]; <- this is still legal in java
even better
I hope future java versions will steal the idea of operator overloading from C++
there's nothing as confusing as operator overloading ngl
but can also be nice
altho its not in javas style to add that type of shortcut for the given verbosity itd substitute
public static void dA(Test. @NotNull Test2<@Nullable Test.Test3>.NonNls[] @NotNull bC) {
return;
}
hmm
Nms be like
bet your decompiler has a stroke upon seeing that
When I have a String str = ChatColor.BLUE + "something";
how can i remove ChatColor.BLUE
when i dont know "something"
Hey hey,
Is there a way to get the itemstack that's being popped out of the itemframe?
Seem as though the one you can get with EntityDamageEvent#getEntity#getItem is a different one?
Since itemframe items are entities
you can try using this
declaration: package: org.bukkit.event.entity, class: ItemSpawnEvent
yeah probably
I don't think those fire since you are not breaking the item frame, just popping the item out
Just gonna cancel the event and spawn in my own item, ty for the help
native has always been available pretty much
think its probably always been there tbh and i just didnt notice
yea
dont really see how it could be used for anything though without major java compiler hacks
jni
i am not smart enough to use that
listeners do get disabled if the plugin gets disabled automatically, right?
There is nothing smart about that. All you do is compile some dlls and call functions from java.
If you know some C(++) then this is not exactly black magic. But since JIT is a thing i dont really see
a benefit. Maybe for AI applications or CUDA stuff.
myes
iirc thats the implementation
what do you need to call explicitly when disabling from the API
except for the shutdown plugin things
not much
I mean
if that is what you mean
strong references to other plugins should be dropped
thats bout it
and yeah I mean external io connections and streams should be closed probably
ig also services such as ExecutorService instances might deserve to be properly terminated
Why is the BlockBreakEvent e.getDrops not exactly the number of items when I break the block with Fortune3? Can I query it to see how much is really dropping?
try event.getBlock().getDrops(event.getPlayer().getItemInHand());
Ok, i try
Look into the BlockDropItemEvent
Will that work for an air item stack? Aka return an empty collection?
probably, or use blockdropitemevent like smile said
Yes. It will return exactly the items that would be obtained.
Ohhh, exciting
I need that
I still wonder
why the returned list of drops is only partly mutable
like, you can remove items, but you can't add any
it seems a bit weird to me
anyone know what is going wrong here? it isnt a crash but it is annoying
https://cdn.discordapp.com/attachments/704402403470082199/974817199082598400/latest.log
?paste
Whatever your chunk generator is is not doing a great job
i tried hastebin, there is too much text
core.jar//com.cmdpro.servercore.PlantPopulator.populate(PlantPopulator.java:30) is what's in the trace
hm
core.jar//com.cmdpro.servercore.PlantPopulator.populate fks up your chunk loading
ill send you the code in there
Actually seems to be a few different places in your populators. TreePopulator as well
it seems like it just places so many trees on the main thread it times out
And plants, yeah, that's most likely the case
Im suspecting that the generator calls for the chunk so generation is triggered in a recursive loop.
Or it just takes way too long
Already right off the bat, for (int i = 0; i < random.nextInt(50, 256); i++) {
You're going to want to generate that number once
Remember that that condition is checked and evaluated every iteration
It would run 256 times at most
You should not base your generation on a single chunk. Rather use some noise algo like OpenSimple to create
a double[][]. Then generate a tree if a field has a certain value (>0.9 for example)
After that you should play around with the frequency and amplitude to get thin high amps for single trees.
I'd +1 that, yeah. I was about to suggest something a bit more mathematical
For convenience by the way, there is World#getHighestBlockAt() and #getHighestBlockYAt(). No need to loop it yourself. You can make use of height maps to ignore water or leaves
There's actually one specifically for world generation, https://helpch.at/docs/1.16.2/org/bukkit/HeightMap.html#WORLD_SURFACE_WG
Spigot does have noise generators by the way
Perlin and Simplex
noise
I only know that term "octave" from music etc
how do i get all the args that the player entered for the command
just use the args array?
no i mean i want to take how long does players' message's length
args.length?
i know that shit wtf
I think they want to do String.join(" ",args).length
i cant explain myself
(command.getName() + " " + String.join(" ", args)).length
it joins the provided list together
well String.join does this:
args[0] = "my";
args[1] = "name";
String result = String.join(" ", args); // It's now "my name";
with the string provided seperating
Where do you need it? Because there are some events that could be helpful
actually i want to make a message system when player enters arguments i want to calculate how long is that argument is
if you're just trying to add a character limit on commands CommandPreprocessEvent
then, as everyone already told you, use String.join on the args array and use " " for joining
String#length()?
A message has no arguments
do you mean in a command or like a player talking in chat
String.join(" ", args).length
they probably have a command like "/msg asd asd asd asd asda sdasdadasdsd"
its that simple
commands
yes
then you have had your answer 5x over
Ah that makes sense
i didnt know String.join existed for a while and for the longest time i was manually stringing arguments together ;-;
F
it exists since Java 1.0 IIRC lol
new approach:
int size = String.join(" ", args).length
idk why i never thought to check for a method like that
Never seen before
yep JDK1.0
life got so much easier after i found it
so this shows what
arg length?
the length of all args combined by a space
bruh sorry but, can you read?
Here are some links to get you started on learning Java:
- https://www.codecademy.com/learn/learn-java
- https://www.sololearn.com/learning/1068
- https://www.learnjavaonline.org/
- https://programmingbydoing.com/
- https://docs.oracle.com/javase/tutorial/java/index.html
The last one is the only official one, however some of those concepts assume that you already know a bit about programming.
?
meanwhile if you're learning unity you have to unlearn programming and get ready to commit some programming war crimes
war crimes are fun
I wonder if we can make a sound-based world generator
for example, this prints "15":
public static void main(String[] args) {
String[] message = new String[] {"my","name","is","jeff"};
System.out.println(String.join(" ",message).length());
}
Input: /msg some arguments in msg
args: ["some", "arguments", "in", "msg"]
After join: "some arguments in msg"
It has been explained several times now
as long as you are the one doing them
String[] test = new String[]{"this", "is", "a", "test"};
String.join(" ", test) ----> "this is a test"
because that's the length of "my name is jeff"
not when you're committing them against your future self
we all made an example at the same time lol
where we scream at a mic and the louder we scream, the taller the mountains become
and background noise makes trees or something
and if we say wowowowowowo we can end up with some very funky terrain 🤔
please let me know if you are moving anywhere so I make sure I am always at least three cities over from you
okay you dont need to be moody
noone is being "moody"
You can directly feed the amplitudes and frequency into some noise algo
yeah that's where I was going off of
didnt mean you
and then the same noise will always make the same world
"noone"
and then we make NFTs out of screams
fuck NFTs
i am mooding right now
the only terrain generator that might get a dmca takedown notice
wait what
or maybe grab an image and convert pixel data to noise somehow
I wonder what an FBI-warning generated world would be
you are slowly recreating perlin noise
yeah except instead of using just funky numbers we can use memes
what if we grab every frame on the shrek movie and convert it to noise, feed that all into an algorithm and end up with a great world
And layer despacito on top of it
yes
the audio makes the ores, the video makes the terrain itself
if it's hella loud, there will be more ores
this idea is as worthless as it would be likely to get 3 million views on youtube if you made a video about making it
rather use this song I made out of a friend's cough https://soundcloud.com/le-crochet/schoko-hustet
Hängst du schon am Haken? Knusprig Paniert und JEFF & Jefferson ergeben zusammen: Le Crochet!
Le crochet reminds me of Fish au chocolat
probably
"Le Crochet" is french for "the hook" iirc
and maybe start a trend off of meme worlds
and get famos
either that or I'm extremely sleep deprived
I tried to remove arg[0] with for loop but its colliding
how can i remove arg[0] without any exception
you cannot just "remove" elements from an array
You have to create a new array to "remove" the first element
You can set them to null, or shorten the array
I use this to do it:
public static <T> T[] shiftArray(T[] original) {
if(original.length == 0) return original;
T[] shifted = (T[]) Array.newInstance(original.getClass().getComponentType(),original.length-1);
if(shifted.length == 0) return shifted;
System.arraycopy(original, 1, shifted, 0, shifted.length);
return shifted;
}
obviously you can replace "T" with "String" if you only need it for strings
you replied to the wrong message and I got extremely confused
That does seem like a fairly simple method hmm
I wonder if it's possible to simplify it further
Those shenanigans again... Just use a Deque.
only way to block opening crafting tables is with interact? bc inventoryopen and checking the type didn't work
no, why would I lol
check the holder or something
just check InventoryOpenEvent?
where's the problem?
what type did you compare to?
CRAFTING
lemme check
less overhead, both cpu and memory wise. You also have one less point in your system that can fail and you have to maintain.
ah
tbh I doubt it
yea i didn't do workbench
creating a deque just to copy an array?
thanks
np
To easily pop args from your array. Ill write a jmh benchmark. Interesten in what is faster to be honest.
can u only have the given ChatColors for colors in scoreboard and chat
or can i use any custom color code
scoreboards only support the 16 normal chat colors
chat supports hex colors
so
cant have brown?
idk, check the ChatColor class
i thought scoreboard supported rgb
hm maybe I'm wrong
Array: 29300
Deque: 47600
https://www.spigotmc.org/threads/1-16-scoreboard-objective-score-with-rgb-hex-color.468079/ looks like its possible
but not fun
hmm
Yeah thats not even remotely close to being a benchmark...
> Could not resolve all files for configuration ':Bungee:compileClasspath'.
> Could not find net.md-5:brigadier:1.0.16-SNAPSHOT.
Searched in the following locations:
- https://repo.maven.apache.org/maven2/net/md-5/brigadier/1.0.16-SNAPSHOT/maven-metadata.xml
- https://repo.maven.apache.org/maven2/net/md-5/brigadier/1.0.16-SNAPSHOT/brigadier-1.0.16-SNAPSHOT.pom
- file:/C:/Users/Punchline/.m2/repository/net/md-5/brigadier/1.0.16-SNAPSHOT/maven-metadata.xml
- file:/C:/Users/Punchline/.m2/repository/net/md-5/brigadier/1.0.16-SNAPSHOT/brigadier-1.0.16-SNAPSHOT.pom
Required by:
project :Bungee > net.md-5:bungeecord-api:1.16-R0.4 > net.md-5:bungeecord-protocol:1.16-R0.4
Possible solution:
- Declare repository providing the artifact, see the documentation at https://docs.gradle.org/current/userguide/declaring_repositories.html
``` error on attempting to compile with gradle, anyone know where to get the brigadier thing?
why not? except for the obvious thing that I didn't run it 200 thousand times
Jmh tunes garbage collection and all
With accurate numbers, failure rates
Well
You're calling that code on another thread
Bukkit doesn't like it
Bukkit.isPrimaryThread
Returns true if you're on the main thread
Benchmark (amountOfArguments) Mode Cnt Score Error Units
ArrayVsDequeArgsPop.argsFromArrayCopy 2 avgt 4 25,643 ± 0,265 ns/op
ArrayVsDequeArgsPop.argsFromArrayCopy 3 avgt 4 49,742 ± 0,351 ns/op
ArrayVsDequeArgsPop.argsFromArrayCopy 4 avgt 4 71,057 ± 0,715 ns/op
ArrayVsDequeArgsPop.argsFromArrayCopy 5 avgt 4 96,647 ± 0,694 ns/op
ArrayVsDequeArgsPop.argsFromDequePoll 2 avgt 4 15,959 ± 0,099 ns/op
ArrayVsDequeArgsPop.argsFromDequePoll 3 avgt 4 32,533 ± 0,325 ns/op
ArrayVsDequeArgsPop.argsFromDequePoll 4 avgt 4 38,818 ± 0,238 ns/op
ArrayVsDequeArgsPop.argsFromDequePoll 5 avgt 4 40,677 ± 1,473 ns/op
https://paste.md-5.net/urugotayox.java
There is only a single time when copying the whole array is faster: When there are exactly 2 elements in the array.
And after that it gets quite bad quite fast
Use the scheduler to run the task on the main thread
waiiit noooo
You have no idea when and how the jvm is warmed up. How the jit compiles during your tests, no averaging so a little hickup in your CPU from your browser or a discord
can invalidate a single measurement and so on.
you cannot compare this
you are never turning the deque into an array again, do you?
are you actually converting the deque into an array again?
Why would i? I thought this was used to simply pop args from an array
because people who want to remove an element from an array obviously need an array and not some random other thing
someone who says "how can I remove the first element of my T[]" wants a T[] as result and not a Deque<T>
otherwise they wouldn't have asked this question I guess
Or its an xy question. Which is the case most of the time.
yeah probably
I mean I totally agree with you that a Deque<T> is probably more useful and also faster. But the question was "how to remove the first element of an array" and not "how to remove the first element of a deque"
and I think in 99.9999% of cases, the performance of both operations is really neglible
if someone is removing the first element of an array 10 thousand times per tick, they're doing something wrong anyway lol
true
My only point is: Dont reinvent the wheel
But i have no idea what this limpeex guy was talking about anyways...
lol yeah I think they wanted to do sth like this:
have a /msg command, and a message can only have up to 500 letters or something
and obviously args[0] is probably the receiving player's name
so they wanted to turn args into args without the first element, then check if the "length" of the joined string is less than 500 or whatever
that's the only explanation that makes sense to me
If I'm integrating JDA into my plugin, should I be running most JDA-related things async?
not that this isn't over, but you could've just returned System.arraycopy(original, 1, original, 0, original.length - 1);
System#arraycopy() will automatically create a new array if the src and dest arrays are the same, so you're just doing legwork that it can do itself
Hi want to know if possible to fix this issue - a friend has a custom enchant plugin which allow him to use unbreaking lvl 10 for example, but then you compare the armor with another and its the same as enchanting it with unbreaking lvl 3
hello everyone
i am once again asking for assistance on how to make a certain entity glow for one player
ii am not very good with protocolib and my knowledge with packets is very basic
shop:
blocks:
grass:
itemName: §7Grass Block
price:
buy: 10
sell: 5
dirt:
itemName: §7Dirt Block
price:
buy: 5
sell: 2
food:
steak:
itemName: §6Cooked Beef
price:
buy: 1
sell: 1
my goal:
for each item in blocks make an item and put it in the gui
how?
A bit simply but i explain
First you ill need to loop the "food" section
So you will have to loop each section with Config#getConfiguractionSection()#getKeys(false)
And then build the item and add to the menu
is this the method to get all items in the object???
Explain a bit more
hwat
I didnt understand your question
yes but not with the FileConfiguration stuff
bcs i always just hardcode the configs
Allright so i recommend forward learning that
Because if not its diff to explain
And my goal is you to understand how it works, not to just spoof the code
sping spoof
Not a good moment for shocking
Hey, can someone help me debug this error? I can't figure it out.
Error: https://pastebin.com/4s62fUqg
Library method: https://pastebin.com/L7xp7cTY
Call From Main Class: Bukkit.getOnlinePlayers().forEach(p -> DFSpigotLib.PlaySounds(p, new String[] {"Chime","Chime","Bit"}, new Location(p.getWorld(), 5.929617510431854, 50, 4.765213468406728, -73.46591f, 21.44098f), new float[][]{{2f, 0.749154f},{2f, 0.840896f},{2f, 2f}}, (long) 50));
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
So I have a plugin that can launch a fireball with custom damage, and it will damage every entity in 3 radius of the explosion, for some reason it will broke a totem, so the totem got used but the player still dies.
This is how damage the entity
for (Entity nearby : fireball.getNearbyEntities(3, 3, 3).stream().filter(entity -> entity instanceof LivingEntity).toList()) {
((LivingEntity) nearby).damage(FireShardConfig.INITIAL_DAMAGE * power);
}
whats a deep
Your config file is a ""FileConfiguration""
You can load the config file by using YamlConfiguration.load(yourConfigFile)
Then you can get the ConfigurationSection out of the FileConfiguration
For example, in your config file:
The shop is a section of the config file
The blocks is a section of the shop section.
So on...
You can use loop and get the keys then get then use ConfigurationSection or FileConfiguration to get the value out of the key.
Then proceed to create your item by using the value you just recieve
Isnt what i explained him?
😆
Yeah. I didn't scroll up
a key is a variable correct??
The key is the thing before the ":"
So in this case:
- "test" is the path and the "value" its a string
- "users" is the path of a section, it contains 2 childrens called "uuid-1" and "uuid-2"
test: "value"
users:
uuid-1:
name: ""
coins: 10
uuid-2:
name: ""
coins: 10
okay
i understnad that part
the part i dont is the looping
I do a simple example:
FileConfiguration config = config getter;
ConfiguractionSection blocks = config.getConfigurationSection("shop.blocks");
ConfiguractionSection food = config.getConfigurationSection("shop.food");
for (String key : blocks.getKeys(false)) {
System.out.println("Block name: " + key + ", display: " + section.getString("shop.blocks." + key));
}
There you have a simple example
In the case you are working with sections, the getKeys() method will returned each children name
@grand perch if you need more help just ask!
okay
Do you understand that code i sent know?
sort of
spoonfeed!!! i will report you to spigot supreme court!!!
its not technicly spoon feeding my code is weird
Hahah i didnt want that but its 3am so im sleepy to explain in another way and even more if you are not english native speaker
🤙
I recommend watching about good practices when developing
Cannot resolve symbol 'ConfiguractionSection'
Configuration not Configuraction
Cannot resolve symbol 'section'
?learnjava
Here are some links to get you started on learning Java:
- https://www.codecademy.com/learn/learn-java
- https://www.sololearn.com/learning/1068
- https://www.learnjavaonline.org/
- https://programmingbydoing.com/
- https://docs.oracle.com/javase/tutorial/java/index.html
The last one is the only official one, however some of those concepts assume that you already know a bit about programming.
bump
I can ask something?
WHy you randomly appear for help and just throw "shity to people"
Like you dont help much in that way
section doesnt exist
;-;
he doesnt know how to declare variables my guy
im telling him to learn java
Oh
Yeah i suppoused that
then section would be the config
actually he didnt declare it
ConfiguractionSection blocks = config.getConfigurationSection("shop.blocks");
ConfiguractionSection food = config.getConfigurationSection("shop.food");
for (String key : blocks.getKeys(false)) {
System.out.println("Block name: " + key + ", display: " + section.getString("shop.blocks." + key));
}
can i recommend something
shop:
0:
material: COOKED_BEEF
name: "&4Steak"
price:
buy: 10
sell: 2.5
i think the config would look best like this
why 0 tho
its the inventory slot of the item
Agree
Imajin i do something worst hahahaha
ok
I just keep all the config item on Object!!
shop:
blocks:
0:
itemName: §7Grass Block
price:
buy: 10
sell: 5
1:
itemName: §7Dirt Block
price:
buy: 5
sell: 2
food:
0:
itemName: §6Cooked Beef
price:
buy: 1
sell: 1
But only when doing items that need to do custom things
Yes look better
Why food its diff?
Like why you dont just use one section?
bcs food is a diffrent category on the shop
Oh ok
That why i use a menu api
So i can use this in config:
Shop:
category-1:
0:
name: "bla la"
price: 10
1:
name: "bla la"
price: 10
category-2:
0:
name: "bla la"
price: 10
1:
name: "bla la"
price: 10
i copy every guide on spigot for entity metadata packets
and not one of them work
is anyone able to help me fix my protoclib code to make an entity glow
See you soon people i will go to sleep
You already asked, please be patient...
why name it category-x when i can just name it the category name
i asked like 20 times but it gets lost in a sea of other requests
no harm in asking again so someone might see it
Just an example for you, there you can just chaneit
I dont agree, if you want to dont lost it open a thread on this channel
ok man...
You should respect the rules
I have been banned many times for double posting code every time...
ive been here for 2 years and ive never had someone have a go at me for doing what i do
people are genuinely nice here
i tested it
it doesnt send anything
ConfigurationSection blocks = config.getConfigurationSection("shop.blocks");
//ConfigurationSection food = config.getConfigurationSection("shop.food");
for (String key : blocks.getKeys(false)) {
System.out.println("Block name: " + key + ", display: " + config.getString("shop.blocks." + key));
player.sendMessage("Block name: " + key + ", display: " + config.getString("shop.blocks." + key));
}
this is the updated code i tested
i know i've asked a few times but im getting confused with how packets work
i thought it should just be possible to send an entity metadata update to one player and make the entity glow/not glow, however this never works
do i have to do something like, use the spigot API to go entity.setGlowing(true) and then listen to the entity metadata update packet and interecept it so only some players can see the change or is the first approach possible
ok so update for anyone curious i've been playing around with it
public void addGlow(Player player, Entity target) {
PacketContainer packet = getInstance().getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA);
packet.getIntegers().write(0, target.getEntityId()); //Set packet's entity id
getInstance().getServer().broadcastMessage(target.getEntityId() + " id");
WrappedDataWatcher watcher = new WrappedDataWatcher(); //Create data watcher, the Entity Metadata packet requires this
WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class); //Found this through google, needed for some stupid reason
watcher.setEntity(target); //Set the new data watcher's target
byte flag = 0;
flag |= 0x01;
flag |= 0x02;
flag |= 0x08;
getInstance().getServer().broadcastMessage(flag + " flag");
watcher.setObject(0, serializer, flag); //Set status to glowing, found on protocol page
packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); //Make the packet's datawatcher the one we created
try {
getInstance().getProtocolManager().sendServerPacket(player, packet);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
this works for under a millisecond, i honestly think the only reason i can see the changes is because i have a 240hz monitor
i can see the player crouching+sprinting etc but then it goes back instantly to normal
what am i missing
anyone got a nice announcement plugin?
has bungee cord the same code as spigot?
ItemStack[] inv = player.getInventory().getContents();
int count = 0;
for (int i = 0; i < inv.length-4; i++){
if (inv[i] != null){
if (inv[i].isSimilar(item)){
count += worth * inv[i].getAmount();
player.getInventory().setItem(i, null);
}
}
}
GiveCoins(player, count);
}```
When I call this function like this `SellItem(player, item, 1);` I get 1299 coins and IDK why.
If I call it and I have something valuable in my inventory is gets it and gives me the right amount of money + 1299 for some reason
I don't understand where's the 1299 from
I tried calling it with any worth and item and it always returns the right amount + 1299
The count in the function is fine
the count is what it's supposed to be
but I still get 1299 more coins than I should
The function GiveCoins() is also fine and works correctly
How could I make my plugin be useable in more than one version?
no
if i'm getting a collection from a database, is a set better than a list?
depends on what you need to do with the collection
like is it possible to do thjat?
yes it is possible
talking about this
I mean it's possible but is it possible for a plugin thats already made
the easiest way is to make use of API methods only and then use multiple classes for where API is slightly different and identifying the version plugin is being ran on for this which you can make use of Enums for this
or would I have to er make the project or re write the pom.xml
yeah I'm not that good
multi module is the keyword
you don't need a multi-module for API only
hmm, still I haven't done anything with NMS yet.
API is only different between certain sets of versions
I actually wanna make my plugin useable from 1.16 to 1.18
and even then it really depends which methods are being made use of as not everything changes in the API
the thing is that i'm not really doing much with it, its just to store elements in, which will be added to the cache later
i think he's talking about NMS
from 1.16 to 1.18 not much really needs to be done except compiling against 1.16
yeah but I want to make it so that one jar file can be ran in all versions
yes compiling for 1.16
yeah I don't know how to do that
means the plugin can be used in 1.17 and 1.18
you don't need to compile specifically for higher versions unless you want to make use of methods that exist in those versions specifically
not 1.16?
which I am not aware of any major changes between 1.16 to 1.18
if you compile for 1.16 it should work in 1.16+
A set should be fine for this. Easier to work with a set overall then Lists
especially in regards to collections sometimes
correct
but how can I shift it from 1.18 to 1.16
you use 1.16 as the dependency to compile against, use the API methods that exist in 1.16 which should exist in later versions
which you will need to test
how can i remove specified element from an array
if the methods are different or have been changed in a later version, this is where you have to make use of multi-class specific code
or as stated earlier multi-module
you need to know its index
i know
I actually made it but its not updating the index after removing
you mean the index of the rest of the elements?
?paste
your method is a void method
since you don't have a global array for the string
the void method essentially provides nothing once it is done
it is lost into the void
instead of a void method, change that to String[]
and then return an array 🙂
hmm im looking for a way to work around this:
i have a Storage interface with one abstract method: Set<Home> loadHomes() and i want to have two implementations of that interface: a YamlStorage and a H2Storage but i want to work with futures in the h2 one, but i cant just change the return type from Set<Home> to Future<Set<Home>>, maybe i can work with callbacks idk whats the best to handle this
an interface for what?
instead of using Abstract
you could change it to an interface and then have the following classes implement it, and override it if necessary
ye but i want to 'override' the return type in the H2Storage to be a Future<Set<Home>> instead of a Set<Home>
do you understand?
x)
Can anyone help?
there is an PlayerInventory#containsAtLeast method
yeah. This might be a case where your api is too concrete at the upper level
and need to move the concreteness to the lower levels instead
https://paste.md-5.net/oviqapocaj.cpp like this?
ye that happened to me many times before, dunno really how to fix it
that should work and yield some kind of result 🙂
o.O
did you use /reload?
if so probably best to just restart the server lol
you should have gotten something different back
yes
How would that help
how do i get a datawatcher in 1.18
do you mean reload of stopping and restarting?
I don't mean reloading anything. Just stop and start the server or otherwise known as restarting
nvm
same
https://paste.md-5.net/owapoyiqar.cpp whole class
I just don't even know what could cause this problem
There shouldn't be any problem
whats not working?
also method names should start with a lowercase character
SellItem -> sellItem
that is an odd number
maybe you only want to check the material?
Wdym
instead of checking if the itemstack is similar
@wet breach im pretty sure there is a better way
There is, you need to do the reverse for your API
let your storage classes set the methods, make a class that combines all the storages into easy methods
so no storage interface
you can, just its doing the opposite
instead of going from 1 top class, you are starting with a multiple and then condensing down
how do I get the material of an ItemStack
getType
count += worth * inv[i].getAmount(); explain this math?
this is obviously where it is going wrong
I have a feeling it has to do with that multiplication on the right
Count = count + worth * item amt
I know math, I need them to explain why they are doing this
Where?
the amount of coins is supposed to be equal to the amount of coins plus the worth of the sold item multiplied by the amount of this item
I just opened this chat
then don't respond to things if you are out of the loop
👀
What's wrong with this?
try changing it to this then
???
Oh it's a sellitems method
count = ((count + worth) * inv[i].getAmount());
that likely does not do what the user wants
isnt worth the price?
No because you're multipling the previous cost by the amount
I check it and the count variable is always what it should be but I get (1299 + count) coins
Isn't that growing exponentially now?
Did you try debugging each incrementing of count to get where it comes from?
And even just before invoking the giveCoints method?
This is giveCoins(). I already checked it and it should be fine
int[] amount = new int[9];
amount[8] = coins / 10000;
coins %= 10000;
amount[7] = coins / 5000;
coins %= 5000;
amount[6] = coins / 2000;
coins %= 2000;
amount[5] = coins / 1000;
coins %= 1000;
amount[4] = coins / 500;
coins %= 500;
amount[3] = coins / 200;
coins %= 200;
amount[2] = coins / 100;
coins %= 100;
amount[1] = coins / 10;
coins %= 10;
amount[0] = coins;
ItemStack[] items = {Coins.one.clone(), Coins.ten.clone(), Coins.hundred.clone(), Coins.twoHundred.clone(), Coins.fiveHundred.clone(), Coins.thousand.clone(), Coins.twoThousand.clone(), Coins.fiveThousand.clone(), Coins.tenThousand.clone()};
for (int i = 0; i < items.length; i++){
items[i].setAmount(amount[i]);
player.getInventory().addItem(items[i]);
}
}```
In that case, it's the giveCoins method that is bork, not your sellItems one
Oh yeah, that has huge potential to be borked
I have another command that the only thing it does is use this function and it works perfectly
Even with the same value?
ah yes modulus
lets asume I put 345 coins.
I get 1 coin of 200, 1 coin of 100, 4 coins of 10, 5 coins of 1
That is how it should be
o.O
And for your sellItems method it just gives 1299 coins more?
yes
Even if you give it 345 coins?
yes
sounds inplausible
I checked it. if count == 0 in the end of the function I still get 1299
I can see how they are getting that
not sure why you are doing your math like that though
and that's how I called this function
SellItem(player, item, 1);```
so why are you using an array to do counting?
in the giveCoins()?
to make the code shorter
If I hadn't used the array I would have needed to make a clone of each item and then add this to the player's inventory which would take 18 lines
if you wanted to do math that way, you would need to do it similarly when doing math for binary
?
private void giveAmount(Player p, ItemStack is, int amount) {
is = is.clone();
is.setAmount(amount);
player.getInventory().addItem(is);
}
public void GiveCoins(Player player, int coins){
giveAmount(player, Coins.tenThousand, coins / 10000);
coins %= 10000;
giveAmount(player, Coins.fiveThousand, coins / 5000);
coins %= 5000;
giveAmount(player, Coins.twoThousand, coins / 2000);
coins %= 2000;
giveAmount(player, Coins.thousand, coins / 1000);
coins %= 1000;
giveAmount(player, Coins.fiveHundred, coins / 500);
coins %= 500;
giveAmount(player, Coins.twoHundred, coins / 200);
coins %= 200;
giveAmount(player, Coins.hundred, coins / 100);
coins %= 100;
giveAmount(player, Coins.ten, coins / 10);
coins %= 10;
giveAmount(player, Coins.one, coins);
}
Without an array it is one line shorter
ok you're right
Why do u have to clone the item each time?
If you're setting the amount each time
Oh i guess other usages
because otherwise the items would be changes so that if i use another command that uses these items it may not work
I guess it isn't really needed there actually
??
As long that is the only usage of it that is
You mean instances of those items?
As CB will clone the itemstack again once you call #addItem
lets assum i set the amount to 64 to give it, if i try to use another command that uses the item that i used before, the mount would stay 64 until i reload the plugin
As long as the amount is irrelevant for other logic, you can ignore that fact
Yeah^
But really this is just a minor nitpick about performancee
Though depending on the plugin it can be a justified nitpick, cloning is expensive
well I wanted to get help because my command isn't working. my performance is mostly fine
Well if performance is fine you can keep it as is until you need to optimize i guess
At the end of givecoins
What's the value of coins?
the amount of coins in the end of giveCoins() is the first amount % 10
if performance is your concern
you could easily do this with bitshifting
and know all the remainders in one go of a loop
.
but seems you are just making this more complex then it really needs to be
just because it is shorter in terms of lines, doesn't make it better or more optimal
IK. I'm not trying to make it efficient
It is probably some random method that appears unrelated but actually bricks the method in an unexpected way
But really you'd need the full source to estimate what is going on. Just did a test myself on my own impl and it seems to work right
Maybe I can make a function to remove coins and always remove 1299 from the player after he sells anything
in 1.18 spigot you cant use ENTITY_METADATA properly, the changes last for a millisecond before going away
how can I make it so that nobody can break blocks in the server but they can only at given spots of like 30x30s
Give the whole source code
?paste
really?
Nah
the only time my packet works is when i run a 1ms timer to set it constantly
im convinced its broken
ive been at it for a day and tried every tutorial
You have no breaks in your onClick method, are you sure that that is wanted?
I have also problems with packets and ENTITY_METADATA
i swear its broken?"
idk who to ask or what to do
feel like ive just wasted a day trying to do the impossible
it isn't wait
so setting my itemframe invisible works, but settings the item inside is weird
idk maybe protocolib is broken
np
so for me I think its actually my problem, bc setting the item as APPLE works, but not as FILLED_MAP with image
idk its just fucked haha
this has to be the least documented version of MC
new BukkitRunnable(){
public void run(){
Player p1 = getServer().getPlayer("account1");
Player p2 = getServer().getPlayer("account2");
getGlowManager().setGlowing(p1, p2, true);
}
}.runTaskTimer(this, 0, 1);
this makes it work
so idk wtf is going on
@harsh totem I'd recommend you make classes for coins and sellableitems
Reee BukkitRunnable
exactly
this is what im saying
works for 1 millisecond then breaks
Use lambdas
no i dont want to use it haha
im saying why cant the packet persist
theres something wrong with it
like i noticed today when i was testing if i sent the packet to set a palyer on fire/running itd work for a millisecond
and then disappear
what in 1.18 is so different that it gets rid of the changes instantly
idk i can read through it all but tbth my knowledge on packets is so small and limited i wouldnt be able to find it if u put it right in my face
are you sure you are setting the time correctly?
as in you are not setting it to just 1 tick?
for glowing?
public void setGlowing(Player player, Entity target, boolean glowing) {
PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA);
packet.getIntegers().write(0, target.getEntityId()); //Set packet's entity id
WrappedDataWatcher watcher = new WrappedDataWatcher(); //Create data watcher, the Entity Metadata packet requires this
WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class); //Found this through google, needed for some stupid reason
watcher.setEntity(target); //Set the new data watcher's target
byte entityByte = 0x00;
if (glowing) {
entityByte = (byte) (entityByte | 0x40);
} else {
entityByte = (byte) (entityByte & ~0x40);
}
watcher.setObject(0, serializer, entityByte); //Set status to glowing, found on protocol page
packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); //Make the packet's datawatcher the one we created
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
heres my code
https://wiki.vg/Protocol#Entity_Effect yeah, the only reason would be that the duration is 1
whatever it is you are trying to do. Things done via packets have to be constantly sent because generally the server is unaware of what you are doing and thus when the server sends an entity update to the client
it removes your changes
Where do you set the duration?
this used to work fine in older versions
Likely because of how 0 (or whatever the default val was) was treated
how do you mean
just because it worked fine in older versions, doesn't mean older protocol versions are the same
glowapi is broken as well so idk what my options are to fix this
yeah i mean thats true
Well, assume the default duration is 0, before it was treated as an infinite time period, now it is treated as less than a tick
I just know when you are doing things with packets in regards to entities especially setting their metadatas. If you are not cancelling the entity updates in the server events, then the server sending the update will wipe your changes.
how do i do this
I'd highly assume that it is a potion effect at the backend, but idk what you are doing
i can track who should/shouldnt see glows
oh it's entity metdata
it used to just be an entity metadata
yeah
u CANN use potions but that seems doodoo
like isnt the point of manipulating the datawatcher to stop the server from wiping changes?
I think exactly that is happening rn
but uh, I am not really knowledgeable in this field
either
idk if anyone reading this has a solution i’m gonna give it a rest but i’d appreciate any input or push in the right direction
I do have classes for these
If you already have a real bukkit Entity then you should not create a WrappedDataWatcher from scratch but wrap
the current entities DataWatcher. Then manipulate the bytes.
Be sure to also listen for outgoing meta packets for that entity because if the player receives any update for this
entity then the glowing effect will vanish.
do I need to listen for outgoing meta packets aswell? I create an invisible item frame (working) and want to set the item inside, but that spawns and despawns instantly
Is the item frame present on the servers side?
the itemframe is an packet
Then the server wont send any packets for this item frame because it doesnt know that the item frame exists.
ok, but why is my itemframe with map with image not working ._.
How do you add the map to the item frames?
I have this:
PacketManager.sendItemFrame(player, l.getX(), l.getY() + y, l.getZ() + z, true, map); and map is an itemstack, when I change map to
new ItemStack(Material.APPLE), then its working
regardless of how you are creating the itemframe with the map in it via packets. The reason it disappears is you will have to stop and modify any block or chunk updates near your item frame otherwise it will vanish from the client
Did you tag the item frame as 'fixed' so it doesnt care about adjacent blocks?
eh no ig, but still it works with an APPLE
sendItemFrame(): https://paste.ofcode.org/4NPr7ttfRBGBDRdWN73Zq8
how do i get the entitys datawatcher
i need to listen to every packet? that seems awfully laggy
If you have 1k players and show them 1k glowing entities it would def use <0.25% of the tick.
You will run out of cpu time for players before listening to some TCP packets becomes an issue.
so its fine to do it this way?
it shouldnt be that drastic anyway
how do i go about grabbing an entity’s already existing datawatcher
?paste
My Intellij goes to 100% cpu usage when decomiling Material.class
Then dont decompile any spigot classes... The sources can be imported.
Ill send you something in a minute. Just have to test it.
ty
ive had to go afk for a while so ill trst when im back
ty for the help
lol yeah now I can't open the project anymore xD
frick
ok finally
cool
im gonna import those sources really fast
:P
How do I import the sources?
how would i do something like event.getClickedBlock() == Anvil like how would i do the anvil bit
because Material.Anvil isnt working cuz it gets a block and not a material
Get the material of the block and compare it with Material.ANVIL
ah ty
Ok i got it to work. This is an example that lets me set an entity glowing for 1 second after hitting it:
@EventHandler
public void onInteract(EntityDamageByEntityEvent event) {
if (event.getDamager() instanceof Player player) {
Entity entity = event.getEntity();
glowManager.setGlowing(player, entity);
Bukkit.getScheduler().runTaskLater(this, () -> glowManager.stopGlowing(player, entity), 20);
}
}
Its a single class. You can take a look here:
https://gist.github.com/FlorianMineCrypto/310fd25ead0e7af1bb3a81abcd5dbb0b
ill sus now
wait are you manually removing the glow
or does it time out
Bukkit.getScheduler().runTaskLater(this, () -> glowManager.stopGlowing(player, entity), 20);
because i want to make it permanent until i turn it off
sorry if i missed it because im on my phone out atm
so u turning the glow on makes it permanent until u turn it off?
I have a problem with loading images on a map, that is inside an item frame, that is send through a packet to a player, the item frame and setting is the item is fine, but I have problems with the map. It only works when I also add the map to the players inventory if not, than they spawn and despawn instantly:
main part: https://paste.ofcode.org/36FcpZFVjQwhV885veFCe2c
ImageRenderer: https://paste.ofcode.org/4VGrT3MbjT8gZ7FYSHq3NL
with add map to players inventory: https://www.youtube.com/watch?v=gbldtnt6Ojs
without: https://www.youtube.com/watch?v=Fg7q0iOQeSc
how can I change the names of people in TAB and their names above their characters in game
Just give them a new PlayerProfile with another name.
can also add colors like that
if i want it to look like this on tab and above their characters
can new PlayerProfile do taht
Sure
player profile changes the name even for commands
so if you change my name to yada1 instead of /tp yada0 you would have to do /tp yada1
its nms
what
bit more complicated than that
if you don't know what NMS is probably shouldn't be touching it
Do you want to change the players name all together?
So that he appears differently in other plugins, messages, etc too?
To achieve what?
i already did the messages by just canceling mesage and sending new
huh
cus I want cool looking names i guess
idek
with ranks next to tehma
and colors
Ah thats a different story. You can achieve that by using prefixes and suffixes of teams.
ty ill test it when im home ❤️
would it be better idea to make a team for each rank
so they all have same prefix and suffix
there is other ways of learning something without doing. You don't need to use NMS to know what NMS is.
did you also not understand java?
yeah for me they are one in the same anyways not arguing semantics here nor am I changing my stance 🙂
obviously you decided to learn the more difficult way, and either it has paid off or you learned some terrible habits. Either way, most others don't learn this way
I didn't say anything in regards to spigot
if you learn
if you don't learn something new from what you previously knew you don't progress
#help-development not #debating
How do I import the spigot sources in a maven project, so Intellij doesn't have to decompile everything when opening?
anyways, I am going somewhere else. You are a terrible debater
.
nor accept their opinion
omg
not sure really - i just look at the stash normally
I used this for their name on the TAB list
stash?
?stash
but how can I change their names on their heads
normally you could right click on the maven project to tell it where it can find the sources for a dependency
at least this is how it is in netbeans
pretty sure it is something similar in IntelliJ
I am a netbeans fan
in case you didn't know 🙂
no
while intelliJ and netbeans are pretty similar in terms of functionality and could argue they are the same. They are still different because of how they both choose to organize their menus, what level of control over the IDE's they allow you to have as well as even though they have the same features how they are implemented are not the same.
then yah
tho zacken you do have a point, all ides do share a common set of features in order for them to be considered ides
and not just DEs or Code Editors
why does this not work for setting the players' name above their heads to have a prefix
does it work on tab?
i did something else for tab
i mean this is something i guess
but doesnt work on tab
even when i dont have this
i want to start a bukkit runnable every time a player hits a player but if a bukkit runnable is already running how do i stop it?
any good recommendations for a command annotation framework?
You can keep a Map<UUID, Integer> that maps the player id to the runnable id.
You should most probably do something else to manage this.
how could I use this API in my maven project
dumb question
first time using maven
It takes a while to get used to. But if you understand all the internals then you
will write commands very fast.
good :)
Usually they have an example setup for that on their documentation
is there an easier way u know that I could use to setup the players' naems above their heads
new BukkitRunnable() {
@Override
public void run() {
something.put(p.getUniqueId(), this);```
luck perms supports that iirc
Explain in detail what you are trying to do
yes
did you add the proper repository?
<!-- StatsAPI -->
<dependency>
<groupId>de.snx</groupId>
<artifactId>statsapi</artifactId>
<version>v1.2.6-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/StatsAPI.jar</systemPath>
</dependency>```
Why cant I use the API?
click the maven reload button
doesnt work
com.nametagedit:nametagedit:pom:4.1.16 was not found in https://hub.spigotmc.org/nexus/content/repositories/snapshots/ during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of spigotmc-repo has elapsed or updates are forced
com.nametagedit:nametagedit:pom:4.1.16 was not found in https://hub.spigotmc.org/nexus/content/repositories/snapshots/ during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of spigotmc-repo has elapsed or updates are forced
click on the "m" button, then enter "mvn clean package -U"
Then you should only need one runnable.
When the player gets attacked -> Add a unix timestamp to their PDC
Then start one runnable when the server starts. This runnable goes through every player in 20 ticks
and checks the timestamp. If the timestamp is further than N milliseconds in the past you send them a message.
If you want to check if someone is being tagged as "in combat" then you just get their PDC and check the timestamp.
dont have this
are you using intelliJ?
yes
then you do have this button
It should be on the right side
by default, on the right side, there's a bar called "maven"
Probably is
but wtf is this theme
press "shift" twice, then enter "execute maven goal"
