#help-development
1 messages · Page 1275 of 1
good thing i did it before the full relese of the server to the public
when am i getting an invite to this server, ahah
whenever you want
dm
location generally has excess information for what you need to represent a location; specifically, it includes pitch/yaw
so two locations at the same location are not the same location if their "direction" is different
if that doesn't make sense to you, that's because it doesn't
if you don't need floating point precision for the coordinates, you can use Block as the key, just remember to clear the block references on world unload since they strongly reference the world they're in
if you don't need world information but need floating point precision, you can use bukkit Vector
for anything else you'll want to define your own class/record to use as key and implement hashcode/equals on it as desired
e.g.
public record Position(World world, float x, float y, float z) {}
any reference can be null
it if shouldn't be null you can annotate it with @NotNull which will on a best effort basis emit compile time warnings if you try passing something that is or might be null to it
e.g. @NotNull World world
i mean
world can guaranteed itself notnull in runtime?
for example when player leave player object can be null
so need use uuid every method args
you are mixing concepts a bit here but yes, the same principle does apply to worlds, though it is much rarer for worlds to not be present
so i need use world name then
for example if you try doing Bukkit.getWorld("myworldname") before a world named myworldname is loaded, it will return null
wolrd loading before onEnable
you can use UUID in place of World in the record, yes, that will be more robust
not?
hello
lol arl thenks
so if your plugin loads before multiverse and your world is loaded by multiverse, it won't be loaded yet
You can use compiler hacks like lombok or w jetbrains annots to enforce nonnullness (it injects checks)
Or you can use checkers nonnullness framework to prove that ur code isn’t null in certain parts
this is particularly catastrophic for serialized Locations because they're deserialized from your plugin config when you load the config, typically in onEnable, and if the world they're in isn't loaded yet, you will have a bunch of null-world locations in your config
But otherwise, almost anything can be null ilmir, Java sucks due to this
skill issue
120%
So ihave to think of all the objects in bukkit as ones that could disappear at any time.
no, that's not what null means
can you run papermc plugins on folia
Well not really, if a reference points to an object, it won’t magically stop pointing to that same object
and is folia better than paper?
somewhere there has to be a “ref = null” kinda thing
imo folia is snake oil
yea...
what is that supposed to mean
it's something you apply to a snake so its scales don't fall off
you'd think
folia can be better, if utilized correctly
jhmm
so do papermc plugins run on folia?
is that new?
no
Some do, most need to be modified since folia requires plugins to properly synchronize
weird
ah
maybe i was deserializing from json myself or something
so I'll just say on Paper
i ended up like subclassing it with PersistentLocation or something that'd hold the world UUID and do the Bukkit.getWorld call in Location::getWorld
If the plugin claims to support folia, that’s probably ur green flag
quite a few large plugins already do "support" folia
My server has 83 Plugins
Don't think most of them are gonna be supporting folia
“Support” 😭🙏
though i'm a little bit skeptical about how proper that support is, as things are very easy to get catastrophically wrong in a threaded environment
just because it compiles and you mass-replaced your bukkit.getscheduler calls to whatever entity scheduler folia added, doesn't mean it actually works as intended
Am I too dumb to understand or are you speaking 🤓 language
yes
Yea I mean its also hard as a plugin to not oversynchronize, as in keeping the granularity on ur locks balanced
He basically says, plugin devs == clumsy wizards => they dont support folia properly even though they think they do
ohh
alright
i.e. it will probably load and work for the most part but there could be for example dupe exploits introduced by the changes
You're in the development channel lol
right thank you
makes sense
this menu code might genuinely be some of the worst I've ever made
I might emulate all the logic to make it less ass ngl
I bet that'll make it even worse
nothing worse than 1000 lines of bullshit fuckery
I tried separating the actual contents from the display items and I broke the container synchronizer
what if it was 1000 lines of larky's bullshit fuckery
what the fuck
atp might be worth emulating
I've got no clue why commenting out the synchronizer code magically fixes all my issues
doing this the manual way is a huge pain in the ass
work on @remote swallow's farm and send me catpics daily
fts I'm not gonna do it that low level
just gonna make some button that emulates it
it's like 10 lines instead of 1000
How can i listen to a command being used?
declaration: package: org.bukkit.event.player, class: PlayerCommandPreprocessEvent
don't use it to make commands, though. For that use the CommandExecutor API
No, its to listen to a player getting op don't worry
if you're trying to restrict players from using commands, you're better off using a permissions plugin for that
No, its to give an item to the player getting op
I see, that should be fine then
Any ideas how i could get the player / args & the command name
you just get the message from the event and split by space
first element on the array would be the command name and the rest would be the arguments
is there the / in the message?
Is there any way to modify knockback for PVP?
Like say I want to make it so that there's more knockback (goes farther)
I listen to the PlayerVelocityEvent and set the event's knockback but this only works in PVE and not PVP for some reason
how do i get the value of a gamerule https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/GameRule.html
declaration: package: org.bukkit, class: GameRule
is there some method in server or world?
nvm think i found it
i assumed it would be in server but of course gamerules are per world so it is in world
makes sense
didn't paper make them per-world?
No
is there a way to check if a world has a gamerule
im trying to make something compatible with both the minecart experiments and not the minecart experiments
and GameRule.getByName returns a value whether the experiments are enabled or not
and world.getGameRuleValue does not return null if the world doesn't have a gamerule but instead throws an exception
Check the FeatureFlag
hm
Specifically world.getFeatureFlags().contains(FeatureFlag.minecartthingy)
okay well what if I want to make this future compatible
assuming this will one day be implemented
i guess I can do world.getGamerules or whatever and do a linear search
but then I'd probably want to cache that somewhere
ugh
The feature flag isn’t going anywhere
I assume the deprecated ones are always included? Idk
hey so question, when i call this slash method, from a plugin that depends on a separate damage plugin, that damage plugin returns null when trying to create its own damage key. any1 know wassup? i have it saved as a dependancy in my pom.xml and and plugin.yml
oooor don't worry about trying to futureproof it and just update it when things change
the thing about the future is that it's unpredictable
whoops put the same image twice
are you shading it into your jar
90% of cases where you're trying to get another plugin's instance and it's null, you are either shading in that plugin's classes into your own plugin jar, or you forgot to include it in depends in your plugin.yml
remind me, how do I detect a right click on air?
no, i dont have it shaded in my pom.xml, im pretty sure
open up your jar and doublecheck
i don't remember if the client sends any packet for right click on air with an empty hand
seems like interactevent does according to docs
but defaulted as false
sorry cancelled I mean
you can try it but i'm not 100%
worth a shot I guess
yep i dont
and you have it listed in the depends of your plugin.yml
yep
check the logs and see if that plugin enabled correctly
yep it does
what happens if you try Bukkit.getPluginManager().getPlugin(pluginname) instead of that static instance getter
i mean you presumably can't change the code for DamageKey, but try calling ^ in your plugin and see what it returns
so i made an if else to check if its not null and apparently it isnt null
see if it returns true for isEnabled
then try getClass() on it and compare it to DamagePlugin.class
if you have the source code for that class or your ide can decompile it, check if the author made a boob setting the static instance field or something
wait no i made the plugin lol
then doublecheck it all the more
The client doesn’t send anything if you right click air with an empty hand
just create an empty item
But what if I don’t use a resource pack
Actually
Can you use air with custom_model
possibly
then fuck you ig
air isn't a model but a texture
but I do wonder
Technically it’s neither
technically it is a texture, rhetorically it is neither
ig the lack of a model counts as a model
ig the lack of a texture counts as a texture
well, there is a texture, no?
which is just a transparent png
for the item at least lol
it is enabled, but not the same as DamagePlugin.class
i dont actually know what that means tho
there is no texture for air
then I must be misremembering
Should work then
Also why does mcasset now have an ad
They did a redesign and now there’s a banner ad
interestingly the block model for air is also an empty json
But iirc Mojang told them they couldn’t run ads on it
🤷♂️
that means someone is shading it into their jar
I ended up going with this solution
since I'm pr-ing a plugin that supports back to 1.14
easiest option
but it litterally isnt in my maven-shade-plugin part of my pom.xml
maven shades everything that isn't marked as provided by default
are you sure you checked in your jar and didn't find the classes there?
like open it in winrar or whatever and physically look at what's inside it
ok im gonna double check again, maybe im blind
oh shit i am blind, there it is
it could in theory also be some other plugin including the class, you can call DamagePlugin.class.getClassLoader().toString() to see which plugin loads it i think
not relevant here since you found the shade but might be useful in the future
well now that i found the shade how can i remove it? i tried deleting it but it just came back up when i restarted the server
let's see your pom.xml
ignore the censoring
must avoid code duplication at all costs
nah i just didn't feel like putting the second two clauses a second time
er last two clauses
chatgpt has a problem with file pasting, apparently
<dependency>
<groupId>com.github.Somebodys-home</groupId>
<artifactId>DamagePlugin</artifactId>
<version>c0d40b42cf</version>
</dependency>
here is your problem
add a <scope>provided</scope>
the default scope is compile which means it will get included in the jar by maven shade plugin
provided means it will be "provided" by the runtime and not included in the jar
ok good news, i got it working but i do have a question
i updated some stuff about the damage plugin i was depeding on and when i changed the version and reloaded my plugin, the plugin was back in the .jar file. any reason why that happens?
Make sure you're using the plugin jar without a suffix
let's see your new pom.xml
and make sure you do mvn clean package, if you omit the clean, you may be including stale classes in the jar
So, when running code on a PlayerVelocityEvent (to alter knockback when it happens):
event.setVelocity(newVelocity);
does NOT work in PVP. works only with PVE.
but
event.setVelocity(new Vector(0,0.5,0));
WORKS FULLY ALWAYS.
Does anyone have any idea why?
newVelocity isn't what you think it is
newVelocity is a vector I have calculated and it says exactly what it should say
I take the original event's velocity, shrink it, and then set the events velocity to that
But in PVP, somehow the player will just take no knockback instead of modified knockback
Meanwhile zombies and skeletons etc. cause the correct amount of knockback to the player
Unless I manually specify a knockback in the code instead of calculating one... Then for some reason it works even in PVP
I don't understand
why is (0,0.5,0) ok but something more precise like (0.18674,0.2523,0.67362) is treated as (0.0,0.0,0.0)?
You probably have to delay a tick
And only with PVP... Otherwise both are fine
EntityKnockbackEvent
I'm gonna try to use that then
Apparently I don't have that
Was this added recently?
Define recently
Oh
I don't think I can do this actually. If I delay a tick, aren't I just letting the event run without me modifying the knockback at all?
But then won't the knockback packet have already been sent to the player?
Yes?
So you aren't modifying it because you can't do that after the fact
You can?
Knockback is just velocity
Sending another velocity packet a tick later will then update their velocity again
So after the player has started their knockback trajectory, you can just come back and change it? And it won't look jank?
Well, if it isn’t timed properly or there’s latency to consider, it may look jank
But if it is just the next tick then it might be just fine
I see
Unfortunately I think a lot of my players would notice, they don't have the best latency
Well there's also the chance that it just doesn't fix this at all
And if it does, then there's the question of "why does it need 1 tick delay in PVP but not PVE"
And the answer is probably that something else is wrong that I'm missing and the problem will probably still pop up again occasionally
Player knock back might be treated differently, let me get into my computer and check
I’m the meantime, it’d be good if you could make a MRE so we can try to reproduce it
(MRE = Minimal Reproducible Example)
Ah... I'm not sure I could make an MRE out of this but I know how to print variables that could possible narrow down what's going on.
Well
I can get something actually hold on
This is the plugin I'm trying to fix
My code cleans up a few things, but the bug happens in this plugin without code changes as well
Can’t you use the attribute for this
Did the attribute exist in 1.19
Yeah
Attributes exist... But I think by using them I would lose the functionality where if the plugin is removed and then you join the server it doesn't remember your previous attribute
Like it's permanent until you change it back
Oh
Hm
Ok
I guess I just need to figure out the math then
Use a multiplier operation on the attribute btw, don’t change the base
doesn't spigot expose transient attribute modifiers?
Interesting....
Ok this might be literally exactly what I need
Just need to find documentation on how to use 1 vs the other
That’s a thing? I don’t think we do?
i did a thing
would this give a player blindness for 10 seconds on respawn?
I’m trying to get world edit to work on realms but idk what to do. Help?
I cannot make a server, because my computer isn’t strong enough to run a server, so I have to use Java’s realms
So don’t ask me why I didn’t just make a server
why are you asking about realms here in spigot #help-development ?
I’m new and I can’t find a chat that seems to be what I’m asking for
okay, minecraft realms is vanilla, no mods, you cant host mods on realms
also spigot runs plugins and not mods
but you can get world edit for spigot
I thought it was a data pack
My friend sent me this https://dev.bukkit.org/projects/worldedit
Do plugins not work on vanilla ?
They do not
Shit
thats a plugin
No
That’s 10 ticks not 10 seconds
ohhhhh
Thanks for the help, though.
so i would do 200 ticks (10 seconds) then?
Yes
?scheduling
btw i do have instant respawn on
like so?
i feel like ive done something wrong
because DreamDeath is underlined red
brb going to make waffles for friends bday
ping me when replying please 🙏
An instance of your plugin
you need to put your plugin's instance there
aka, an instance of the class that extends JavaPlugin
if that is DreamDeath class, then you either pass the instance around in this class's constructor or make a singleton
dependency injection approach:
public class DreamDeath extends JavaPlugin {
@Override
public void onEnable() {
new YourEventListener(this);
}
}
public class YourEventListener implements Listener {
private final DreamDeath plugin;
public YourEventListener(DreamDeath plugin) {
this.plugin = plugin;
}
@EventHandler
public void onDeath(PlayerRespawnEvent event) {
Bukkit.getScheduler().runTaskLater(this.plugin, () -> {/* do stuff */}, 1);
}
}
Singleton approach:
public class DreamDeath extends JavaPlugin {
private static DreamDeath INSTANCE;
public DreamDeath() {
INSTANCE = this;
}
@Override
public void onEnable() {
new YourEventListener();
}
public static DreamDeath instance() {
if (INSTANCE == null)
throw new IllegalStateException("Plugin isn't loaded")
return INSTANCE;
}
}
public class YourEventListener implements Listener {
@EventHandler
public void onDeath(PlayerRespawnEvent event) {
Bukkit.getScheduler().runTaskLater(DreamDeath.instance(), () -> {/* do stuff */}, 1);
}
}
hi sorry i got to go, ill try working on it tomorrow!
thanks tho
multiply it to ticks
10 seconds = 10 seconds * 20 ticks / second = 200 ticks
You need to pass 200 ticks, and also you might have to do it in a scheduler because the player object might not be valid for a few ticks
Hi I'd like to customize the appearance of the GUI by applying my own textures I’ve been working with the GUI code but haven’t found a straightforward way to integrate external images or textures into the interface elements.
Is there any way to apply custom textures to GUI components? If so, could someone point me in the right direction or provide an example of how to do it?
I made this post a while ago about the topic
this is look so difficult
is there another way?
like API?
no
it just looks difficult but it is actually not that hard to get the hang of
Is there a more efficient way of finding an item in a player's inventory and modifying it (its lore) than iterating through all the inventory slots and finding it. You cannot store them in a collection because they will get added to the inventory as a copy anyway. This is needed because ofc we'll have more players at the same moment to modify the items. (all players have the same set of items that need to be modified). I don't want to re-add new items because of the adding animation.
What have you tried?
My idea was to not let the items out of a specific slot thus knowing the location. It ig works but I hate the idea.
Can you come up with any other solutions?
I could do some hashmap weird index stuff
Would the complexity of it outmatch looping over 45 items?
Map<String, Integer> that maps item types to their current slot positions would work?
String 
O(1) time execution would be ideal but I don't think is possible without really weird stuff
if I put this in a command block it doesn't work
give @p minecraft:diamond_sword{Unbreakable:1b,Enchantments:[{id:"minecraft:sweeping",lvl:1000s},{id:"minecraft:knockback",lvl:1000s},{id:"minecraft:fire_aspect",lvl:1000s},{id:"minecraft:mending",lvl:1000s},{id:"minecraft:sharpness",lvl:1000s},{id:"minecraft:looting",lvl:1000s}]} 1
Idk it just hurts me to have 16 * 5 players having 45 slots checked concurrently
I don't recall if you can do it in spigot but in the other one you can check PDC without getting the item meta
It's a bit more performant
If you care about updating things in a chest you'll still need to track it
At least this is how I do it at work
Thanks I'll check it out
what HUD element do you offset for those 3 slots on the right there?
LOL
Ig indexing is much better. You see O(n) approach would be even worser due to the fact that I need to look for 8+ items per player
you can index the inventory once and then look for the items but that's needlessly complex for just a getPDC -> getItemId -> do whatever
- dupe potentials when dropping items
you can do it in stages
loop through inv -> map out item ids to slots -> get item ids at slots -> update them
but that's not faster than just updating as you find
public interface ItemProcessor {
Optional<ItemStack> process(ItemStack input);
}
Use the optional to prevent updating the gui
True computer scientist
you could not imagine how many plugin developers dont look at optimizations in the long run
How much?
we're looping over 45 slots it's nun crazy
tracking each individual item will cause so much cpu overhead
i mean i've seen many plugins do shit which just looks like it wasnt planned for servers with more than 50 concurrent users, but it makes sense why they stay small
not the case here
doing IO in the main thread and saving all the player data to a single giant .yml file is not what we're talking ab
Inject an item with a tag with PDC (each item has different id), do iteration once per player and check the ids of items, if we finish early -> break
gang.. i know that.
I meant, being mindful on time complexity is not something I've seen much of witth plugin developers (with exceptions of bigger names)
public void processPlayer(Player player) {
PlayerInventory inventory = player.getInventory();
Map<UUID, Integer> itemsForProcessing = new HashMap<>();
ItemStack[] contents = inventory.getContents();
for (int index = 0; index < contents.length; index++) {
ItemStack item = contents[index];
if (item == null || item.isEmpty()) {
continue;
}
UUID itemId = ...;
if (itemId != null) {
itemsForProcessing.put(itemId, index);
}
}
if (itemsForProcessing.isEmpty()) {
return;
}
for (Map.Entry<UUID, Integer> entry : itemsForProcessing.entrySet()) {
UUID itemId = entry.getKey(); // You can replace the UUID with an itemstack or something, or just contents[slot]
int slot = entry.getValue();
}
}
in most cases it just doesn't really matter
Premature optimization is the devil and you shouldn't worry too much about it until it become a problem
wise
If I'm scanning millions of blocks I'll worry about performance, sure
if I'm looping over 45 slots once in a while I really won't care
Especially when we're only talking about 16 players
would be worse at 50x that
and even then it's probably fine to do it async
Your example would need to check for slot changes no?
No enhanced for loop? :(
we need the index
run it once in a while
type shit
Wouldn't that be less efficient than iterating once when needed.
shit
So I think I have 2 options:
- iterate once per player when needed (easy)
- track indexes
sure go ahead
call it whenever
Nice, thanks for help
it can be actionbar texture, just i guess
@drowsy helm what is map mean?
So, how is it done?
So what exactly is this method I hear you asking? Simple! Unicode textures.
Minecraft supports a character system called unicode, this allows us to map a texture to a character within the unicode range.
Minecraft resourcepacks allow us to map these textures through the default.json file within the fonts directory of a resourcepack.
Note: This can be done outside of default.json but for our purposes we will keep it simple.
Map means to connect things together basically.
Connect A and B
So what he means there is, use a sample Unicode character, and associate a texture with it through the font
sorry i didnt respond, but its the same thing but with the provided scope declared
to display entity movement on 1.20.4 client, i use ClientboundMoveEntityPacket.Pos. but it just add move distance to the position previous one,not sync position.server sync position to client after i hurt the entity only.i want to know which packet that server using to sync entity position to client?
is it using ClientboundSetEntityDataPacket and package SynchedEntityData in a list,then send it to client to sync position?
where can I get the spigot api to make my plugin?
you can with maven or gradle
<repositories>
<!-- This adds the Spigot Maven repository to the build -->
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<!--This adds the Spigot API artifact to the build -->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.21.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
this for maven
Does anybody has any good packet learning tutorials with protocollib?
PlayerCommandSendEvent is only fired on player join right? So... what if I want to dynamically update an available list of commands during the gameplay? How would I do that
oh boy
the Pos packet sends relative movement, not absolute
Entity metadata has nothing to do with position, look for any "entity teleport" packets
I made one back in the day but it isn't really that great. What would you like to know? I'm noticing a trend in people switching to PacketEvents as protocollib has been buggy and "outdated"
look for the syncCommands method, might not be present in spigot
huhh thank you very much
or updateCommands or something
I'm trying to create scoreboard packets that will display in the sidebar
that is perfect
I have 0 knowledge in packets so I basically want to learn
I don't see why you can't do it without the API
using nms?
yeah i need it because player ranks can change during the gameplay and with that permissions change too
spigot's scoreboard system
i have made PlayerGroupChangeEvent so i'll call it in there
I have 2 different plugins that both use scoreboard and they collide
they don't work together
waittt but how does updateCommands() work exactly? does it read plugin.yml command permissions? and based on .... whatt???!!? does it call the event again?
Right now I do that
basically
I tried to use teleport packet, but the entity seemed to twitch during movement, so I gave up using teleport packet and switched to using relative movement packet instead
It resyncs brigadier commands
should be used when, for example, you update the command map
Is it possible to listen to packets without using external libraries ?
and, I'm using eclipse, how can I build my plugin?
Yeah just do what the libraries do and hook in to the netty channel
Not worth the effort though
yeah.... but how can you retrieve the command map, current commands available to the player? at runtime.. not on join
and modify it exactly as you want?
Bukkit.getCommandMap
the libraries have to do it somehow
(with nms and injecting into the netty channel)
is that per player?
ohh. i though it would be simpler... because i have made this.. and i though that i could just update the list of commands in here?
this is just a sample... yeah.. how the heck do you track that?
if i store the command map somewhere on join event, i can't modify it later on
can i
but i've tried this and it didn't work... because i would need an actual method to retrieve the current command map for specific player
I think Eclipse is deprecated
You should try IntelliJ IDEA Community Edition
It’s not deprecated
"eclipse is deprecated" hits hard tbf
If you use maven, you just have to right-click on your project and click on run as > maven install
yeah I found how to do it
thx
now it works. PERFECT!!!!
you fucking what
Bukkit.getPlayer(playerId)
that's old code
you wrote it in the first place
I still do
why would I need to use the name instead of uuid
server isnt in offline mode
now it works
player.isOnline will always return true
really
who can make recource packs for minecraft
Don't post in all channels
getPlayer can take a UUID 😭
?jd-s
is it better to code spigot plugins in kotlin or java?
Realistically kotlin is a more modern language but java will result in better help
If you're a server owner and you decide to write your codebase in kotlin you're pretty much closing yourself to 80% of your potential candidates
ohh
so should i like code spigot in java
Ideally yes especially if you haven't mastered it
You can dabble in kotlin but you'll usually be on your own
i mean i know java pretty much coded many plugins in it but new to kotlin
write Scala
what
i did not stutter.
Clojure or gtfo
Me and the boys do plugins in jython 😎 💪
Anyone here able to give advice on a server running slow? I have a sparks report
well it would probably help if u sent said spark report
also this is for plugin development [mainly] so unless u think its ur own plugin slowin down, #help-server
doesn't private constructor in this case violate open-closed principle?
public class Foo {
// imagine `bars` is a variable which is really internal collection which shouldnt be mutated outside, but could be inside of this class.
private final Collection<Bar> bars;
protected Foo(Collection<Bar> bars) { // which one should i choose: public, protected or private?
this.bars = bars;
}
public static void create() {
// Special logic goes here before creating foo.
return new Foo(new ArrayList<>());
}
}
protected seems like a compromise for future code extensions, but now you have responsibility to keep this constructor alive for people who are subclassing this externally
public is like fuck the safety, we're going C route
private kinda breaks open closed principle if you think pragmatically
maybe, but who cares
maybe it needs to be broken for the class to make sense
like singletons
the curse of overengineering
for me
software engineering is full of paradigms that are broken and contradictory to each other
yes
because different problems require different solutions
there are no 5 rules you can write for software that can always be followed
What would curse of binding 5 entail
i would say the biggest problem for me personally is expect what future holds for the code
i can write code that just works for today but i dont know how much tech debt that code might incur in the future
that's the most painful of engineering for me
yes
thats probably the hardest thing ever
because its always changing
requirements are always changing, your own experience and ways t do things are always changing
my code from like 1.5 years ago looks ass
but my codebase is never big enough for it to be a real problem
refactoring should be a big part of the normal programming flow
sadly
nooo not sadly, it's what guarantees me a salary :kekw:
haha exactly, and thats the other side of the equation 😛
hate refactoring because of the idea that it takes time that noone has
but funnily enough usually the codebase that got scrambled together the fastest has the longest refactor time
i feel like this can never go wrong if you provide factory methods anyways
full encapsulation is rigid imho
and doesnt adapt to the context of class use
The only way to guarantee pure immutability is to make the variable private and copying the list into an immutable collection in the constructor
its like with react components too, you have component which needs specific margin on the element to position it correctly
its either you dump full encapsulation and add class attribute which allows you to inject custom css classes on top of already predefined classes in component
or you wrap component in a separate <div> container with flexbox and gap. but that essentially bloats the html structure with useless notations
the factory method might just sanitize inputs
make the constructor protected if you plan on having the class extended, make it private (and the class final) if you don't
or just make public and dont bother
then skip the static factory method entirely
why? what if its specific implementation of class i want to reuse somewhere?
with specific dependencies
then you apply dependency inversion and yeet the factory method to the interface
make a skeleton class with a traditional constructor
Use the factory method to pick the impl based on the parameters
best of both worlds
public interface ElementContainer extends Iterable<Element> {
...
static ElementContainer create(Element... elements) {
...
}
static ElementContainer create(Iterable<Element> iterable) {
...
}
}
public abstract class SkeletonElementContainer implements ElementContainer {
protected SkeletonElementContainer(...) {
...
}
}
look at List.copyOf for inspiration ig
it is usually pointless to worry about this unless you're working with a team
whatever tech debt one might incur from code they make themselves is manageable enough when they're already proficient enough with the language
the rest is just understanding the problem space and understanding what needs to be adapted in order to continue expanding that space
and to understand the problem space, you just have to code your way through it, no better way than that
because when a player change his username uuid keeps same iirc (if online mode is true)
I mean the open closed principle is like “closed for modification but open for extension” I don’t follow SOLID rigorously, but I have done it in the past, and my experience with that principle is that its a perspective trying to ensure reusability and independent redeployment. Let’s say you’re running a microservice architecture with many smaller jar files that have the ability to be independently redeployed w/o recompiling ur entire system.
On another note, I think its important to consider scope with this principle, seeing as private would only allow extension within the same class-file, and as u are aware sometimes public is used to provide visibility for testing.
But to answer your question, no it doesn’t- at core object oriented programming was a bout sending messages from sender to receiver, depending on the receiver type, the message may be interpreted one way or another (polymorphism). This in conjunction with procedural programming where we emphasize the scope of our code components, reusability by isolation and abstract away global state and data.
oh hey im also working on a UI framework rn
but for the client
its really fucked
Aren’t there some good gui libs for the client
i wish i could do math on Number objects
purple made a NumberWrapper class that does all that shit super quickly
Who's purple
idk
my dog
your dog is purple?
PlayerInteractEvent only works for RIGHT_CLICK_BLOCK and not LEFT_CLICK_BLOCK
If I left click the block with the axe, isn't that supposed to be LEFT_CLICK_BLOCK? or maybe its considered block breaking? because I'm in creative and it instantly breaks the block?
PlayerInteractEvent doesn't even fire if I left "click" the block with the axe..
doesn't even work in survival
what's the code
even if it is considered block breaking, it should trigger an interact event
don't crosspost
does anyone know how to apply custom enchantment ? Right now, I have the GUI working and I can detect the item and the click event, but I'm not sure how to properly apply a custom enchantment
What mc version?
They changed it recently
1.21.5
if the enchantment has been properly registred, you'd get the enchantment from the registry and then just apply it like any other enchantment with ItemMeta#addEnchant method
with the registry being Registry.ENCHANTMENT
they're looking to apply one, not to register it
it's working with advancedenchantment plugin?
wait, are you developing a plugin?
Because if not, then this is a question for #help-server
Given that they dont know how to apply it. Im assuming they done know how to register it either
yeah i'm developing plugi
I mean you can just use a datapack for the registration and hope it works lol
just use their API if you're using their plugin to create enchantments
yeah i'm a little bit confuse about import this api
i don't know how to import this one to my build.gradle
it's different from other
what did you put in your build.gradle
is the jar in the libs folder?
and did you reload gradle
the class seems to be AEAPI, not sure where you got AdvancementEnchantmentsAPI from
I smell AI-generated code 👻
just copy whatever is in their wiki
it's red
then import it
thank!
maybe he saw "AEAPI" and figured to expand the acronym lol
but uh---- maybe also ai
probably
well, I can't fault anyone for trying to use AI in this case, but if there's a wiki available then at least copy it into the prompt so the AI has any idea what you're on about
How would you sync inventories between servers connected via velocity? Make it a velocity plugin and request it from the old server, send it to the new one and then transfer the player?
Or Have it run on the server and save it to some database when the player leaves and hope its saved before it gets loded by the server the player transfers to
you're not gonna have a fun time if you decide to do this on the proxy
I thought so
can it even be done at the proxy level, I don't think you have an inventory information there
you do not
Then id need to hope the lock is created before the data is accessed
unless you send it through plugin messages or just lookup a database
Idk how quickly velocity does all that
not sure if plugin messages are ideal there
Yeah cause they dont have a request/response kinda pattern
anything that can communicate between servers should work fine
I'd probably just go for some message broker
I would personally just make velocity keep them at configuration phase till the database lock is lifted
yeah
But what if it takes more than 30 seconds!
But i think the time between the Client disconnecting and the check for that lock might be too short for the lock to be created
Idk how velocity does that
that's why you keep them at configuration phase
If they are transferring from server to server you can just delay the transfer
explode the current server
If they disconnect and reconnect you’ll have to hold them somewhere
isnt it possible to have an always-active lock and then just unlock it after saving the inv?
Hmm
would absolutely hate having to use a closed source API
a database operation like that should take a few miliseconds at best anyway
without taking into account latency
smart
Or message broker and update the inv as soon as a message comes, i think joining the world takes long enough so you cant dupe
have you considered existing solutions
No
there must be a cross-server sync plugin out there
ah well the only option that came up with google is premium so yeah
it is source-available tho, so you can take inspiration from it at least
I found husk sync but i would need it to be for fabric
But i guess i can take inspiration from them
Oh husksync is for frabrix
Compile it?
it works on fabric and spigot, yeah
disingenuous
if I am going to use it for a production server, I'll at least have the decency to buy the plugin
if it’s open source they clearly expect people to do that ¯_(ツ)_/¯
You pay for support
And convenience
I mean, if I am just a kid making a server for my friends, I can see why one would prefer to just compile it
but if I am actually using it in a server where I make money, I don't see any reason to not contribute to the project by buying the plugin, regardless of whether one needs the support
When one server goes down and the player leaves and joins the one that was down before, i need to save the inventory somewhere
I cant use a queue then
if a server goes down then you got bigger problems than the inventory I imagine lol
I'd just save the inventory periodically as well as on-demand when someone leaves/switches a server
True dev right here lol
is there perchance some form of event that triggers when a new day starts on a world? I wanted to avoid the plugin having to constantly check the world age
I don’t remember how to get there, but the world should already track time and I thought there was api to play with. That being said just make your own event and call it whenever
just check it every tick, no need to make it complicated
this is my old code from 1.20.?:```java
public static ItemStack setNBT(ItemStack item, String key, String value) {
net.minecraft.world.item.ItemStack nms = CraftItemStack.asNMSCopy(item);
NBTTagCompound tag = nms.w();
tag.a(key, value);
nms.c(tag);
return CraftItemStack.asBukkitCopy(nms);
}
well I believe the world does keep track of global time, but I wanted to avoid having to constantly check whether that time is now a new day
what are you using NBT for
my goal is to be able to write some key-value to the itemstack and retrieve it later (without adding it to the lore of the item)
why though, a task timer isn't expensive by any means
It’s not a very demanding thing, can check like every 10 ticks
you're better off using PDC for that
Even 1, like it’s really not even close to being anything bad in the sense of performance
?pdc
thanks
And also there is no event so you will have to track it yourself
me asf PRing a TimeTickEvent right now
I was gonna say
this is exactly what i was looking for!
Feels like that one’s not bad at all, and actually makes sense to have kek
There’s plenty of useless mojank approved api points
It'd be just a pretty way to make a task timer honestly
even worse considering it'd trigger for every world that ticks lol
Well I feel like if this were an event, time would be sync across all worlds yeah?
why would that be the case
time on world a isn't necessarily the same as world b, I could've created world b later in the server lifetime and they'll have inherently different world time
of course, you could sync them but that's often too meddlesome
A, so you’re not ticking every world + event doing god knows what with other listeners, and B, I just feel the event implies it’s a rather global tick event, what are we passing the event in the first place? And to my knowledge, if we’re passing and holding a world reference that’s just bad anyway so keep it lighter right?
Point a, you’ve essentially just made another player move event
Hi. Is there a way to track a moving entity with an end crystal beam? Set beam target doesn't seem as smooth as the beams look while tracking an ender dragon. Thanks.
I saw this, but would this still work for end crystal beams?
the post mentions both end crystal beams and guardian lasers
Cool. I'll look into it a bit further in that case. I appreciate the help.
tbf it doesn't seem to be doing anything special
just setting the beam target every tick should work as well
it does use packet for the end crystal instead of spawning an actual end crystal but eh, I don't think that makes any difference
uhm does anyone know why the enchantbook i get from my custom gui with ae apply enchantment from this snippet code: doesn't work?
` for (int slot : selectedEnchantSlots) {
EnchantmentData enchantData = slotEnchantmentMap.get(slot);
if (enchantData != null) {
enchantedBook = AEAPI.applyEnchant(enchantData.getName(), enchantData.getLevel(), enchantedBook);
}
}
inventory.setItem(COIN_SLOT, enchantedBook);
}`
I bet you enchanted the book instead of storing the enchant lol
You gotta use EnchantmentStorageMeta to make books work
idk what that means
i create a gui for put a scripture and then you can select an enchantment from gui and you will get an enchantment book
ask whoever made that thing then
it is a premium plugin so they should have some kind of support channel
no they won't
they have a discord tho
what's worse is that they don't seem to have registered the enchantment properly, otherwise you wouldn't have to do custom logic for the anvil
i made an inventory when you can put an item, when you clsoe it you get the item back. but when server is stopped it deosnt call the InventoryCoseEvent i guess?? when i start the server again the item is gone.
should i just close every inventory at onDisable() by iterating through all players?
you could do it at player quit rather than on disable
but I am surprised disconnecting doesn't call inventory close, probably a bug
consider reporting it to the JIRA
well, you can test it
yep
by logging that
it didnt print anything
not playerquit and not inventoryclose
its disabling my plugin first
then it says i left
xD
so no
that shouldn't be possible
the first thing that happens when one does /stop is players being kicked, not plugins being disabled
latest version?
1.21.5
if you are using Paper then you have to report it to Paper, no other way around that
i said im not
well then just report it to the JIRA
whhat is that
?jira
sure, that works in the meantime, but it is ultimately a bug for plugins to be disabled before the players are kicked
isnt that the same issue
what's the link
while the cause is the same, the resolution for that bug and yours is different
in your case, you'd be asking for the players to be kicked before the plugins are disabled, that way the events are called properly. While that bug report is asking to change the behavior of the plugin loader to allow for access to plugins being disabled upon shutdown
Hi , how to get requirement for sell plugins on spigot ? i mean what is the condition ?
?premium
why would you need to iterate through all the players if you created the inventory to begin with? do you not have a list of opened inventories?
then just itereate the inventories and close out your objects and call world.save()
how do i close inventory from inventory instnace
why world.save?
InventoryView#close
you shouldn't save the Inventory instance but the InventoryView since that's the actual opened inventory though
idk what kind of inventory you have, if you are making use of one that would save to the world then you need the world to save to preserve the inventory
so it closes this inventory for everhy player which has it opened?
otherwise you need to save your data
if 2 players open 1 inventory is it 2 inventoryviews?
could be, it all depends on how you open that inventory
no, its custominventory, its ment to disappear
i dont know ;c
no it is 1 inventoryview
if you open the InventoryView, then it'll be an inventory with 2 viewers, if you open the Inventory itself, then it'll create another InventoryView
^
🤯
anyways, you should be saving the inventories every so often
in case you can't do it at server shutdown
i need the player's inventory at the bottom
why would i use inentoryview??
reinventing the wheel go Brrrrrrr
what are you making.........
ignore the fact that its a cheat i just needed a codebase
was making a UI framework
mhm....
Am gaining so much respect for you
You should see my latest bypasses. mmmmm
I've lost count at how many UI frameworks for minecraft there are
they usually don't pass the test of time
if you can manage to maintain it over a long period of time, it should already be better than 99% of the ones out there
meteor has a nice UI. It’s not really a framework since it’s just dynamic entries done for each module with very little configuration. But it just looks clean
meteor the client?
Is there a way to disable the number shown above the xp bar (as if you were level 0) but still be able to use the bar as if you were a higher level (have more increments)?
(I'm trying to use the xp bar to represent other things and I'd like it to show many increments as if it was a high level xp bar but I don't want a number to show up above it)
✨ packets ✨
might do
yeah :/ any way without packets?
or you can get away by doing some resource pack funkery
not without resource packs, no
oh wait, I misunderstood what you meant, you can do it with packets, yeah
but no, not any way without packets
public void setPlayerExperience(Player player, float experience, int level, int totalExp) {
var packet = new WrapperPlayServerSetExperience(
experienceBar,
level,
totalExp
);
PacketEvents.getAPI().getPlayerManager().sendPacket(player, packet);
}
setPlayerExperience(player, 0.0f, 0, 0);
pretty easy with packetevents though
interesting- is packetevents a plugin/dependancy?
it is a minecraft library
you can check it out here, and here: https://github.com/retrooper/packetevents
yeah alr i'll look into it, ty
should calling player.closeInventory(); in onDisable call InventoryCloseEvent ??
cause it doesnt
?mappings
Compare different mappings with this website: https://mappings.dev/
what is that
it is a bug introduced by the automatic library support feature, you should just report and wait for it to get fixed, should be fairly fast
its basically a dictionary which translates mojang names for methods between different server software
if it is just for your server, you could do a quick patch yourself tbh
due to how mojang obfuscated their method names for minecraft server sometimes its very handy to compare them to see what it means
it should be just moving the statement that kicks all players before the plugin disabling logic
or if you're doing reflection stuff
not for my own
its basically google translate for NMS code
how where
if it is for a public plugin then just wait for it to get fixed
its for someone but they wont wanna wait soo
ill just do it manually instead of in the event
but i dont wanna save it ??
In vanilla native minecraft server Grindstone menu class is for example named: net.minecraft.world.inventory.GrindstoneMenu, but on spigot its net.minecraft.world.inventory.ContainerGrindstone
but was the link ment to ssave my problem ?
weren't you trying to save it since whatever item you were handling disappears?
I think they're talking about something different
no it was just for my use, i did call the bot for myself
lol 😄
just take the item, give it to player
and i dont need the inventory
anymoere
yep
but what do you mean they'll fix it? will i have to use buildtools to generate 1.21.5 spigot again ?
yes
well, rather. It'll get fixed if you report it
if you don't report it then it'll just go unnoticed like it has now
md usually picks up bugs like these pretty fast so that's why I am saying it should be fixed relatively fast but I don't know their schedule so it's all speculation
otherwise, it is a free PR
hey guys i am currently working on a civilzation server with 4 differnt contients like desert,jungle,snow and plains . i wanted to give one of these roles to a player joining for the first time and teleport them to their respective contitent . i have tried some plugins but it doesnt seem to work.can anyone help with a working method?
declaration: package: org.bukkit, interface: Sound
how am I supposed to use Registry.getKey
what is NamespacedKey
how does it convert to a sound enum
eg.: I want to parse a string into a Sound object
NamespacedKey is just a key with a namespace, i.e. minecraft:ambient.cave or whatever the sound is called
I don't remember whether sounds use dot or underscore but yeah
to get a sound by their namespace, you'd do it like this Registry.SOUNDS.get(NamespacedKey.minecraft("whatever"))
are you developing a plugin to do this? Otherwise this is a question for #help-server
oh sorry my bad
both
ambient.basalt_deltas.additions
well that's fun
but that's only because the biomes and entities have underscores in them
that makes things much more complicated
and takes time
how is it more complicated
i have to go through entire list of strings instead of suggested enum list
and check whether they have _ in it or not
i have to make some kind of wrapper for this
this is dumb
hmm
where can i find the list of minecraft... sounds?
i don't even know the format of the string
the wiki
minecraft:sounds.<sound name> ?? what
or iterate the registry
Registry.SOUNDS.stream().limit(10).forEach(System.out::println);
you can do that for example
it'd be more helpful if we knew what you were trying to do with the sounds
hm, but is it server jars fault?
cause if i do this manually, and then this will get fixed, tha thing will happen 2 times, 1 on onDisable(), 2. in the event
I'd consider it a bug, since you should be able to listen to some of these events even on shutdown
does it matter
so server jars fault
yep
well, that's ultimately up to MD, we won't know till the bug report gets marked as accepted
uhm
that's why I told you to report it
the sooner you report it, the sooner it'll get fixed
oky
I'm just trying to get the string from the config -> try to parse it into a Sound object -> play it to the player
I can't find anything on the wiki with the list of sounds
am i blind
then you don't need to gather any list of strings
or is there nothing
yeah
the article is literally called Sounds.json
and then every individual article for every entity and block has a list of sounds they play
On the minecraft wiki
i didnt even know this existed
if you're just parsing them off a configuration or something, then you can just do something like this:
public Sound getSound(String value) {
var key = value.indexOf(':') == -1 ? NamespacedKey.minecraft(value) : NamespacedKey.fromString(value);
return Registry.SOUNDS.get(key);
}
that's all you have to do to parse it
you may put a try in there for invalid keys but other than that, yeah
i was actually just looking at exp related stuff, https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/Player.html#sendExperienceChange(float,int)
declaration: package: org.bukkit.entity, interface: Player
Apologies if this isn't the correct place to ask about other plugins, but I'm experiencing the following issue using ProtocolLib:
[19:57:41 WARN]: Exception in thread "Thread-8" FieldAccessException: Field index 0 is out of bounds for length 0
[19:57:41 WARN]: at ProtocolLib.jar//com.comphenix.protocol.reflect.FieldAccessException.fromFormat(FieldAccessException.java:49)
[19:57:41 WARN]: at ProtocolLib.jar//com.comphenix.protocol.reflect.StructureModifier.write(StructureModifier.java:318)
[19:57:41 WARN]: at fireworks-1.0-SNAPSHOT.jar//com.dnamaster10.fireworks.ExplosionInstruction.execute(ExplosionInstruction.java:24)
[19:57:41 WARN]: at fireworks-1.0-SNAPSHOT.jar//com.dnamaster10.fireworks.ShowRunner.lambda$run$0(ShowRunner.java:98)
[19:57:41 WARN]: at java.base/java.lang.Thread.run(Thread.java:1583)
A snippet of the problematic code is as follows:
PacketContainer explosionPacket = new PacketContainer(PacketType.Play.Server.EXPLOSION);
explosionPacket.getDoubles()
.write(0, position.getX())
.write(1, position.getY())
.write(2, position.getZ());
explosionPacket.getIntegers().write(6, 3);
protocolManager.broadcastServerPacket(explosionPacket);
From what I can tell, my code appears to match that of the examples on the GitHub repository for ProtocolLib. Does anyone know why I might be getting an out of bounds exception for this type of packet, when the examples seem to be able to modify these values perfectly fine?
Thanks, and please redirect me if there's a more-relevant channel to post this question.
Edit: The error is being thrown for the first write call, write(0, position.getX()).
Check the packet's nms definition
it's likely you won't see any double fields
if you do protocollib L
hey so when i imported my custom damage plugin, whenever i try to use any of the methods in there i get this nomethodfound error. how can i be sure that the version of the plugin im importing is the same one thats being used by the server?
Do you have teh actual damage plugin in your server
or shaded if thats how it's intended
That error just means it's not in the current runtime
yep, its actually there
only other reason that would show is if you have an old dependency of that plugin and they have changed method names/package
nope, no name changes here
and it's 1000% loaded in and enabled on the server?
because that doesn't make sense
And you’re not doing any package relocations
does it have it has a dependency?
