#help-development
1 messages · Page 1165 of 1
whats the best way to send discord webhooks? i know theres a api for this but i want to understand how to do it myself (I want to send embeds too)
is there any way to get a hash (md5, sha,...) for a plugin file?
Something like this?
https://stackoverflow.com/questions/304268/getting-a-files-md5-checksum-in-java
not inside java, i'm trying to make a plugin auto update bash script, but i dont want to download a file that is already up to date
but yes, similar to that
looking for some http endpoint to fetch a checksum of some sort to keep traffic low.. i dont see such thing in spiget api
most linux distros come with the md5sum binary
that requires me to download the file first anyway
yes
rather certain that isn't a thing
modrinth has in its http api an attribute that contains file hashes, i'm looking for the same thing for spigot resources
Given that like, spigot has resources that are downloaded from external sites etc
for those, the hash could simply be undefined
well but it isn't 
yea its not because it simply doesnt exist 😄
lul
making http apis always comes with the duty to keep traffic as low as possible
i'm opening a ticket with spiget, maybe they can work something out
thanks
😅 I have my doubts, but gl
of course it would be unfeasible for them, because that would mean they have to at least cache each sum on the first request. imo it would be spigot's duty to implement such thing (or maybe even implement ANY sort of http api :I)
Welp, there is https://github.com/SpigotMC/XenforoResourceManagerAPI
check this library, its also compatible with all "full-size" discord bot libraries https://github.com/MinnDevelopment/discord-webhooks
hmm, i've seen this in the past but didnt get much out of it, i was getting trouble actually downloading files. spiget solved this for me
what are the "threads" mentioned here?
oh oh wait theyre discord threads
im gonna use this api but i kinda wanted to learn how to do them myself lmao
i tried looking at the code but its like 1k lines most files
if you're referring to this section, no those are normal java threads
I was reffering to this
yea youre right those are discord message threads
Is there a guide or anything out there on how to do this myself?
like how sending discord webhooks or whateve r works
my recommendation: don't. writing discord api isnt trivial
on the other side; webhooks are kinda not very complex.
if you really want to make a wrapper for this yourself, check out discord api documentation
thanks
i just wanna put it on my github ngl
Custom Player Heads aren't working anymore?
I came back to developing plugins using the SpigotAPI after about a year and all of a sudden none of my past code seems to work. Its throwing errors that dont even really make sense to me (for example: Caused by: java.lang.NullPointerException: Profile name must not be null)
you can use the playerprofile api
what do you mean? do you want to see my code?
sure
UUID uuid = UUID.fromString("b608ab5b-4253-3178-a6dd-9e943a42eb49");
Block block = chunk.getBlock(x, y, z);
block.setType(Material.PLAYER_HEAD);
Skull skull = (Skull) block.getState();
PlayerProfile profile = Bukkit.createPlayerProfile(uuid);
PlayerTextures textures = profile.getTextures();
try {
URL url = new URL("http://textures.minecraft.net/texture/a79f8c92776d642d119f9e92360b1e5b971e66e61428a3e1b311d8b6185e6");
textures.setSkin(url);
profile.setTextures(textures);
skull.setOwnerProfile(profile);
skull.update();
} catch (MalformedURLException ex) {
throw new RuntimeException("Invalid URL", ex);
}
}```
PlayerProfile profile = Bukkit.createPlayerProfile(uuid); you neec a name
does that take 2 arguments? or one?
back in the day it used to take in just UUID
oh damn i aint ever see that
if it was just one, now it's 2
thank you very much
no problem 😄
am i doing something wrong here?
the compression should work no?
i get null at decompress
compress seems to work, the length is 20
i'll read the contents to see if they got compressed
I have a question. I have two plugins. One plugin that serves as the core and one plugin that depends on the core.
Both are separate because the core is used on different servers and the other only on one server. The second (survival) depends on the core. Both run on the same server.
Both have the same command declared (in plugin.yaml as well), which is the config cmd. I want the main plugin to execute the core's command handler when I run the command and the first argument is core. However, if the first argument is survival, let the second plugin handle it.
I've already tried to make the first one return false when the first argument is survival, I tried with PlayerCommandPreprocessEvent and it still not working. Does anyone have any suggestions on how to make this work?
you need to have your core handle commands, and register new subcommands from the survival server
So, what you're saying is that I should just register the command in Core, register subcommands (how do I do that? I've been using the args to determine the subcommand), and put all the logic in Core?
you can use the PlayerCommandPreprocessEvent for sure for things like that.
you can also register a separate command for survival
but playercommandpreprocessevent is not the best option for handling commands i think
i use it to block commands with it
but having it to run commands seems wrong
it works very well but its complicated
it won't support suggestions for one
but it's not cancelling the event
package kvsilva.whalehound.whalehoundcore.Events;
import kvsilva.whalehound.whalehoundcore.Utils.Messages;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.plugin.Plugin;
import static org.bukkit.Bukkit.getServer;
public class CommandInterceptor implements Listener {
private Plugin survivalPlugin = null;
@EventHandler
public void onCommandPreprocess(PlayerCommandPreprocessEvent event) {
if(survivalPlugin == null){
survivalPlugin = getServer().getPluginManager().getPlugin("Survival");
}
Messages.log(survivalPlugin != null ? "different from null!" : "its null.");
Messages.log(survivalPlugin != null && survivalPlugin.isEnabled() ? "its enabled!" : "its not enabled.");
String[] args = event.getMessage().substring(1).split(" ");
Messages.log("arg[0]" + (args.length > 0 ? args[0] : " null "));
Messages.log("arg[1]" + (args.length > 1 ? args[1] : " null "));
if (args[0].equalsIgnoreCase("config") || args[0].equalsIgnoreCase("cfg")) {
if (args.length > 1 && args[1].equalsIgnoreCase("survival") && survivalPlugin != null && survivalPlugin.isEnabled()) {
Messages.log("cancelling it!");
event.setCancelled(true);
survivalPlugin.getServer().dispatchCommand(event.getPlayer(), event.getMessage());
}
}
}
}
the core is a message printed on the core plugin handler
am i missing smth?
survivalPlugin.getServer().dispatchCommand(event.getPlayer(), event.getMessage());
i think you cant run the command from there
it will reroute back to the core command i guess
ye, thats what its doing
but why you dont use this code in the sub-plugin and run the code directly ?
I was thinking of having the command registered in Core, and the command itself, depending on the first argument, would invoke a specific command.
For example:
/config core - Invokes /configcore
/config survival - Invokes /configsurvival
I just thought of this; I haven't tested it yet.
Create a PlayerPreProcessEvent for it and invoke the command there?
dont invoke, run the code you want to run in the command
i still think registering features into core from survival is the best idea
yes
But that wouldn't make sense for other servers, since in another server those features would all be obsolete, and the code would start to get confusing
well, a core is supposed to have features that are unused by some
and used by others
look at spigot api for example
most plugins won't use all the features it provides
but they are there and it makes sense
you can also shade the core into the plugin and during shade(i think) you can drop unused classes
Yes, but in general, it makes sense for anyone to use. However, if I create a gladiator system (just thought abt smth), putting it in the core wouldn't make sense, even though it would make sense to configure it with the command /config gladiator and use features from the core, no?
u mean create only one plugin, instead of having 2-3 and so on? and import the core into them and compile with it, instead of being provided on runtime?
you don't need to put gladiator into core, you just need to hook the necessary components that allows you to do /config gladiator something something
or i don't know
yeah
i have a game engine that i shade into my minigame plugins
instead of having a game engine plugin and a minigame plugin
the core makes sense if you wanna make multiple plugins on same server tho
I plan to create several "small" plugins that would then be used by Survival, and they would all also end up using the core
That's why I haven't combined them and compiled just one... but maybe that's the best option, or I could do that "routing" of the commands from /config core to /configcore and /config survival to /configsurvival lol
Sounds like survival should rather be the common module
what i do in core plugins instead is to make brigadier like command system in which then i can hookup command nodes through command registry
then it dynamically dispatches you proper autocompletion and you can do command argument injections externally
i fixed it, i had to flush and set the character set to utf 8
@lilac dagger Have you dealt with a particular system within a minigame where you had to handle individual turns?
like chess turns?
Yeah that works
i haven't, but it sounds doable
just disable whatever features you don't want your opponent doing on turn change
like give a ticket to a team
and pass it along
In the current impl, my thought was to just map uuid -> bool within the "round" object and track turns this way
ie: if(isTurn) {} kinda thing
My issue with this, is just how to dictate who should go first... in disc golf per hole it's based on whoever scored the best on the previous hole so I guess I have to implement some handling for this
use a list shuffle the list
remove from list if a team has been eliminated
and pass the ticket this way
keep track of current index in round
of who has the ticket
Hmm this would also differ between round types... doublesRound as compared to an FFARound would be a bit weird
@Override
public void handleStroke(UUID playerId, String technique, Disc disc) {
Player player = Bukkit.getPlayer(playerId);
if (player == null) {
return;
}
if (!this.turns.get(playerId)) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&4It is not your turn!"));
return;
}
PlayerData playerData = playerDataManager.getDataByPlayer(playerId);
PlayerSkills skills = playerData.getSkills();
ScoreCard scoreCard = scoreCards.get(player.getUniqueId());
scoreCard.trackStroke();
this.turns.put(playerId, false);
disc.handleThrow(player, skills, technique, player.getFacing());
}```
Like as an example, this method should really be "handleTurn" or something
I think the ticket idea is good tho
you can handle multiple turns in round as well
and if some teams have more than others you can track a getnumberof turns from team
you can extend round for this
MultipleTurnRound
So in an ffa round, (and this is just based off my irl experience) whoever wins the previous hole is first up to throw on the next... this is simple enough, it just gets a bit more complex in the doubles round as your team is scored as if you were one person, both of you throw and you take the better one etc... now that I'm typing it out the ticket idea works anyway so I think I'm just yapping at this point lol
yeah the ticket system should work in doubles as well, it depends on how you'll implement it really
It's the same I think as ffa round considering your team is scored as one person, just give a team the ticket and when all of the team has made their throws, pass the ticket
yup
is calling Damagable#damage(amount) on a player also including his armor as a damage reducer?
i never tried the method, you can test it yourself i think
just run it with and without the armor
see if damage changes
If you wanted to ignore the armor you could directly modify their health via attribute iirc?
I know, I WANT damage reducers to be applied.
yeah I will, the problem in NMS is that I cannot find where it is implemented!
why nms
follow the craftlivingentity
I feel theres enough api to do this no?
no no no
I want to look how it is done behind the scenes in NMS but I cannot find where this interface is actually implemented.
Ok, thanks.
@lilac dagger when you say ticket, would you make a ticket object and store with a team/player? And if so tracking the ticket, would you just check to see if a teams/players ticket is not null when it's their turn and then set it back to null after their turn?
a list and an index is all you need
you can make a ticket object too, but that's more work than necessary
i have something similar to turns here
Oh wow collections has a shuffle method for me ❤️
I was literally about to do that myself lmao
What do you mean sorry?
it means this way you don't have to check whatever you're over the list size
list.get(newIndex % list.size()) //This is the current team
Is this rather for safety or to get the team's turn index?
safety yeah
Ah gotcha
but it's not really necessary
it depends on the implementation
in your case you'll need 2 tickets, one for team, and one that goes through all members of the team
this inconsistency makes me mad, why does json allow fromJson to use a Reader parameter while toJson requires a JsonWriter
i guess they have to write to it in a specific way, but still
am i blind?
I don't see ServerboundInteractPacket
https://wiki.vg/Protocol
found it
now i have to figure out what type of information comes in before in the bytebuf
anyone knows, if i handle the bytebuf directly, do i have to also handle packets if they're compressed or not? https://wiki.vg/Protocol#Without_compression
i think i'll stick to handling the mojang packet instead
this is more work than i need for 1 single packet read
i'm pretty happy with how it is currently
late to the party, but why not just make an abstraction so that other plugins can register "extensions" to the config command in core
and please don't use the PlayerCommandPreProcessEvent for handling commands you own the code for
You're not that late because I was working on other things in the plugin, so that one was on hold xD
ye, im not using it + would be a problem because some of them must be the console
Have a example for it? 🤔 i will try to think in smth that helps me register sub commands in another plugin command
I mean, registering "sub-commands" in another plugin would be easy, you just have to delegate the handling to a Map<String, Handler> where the key would be the sub-command and the value/Handler would be whatever you want really, it could be a Consumer<CommandSender>, or a more specialized class which gives out more context about the command in question (i.e., the rest of the arguments)
then again, when you go down this route it means you're essentially creating a command framework so if you're not afraid of dependencies, I'd just recommend going for something like Incendo's Cloud command framework or Jorel's CommandAPI
That's actually funny because I've been working on creating the abstraction for my commands to validate arguments, permissions, whether they're optional or not, etc xD
given a complex enough command, one naturally finds themselves in that place, yeah
but I highly recommend these frameworks as they're battle-tested and work across a bunch of platforms
did that way ty 😄 and it works
I was curious is this possible in Spigot? If so with minimal spoonfeed would anyone help me figure this out this would be awesome for my server 
I’ve tried action bar and can’t replicate
they must be using a resource pack with custom fonts for that
Dannnng
doesnt wynncraft do that? so yeah its definitely possible with just resource packs most likely
Wynncraft has a huge custom pack, yes
It looks so vanilla even tho it doesn’t
I mean, resource packs are vanilla
I get what you mean though, they did match the vanilla style pretty well with that prompt
if I didn't know better, I'd have thought it was some bedrock edition feature
visual design is genuinely the hardest part of making something like this imo
at least for me
Ikr
eh, it is really not that hard lol
It is thooo
i think in numbers not colors
that one is literally just a black overlay
nobody starts being good at something
ok heres a better example of what i mean then
And im going broke paying people lol i wanted to code it lol
Custom tooltips were recently added in a snapshot
too much color, and the contrast with the gray font and the background is bad but the concept is good
eh, maybe not that much color, just the purple feels a little out of place
every other color there is pastel-ish but the purple
point is designing how shit looks is way harder than actually making it function cus theres so many different things to think about
anyway
you talking about 1.20.4?
I tend to disagree, since there's a bunch of tools for designing things like that, the workflow is good
I might just need to do an in chat dialogue system 🫠
no?
what snapshot then
making resource packs in the other hand, you got to do shit by hand, it isn't pretty
we arent?
theres snapshots of it
don't do chat, nowadays doing systems that make use of chat is annoying due to signed messages and what not
well, if it is a one-sided dialogue, then it is fine I guess
Its one sided
I'm using this method to get a short position for a MultiBlockChange packet for client side ghost blocks, but because of this i cant place blocks above Y-15. Using protocollib to send the packet, any way around this?
public static short toChunkPosition(Location loc){
int x = loc.getBlockX() & 0XF;
int y = loc.getBlockY() & 0XFF;
int z = loc.getBlockZ() & 0XF;
return (short) (x << 16 | z << 8 | y);
}```
is there a reason you aren't using the API method for the multi-block change
was not aware of it. Is it in 1.21?
declaration: package: org.bukkit.entity, interface: Player
been around for a while now
oh thank you! Il toy with it
24w36a
wtf
oh right thats the new texture thing
forgot about that
does it scale the texture based on tooltip size as well?
¯_(ツ)_/¯
Yes
how do i register a custom enchantment
use a datapack
simplest way to go about it
for servers
there is no API for it
so you'd have to play around with NMS to do it
hence why I recommend you just use a datapack, creating one shouldn't be that hard
if you want to do it with NMS nonetheless, here's a guide: https://www.spigotmc.org/threads/1-21-register-custom-enchantments.651347/
don't know if it has been updated or anything, but should serve you as a base
cant u extend enchant?
no
How do i make plugin when player breaks my shield with axe and they can't move or hit like radius 5 blocks
How can I remove the Message for a player?
You have no home bed or charged respawn anchor, or it was obstructed
when a player joins my server they are always sent to the world they last left at
is there a way to make sure they are always only sent to one world
without just tping them
Without using a plugin your options are either let them go back to the server they logged from or you have everyone start at the hub. Anything different from this you need a plugin
hehe, forg
wynncraft just shows their dialogue in normal chat dont they?
unless theyve updated recently
yes I can use a plugin
I was just wondering because right now I just tp them and its works but for a second theyre in another world
oh yeah I think ur right
Yeah I think Wynn still uses chat
But you can make those boxes with the action bar and some font magic
is tping them on leave not an option
good idea
surely thats for deaths right
nope, that's when they join
read the javadoc
you can just set the spawn location there, it shouldn't have the same effect as teleporting on join
ty
?paste
what is the worldGuard field
a plugin
WorldGuard.getInstance().getPlatform().getRegionContainer() this is how you access the RegionContainer
😮
public boolean isInRegion(Player player, String regionName) {
var query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
var regions = query.getApplicableRegions(BukkitAdapter.adapt(player.getLocation()));
if (regions.isVirtual())
return false; // ?, given the documentation this seems to be the appropriate choice for a method like this, however I'm not completely sure
for (ProtectedRegion region : regions) {
if (region.getId().equalsIgnoreCase(regionName)) {
return true;
}
}
return false;
}
in any case, you're probably want to ask in the EngineHub discord, they may know better
Does YamlConfiguration contain the file's absolute path by any chance?
i dont think so, but u could probably just yoink it from JavaPlugin#getDataFolder if u also know the name of the file
Wondering if someone can help. I'm tring to create a HoverEvent to show an item, but it doesn't render the name/lore or other tags when building it out. I've seen a few things posted here, on the forums, and elsewhere suggesting to use ItemMeta#getAsString which I'm doing, but it doesn't seem to be working. Has anyone been actually able to figure this out since 1.20.5/6 onward? It seems all posts end with the same general suggestion, but no confirmation that anything actually works. I can't even seem to form a tellraw properly either
@EventHandler
public void onClick(PlayerInteractEvent event) {
ItemStack item = event.getItem();
TextComponent component = new TextComponent("Hover me");
component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM,
new Item(item.getType().getKey().getKey(),
item.getAmount(),
ItemTag.ofNbt(item.getItemMeta().getAsString()))));
event.getPlayer().spigot().sendMessage(component);
}
manually build it. use getCustomName() as line 1 of the hover message, go to next line and print the item enchant names from a list, then the item lore from a list. thats all.
Yeah, that does feel unfortunately like the only way to actually do this at this point
its likely the most reliable way long term
yup.... especially with all this crazy item stuff coming through. I suppose building it manually works, it just loses the ability to easily display things like damage, nutrition value, attack speed, etc. that would automatically be added if I could find some way to generate a proper NBT string
well the issue is youd probably have to go a NMS route, which is usually a hassle. There are methods to grabbing all that info which you could likely format nicer than vanilla
private String getItemLore(ItemStack item) {
ItemMeta meta = item.getItemMeta();
StringBuilder loreBuilder = new StringBuilder();
loreBuilder.append(getItemName(item) + "\n");
if (meta.hasEnchants()) {
meta.getEnchants().forEach((enchant, level) -> {
String enchantName = enchant.getKey().getKey().replace('_', ' ').toLowerCase();
enchantName = Character.toUpperCase(enchantName.charAt(0)) + enchantName.substring(1);
loreBuilder.append(ChatColor.GRAY + enchantName).append(" ").append(ChatColor.GRAY + level.toString()).append("\n");
});
}
if (meta.hasLore()) {
loreBuilder.append(String.join("\n", meta.getLore()));
}
return loreBuilder.toString();
}
```I did this for the enchants & lore
can anyone give me an example of some code using interpolation with display entities? im just seeing methods to set the delay or set the duration not what it should be doing while interpolating (ex. change scale continuously to a specific size from a smaller size)
you just set the beginning and end transformation
Im running 1.21.1 faction servers and there are tons of crops on my server, causing so many lags. How can I optimize that ? Thank you
the interpolation happens on client-side, and there's not much of a way to configure it besides those two properties you mentioned. If you want to do something akin to changing the velocity of the interpolation, you probably want to play around with the interpolation duration mid-interpolation
that sounds like something for #help-server
i dont care about easing or anything i just want to get it to scale up from being small
im just not grasping how to use the interpolation methods
you see, you don't care about the interpolation
you just set the duration you want, aka the velocity
yeah but how do you tell it what to do during that time
then you just scale up the display entity with the transformation matrix
by setting the transformation
so setting an interpolation makes the next transformation that happens be that interpolation?
if so, thats really simple
ok i will try
it is so mind-numbingly simple that makes one believe it wasn't Mojang who made such a system lol
we're way too used to working around the shit out of vanilla behavior over here in the server side
I managed to get a proper tellraw put together
/tellraw @a {"text":"text","hoverEvent":{"action":"show_item","contents":{"id":"minecraft:stone","count": 1,"components": {"minecraft:custom_name":"asdf","minecraft:lore":["asdfff"]}}}}
It looks like the getAsString method probably would work, it's just getting stuck in as tag instead of components so it breaks
I'd just go for adventure-platform if I were you
Yeah... I've been debating.
well, to try and make bungeechat work, what if you just scrap the Item abstraction
var item = event.getItem();
var nbt = "{\"id\":\"%s\",\"count\":%d,\"components\": %s}"
.formatted(item.getType().getKey().getKey(), item.getAmount(), item.getItemMeta().getAsString());
var component = new TextComponent("Hover me");
component.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new BaseComponent[]{ new TextComponent(nbt) })));
event.getPlayer().spigot().sendMessage(component);
it seems like the ItemSerializer class needs some updating
the representation they're using is the old one, though I'm unsure if it still works that way
public static void placeBlock(Location location, Material block, JavaPlugin plugin, Player player) {
World world = player.getWorld();
// Adjust location to center the block display within the block space
Location centeredLocation = location.clone().add(0.5, 0.5, 0.5);
BlockDisplay blockDisplay = world.spawn(centeredLocation, BlockDisplay.class, display -> {
display.setBlock(block.createBlockData());
display.setBillboard(Billboard.FIXED);
display.setTransformation(new Transformation(ZERO_VECTOR, NO_ROTATION, INITIAL_SCALE, NO_ROTATION));
});
// Use a scheduler to set the interpolation parameters and transformation on the next tick
new BukkitRunnable() {
@Override
public void run() {
// Set the interpolation duration which will affect the next transformation
blockDisplay.setInterpolationDuration(100);
}
}.runTaskLater(plugin, 1); // Execute this block 1 tick later
// Trigger the final transformation which should now interpolate plsplsplspls
blockDisplay.setTransformation(new Transformation(ZERO_VECTOR, NO_ROTATION, FULL_BLOCK_SCALE, NO_ROTATION));
}
``` idk if im doing this wrong but for some reason it doesnt interpolate it just sets itto full size
This does indeed work 😄 Thank you kindly! I was playing with making my own Item class that could be constructed similarly to before, but was running into a bunch of issues. But this does the trick!
you need to set the transformation inside the delayed task too, otherwise the interpolation duration is set after the transformation happened
have you tried doing it without the delayed task at all though?
Minecraft's wiki also needs to be updated... it still reflects the tag setup instead of components lol
it's kinda annoying considering one has to depend on the deprecated constructor but eh, if it works
I do wonder if bungeechat has the flexibility to allow one to override the default serializers tho
doesn't look to be the case, but one could make do by reflectively changing the field in ComponentSerializer if it ultimately becomes necessary
it's just matter of someone hitting up md about updating the ItemSerializer representation anyway
I had set up a class that extended Contents, which was closer. The problem was serializing the item down into nbt means it's a string… and putting that directly in the components tag doesn't work because it's expecting a json object instead. I could reparse the string into json, but then all the 0b or 3d whatever was read in as a string because I don't have the serializers registered for those data types. Lol
how to make it so when player destroys a block, there appears different block, i made this but it actually made that the diamond block "drops" gold block when mined
if (event.getBlock().getType() == Material.DIAMOND_BLOCK) {
event.getBlock().setType(Material.GOLD_BLOCK);
}
this is BlockBreakEvent
public static void placeBlock(Location location, Material block, JavaPlugin plugin, Player player) {
World world = player.getWorld();
// Adjust location to center the block display within the block space
Location centeredLocation = location.clone().add(0.5, 0.5, 0.5);
BlockDisplay blockDisplay = world.spawn(centeredLocation, BlockDisplay.class, display -> {
display.setBlock(block.createBlockData());
display.setBillboard(Billboard.FIXED);
display.setTransformation(new Transformation(ZERO_VECTOR, NO_ROTATION, INITIAL_SCALE, NO_ROTATION));
});
// Use a scheduler to set the interpolation parameters and transformation on the next tick
new BukkitRunnable() {
@Override
public void run() {
// Set the interpolation duration which will affect the next transformation
blockDisplay.setInterpolationDuration(100);
blockDisplay.setTransformation(new Transformation(ZERO_VECTOR, NO_ROTATION, FULL_BLOCK_SCALE, NO_ROTATION));
}
}.runTaskLater(plugin, 1); // Execute this block 1 tick later
// Trigger the final transformation which should now interpolate plsplsplspls
}
this implementation just sets the block and so does running it outside
oh.. its because it changes the block before player mines it
you mean, no interpolation happens?
yes
it just makes it instantly full size
Correct. You need to cancel the event. Then just drop a diamond block. That or just throw a delay before setting the block
private static final Transformation[] FRAMES = new Transformation[]{
new Transformation(ZERO_VECTOR, NO_ROTATION, INITIAL_SCALE, NO_ROTATION),
new Transformation(ZERO_VECTOR, NO_ROTATION, FULL_BLOCK_SCALE, NO_ROTATION)
};
public static void placeBlock(Location location, Material block, JavaPlugin plugin, Player player) {
var world = player.getWorld();
// Adjust location to center the block display within the block space
var centeredLocation = location.clone().add(0.5, 0.5, 0.5);
var blockDisplay = world.spawn(centeredLocation, BlockDisplay.class, display -> {
display.setBlock(block.createBlockData());
display.setBillboard(Billboard.FIXED);
display.setTransformation(FRAMES[0]);
});
// Use a scheduler to set the interpolation parameters and transformation on the next tick
Bukkit.getScheduler().runTask(plugin, () -> {
blockDisplay.setInterpolationDuration(100);
blockDisplay.setInterpolationDelay(-1);
}); // Execute this block 1 tick later
Bukkit.getScheduler().runTaskLater(plugin, () -> blockDisplay.setTransformation(FRAMES[1]), 2);
// Trigger the final transformation which should now interpolate plsplsplspls
}
what about this
kinda wonky, but if this doesn't work nothing will
no, cancelling wont change anything because i want to place there (lets say) gold block, i cannot place it before the event, because then player breaking diamond block will actually break gold block instead, i need to do the delay (i think so)
the display next to the lambdas below cant be resolved
i think cuz wrong scope?
I just confused the vars, it should be blockDisplay
This transformation, can you change values on the original transformation? I wonder if it only interpolates if the transformation is the same object. If it gets replaced, it may ignore the duration
so it should be in the block display code block
oh
u edited it
for this now i can see the initial scale and then 1 tick later its full scale
no interp
im really looking for someone who has used it before but i cant find anything
i saw it in a datapack first and i wanted to implement it
I edited the above again
it cant resolve FRAMES
it is there tho, did you not copy the whole thing
I would set your timers to higher delays just to make things visible. I also saw something mentioning that there might be a cap on the transformation duration. Try something smaller like 40
am on lunar
that was it
no way
now that you say that, i remember that from the video i saw
that's so dumb
it should be clamped if it is over the limit, not just refuse to work lol
59 is the max I think?
im gonna try this now with the transformation in the block
yeah it works
but for some reason it doesnt go to full size
can you try without delaying it at all
yep
whoah this is really wierd
it partially does the one i spawn, and then when i spawn the next one, it sets the previous one to full size
what
so, you spawned one, it for some reason doesn't scale up to its full length, but when you spawn another one, it does?
perhaps the client-side calculation gone wrong, you're better off trying it on the vanilla client tbh
i spawn 1
it goes to like say 60% size
i spawn another
the previous one jumps to full size
the one i just spawned goes to 60% (roughly)
no media perm its hard to explain
you just have to verify your forum account to get media perms
anyhow, that does sound like an issue with the client
because if it jumps to full size when you spawn the other one, it just means the spawning of another entity is forcing a re-render
it probably doesn't matter what you spawn there, it'll still jump to full size
well that doesnt really concern me all that much since there will only ever be one at a time
however
i do need to get it to go all the way to a full block
you need to trigger an update on the thing
then again, if it doesn't interpolate properly it is all in vain
could it be that its going at a constant rate but not considering if it will get to that end scale in time before the duration is over
the thing is, it should
the client has all the data to make that calculation properly
give me a sec, I'll try it on my side just to be sure
for some reason changing the duration value seems to have no effect on the actual duration
i went back to this and now setting it to 40 does the wierd partial size thing in the video but lower doesnt? what the freak is going on
does this also returns the item in cursor?
no iirc
alright, i'll have to make it then
The Sound JD mentions that
There may be additional sounds present in the server, for example from a DataPack which can be accessed via Registry.SOUNDS.
But from what I can see on the Minecraft wiki, it seems like sound events are defined in resource packs, which aren't loaded on the server?
Am I missing something? or is that outdated?
Sounds cannot afaik be declared via a datapack, only a resource pack, and those also cannot be accessed from a registry lol
does anyone know why portals and clouds are in front of text displays?
maybe try setting the see through property of the display
its already on true
if it is true then well, it's see through lol
meaning the particles will be in front of it
i disabled it now it works
Afaik music discs are data driven now so they can be added by a datapack
music discs != sounds
?nms
#bot-commands smh smh
I always got those bot commands channel hidden lol, never use them
So the JD is wrong? the server does have a registry, but I guess it's always just the default values then
probably, but I'm not entirely sure
but I believe there's a Player#playSound method with a string arg instead of the sound enum
Oh yeah I know, I was just adding handling for custom sounds then realized halfway that I don't think that's actually a thing
Is there a way to get the most lagging chunks?
where do i find the state of a fence?
A fence only has BlockData
thanks
How do I put a custom nbt on a ItemStack? I'm using spigotapi 1.20.1
?pdc
Thanks a lot!
Hey! I have multiple Kotlin projects, and I’m running into a linkage error when some of them use extension methods or Kotlin lambdas. This happens because the plugins add Kotlin to the classpath multiple times. However, if I try relocating Kotlin, none of the extensions will work or index properly. I think this might be a limitation with ShadowJar.
How can I manage this?
I'm trying to create a plugin with NMS using maven, however when I try to put the plugin into the server I get the error
Caused by: java.lang.NoClassDefFoundError: net/minecraft/world/entity/monster/WitherSkeleton
This is my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>me.FlaykertZ.TimeStarFactions</groupId>
<artifactId>TimeStarFactions</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>TimeStarFactions</name>
<properties>
<java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<defaultGoal>clean package</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.21-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.21.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<classifier>remapped-mojang</classifier>
</dependency>
</dependencies>
</project>
And I'm using Intelij with mvn install to create the jar file
This is the code
package me.FlaykertZ.TimeStarFactions.customMobs;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.goal.RandomStrollGoal;
import net.minecraft.world.entity.monster.WitherSkeleton;
import net.minecraft.world.level.pathfinder.PathType;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_21_R1.CraftWorld;
import org.bukkit.entity.Zombie;
public class witherSkeletonCommander extends WitherSkeleton {
public witherSkeletonCommander(Location loc){
super(EntityType.WITHER_SKELETON, ((CraftWorld) loc.getWorld()).getHandle());
this.targetSelector.addGoal(0, new RandomStrollGoal(this, 0.8D));
Bukkit.broadcastMessage("test");
}
}
?nms
why do i need to cast?
I don't think there is a shortcut for short
ok
There isn't one for byte either, sadge
:(
cries in (byte) 1
Trying to make a custom mob with pathfinding with this code
public witherSkeletonCommander(Location loc){
super(EntityType.WITHER_SKELETON, ((CraftWorld) loc.getWorld()).getHandle());
this.setPos(loc.getX(), loc.getY(), loc.getZ());
goalSelector.getAvailableGoals().clear();
targetSelector.getAvailableGoals().clear();
this.goalSelector.addGoal(0, new FloatGoal(this));
this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.8D));
this.targetSelector.addGoal(1, new HurtByTargetGoal(this));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<Player>(this, Player.class, true));
// this.targetSelector.addGoal(0, new AvoidEntityGoal<Chicken>(this, Chicken.class, 20, 5.0D, 5.0D));
}
However when I spawn him it won't attack me if I hurt him nor attack me when he sees me
wdym
Add your custom goals in registerGoals()
See any of the vanilla mob classes for reference
public witherSkeletonCommander(Location loc){
super(EntityType.WITHER_SKELETON, ((CraftWorld) loc.getWorld()).getHandle());
this.setPos(loc.getX(), loc.getY(), loc.getZ());
goalSelector.getAvailableGoals().clear();
targetSelector.getAvailableGoals().clear();
registerGoals();
// this.targetSelector.addGoal(0, new AvoidEntityGoal<Chicken>(this, Chicken.class, 20, 5.0D, 5.0D));
}
@Override
protected void registerGoals() {
super.registerGoals();
this.goalSelector.addGoal(0, new FloatGoal(this));
this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.8D));
this.targetSelector.addGoal(1, new HurtByTargetGoal(this));
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<Player>(this, Player.class, true));
}
Like this?
Yes
You also need an attack goal if you actually want them to attack
targetSelectors are just for selecting targets
Hello, I would like to make sure that my NPC doesn't get recreated every time I reload my server. How can I do that, please?
public void createFarmerNPC() {
Location location = new Location(Bukkit.getWorld("world"), NPC_X, NPC_Y, NPC_Z);
farmerNPC = CitizensAPI.getNPCRegistry().createNPC(EntityType.PLAYER, NPC_NAME);
SkinTrait skinTrait = new SkinTrait();
farmerNPC.addTrait(skinTrait);
skinTrait.setSkinPersistent(NPC_ID, SIGNATURE, TEXTURE);
farmerNPC.spawn(location);
}
Lol in Kotlin they're treated based off context
and how do I make a custom mob follow a different custom mob
with the followmobgoal?
If I have a custom packet entities system what's the best way to avoid conflicting entity ids with spigot?
Use nms to increment the internal counter
What class is it in?
Don't remember
nvm-
your fields shouldn't be UPPER_CASE
that's only for static final
What if they are constants for some silly reason
i thought so too, but then i saw npc id
and npc x y z
even if this coord doesn't change, it's better to be in a config for easy access
anyway camelCase is what we java nerds use in our code to define most of our fields
actually you nerds, i'm not that smart 😅
It doesn’t change anything in my code. the NPC appears without any issues, but a new one gets created each time I reload. But I’ll take note.
well, it's part of code convention, it can work, but you're making other devs jobs harder to help you
Okayyy
sry
imagine if someone started one line ing everything or named their fields _LiKeThIs
i think you have to register the npc in citizens no?
this is just for create
or maybe it's the id that's getting overwritten
actually, i'm not sure why a skin takes an npc id
Yes, it's registered in Citizens. But I can't overwrite the old NPCs because the IDs increment by 1 each time
and you say it doesn't show on rejoin?
what happens if you tp between worlds?
as far as i know citizens npc once created it's handled by the plugin itself
No, I’m saying that it shows up when the plugin is enabled.
Do you guys have any ideas about how id make a pathfinding algorithm for a procedural parkour plugin im making where ive already got a really fast way to know all possible jumps at a specific spot already that can pathfind close to and around pregenerated terrain in an "interesting" way? Where can i read up on something like this? I was thinking maybe i could utilize an ingame mob and simulate its pathfinding to use for a path the parkour should follow
ohh
i missunderstood you
you can remove the npc upon on disable
or keep track of ids and remove them onenable
alternatively, you could make your own fake players, but that's gonna require a tracker and packets
Yes, I've already tried, but I feel like it doesn't work.
i'm sure there's api to remove npcs by id
i assume once created the npc has an id no?
yes with NMS ?
I've already tried; I wanted to do it with NMS from scratch, but I can't do it; it's too complicated for me :/
do you have any example ?
the code is private for now
ok np
Originally, I didn't want to use Citizens.
but i could share the packets i use to set an npc visible and invisible
connection = getConnection(player);
if (isVisible) {
connection.send(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, this));
connection.send(new ClientboundAddEntityPacket(this, serverEntity));
connection.send(new ClientboundRotateHeadPacket(this, (byte) (getYRot() * 0.71)));
connection.send(new ClientboundSetEntityDataPacket(getId(), entityData.getNonDefaultValues()));
if (list != null) {
connection.send(new ClientboundSetEquipmentPacket(getId(), list));
}
connection.send(new ClientboundAnimatePacket(this, 0));
} else {
connection.send(new ClientboundRemoveEntitiesPacket(getId()));
}```
okk thx
you could optimise the remove entities packets by doing it in a batch
i haven't really seen a easy way for me to do it tho
it'd save a bit of bandwith
the animate packet is not needed, only if you want to fix the body rotation
Okay, I want to look into it a bit more..
oh yeah, on newer versions, you need to set the connection of the fake player to something otherwise there's a null pointer somewhere
i have any doc ?
there's no documentation for nms
:/
you just need to know what you're doing
and trial and error
but i did show you how you can set connection
you just set it with the player you want it to be visible to
i think it was one of these packets that triggered the null pointer
But I'm on 1.21.3, so I don't think it's the same, right?
Compare different mappings with this website: https://mappings.cephx.dev
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.
?nms
there you go
?switchmappings
thank you
use A* i think
or a shortest path algorithm
Ive heard that term before
dijkstra i belive
dijkstra can do this actually
if you want to make a list of possible jumps
and generate terrain based on it
two paths, set some random rules and make it find the shortest path
and fill it with parkour segments
that are actually doable for players
there you go
so the last thing is already did
you just need to make a cuboid, make random rules, of where to go and where it can't and use dijkstra to find the shortest path or i don't think you even need the shortest path here
you probably want the longest path
why are the buildtools broken?
buildtools broken on windows, why?
Should i be using pregenerated terrain or generate terrain to fit the path?
like below the parkour segments?
Yeah
or you want to make walls
?notworking
"Does not working" is a useless statement. Please describe what exactly is not working, what you expect it to do, and what actually happens. If you get any console errors, also ?paste the entire stacktrace.
it all depends on your implementation
?why
Well i was sort of envisioning it being pretty close to the terrain
Patching net\minecraft\world\level\World.java
Patching net\minecraft\world\level\WorldAccess.java
Der Befehl "sh" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
Error compiling Spigot. Please check the wiki for FAQs.
If this does not resolve your issue then please pastebin the entire BuildTools.log.txt file when seeking support.
java.lang.RuntimeException: Error running command, return status !=0: [C:\Windows\system32\cmd.exe, /D, /C, sh, applyPatches.sh]
at org.spigotmc.builder.Builder.runProcess0(Builder.java:1042)
at org.spigotmc.builder.Builder.runProcess(Builder.java:967)
at org.spigotmc.builder.Builder.startBuilder(Builder.java:679)
at org.spigotmc.builder.Bootstrap.main(Bootstrap.java:60)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: Cannot invoke "javax.swing.JButton.getPreferredSize()"
?itisnotworkingeverywheresowhywouldineedtoputdebugoutput
If this does not resolve your issue then please pastebin the entire BuildTools.log.txt file when seeking support.
send me src from where is that
Not super far away
it's a bit more complicated if you want it to make part of the pregenerated terrain
You have exceeded the maximum size of 512 kilobytes per Paste.
will it use the pregenerated terrain as part of the parkour generator?
use any paste site that will work or just upload the file
Probably would do a "parkour dimension"
i was thinking i could possibly use cave carvers at almost sea level to generate paths for me
well, you'd need the information about where a cave starts and ends if it ends
I guess yeah
if you have those you could calculate a path in the cave from a place to another
you'll need a custom path finding algorithm that takes your parkour segments as each possible point btw
now that i think of
and somehow not circle back
i guess you could make all the nearby points score really high so the path won't try to loop back
@remote swallow https://outfluencer.dev/broken.txt
In the past i made it so that the next jump must be within 30 degrees in the xz plane of the vector between the last 2 blocks
you can use a selection and a start point and end point to define your parkour on the terrain
This way it never loops upon itself even just picking random points
that's a good idea
but what if you want it to go above a previous part of the parkour?
It just turns 30 degrees each time
oh so it works
This could also be made simpler if i just pick a few maps that would be good for parkour and then place a bunch of markers in it that the pathfinder can choose between
So that it goes to and between things in an interesting way
yeah, but it won't be as random anymore
Yeah
i don't think a* or dijkstra is best here if you want to make it random
you need some sort of snake like algorithm
I think they would work well if theres a way we can determine what it means for a cool place to go to would be deterministicly
but they need to be modified for your need
Like in an ideal world we consider a jagged peaks biome as a surface represented by some equation, and the interesting part is where its slope is the greatest
where I can learn spigot plugin development fast??
Which would create those poi markers i mentioned on the fly
Do you know java
but it's not easy to calculate those without the generator data
Indeed
and if you plan to go through a jungle biome, someone could just climb vines and skip it all
Yes ive considered jungle biomes as being something id rather avoid
Because you would just be above ut
yea little bit
Probably only would do mountainous biomes because they are the most interesting and do not have alot of trees
did you consider generating custom terrain?
Yea
one that's friendly for parkour?
and you have info about start and end and so on
so you could snake through
Can you generate worlds with noise functions that you can analyze mathematically or do you just use the built in stuff in world gen
Last time i messed with world gen was 1.18 with datapacks
this is how minecraft is done
perlin noise all the way
i think even the caves are a variation of perlin noises
You can watch the world gen talk if you're curious
but you need to access the perlin noise information that minecraft uses
which i don't think it's easy
I should look at axioms plugin code
i did watch it, but some information was lost on me
They do stuff related to slope angle all the time
it's an interesting project, if i ever make a parkour plugin then i'll be more helpful for sure
analyzing all the possible options i have and considering each limitation
Whats that
it's a talk about how mojang generates worlds with perlin noise
Oh with henrik
The past year and a half I've worked almost full time with Minecraft world generation. We've radically changed how the world is generated, to enable dramatic new caves, massive mountains ranges and overall more natural-looking terrain.
In this talk we'll geek out on the gory details of this. How does Minecraft procedural world generation actual...
yes
How can I delete a resource loaded by mistake?
what
ok thx
But isn't there a way to remove it?
you report it and ask for it to be deleted
but they won't delete my account for this stuff, I hope?
@vagrant stratus can you delete my resource ?
._.
but it doesn't make sense that there is no way to delete one of my resources
what is resource and why are people always asking for it to be deleted
like skript files
don't hate on people using skript 😄
it's a nice way to understand the concept of programming
like how lines run one after another
how variables work and how to schedule tasks
I've tried skript before
Skript is fine for those not up to setting up a dev environment.
It is genuinely worse than scratch
The syntax is a complete fucking mess too you're better off just learning java
i used skript when it had like 1000 possible things you could do
now's probably at like 100000
with addons
it used to look like natural language which was nice
no idea how it looks now
i can't seem to find an example
that's why you're better off just learning java because there's so much more out there as far as tutorials, examples, and other support
how do i get it to scale outwards from the center and not from the corner with transformations
private static final Transformation[] FRAMES = new Transformation[]{
new Transformation(ZERO_VECTOR, NO_ROTATION, INITIAL_SCALE, NO_ROTATION),
new Transformation(ZERO_VECTOR, NO_ROTATION, FULL_BLOCK_SCALE, NO_ROTATION)
};
public static void placeBlock(Location location, Material block, JavaPlugin plugin, Player player) {
var world = player.getWorld();
// Adjust location to center the block display within the block space
var x = location.getBlockX();
var y = location.getBlockY();
var z = location.getBlockZ();
Location blockLocation = new Location(world, x, y , z);
Location centeredLocation = blockLocation.clone();
var blockDisplay = world.spawn(centeredLocation, BlockDisplay.class, display -> {
display.setBlock(block.createBlockData());
display.setBillboard(Billboard.FIXED);
display.setTransformation(FRAMES[0]);
});
/*blockDisplay.setInterpolationDuration(40);
blockDisplay.setInterpolationDelay(0);
blockDisplay.setTransformation(FRAMES[1]);
the above code does not fully scale the display for some reason
*/
//attempt to hard code
// Number of animation steps based on the scale increment
int totalSteps = (int) ((FULL_BLOCK_SCALE.x - INITIAL_SCALE.x) / SCALE_INCREMENT);
for (int i = 0; i <= totalSteps; i++) {
final int step = i;
Bukkit.getScheduler().runTaskLater(plugin, () -> {
float scale = INITIAL_SCALE.x + SCALE_INCREMENT * step;
Vector3f currentScale = new Vector3f(scale, scale, scale); // Ensure scale does not exceed FULL_BLOCK_SCALE
if (currentScale.x > FULL_BLOCK_SCALE.x) currentScale = FULL_BLOCK_SCALE;
blockDisplay.setTransformation(new Transformation(ZERO_VECTOR, NO_ROTATION, currentScale, NO_ROTATION));
}, i); // Schedule each step 1 tick apart
}
Bukkit.getScheduler().runTaskLater(plugin, () -> {
blockDisplay.remove(); // Remove the display entity
world.getBlockAt(blockLocation).setType(block); // Set the actual block in the world
}, totalSteps-1); // Schedule this to run after enough time for interpolation to complete
}
i gave up messing with interpolation and just hard coded it
it looks fine
is this chatgpt code
no but i learn from chat gpt so it probably looks like it
also excessive comments ik
"adjust location" hmm ah yes not chatgpt
that was me if it was chat gpt it would probs do that all in one line
anyways what do i do to get it to scale or at least fake it to look like its scaling not from the corner
do i translate simultaneously
//attempt to hard code
// Number of animation steps based on the scale increment
yeah definitely no chatgpt
yes
random multi line comment with code that wasnt working
yeah I believe you that you wrote that :p
i just decided to use a for loop even though its probably not the proper way to do it cuz i just want it to work
and im not super fluent in java or the spigot api
why would chat gpt randomly not capitalize
because it did not write the first of those comments
it didnt write any of them 🥺

