#help-development
1 messages · Page 1359 of 1
That was the whole message, lemme send some later ones
But i think i have an idea thats not as efficient as directly modifying the byte[] but way simpler.
Just creating a copy or snapshot of the chunk and actually modifying the block content of it.
Do you use maven?
Nope. You should have all the NMS classes
Yea, that could work
Oh damn i didnt think of using a custom implementation of ChunkPacketBlockController...
But lets see if we can get it to work using the current way.
Just so that you know, I’m on my phone and boutta go to bed. If you get anywhere with it, probs @ me and I will check tomorrow if I don’t get back to you
Sure. I was also just planning on tinkering with it for a bit ^^
Sure!
package index
how do I make it so that my plugin is compatible with perm plugins? as in if i have luck perms on my server I can give people lets say Plugin.permission?
with an EntityType you can get it's unique id, but how could I get the EntityType with it's id? (that is stored in a data YML file)
I guess using their API?
how would i do that?
The proper way is registering permissions in your plugin.yml
But you can always check permissions using Player#hasPermission
Permission plugins can add any permission to any user regardless of other installed plugins.
search, but basically you can use maven or simply importing the API Jar and insert some code
You cant get any UUID from an EntityType and vice versa.
And you dont need to use maven or import any of luckperms API
You are basically always compatible with any permission plugin.
Using Player#hasPermission is fine. Registering the permission in your plugin.yml is even better.
stand.getEntityId()
Is that from an ArmorStand instance?
yes
UUID entityID = entity.getUniqueId();
// then later
Entity entity = Bukkit.getEntity(entityID);
Player player = (Player) sender;
if(player.hasPermission("modplugin.openED")) {
if(args.length > 0 ){
Player target = Bukkit.getPlayerExact(args[0]);
Inventory ti = target.getEnderChest();
player.openInventory(ti);
}else{
player.sendMessage("Please enter a valid target.");
}
}else{
player.sendMessage("Please get the permission called modplugin.openED");
}``` this is my code, but when using luckperms and even adding the perm manually It doesnt give the person the perms
But each time an entity is spawned again it might get a new UUID
so, entity will be my armorstand, and to get the armorstand from it's own id should be with Bukkit.getEntity(id)?
fine
Are you certain that this code works properly and that you are using the permission plugin correctly?
Does this code work when you are operator?
so if I spawn an armorstand named "Jeff" with the id 123, and there is a zombie that spawns, the armorstand named "Jeff" will change the id to something else?
No. UUIDs are unrelated to Names
yea it works in op, and all the other perms work
getEntity is undefined
What version are you on?
Thats also what i thought...
1.8
Then you misstyped something
Ancient
yikes
where? in lp?
No idea. If it works in op but not when you have the permission then you actually dont have the permission. I just suspect a typo.
1.8 didn't even have UUIDs yet xD
ok copy
like xD
yes it have
XD
It still had entity Id support tho XD
so what can I do to get the armorstand by it's unique id?
I mean I guess use World#getEntitiesByClass(ArmorStand.class)
and then iterate over that list
to find the armor stand
horribly slow
but eh
is for a hologram plugin
Ah. Yes. The O(n) for finding an entity by its ID. The taste of outdated versions.
what?
I would actually not bother writing your own hologram plugin if you are on 1.8
Just use one of the many established ones.
hey so i tried copy pasting the perm from the code to the perms and it still doesnt work for some reason. Any ideas?
ow damn, 1:40 am, all day and night programming XDD
Get a list with all your permissions from luck perms and see if you actually got it.
I don't want you to write my hologram plugin code, I only need to know how can I get the Entity by the unique id
how would I do that?
I think it is like /lp tree <player>
{
"type": "permission",
"key": "modplugin.openEC",
"value": true
}
It is added but still doesnt work
and from the same plugin another command works
modplugin.openEC or modplugin.openED ?
EC
And your code says what?
Ah ok. Make it all lower case.
But it works perfectly fine when you have op?
ye
Then the only explanation is that the user simply does not have the permission.
they do
i checked twice
i gave everyone the command and it still doesnt work
idk
Create a simple check. Maybe on chat event and check for the permission then return if the player has it or not.
@EventHandler
public void onChat(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
String perm = event.getMessage();
String returnMessage = "" + player.hasPermission(perm);
player.sendMessage(returnMessage);
}
how would I check what permissions the user has?
Just write the permission in the chat
ok
And it will return "true" if the player has the permission and "false" otherwise
No. Just copy that code into a Listener class and write the permission in chat
You didnt register the listener
There you go. Didnt set the permission properly...
So its more of a problem with using LuckPerms correctly 😄 thats good news for you
how would I set it properly?
LuckPerms is well documented and im out for today ^^
ok bye
I wouldn't ever recommend /reload (Sorry if thats not the /reload message I'm seeing.)
it looks like it XD
is using a plugin from black spogit can get you arrested??????????????
any1 on rn fucc wit jooq? .-. if so how good is it at async stuff
yes, and if u go to a jail where theres a dev gang theyll cut off ur arm for piracy
wtf
dev gangs dont fucc around .-. also dis offtopic
my friend usees black spogit
Yo reload and plugman are two neat features 
smh
You can’t deny they’re
Reloading isn’t bad unless you got a plugin with hella events and things saved in a hash map for whatever reason
what
Reload is the reason events and hashmaps cause issues because their data isn't unloaded.
plug-in
Hmm I haven’t experienced that yapper
Or well maybe cuz I usually create a new instance but ye
literally what I said
Reloading isn’t bad unless
Reloading is bad period... Just restart to make sure no issues are caused.
Anyone know how vault prioritizes economies when there are two present in a server?
Explain to me how it would be bad for a small plugin with 10 commands that do basic function of /gmc etc
I want to get all the boss bars of the server one by one. So I tried various for-each, but all of them failed. How do I get it?(Bukkit.getBossBars())
It's iterator
Just use the iterator as an iterator?
tbh imo overall reloading isn't bad if it's small but it's just easier to restart making sure it'll work
uhh, how to? I learned about iterator but I only know how to print iterator (using while)
while (iterator.hasNext) {
Object whatever = iterator.next
}
ohh thanks
I took all the boss bars of the server with the following code and created the code to output if it contained a player. But as soon as the player comes in, the boss bar is printed out until the server bursts endlessly.
BossBar bossBar = Bukkit.getBossBars().next();
Bukkit.broadcastMessage(bossBar + "");
if (bossBar.getPlayers().contains(player)) {
bossBar.removePlayer(player);
Bukkit.broadcastMessage(bossBar + " remove");
}
}```
(It prints only `Bukkit.broadcastMessage(bossBar + "");`)
ah.. hmm I think you meant this if i understood correct
BossBar bossBar = Bukkit.getBossBars().next();
What?
No that’s the item from the iterator, put the iterator itself into a variable once
ah! I understood thanks
you meant this right? If i understood correct
while (bossBarVarb.hasNext()) {
BossBar bossBar = bossBarVarb.next();
Bukkit.broadcastMessage(bossBar.getTitle() + "");
if (bossBar.getPlayers().contains(player)) {
bossBar.removePlayer(player);
Bukkit.broadcastMessage(bossBarVarb + " remove");
}
}```
Correct
thanks for help
Hey spigot discord, I'm having problem about bossbar. i'm trying to get all bossbars. and it works at only vanilla bossbar (/bossbar add test 1) and it doesn't works on my custom bossbar. (This problem isn't posted on google)
VanillaBossBar creating command:
/bossbar add test 1
custom bossbar creating code:
bar.addPlayer(player);```
thanks for help, and you meant persistent to vanilla thing?
ohhh, I found **not created using createBossBar(String, BarColor, BarStyle, BarFlag...)** thanks,
how to get created using createdBossBar?
ok, thanks for help
player.addPotionEffect(PotionEffectType.ABSORPTION, 120, 4); Is this not correct? I am using a listener with the PlayerItemConsumeEvent
yep, I figured it out, thanks for the help, Im just getting into spigot development
Can't register commands in Spigot plugin (I'm Japanese, so I use a translator)
Main ArtifactID.java
package groupid.artifactid;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
public final class ArtifactID extends JavaPlugin implements Listener {
@Override
public void onEnable() {
System.out.println(ChatColor.BLUE + "Plugin is enabled.");
Bukkit.getServer().getPluginManager().registerEvents(this, this);
getCommand("test").setExecutor(new DebugCommand());
}
@Override
public void onDisable() {
// Plugin shutdown logic
}
}
Command DebugCommand.java
package groupid.artifactid;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
public class DebugCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length == 1) {
String message = args[0];
if ( message.equalsIgnoreCase("test"))
{
sender.sendMessage("test ok");
}
else {
sender.sendMessage("test no");
}
}
return true;
}
}
plugin.yml
main: groupid.artifactid
name: DebugPlugin
version: 1.0
commands:
test:
description: TEST
aliases: [test1, test2]
I'd like to know what the solution is.
Error
do a clean compile
how to set a playerhead by this "ID"?
/give @p minecraft:player_head{display:{Name:"{\"text\":\"Red X\"}"},SkullOwner:{Id:[I;1590668272,1381189552,-1538418164,-1841266247],Properties:{textures:[{Value:"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmViNTg4YjIxYTZmOThhZDFmZjRlMDg1YzU1MmRjYjA1MGVmYzljYWI0MjdmNDYwNDhmMThmYzgwMzQ3NWY3In19fQ=="}]}}} 1
The main in the plugin.yml is wrong.
It should be groupid.artifactid.ArtifactID
Error occurred while enabling ArtifactID v1.0 (Is it up to date?)
java.lang.NullPointerException: Cannot invoke "org.bukkit.command.PluginCommand.setExecutor(org.bukkit.command.CommandExecutor)" because the return value of "groupid.artifactid.ArtifactID.getCommand(String)" is null
at groupid.artifactid.ArtifactID.onEnable(ArtifactID.java:14) ~[?:?]
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:264) ~[spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:337) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:403) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
at org.bukkit.craftbukkit.v1_12_R1.CraftServer.enablePlugin(CraftServer.java:381) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
at org.bukkit.craftbukkit.v1_12_R1.CraftServer.enablePlugins(CraftServer.java:330) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
at net.minecraft.server.v1_12_R1.MinecraftServer.t(MinecraftServer.java:422) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
at net.minecraft.server.v1_12_R1.MinecraftServer.l(MinecraftServer.java:383) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
at net.minecraft.server.v1_12_R1.MinecraftServer.a(MinecraftServer.java:338) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
at net.minecraft.server.v1_12_R1.DedicatedServer.init(DedicatedServer.java:272) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:545) [spigot-1.12.2.jar:git-Spigot-79a30d7-acbc348]
at java.lang.Thread.run(Thread.java:832) [?:?]
beyond repair
groupid.artifactid.ArtifactID class
lol
I'm not sure.
your main class
ArtifactID
How would you upload a file to a website with java?
that's a very vague question
I want to create a file, and then send it to a website where it stores it
what is "sending it to a website"
just like store it in a website folder
My website
on the same machine?
On a vps
somewhere else?
vps
use ftp or something then
Hi everyone I have an issue with a custom villager (nms)
?ask
If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply.
yes 2 secs
//
and with fake players they just become invisible
but if I go far away and I come back all is normal
I can still interact with the npc
how are you spawning them
public void sendVillager(Player p, CustomVillager villager) {
Reflection.sendPacket(p, new PacketPlayOutSpawnEntityLiving(villager));
Reflection.sendPacket(p, new PacketPlayOutEntity.PacketPlayOutEntityLook(villager.getBukkitEntity().getEntityId(), (byte) ((villager.getBukkitEntity().getLocation().getYaw() * 256.0F) / 360.0F), (byte )((villager.getBukkitEntity().getLocation().getPitch() % 360.0) * 256 / 360), false));
Reflection.sendPacket(p, new PacketPlayOutEntityHeadRotation(villager, (byte) ((villager.getBukkitEntity().getLocation().getYaw() * 256.0F) / 360.0F)));
}
because you're spawning it with a packet
once the player respawns or relogs packet data wont persist
same reason why sending a block change through packets isnt permanent
there is a way to make it permanent ?
spawn it through regular means, not packet
If they are not permanent why when I go far away and I come back all is good
anywhere i could find the vanilla minecraft source for enchants
what for
i know theres Minecraft Coder's Pack but thats been abandonned ages ago
fat chance of finding minecraft src for latest versions
if you just need formulae for enchants like fortune then I’m pretty sure info like that will be available on the wiki
Is it possible without FTP?
What I'm trying to do is edit certain values of Enchants, change names, etc. as well as add custom ones. & I really didn't want to have to just make them from scratch.
FTP is probably your best bet for large files
How would you do it?
With java
sounds like modding, not plugins
run buildtools with --generate-source --generate-docs
assuming your site has backend, make that host an FTP server and just upload it from the java app
or have an ftp server on teh same machine as your site
It's hosted with netlify, and I only have an index.html file. There is also an folder called files. Could you store some file in the files folder by making a request or smth?
@drowsy helm in "Citizens" villagers are spawned with packets
Could you show the code? I'm 100% sure they are doing other stuff on top of packets
do they support ftp uploading? I think you can do it through http requests but again, you need backend for that
They don't support FTP
You can import code from a git repo
and all code from the repo will be there
folders etc
I'm asking whether they support backend applications like nodeJS or anything
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.
Yeah, I think so
Well you'll have to write some backend for HTTP requests, sending files just isnt possible like that with a html/js only site
is that from citizens?
no
I mean the code from citizens that you're referring to
ah
they probably send update packets every so often or under specific circumstances
packets just dont work like that and stay persistent
What's the "update packets" ?
spawn packets, entity information packets etc
just stuff to retain the data once the player comes backl
you'll probably also notice if you spawn the entity before you join, then join it won't have the data
just dont use packetse
lemme find what i do
((CraftWorld)loc.getWorld()).getHandle().addEntity(ent());
Then you're gonna have to run packets constantly for whenever you need to send data about the entity to the client
i.e when they join, when they render it etc
wait ((CraftWorld)loc.getWorld()).getHandle().addEntity(ent());
I didn't think that when you said spawn them without packets
show me
player.getWorld().spawnEntity(location, EntityType.VILLAGER) I thought you meant this
nah that doesnt take custom entities
ah
((CraftWorld)World).getHandle().addEntity(Entity);
then just pass the instance of your entity class
I need custom entity : ' (
Wdym
Just have your villager class extend VillagerEntity
Thats how custom entities should be handled
now all you need to do is use an ftp client on your java app and upload it
i recommend apache net ftp
Guys, i'm creating a keysystem, i need to make a key not place able. I need to check the itemmeta, how can i do this?
I tried with this:
@EventHandler
public void onKeyPlace(BlockPlaceEvent event) {
Player p = event.getPlayer();
ItemMeta meta = event.getItemInHand().getItemMeta();
LangMethods langMethods = new LangMethods(plugin);
if(event.getBlockPlaced().getBlockData().getMaterial() == Material.TRIPWIRE_HOOK && meta != null && meta.getDisplayName().equals(plugin.getConfig().getString("Key-Mistery-Name"))) {
event.setCancelled(true);
}
}
I don't believe ItemMeta is persistent between server starts
I would recommend to use PDC if possible as that is more likely to be persistent and appears to be what you want to do
Also, ItemStack#getItemMeta is a very expenisve call, you should call it last
I think it is too heavy to add everything placed in a PDC
whats the content?
I mean the meta.getDisplayName().equals(plugin.getConfig().getString("Key-Mistery-Name")) check
Though, it is a matter of perference
Okayokay, you are completely right, several times I call that operation soooooooooo expensive but my problem is another .. I need to find the meta of the block to compare it and if it matches the key delete the event.
Tripwire is a block. it has BlockData but no meta. Meta is on ItemStacks
Good very good! But how do I solve my problem? 👍
When you place your trip wire it is no longer an ItemStack. You have no meta to compare
If you want to track specific blocks you need to implement some database system to know which blocks are your custom ones.
or use the chunks PDC
Can I use another method? If so, which one? I want an easy-method
There is no easy method
Are you sure?
Only special blocks with TileEntities have their own PDC so your only option is either a database or chunk PDC
What if I put a metaData on the item?
But event.getBlockPlaced().getMetadata() exists.
a data set that is lost when the server stops
Is there a way to check if the config has a key without a value? In my config I have keys that don't have any value by default because they are only there if the user wants to overwrite something. I'd like to check if the key is there to make sure users have all the possible config options, but it doesn't seem to work, I think because there's no value the config just ignores it.
Not if i'm going to add the metadata in the onEnable
you would have to add the data to every placed block every single time the server starts
Which would mean you have a database of what blocks to put the data on
Which means you don;t need to put the data on the block at all
Maybe I didn't understand how it works because I thought I could add a metaData to the item and then when it is placed it is not lost and I can compare it.
meta on ItemStacks is permanent, When placed as blocks its lost.
blockMeta is temporary
So the only simplest and most effective way is to?
a database or chunk PDC
Or the BlockInteractEvent?
no
I think yes because i need to interact before make the block placed
You think yes, good luck with that then.
I'm going to try your method, thanks.
Good plan
guys how can i give a player a whole pvp kit with weapons and armor
i tried player.getInventory().setItem();
and player.getInventory().setArmorContents(armor);
but it doesnt work
Both work
then why am i not getting any armor?
You didnt show any code so we cant possibly know
oh yeah
public void PVPkit(Player player) {
ItemStack[] armor = {};
armor[0] = new ItemStack(Material.DIAMOND_HELMET, 1);
armor[1] = new ItemStack(Material.DIAMOND_CHESTPLATE, 1);
armor[2] = new ItemStack(Material.DIAMOND_LEGGINGS, 1);
armor[3] = new ItemStack(Material.DIAMOND_BOOTS, 1);
player.getInventory().setItem(0, new ItemStack(Material.IRON_SWORD, 1));
player.getInventory().setItem(1, new ItemStack(Material.IRON_AXE, 1));
player.getInventory().setItem(2, new ItemStack(Material.BOW, 1));
player.getInventory().setItem(3, new ItemStack(Material.FISHING_ROD, 1));
player.getInventory().setItem(4, new ItemStack(Material.GOLDEN_APPLE, 5));
player.getInventory().setArmorContents(armor);
}
and then when player teleports to the arena
PVPkit(player);
Thats not how to put items in an array
This will throw an ArrayIndexOutOfBoundsException
how do I do it then?
oh
i had to specify the array length then?
so it becomes ItemStack[] armor = new ItemStack[4];
correct
private void invisibleProjectile(Entity e) {
for (Player all : e.getWorld().getPlayers()) {
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(new int[] { e.getEntityId() });
(((CraftPlayer)all).getHandle()).playerConnection.sendPacket(packet);
}
}
@EventHandler
public void projectileLaunch(ProjectileLaunchEvent e) {
Projectile proj = e.getEntity();
invisibleProjectile((Entity) proj);
}```
invisibleProjectile((Entity) proj); this dont working
now how do i teleport a player when he dies?
Delay your invisibleProjectile call by at least 1 tick. It probably won't exist on the client until the event finishes.
how i do this ?
teh Bukkit scheduler runTask
how do i teleport my player when he dies?
this doesnt work
public void onPlayerDeath(PlayerDeathEvent event){
if (event.getEntity().getWorld().getName().equals("pvp")) {
event.getEntity().getInventory().clear();
PVPkit(event.getEntity());
Player player = event.getEntity();
player.teleport(new Location(Bukkit.getWorld("pvp"),-21.367, 85, 91.386, -86, 48));
}
}
if i choose the respawn event
do i teleport them as soon as they respawn if they are in the specified world?
how do i check which world they died in?
What coll said would be easier tbh. You'd have to track the world in the damage event anyway
So just check if the damage would kill them and then teleport them to the spawn of the current world they're in
Check if their health - event.getFinalDamage <= 0
Yes
i cant find it
I think the configuration API doesn't work like it should. FileConfiguration.isSet (https://hub.spigotmc.org/javadocs/spigot/org/bukkit/configuration/MemorySection.html#isSet(java.lang.String)) should check if a path is set, and return false if it isn't, even if there's a default value, but for me it always returns true as long as the value is in the default config file. Manually setting the defaults to an empty YamlConfiguration fixes this, but that's not a nice solution, is there anything I'm missing?
declaration: package: org.bukkit.configuration, class: MemorySection
How can i set the Y of a player?
Probably teleport him
If its in the file then its Set, its not a default value at that point.
//like this?
Location l = player.getLocation();
player.teleport(new Location(l.getWorld(), l.getX(), l.getY() + 0.4, l.getZ(), l.getYaw(), l.getPitch()));
I mean it isn't in the actual file on the disk, but it is in the default file in the plugin .jar
If the value for the requested path does not exist but a default value has been specified, this will still return false.
so it should return false, but it doesn't
what default file in the jar?
config.yml
then its set
no, because that file specifies the defaults
if it exists in the config at all, its set
that's the default config file, not the actual config file
no, its just the default config. everything in it is set
not if I delete it
delete what?
the value
I delete it, so it's not in the actual config anymore, but it does still have a default
If its in the file, it exists.
according to the docs, that should still return false, but it doesn't
so you're saying there's no difference between default config and actual config?
by that logic the config file would be hardcoded and could never be changed?
use this and set a default thats NOT in the config https://hub.spigotmc.org/javadocs/spigot/org/bukkit/configuration/Configuration.html#addDefault(java.lang.String,java.lang.Object)
if you then test that path for isSet it will reply with false
I'll try that, one minute
You’ll need to check and cast to livingentity
you're right, but I don't get it
You are thinking that the file included in teh jar is defaults when its not
its the default config FILE, not defaults
so if a value isn't in the actual config file, it just takes it from the default config file?
defaults are completely separate thing.
no
its a default FILE, not a default settings
but then why does it say the value is set, if it's only set in the default file but not the actual file?
its the file that will be copied to your plugin directory when instructed. but every value in it is set
yeah but when I change the saved file (including deleting stuff) shouldn't that overwrite it?
because thats the config and default FILE, not default values
then how can I check if a value is set in the actual config file on disk, ignoring the default one?
once loaded the one in memory is the only one thats checked
but apparently the default config still affects which values count as set?
no
I did all that after loading the config
ok, so I have key X in my default, but I remove it in my file on disk, and then reload the config file, so the one from the disk is in memory now, right?
how do i remove fire damage from player?
if you already had a config loaded and you load your edited file over it you may confuse it. You should perform a copyDefaults to ensure they match
I don't want to copy the defaults, since that might overwrite changes that users make to the file
users shoudl not be manually editing yrou file when the server is running
i need create a runnable ?
I don't think there's anything wrong with editing the file while the server is running
that's why virtually every plugin has a reload command
also you said the default config doesn't set defaults, that seems to be false, I just tried printing the defaults keys and it contains all the stuff from the default config
if you are correctly reloading yoru config you should have no issues
I call saveDefaultConfig() in case the file doesn't exist, and then reloadConfig() to reload it, anything wrong with that?
Looks fine to me
So you are saying that defaults are always being read from the yml in the jar file?
seems like it
but apparently something is still different than adding them dynamically since it worked when I did that
mvn clean install is giving me this
for (int i = 0; i < 5; i++) {
p.sendTitle("§c§lYou died!", "§7Respawning in §f" + i + "§7seconds");
}``` which runnable do i use perform this task in seconds?
runnables are in ticks 20 ticks = 1 second
While using Bukkit.getServer().dispatchCommand() im getting an async error, what method shall i use to prevent this async thing?
runtask or callMethod
example?
Bukkit.getScheduler().callMethod(...
isnt it called callSyncMethod btw lol
it could be
well do u run that asynchronously?
if you do consider dispatching the command on the server thread instead
somethign like (untested) Bukkit.getScheduler().callSyncMethod(plugin, Bukkit.getServer().dispatchCommand(sender,"blah")));
It takes a Callable<V> iirc but yeah
or Bukkit.getScheduler().runTask(plugin, () -> { Bukkit.getServer().dispatchCommand(sender,"blah"); });
depends on your needs
if you want a delay runTaskLater
what do you mean delay
i intend to make perform this task in seconds
which one do you recommend
translator
be more specific "in seconds"
convert seconds to ticks
1 second? 2 seconds? or how many seconds
5 seconds
worse I need to decrease wait, wrong code
for (int i = 5; i != 0; i--) {
p.sendTitle("§c§lYou died!", "§7Respawning in §f" + i + "§7seconds");
}```
thats an odd way to make a decreasing loop but nice, yeah so maybe you could create some sort of recursive delaying task
hm
just needs runTaskTimer, and self cancel when finished
yeah either that or recurring delaying task as the delay is suppose to decline for each run if I understand right
you just put the counter in the runnable, outside the run method
each time it runs, decrease counter
when it reaches zero cancel task
i need put a for outside of the run method ?
@SuppressWarnings("deprecation")
@EventHandler
public void deathTime(Player p) {
death.add(p);
new BukkitRunnable() {
@Override
public void run() {
for (int i = 5; i != 0; i--)
{ p.sendTitle("§c§lYou died!", "§7Respawning in §f" + i + "§7seconds"); }
cancel(); death.remove(p);
}
}.runTaskLater(Arma.getPlugin(Arma.class),20L);
}```
no, very wrong
whats wrong
It should be something like ```java
final Player player = Bukkit.getPlayer("namehere");
new BukkitRunnable() {
int time = 5;
@Override
public void run() {
if (time == 0) this.cancel();
player.sendTitle("§c§lYou died!", "§7Respawning in §f" + time + "§7seconds", -1, -1, -1);
time--;
}
}.runTaskTimer(plugin, 0L, 20L);```
readability
its very nice when people put this. and super. if applicable son
wow. i always thought i needed to make a class that extended bukkitrunnable in order for it to cancel itself. You learning something new every day...
@eternal oxide, do you remember me? I used a simple if(ItemStackKey.equals(e.getItemInHand) e.setcancelled true..
the example technically does that, it's an anonymous class
I always extend it also lol
Yea true.
Why? When you could just do what you did above.
single responsibility principle
I'm going to have to read up on that
I want to split a string like "8000.00" into two part and use the 8000 without the .00 . How can I split it? (String[] split = output.split("\\."); String splitted = split[0]; did not worked)
String.format
and how do I use it?
String.format("%d", 8000.00); would give your 8000
ok, thanks
How may I use NMS?
Hello, I have a problem, the problem is that the "Skript" plugin does not read some scripts
You just need the nms code on your classpath (using maven or just using the spigot jar without maven)
But NMS is nothing you voluntarily use. Its something you try to avoid at all costs and only pick up when you absolutely need to.
Ask on the Skript discord
I need it as I can't send action bar messages for 1.8.8
This version is ancient and the support for that version was dropped years ago.
Search in old forum posts for answers.
Afaik, you shoudnt really use nms, because that will break compatibility with other Minecraft versions, unless you plan on not switching then or having specific code for each version. You would have to update your code every time a new version comes out though
Guys, Door door = (Door) e.getClickedBlock() doesn't work, e.getClickedBlock().getBlockData doesn't work and e.getClickedBlock().getState() doesn't work (With all the server gives me the "Can't cast" error). Help? (1.16.5)
show the actual error
its on BlockData
java.lang.ClassCastException: class org.bukkit.craftbukkit.v1_16_R3.block.CraftBlockState cannot be cast to class org.bukkit.material.Door
and "doesn't work" tells us nothing
Where
Door
and i need to make e.getClickBlock().getBlockData or State?
data
Won't work, i think i'm wrong, i'm trying to restart the localhost.
org.bukkit.block.data.type.Door door = (org.bukkit.block.data.type.Door) e.getClickedBlock().getBlockData();
yes
It doesn't work, it doesn't open the door but I did a very quick debug with System.out.println and it goes all the way to that line, so it passes everything.
What doesn't open the door? Its already a door.
@EventHandler
public void onDoorInteract(PlayerInteractEvent e) {
KeyCheck keyCheck = new KeyCheck(plugin);
Player p = e.getPlayer();
if(keyCheck.isKey(p.getInventory().getItemInMainHand())) {
if(e.getClickedBlock() != null && e.getClickedBlock().getType() == Material.IRON_DOOR) {
System.out.println("1");
org.bukkit.block.data.type.Door door = (org.bukkit.block.data.type.Door) e.getClickedBlock().getBlockData();
door.setOpen(true);
}
}
}```
code block
How
three ` before and after
and as its blockdata i guess set the new one
I didn't understand, should I set the same date that I put on the port on the e.getClickedBlock ()?
e.getClickedBlock().setBlockData(e.getClickedBlock().getBlockData());?
you first should store the blockdata,then cast door to it
do the change then set with that stored blockdata
oHHHH okAY
e.getClickedBlock().setBlockData(door);
you may have to get teh other half of the door and do the same. Not sure on that though
Thanks to everyone and good Easter! (it Work!)
[ERROR] The project me.zoibox.core:Core:1.0-SNAPSHOT (E:\core\src\main\pom.xml) has 1 error
[ERROR] 'dependencies.dependency.systemPath' for me.zoibox.core:ActionBarAPI:jar must specify an absolute path but is src/main
/ActionBarAPI-1.5.4.jar @ line 171, column 25
<dependency>
<groupId>me.zoibox.core</groupId>
<artifactId>ActionBarAPI</artifactId>
<scope>system</scope>
<version>1.5.4</version>
<systemPath>src/main/ActionBarAPI-1.5.4.jar</systemPath>
</dependency>
use teh github repo for is https://github.com/connorlinfoot/ActionBarAPI
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>```
<groupId>com.github.connorlinfoot</groupId>
<artifactId>actionbarapi</artifactId>
<version>1.5.4</version>
</dependency>```If thats the correct version
ty ill give it a try
[ERROR] The project me.zoibox.core:Core:1.0-SNAPSHOT (E:\core\src\main\pom.xml) has 1 error
[ERROR] 'repositories.repository.id' must be unique: jitpack.io -> https://jitpack.io vs https://jitpack.io @ line 74, column
17
@eternal oxide
That says you already have that repo added
tysm
[ERROR] Failed to execute goal on project Core: Could not resolve dependencies for project me.zoibox.core:Core:pom:1.0-SNAPSHOT: C
ould not find artifact com.github.connorlinfoot:actionbarapi:jar:1.5.4 in spigotmc-repo (https://hub.spigotmc.org/nexus/content/gr
oups/public/) -> [Help 1]
****
try ActionBarAPI instead of actionbarapi
aight
Github has stopped allowing uppercase letters in artifacts but it seems to be selective when it bans them
[ERROR] Failed to execute goal on project Core: Could not resolve dependencies for project me.zoibox.core:Core:pom:1.0-SNAPSHOT: F
ailure to find com.github.connorlinfoot:ActionBarAPI:jar:1.5.4 in https://hub.spigotmc.org/nexus/content/groups/public/ was cached
in the local repository, resolution will not be reattempted until the update interval of spigotmc-repo has elapsed or updates are
forced -> [Help 1]
[ERROR]
show us your pom. Drop it in here and it will be auto formatted
you have a space after ActionBarAPI
oh yeah im dumb at 1am lmfao
bruhb
[ERROR] Failed to execute goal on project Core: Could not resolve dependencies for project me.zoibox.core:Core:pom:1.0-SNAPSHOT: F
ailure to find com.github.connorlinfoot:ActionBarAPI:jar:1.5.4 in https://hub.spigotmc.org/nexus/content/groups/public/ was cached
in the local repository, resolution will not be reattempted until the update interval of spigotmc-repo has elapsed or updates are
forced -> [Help 1]
it should continue past that. its just failign to find it on spigot
new BukkitRunnable() {
@Override
public void run() {
invisibleProjectile((Entity) proj);
}
}.runTaskLater(Arma.getPlugin(Arma.class), 50);
}``` like this ?
you should remove that from yoru project
why?
no manually added libs
you should not be compiling it
huh
its a dependency
when I compile the whole plugin it wont compile if I put it under library in intelliJ
oh
its a maven dependency
yeah
omg
im
so
dumb
lmfao
[ERROR] Failed to execute goal on project Core: Could not resolve dependencies for project me.zoibox.core:Core:pom:1.0-SNAPSHOT: F
ailure to find com.github.connorlinfoot:ActionBarAPI:jar:1.5.4 in https://hub.spigotmc.org/nexus/content/groups/public/ was cached
in the local repository, resolution will not be reattempted until the update interval of spigotmc-repo has elapsed or updates are
forced -> [Help 1]
[ERROR]
deleted it btw
one sec I'll test your depend
k
give me an init line for ActionBarAPI
wdym
just a sample line that will use action bar
//my config query would actually work that way ?
int Lizenz = yamlConfiguration.getInt("Lizenz");
if(Lizenz == 1102568){
Bukkit.getConsoleSender().sendMessage(Main.getPrefix() + "§aDeine Lizenz ist gültig viel spaß mit §5Ultra§7-§dAntiCheat");
} else {
Bukkit.getConsoleSender().sendMessage(Main.getPrefix() + "§cDeine Lizenz ist ungültig bitte kaufe dir eine unter:§5 ");
Bukkit.getPluginManager().disablePlugin(this);
}
Yeah, I can;t get it to see it either
@eternal oxide #help-development message is this or not ? because is dont working
it needs to me an instance of the main class
an instance
Unfortunately it does not work
what do I do @eternal oxide
What the hell does Arma#getPlugin(Class) do?
one sec
I think its a type aware static method to get a plugin instance by its class
assume Arma extends JavaPlugin
What does not work here?
this
@quiet ice
jitpack sees it fine
nvm, I replied to the wrong person, meant @tardy yacht
cant I just get the jar from the plugin dir?
you could install it locally (into yoru maven local)
well, you need compile time linking
Otherwise java will have no idea what the methods are about and guessing would not really owrk
or if I do im just gonna make my own util
if I run the plugin and the number in the config is correct, it sends the message for wrong
remember, T extends Object == T extends Object tends to misbehave for anything but Boolean and otherwise cached values
mvn clean install is outputting this
[INFO] --- maven-install-plugin:2.4:install (default-install) @ Core ---
[INFO] Installing E:\core\src\main\pom.xml to C:\Users\wsmit\.m2\repository\me\zoibox\core\Core\1.0-SNAPSHOT\Core-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.998 s
[INFO] Finished at: 2021-04-05T01:10:44+10:00
[INFO] ------------------------------------------------------------------------
No clue, I don;t use install myself
would you possibly send me the correct code am easy to get lost for config work
Your code should work though
There is nothing wrong and you did a typo that I did not spot or I cannot spot
ok thx
at org.bukkit.plugin.SimplePluginManager.getRegistrationClass(SimplePluginManager.java:703) ~[patched_1.16.5.jar:git-Paper-562]
at org.bukkit.plugin.SimplePluginManager.getRegistrationClass(SimplePluginManager.java:701) ~[patched_1.16.5.jar:git-Paper-562]
at org.bukkit.plugin.SimplePluginManager.registerEvents(SimplePluginManager.java:640) ~[patched_1.16.5.jar:git-Paper-562]
at nl.timnl.eindjeminecraft.EindjeMinecraftPlugin.onEnable(EindjeMinecraftPlugin.java:48) ~[?:?]
at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:263) ~[patched_1.16.5.jar:git-Paper-562]
at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:380) ~[patched_1.16.5.jar:git-Paper-562]
at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:483) ~[patched_1.16.5.jar:git-Paper-562]
at org.bukkit.craftbukkit.v1_16_R3.CraftServer.enablePlugin(CraftServer.java:501) ~[patched_1.16.5.jar:git-Paper-562]
at org.bukkit.craftbukkit.v1_16_R3.CraftServer.enablePlugins(CraftServer.java:415) ~[patched_1.16.5.jar:git-Paper-562]
at net.minecraft.server.v1_16_R3.MinecraftServer.loadWorld(MinecraftServer.java:580) ~[patched_1.16.5.jar:git-Paper-562]
at net.minecraft.server.v1_16_R3.DedicatedServer.init(DedicatedServer.java:280) ~[patched_1.16.5.jar:git-Paper-562]
at net.minecraft.server.v1_16_R3.MinecraftServer.w(MinecraftServer.java:1055) ~[patched_1.16.5.jar:git-Paper-562]
at net.minecraft.server.v1_16_R3.MinecraftServer.lambda$a$0(MinecraftServer.java:289) ~[patched_1.16.5.jar:git-Paper-562]
at java.lang.Thread.run(Thread.java:832) [?:?]```
I only registered more events, and then I get this bug
what do u use
use Intellij Idea with the minecraft development plugin then everything should work
no
One of yoru custom events does not implement getHandlerList
No, I only added Bukkit events
that says you didn;t
I need help please
@EventHandler
public void onBucketEvent(PlayerBucketEvent e)
{
Region region = RegionManager.locationInRegion(e.getBlock().getLocation());
if(region != null)
{
PlayerBuildInRegionEvent event = new PlayerBuildInRegionEvent(region, e.getPlayer());
Bukkit.getServer().getPluginManager().callEvent(event);
if(event.isCancelled())
e.setCancelled(true);
}
else
{
e.setCancelled(true);
e.getPlayer().sendMessage(ChatFormat.format("&4Error: &cJe mag hier geen water plaatsen!"));
}
}
@EventHandler
public void onNetherEvent(PortalCreateEvent e)
{
e.setCancelled(true);
if(e.getEntity() instanceof Player)
{
Player player = (Player) e.getEntity();
player.sendMessage(ChatFormat.format("&4Error: &cJe mag niet naar de nether of de end!"));
}
}
@EventHandler
public void onDrop(PlayerDropItemEvent e)
{
e.setCancelled(true);
}
@EventHandler
public void onReceipe(PlayerRecipeDiscoverEvent e)
{
e.setCancelled(true);
}
@EventHandler
public void onRespawn(PlayerRespawnEvent e)
{
if(SpawnManager.isSpawnSet())
{
Player player = e.getPlayer();
LocationManager.teleportPlayerToLocation(player, SpawnManager.getSpawn());
player.sendMessage(ChatFormat.format("&aJe bent naar de spawn geteleporteerd!"));
}
}
This is the only code I added
It is probably "PlayerBucketEvent", because this class doesn't have the method
This was the problem
notice public abstract class PlayerBucketEvent abstract
I just created from this the empty and fill
Yes
try to specify <type>jar<type> or similar, I do not know what exactly it is
The child events are. Thats an abstract event so can;t be called
where
<packaging>jar</packaging> within the pom, so at the same level as the dependencies or repositories block
true
it wasn't that btw
ehhh, sm can help now #help-development message
what u need help with now again
invisibleProjectile() is dont working
Yes, but proj has to be final
proj has to be final ?
You see, based on where you redirected I would give you help on collapsing the bukkit runnable into a lambda
you mean define it like a final Projectile bla bla ?
yes
the runnable can only access it if its final
You may have to store it locally in the runnable
but when i define it on a cast i need to ?
so when it finally runs its available
final Projectile proj = e.getEntity();
final Projectile proj = e.getEntity();
new BukkitRunnable() {
@Override
public void run() {
invisibleProjectile((Entity) proj);
}
}.runTaskLater(Arma.getPlugin(Arma.class), 50);
}```
store a copy in yru runnable
Doesn't Javac inject these already if the locals are final?
final projectile = proj;
@override
(for anonymous classes)
Yes
aaah now i understand
His isn;t final
Well, then make it effectively final
yep
I keep getting this error Jar does not contain plugin.yml I'm not quite sure why I keep getting it? This is my pom.xml setup for the build section: xml <build> <finalName>Trouble in Mineville</finalName> <sourceDirectory>src/main/java</sourceDirectory> <resources> <resource> <targetPath>.</targetPath> <filtering>true</filtering> <directory>${basedir}/src/main/resources/</directory> <includes> <include>plugin.yml</include> <include>config.yml</include> </includes> </resource> </resources> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build>
#help-development message then this code is working ?
If you had added a try/catch to your runnable you'd have seen it was erring out with an NPE
public static DiscordUser getDiscordUserForUUID(UUID uuid)
{
AtomicReference<DiscordUser> discordUser = new AtomicReference<>();
new Thread(() ->
{
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
return;
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
{
discordUser.set(dbUser);
return;
}
}
}).start();
return discordUser.get();
}
How to do this async? Because I need to do this async otherwise the server will crash, but I don't know how I can return the correct value
it should
tvhee what u wanna do async?
Don't bother defining includes yourself
Querying the database
btw use CompletableFuture instead of creating new threads
it is not working
it uses a threadpool instead which is arguably more optimized
a Future
Example?
Executor executor = new ForkJoinPool();
CompletableFuture<?> future = CompletableFuture.supplyAsync(() -> {
return DiscordUser.fetch().get();
},executor).thenAccept(obj -> {
//callback on the same thread the first supplier was called on (not the server thread to say)
});
or smtng
Thanks
what?
Maven does it automatically if it is in the src/main/resources folder
Default policy is include everything in that folder, no need to override it
So just remove incluses and include?
also yeah I'd suggest using your own executor as
* By default, CompletableFuture uses the ForkJoinPool.commonPool instance.
* However... ForkJoinPool is a fixed size pool limited by Runtime.availableProcessors.
* Some (bad) plugins incorrectly use this pool for i/o operations, make calls to Thread.sleep
* or otherwise block waiting for something else to complete. This prevents the LP cache loading
* operations from running.
*
* By using our own pool, we ensure this will never happen.
``` Yeah its from LP :]
I don't know how to set my code inside that
look at the code I sent
Yes I looked
it shows an example where I pass it in CompletableFuture#supplyAsync(Supplier,Executor)
Incompatible types: expected not void but the lambda body is a block that is not value-compatible
Executor executor = new ForkJoinPool();
CompletableFuture<?> future = CompletableFuture.supplyAsync(() ->
{
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
return;
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
return dbUser;
}
return null;
},executor).thenAccept(obj ->
{
//callback on the same thread the first supplier was called on (not the server thread to say)
});```
Where?
you have to specify the type parameter to the type you wanna operate on ofc
I presume DiscordUser would be it in this case
Yes
CompletableFuture<DiscordUser> ...
I changed that, error not solved
yeah
How to solve this error? I really have no idea
If I return everywhere null, Intellij suggest to change it to void
what u got now
CompletableFuture
<DiscordUser>
Provided:
CompletableFuture
<Void>```
```java
Executor executor = new ForkJoinPool();
CompletableFuture<DiscordUser> future = CompletableFuture.supplyAsync(() ->
{
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
return null;
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
return dbUser;
}
return null;
},executor).thenAccept(obj ->
{
//callback on the same thread the first supplier was called on (not the server thread to say)
});```
yeah
since you return null
the supplier thinks its a void
throw CompletionException
or what its called
instead of returning null
CompletableFuture<DiscordUser> future = CompletableFuture.supplyAsync(() ->
{
DiscordUser user = null;
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
return user;
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
return dbUser;
}
return user;
},executor).thenAccept(obj ->```
Wants void
I now not return null
DiscordUser user = null;
Oh, also not allowed?
well thing is if you return null it thinks it is a Void type (its a generics thing)
so whenever its null, throw a RuntimeException or smtng
Executor executor = new ForkJoinPool();
CompletableFuture<DiscordUser> future = CompletableFuture.supplyAsync(() ->
{
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
throw new IllegalStateException("Result set is null");
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
return dbUser;
}
throw new IllegalStateException("Result set is null");
},executor).thenAccept(obj ->
{
//callback on the same thread the first supplier was called on (not the server thread to say)
});```
Not working
hmm
I have dinner now, see you later
ok
My bad you should probably not put it into a variable or you'd have to put it as CompletableFuture<Void> as CompletableFuture#thenAccept returns CompletableFuture<Void> sry lol
send ur plugin.yml
OMG
name: Core
version: ${project.version}
main: me.zoibox.core.core.Core
api-version: 1.8
authors: [Zoi]
description: CORE
softdepend:
- ActionBarAPI
depend: - EventAPI
- helper
Anyone able to help me out with my issue?
I am back
Look at the image man, it does
I don't understand, can you pls give me the code? This is what I want to reach:
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
return null;
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
return dbUser;
}
return null;```
thats called spoonfeeding
@ivory sleet its still happening
Is it the target folder?
final Executor executor = new ForkJoinPool();
CompletableFuture<DiscordUser> loadUser() {
return CompletableFuture.supplyAsync(() -> {
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null) {
return null;
}
List<DiscordUser> users = new ArrayList<>();
try {
while(rs.next()) {
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
} catch(SQLException e) {
e.printStackTrace();
}
for (DiscordUser dbUser : users) {
if(dbUser.getPlayer().equals(uuid)) {
return dbUser;
}
}
return null;
},executor);
}
void loadUser(Consumer<? super DiscordUser> callback) {
this.loadUser().thenAccept(callback);
}
``` @maiden briar
I think
Ah thanks
me?
no tvhee
Can you tell me where I'm supposed to put the plugin.yml file? Cuz honestly, I don't know anymore
yes I told you, either your main class isnt included in your jar or its relocated
it looks right but I dont use maven
so tbf Idk
gradle is superior in my opinion
cuz it's supposed to be where I put it
ye
private static final Executor executor = new ForkJoinPool();
private static CompletableFuture<DiscordUser> loadUser(UUID uuid)
{
return CompletableFuture.supplyAsync(() ->
{
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
return null;
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
{
return dbUser;
}
}
return null;
}, executor);
}
public static DiscordUser getDiscordUserForUUID(UUID uuid)
{
DiscordUserManager.loadUser(uuid).thenAccept(discordUser ->
{
// What to fill in here?
});
}```
well thing is if you wanna return the user it would have to be blocking the thread its called on
Yes
thought that was what you didnt want
I just wanted to get the user async to prevent crashes
Example?
Idk depends on what u wanna do with the user
if u wanna print him do that
if u wanna get his id do that?
I want to return him
Checking if not null
So I make a boolean from the method and then how to check if the user is not null in the logic?
I know, but the bot will change them into the database
If somebody enters a command
or call a sync method to do whatever logic on the returned player
Ok how?
well he's not working with players
Hi, does someone has a clue on how to degen a region/chunk with worldedit ? I can't find it in their api
He can still pass an object using the callSyncMethod
The idea is simple: I just want to query the database and return the values from it, but then async so the server won't crash
You realize your code can;t stop and wait for the response
Yes
you call teh query and then let yoru code go off and do other things
Actually, it can, but it will freeze the used thread
I just check some things from the user inside a command and then stop
I think you wanna do this tvhee
Fetch from database
Put into cache
If user exists in cache, get it
Else load it and put it in the cache then get it and have a fallback callback
it will only freeze the async thread for a few ms waiting for the sync
Yes, but I get a crash then
What is fetching?
not like this
loading, querying
Ah
Or you could try to implement something like the wait()/signal() on linux/C (which require to know how to manipulate threads safely)
and if you wanna run something on the main thread, then simply define that in the callback or the return if its present with BukkitScheduler#callsSyncMethod or just BukkitScheduler#runTask
public static DiscordUser getDiscordUserForUUID(UUID uuid)
{
Bukkit.getServer().getScheduler().runTask(EindjeMinecraftPlugin.getInstance(), () ->
{
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
return null;
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
{
return dbUser;
}
}
return null;
});
}```
Error that I can't return things
then from teh Async task callsync method or a run task
Can anyone with any Maven knowledge help me out here?
You go to /main/resources and put your plugin.yml inside it
If you work with articfacts then refresh it
Yes but how can I return the value from the method?
I have public DiscordUser, how to return that user?
Well thing is you cannot always "return" stuff and expect it not to be blocking, especially when we work with multithreading. Instead we use callbacks that defines behaviors of functional interfaces which then are called on separate threads.
Ok I understand, how to create this callback?
It is there?
Bukkit.getScheduler().callSyncMethod( your method here that it can pass your object to
CompletableFuture#runAsync(Supplier)
BukkitScheduler#callSyncMethod(Callable)
its basically a function you define which is to be called later at some point
public static DiscordUser getDiscordUserForUUID(UUID uuid)
{
Future<DiscordUser> future = Bukkit.getServer().getScheduler().callSyncMethod(EindjeMinecraftPlugin.getInstance(), () ->
{
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
return null;
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
return dbUser;
}
return null;
});
try
{
return future.get();
}
catch(InterruptedException | ExecutionException e)
{
e.printStackTrace();
}
return null;
}```
Something like this?
teh callSync goes inside your Async code to pass back any value you need
ima wait and ask the question later tonight
no, that is firstly sync secondly a blocking future
How do you build your resource?
Oh god..
do u guys know any good user-friendly script engines?
Explaining CompleteableFuture is one of the hardest thing
everything is here @maiden briar
I don't understand that
Ok
Its one of the advanced java concepts...
Then I don't know, have you decompiled your plugin? Because then you are 100% sure
the really simple way... make an Async runnable to do yoru loopup...
If there is nothing to return yes,async runnable is the way to fo
then at teh very bottom of yoru code, when you have the data you need to return, you use Bukkit.getScheduler().callSyncMethod to call a method in yrou plugin to pass the final data to
??? I can see where I put my plugin.yml file with my eyes
No then you are 100% sure java has compiled it
I also was 100% sure of a file, but then I decompiled it and saw it was missing
How do I do that?
Search on the web
you can't just tell me here?
I just ran version 1.8.8 and it does not work.
did you use BuildTools?
I fixed it.
Ah nice
legacy user detected 🆘
Thanks
BuildTools does not work for me
Conclure is typing.......
if you want a working version of 1.8.8 build it yourself
or don't run version 1.8.8
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
1.8 😂 😂
lmao
Ok
Which site
the site that provides downloads for spigot jars
Oh
@maiden briar Can I delete the test folders?
I don't know that
okay
Runnable r1 = () -> {
System.out.println("hi");
}
Runnable r2 = new Runnable() {
public void run() {
System.out.println("hi");
}
}
You know both of these operate equivalent. They both anonymously implement the method run(), they define that logic happens in run() but they're never called meaning that you don't know that thread nor when it's called.
For instance
class A extends JavaPlugin {
public void onEnable() {
r1.run();
}
}```
here r1.run() is called on the main server thread.
Now let's take a look at CompletableFuture
```java
Supplier<String> s = () -> {
Thread.sleep(100_000L);
return "ddd"
};
CompletableFuture<String> fut = CompletableFuture.supplyAsync(s);
So by now you know that the supplier s is just implementing/defining the method Supplier#get. It never calls it. What CompletableFuture.runAsync(s) does is that it takes the supplier you pass and runs it on another thread. Let's call it thread #1.
Lets take a look at blocking vs non blocking
//blocking
void onEnable() {
String s2 = fut.join();
System.out.println(s2);
}```
Here we call CompletableFuture#join() which returns the string, but since it returns the value the main server thread has no other choice but to wait 100 seconds (the main server thread) as every operation on a single thread can only be executed consecutively.
But if we would do this instead:
```java
//non-blocking
void onEnable() {
fut.thenAccept(obj -> {
System.out.println(obj);
});
}
Here we only defines what happens in the Consumer#accept. We never call it on the main server thread. So the Consumer will be called on thread #1 here.
Idk if u got a better understanding now?
Wow thanks
public void getData() {
new BukkitRunnable() {
@Override
public void run() {
//get data...
Bukkit.getScheduler().runTask(instance, () -> dataConsumer("test"));
}
}.runTaskAsynchronously(this);
}
public void dataConsumer(String data) {}```
And?
This is spigotmc, not whatever you have issues with
Unless this is a spigotmc issue
it's because he's trying to run buildtools for the server startup
Ok, sorry
which is plain wrong
@maiden briar code above
This?
oh yeah, buildtools is a builder to build spigot jars
yes
They use it, just in dev time
10 seconds vs 5 minutes of buildtools
And plugin devs that use nms (ew) need to run it unless they use codemc (ewww)
just get the patched jar from cache folder
That's not how maven works
nms is hell and if you know how it works you are a god
so drop it in your local repo? or just put it in a libraries folder in your plugin?
lmao
i dont see the problem
public static DiscordUser getDiscordUserForUUID(UUID uuid)
{
new BukkitRunnable()
{
@Override
public void run()
{
DiscordUser user = null;
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
return;
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
user = dbUser;
}
dataConsumer(user);
}
};
return null;
}
private static void dataConsumer(DiscordUser user)
{
}
BT already does that for you
still takes 4 minutes less
https://www.spigotmc.org/resources/deluxeasyncjoinleavemessage-fully-optimized-async-everything-open-source.88129/ - Conclure/DeluxeAsyncJoinLeaveMessage
Plus, you are now working with paper's API, not with spigot's API
Good.
Good luck with cross compatibility if you plan on using any paper only features
paperlib
There are differences outside of that
@eternal oxide and then?
who cares
I certainly do care
I care
who doesn't care 
shitty devs
👀
I may have shipped a lot of releases that only partly worked on spigot, but it's because paper accidentally patched a bug somehow somewhere
I tried this, but I can't return the value....
Supplier<DiscordUser> supplier = () ->
{
DiscordUser user = null;
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
return null;
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
user = dbUser;
}
return user;
};
CompletableFuture<DiscordUser> future = CompletableFuture.supplyAsync(supplier);
future.thenAccept(user ->
{
return user; //Doesn't work?
});```
yes thats the point of using callbacks
you wont be able to return values directly due to what I stated in that message
another approach if you somehow want to return it would be to cache it then
DiscordUser discordUser = null;
Supplier<DiscordUser> supplier = () ->
{
DiscordUser user = null;
ResultSet rs = QueryBuilder.selectFrom("DiscordData").executeWithResult();
if(rs == null)
return null;
List<DiscordUser> users = new ArrayList<>();
try
{
while(rs.next())
users.add(MySQLDataConverter.convertDiscordUser(rs.getString(1), rs.getLong(2), rs.getString(3)));
}
catch(SQLException e)
{
e.printStackTrace();
}
for(DiscordUser dbUser : users)
{
if(dbUser.getPlayer().equals(uuid))
user = dbUser;
}
return user;
};
CompletableFuture<DiscordUser> future = CompletableFuture.supplyAsync(supplier);
future.thenAccept(user ->
{
discordUser = user;
});
Already tried this, but then the query won't be executed (always null)
you're trying to lazily set it?
What else?
callback?
Ok how?
future.thenAccept(user ->
{
//define logic here
});
Oh, I need to return the future, and in my command class I have to fill in the logic?
yeah return the future