#development
1 messages · Page 42 of 1
Shift + Z Z
vim users be typing in wingdings to quit
Yeah I mean once you understand the basics of modal editing it's really easy
Just getting there I suppose lol
blasphemy
nano 🫡
I personally wouldn't do it, as that's a lot of unnecessary packets that are bound to clog the pipeline up. I would assume lower speed connections would be choppier/glitchier with that method
I mean it's a small packet, but it would probably be easier to just move the time back every few ticks
Does anyone know why jetty would throw this exception out of nowhere? https://pastebin.com/EP4SWhMX
Code: https://pastebin.com/7eKSHxuj
i mean even if you send it once every second... twice a second, the game already sends many more packets with much more frequency already
yeah, I just feel like adding an extra time update packet to every player every tick isn't the best idea
yeah, that was their original idea for it (every tick)
ah
<not my code>
return playerPermissions.computeIfAbsent(id, k -> createPlayerPermissionSet());
if (playerPermissions.containsKey(id)) {
return playerPermissions.get(id);
} else {
PlayerPermissionSet set = createPlayerPermissionSet();
playerPermissions.put(id, set);
return set;
}```
The first return will replace anything that's below, right?
I love some C-style code 🤤
that won't even compile lol
yeah I know smh
one char variables and obscure code 
it's not like we're the ones maintaining it ¯_(ツ)_/¯
yeah but still annoying to read
So, when a player disconnects from any backend server in my bungeecord network, their data gets saved on the database right
Now, I want to do so that if a player connects to another server, the data does this:
- Gets saved on the database
- Is removed from the player's current server
- Is loaded onto the player's new server
Though, the issue is that I'm afraid a player will manage to connect to the server before the data is saved on the database?
I would look at plugins like HuskSync or MPDB. HuskSync deals with this problem by using Redis, as that makes the latency very low. https://github.com/WiIIiam278/HuskSync
❤️
what is a redis server..?
A server running the redis db
Ah
I am very smart
lmao
i was gonna say it's basically a cache server that also can do message passing and stuff since it's all in memory
so you can really quickly save data and then read it immediately after
I think my description is better
ofc
I was just thinking that since there is only one way for players to go from server to server, to simply save the player data using a CompletableFuture
And then teleport the player only when the data is saved
how are you gonna get that CompletableFuture between servers?
i mean i wont
That is just used to trigger an event, and once the event is triggered the player is teleported to the server
oh I see, yeah that is not the best idea
the way HuskSync does it is it just puts people in limbo and cancels their interactions and movements until it loads the data
which is generally faster than the time it takes for them to load the new world and everything
so you don't even notice
Yeah but I gotta figure out Redis and all that
I mean you don't have to
the same principle can apply to anything, it would just take a lot longer with like an actual db
Wdym
have them wait at the end rather than at the beginning
there's no reason to make them wait for the data to save
I mean thing is
The way I teleport players between servers is through a system which, once the player begins the teleportation process, takes 2-3 seconds to teleport them due to the animation playing
Kinda works like a loading screen in a game
Yeah but what I mean is
that shouldn't factor into it though, since admins and people who have /server can bypass that
That I can save the data when the player is about to teleport, and then teleport them away once its finished
if your db takes 2-3 seconds to save, you have bigger problems
and regardless, you don't need them on the server to save their data
nah it doesn't, that waiting time is mostly just to make the teleportation satisfying
But I need the data on the database to retrieve their updated data
I've already disabled that command and implemented my own
(for players)
yeah so wait for it on the other end
i guess this works better with a messaging system like Redis where the data is only there when it is done
But that's harder to implement with what I already got compared to having the player wait in their current server
It shouldn't make much of a difference anyway, which side they wait on?
I guess it makes less of a difference if you have a weird animation
but on normal servers, it just instantly sends you and then gets your data when you get there
makes it simpler to reason about
but anyways, if you just put the player in a limbo state and cancel all their events when they are still loading, you can just wait for the data to be loaded and bam
i suppose you could do the opposite and hold them on the first server until you're 100% sure their data has been saved
but you still have to wait for the data to be loaded anyways, so it makes sense just to do all of the waiting on the destination server
I suppose this error means I am not opening/closing connections through HikariCP properly? https://paste.helpch.at/emenenofag.php
The error is pointing at this method:
public Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}```
This is my saveAllData() method as well since it's probably what's wrong: https://paste.helpch.at/zukahomabe.java
hey so
I made a provider class that takes a result set and maps all rows and inserts them in order into a list
I need to know
ResultSetProvider.getAllRows(ResultSet set) returns a CompletableFuture and I am supplying the resultset in a CompletableFuture#supplyAsync and returning a ResultSetProvider.
When the ResultSetProvider#getAllRows(ResultSet) is called, the ResultSet is provided through a PreparedStatement that's being initialized in a try-with-resources
Since I am using a completeable future and returning the value with .join(), will I need to be concerned about the result set autoclosing before the provider can map it?
the provider is mapping to a List<Map<String, Object> (might change to set but I actually cannot confirm that we are not storing identical values)
I asked this somewhere else but I'm asking here for a differential
depends when you're joining, if inside or outside the try-with
usually proper solutions are, either having a callback to close the connection/stmt/rs when things are done, or handing the resources over to the other thread so they are closed by that other thread
with the callback option you could probably get away with
Connection c = ...
PreparedStatement ps = ...
ResultSet rs = ...
return CompletableFuture.supplyAsync(() -> ...)
.handle((r, t) -> {
try (c; ps; rs) {
} catch (SQLException ex) {
throw new CompletionException(ex); // handle downstream
}
});
What I would suggest is
try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM bans"))
{
try (ResultSet r = statement.executeQuery()) {
return doSomethingTo(r);
}
}```
or alternatively
```java
IntermediaryData data = null;
try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM bans")) {
try (ResultSet r = statement.executeQuery()) {
data = loadIntermediaryData(r);
}
}
doSomethingTo(data);```
you sly dog
😮
at that point you're no longer using futures
Yes
which, tbf is another way to solve the problem
yes which weve established is probably good
Don't look at Bev Ben
either of these approaches will work
no advertising please
Bump
uh that sounds more like a problem on the database side
or you've misconfigured something
if any connections throw that exception
i tried it both with my university database (lol) and my private one and the issue was present in both cases
// Configure and initialize the HikariDataSource
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://" + host + ":" + port + "/" + database);
config.setUsername(username);
config.setPassword(password);
// Optional: Set additional HikariCP settings
config.setMaximumPoolSize(30); // Adjust the pool size as needed
dataSource = new HikariDataSource(config);``` this is how I configure the HikariConfig
@minor summit @icy shadow thanks for the help again; also ideally i didn't really want to be using futures because these would end up being costly operations that could probably block the main thread as data is being collected when players join and leave
if the operation is expensive, it's gonna be expensive regardless of thread
yeah lol
and if it's expensive that's all the more reason to be doing it off the main thread
just to make sure, you are doing the database queries asynchronously, right?
if it's sync, it's gonna block the current thread
if it's async and you join, it's gonna block the current thread
hmmm i want to do this in a way that is non-blocking and asynchronous
and i'm not sure @icy shadow this is a class file that someone else had created and i'm trying to fix.
joining means blocking until it's done
Yeah i get that and I wanted to make sure that the result was returned before we did any operations on the ResultSetProvider
if it's not then you have a big problem
What does an async sql call look like
so far everything is being done in twr blocks
thats not really anything to do with it
jdbc is by nature, blocking io, best you can do is throw the whole thing into another thread
it would just be called in some future (supplyAsync) or with the bukkit scheduler or whatever
^
i dont necessarily see anything anywhere that indicates it's asynchronous
if you want non-blocking sql, look into something like r2dbc
what if i wrapped everything with Mono / Flux
lol
I've been trying to learn r2dbc but that's not an option for this project as of this moment
Due to restrictions from the parent organization
just put it in a future man and forget about it
throwing it in a mono/flux isn't any better than throwing it in a completablefuture
it doesnt need to be fancy
btw kinda unrelated to your question but can't there technically be a method to make nearly everything non-blocking?
Since for things that can't return like a stream of bytes (like downloading a file), it's going to be blocking a thread, anyways, right?
So just make a method that starts a new thread and runs a callback when complete
that is still technically blocking, it's just blocking a different thread lol
basically this
A future, or a completablefuture
a cf is a future
is there not a Future<T> class?
sure but it's ass
ohhh and I assume CF is a child?
it's an interface and it's very lacking
got it
Okay so I should put all the sql calls into completable futures?
throw the thing in cf.supplyasync
What about calls that are only updating the DB and not actually receiving data?
still should be async
okay cool
it's the IO that's the problem, not the actual database call
runasync ig, returning a future allows for stuff like chaining when things are done etc
but yes you want to run it async
you could have a connection that for some reason takes a few seconds to open, you absolutely do not want the main thread to be blocking for that
i've seen people in luckperms with db ping of 500ms 💀
Okay so I should return a completable future for the calls and then provide a callback to run afterwards, and then wherever i'm using the sql data i should use the methods provided by the CF to manipulate and store/return ?
or can i do the completable future work within the method body and not have to change the code signature?
yeah nothing about that is obviously bad, check your database logs would be a good start
is it happening on every connection?
uhhh im not really sure what u mean here but CF's are a replacement for callbacks
ohh okay so i meant like
can i do the completable future work within the method body and then just return the result as normal so the code signature doesn't change, or should i return the completablefuture and make the changes to the methods uses?
to be honest if you saw this codebase i'm working on you'd be questioning why i'm even bothering to work on it
quite a disaster
still not sure what method you're actually talking about but tldr is no
without blocking you cant turn a CF into a normal value
if you need to "return the result as normal" you'd need to wait until the result is there, which means blocking
^^
ok well I need to make sure that this never blocks the main thread
that's the only condition
then return the cf, which means changing the signature and adapting at call sites
okay
thanks
What methods from the CF wont block the thread? // edited because i asked the wrong thing
and if i put a try with resources in a supplyAsync that will still open and autoclose when the CF is called correct?
or do i need to close manually in a finally block
supplyAsync will run the supplier code in another thread
you want to perform all the work involving using the connection/stmt/resultset inside the supplier function, inside a try-with, not storing them in fields or collections you then return and pass around
ok so I want to return a completablefuture of any particular object that i want to acquire through the database, otherwise a CompletableFuture<Void> if the call doesn't require a return value?
basically
and then use something like #whenCompleteAsync() or #thenAcceptAsync() for any other work I might need to do in the areas where the CF is being called?
or can i just run the regular non-async call off the CF since it's supplied async?
these continuation methods you would use if you want to run something after you are sure the async action has completed
e.g.
println("started");
var someFuture = ...;
someFuture.thenRunAsync(() -> println("completed"));
println("uh idk");
this will (most likely) print:
started
uh idk
(and after a bit) completed
So, for CompletableFuture<Void>, i am returning null at the end of the block because a void has no value?
just making sure I'm understanding this correctly
hey guys...anyone can help me with a dev problem?
i try to create a plugin...at the moment, it looks pretty good...
this plugin isnt very difficult bcs its my first but i here is my problem:
the plugin works with /reward (then you get a dayli reward)
iam worked with cool down (but idk how i can make that its isnt in milli seconds bcs i need 24hours)
but that not the problem for now
the problem is...if the player has a full inventory then the plugin say you "here is your dayli reward" and dont give you anywhat...
what i need todo that the plugin check if you have a empty slot in your inventory that the plugin can give you the dayli reward?
and what i need todo that the plugin say "pls make an empty slot before you can get your reward"?
How can I just tell a completablefuture to execute without doing anything else? Just call it?
what
?
that... depends?
if it's being supplied async
would calling complete() block the thread?
i need to avoid blocking the thread entirely;
nobody can help me??
then dont force it to complete?
why would you complete it if it's being supplied asynchronously
it's 1 or the other
supply is the same as "do this, then complete() the result"
Okay so then if plugin.sql.removeAdmin(admin) returns a CompletableFuture, when I call it, the completable future will execute and complete by itself?
ok
or at least how you actually use them lol
so if i don't need to wait for the future to complete, and i am not interested in the result, i can just call it. Otherwise, I should use .join() if i need the object directly, or one of the other methods if I don't wish to block the thread and I'm not storing the object for use later on. This is correct?
I've been reading the docs by the way I just don't quite understand some of the things fully that it explains
you should not be using join or get most of the time
because those will block
theyre just like callbacks mixed with streams, usually you'd use things like thenApply and whenComplete
Right but in some cases here we need to cache the value returned by certain futures. Is there a better option than .join() or .get() that will allow us to return that value so we can store it?
whenComplete(addToCache)
you cannot get the value without blocking, period
no way around it
all you can do is use the callback functions, or block (which is a good idea in a few situations)
What are the JUnit 5 equivalents of Result & Failure objects from Junit 4 (for test suites)?
I can't seem to find any valid documentation on it. I.e I have this test suite (for j4)
Result result = JUnitCore.runClasses(AppTestSuite.class);
for (Failure failure : result.getFailures()) {
System.out.println("[JUNIT 4.11 TEST SUITE #1] " + failure.toString());
}
System.out.println("\nTime elapsed: " + result.getRunTime() + "ms");
System.out.println("Total Tests: " + result.getRunCount() + " Ignores: " + result.getIgnoreCount() + " Failures: " + result.getFailureCount());
}
huh I never saw a single person manually dispatching unit tests lmao
its just for practice
I literally cannot get anything to function with Junit 5 though, it seems like everything is just fragmented and thrown all over the place
You’re probably looking for https://junit.org/junit5/docs/current/user-guide/#launcher-api-execution
you can use a summary generating listener:
SummaryGeneratingListener listener = new SummaryGeneratingListener();
LauncherFactory.create()
.execute(LauncherDiscoveryRequestBuilder.request()
.selectors(DiscoverySelectors.selectClass(...))
.listeners()
.build(), listener);
List<Failure> failures = listener.getSummary().getFailures()
?
player.getInventory().getFirstEmptySlot() !== -1
this means they have at least one slot empty
oh okk then i only forget the !== -1 thank you 🙂
and can you help to solve the timer problem?
that the cooldown dont say 8400000 milliseconds to whait...that the cooldown say 24hours:minutes:seconds to whait?
i have try with SimpleDateFormat but i think i dont do it correct 😦 bcs i try out 4 hours...
I either got an error when executing the command ingame or the time was still displayed in milliseconds 😦
SDF is for date, not time
you can try this https://github.com/PlaceholderAPI/Statistics-Expansion/blob/ae4a6eb7bfeace7cc57deef41a7318163f85f757/src/main/java/com/extendedclip/papi/expansion/mcstatistics/StatisticsUtils.java#L135-L168 but you need to convert the time in seconds first
mhh ok thank you, i will try out...
1 last question to this...
need i say the cooldown that it need format or will it do byself?
i mean like
this.cooldown.get(formatTime)
?
cooldown is the placeholder from the time in milliseconds...
need i say the placeholder that it need work with formatTime? or will it know with this?
i can send you the jar file if you want look how i have code it...
(iam not very good...i start to lern java at the moment)
I can't go through basics rn. You need to pass to the formatTime method the time in seconds, and it will return a formatted string which then you can use wherever you need
ok that was my ask 😄
but need i do it with the variable cooldown wich i use to use save the seconds or need i do it with the seconds directly? bcs then its the string equalsTime
Barry How can ItemStack#getItemMeta be nullable? Do some items just not have meta?
No, only after 30
Which is the amount of pools I've got
So it definitely looks like I am not closing the connection pools appropriately
Is there some other code I should show other than that? idk what else might be at fault
It looks like it happens only in autosave logic
Yes you need to show where you use each connection you get. Iirc you either use a try-with-resources or you manually release the connection after using it
I am pretty sure I am doing the first?
Show please!
Yeah sorry I was pasting the code to the paste
The error specifically points at dbManager.getConnection().setAutoCommit(true);
ah i got it
dbManager.getConnection().setAutoCommit(true); this opens a new connection, and never closes it
you'll probably need a nested twr if you need the auto-committing
Ahhhh shit that makes sense
same goes for the rollback obviously
I've just got to replace it with this right?
try (Connection connection = dbManager.getConnection()){
connection.setAutoCommit(true);```
pretty much
And the rollback yeah
Yeah I would do a search in your entire codebase for every dB Manager.getConnection() and make sure
So basically i should NEVER use dbManager.getConnection() since if I do that shit will go wrong
yeah there
We basically said the same thing haha
Well you just gotta make sure you free it after every use
It's like doing memory management in C yk
Yeah, just that the try catch does it for me
Yes
i mean... you have to use it to get a connection lol, but apart from that no
the smart thing to do would be encapsulate the whole getConnection away with some usingConnection(Consumer<Connection>) method
Yeah what I meant is that I should only use it after creating a var holding that in the try brackets
I have got no idea what that means tbh
Now you're thinking with portals!
public <T> useConnection(Function<Connection, T> f) {
try (Connection c = getConnection()) {
return f.apply(c);
}
}
``` for example
then you never actually touch getConnection except in that method
Ahh yeah okay I get that
I just haven't really used functions before tbh
Or I mean, made use of them myself
i honestly just havent found a use for them in my own code
i mean I use the built in ones or any that any of the PaperAPI may use
but I never used them in code I wrote myself
Start doing web dev, you'll find a lot of uses for closures lmao
I stg nearly everything in react is a closure
3d web development 🤯
What
is that bad 😂 it's an optional module I had, it was either that or some other weird one
The weird one? It's "Technology-Enhanced Learning Environments"
no what is 3d web development
what does that mean
screens are 2d
like i feel like the second class for web dev shouldn't be immediately 3d shit yk
Code:
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
if(e.getCurrentItem().getType() == Material.BEDROCK) e.setCancelled(true);
}
@EventHandler
public void onInventoryCreative(InventoryCreativeEvent e) {
if(e.getCurrentItem().getType() == Material.BEDROCK) e.setCancelled(true);
}```
Problem:
https://i-have.c0ronavir.us/cbw45MvT
no embeds?
set current item to null (I THINK)
useConnection(identity())
gottem
cause it's funny
!!!!!
now it deletes the original item, but i still pick up a copy and can place it
the issue is, I'm trying to make an item just act like a button, you click it and something happens but the item doesn't get affected. Currently in creative when the item is clicked it gets copied to the cursor and i can do whatever i want with it. In survival it acts like it should but creative is a problem.
Yes creative is the problem. There is also a separate event in the spigot api for clicking in creative.
For some reason alot of the inventory interaction for creative is handled client side.
I used this event but it doesn't change anything.
@EventHandler
public void onInventoryCreative(InventoryCreativeEvent e) {
if(e.getCurrentItem().getType() == Material.BEDROCK) {
e.setCurrentItem(null);
e.setCancelled(true);
}
}```
it still copies the item.
Yeah, like I said alot of the creative inventory happens client sided.
So there is nothing I can do about it? I just have to circumvent it?
Not in its current state. You would need a mod or something to send more packets to geter a better indication of what the player is doing.
What should be launched first? The Bungeecord instance or the backend servers?
I don't think it really matters? I typically do proxy first.
you won't be able to connect to the backend without proxy
and with proxy you won't be able to connect to the backend if it's off
really doesn't matter, but proxy would typically boot faster allowing players in, and in the meantime while they connect the backend would spin up
Yeah okay cool cool
they're completely detached 😌
makes doing maintenance and stuff super nice as you can just go through the backend servers one by one to update
epic
If i add player.getInventory().clear(); into my code, my server will crash with this message,
[20:17:54] [Server thread/ERROR]: Encountered an unexpected exception
java.lang.AssertionError: TRAP
at net.minecraft.server.v1_16_R3.ItemStack.checkEmpty(ItemStack.java:99) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.ItemStack.setCount(ItemStack.java:890) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.PlayerInteractManager.a(PlayerInteractManager.java:407) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.PlayerConnection.a(PlayerConnection.java:1425) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:28) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.PacketPlayInBlockPlace.a(PacketPlayInBlockPlace.java:1) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:19) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.TickTask.run(SourceFile:18) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.IAsyncTaskHandler.executeTask(SourceFile:144) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.IAsyncTaskHandlerReentrant.executeTask(SourceFile:23) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.IAsyncTaskHandler.executeNext(SourceFile:118) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.MinecraftServer.bb(MinecraftServer.java:942) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.MinecraftServer.executeNext(MinecraftServer.java:935) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.IAsyncTaskHandler.awaitTasks(SourceFile:127) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.MinecraftServer.sleepForTick(MinecraftServer.java:919) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.MinecraftServer.w(MinecraftServer.java:851) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at net.minecraft.server.v1_16_R3.MinecraftServer.lambda$0(MinecraftServer.java:164) ~[spigot-1.16.5.jar:2991-Spigot-018b9a0-f3f3094]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_202]
does someone know a fix?
@EventHandler
public void onInteract(PlayerInteractEvent e) {
Bukkit.broadcastMessage(e.getClickedBlock() != null ? e.getClickedBlock().getType().toString() : " air");
if(e.getClickedBlock() != null && e.getClickedBlock() instanceof Container) {
Bukkit.broadcastMessage("container");
if(StaffManager.isInStaffMode(e.getPlayer())) e.getPlayer().setGameMode(GameMode.SPECTATOR);
e.getPlayer().setVelocity(new Vector(0, 0 , 0));
}
}
it's giving me "chest" and "barrel" but their not instanceof Container?
or am i using it wrong?
getClickedBlock() returns Block, Container is a subinterface of BlockState
so you want to get the blockstate
thank you 
so (Container) e.getClickedBlock().getBlockState()
also remember that getBlockState returns a copy of the blockstate, so you have to setblockstate or whatever for changes made to take effect
or i believe thats correct
all g I just wanted to detect clicking a container e.getClickedBlock().getState() instanceof Container worked fine
good
skript wise would armor stand interact trigger if an armor stand was shot by an arrow
is this also wrong 😭
possible
idk how many skript users we have and how many of them are watching this channel
idk anything about skript anymore but i doubt it
What's the best course of action to add custom recipes to my Paper server, using my items made with custom model data?
The main issue is that all my custom items are just "minecraft:coal" with custom model data, meaning that any piece of coal can be used to replace the ingredients.
https://hub.spigotmc.org/javadocs/spigot/org/bukkit/inventory/ShapedRecipe.html#setIngredient(char,org.bukkit.inventory.RecipeChoice) I assume this would do what you want
If that's not enough (e.g. the item can have a different name / lore) I assume you can also use the PrepareCrafting event and keep your recipes somewhere and then check if the item is completelly matching and not only its material.
yeah that's what I think i'll have to do
But then, how can I have it pop up in the recipe book
shouldnt #5 not match given this expression?
well, no, it's just matching it multiple times
Right so I create the recipes, then register them, and then handle everything in the event
yeah there's a lot of 1-3 e's in that line
But then, how about having the recipe show up when the player picks up an item or does an advancement or something? I guess I will have to do all that with code instead of being able to do it through jsons right?
theres something that can make the regex start at the first
i dont remember on the top of my dead
Ah yes, you need to give them access to the recipes somehow. Unless you need it to work like vanilla recipes, where you unlock them by collecting certain items, I would just give access when the players enters the server
Yeah I need it to work like Vanilla
so I'm currently looking for a way of taking a list and then sorting it based on input so I can get the stuff that has been added to it in order (based on input, as I said), I was thinking of using a set but I dont exactly know if thats the best thing to do
so what should I use?
a set?
take a list and then sort it based on collections.sort?
sets inherently have no order, so would probably not be a wise choice for an ordering scenario as you describe
you should probably just take a list and sort it however, it's not super clear what your intention for sorting it is "based on input?"
so sorting a list with Collections.sort()?
there are lots of ways of sorting, that is one of them
so when I loop the list to get the values in it I get them in order of input
so lets say I push some stuff into a list
then I sort it to later get the values inside it in order
thats what I need to do
yes thats what I meant
it most likely is already ordered that way
unless you construct the list in a specific way, that's how lists are generally built lol
I sit here for 2 hours at 2am to find where in my code I have an infinite loop and then I see this: for(int index = loc.getBlockY(); index > -63; index++) {

index++
-63
just noticed wrong channel mb
that will eventually break 
thank god java doesn't have unsigned integers or you'd be waiting twice as long!
no if it had unsigned then yes it would loop forever 
I am using FAWE, and I am getting a weird error about the schematics I am using. I created them on 1.19.3, but they wont paste (I am using the API): https://paste.denizenscript.com/View/108289
Content of Server Log Paste #108289: Unnamed Server Log Paste... pasted 2023/04/02 08:11:53 UTC-07:00, Paste length: 4377 characters across 32 lines, Content: [11:05:27] [Server thread/WARN]: java.io.IOException: Schematic file is missing a Blocks tag[11:05:2...
Is there something I am doing wrong?
How does the Java logger work exactly
I set its level to FINEST, shouldn't anything printed out with .fine() be shown?
Since it's a lever higher than FINEST?
System.out.println(Bukkit.getLogger().getLevel());
Bukkit.getLogger().fine(itemKey.getKey() + " has flags: " + this.flags);```
The logger level shown from the first line is `FINEST`, but for some reason the message below it doesn't display in the console?
just log with info
I wanna split up the importance of logging messages though
I know that doesn't answer your question but it works
Ughh
ah
I am logging with info as well, which works, but instead of constantly commenting out/in stuff over and over again i'd rather just set different logging levels
are they for debug?
Yeah
and also, don't use the bukkit logger directly
use your plugin logger
Oh sh
I forgot about that
Yeah my bad
I think that's the issue
the bukkit logger's logging level is set elsewhere
and you can probably enable debug level somehow and use that
Hmm i suppose there is no way to make custom recipes using items with custom model data work as seamlessly as normal Minecraft recipes?
The recipe book tells the player that he cannot craft the custom item even if they got the right ingredients in theit inventory
Does anyone know if there is any way to fix this?
The recipe book not correctly displaying whether the player has the correct items to craft something?
were there any changes to custom model data and unicode image replacements between 1.17 and 1.19? I am using the same resource pack, and no custom model datas or unicode image replacements are working.
;d PrepareInventoryResultEvent
smh
https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/inventory/PrepareInventoryResultEvent.html
declaration: package: org.bukkit.event.inventory, class: PrepareInventoryResultEvent
Oh I did it backward that's why
Nvm DocDex said no anyway
What
Oke
You can create advancements I guess and give them the recipe
Does creating a recipe actually make it craftable then?
Yes ofc
Doesn't seem right, but I'll take your word for it
What doesnt seem right?
I mean, yes, simply creating the object wont make it work, you need to register it through Bukkit#registerRecipe or smth
This is the issue, not that
Hm
The recipe can be crafted, but the recipe book believes it cannot
I suppose that can be fixed through packets...?
Oh neat
The book might be client side
yeah that's the thing it probably is
What happens if you use the recipe give cmd?
I'm pretty sure you can edit the book but idk if it is possible using spigot's api
I already have the recipe
And how does the recipe code look like?
Also, try to give yourself a stick with model data for example and see if the torch recipe is red too
it's not optimal rn as it's a whole method for a single recipe, but first I wanna make sure this method works before i refactori t
i'm not sure how to do that tbh
Try /minecraft:give stick{CustomModelData:1}
And you also need the recipe which is unlocked by getting coal btw
it's not red
yeah they got a display name if that's what you mean
And other flags I created myself
yeah they've got 1/2 persistent data
But still, if the item can be craftable it should work I guess
@Override
public boolean test(@NotNull ItemStack t) {
for (ItemStack match : choices) {
if (t.isSimilar(match)) {
return true;
}
}
return false;
}```
I tried creating my own RecipeChoice but Bukkit didn't like that
public interface RecipeChoice
extends Cloneable, Predicate<ItemStack>```
RecipeChoice has 2 extensions, 3 super interfaces, 2 implementing classes, and 3 methods.
Represents a potential item match within a recipe. All choices within a recipe must be satisfied for it to be craftable. This class is not legal for implementation by plugins!
sealed interfaces in 20 years
Are packets through ProtocolLib not an option
Idk
I suppose the PaperAPI doesn't fully support this
So I'll just have to deal with the recipe book displaying the custom recipes in red
I guess if you register it as a normal recipe (with materials instead of choices) it works fine?
The issue though with that is the recipe will result available at the wrong times
Since all my items are Coal with custom data
yeah I just said to test
Yeah that does work
I genuinely feel like the solution might be using packets through protocollib
Nah what
In a server without any plugins, when I try clicking on the recipe for the torch it doesn't work
This, inside of RecipeChoice, is deprecated... but why?
The explanation is extremely vague
d;recipechoice#getitemstack
@Deprecated @NotNull
ItemStack getItemStack()```
Gets a single item stack representative of this stack choice.
for compatibility only
a single representative item
great
Yeah rip
sometimes spigot annotates stuff with deprecate to warn users about something, e.g. Bukkit#getOfflinePlayer(String)
but this makes no sense
I wonder if it doesn't actually work in the newer versions and was kept in purely for compatibility?
Though if that were the case I'd expect it to return null
public List<String> noX(List<String> strings) {
return strings.stream()
.map(e -> e.replaceAll("[Xx]",""))
.collect(Collectors.toList());
}
is using String#replaceAll overkill here (regex)
(remove all occurances of "X" from a List of strings)
how can I get the formatted name of a material? for example: Material.DIAMOND_SWORD into "Diamond Sword"
Component.translatable(Material.DIAMOND_SWORD.key()) or smth around those lines
that gives me a TranslatableComponent, but how does that become a string?
toString() just print json
It does not become a string
What do you want to do?
The component will be rendered depending on client's language
I want it turned into a string that I can manipulate
Welp, for that you would need to handle the names on your own
PlainTextSerializer might work
In all honesty, I've got to say GPT-4 is pretty great when it comes to the PaperAPI
I've been using it to write documentation for me, and other than making a couple minor corrections it's been really great
Your questions are making sense now
I mean yeah, i'm talking to ChatGPT to figure out how to do some things within the PaperAPI it's really good
u bought gpt 4? 👀
Though if not used correctly it's just a spoonfeeding machine which breaks every other method
Yeah, I use it for uni 😂
it's still a spoonfeeding machine either way 😉
💀
For sure, but it speeds up things a LOT
After half a decade of writing plugins, if I don't have a lot of free time with uni/work to work on this stuff
Yes, as a spoonfeeding machine, it does make spoonfeeding a lot faster
Spoonfeeding is mostly shit for beginners, after years of programming if I don't have a lot of free time to work with the PaperAPI it makes it a less annoying yknow
github copilot is literally just spoonfeeding
it's not good for beginners but useful for advanced developers
But very often it writes code which makes 0 sense
That is true
And it does speed up repetitive stuff quite a lot
for me its just mainly useful for repetitive code
not like completely repetitive but similar patterns
^ 😂
yeah, ChatGPT is good as it can explain parts of the API or help refactor code
mhm but you can't input the whole project
although
maybe gpt 4 u can?
not a big project
but i think gpt 4 can store more memory
Nah, it shits itself if you write more than like 2000 characters or something
oh lol
It's got a memory of 64k characters or something?
Though after a while it begins hallucinating methods that do not exist within the API
💀
Translatable components are player dependent
Oh that makes sense, I haven't touched those specifically yet.
yeah the point is that you send it to them in the chat or whatever and then their client translates it in their language or somethin
Paper has a method
I think
ItemStack#get18NDisplayName or smth
I am just doing a quick ```java
String formattedName = Arrays.stream(material.name().toLowerCase().replace("_", " ").split("\s+"))
.map(word -> word.substring(0, 1).toUpperCase() + word.substring(1))
.collect(Collectors.joining(" "));
a lot of it is different but if that's ok then it works
I am not using Paper, so this is the next best choice (that I can think of)
didn't think of using paper?
my server instance isnt paper
Well that didn't clarify anything
pinged me to tell me something we already knew lol
Oh paper api instead of paper server maybe,
yeah, something like that
Makes sense, my bad 😳
spigot ig
wtf why
idk, never bothered to replace it with paper/purpur/pufferfish
I will once into production tho
you're missing out big time
especially considering you could use a bunch of APIs that would make your life a lot better
Paper is a drop-in replacement too, not terribly confusing
I know, I just havent done it
well this is as good a time as any
considering you could literally use part of the paper api
yeah submit to peer pressure
i mean it's in their best interest
I agree, they should submit to peer pressure
That's why Im pressuring them as a peer
isnt using the paper api more than just adding a dependancy? I remember some sort of dev kit or something I had to set up
nope
you just swap out in your gradle file
it's also easier to setup a dev server for than spigot, since you don't need to run buildtools or anything
https://bstats.org/global/bukkit 58% of servers use paper now apparently.
Wondering what that 6% unknown is
For A authentication plugin should i have it check for the players name for authentication or their uuid?
lowercase/uppercase name I would guess
Depends on what you're authenticating for, if you're an online mode server UUID works just fine.
If you're an offline mode server Idfk
because won't the UUID change if you joined with mycoolnickname and later with MyCoolNickname?
In offline mode yes I believe so
you usually block the other variants of one name
if someone joined with Username, then someone else can not join with USERNAME
well I suppose you'd save the name of the player with capitalization on the first join and just check if it matches it on other attempts
hm
UsErNaMe.upperCase() is the same as username.upperCase()
Map<NameLowerCase, NameActual> names?
onJoin
actual = names.get(joinedName.lowerCase)
actual == joinedName?
You can look at what AuthMe does, but it depends on your server type I guess, online or offline.
or just store the name directly?
¯_(ツ)_/¯
Over complicating things is the true sign if an engineer
Thank you everyone else for pitching in too, I’ve gone ahead and stored the name along with any type of variant and it seems to work perfectly! I didn’t think to do that so thank you 
you really shoudn't need to store all the possible variants
It doesn’t store all the varieties but instead saves just the actual name then upon checking it will try all those varieties on the name, hence making the player login if it matches
you store either a uppercase or lower case version, but with the first vwrsion if the username
<String,String> map
map.put(username.toUppercase(),username)
then check if the value in the map that corrisponds to username.toUppercase() is the same, if not deny access
You dont want to allow users to join with various versions of an username, if this is for Minecraft.
TreeSet moment
How can I fix the NULL-Exception Error?
https://paste.ofcode.org/5WiUavs8btB22RESpyieHT
My code:
https://paste.ofcode.org/R3KTNsPAM97xWiZprdnEy6
that is not a null exception error. that's a number format exception
oh i see
And it comes from line 32.
long duration = Long.valueOf(args[1].substring(0, args[1].length() - 1));
args[1].substring(0, args[1].length() - 1) this is not a number. it is an empty string
oh, that's my bad prob thx for helping
@EventHandler
public void on(ProjectileHitEvent event) {
event.getEntity().remove();
if (event.getEntity().getShooter() instanceof Player attacker) {
if (event.getHitEntity() instanceof Player victim) {
if (GameManager.getPlayerTeam(attacker) == GameManager.getPlayerTeam(victim)) {
event.setCancelled(true);
}
else if (victim.getHealth() - victim.getda <= 0) {
killReward(attacker);
Bukkit.broadcast(MessageManager.messageManager(attacker.getName()+ " <red>shoot <white> "+ victim.getName()));
}
}
}
}
It's currently spaghet but how i can check did projectile kill entity?
uh oh arrow code
@EventHandler
public void onProjectileHit(ProjectileHitEvent event) {
if (event.getEntity() instanceof Arrow arrow) {
if (arrow.getShooter() instanceof Player shooter) {
Entity hitEntity = event.getHitEntity();
if (hitEntity instanceof LivingEntity target) {
if (target.getHealth() <= 0) {
// The projectile killed the entity
}
}
}
}
}
here's more arrow code for ya bud
So you basically say this would work?
@EventHandler
public void on(ProjectileHitEvent event) {
event.getEntity().remove();
if (event.getEntity().getShooter() instanceof Player attacker) {
if (event.getHitEntity() instanceof Player victim) {
if (GameManager.getPlayerTeam(attacker) == GameManager.getPlayerTeam(victim)) {
event.setCancelled(true);
}
else if (victim.getHealth() <= 0) {
killReward(attacker);
Bukkit.broadcast(MessageManager.messageManager(attacker.getName()+ " <red>shoot <white> "+ victim.getName()));
}
}
}
}
yeah, most likely. also, try and use return statements instead of nested ifs. for example:
@EventHandler
public void on(ProjectileHitEvent event) {
event.getEntity().remove();
if (!(event.getEntity().getShooter() instanceof Player attacker))
return;
if (!(event.getHitEntity() instanceof Player victim))
return;
if (GameManager.getPlayerTeam(attacker) == GameManager.getPlayerTeam(victim)) {
event.setCancelled(true);
return;
}
if (victim.getHealth() <= 0) {
killReward(attacker);
Bukkit.broadcast(MessageManager.messageManager(attacker.getName()+ " <red>shoot <white> "+ victim.getName()));
}
}
It makes it far more readable and understandable.
Thx!
This return health that I had before i got shot
famous last words, left for technical debt, forgotten jira task by now
Anyone know the mappings for EntityPose? I found Pose as the unmapped but its different from entitypose.
getting an error on this int length = Integer.parseInt((String) this.getConfig().get("test.test.test"));
error: class java.lang.Integer cannot be cast to class java.lang.String
how would i rework this to fix it?
getConfig().getInt("test.test.test")
thank you so much! <3
any idea why neither of these EventHandler methods are being invoked?
@EventHandler
public void cancelDragEvent(InventoryDragEvent e) {
e.setCancelled(true);
Bukkit.broadcastMessage("inventorydragevent called");
}
@EventHandler
public void onClickEvent(InventoryClickEvent e) {
Bukkit.broadcastMessage("inventoryclickevent called");
if (e.getClick().equals(ClickType.RIGHT)) {
this.player.sendMessage(ChatColor.translateAlternateColorCodes('&', "&a&l[BitCore]&a Right clicking will sell the item!"));
// player.playSound(player.getLocation(), Sound., null, 0, 0);
} else if (e.getClick().equals(ClickType.LEFT)) {
this.player.sendMessage(ChatColor.translateAlternateColorCodes('&',"&a&l[BitCore]&a Left clicking will buy the item!"));
}
}
Did you register the listener?
Np
thats called the enum is no lomger an enum while unmapped
Yeah I just matched it myself. I moved on lol
👍
certainly makes figuring out what the unmapped version of a mapped class, method or variable is called
cus navigating the minecraft code is hard sometimes
Especially when you have to find all remapps and moved code from 1.8.4 to 1.19.4 lol
created a public variable at the beginning of the main class public List<String> playerlist;
edited it in a function within the main class this.playerlist.add(p.getUniqueId().toString());
error cannot invoke "java.util.List.add(Object)" because "this.playerlist" is null
i assume i am getting the error due to changing the variable within the function although i do not know how i would keep the variable public while being able to edit it within the function.
You never initialize the variable playerList... playerList = new ArrayList<>();
god im stupid, thank you
Np.
@EventHandler
public void cancelDragEvent(InventoryDragEvent e) {
e.setCancelled(true);
Bukkit.broadcastMessage("inventorydragevent called");
}
Still doesn't get called, unsure why. Listener is registered, not sure if its because it shares the same class as another Listener (I dont think that should be a problem)
show the whole class along with the class where you register it
that code itself looks fine, so maybe theres something else that could be causing the issue
First class is where the listener is registered, 2nd is where the eventhandler method is
Also, (screenshot from the provided code ^), for some reason this code doesn't work either. the method is invoked, but neither of the conditionals are passing
Enums should be compared using == rather than #equals
Ah alright, thanks for letting me know ^
found what my problems were:
- NPE (player was null, using
getWhoClicked()instead to access the interacting player) - clickevent cancellation state wasn't false (thought only drag was necessary)
I have an expansion hook in my plugin which I can see in my server console is successfully registered on server startup, but none of my placeholders are working. Here is my onRequest method of my hook:
@Override
public String onRequest(OfflinePlayer player, String params) {
if (params.equalsIgnoreCase("timelock_server_name")) {
return plugin.getConfig().getString("placeholders.timelock_server_name", "My Server");
}
if (params.equalsIgnoreCase("timelock_unlock_at")) {
return Timelock.unlockAt;
}
if (params.equalsIgnoreCase("timelock_lock_at")) {
return Timelock.lockAt;
}
return null; // Placeholder is unknown by the Expansion
}```
Running /papi list shows my hook.
The hook is registered in my onEnable method of my plugin class:
// Register placeholders with PlaceholderAPI.
new TimelockPlaceholderExpansion(this).register();```
When I do /papi parse <player name> %timelock_server_name% it just returns my placeholder, %timelock_server_name%
Does anybody know what could be wrong here?
You don't include your expansion name in the match. So for your current setup to work, you'd need to do %timelock_timelock_server_name%
So just get rid of the first timelock_ in all the checks!
@glacial comet
This works! Thank you very much.
In the identifier, I had actually put my full package name identifer instead of just timelock so I had to fix that, too.
looking for a dev that knows to work with deluxemenus and make me a custom shop, i could pay up to 5$ cuz its a very basic thing.
Is it $5 because it's basic, or $5 because you only have $5 🤔
is there an expression to get the coordinate of the other edge of a schematic (the point not entered into the editsession)?
Any idea as to why the two EventHandlers aren't executing their code?
It seems as though if (!(e.getInventory() == gui)) return; is returning true.
Try using equals instead
Also why !(e.getInventory() == gui) and not e.getInventory() != gui?
are you registering the listener?
what fixed it was having the registered Listener instance be the same as the one being used by the CommandExecutor used to open it
Actually, what would be even smarter is to just.. not initialize gui during instantiation..
less nesting ig
wait, no. that doesnt make sense what I've said.
You're right
i'm starting to wonder if its just more practical for the majority of this class (aside from EventHandlers) to just be static. I mean, if its made to construct only one gui, then why instantiate it?
Instead of just having one instance of the class used for everything from listener registration to accessing the guis functionalities, instantiate it once to register the events, and the rest of the functionality remains static
id still instantiate it
yeah fair, hate the idea of making it all static anyway
Objects are compared with equals()
Sorry, sent in the wrong channel. If that message was for me
Has anyone built this plugin? https://github.com/Xiao-MoMi/Custom-Crops it doesn't have all the required libraries added in build.gradle / the libs folder 
The free plugins are easy to get, but then there's this battle pass plugin that used to be OS but the new developer made is private 🙂
Just comment out the code that uses those libs, ez 😃
yeah I wanted to avoid that but it seems like the only option
@pulsar ferry I wonder if gradle can be configured to ignore certain classes 
Anyone know what
compileJava {
options.compilerArgs += ['-parameters']
}
``` Would be when compiling with kotlin 1.8.20 cause compileKotlin is deprecated
i tink anyway
what
that should be only relevant for Java code anyways, unless Kotlin has a similar feature
i think i found what i need anyway
tasks.withType<KotlinCompile> {
kotlinOptions.javaParameters = true
}
yeah i found that
maybe they have an api plugin that you can use as a replacement?
like some devs have a basically empty jar with the class names and methods that wouldnt do anything, but are the same locations as the premium plugin location to basically work
interfaces
like the bukkit classes
Nah, the dev is greedy and didn't made and api, unless the wiki is outdated
fun
customers:
- name: "X"
age: "Y"
- name: "A"
age: "B"
What is the best way to get customers as some type of list (maybe a list of maps with String keys and String values etc) in plugin config?
I think that's a List of Map<String, Object> or something like that
config.get("customers") would return an object, in this case a memory section
i was sure it was a memory section
i mean in this case customers is a list of sections
ohhh i see
Are we talking about these? https://hub.spigotmc.org/javadocs/spigot/org/bukkit/configuration/MemorySection.html
actually how do you cast an object as a list without it complaining that it might not be
Is it paper spesific?
no
Thanks
"'setPlaceholders(org.bukkit.entity.Player, java.lang.String)' is scheduled for removal in version 2.10.8"
what is the other syntax please ?
uhhh placeholderapi is at 2.11.3
it was undeprecated
i remember seeing that awhile ago
as far as i can tell from looking at papi's wiki page on github theres no other method for setting placeholders, or atleast i cant find them, maybe im blind idk
yes thanks I updated it
0 placeholder hook(s) registered! ????
total = PlaceholderAPI.setPlaceholders(player, total);```
did you download the bungee expansion?
through the ecloud command usually
yes
ok thanks
the problem is:
at fr.idaamo.essentials.Listners.PlayerListener.onJoin(PlayerListener.java:83) ~[?:?]
at sun.reflect.GeneratedMethodAccessor70.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_312]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_312]
at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[server.jar:git-Spigot-21fe707-741a1bd]
... 14 more```
and the scoreboard says "%bungee_total%" not the total
whats on line 83
id assume it nped before it could replace the text or smth
nah I tested a mysql thing
but the bungee doesn't have to do anything with that
total = PlaceholderAPI.setPlaceholders(player, total);```
{
Score second = objective.getScore("§7Connecté: " + total);
second.setScore(8);
}else{
Score second = objective.getScore("§7Connectés: " + total);
second.setScore(8);
}```
I did this
is the bungee expansion registered? 🙂
well you still didnt answer whats on line 83 in the playerlistener class
so telling us that doesnt give info on what was null
I removed it
it's not important
no, how do I do that please ?
um
I just didn't install it correctly
so you do /papi ecloud download bungee
then /papi reload
ye I installed it already, there is no bungee_total anymore but it says 0 but I'm in the server...
it takes around 30s for placeholders to update
so what do I have to do ?
wait
im assuming it polls all of the placeholders every 30 seconds?
lessgoo thank you all
Would be possible to publish a jar to github packages? I don't have the src, only the jar 🥶
anyone here used the LitebansAPI before? Im trying to listen to ban events but the wiki isnt great
Official LiteBans API repo, wiki and issue tracker. https://ruany.gitlab.io/LiteBansAPI/
first result shows how to listen to ban unban events
i dont see Events.get()
ye
and you clicked the little maven or gradle icon after making changes
Yes
<dependency> <groupId>com.gitlab.ruany</groupId> <artifactId>LiteBansAPI</artifactId> <version>0.3.4</version> <scope>provided</scope> </dependency>
and the repo link is correct?
Yep, <repository> <id>jitpack.io</id> <url>https://jitpack.io</url> </repository>
try typing litebans.api.Events
dont copy and paste
it should have auto completion things for it
Yes it does
middle click Events
i have it imported already
if your using intellij atleast it should show some form of source
hmm yes im using intelij but nothing happens on middle click
do you see any methods at all?
it just shows Events on the autocompletion
so auto complete it and check if you can find any methods
only thing is Listener - which is a class inside of Events
your just doing Events and not new Events right
yea i didnt create an instance of it, im just using Events
weird
go find your external libraries, find litebandapi and look through and find the Events class
double click it, it should open
should be below your project structure
can we switch to dms or somewhere where i can post images?
post the images to imgur and post here
did you mean external libraries by here or my pom.xml https://i.imgur.com/gafgAgh.png
neither
the libraries below where your pom xml is found
oh 🤦♂️
should be a directory right at the bottom of the list
yes it does
does it show the get method?
yes
if (instance == null) {
throw new MissingImplementationException();
} else {
return instance;
}
}```
then you should beable to use the get method
maybe its something with maven then
if its there you should beable to use it
Events is abstract, so it should be green afaik
unless its not hmm
not green i mean
maybe its interfaces that are green
mind posting the full class to paste.helpch.at
just ctrl + a ctrl + c
ofcourse post the link here
i ment your class

wheres the access modifier
and the variable type
you cannot have a statement in the main scope of the class
it has to either be a variable or a method
no wonder it doesnt work
you can have a statement in a method
you can in theory have a statement as a variable as long as it returns a type
statements that return void, cannot
Folia ETA?
Tomorrow
Next near maybe yesterday
Very exciting to hear
I released it for you
How would I go about loading and pasting a schematic at a certain location using the WorldEdit API
Take a look at their documentation, it has an example for that
I need to replace some item frames with display entities, and by some I mean quite a lot spread across the world (custom furniture made by oraxen). Is there any way I could loop through all the chunks that are generated, to load them and do the replacement? The plan B would be to use ChunkLoadEvent and do the replacement progressively as players load chunks but I would really like to do the replacement once for good.
Edit: Since the map is pre-generated I guess I can just get the coordinates of the chunks that are in the corners and use a for loop.
Hey, what's the best way to get the plain String of item#displayName and each of item#lore? with their text colors as & or §?
LegacyComponentSerializer
I tried LegacyComponentSerializer.legacyAmpersand().serialize(itemStack.displayName())
But I am getting "&fchat.square_brackets"
ItemMeta#displayName
get it from the meta not from the item
woo let's go poor naming
Sooo it’s coming out today still?
Folia is already public
Matt sent a link here
So this plugin supports folia?
no
That’s what I was getting at..
Deluxe Menus
no, but I would like to, the developers hope that you will make support for the core
kernel?
flolia
me?
I just said that I hope that the developers will make support
Oh when I read " the developers hope that you will make support " I thought you were referring to me lol
a lot of extra work to add support for another fork that's has entirely different internals lol
That is true, but you guys are very talented ( :
unless it becomes more popular than paper itself and has a clean way of making sure to not allow racing conditions, then I don't see developers adding support for it by default
hmm if this isn't planned I wouldn't mind assembling a small team of people to help me add Folia support. The biggest road block is that this Deluxe Menu doesn't have a GitHub yet. At least from what I know.
If you would be interested in this proposal let me know. I would still need the GitHub to Deluxe Menu so if you could send me it ( it can be through dms or here ) if you approve of this I would appreciate it.
the core has already taken 20% of the used cores in a week + multithreading is a very weighty argument and a breakthrough in servers
I think most things that needs to be changed are regarding tasks
I hope you guys know that Folia is far from being ready for production. As for DeluxeMenus, I don't have an answer regarding when it will support Folia.
And I don't think many of us have enough resources to test the changes during development.
Is there any resource on how to preverse comments when using Configurations in Bungee plugins (on save)?
Whenever I set a new value and save the config, all my comments disappear
I checked with Deluxemenus they say they don't have it yet
So I am kinda silly bad at trying at softdepends.. what's the proper way of handling soft depends?
did worldguard softdepend and it just went ballistic trying to find class even when disabled.
Check the plugin manager if the plugin is enabled, and don't try and instantiate classes that don't exist
if you require those classes for your plugin to function correctly, then use depend. if not then do what doctor zod said
appreciate it ^^
Is there a way I can get a Crafting Table Recipe by its id (String)?
are recipes stored with their ids?
NamespaceKeys on 1.13+
does it work for default crafting recipes too? or for just custom recipes from a plugin?
all recipes have a key
since they are all registered to the exact same place afaik
oh
this doesn't seem like developer questions
oh sorry
I have a plugin that expands barrels, and due to some issues, I need to create a custom loop that transfers items when hoppers interact. How can I do this at server startup without looping through every single block? I just want to check if there is a hopper above/below the barrel
Continued from #off-topic
Try looping tileentities
yeah, I am trying that now, just seeing if there were any alternatives.
Looping through TileEntities on ChunkLoad seems to be the best method.
Depending what you are doing you could loop through the world's nbtdata
I have 3 base components, and I want send them in one line. How can I add the base components together to make one line?
Should I use BaseComponent#addExtra?
d;adventure Component#join
@@Contract(pure=true) @@NotNull
static Component join(@NotNull @NotNull JoinConfiguration config, @NotNull @NotNull ComponentLike @NotNull ... components)```
Joins components using the configuration in config.
4.9.0
the resulting component
config - the join configuration
components - the components
^
how are these two ItemStacks not similar to each other
for some reason ItemStack#isSimilar returns false
well one is AIR x 1 and the other is AIR x 0
ah
amount 0 sounds sus, does it work for other stack sizes?
perhaps the 2 stacks have other data that is different
because from looking at this youve set the itemstack to have a material of air, which doesnt remove extra data that the itemstack might have had before hand
I am logging out ItemStack#toString
so I am pretty sure thats all the data
why would you trust a method that can give you arbitrary values instead of using a debugger
amount=0 means it is air
oh, empty items aren't similar to empty items
public static boolean isSame(ItemStack p_41747_, ItemStack p_41748_) {
if (p_41747_ == p_41748_) {
return true;
} else {
return !p_41747_.isEmpty() && !p_41748_.isEmpty() ? p_41747_.sameItem(p_41748_) : false;
}
}
that's intentional
yes, p numbers
I'm doing a plugin with dynamic inventories, what is the best way to check is it my gui at InventoryClickEvent? I mean is there anything like a uniqueid of menu or sth else?
you can check the InventoryHandler instance
inventory.getHandler() instanceof MyHandler
what should "MyHandler" be exactly? I create inventories using Bukkit.createInventory
d;Bukkit#createInventory
@NotNull
public static Inventory createInventory(@Nullable InventoryHolder owner, @NotNull InventoryType type)
throws IllegalArgumentException```
Creates an empty inventory with the specified type. If the type is InventoryType.CHEST, the new inventory has a size of 27; otherwise the new inventory has the normal size for its type.
InventoryType.WORKBENCH will not process crafting recipes if created with this method. Use HumanEntity.openWorkbench(Location, boolean) instead.
InventoryType.ENCHANTING will not process ItemStacks for possible enchanting results. Use HumanEntity.openEnchanting(Location, boolean) instead.
a new inventory
owner - the holder of the inventory, or null to indicate no holder
type - the type of inventory to create
IllegalArgumentException - if the InventoryType cannot be viewed.
holder*
you create a custom class that implements InventoryHolder and on click you check if the holder of the inventory is an instance of your custom holder
understood it, thanks
This warning is incorrect right?
Or am I just too tired
It could be left click something
they cancel each other out i believe
!=
How, if it's not right click on block or air it could still be left click on block or air?
It's not the only two possible actions
if statements can be very much fucked in my brain so give me a second
but there is if (!event.isRightClick())
Oh really?
because it could also be PHYSICAL action believe it or not
Ah yeah, with action.isright... etc tho
Dont really understand the whole physical thing
copilot for the win
yeah you want &&
physical is pressure plates
"ass pressure" because md_5 thinks hes hilarious
Would that be considered a player interaction? Well ig it makes sense actually
public enum Action
extends Enum<Action>```
Action has 1 extensions, 3 all implementations, 2 methods, and 5 fields.
Lmao
Get good
Thank you
you already have an answer for what to do, but the reason it's giving you that warning is like this: if the action IS Action.RIGHT_CLICK_AIR, then the first boolean is false and the second is true, so therefore the whole thing is true. If the action IS Action.RIGHT_CLICK_BLOCK, then the first one is true, so it's true. And if it's any other action, they're both true. So there's no way it can be false since it is always one thing, it can't be both of them, which is the only way you return false.
Ohhh yeah that makes sense, I should really get some sleep lol
Ty
Btw quick question, what would a material string be? For example item.getType().toString()
If it was a netherite sword for example
try it and see!
Yeah I can do that, but havn't set up any testing yet so would take some time
likely just the name, but I think there's a function like Material#name() that gives you the serializable name
Just wondering if anyone knows
I need it pretty exactly though, for this ugly code lol
String type;
String itemMaterial = item.getType().toString();
switch(itemMaterial) {
case "1" -> type = "sword";
case "2" -> type = "shovel";
case "3" -> type = "axe";
case "4" -> type = "pickaxe";
default -> {
return;
}
}
Ignore those 1, 2, 3 and 4
Those would be the material to string
okay I don't think I understand what you want here
because you can just switch case over an enum
and it's like, actually type safe and stuff
lol
yeah sidenote that's like the whole point of enums lol
Yeah makes sense, and I would've probably just thought of that if I was awake lol
That doesnt work with BaseComponents, and I am not sure how to convert as the docs for Adventure also don't explain how to do hover and click events.