chatgpt definitely wrote that
blockDisplay.remove(); // Remove the display entity
Do you just like useless comments or was it ai
What would be the optimal way of identifying a PlayerHead? Im creating a custom "ore" sort of, and right now im identifying it with PersistentDataContainer key.
i write excessive comments when im first writing the code
it confirms to myself what i expect to happen
So does chatgpt, but I'm not gonna argue with you
i implemented my placeblock method into my /nextjump command pretty easily but now i need to figure out a better way to choose from the next possible jumps set
Is there a place that lists all new things added to spigot per release?
the release post
im pretty new to concurrency, is this thread safe/should i change it? ```java
public class AtomicObject <T1>
{
private long tID = 0;
private T1 obj = null;
public AtomicObject(T1 obj)
{
synchronized(this.obj)
{
this.obj = obj;
}
}
public synchronized boolean lock()
{
if (this.tID == 0)
{
this.tID = Thread.currentThread().threadId();
return true;
}
return false;
}
public synchronized boolean release()
{
if (this.tID == Thread.currentThread().threadId())
{
this.tID = 0;
return true;
}
return false;
}
public synchronized T1 get()
{
if (this.tID == Thread.currentThread().threadId())
{
return this.obj;
}
return null;
}
public synchronized void set(T1 obj)
{
if (this.tID == Thread.currentThread().threadId())
{
this.obj = obj;
}
}
}
umm what is this for
to prevent race conditions between the server thread and a dispatcher
mfw AtomicReference
right i guess that does it too 😄
i don't think this is thread safe
get and set can access the data independently (synchronized won't catch it)
you need a reetrantlock to check instead of a thread id
but an atomic reference is the best option based on what you have above
block.applyBoneMeal(BlockFace.UP)
why does it return false if the bonemeal was applied succesfully and my plant has grown
Does it say what the return is for?
does anyone have any tips on how to constantly hide/show a player without removing their entry in the Tablist?
i am sending an entity destroy packet to all viewing players, but i am struggling on finding a way to spawn them back in
Ask the library dev?
wut
spigot has no armor equip event
Spigot has no such event
Hi, I have a problem. I try to get a player's server using Bungee Messages, but it doesn't seem to work and I don't know why. Here is my code :
@Override
public void onEnable() {
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
getServer().getMessenger().registerIncomingPluginChannel(this, "BungeeCord", this);
}
@Override
public void onPluginMessageReceived(String channel, Player player, byte[] message) {
if (!channel.equals("BungeeCord")) {
return;
}
ByteArrayDataInput in = ByteStreams.newDataInput(message);
String subchannel = in.readUTF();
Bukkit.getLogger().info("Received message from BungeeCord subchannel: " + subchannel);
if (subchannel.equals("GetPlayerServer")) {
String userName = in.readUTF();
String serverName = in.readUTF();
Bukkit.getLogger().info("Player " + userName + " is connected to " + serverName);
}
}
public void checkPlayerConnected(Player sender, String targetPlayerName) {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("GetPlayerServer"); // Channel
out.writeUTF(targetPlayerName); // Name of the target
sender.sendPluginMessage(this, "BungeeCord", out.toByteArray());
}
what exactly doesn't work?
oh sorry, forgot to mention. I don't get in the console where is the player connected
"Bukkit.getLogger().info("Player " + userName + " is connected to " + serverName);"
does the first log work as intended or what?
Yes it does, I do get "Message rom BungeeCord subchannel: PlayerList" but from another channel because I have another plugin using "PlayerList"
interesting, the code seems correct tho
yeah :'(
I mean I followed this https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/#getplayerserver
idk what's wrong :/
yeah, this is following the packet format
maybe you are having your bungeecord setup wrong or idk...
I can retrieve serverlist and even connect to other servers, i dont see what would be wrong
is your targetPlayerName correct?
it is
well ok assuming you specify it via command or hardcoded...
I do specify it via command, but I can hardcode it so you see
try and see and also you need to have a player online to get his data
Yup :D
give me a sec to show you
ok
I get nothing back in my console
Okay, it's completly my bad I think.. :')
I'm sorry
is it working?
I'm using Velocity, seems like they kept almost every bungee messages the same, EXCEPT GetPlayerServer
they changed GetPlayerServer into GetServer
I was in a similar situation once lol
Yeah ahah, it's my bad, sorry for the time I took you ^^
no problem
Wishing you a good evening/day :)
same
thank you :D
why cant I set world spawn
Hi i need help how do i make when player jumps twice in air they get elytra for flying and when they land elytra disappears.
What do you mean you can't, provide some context.
I do /setworldspawn and it doesnt work
when people join they are where they last were
How is this related to spigot lol?
Pretty sure that spawn location is only used for respawning and first time joins
thats my server soft ware
Also you must set this position to an air block
huh how to make it respawn EVERY TIME
Just use essentials + ess spawn
With world spawn not.
whast that
Use a pre-made plugin or even a datapack for that.
.
There are also plenty of essx alternatives
but I hate essentials
Did I not just say?
im trying with multiverse but it doesnt work
Go to #help-server and also some plugins aren't compatible together
World spawn should be used for every respawn and first join
Players joining again will be at their last location
they have muiltiverse so just mvm set spawn world
I give up
You're trying to set a spawn point that the player always goes to every time they join the server? And every time they respawn?
on the spawn point thing?
yes
Are you up for a little programming? This would be a pretty simple thing to handle programmatically, but I'm not sure if plugins exist that will take care of it
This is #help-development, implying this is for programming anyways.
but I dont know java
Then why are you in this channel?
support
Then use #help-server. This channel is for help with developing plugins.
He said he didn't like essentials lol
yeah, lol. But I don't know that anything else quite has the functionality for it
Hey I have a weird bug.
I am overriding /help, but I am receiving no args (empty array) in the executor, unless I write it explicitly as /myplugin:help
When I try to run /minecraft:help, it shows the usual unknown command message
It is running the same executor without the full namespaced command, but the only difference is that args is empty
I am registering commands as so:
Objects.requireNonNull(plugin.getCommand(commandName)).setExecutor(new HelpCommand());
It is defined in the plugin.yml as below:
commands:
help:
description: Tells the admins the user needs help
usage: /help [message]
so running /help thing yields args of [], while running something like /myplugin:help thing yields args of [thing]?
or it might include myplugin:help in the args, dont remember
iirc overriding bukkit commands has always been pretty jank
yep exactly
yeah just sounds like jank with overriding commands to me
is there any way to fix it?
it's hard to search on the internet because it's about "help"
You could try removing the bukkit help command from the command map
and then add yours back in
i was gonna say that, but i thought only plugin commands were stored in the command map
unless im thinking of something else
hmm potentially
remove a players permission to /bukkit:help, give permission to use urs
unregistering minecraft:help didn't work
(unless i did it wrong?)
plugin.getServer().getCommandMap().getCommand("minecraft:help").unregister(plugin.getServer().getCommandMap());
yeah you can't do that
vanilla commands don't exist on the command map
what epic said would probably be easiest
that is so silly
bukkit makes me so mad
so true
im making a paper plugin and i made this recipe but when i put all of the stuff in the crafting table it only shows a normal book not the one i made. does anyone know what i did wrong?
{
ItemStack book = new ItemStack(Material.BOOK);
ItemStack amethyst = new ItemStack(Material.AMETHYST_SHARD);
ItemStack totem = new ItemStack(Material.TOTEM_OF_UNDYING);
ItemStack gold = new ItemStack(Material.GOLD_BLOCK);
ItemStack diamond = new ItemStack(Material.DIAMOND);
ItemStack questBook = new ItemStack(Material.BOOK);
ItemMeta questBookMeta = questBook.getItemMeta();
questBookMeta.displayName
(Component
.text("QUEST LICENSE")
.color(TextColor.color(75,0,130))
.decoration(TextDecoration.BOLD, true)
);
questBookMeta.getPersistentDataContainer().set(Keys.QUEST_BOOK, PersistentDataType.BOOLEAN, true);
questBookMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
questBookMeta.addEnchant(Enchantment.LOOT_BONUS_MOBS, 1, true);
ShapedRecipe bookRecipe = new ShapedRecipe(new NamespacedKey(main.getInstance(), "QuestBookRecipe"), questBook);
bookRecipe.shape
(
"AGA",
"DBD",
"ATA"
);
bookRecipe.setIngredient('B', book);
bookRecipe.setIngredient('A', amethyst);
bookRecipe.setIngredient('T', totem);
bookRecipe.setIngredient('G', gold);
bookRecipe.setIngredient('D', diamond);
Bukkit.addRecipe(bookRecipe);
}```
most likely because you are not applying the itemmeta to the itemstack but if you are making plugins for paper, ask on paper...
it makes sense vanilla commands are registered in a completely different way
Yo we are trying to import a plugin into our server, but we are running into a problem and its not working alot to explain, can someone help over vc? via screenshare
you will have a close to 0% chance of getting someone in a vc just try and explain it as best you can here
Ok basically we are trying to import a custom plugin and idk what is happening so cant explain much but its not fully uploading
like it shows in plugin folder
but doesnt work when trying to execute it in game
what does it say in console
Any console errors?
it will at minimum give you a config error if its not valid and is a jar
^
ctrl + f on the console page and search for the plugin name or some sort of relevant reference to the plugin
not showing up
What plugin is it?
?paste
can you put your console log in this
What type of file are you uploading?
Where are you uploading it to? (Remote Sever? Panel?)
What directory is it being uploaded to?
nvm son1c figured it out thank you though
I just thought of the best name for my parkour pathfinding alg i just conceptualized and am writing out rn
Walk in the parkour pathfinding
Walk in the parkour pathfinding Goal: Pathfind around Pregenerated minecraft terrain in an interesting way that makes the parkour “fun” and travel through the world, not staying in one area. Methodology: Recursively generate jumps into a list based on this process, given a list of all possi...
@lilac dagger this is what i thought of
how to make player say something with json?
looks like player.chat only allows plain string
deserialize it?
deserialize?
how do i make a anticw 😭
CW?
yes, like crystal cheats
makes it to where you can automatically crystal pvp
how can I do that?
I want to make player say {"translate": "block.minecraft.air"}
just write really fast code /s
its very obvious when it isnt normal
then the check should work well
but i need something like a plugin that would check how fast they are crysstalling
like i said it is very obvious because you will crystal at obvlivion
okay
you are in #help-development
it is expected that you can write it yourself
#help-server if you are not java inclined
is there a channel for finding plugins?
but I doubt anyone has a specific AC check for this
or do i have to look through spigot?
Ok
package dev.mcneds.parkour.util;
import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot;
import org.bukkit.Location;
import org.bukkit.World;
import java.util.ArrayList;
public class ChunkAnalyzer {
public static ArrayList<Location> highestBlockPositions (Chunk chunk){
ArrayList<Location> chunkMesh = new ArrayList<>();
ChunkSnapshot chunkSnapshot = chunk.getChunkSnapshot(true, true, false);
World world = chunk.getWorld();
int chunkX = chunk.getX();
int chunkZ = chunk.getZ();
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
int y = chunkSnapshot.getHighestBlockYAt(x, z);
chunkMesh.add(new Location(world, (chunkX * 16) + x, y, (chunkZ * 16) + z)); // actually convert from chunk coords to world coords you bozo
}
}
return chunkMesh;
}
public static Location highestInChunk (ArrayList<Location> chunkMesh){
Location maxLocation = chunkMesh.getFirst();
for (int i = 0; i < 256; i++) {
if (chunkMesh.get(i).getBlockY() > maxLocation.getBlockY()){
maxLocation = chunkMesh.get(i);
}
}
return maxLocation;
}
}
is there a better way to find the highest block in a chunk
(faster)
?stash
is this even possible?
not with json but you can use components
Hey, I use a claim plugin (Factions by MassiveCraft) and I'm having a problem.
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) {
Player player = event.getPlayer();
player.sendMessage("§cYou broke a block.");
}
The problem is that if a player try to break a block in a claim where he can't place, the break block Event is cancelled, and my code wont run even tho it has HIGHEST priority and ignoreCancelled
Components support Translatable objects
isnt "ignoreCancelled=true" to not fire the event when its cancelled ?
what?
even without ignoreCancelled
that was for myself lol
does that mean it has to be player.sendMessage instead of player.chat?
oh lol
sendMessage is to send a message to the player, and you can use component with (so like hoverable messages etc)
yes
did you register the event completly ?
What do you mean ?
Why do I keep getting this silly error??
[09:27:35 WARN]: java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver
https://mvnrepository.com/artifact/mysql/mysql-connector-java/8.0.33
https://mvnrepository.com/artifact/com.mysql/mysql-connector-j
Which should I use?
Bukkit.getPluginManager.register...
Yup i did
because the code run if it's not in a claimed area etc
(same for the other events in the class)
did you try to remove the priority and ignoreCancelled ?
yes
I first tried just @EventHandler, then added priority and ignoreCancelled
nothing works
but it works when the area is not claimed ?
sounds like you did not update the plugin jar
Then let me update the message so we'll see :)
This is my connection code
public Connection connect() throws SQLException {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
return DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database, username, password);
} catch (SQLException | ClassNotFoundException e) {
throw new SQLException("Could not connect");
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onBlockBreakFaction(BlockBreakEvent event) {
Player player = event.getPlayer();
player.sendMessage("§cYou broke a block. (New Message)");
}
this is in a non-claimed area, and still doesn't work in a claimed area
now i'll try with the ignorecancelled and update you
Iirc highest priority means it will be called last
did you include the driver dependency if your using maven ?
Try lowest, who knows, maybe it'll work
Yeah which one should I use, I sent the two links
i guess the problem is that is should get called every time ...
i guess the first one sounds nice
i'll try, but I just updated with the ignorecancelled and the jar IS updated cuz i have a new new message i made, let me try with lowest but yeah (and doesn't work in claim still)
and shade it ?
Nope, it doesn't work :/
anyone familiar with setting up intellij modules for spigot plugins
are you stopping yoru server between updating the plugin?
Yeah it says project's main artifact does not exist when I shade it
?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 you provide the pom ?
hmm i dont know... pom seems correct and your code too
Yeah lol
Yes
wait
?jd-s sec
ok yeah its that
its like priority over the final say of the event rather than call order priority
Yes
?stash i wanna see what this undocumented method is
what
ah its the integer value of the priority
getSlot in EventPriority.java
couldve totally used .ordinal but i see why they wouldnt
