#help-development
1 messages · Page 1387 of 1
No, you're just making a web request
Ok, sounds good
I start the server, when I join it will time me out then say ./start.sh does not exist, stopping the server!
How can I wait without halting the entire server?
java -Xms[STARTUP-MEMORY-IN-GB]G -Xmx[IDLE-MEMORY-IN-GB]G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar [SPIGOT-LAUNCHER-NAME].jar nogui
paste this inside the shell file (.sh)
these are optimized flags of garbage collection for minecraft
made by aikar's love to community
I don't have an sh file do i create one and put this in it?
just create it
okay
Question, does this apply to plugin creation?
https://www.youtube.com/watch?v=YYP_dNSYOG4
In this video I show you how you can easily interface with discord webhooks using Minn Development's Discord-Webhooks library.
Discord's intro to webhooks: https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks
Discord-Webhooks Github: https://github.com/MinnDevelopment/discord-webhooks
0:00 - Intro
0:30 - Creating the Webho...
Ok :D
I created the file and pasted the stuff in it now do i run the server by opening the new .bat file or the old one @mortal hare
ye
if you're on linux terminal:
chmod +x [filename].sh
./[filename].sh
if you're on windows:
just double click it, or from cmd.exe inside directory - [filename].bat
"This app can't run on your pc
To find a version for you pc, check the software publisher"
Windows
Is there a simple database/method to store Usernames and their points?
.bat
exactly
nope
maybe its windows defender
ill disable it and let you know
can you do a screenshot?
can't upload images here
on the edited file
okay
login to your spigotmc account
and verify the discord account
and you'll be able to do that here
@EventHandler
public void onMushroomBlockUpdate(BlockPhysicsEvent event) {
if (event.getBlock().getType() == Material.BROWN_MUSHROOM_BLOCK ||
event.getBlock().getType() == Material.RED_MUSHROOM_BLOCK ||
event.getBlock().getType() == Material.MUSHROOM_STEM) {
event.setCancelled(true);
//Update the blocks with their current face values to force the client to update
resendMushroomStates(event.getSourceBlock());
}
}
private void resendMushroomStates(Block block) {
Location loc = block.getLocation();
for (int x = loc.getBlockX() - 10; x < loc.getBlockX() + 10; x++) {
for (int y = loc.getBlockY() - 10; y < loc.getBlockY() + 10; y++) {
if (y < 1) continue;
for (int z = loc.getBlockZ() - 10; z < loc.getBlockZ() + 10; z++) {
if (block.getType() == Material.BROWN_MUSHROOM_BLOCK || block.getType() == Material.RED_MUSHROOM_BLOCK
|| block.getType() == Material.MUSHROOM_STEM) {
BlockData blockData = block.getBlockData();
MultipleFacing multiFacing = (MultipleFacing) blockData;
multiFacing.setFace(BlockFace.UP, multiFacing.hasFace(BlockFace.UP));
multiFacing.setFace(BlockFace.DOWN, multiFacing.hasFace(BlockFace.DOWN));
multiFacing.setFace(BlockFace.NORTH, multiFacing.hasFace(BlockFace.NORTH));
multiFacing.setFace(BlockFace.SOUTH, multiFacing.hasFace(BlockFace.SOUTH));
multiFacing.setFace(BlockFace.EAST, multiFacing.hasFace(BlockFace.EAST));
multiFacing.setFace(BlockFace.WEST, multiFacing.hasFace(BlockFace.WEST));
block.setBlockData(multiFacing);
}
}
}
}
}
I am trying to cancel the mushroom block state update but for some reason it still changes
have you tried debugging it if it does happen for mushrooms on that event?
it is fired yes
How the best metod to set all chunk to max bright? (max light and max skylight)
not sure mate, i've rarely used that event
Thank you it works now it was windows defender, ill see if I can join or it's still giving me the same error
Now it's giving me this infinite error and won't let me join, timed out @mortal hare
anyone that can help me out here?
it's really weird, the event cancel should work by itself
some kind of powerranks plugin cause errors
what java version have you got on your computer
some software just vomits errors when it seems older or newer java version
openjdk version "1.8.0_282"
minecraft version?
1.16.5
this error wasn't happening but as soon as i installed essentials everything is ruined
aight
why wouldnt you restore the blockstate whenever someone breaks or places mushroom blocks
yes
but you can listen to onBlockBreak or onBlockPlace events and check if block is mushroom type
if its is restore the blockstate
??
still it changes the blocks around it
because that is how the mushroom block works
what's stopping you to check 3x3 block area around the broken block
that is why I need to listen to the BlockPhysicsEvent
then it will change the ones around the ones that are placed and again and again
you only need to change 6 block's blockstates
since it only changes the blocks around the broken or placed block
if that's not an option for you and spigot doesn't work
try to listen to the packet which changes the block type
and create your own custom bukkit event
or handle it from there synchronised to the main server thread (BukkitRunnables)
What the best metod to set all chunk to max bright? (max light and max skylight)
Never done it so i don't know if spigot api supplies light api
but you can do it manually via NMS i think
this will change the block states of the changed blocks around it
Hey, can someone help me to find out how could I change the crafting slots of the player inventory ?
Cause it seems that it is a sort of view and can't get the actual slot
if its for example a 100x100 and you place one in the center
you will have to change for each one of those blocks the block state because when you update one it will update the others again and again
idk what you're talking but it only changes the blockstates around the broken block
unless this is different in older versions of minecraft
if it would work like that, i would be lagging p2w creative server straight away
heck no need for creative servers, you can do it in survival with silk touch enchantment and a big ass area
p2w? creative?
if you change the state of a block
the others around it will change
well maybe mushroom blocks don't fire that event, but block around it like for example do
i dunno
im running one a 64 bit operating system, I downloaded the 64 bit java sdk 11 but it doesn't open
it confirms that it will change stuff on this pc, I click yes and it won't open
even in task manager there is nothing
alright
i've never heard about this too
are you sure you haven't downloaded some kind of trojan virus?
bruh
i use amazon coretto
why does everybody assume that when something doesn't work it's immediately a virus
why not just use adoptopenjdk smh
because first signs of RAT or trojan is to hide itself
because the download speeds of adoptjdk were slow
when i downloaded it
How can i make nametag prefix? I tried with scoreboard teams, but when i make prefix type "&cPREFIX " so the player's name is still white
How could I make something run every few seconds?
use ChatColor enums
BukkitRunnable
yeah i make it witch chatColor, but the result is the same
This tutorial will guide you in using the scheduler provided by bukkit. It will allow you to defer the execution of code to a later time. This is not the same as registering a Listener, a block of code which is executed in response to an event in the game. Blocks of code may also be scheduled to be executed repeatedly at a fixed interval, with o...
is there any way to set only 1 heart of absorption ? (the potion effect is minimum 4 hearts) ?
well, damage the player
use scaledhealth method
he will take knockback
or send the packet
good point
never heard about it
#player.setHealthScale(double scale)
hoooo
this will scale your health bar
well okay but i wanna have the visual effect of the absorption
more hearts or less hearts
that's half a heart btw
4 = 2 hearts
2 = 1 heart
yeah sorry wrong word
i don't know much of the potion api of bukkit, but you could also send packet which sets the health of player, but its synced with the server so if you set it to 0 hearts, the player dies
but the setHeal method change permanant heart not absorption heart
in ealier days of minecraft you could've glitched the minecraft client in to removing the health bar
miss that glitch so much
i think you couldn't set it normal hearts to the absorption ones if you're talking about it
you can set it to wither ones or hardcore ones tho
if you're talking one absportion heart above the normal hearts then yes you can
but im not sure if spigot api allows it
or you need to handle it yourself
im not an expert in spigot api
with packet ?
yes but im not sure, there could be a better way to do that
hmmm
and im pretty sure there is
nope
I have my antivirus run 24/7
well
and btw, restarting doesn't fix it
what an ass hole i am
#DamageableEntity.setAbsorptionAmount(double amount)
What Absorption means?
Thanks
its a potion effect
thanks for help this is what i need
np
yo I fixed it
one of powerranks's ymls was corrupted
thanks dovidas for the help : )
How can I send an actionbar to somebody
np
Packets or Spigot API
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, someComponent);
oh
how strange it looks
but at the same time correct
Message can be sent via action bar, title, subtitle, chat
So for example
Player player = ...;
BaseComponent[] components = new ComponentBuilder().append("Some text").create();
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, components);
so its better to group them i guess
Ty
Whoever thought of that component api integration, hands down
But enum name shouldn't be ChatMessageType
Chat is the type of message
in this case
name makes no sense
but i guess this was left out because of bungeecord component api
before it was integrated with other types of messages
public String getTexture(final UUID u) {
URL urlUUID = null;
try {
urlUUID = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + u + "?unsigned=false");
} catch (MalformedURLException ignored) {
}
try {
InputStreamReader reader = new InputStreamReader(urlUUID.openStream());
JsonObject json = new JsonParser().parse(reader).getAsJsonObject().get("properties").getAsJsonArray().get(0).getAsJsonObject();
return json.get("value").getAsString();
} catch (IOException e) {
return null;
}
}
need a method that doesn't kill tps 😬
It should be ^^ it's all the same packet
https://wiki.vg/Protocol#Chat_Message_.28clientbound.29
It "kills TPS" because you make a web request synchronously. Put it inside a CompletableFuture that you run async and you're fine.
Hi, I have this code:
List<ItemStack> drops = event.getDrops();
String items = drops.stream()
.map(it -> String.format("%d %s",it.getAmount(),it.getType()))
.collect(Collectors.joining(", "));
``` that prints me this: `1 IRON_SHOVEL`
And I want to print me this: `:iron_shovel: x1`
How can I do that?
and to use the return of a completablefuture?
just change your format and lowercase the get type ?
such as passing the result string type as the texture of an item
i'm not sure how to incorporate .thenAccept in there
CompletableFuture.supplyAsync(() -> {
// ... web request
return "texture";
}).thenAccept(result -> {
player.sendMessage(result);
});
Be careful though, you're not on the main thread in #thenAccept, so you might need to call some API through BukkitScheduler#runTask.
what prevents you from doing something like this ```java
String items = input.stream()
.map(item -> String.format(":%s: x%d", item.getType().toString().toLowerCase(), item.getAmount()))
.collect(Collectors.joining(", "));
gui.setItem(13, getTexture(visiting.getUniqueId()).thenAccept(texture -> {
createSkull(texture, 1, "&avisit", "&7Player: " + inst.getRankedName(visiting));
}));
public CompletableFuture<String> getTexture(final UUID u) {
CompletableFuture<String> result = new CompletableFuture<>();
try {
InputStreamReader reader = new InputStreamReader(new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + u + "?unsigned=false").openStream());
JsonObject json = new JsonParser().parse(reader).getAsJsonObject().get("properties").getAsJsonArray().get(0).getAsJsonObject();
result.complete(json.get("value").getAsString());
} catch (IOException e) {
result.completeExceptionally(e);
}
return result;
}
look right?
cause apparently i'm doing something wrong with the first line (:
but your getTexture method is still on the main thread
why use a completable future then
Well gui is an Inventory I am guessing ?
yes
it expects an ItemStack not a CompletableFuture<ItemStack>
so you will have to either CompletableFuture#join
which holds the thread you call this on until the future resolves
sounds like we're not doing that
Yeah xD
tho joining would kinda defeat the purpose
because then you could just run all of this on the same thread anyway
so I guess you would more do a
getTexture(...).thenApply(texture -> createSkull(...)).thenAccept(skullStack -> gui.setItem(13, skullStack))
try calling that with somehting like this
why two then accepts? one is enough lol
idk the entire point of reactive programming is splitting these up no ?
and doesn't block the main one
Is there a way I could stop a projectile from damaging a specific plaer
Hi, is there an event triggered by the usage of the crafting recipe ?
if(!(sender instanceof Player)){
return false;
}
Player player = (Player) sender;
if(args.length == 1){
try{
String argsValue = args[0];
float FlySpeed = Float.parseFloat(argsValue);
player.setFlySpeed(FlySpeed);
}catch (Exception e){
player.sendMessage(ChatColor.RED + "Please use a float value !");
}
}
return true;
}```
this is supposed to change the flyspeed to the input value but somehow it throws an error each time
Don't catch exception in abstract Exception form
event entitydamagebyentity e.setCancelled(true);
it can lead to bad both in bad code reading quality and some problems, like when threads fails
etc
ok is there a way i can verify if the input value is a float ?
public class main extends JavaPlugin {
private World world;
@Override
public void onEnable() {
World delete = Bukkit.getWorld("world_the_end");
File deleteFolder = delete.getWorldFolder();
World unload = Bukkit.getWorld("world_the_end");
unloadWorld(unload);
deleteWorld(deleteFolder);
}
@Override
public void onDisable() {
}
public void unloadWorld(World world) {
this.world = Bukkit.getWorld("");
if(!world.equals(null)) {
Bukkit.getServer().unloadWorld(world, true);
}
}
public boolean deleteWorld(File path) {
if(path.exists()) {
File files[] = path.listFiles();
for(int i=0; i<files.length; i++) {
if(files[i].isDirectory()) {
deleteWorld(files[i]);
} else {
files[i].delete();
}
}
}
return(path.delete());
}
}
it deletes the end every time the server starts up, but it dosent create it again so i tried setting the plugin to run before the world was loaded but since the location of the world is received only after the world it loaded, it dosnet work, so it there any way to hardcode the location of then end dimension or recreate the world after it has been deleted
try using #String.trim()
for an argument
and see if it works
wdym by location of world
folder path location? @prime nimbus
yes
try{
String argsValue = args[0].trim();
float FlySpeed = Float.parseFloat(argsValue);
player.setFlySpeed(FlySpeed);
}catch (Exception e){
player.sendMessage(ChatColor.RED + "Please use a float value !");
}
}```
like that ?
yes
well you can use plugin's data folder path location and traverse it back two folders to get root location of your minecraft server folder
im not sure on how to do that
it stills throws an error
sorry im pretty new to java
File endFolderLoc = new File(#Plugin.getDataFolder().getParentFile().getParentFile(), "world_the_end")
if you are that new that you don't know basic Java API stuff, then you probably should be learning more about said API that is part of the language you want to learn.
what input do you input it?
oh okay, ill try it
/speed 10.0
try adding f to the back
why is this happening (bungeecord)
this is a tabexecutor thingy
but when i try typing "un"
or try using Float.valueOf() instead
it doesnt recommend unsponsored
@gritty mist
still doesnt work
have you tried switching clients?
wdym
or maybe you send the tab completion every letter?
how do i do that
i have this in my command class
@Override
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
List<String> names = new ArrayList<>();
for (String s : BanManager.getBanManager().config.getKeys()) {
String name = BanManager.getBanManager().config.getString(s + ".name");
names.add(name);
}
return names;
}```
this is my first time using tabexecutor/tabcomplete
Try saving the names in lowercase
so idk how to use it
i think its casesensitive
it doesnt work with the valueof to
unless I wrote it wrong
float FlySpeed = Float.valueOf(Float.parseFloat(argsValue));
lets try it
you don't need trim() in this case
ParseFloat is raw type of valueOf(), it has more strict rules
that's why probs it didn't worked
so if i want to slow down a bit can I write ?
float flySpeed = Float.valueOf(argsValue)/10;
why is this happening (bungeecord)
https://cdn.discordapp.com/attachments/741875863271899136/834170095743926362/unknown.png
this is a tabexecutor thingy
but when i try typing "un"
it doesn't suggest "Unsponsored"
i have this in my command class
@Override
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
List<String> names = new ArrayList<>();
for (String s : BanManager.getBanManager().config.getKeys()) {
String name = BanManager.getBanManager().config.getString(s + ".name");
names.add(name);
}
return names;
}```
Have you tried add random tab completion to it?
maybe bungeecord lacks this feature
and you would need to implement it yourself
with contains
idk
Cause you're not filtering out suggestions that don't match the partial string
That's also a pretty slow way of doing it - if you have a lot of bans, that will definitely cause lag on tab complete
What you want to do is keep a cached set/list of bans somewhere
And then when they're tab completed, you filter out ones that do not start with the partial string in the last argument passed
wat. Bukkit Configuration API is Cached. There's MemorySection class dedicated for this
FileConfiguration is just a glorified HashMap that was loaded from a file
Its a wrapper of SnakeYaml
still
the configuration is cached
there's no need to create new references to it
Yeah he is literally fetching potentially hundreds/thousands of values from a hash map every time someone types a character
That's a bad idea
why? map's contains() method time complexity is O(1)
how is that different from hashset
which uses hashmap internally
Because if you cache them in a set the elements are just in there and you can iterate them
Instead of fetching them all from a hash map
Like, yes, hash maps are efficient
But hashing is still an operation that takes much more time than native array access
Iterating a hash set is only marginally slower than iterating an array
well for putting this into list or primitive array your statement correct, but putting it in set is as not efficient as the hashmap
More than just the runtime complexity of an algorithm matters
???
In a set it's already in there
What he's doing is literally going through and fetching each value from a hashmap, essentially
Depends on the element count. Array iteration is several times faster that Set iteration. Dont underestimate that.
Calling get on a hashmap to generate each element
That is significantly slower than just using an already-generated hashset
That for sure
This is true but you do need fast remove from the cache
And an array/list can't provide that
This guy is getting a set of keys, presumably UUID keys, iterating it, and then for each key, fetching a value from a hashmap
so you're saying that everytime hashmap get an instruction to check if it contains the object it calculates all the hashcodes of the objects
that sound inefficient
???
No what the fuck
He is getting the set of UUIDs as keys
(Strings, mind you)
Then generating a list of the banned players by iterating that list and getting each player's name from a hashmap
To generate a hash of each string it needs to iterate all the characters
Is there a way to cancel the autocraft of the crafting recipe book ?
UUIDs are like 48 characters in length, right?
no im talking about hashset vs hashmap performance on contains()
Bro
Oh my god
That's not what we're talking about
HashSet is backed by a HashMap
They are literally the same data structure. HashSet is just a HashMap without values
That's not what I'm talking about
What I'm talking about is that his way of doing it requires hashing potentially hundreds to thousands of elements every time someone types a character
that's what i was talking about but i got confused because he started talking about runtime complexity
Which is going to create a hell of a lot more issues than just iterating a cached HashSet of those same values already fetched
I'm not talking about the runtime complexity
They have the same runtime complexity but his way is still a lot slower because the O(1) operations are much more expensive
Just because it doesn't take more time with more elements doesn't mean it can't still be slow
i got it, i just got confused by your explanation, no worries
One could use a tree approach to calculate all the possible inputs beforehand 😄
So
u
un
und
unde
...
all point to
undermined and undetermined
With depth first traversing and early escaping this would be quite efficient. O(log n)
Yeah you could just get the node for the current partial string
And then iterate the subtree to get the completions
You could technically have an O(1) solution but it would be pretty memory intensive
Storing a list of possible completions at each node
Yeah XD
O(log n) is perfectly acceptable here
Hm..
It's O(n) for the base case
When they haven't typed any characters yet
Then again it's O(n) no matter what you do
Because it has to serialize and send the completions
well i have command node system which acts like it, by iterating the nodes
eh its not the best one
but fits well for me
brigadier is still better
Is it possible to transition the worldborder by position rather then size? Like on warzone how the border moves
Call of Duty in Minecraft!
Pretty much the goal, yes
Hungergames sort of
Setting the center wont transition though. Damn shame
Only the size allows for a transition
why not use a task
Not SMOOTH enough
too damn picky
If you move the border with a task then it should be quite smooth
Hello,
Hello,
im currently making a plugin to change skin texture of a player
@lost matrix Are you MOVING the border's center?
I mean like MIGRATE the border to another center
Not the size
You need to remove the "textures" property then add your own again. Dont forget that it needs a signature.
Yes im moving the center of the border
Very cool, I'll give it a go
@lost matrix yes that im doing
and its works well
but idk what the best way to reload skin view for other player
simply hide and show ?
and for a self view
teleport to other world and come back if you want it to be simple
You need to. There is no other way.
But i would simply use
player.spigot().respawn();
that i was doing but i didnt know if it was a good way
respawning looks a better way
I dont think there is a better way.
- Change the GameProfile using nms or reflections
- Respawn the player using spigot API
is nms better than reflections
or just different way
im doing it with nms right now
nms makes your plugin only viable for one exact version.
Using reflections might make it compatible with multiple ones.
You can also use a multi module setup to write the same code for each version and implement an interface that is used in your plugin.
But reflections are risky and will be slower if you dont cache them
okok ty for your explanation
I will look more details on the internet
ive tried with player.spigot().respawn();
but it looks to doing nothing
so how cand i o pls ?
its works pretty well when im teleporting a player to another dimension then tp him back to his original position
but it dont looks like clean to do it like that
What’s the difference between a hash set and arraylist? In terms of the data it stores?
@quaint mantle HashSet = wrapper for HashMap. So O(1) gets/puts/removes
Arraylist is a wrapper for an array. So just a generic list
Alright cheers
If you're just iterating the data, use an arraylist. Otherwise, a hashset
Cheers
Is there a way to have a chat click that runs code rather than just a command?
🤷 why not have a command that runs code
I'd just prefer not to register a command if I can avoid it
Only with some trickery. So you would still need a command but with a dynamically generated secret that is mapped to a delegated function
So like, I could make an api for it that does it or something maybe? I'd need an interface I think
Using one of the functional interfaces should suffice
Map<String, Consumer<Player>>
Ah okay, I've not actually used Consumer before but let me look at it, probably is what I need
You can check PlayerPreProcessCommandEvent Or check for the click in chat.
Well I'm gonna probably do that anyways, but I need to register the command. Which is fine. Why would I need to use Consumer actually @lost matrix? I just need to run code, couldn't I use like Runnable or something?
Don't have to register the command if you check the pre event
Ill write you and example of the thing i just thought of.
Okay awesome thx
I haven't put must testing into PlayerPreProcessCommandEvent but is it possible to have tab completions?
Hey, how would I access for example the playerList string from the Bungee plugin message in other places around my plugin?
I have the actual thing done that gets the player list and then the subchannel listener, but just unsure on how to get that string..
Either pass it down to your other instances in a reactive way or cache it using a Map<>
Normally you would use a system, where one instance requests the name and sends a Callback
or Consumer<String> with the request which later consumes the received name.
Ok so it works and the user can only click the message once. After that clicking is useless.
Yea I mean as long as that's per user and not just 1 click over all that's probably fine
iconic username
https://gist.github.com/Flo0/e3730a8f8ba0dd58aa91b0d528777966
This is how ive done it. Quite compact actually
Klick???
Hello. Doing webhook programming right now. Everything works well, one question though: For setting the image/thumbnail, you need a String (a url to the image). Which image hosting website do you guys suggest?
In the onJoin method you can see how to assemble such a command
If I were to put it all into the actual subchannel listener, would I just be able to output playerList from there or would that not work at all?
Dont do that. Separation of concerns. A listener should only listen and then pass its results to other classes.
Ah I see how it works
Alright, sorry still am a bit confused on all of the other stuff you said though
Ill write you and example
Alright
Would anyone know why setSitting() wouldnt be working for me? I’ve confirmed that the code works entirely and there are no errors whatsoever. The wolf in question just wont stand up
This one would be used for executing something with the players IP for example:
https://gist.github.com/Flo0/9c0bbf1c4f175ec924353c079169aad1
You could also design this to use a CompletableFuture.
Alright thank makes more sense, thanks. Also, would I have to just make a new class for each one if I use multiple things or could I put it all in one somehow?
But at second glance this looks quite complicated... Non linear programs can get confusing quite fast.
You could probably throw them all in one class. But separation is way cleaner.
Yeah that's understandable, thanks
hello
whats going on with spigot api
i got this error
Could not find spigot-api-1.16.5-R0.1-SNAPSHOT.jar (org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT:20210411.223231-46). Searched in the following locations: https://hub.spigotmc.org/nexus/content/repositories/snapshots/org/spigotmc/spigot-api/1.16.5-R0.1-SNAPSHOT/spigot-api-1.16.5-R0.1-20210411.223231-46.jar
Are you using maven?
First of all the scope should be compileOnly instead of implementation
still the same
Then you need to include the sonatype repositories
maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' }
maven { url = 'https://oss.sonatype.org/content/repositories/central' }
still the same
No idea then... run BuildTools once on your machine
Ok nice
No idea then... run BuildTools once on your machine
where is BuildTools ?
?bt
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
'registerEvents(org.bukkit.event.Listener, org.bukkit.plugin.Plugin)' in 'org.bukkit.plugin.PluginManager' cannot be applied to '(com.synth.tns.PlantSapling.EventsClass)'
Whata does this mean?
Does EventsClass implement Listener?
public class PlantSapling implements Listener {
public void createBoard(Player player) {
ScoreboardManager manager = Bukkit.getScoreboardManager();
Scoreboard board = manager.getNewScoreboard();
Objective obj = board.registerNewObjective("Saplings", "", "Saplings Placed");
obj.setDisplaySlot(DisplaySlot.SIDEBAR);
}
public static class EventsClass implements Listener {
private final Map<UUID, Integer> saplingMap;
public EventsClass() {
this.saplingMap = new HashMap<>();
}
@EventHandler
public void onPlayerPlantSapling(BlockPlaceEvent e) {
if (e.getBlockPlaced().getType().toString().endsWith("SAPLING")) {
if (this.saplingMap.containsKey(e.getPlayer().getUniqueId())) {
int placed = this.saplingMap.get(e.getPlayer().getUniqueId()) + 1;
this.saplingMap.remove(e.getPlayer().getUniqueId());
this.saplingMap.put(e.getPlayer().getUniqueId(), placed);
System.out.println(this.saplingMap);
System.out.println(e.getPlayer() + " placed a sapling");
} else {
this.saplingMap.put(e.getPlayer().getUniqueId(), 1);
}
}
}
}
}```
Latest
how you use latest spigot api ?
This has nothing to do with object orientation. Pls show how you register the event. And pls unpack this inner class.
Yeah I removed the inner class.
Pls show how you register the event
@lost matrix are you in germany
public final class TNS extends JavaPlugin {
@Override
public void onEnable() {
System.out.println("Wassup");
getServer().getPluginManager().registerEvents(new PlantSapling);
}
@Override
public void onDisable() {
// Plugin shutdown logic
}
}```
...
This wont compile. new <ClassName>(ConstructorParams)
so new PlantSapling() in your case
Also you'll need to provide the plugin instance
.
Pardon?
So new PlantSaplling(), this
Oh
This being the reference to the current instance of your TNS class
Hope you understood why that fixed it 😅
Spigot basically wants to know what plugin is registering the listener here. So besides providing your listener instance (new PlantSappling()) you also need to provide your instance of the Plugin interface which is, when executing from onEnable just this
Just tested a clean gradle project. Works fine.
Make sure to add at least those repos:
repositories {
mavenCentral()
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
}
And this dependency
dependencies {
...
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
}
They are already added btw
inside a pom.xml
Not sure what that is
Is that like a package.json but for java?
Oh
hello how would i add the string? getConfig().addDefault("message"); I have to do something... i just am not sure what
Describe what you are trying to do
im trying to have a onjoin message taht u can change
and i tried manually making the config with creating a file but it didn't work
Ok so there are two approaches for default configurations.
- You just write and put a config.yml in your plugin and then save it when the server starts
- You generate a config.yml from code when the server starts
Which one do you prefer?
its still not working for me
I tried the first one but that doesn't work for me and now im trying to do the second one
but when i created a clean project its working
Then your old project is somehow malformed
I would go for a file that you deliver with the plugin for now. I think thats simpler.
I have tried that but it doesn't work
Lets make it work then.
Do you use maven or do you add spigot to your project manually (as library)
spigot api
Ok so you manually add the spigot api i suppose.
Then go to your src folder and create a new file.
Name it however you want. So messages.yml should suffice.
Content should look similar to this:
messages:
on-join-message: "This is a default message."
ok
malformed ?
player.sendMessage(getConfig().getString("on-join-message"));would it be that?
Then (just to be sure) compile your plugin and open the jar with a compession program like 7zip or winrar to see if the yml is actually in your final jar file.
ok
yup
it shows up
Next you should export the file when your plugin starts.
@Override
public void onEnable() {
setupFiles();
}
private void setupFiles() {
this.getDataFolder().mkdirs(); // Creates plugin folder
this.saveResource("messages.yml", false); // Saves the messages.yml if it doesnt exist
}
create a method named setupFiles() where you handle all your io setup stuff.
Normally you would create a FileManager class that handles all that so your JavaPlugin class doesnt get messy
ok
If this is done. Compile your plugin and run it once with your server. You should then see a messages.yml file in your plugin folder
ok thx
private void setupFiles() {
this.getDataFolder().mkdirs();
this.saveResource("messages.yml", false);
// Create a file variable. This is not the actual file on your hard drive but only a representation for Java to work with
File messagesFile = new File(this.getDataFolder(), "messages.yml");
// Load the content from that file into a FileConfiguration. This reads the whole file at once.
FileConfiguration messagesConfig = YamlConfiguration.loadConfiguration(messagesFile);
// Now you can access all the content using the methods from FileConfiguration
String message = messagesConfig.getString("messages.on-join-message");
// Print out the message we just got from our FileConfiguration
this.getLogger().info(message);
}
Thank you @eternal night and @lost matrix! My first ever plugin works
I am so happy
Now I just need to find a way to parse the stuff onto a scoreboard
Alright, so I have the player list fetcher working (I think) now it's a matter of trying to figure out how to access it from another class. The actual event is called in onEnable(), but this is just losing me
Yeah thats just ugly. Mind sharing your list fetcher as well as the method where you want to use it?
Yeah sure let me upload it to github or smtn
so what would I put in the onjoin event?
Mind the messy shit:
https://gist.github.com/PrinceBunBun981/dc56752542b62efcd4f389b231d99b49
whatt
I see that it would print out the message but would I just put that in the event method?
You first need to somehow gain access to the FileConfiguration you just created. For this you could create a field in your JavaPlugin class.
Then you need to pass the FileConfiguration in the construcor of your listener class like this:
public class SpigotCore extends JavaPlugin {
private FileConfiguration messagesConfiguration;
@Override
public void onEnable() {
this.setupFiles();
JoinListener listener = new JoinListener(messagesConfiguration);
Bukkit.getPluginManager().registerEvents(listener, this);
}
private void setupFiles() {
this.getDataFolder().mkdirs();
this.saveResource("messages.yml", false);
File messagesFile = new File(this.getDataFolder(), "messages.yml");
this.messagesConfiguration = YamlConfiguration.loadConfiguration(messagesFile);
}
}
Or you create a getter method in your JavaPlugin class so you can get the FileConfiguration from other classes like this:
public class SpigotCore extends JavaPlugin implements Listener {
private FileConfiguration messagesConfiguration;
@Override
public void onEnable() {
this.setupFiles();
JoinListener listener = new JoinListener(this);
Bukkit.getPluginManager().registerEvents(listener, this);
}
private void setupFiles() {
this.getDataFolder().mkdirs();
this.saveResource("messages.yml", false);
File messagesFile = new File(this.getDataFolder(), "messages.yml");
this.messagesConfiguration = YamlConfiguration.loadConfiguration(messagesFile);
}
public FileConfiguration getMessages() {
return this.messagesConfiguration;
}
}
ok thanks
Ok so first of all playerList.toString() This will just print out the memory location of that array.
You are converting a String to a String[] and then back to a String. Just let the playerList variable be a String.
Only thing is the actual output is String[] playerList = in.readUTF().split(", "); (according to the messaging docs at least)
Then the correct usage of your current setup would be
final Player player = (Player) sender;
this.playerListFetcher.fetchPlayerListAndExecute(player, (server, playerList) -> this.sendList(player, server, playerList));
It should work but its quite hard to understand.
in.readUTF() returns a String
in.readUTF().split(", "); splits this String at each comma and makes an array out of it
Alright, so thankfully when removing .toString() the errors went away, but lemme test it
Okay, so I got ALL: [Ljava.lang.String;@46088d50 in game as the message and a null pointer exception in the console. (https://paste.helpch.at/tejedufeqe.bash)
Oh I'm a dumbass
Still had .toString() in the consumer thing, now that I've changed String[] to just String
Thats the memory location of your array (as i told you)
And you should only have one exact instance of PlayerListFetcher because currently each time you execute the command you register
a new channel and a new listener. Which is a straight memory leak. So create one instance of PlayerListFetcher in your onEnable
and pass it to other instances where this instance is needed.
Yes.
Replace final String[] playerList = in.readUTF().split(", "); with final String playerList = in.readUTF();
Yeah, just re-read one of your previous messages (once again dumbass me)
All good
Alright! Sends the message with all players, also removed it making a new one, thanks for putting up with me lmao
i have a question, its not about spigot, but its about plain java
is an initilized string with nothing in it null?
No
String string = null; is null...
String string = ""; is not null.
np
String string; is null
will this work?
yes
da fk is this
basically what i want to do is remove a uuid from a list called stalkers
what bit am i looking at
no wait
this part
if (invalidPlayers.toString() != null && alreadyStalker != null) {
player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except " + alreadyStalker.toString() + ",because these players are already not stalkers, and also except " + invalidPlayers.toString() + "because these players are invalid!");
} else if (invalidPlayers.toString() != null && alreadyStalker == null) {
player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except" + invalidPlayers.toString() + ",because these players are invalid!");
} else if (alreadyStalker.toString() != null && invalidPlayers.toString() == null) {
player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except" + alreadyStalker.toString() + ",because these players are already not stalkers!");
} else {
player.sendMessage(ChatColor.GREEN + "Removed all players successfully!");
}
idk why it pasted like that
right
lemme try again
Because you dont respect the character limit
if (invalidPlayers.toString() != null && alreadyStalker != null) {
player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except " + alreadyStalker.toString() + ",because these players are already not stalkers, and also except " + invalidPlayers.toString() + "because these players are invalid!");
} else if (invalidPlayers.toString() != null && alreadyStalker == null) {
player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except" + invalidPlayers.toString() + ",because these players are invalid!");
} else if (alreadyStalker.toString() != null && invalidPlayers.toString() == null) {
player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except" + alreadyStalker.toString() + ",because these players are already not stalkers!");
} else {
player.sendMessage(ChatColor.GREEN + "Removed all players successfully!");
}
o
ok anyways
If this happens then you need to overthink your design.
ok
also please change that if statement with getOnlinePlayers()
ok
@EventHandler
public void onTryShoot(EntityShootBowEvent e) {
if (e.getEntity() instanceof Player) {
Player p = (Player) e.getEntity();
e.setCancelled(true);
}
}
this takes arrows out of the player's inventory, now instead of just adding an arrow back into it, how do i fix this efficiently?
declaration: package: org.bukkit.event.entity, class: EntityShootBowEvent
thanks
And pls rename your event frome to event
Single character variables are a disease that needs to be stopped.
i'll search and find for my entire project (:
Also p -> player
private void doBlockEater(final Player player, final Block startingBlock, final int amount) {
if (startingBlock.getType() == Material.AIR) return;
final Material targetMaterial = startingBlock.getType();
final ItemStack item = new ItemStack(targetMaterial, 1);
final ArrayList<Block> blocksToCheck = new ArrayList<>();
blocksToCheck.add(startingBlock);
Bukkit.getScheduler().runTaskAsynchronously(getInstance(), () -> {
while (!blocksToCheck.isEmpty()) {
int blocksToRemove = 0;
final Block block = blocksToCheck.get(0);
blocksToCheck.remove(block);
if (block.getType() == targetMaterial) {
for (final BlockFace blockFace : faces) {
blocksToCheck.add(block.getRelative(blockFace));
}
if (block.getType().name().contains("LOG")) {
player.getInventory().addItem(item);
block.getWorld().playSound(block.getLocation(), Sound.DIG_WOOD, 0.3F, 2.0F);
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(getInstance(), () -> block.setType(Material.AIR), 3);
}
blocksToRemove++;
}
if (blocksToRemove >= amount) blocksToCheck.clear();
}
});
}
what is effectively wrong with this method of cutting down an entire tree but with an interval of 3 ticks per second of producing an animation of breaking the log block
considering, it used to work better on my old slower system then i upgraded, and it's worse. but even before, it would give me way too many logs filling up my entire inventory after around 20 blocks broken
You're scheduling the removal of all the blocks 3 seconds later
I think u want to schedule the removal 3 seconds after the previous removal
yeah
but that wouldn't even answer for the reason why my inventory fills up completely and my ears are bloated with emotion
only from 10 blocks worth of logs
for the blocksToCheck?
hi y'all, im completely new to plugin making so excuse the basic question.
so far i have a working command '/power [target]', but right now it's empty and just sends a message to the player. what I want the command to do is store the target player's UUID in an arraylist somewhere that persists through server resets. how would you guys go about this?
through server resets?
restarts
Queue<Block> blocks = new LinkedList<>();
blocks.add(startingBlock);
int count = 0;
while (!blocks.isEmpty() && count++ < maxRemovedBlocks) {
Block block = blocks.remove();
if (block is target) {
// ... same code you have
}
if (is log) {
runLater(plugin, () -> {
// add item and remove block
}, count * 60);
}
}```
Yes
arraylists are tied to memory, and memory is reset after /rl, /restart, /stop, the process ceasing to exist blah
you can write it to a file
Lemme see the javadocs because i dont remember the method names
and parse that onEnable()
this'll help you
yessuh
ah i'll try that
and lyk
@rugged topaz would i just be putting this in my main class? does it matter where?
what is lyk
let you know
ah
for that matter it's preferable that it is in your main class
and if your main class is called Main, Plugin, consider changing it (:
i was told that naming it main was standard? is there a specific reason
ambiguity
and that's not true
just call it the name of your plugin
private void doBlockEater(final Player player, final Block startingBlock, final int amount) {
if (startingBlock.getType() == Material.AIR) return;
final Material targetMaterial = startingBlock.getType();
final ItemStack item = new ItemStack(targetMaterial, 1);
final Queue<Block> blocks = new LinkedList<>();
blocks.add(startingBlock);
Bukkit.getScheduler().runTaskAsynchronously(getInstance(), () -> {
int count = 0;
while (!blocks.isEmpty() && count++ < amount) {
Block block = blocks.remove();
if (block.getType() == targetMaterial) {
for (final BlockFace blockFace : faces) {
blocks.add(block.getRelative(blockFace));
}
count++;
}
if (block.getType().name().contains("LOG")) {
Bukkit.getScheduler().runTaskLaterAsynchronously(getInstance(), () -> {
player.getInventory().addItem(item);
block.getWorld().playSound(block.getLocation(), Sound.DIG_WOOD, 0.3F, 2.0F);
player.playSound(player.getLocation(), Sound.SUCCESSFUL_HIT, 1.0F, 1.8F);
givePlayerForagingXP(player);
block.setType(Material.AIR);
}, 1 * 60);
}
}
});
}
@sudden raft
how's this
Conventional standards are naming your main class something informative
remove the count++ inside the if
It's already done in the while(...)
whoops
Also it's not necessary to run everything asynchronosuly
it's not possible to run everything async ;)

Bukkit.getScheduler().runTaskLaterAsynchronously(getInstance(), () -> {
player.getInventory().addItem(item);
block.getWorld().playSound(block.getLocation(), Sound.DIG_WOOD, 0.3F, 2.0F);
player.playSound(player.getLocation(), Sound.SUCCESSFUL_HIT, 1.0F, 1.8F);
givePlayerForagingXP(player);
block.setType(Material.AIR);``` *psst* You shouldn't be messing with the Bukkit API async, this code won't even work
so just
why's that?
you're trying to modify the world async
oo oohoohh
pretty sure you can't even play sounds async either
it shouldn't work
could it work if u disable the AsyncChecker?
i dont remember the class name hahaha
🤷 never tried it
I don't like using async that much, I run everything on the main thread, even Thread.sleep /s
🤨
try running it sync
as for the two async's tho, remove the first one? or
the nested one
or the first
the nested
private void doBlockEater(final Player player, final Block startingBlock, final int amount) {
if (startingBlock.getType() == Material.AIR) return;
final Material targetMaterial = startingBlock.getType();
final ItemStack item = new ItemStack(targetMaterial, 1);
final Queue<Block> blocks = new LinkedList<>();
blocks.add(startingBlock);
Bukkit.getScheduler().runTaskAsynchronously(getInstance(), () -> {
int count = 0;
while (!blocks.isEmpty() && count++ < amount) {
Block block = blocks.remove();
if (block.getType() == targetMaterial) {
for (final BlockFace blockFace : faces) {
blocks.add(block.getRelative(blockFace));
}
}
if (block.getType().name().contains("LOG")) {
Bukkit.getScheduler().runTaskLater(getInstance(), () -> {
player.getInventory().addItem(item);
block.getWorld().playSound(block.getLocation(), Sound.DIG_WOOD, 0.3F, 2.0F);
player.playSound(player.getLocation(), Sound.SUCCESSFUL_HIT, 1.0F, 1.8F);
givePlayerForagingXP(player);
block.setType(Material.AIR);
}, amount * 40L); // count * 2 seconds interval
}
}
});
}
current code
still async huh
it's not
haha
for some reason, it only breaks 1 block tho
oh and now
almost a minute later
it's working in pairs of 2 blocks every 2 seconds
almost what it's meant to? but completely broken nonetheless
oh frick
the timing's heavily inaccurate
idk why we're multiplying count by 2 seconds
if it's meant to be at a 2 second interval per block
or even, 4 ticks
there any methods for getting ping without using nms?
i dont think so
because the tasks are being scheduled at the same time
so, first block waits 2 seconds to be removed, the next waits 4, and so on
Bukkit.getScheduler().runTaskLater(getInstance(), () -> {
block.setType(Material.AIR);
player.getInventory().addItem(item);
block.getWorld().playSound(block.getLocation(), Sound.DIG_WOOD, 0.3F, 2.0F);
player.playSound(player.getLocation(), Sound.SUCCESSFUL_HIT, 1.0F, 1.8F);
givePlayerForagingXP(player);
}, count * 1L); // count * 1 tick per block
fr some reason
this is just too slow
and i'm not sure if that's to do with the fact that it's sync
but probably
@sudden raft
slow?
Try this thing
public class BlockEaterTask extends BukkitRunnable {
private static final EnumSet<BlockFace> DETECTION_FACES = EnumSet.of(
BlockFace.NORTH,
BlockFace.SOUTH,
BlockFace.EAST,
BlockFace.WEST,
BlockFace.UP,
BlockFace.DOWN
);
private final int hardCheckLimit;
private final Set<Block> checkedBlocks;
private final Queue<Block> blockQueue;
private final Predicate<Block> filter;
private final Consumer<Block> action;
public BlockEaterTask(final Block startBlock, final int hardLimit, final Consumer<Block> action, final Predicate<Block> blockFilter) {
this.hardCheckLimit = hardLimit;
this.checkedBlocks = new HashSet<>();
this.checkedBlocks.add(startBlock);
this.blockQueue = new ArrayDeque<>();
this.filter = blockFilter;
this.action = action;
}
@Override
public void run() {
if (this.blockQueue.isEmpty() || this.checkedBlocks.size() == this.hardCheckLimit) {
this.cancel();
return;
}
this.next();
}
private void next() {
final Block nextBlock = this.blockQueue.poll();
for (final BlockFace face : BlockEaterTask.DETECTION_FACES) {
final Block surrounding = nextBlock.getRelative(face);
if (this.checkedBlocks.contains(surrounding)) {
continue;
}
this.checkedBlocks.add(surrounding);
if (this.filter.test(surrounding)) {
this.action.accept(surrounding);
this.blockQueue.add(surrounding);
}
}
}
}
um does EntityDamageByEntityEvent give the kb that the player has recieved ?
i dunno how i'd use that tbh
while (!blocks.isEmpty() && count++ < amount) {
Bukkit.broadcastMessage(count + "");
printing count immediately sends 35 messages (in my instance) from 0-35, so i'm pretty sure at that point count = 35, which is equal to the amount i pass in
Yes it's correct
forsure?
yes, read this
mhm ik
but idk why it'd immediately find its way to count = 35 whilst it hasn't broken a single block yet
ahh understand why now
but still undesired result :/
how are u calling the method?
blockbreakevent, if the block is equal to type of log, if the player has the intended item in their hand, and if they're in the intended spot, doBlockEater(e.getPlayer(), e.getBlock(), 35)
should be nothing wrong
w that
Hmm
Example:
public void destroyStone(final Block startBlock, final JavaPlugin plugin) {
final BlockEaterTask task = new BlockEaterTask(startBlock, 100, Block::breakNaturally, bl -> bl.getType().equals(Material.STONE));
task.runTaskTimer(plugin, 1, 1);
}
i'll try it
hey you made this for me some months ago, i really appreciate it (especially now when i understand it more, lol)
the block iterator
Dont remember ^^ but you are welcome 😄
A i see ^^
if (this.blockQueue.isEmpty() || this.checkedBlocks.size() == this.hardCheckLimit) {
Bukkit.broadcastMessage("cancel");
this.cancel();
return;
}
seems like it's always cancelled
isn't blockQueue gonna be empty if it's initalized empty regardless?
Uhm. The first block should be inserted in the queue in the beginning.
the starting block is added to checkedBlocks
Oh nvm. You need to add that in the constructor
this.blockQueue = new ArrayDeque<>();
this.blockQueue.add(startBlock);
just
if (blockFilter.test(startBlock)) {
action.accept(startBlock);
}
At the end of the constructor. idk
that fixed it
but i needa perform multiple things at once,
is it possible to pass that in as a parameter instead of this final Consumer<Block> action?
rather not just cheat it into the actual class
like a lambda of code
Sure. This here would grow all the connected wheat to max age:
public void growWheat(final Block startBlock, final JavaPlugin plugin) {
final BlockEaterTask task = new BlockEaterTask(startBlock, 100, this::growBlock, this::isViableBlock);
task.runTaskTimer(plugin, 1, 1);
}
private boolean isViableBlock(final Block block) {
return block.getType() == Material.WHEAT;
}
private void growBlock(final Block block) {
final BlockData data = block.getBlockData();
if (data instanceof Ageable) {
final Ageable ageable = (Ageable) data;
ageable.setAge(ageable.getMaximumAge());
}
block.setBlockData(data);
}
how would i round up a number to a multiple of 9? i am making a InventoryLib
Wait...
This looks like it should work:
public static int roundUp(final int number, final int base) {
return (Math.floorDiv(number - 1, base) + 1) * base;
}
Now it works...
Just not for 0
thanks a lot
..
how to create custom achievement popups?
i dont understand exactly how to spcify the reciever player
what are u trying to do?
understand plugin messaging
yea i got it but i mean like are u trying to do (Connect, IP, IPother etc.)
nothing yet. i just want to know how it works
u just send messages between spigot and proxy
yeah: for example Connect
ok, the channel is "BungeeCord", the subchannel is "Connect", the argument is "", and the reciever is player???
@quaint mantle is this correct?
yes
ok, thanks
like you write into the argument something like i said for ex. Lobby, Auth
like name of server when u use Connect
any idea how would I stop growing sugarcane and cactus at max
so it doesen't go back to 0 age
when it grows block above
sample of spigot game?
Yes sir
wdym by that
Or anything on spigot
you mean plugins?
Yes
Did you made it
Hey! I saw you were interested in our Java Project of working with the SpigotAPI.
This is a long-term project. We have a current open project of about one year of work. Here is the plugin we are currently working on:
https://docs.google.com/document/d/1wKi4Cr7dHou1JZFjqPwi2GBE-WLGEhF5XYXtWguYlXA/edit
This is also a well-paying and loyal position.
I have a few question, it is okay to be honest, as we are hiring several developers who are interested in this position long-term.
Do you have any experience with SpigotAPI?
Have you played Minecraft?
Could you learn the SpigotAPI?
Do you have experience working in gradle?
What interests you about this job and why do you want this project?
This is just to get an understanding so we can work better together! :D
That's is what am looking for
what
?services
If you wish to request or offer development/art/building/administration services, please do so at https://www.spigotmc.org/forums/services-recruitment-v2.54/
xd
There are multiple issues with your messages my man
yeah like
Do you have any experience with SpigotAPI?
Could you learn the SpigotAPI?
?
- You are asking for services in #help-development
why would you apply for spigot developing when you dont know spigotapi
Am newbie
- You are asking for server help in #help-development
I want to start
- This is not how you hire people
you want to start with what?
How to write Spigot plugins - https://www.spigotmc.org/wiki/spigot-plugin-development/
Meh, that is a bad one
well first of all if you dont know java u should learn it first before working with apis and stuff
https://bukkit.fandom.com/wiki/Plugin_Tutorial_(Eclipse) is a better one
Granted, it is outdated but it does a lot more right
It looks decent
I link the other as it covers more IDEs and should be all anyone needs.
Hi hi, i'm trying to get a config.yml file for bungeecord and I used this example https://www.spigotmc.org/threads/bungeecords-configuration-api.11214/
I get a null pointer error in this line: Files.copy(in, file.toPath());
full method:
private void saveDefaultConfig() {
if (!getDataFolder().exists())
getDataFolder().mkdir();
File file = new File(getDataFolder(), "config.yml");
if (!file.exists()) {
try (InputStream in = getResourceAsStream("config.yml")) {
Files.copy(in, file.toPath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Full class (and yes, I know bungeecord already sends a startup message for the plugin)
https://pastebin.com/nwewHt4P
I'm sure a lot of you don't know about this one hidden gem in BungeeCord. BungeeCord has a Bukkit-style configuration API.
It's simple to use, too,...
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Can anyone explain what i'n doing wrong?
oh and the error
11:47:04 [WARNING] Exception encountered when loading plugin: UltimateStats
java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.nio.file.Files.copy(Files.java:2984)
at me.Michielo.UltimateStats.BungeeMain.saveDefaultConfig(BungeeMain.java:51)
at me.Michielo.UltimateStats.BungeeMain.onEnable(BungeeMain.java:19)
at net.md_5.bungee.api.plugin.PluginManager.enablePlugins(PluginManager.java:250)
at net.md_5.bungee.BungeeCord.start(BungeeCord.java:285)
at net.md_5.bungee.BungeeCordLauncher.main(BungeeCordLauncher.java:62)
at net.md_5.bungee.Bootstrap.main(Bootstrap.java:15)
BungeeMain.java:51
either in or file is null
Alrighty ill mess around with it
yep
And #getResourceAsStream was indeed null, and i found this fourm post https://www.spigotmc.org/threads/getting-file-as-inputstream-within-the-jar.405681/
And tried what they said:
this.getClass().getClassLoader();
try (InputStream in = ClassLoader.getSystemResourceAsStream("config.yml")) {
however this still returns null
Use Java 15+ and you wouldn't be in here anyways
o
The more descriptive Null Pointer Exception messages are really worth to get Java 15+
Objects#requireNonNull(obj,str) 🤡
this forum post
I had that before, but it was null
So i googled and got that forum
Are you trying to save the default Bungee config for your plugin?
yup
Jup
.
null error
If you have then you are missing the config.yml in your plugin jar
happens to everyone at some point 🙂
Ok, I now understood how to send messages from a spigot plugin to the bungeecord system and how to recieve responses. But how to send messages from Bungeecord to Spigot and how to recieve messages on Bungeecord?
Check the plugin message channel API in bungee javadoc but presumably you’d do smtng very similar to what is done in spigot API
What's the difference between InventoryInteractEvent and InventoryClickEvent? (In terms of making GUI menus)
Interact is an abstact event thats used as a base for other Inventory events. It will not be fired itself.
As I just said, interact will never fire. Its an abstract class
look at its subclasses for those that you can listen for
hi! there is a task to get chunks in a certain radius from the player, how can this be implemented?
Explain what you mean by "get chunks"
the player specifies the value in chunks with the command and I need to get all chunks in this radius getChunk()
InventoryInteractEvent wont ever fire it's mainly used for inheritance and convenience
Hey, is there anyway to do so everytime someone dies it comes up with different death message?
Like different death message everytime
yeah
I tried multiple ways but none worked
I made 6 classes, and each one has a different death message
But It's 1 same message from them and it never changes
The reason I ask is teh implementation greatly depends on what you need it for. What do you need the chunks for? To store them, or what?
Show the code. Debug the code.
First class :
public void onDeath(PlayerDeathEvent e) {
if (e.getEntity().getKiller() instanceof Player) {
Player k = e.getEntity().getKiller();
Player v = e.getEntity();
e.setDeathMessage("§6§l" + v.getName() + "§6 was slain by §l" + k.getName);
}
}
}```
class PogConclure implements Listener {
String[] messages = new String[]{"first", "second"};
@EventHandler public void onDeath(EntityDeathEvent event) {
if(event.getEntity().getType() != EntityType.PLAYER) return;
Bukkit.broadcastMessage(messages[ThreadLocalRandom.current().nextInt(messages.length)]);
}
}``` @rapid vigil
And same thing with other classes, but different death message
creating territory protection
claim.isNewRegion(chunk);
Debug. Are the listeners even running?
oh yeha you might wanna set it instead
Thanks Conclure. Appreciate it
take the players location (x,z) / 16 will give you the chunk.
Add half the players given value to get max, minus half to get minimun.
its just two loops then to grab all chunks
public class RandomDeath {
final static String[] message = new String[] { "You died!", "Fatality", "Poor you" };
final static random = new Random();
public static String getMessage() {
return message[random.nextInt(message.length)];
}
}```
What's wrong with Conclure's code though?
Nothing. I didn't see it. Both are just as valid
Thanks a lot appreciate it anyways ;)
public Location getLocationAim(Player p) {
Vector direction = p.getLocation().getDirection();
Location l = new Location(p.getWorld(), direction.getX(), direction.getY(), direction.getZ());
return l;
}
@EventHandler
public void PlayerInteractEvent(PlayerInteractEvent e) {
if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
Player p = e.getPlayer(); Location point = getLocationAim(p);
Bukkit.broadcastMessage("Funcionando ponto: " + point);
particle(EnumParticle.NOTE, point);
}
}
}```
Not sure what you are asking
translator bad
You want the block the player is looking at?
the cross hair is only on the client. It represents nothing on the server
no i mean
when you right-click on the block, you have the location of the block, I wanted the location of the crosshairs on the block
There is a method but I forget what it called. sec
i forgot, i'm on 1.8
ok, not helping with that
Lads what in the hell did you guys do the the project structure of craftbukkit all my branches are no longer compilable
Nothing
@eternal oxide Well Something happened to all my NMS patches none of them are able to apply anymore
Also for some reason my project is unable to import any of the classes in the same package
Can i set more then one Item in an Inventory in one Code Line?
Sounds like you need to clean/invalidate cache on your project
i had an idea, using the direction of the player I could multiply with the distance of the block
and get a location by this vector
Actually a good idea
Still wont fix all my patch files tho but still
ill redo the changes on those because merging patch files is a pain in the first place
Thank you that actually worked to my surprise
Hi guys, can some explain me what dataWatcher is used for?
Can i set more then one Item in an Inventory in one Code Line?
Think events for variables
so, when a variable changes it executes code, right?
correct
setContents()
@eternal oxide Could you help with my patch files ever since we decided to change all of the paths for them none of them work for me anymore and i cant get my root fixed due to that fact
No but you can make a helper method for it
I've not done any patches.
Well darn guess i just nuke my changes and rebuilt them from the ground up
Probs have to move em manually
Does anyone know what it is the variable "a" inside the DataWatcherObject class?