#help-development
1 messages ¡ Page 776 of 1
not necessarily
yeah I know the basics
but the write method in the ChannelDuplexHandler
LoggingHandler
don't waste your time writing code that already exists unless it's strictly necessary
is only for the Player that is
it is
strictly necessary
No not really
in a computational sense
Negligable
w h a t
in a computational sense your words are complete nonsense
?
just because you can't understand them doesn't mean they don't mean anything
they might mean something, but like... don't make your life harder man
one dependency isn't much
Big bois
But I'm on the development phase that I look for optimizations everywhere, and using a lib is 9/10 times a slower option
Also performance is key to my plugin
since it's an antibot
online-mode=true is a pretty good antibot
doesn't matter that literally nobody uses it
đ
đ
those few nano or miliseconds are not worth it
there's a major difference between the two
ÂŻ_(ă)_/ÂŻ
hell fucking nah, what is that
yo how do you
hide your code
at decompilation
cuz I was just skidding getting some inspiration
and the guy literally said "nuh-uh"
Can you?
Don't you just obfuscate it, too make it hard too understand
w h a t
Obfuscating is a waste of time
Totally agree with you
Some obfuscation even slows down the execution
mfo thought he could outsmart me
So if ur worried about nanosecond donâg
not for anticheat devs
lol
It is
Fuck
anticheat obfuscate their code more times than they have lines in their main class where they write all their crap
how am I even supposed to skid that
greek ass
an obfuscator that turns everything into greek would be cool imo
A good system for those who needs none online players is XCard is a proxy which includes AntiBot, rate-limiting. Its even blocks you directly via firewall if you start spamming packets
Donât advertise weird stuff
are you praising it or criticizing?
you can pretty simple, if you read the bytecode haha. There nothing matters if its obfuscated
I just mention it because he asked for an antibot
lol
assembly people agree
Verano is just not the best at english
what is your native lang if I may ask?
yeah, spanish totally different haha
oh, nice
yo, you type faaaast
public String getChestType(Location location) {
return chestLocations.entrySet()
.stream()
.filter(entry -> entry.getValue().contains(location))
.map(Map.Entry::getKey)
.findFirst()
.orElse("default"); // Or another default value indicating no match
}
hi can i do this diffrently?
yeah they are years of using pc, since im 5y old
yes it's possible
nice
Why
Can just return null too, but yeeah thas okay. Because is more descriptive rather returnning null
it just not work
or return the correct value
i mean it only return default chest xDD
is there a method to "wrap" or \n if line.length>maxLength or should i actually make it ?
What are you trying to do with the function?
for lore
Lol
I asked bing for fun
Hello, this is Bing. I can help you with rewriting your code in different ways. Here are three possible alternatives:
// Alternative 1: Use a for loop instead of a stream
public String getChestType(Location location) {
for (Map.Entry<String, List<Location>> entry : chestLocations.entrySet()) {
if (entry.getValue().contains(location)) {
return entry.getKey();
}
}
return "default"; // Or another default value indicating no match
}
// Alternative 2: Use a lambda expression instead of a method reference
public String getChestType(Location location) {
return chestLocations.entrySet()
.stream()
.filter(entry -> entry.getValue().contains(location))
.map(entry -> entry.getKey())
.findFirst()
.orElse("default"); // Or another default value indicating no match
}
// Alternative 3: Use a ternary operator instead of an optional
public String getChestType(Location location) {
String chestType = chestLocations.entrySet()
.stream()
.filter(entry -> entry.getValue().contains(location))
.map(Map.Entry::getKey)
.findFirst()
.orElse(null);
return chestType != null ? chestType : "default"; // Or another default value indicating no match
}
@twin venture Itâs most likely due to you using Location
Are you using a proper block location
declaration: package: org.bukkit.util, class: ChatPaginator
ty
when are they fixing legacy compoennts? Im tired of not being able to personalise compoennts via config
fixing?
Yeah they are broken legacy ones, when you using color codes
pr it
It happens that only apply color to some lines, the rest just appears as white
not matter if you put a color code before
I would like to PR it but i will endup changing the whole shity components api haha
?jira
?jira
what that heck never used it
And what is the best fix for it?
Issue tracker
i just realize that thing exists sorry i sound rude
I mean you can use distance or compare the location of getBlock()
Used to it haha
which one is best for performance?
oh thanks, now i dont feel stupid because i not knew about it
Location of le block
what would be the event or method i would utilize if im interested in making a door that kills a player when they interact with it
I mean if ur locations are based on blocks @twin venture
If not youâd want distance
Interact in what way
PlayerInteractEvent
?playerinteractevent
thank you
?interactevent
The PlayerInteractEvent may be called once per hand. If you only want code to be executed once, you can check the result of https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/player/PlayerInteractEvent.html#getHand(), then decide functionality.
For example, only executing code if the main hand was used:
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getHand() != EquipmentSlot.HAND) { // * if the hand used is NOT the main hand:
return; // do not progress past this point |
}
// provide functionality
}
Could i lag the serve rif im constantly updatin an scoreboard which represents table of current claims depending the current location yo uare
Please tag me for any anwers
Alright, I understand this isn't a spigot question, but does anyone know how to make a task run before the build task in gradle? SO hasn't helped me
I'm trying this
tasks.getByName("preBuild").dependsOn("ktfmtFormat")
Gradle can't find preBuild task (and neither can it find build task) (getByName fails, other suggested using project.tasks.preBuild, but preBuild isn't a property of tasks either)
Sure
right, so could you give me recommendations? Thanks Jan
Canât find why
Update it less
hmn, im already running it async the board updation
It doesnât need to be updated all the time
Task with name 'build' not found in project ':HeroesPlugin'.
100ms min should be fine for most things
I'm guessing it's not it's correct name (I don't know if this is idiomatic way of getting the main build task)
oh okay, so what you mean is not updating when he move. Just set a delay of 3 seconds, that perfect right? And again totally thanks!
referring to this, would i store the block in a Material or a Block
if (event.getClickedBlock().getType() == Material.OAK_DOOR) {
event.getPlayer().setHealth(0);
}
I canât recall. Are you doing it in the proper place in the build file?
Type
a blocktype?
What do you mean store
i want to store the block which was interacted with so that i can check it against a door
Why do you need to store it
No idea, this is my build.gradle.kts
plugins {
kotlin("jvm") version "1.9.10" apply false
`java-library`
id("com.ncorti.ktfmt.gradle") version "0.15.1" // https://github.com/cortinico/ktfmt-gradle
}
subprojects {
tasks.getByName("build").dependsOn("ktfmtFormat") // THIS FAILS
apply {
plugin("java-library")
plugin("org.jetbrains.kotlin.jvm")
plugin("com.ncorti.ktfmt.gradle")
}
ktfmt {
// KotlinLang style - 4 space indentation - From kotlinlang.org/docs/coding-conventions.html
kotlinLangStyle()
}
repositories {
mavenCentral()
maven("https://repo.papermc.io/repository/maven-public/")
maven("https://plugins.gradle.org/m2/" )
}
dependencies {
compileOnly("org.spigotmc:spigot-api:1.19.3-R0.1-SNAPSHOT")
}
}
is that code correct? i have tried it i was just thinking through it here
Do it after applying the plugins
I thhink?
It should work fine
The code looks fine, but till cant understand what you wondering to store
legend
that worked
thank you! (Now to figure out ALL Those warnings of unnecesary compilation I have....)
storing a block
blocktype
is there a blocktype variable?
Why do you need to store it
Ur welcome
yeah that what i ant understand
if i wanted to store it so i can give it a name called poopy fart or if i wanted to store it for readability or for whatever
There is no need to store it if you are just killing anyone who touches a door
people store data for shits and giggles
?
but how would i do that in this instance
Where are you from?
Blocktype bt = event.getClickedBlock().getType()?
Thatâs a material, but yes
or do i store it in material
so it would be in material
Material m = event.getClickedBlock().getType()
what do you mean
I give up
dawg i was wondering how to store it so i could know how to do so in the future
wasnt sure if it was a block or a material that i would have been storing
Yes, i asked where you were from to tag someone from there to figure you out haha
i am from america
Oh
Wow
@wet breach This guy speaks ur language
wut?
like naming variables?
Idk smth to help that guy
just got home let me read up a bit
Read the convo for fun
i dont need help
i know the difference between the words, i was just not using the right ones
because it was too much effort tyyping that long word
yeah so
let's rephrase this a bit
Looking at your problem, let's structure this in a few simple steps
when a player clicks, check:
- if the click is a right click
- and the player clicked on a block
- and the block that was clicked is a door
and if all those pass
- kill the player
@echo basalt so when we were talking about my abstract class storing data being incorrect
So the first thing a beginner would do is probably something like
@EventHandler
public void onClick(PlayerInteractEvent event) {
if(event.getAction() == Action.RIGHT_CLICK_BLOCK) {
if(event.getBlock().getType().name().contains("_DOOR")) {
event.getPlayer().setHealth(0);
}
}
}
did u want the individual characters to handle data themselves
Now, let's actually write some good code
?
https://bukkit.org/threads/poc-blockapi-custom-blocks.103310/ who has a breakthrough in this idea?
And we can do so by:
- Assigning our variables so we don't call methods in checks
- Applying guard clauses
or maybe my repository class could store them
checking the string is a nice idea
So it'll look like
@EventHandler
public void onClick(PlayerInteractEvent event) {
Action action = event.getAction();
Player player = event.getPlayer();
if(action != Action.RIGHT_CLICK_BLOCK) {
return;
}
Block block = event.getClickedBlock();
if(!block.getType().name().contains("_DOOR")) { // underscore prevents trapdoor from triggering
return;
}
player.setHealth(0);
}
i made a substring of the last four characters and checked it that way
bet you've been waiting for me to show up all day
considering we don't use ID's no more and resource packs extended quite a bit since then. This is already do able with resource packs
Super old
bruh...
Palettes are a thing now right?
is it possible without them?
uh yeah
one line this shit with ternary operators â¤ď¸
im kidding
i hate one line code
So what do u think
this is good thanks
I really don't want to spend more time with this topic
it just changes the texture
Just try a bunch of stuff and see what works
should I make several commands in one class or every separate command in different classes?
Alr mb
it really depends
since those commands would be around the same topic
i think a lot of us do 1 per sub command
resource packs do more then just that, but without resource packs you would't be able to style your custom block đ
I want to make commands for managing lootboxes
1 for creating, 1 for removing, 1 for giving it
in my case I just have an entire engine that does stuff for me
then yeah one for each
and maybe a 4th class to link it all together
in what sense
you can't change the behavior of the block
what do you mean can't change?
if you're using an engine / api you don't need a 4th class
but just something that implements CommandExecutor and does the logic for you
public class MyBaseCommand implements CommandExecutor {
private final Map<String, MySubCommand> subcommands = new HashMap<>();
...
does tab completion based on the subcommand list
If u want to change behaviour of blocks fork soigot
it'd really be better if we just used a tree for this
in fact, I myself didnât really understand what was written in the article, but as I understand it, they wanted to create blocks with changed behavior
uh
no use events
yeah I dont really get much
think their idea was to just register a new block in the registry and mask it out when sending packets
so you can like easily check if the block is present innit
I am not still not understanding the change behavior part? I mean you can make custom blocks do just about anything you want it to
especially if you are using resource packs as well
by behavior it's probably just extending the nms block class and adding/overriding logic
Well, for example, change the behavior of a block without using an event idk
or I didn't understand something
so from what im understanding making main class with command executor and just one class for each command is just fine?
yep
the "proper" scalable way in the future is to make a sort of tree
where you have a "root" node that's your main commandexecutor class
and each child node can have its own child nodes etc
you are making some kind of plugin with 1000 commands?
uhh I guess
more like I am making a structure I can use across 100 plugins with 10 command each
Ilussion would you command be free? Or u willl sell it source
not really getting what node and child means
Are you familiar with the concept of an object tree
Yes
not asking you
A node is a group of things
no
âŚ
...
if you really really want a mediocre command system just look somewhere in my git projects
I don't sell my utilities
I sell products made with them :)
commissions ..
Whats the best way of storing an ItemStack in MySQL?
Bytes
with nms you just get the nbt and serialize it
Serializing the itemstack into a byte array
is there a plugin like deluxeMenu but with functional buttons?
with bukkit something something bukkitobjectoutputstream
not good
no better alternative
with paper there was a serialize method somewhere
p sure people were talking about itemmeta.toString giving nbt
Thatâs a question for #help-server
also i ask, why dont they already implement that into bukkit
A good serializer and deserializer for items
Are those things i see spigot not satisfied really good
just do it yourself and pull request if you really want to see it
yeah if we wait spigot team to look up it
Imagina if they takes months for support emails
you can just sign the cla and write it
there's no dedicated "spigot team" per se
well
There is the administration team
they handle the forums and discord server
There's also md and some other contributors
but it's not a company
yeah if spigot where a company it would succed a lot. Not saying spigot work is not good
no
havent heard it yet
Also ilussion how about your hour? $$
yes
You know how a linkedlist works
not really
Alright let me write you a basic impl
public class Node<T> {
private final T value;
private Node<T> next;
private Node<T> previous;
public Node(T value) {
this.value = value;
}
public Node<T> getNext() {
return next;
}
public Node<T> getPrevious() {
return previous;
}
public void setNext(Node<T> next) {
this.next = next;
}
public void setPrevious(Node<T> previous) {
this.previous = previous;
}
}
This is a node
public class LinkedList<T> {
private Node<T> head;
private Node<T> tail;
public void add(T value) {
Node<T> node = new Node<>(value);
if(head == null) {
head = node;
tail = node;
} else {
tail.setNext(node);
tail = node;
}
}
public T get(int index) {
if(head == null) {
return null;
}
Node<T> current = head;
int pos = 0;
while(pos++ < index || current == null) {
current = current.getNext();
}
return current == null ? null : current.getValue();
}
}
type deal
this passble create texture for placed blocks?
what does T stand for?
T is a generic type
It's basically context
So if I create a List<Boolean>, every T gets replaced with Boolean
you can set some constraints and use those constraints in methods
for example if you specify <T extends Number>
you can use every method present in Number in any T object
you can do some crazy witchcraft magic
oh so if I want to make List of strings it would be List<String> ye?
ye
okay
But yeah the idea of a Node in linkedlist is a sort of object wrapper that contains another Node as its parent / child
or in this case
parent is previous, child is next
With a tree, you have a list of children
is there any way to force a scoreboard line to be centered?
looks like dynamic typing
you need to know the length of each character
hm, im still pretty confused about how to utilize it in practice
Alright so
With commands
You know how each subcommand can have multiple subcommands?
that's the idea
let's take a look at a luckperms command for example
so in my scenario it would be /lootbox add/remove/give?
as in 3 subcommands for /lootbox
Think of it like
hmm
like?
your tree would look like this
okay
The cool thing about having your nodes
is that you can add like
requirements for nodes
For example, players can only run XYZ commands
and the "give" command requires a permission
hey another question
With those requirements, you can filter out nodes in tab completion and execution
so Id need a 4th class that would be a node?
Well your solution is fine
but if you want to build a full command system for future projects you'll want this in mind
if i want to run something say every second, how would i do that? i tried Thread.sleep(1000), but threw an error
?scheduling
You basically never want to sleep a thread
for now my next project would be to make a plugin that would work with custom damage, mobs, player stats and weapons
I got them done in separate plugins but I wanna merge them
BuT yeah the cool thing about this tree structure is that you can loop incrementally
For example, if I run the /lootbox give ImIllusion command
difference between scheduler and runnable?
it grabs the "lootbox" node
is there any significant difference in this case
matches give to all my nodes, finds the give node
and if I don't have that node's permission, it stops iterating there
if you do, it finds correct lootbox?
and if I have the permission, we repeat the process for the give node
grab next word, match it against all nodes
in that case it'd have to loop through config
like a hash map?
The other thing is that you don't want to match the node's name
but have a sort of argument system
In my command system every node has a name and an argument
The argument is responsible for validation and tab completion
The node name lets me get the value of an argument in execution
Here's what my CommandNode interface looks like https://paste.md-5.net/mevinoxave.cs
so it works similar to keys?
yeah
yeyeye but it's somewhat recursive
what is the best way to store big data in a hash?
so here give remove add are children and parent is lootbox?
uhh no
well
lootbox is a node with no parent and the children are add, remove, give
add is a node with the parent lootbox and the children are <lootbox> or whatever you name it
<lootbox> is a node with the parent add and the children are <player> or whatever you name it
yeah
and things below are children
think of a family tree
is there a term of grandparent
well
or does it not go that far
you don't need to go that far
you can get as many parents as you want by just looping through parents
and yet im still a foster đ
anyway I get the idea
ill do it my way first to tidy things up in my plugin
and then try to improve it with that new thing
never sneeze with ur eyes open
overkill or not, a new thing to learn and flex my braincells
oh yeah one more question about plugin size, since Id most likely do 3 commands ( give/spawn, add to config, remove to config) for custom weapons and mobs, and use their assigned stats along with player custom stats in damage formula to set health bars and such, would it be fine to do in one plugin?
assuming that I would keep it tidy, more or less
congrats, you are now Dad
is it theoretically possible to make custom mobs by animating blocks with armor stands?
or is it too much for server to handle?
isn't that just modelengine
No
?
You tick through it ever server tick
I mean I dont really know what kind of already existing tools can be used to make such things possible
if they do
First result
How could I stop someone from being visible in tab?
Cuz I think they removed the REMOVE_PLAYER enum
yeah it's just a packet now
I have a question about commands, first String s is the first parameter, as in if I wanted to do "/lootbox give", and the String[] strings would be next parameters that would be player, amount, type etc.?
strings represent all what pass to the command after the name meaning that your command is /test a b c, a b c are the arguments
oh
so it basically depends on how many arguments I need?
if I want more than 1 then I use strings?
if you do "/lootbox give", the "give" will be in string[0]
exactly
You use String.join
To join that array
huh
Example String[] foo = {a, b, c}, String bar = String.join(foo, " ") would be equal to "a b c"
If you want to chain more that 1 argument
"/lootbox give DuskTaler 5 someType"
Will give you
s -> "lootbox"
strings -> ["give", "Dusktaler", "5", "someType"]
yep, s is the command itself
Sure, why not (assuming you have atleast one argument, in other case, that code will throw error)
i always call that variable "command" and the other variable (called "strings" in your example) "arguments"
You want always to check number of arguments first
strings are the arguments given after the initial command - an argument is the string after the command splet by spaces
Else you will get an ArrayOutOfBoundsException if no arguments were given
(just so he knows why :D)
if (args.length != 5) return false; for instance if I want my command to have 5 args?
yes
well and also some kind of debug message to player like "you didnt provide enough parameters"
Sure, it would be nice to send some error message to player too
okay I get it entirely now thank you
Wait, should one not return true on error?
oh good question
when do I return true or false
I think true is when command succeeded and false otherwise
But no one use that anyway xd
ah, lol, good to know
ig some debugging shenanigans
Docs should have exact explanation
i have it the wrong way around in my plugins then haha
I may be wrong
sentence: death
if you return false, the server assumes the user didn't have permission and will display a no permission message, either the default is sent or a custom one if one was specified in plugin.yml
typically if you want a more customized error, you return true but send your custom error message
Executes the given command, returning its success.
If false is returned, then the "usage" plugin.yml entry for this command (if defined) will be sent to the player.
Doesn't it return like command usage?
or it returns this
one of them two is returned XD
ah, so if usage is defined, it returns that, else it returns "no permission" ?
if it says it returns the command usage if its false, then that it what it will return
which makes sense because if the command failed, then obviously something was wrong with the command
PDC works on entities right?
yeah
neat
Where do we issue bot commands?
(since there is no bot chat, i'm guessing anywhere?)
?help
selfrole Add or remove a selfrole from yourself.
cleanup Base command for deleting messages.
embedset Commands for toggling embeds on or off.
info Shows info about CafeBabe.
licenseinfo Get info about Red's licenses.
mydata Commands which interact with the data CafeBabe has about...
set Commands for changing CafeBabe's settings.
uptime Shows CafeBabe's uptime.
findcog Find which cog a command comes from.
names Show previous usernames, global display names, and server...
userinfo Show information about a member.
listcases List cases for the specified member.
reason Specify a reason for a modlog case.
permissions Command permission management tools.
can I pay someone to convert a script to a java plugin?
its a complex and advanced script
Sure
dms
... found the bot chat
how do generics work again?
You have to declare generic somewhere, it's usually done at class level
you can do it at the method as well
maybe not void lol
anyone else?
e
?services
If you wish to request or offer development/art/building/administration services, please do so at https://www.spigotmc.org/forums/services-recruitment-v2.54/
how to set color of banner itemstack? i have DyeColor and want to set color of crafted banners to that dyecolor
I am 80% sure each color banner is it's own item
yeah i know that, but if i have dyecolor then how can i change the item based on that dyecolor?
probably with a switch
is there EntityType equivalent of Material type = Material.matchMaterial(typeName);?
fromName()
what does this mean?
deprecation means it's still functional but there's a better alternative
and should be avoided / due for removal
usually*
For example, StringBuffer is deprecated in favor of StringBuilder
well I want to get entity type from config
Registry.ENTITY_TYPE.match()
so I did this
does it work for Material as well?
Yes, Registry.MATERIAL
okay thats pog
You seem to have a custom config class already
how about you extend it and read all the values there instead of doing it on your method
cool I didnt know registry was a thing
It's a relatively new method though so be weary of that. 1.19 or so
is that why they deprecated fromName?
I need to write a huge post regarding good code
might put it both in my gist and here
no idea
actually yeah I might just make a git repo with a backup of every single index post
so what would be the alternative if you dont have access to the registry class
do I just make a method that reads config into list?
Probably just the regular Enum#valueOf() methods, but Registry is 1.13+ so you should have access to it in most scenarios
If you don't have the match() method however, which is newer, you have NamespacedKey#fromString(String) which you can then pass into Registry#get()
And if you don't have NamespacedKey#fromString() you can copy its implementation from Bukkit đ
done
gotta write one about good code practices
uh
I changed my main class name
from Customdamage to CustomDamage
now it says that it cant find the class
I changed it in Maven file and reloaded it as well
did you update plugin.yml
You did probably cast it to Player before checking
Show your whole code then
Iâm not really familiar with persistentdatacontainers, can you just use them for permanent data storage on a player (assuming their data file isnât deleted) instead of using a database or something
Yeah kinda. Drawback: You can only access this data when the player is online
alright, thatâs fine for my current case
I assume it will persist through any actions to the player like deaths etc
As far as I know, it will persist as long as the world file is intact
As that's the place where the data is stored
Im kind of confused because you have no Player import as well...
Oh, true
Nvm, solved, I just didn't have Player imported
Thanks for pointing out
Also is the selectedList variable alright? I was thinking doing it this way, but dunno if the variable just points to the list or if it copies the list. Either way is okay I guess, but if it copies the whole list I'm just taking more memory for no reason..

You just reference the same list in memory with a new variable name.
Thats always what you do in java
I dont get it, why it doesnt print any parameter when I provide it?
What is the command you use and what is being printed out?
okay it does, my bad, but I get "input must not be null" exception
How are teleportation requests usually handled?
Could I do this? Is that efficient?
private HashMap<Player, HashMap<Player, Integer>> teleporters = new HashMap<>();
Player is a player who recieved a request
HashMap<Player, Integer> is a player that sent the request to the player, also the Integer for scheduler runTaskTimer that counts down the teleportation request seconds (eg. expires in 120 seconds)?
good idea? any way to do this differently?
You don't need to store a ticking int
Just store an end time
also keeping a reference to the player object isn't ideal
try to avoid that
I'm thinking of uhh
Use a pair or tuple
can I put pair in a pair?
ohh
Hashmap<uuid, pair<uuid, integer>> or
Hashmap<uuid, teleport request class or record>
I'll probably use UUID I think
yeah
looking good
thank you
I might make a class for it
Would be cleaner..
Yeah no point having a collection for something that is always 1 element
public class TeleportRequest {
private final UUID requestId = UUID.randomUUID();
private final UUID senderId;
private final UUID targetId;
private int ticksLeft;
public TeleportRequest(UUID senderId, UUID targetId, int ticksLeft) {
this.senderId = senderId;
this.targetId = targetId;
this.ticksLeft = ticksLeft;
}
getters and setters innit
}
private static final int TELEPORT_TICKS = 15 * 20; // 15 seconds
private final Map<UUID, TeleportRequest> requests = new ConcurrentHashMap<>();
public TeleportRequest createRequest(UUID senderId, UUID targetId) {
TeleportRequest request = new TeleportRequest(senderId, targetId, TELEPORT_TICKS);
this.requests.put(request.getRequestId(), request);
return request;
}
or whatever
this is just a solution
there are like 20 others
Thank you
whast on line 43
I mean you should check if the enemy name is valid
since this will also crash when you just typo
and I would put the getString part in the actual enemiesconfig class
so you dont have to worry about deserializing the data every time, but only in the place where you actually store it
maybe
and the enemy has a type, health, etc
okay
print the config
how do you know its reading the file correctly
why wouldnt it
So I would still need to wrap TeleportRequest with Map<> I guess? My idea was
*You need this request id if you want to get the request back from a clickable component for example
okay it prints all values as null
I see why
I put wrong config in dependency injection
public Collection<TeleportRequest> getIncomingRequests(UUID playerId) {
return getRequests(request -> request.getTargetId().equals(playerId));
}
public Collection<TeleportRequest> getOutgoingRequests(UUID playerId) {
return getRequests(request -> request.getSenderId().equals(playerId));
}
public Collection<TeleportRequest> getRequests(Predicate<TeleportRequest> predicate) {
Set<TeleportRequest> requests = new HashSet<>();
for(TeleportRequest value : this.requests.values()) {
if(predicate.test(value)) {
requests.add(value);
}
}
return requests;
}
public TeleportRequest getRequest(UUID requestId) {
return this.requests.get(requestId);
}
something like this
You didn't have to do this I really appreciate it xD
how can I set enemy health above their natural health?
how should modifier look like?
I dont get it
AttributeModifier myModifier = new AttributeModifier("extra-health", 25, Operation.ADD_SCALAR) or whatever
qq why does both
player.damage(value, player2)
player.setLastDamage(magicEvent)
and
player.setLastDamage(magicEvent)
player.damage(value, player2)
return for DeathEvent::getEntity().getLastDamageCause().getCause() ENTITY_ATTACK? Shouldn't at least one of them return MAGIC?
or does that only work if i remove player2?
can I just set health to flat 400 for instance?
or do I need to know mob's base hp?
no, setting health higher than maxhealth gives an exception
but with this method
Hello, I wanted to know how I could obtain multiple paths this way:
in that way
like that?
try it
hm setting the last damage cause to EntityDamageByEntityEvent with MAGIC and calling player.damage(double) returns a EntityDamageEvent for some reason
is there a simple way to check 'yes, this code caused that death' or is my only option to throw a double in it that'll never occur naturally?
how can I round a float to like 1 number after , ?
thanks
If you're doing this for user output (i.e. a chat message), consider a DecimalFormat
yeah it didnt work well
it gave me 2 numbers after comma
but after a few hits
it became this
double hp = 2.34568;
DecimalFormat f = new DecimalFormat("##.0");
string hpRounded = f.format(hp);
this should work
yea doubles are dumb
btw choco do u have xp with custom damage?
im having issues with the events
@storm crystal
Keep the decimal format as a constant though please
Doesn't need to be rebuilt every time
ill take your lack of response to my question as a no then lol
Not sure what you mean with custom damage
You could use item attributes or just the damage event to change the damage calculation
oh
but it just tells me 'Have an EntityDamageEvent'
Could assign some metadata to the player if you'd like and check it in the event
Could someone tell me how I can create a for to go through a list with this?
slots = config.getConfigurationSection("slots"); slot = slots.getInt("slot"); item = slots.getString("itemType");
yea but how would i know that that metadata is still correct?
Assign a timestamp to it
If the timestamp exceeds 5 seconds or something, discard
no no its only relevant in the same tick anyway
cuz yknow either u die or u dont
good idea
a player can only take damage from one source per tick if you set them invlun, correct?
Unsure what the default invuln ticks are
like
it just needs to be mroe than 0
if i call player.damage twice, would it damage them twice? in the same tick i mean, thats what im worried about
I suppose it depends on what your config looks like
Cancelling piston head movement
after a few attacks it still becomes like that
number.000004 for example
okay I just forgot to format it in enemy name
now it works perfectly
I think ill have to rewrite this plugin though
since I made it specifically for already existing mobs
and now I just remade it for custom ones
so its kinda messy
yall i got the weirdest dupe glitch ever
so i want to drop iteps past a threshold when an inventory is closed
works fine but if items are in the inventory it dupes the items in the inventory
im assuming my code runs first, drops the items, then the event finishes, doesnt use the changed inventory, and resets it to full + whatever was in the anvil slot
anyone an idea how to bypass this?
like if possible without a 1 tick delay
@ivory sleet iirc u helped me with this before but it could've been any other of the orange/pink people
what exactly lol
can u dumb it down
so i want to limit items in inventory to set caps on stuff like golden apples
for some reason when i remove items from the player inventory to drop them when closing an anvil, it dupes the item, and it looks like the event just ignores the changes i made to the inventory and overwrites the player inventory
it only happens if there are items in the anvil slots, so it must be something with what the event does when adding the items back to the player inventory
@ivory sleet
hm ill check if removing the items from the anvil during the event might do it, if it doesnt, ill come back
how to use that bottom bar above your inventory to show messages to player?
like here on Hypixel
Is that not just the item's name?
i'm not sure but i think it's called ActionBar
yes
Player.sendActionBar()
The action bar is the top message (mining & the percentages). The one below is just the item name afaik
At least that's what it looks like to me
Choco could you see my thread? https://discord.com/channels/690411863766466590/1170522937913249842
Resolved, tysm â¤ď¸
Is it possible to remove description from items like potions?
IIRC you can ItemFlag#HIDE_POTION_EFFECTS
if that doesn't work try using ItemFlag#HIDE_ATTRIBUTES
as that hides other stuff such as damage etc
anyone got any idea how I can do like a styled code block inside a markdown html section
it's just shitting the bed
That in javadoc?
no
or html in general?
markdown
oh idk about markdown. Where is it
that's basically it
writing a new one
this is a big one
might post here over multiple messages
Maybe that'll help? https://www.jetbrains.com/help/hub/Markdown-Syntax.html#indented-code-blocks
O nice
nah it's fine I just ditched the spoiler blocks
imma post it in discord too
will probably do it over multiple messages
Its 5am i probably wont be here when you post it. Ill wake up at 2..3 pm again lol
But ive finished the teleportation functionality
create your blog and post it there xD send a link here afterwards
im working on mine locally, then ill just upload it to the server
just making a markdown copy of my search index
one day
you have to do it on a new line
âââjava
code
âââ
breaks in another way
huh..?
it shouldnt lmfao
make a new repo go to readme and put that in and itll format for you
still brokey
trust me I tried
I just gave up on it
and the new solution is discord friendly
iâm literally looking at code using that rn
that code works
mine doesnt
I have no idea why
just trust me it's fine
ILLUSION SEARCH INDEX - Good Habits (Click me)
Don't nest, use guard clauses
When writing multiple checks, rather than nesting, aim to apply guard clauses in order to keep your code as flat as possible.
Non-compliant code:
public void doSomething() {
if(myConditionOne()) {
doSomethingFirst();
if(myConditionTwo()) {
doSomethingSecond();
}
}
}
Compliant code:
public void doSomething() {
if(!myConditionOne()) {
return;
}
doSomethingFirst();
if(!myConditionTwo()) {
return;
}
doSomethingSecond();
}
When naming variables, use descriptive, intuitive names:
A common mistake is to use short names for variables, such as "p" for player, or "i" for index. This is bad practice, as it makes your code harder to read and understand. Instead, use descriptive names, such as "player" or "index".
It's fine to use a single-letter variable name depending on context. It is common to see i used in for loops, x, y, z when dealing with math and catch(Exception e) blocks.
Non-compliant code:
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
Player p = e.getPlayer();
p.sendMessage("Welcome to the server!");
}
Compliant code:
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
player.sendMessage("Welcome to the server!");
}
Re-use variables when possible:
Many common methods will return a new object in every call, a few common ones are:
- Player#getLocation
- Location#getBlock
- ItemStack#getItemMeta
- Enum#values
Following this practice will also result in cleaner code, with the added bonus of being more performant.
Non-compliant code:
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
boolean standingOnGround = event.getPlayer().getLocation().getBlock().getType() == Material.GRASS_BLOCK ||
event.getPlayer().getLocation().getBlock().getType() == Material.DIRT;
if(standingOnGround) {
event.getPlayer().sendMessage("You're standing on grass or dirt!");
} else {
event.getPlayer().sendMessage("You're not standing on grass or dirt!");
}
}
Compliant code:
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
Location location = player.getLocation();
Block block = location.getBlock();
Material blockType = block.getType();
boolean standingOnGround = blockType == Material.GRASS_BLOCK || blockType == Material.DIRT;
if(standingOnGround) {
player.sendMessage("You're standing on grass or dirt!");
} else {
player.sendMessage("You're not standing on grass or dirt!");
}
}
Avoid repeating collections calls:
Map#containsKey and Map#get can be merged as Map#get and checking for null.
Map#keySet and Map#get can be merged as Map#entrySet and iterating over the entries.
Map#containsKey and Map#remove can be merged as Map#remove.
Map#containsKey and Map#put can be merged as Map#putIfAbsent.
Non-compliant code:
public void doSomething(Map<String, Integer> map) {
if(map.containsKey("key")) {
Integer value = map.get("key");
map.remove("key");
map.put("key", value + 1);
}
}
Compliant code:
public void doSomething(Map<String, Integer> map) {
map.computeIfPresent("key", (key, value) -> value + 1);
}
Perform the most performant checks first
When checking for multiple conditions, always check the most performant ones first.
Non-compliant code:
public boolean isApplicable(Player player) {
return checkBlocks(player) && checkInventory(player) && player.isOp();
}
Compliant code:
public boolean isApplicable(Player player) {
return player.isOp() && checkInventory(player) && checkBlocks(player);
}
(More below)
_ _
Don't expose mutable collections
When returning a collection, make sure to return an immutable copy of it, to prevent the caller from modifying it.
Non-compliant code:
public class MyManager {
private final Map<UUID, PlayerData> playerData = new HashMap<>();
public void setPlayerData(UUID uuid, PlayerData data) {
playerData.put(uuid, data);
}
public Map<UUID, PlayerData> getPlayerData() {
return playerData;
}
}
Compliant code:
public class MyManager {
private final Map<UUID, PlayerData> playerData = new HashMap<>();
public void setPlayerData(UUID uuid, PlayerData data) {
playerData.put(uuid, data);
}
public Map<UUID, PlayerData> getPlayerData() {
return Map.copyOf(playerData);
}
}
Follow SOLID and DRY principles
SOLID is an acronym that encompasses five simple principles:
Single Responsibility Principle
A class should have one, and only one, reason to change. A class should only have 1 role.
Non-compliant code:
public class MyListener implements Listener {
private final Map<UUID, PlayerData> playerData = new HashMap<>();
@EventHandler
private void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
PlayerData data = new PlayerData(playerId);
this.playerData.put(playerId, data);
}
@EventHandler
private void onQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
this.playerData.remove(playerId);
}
}
This example violates the Single Responsibility Principle because our class is performing two roles: Data Management, and Event Listening.
Following SOLID principles, we need to split this class into 2 classes, one for each role.
Compliant code:
public class MyDataManager {
private final Map<UUID, PlayerData> playerData = new HashMap<>();
public PlayerData getPlayerData(UUID playerId) {
// Feel free to check argument validity here
return this.playerData.get(playerId);
}
void handleJoin(Player player) {
UUID playerId = player.getUniqueId();
PlayerData data = new PlayerData(playerId);
this.playerData.put(playerId, data);
}
void handleQuit(Player player) {
UUID playerId = player.getUniqueId();
this.playerData.remove(playerId);
}
}
public class MyListener implements Listener {
private final MyDataManager manager;
public MyListener(MyDataManager manager) {
this.manager = manager;
}
@EventHandler
private void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
this.manager.handleJoin(player);
}
@EventHandler
private void onQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
this.manager.handleQuit(player);
}
}
Open-Closed Principle
You should be able to extend a classes behavior, without causing breaking changes.
Non-compliant code:
public class PetCreator {
public Pet createPet(String type) {
return switch(type) {
case "chicken" -> new PetChicken();
case "cow" -> new PetCow();
});
}
}
This example violates the Open-Closed Principle because it's not open for extension. If another project or module wants to register their own pet, they'd need to change the code.
To make this code compliant, we need to switch to a more functional approach.
Compliant code:
public class PetCreator {
private final Map<String, Supplier<Pet>> providers = new HashMap<>();
public void registerPet(String type, Supplier<Pet> supplier) {
// Feel free to check argument validity here.
this.providers.put(type, supplier);
}
public Pet createPet(String type) {
Supplier<Pet> supplier = this.providers.get(type);
if(supplier == null) {
return null;
}
return supplier.get();
}
}
Liskov Substitution Principle
Classes should be replaceable by their subclasses, without breaking the code.
Non-compliant code:
public interface Pet {
void spawnAt(Location location);
boolean isHungry();
void despawn();
}
public class BoulderPet implements Pet { // Literally just a rock
@Override
public void spawnAt(Location location) {
// Do something nice
}
@Override
public boolean isHungry() {
throw new IllegalStateException("Why would I be hungry? I'm a rock!");
}
@Override
public void despawn() {
// Do something nice
}
}
This code violates the Liskov Substitution Principle because it breaks code flow under normal usage, and must be refactored.
Reworking code to follow the Liskov Substitution Principle requires refactoring it with other principles in mind. I'll refactor it in the principle below:
Interface Segregation Principle
Make fine grained interfaces that are client specific. It is better to have multiple small interfaces opposed to one big one.
Here's a suggestion on how the code from the previous principle can be refactored:
public interface Pet {
void spawnAt(Location location);
void despawn();
}
public interface FeedablePet extends Pet {
boolean isHungry();
void feed();
}
public class CatPet implements FeedablePet {
...
}
public class BoulderPet implements Pet {
...
}
Dependency Inversion Principle
Depend on abstractions, not on concretions. You shouldn't depend on a specific implementation, but rather on an interface. This hides implementation details by providing a robust API, and allows you to define a boundary between API and implementation.
Let's rework one of the examples above.
Non-compliant code:
public class MyDataManager {
private final Map<UUID, PlayerData> playerData = new HashMap<>();
public PlayerData getPlayerData(UUID playerId) {
// Feel free to check argument validity here
return this.playerData.get(playerId);
}
void handleJoin(Player player) {
UUID playerId = player.getUniqueId();
PlayerData data = new PlayerData(playerId);
this.playerData.put(playerId, data);
}
void handleQuit(Player player) {
UUID playerId = player.getUniqueId();
this.playerData.remove(playerId);
}
}
Compliant code:
public interface MyDataManager {
PlayerData getPlayerData(UUID playerId);
}
public class MyDataManagerImpl implements MyDataManager {
private final Map<UUID, PlayerData> playerData = new HashMap<>();
@Override
public PlayerData getPlayerData(UUID playerId) {
// Feel free to check argument validity here
return this.playerData.get(playerId);
}
// This is hidden from the interface and only accessible through explicit typing
public void handleJoin(Player player) {
UUID playerId = player.getUniqueId();
PlayerData data = new PlayerData(playerId);
this.playerData.put(playerId, data);
}
void handleQuit(Player player) {
UUID playerId = player.getUniqueId();
this.playerData.remove(playerId);
}
}
public class MyListener implements Listener {
private final MyDataManagerImpl manager;
public MyListener(MyDataManagerImpl manager) {
this.manager = manager;
}
@EventHandler
private void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
this.manager.handleJoin(player); // Implementation detail
}
@EventHandler
private void onQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
this.manager.handleQuit(player);
}
}
With the example above, we've refactored the MyDataManager class to hide the handleJoin / handleQuit methods by applying Dependency Inversion. This allows us to expose all the getter logic without exposing sensitive join/quit logic where it's not needed.
Use primitives when possible
Autoboxing and unboxing is a process where the compiler automatically converts between primitive types and their wrapper classes (int <-> Integer). This process is very expensive, and should be avoided when possible.
Use primitives when possible, and prefer using unboxed classes when possible. (Int2ObjectHashMap, IntSupplier, Predicate)
Non-compliant code:
Map<Integer, String> map = new HashMap<>();
map.put(1, "Hello");
map.put(2, "World");
String hello = map.get(1);
Compliant code:
Int2ObjectMap<String> map = new Int2ObjectOpenHashMap<>();
map.put(1, "Hello");
map.put(2, "World");
String hello = map.get(1);
Override uneccessary methods
When extending a class, make sure to override all methods that are wasteful, such as fire checks for custom ArmorStand entities.
Only optimize what needs to be optimized
Pre-mature optimization can severely affect code readability and maintainability. As a general rule of thumb, when experiencing performance issues, benchmark and optimize what is actually slowing you down.
PSA: Always seek to improve your code
This guide is not a set of rules, but rather a set of guidelines. It is important to understand that there is no such thing as perfect code, and that there is always room for improvement. Always seek to improve your code, and don't be afraid to ask for feedback. A second pair of eyes can help you spot mistakes you might have missed.
they are both useful tho.
unmodifiableMap will refelct changes in the underlying map
the copy wont
Int2ObjectHashMap is not a fastutil type
Int2ObjectOpenHashMap is probably what you want
yet another fix
THe example for the most performance checks first doesn't really make any sense because in the and statement all of the conditions will need to be checked anyways right?
&& and & have a subtle difference when comparing booleans
Where if the first condition fails, the second condition doesn't run at all
Same with ||, if the first condition passes the second doesn't run
So in the case of player.isOp() && checkInventory(player) && checkBlocks(player);, the checkInventory method won't ever be called if player.isOp fails
Using the bitwise AND/OR (& / |) instead of the logical AND/OR (&& / ||) will result in both methods running regardless of outcome
Anyone know how to use the new PlayerInfoUpdatePacket for 1.20 (Protocol Lib)? Looking at the wiki, it's not to clear what i'm suppose to set, so any help would be amazing.
https://paste.md-5.net/kodorakibi.java there you go sry for being late đŚ
who know what the "getLocalizedName " in itemMeta? how is it different from displayName
It's either a key or translated
that isn't used for anything. its just an arbitrary string that can be set
hi
i have an error
and i don't know how to fix it
survival class code: https://pastebin.com/ye48P8vf
well
read the stacktrace
error points to line 32
the ide did warn you this could be null so you did the most braindead thing and wrapped with Objects.requireNonNull
9/10 chance the command isn't defined on your plugin.yml
Ok, so I need to delete not null from all commands?
Becouse all plugin is registered in the plugin.yml
"sprawdz" is not in your plugin.yml
I know how do use it raw
I don't really know what he wants to do
But for removing players I think there's a seperate packet now
Otherwise you just use the InfoAction enum
is there some way to distinguish growing crops like carrots and potatoes that have a well defined max growth stage to crops like cactus or vines or sugar cane
or do i have to maintain a list of such exceptions
declaration: package: org.bukkit.block.data, interface: Ageable
yea but not for all :d
thats the thing, sugar canes and vines and cactus are also all ageable
heck, even frosted ice is ageable
what does getMaximumAge of those return though
maybe u can use that
it might just return 1 for those idk
i think it does just return 3 because thats when they stop growing
but ill double check
ah ok so the max age of sugar cane and cactus is 15, strangely enough
that of frosted ice is 3 though
bamboo max age is 1 though
and that of chorus flower is 5
doesnt seem very consistent to me
that of weeping and twisting vines is both 25 but during growth stages this goes all over the place
i guess you'll need to keep your own list ;d
:(
which crops ru tryna target
just trying to make a generic farming skill, so just the stuff you can farm
but like look
whats the consistency in this lol
i have no idea lmao
Why do you need it then xD
the only consistency i can see is that it goes up and down based on even/uneven y coordinate
but thats about it
and i dont need it its just a weird ass thing i found while testing lol
?paste
Ahh alrighty
yea you'll just need to keep your own list of crops ur tryna target im afraid
i mean, its not that bad is it?
not that bad but it just means i have to keep a closer eye on what changes between updates
and i hate having to pay attention
you cant do that with generics no
gotta do some ugly workarounds for that
do these workarounds affect optimization?
as far as im aware no
Tag.Crops?
how do i check whats in the tag
ah nevermind ill just output it
yeah it doesnt have everything, like i'd also like to have berries and cocoa be in it
ill just go a manual list
Hey, any idea what this error is trying to tell me?
What are you trying to do
Sort the list of games by players
Like the amount?
Yeah, the amount of players added
I know it can be done with list.sort, but I wanted to expand on my knowledge with the Stream API
It doesnât know how to compare
Or what to compare
.sorted(Comparator.comparingInt(g -> g.players().size()))
Thank you
notably that has the lowest number at the front
if you only need the minimum/maximum there are special methods for that
Also, why does there need to be comparingInt instead of comparing?
you don#t
but comparing expects a Comparable
which means you'll be autoboxing the int returned by size for no reason
when comparingInt exists
Ah, alright. Thanks!
Husk is Zombie -> Zombie true
One last thing - how would one reverse the order?
Comparator.<Game>comparingInt(g -> g.players().size()).reversed()
notably this cannot infer the generic type of g because you chain it into a .reversed call
so you have to manually define it
?
Husk extends Zombie, so Husk is Zombie
oh
but
if i set husk tag to zombie one
it will create a problem as i have other functions depending on the tag
if (zombie instanceof Husk husk) {
} else {}
}```
this should works
Hey, can anyone link me to any good tutorials on using Mysql with spigot thank you
mysql does not have anything to do with spigot
I'm pretty sure there are tutorials for that tho
Yeah I figured that out, but if you want to add a player how would you do it??
How do I reset my stash password?
?support
Ask md
Ty
Hello! I'm trying to make it possible to launch a player in the air right now I'm using "setVelocity" and "new Vector(0, speed, 0);". And then make it so that when the player has ridden a certain number of blocks, the player will not ride up anymore but the player will continue to ride up. Is there any other way to do this because putting "new Vector(0, 0, 0)" looks very bad.
You're better off calculating a vector that will launch the desired height