#help-development
1 messages · Page 417 of 1
setType(Material.AIR) 
If you want them to be broken in a certain time like normal blocks, that’s a bit more advanced
You can do Block#getBreakingSpeed and add the total progress and check if it's over one
change the texture to wood to make it breakable
Send a fake block and when they break the fake block break the bedrock 

True
dont have blocks in the world

lmao seriously
don't run a server
Don’t have world
or break every block a player looks at
left rotation and right rotation? the hell
I think I came here in a bad time
Exactly my reaction
+spin -spin in CS goes hard
wasn't able to find any xd
the api has to have more details than this
Ask Mojang
i wanted to do rendering in c++ but when i saw this, nah man
Have fun. Took me a while to figure out
What do i have to put as the second argument for the World#spawnFallingBlock(Location, Blockdata) for it to spawn a Magma Block?
BlockData
Material.MAGMA_BLOCK.createBlockData
thought its free rotatable
thx
did you figure it out in the end?
Kind of. Im still trying to figure out why you need two linear transformations.
Because there is no imaginary space we can work with. Only a real one.
How do I get the second part of the bed when BlockMultiPlaceEvent is fired?
Ok, you can obtain it via getReplacedBlockStates
is there even a reason to avoid doing the interpolation yourself?
this seems like a lot of effort for something that seems hard to justify
But smooth on client
i know in hypixel duels there is few arenas in one server. whats a good way to create same structure and manage such arenas (specially load/unload worlds)?
NBTTagCompound not existing anymore?
Dont bother with loading/unloading worlds.
Spigot will lag and there is no way around that.
that's another thing too, if I have a transform and change the transform halfway into it to reflect a new state and do that a bunch of times but clients are running slow, how do they catch up?
With the Spigot Config Is it better to using a String index for a lists or should I use an ArrayList and parse?
are you sure they are in one server?
Yeah they run a few of several games on one server
but how can you be certain of that o.O
I'm trying to make the autocomplete dynamic and simple to generate but the ArrayList was requiring a lot of parsing. I tried looking around on forums and got both being recommended.
hasn't their shit been leaked a few times?
not that I am aware of, if it has nothing that wasn't like important
but I have a general idea in how hypixel does their stuff
In the past there have been bugs to leak chat and game messages between games on the same server
You can also get watchdog removal messages when it’s no one in your specific game
chat isn't an indicator that you are on the same server
Well sure
But it’s way more likely they let chat slip from another game on the same server than another sever entirely
doubt it
Plus some of their games are very small, it would be a waste to use 1 server per game
it would be far more optimal to leverage the single threaded nature of mc then it would be to stuff a single server with several games
how so?
assuming that a minigame is going to max your thread out is a fun assumption
you are also assuming the OS wouldn't use the freed up space either
I have no clue why this uses two quaternions
its around 8 arenas on one server
as far as i know
hosting 500 servers each for every duel game would be not that cheap
How scalable do you need this to be?
I would suggest simply having one world with 8 Arenas in them.
yes, but how to manage worlds, im trying to find best way
ah
i mean
Then create an Arena class with a BoundingBox and a Set<UUID> for participants
And an ArenaManager which manages those arenas. Maybe in a Map<String, Arena> where the key is the name of the Arena.
one world with arenas? but none of big servers done it by this way
You wouldnt know if they did.
Not an argument. Also: You are not Hypixel.
If you want to "do it like Hypixel" then start writing your own server
software. Dont use Spigot. Fork it and create a dedicated jar just for
minigame instances.
Because in theory you can have multiple players have the same coordinates on the same world
but perceive completely different game states. *Assuming you have a highly modified jar like Hypixel.
yes they have and they do. When you start becoming a large network, you have to do things differently. Its not the same as a small network where you are restricted to only the limited resources you have.
Whenever calling the following, if the hidden player eats, does the eating sound gets passed to the other player? https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/Player.html#hidePlayer(org.bukkit.plugin.Plugin,org.bukkit.entity.Player)
declaration: package: org.bukkit.entity, interface: Player
is there any plugin which automatically rekit a player when a player kills another player?
if anyone have it please give me ill apricate it
btw there is no good ways to manage worlds in this way?
But again: You dont need to scale that way. They are using a fk ton of technology
for load balancing. They dynamically start servers, load worlds etc depending on
how many players are trying to play something.
you are under the assumption that every server would need to have 10gb of ram or something, when this is not the case, the amount of ram you would need to allocate if it was just per server for a small minigame tends to be lower then if you tried to stuff a single server with many games
I am not asking about what's the behavior, but the expected behavior instead. Like, should we expect the API to hide the eating sounds as well or is this feature not intended?
and 7smile7 is correct in what hypixel does, as well as they have their own fork for servers
Only if you load a ton of worlds when the server starts. Loading and enabling worlds on runtime
lags out a Spigot server because all of this is done on the main thread.
I wonder how that instanced dungeon plugin handles it
the main problem with having multiple worlds for games, is the fact you can't fully unload them without modifying the server code to cleanly do it
This is my assumption of how Hypixel bedwars work. So each server runs multiple worlds which are exact duplicates of a file and then splits players between worlds. So each arena has a world dedicated to it. Whenever the arena is done, I think it marks the world as dirty (which means that changes have been made, like it's no longer clean). At some point, it will no longer be viable so it marks the server instance to removal and will no longer accept new players for arenas and will just request a new server instance to the cloud provider.
It's simple even when it doesn't. So Hypixel still makes use of multiple worlds per server. This has been demonstrated in their Skyblock gamemode. Don't lie yourself!
hello.
how do i make an async function sleep?
um
on async you can just call sleep
is it just Thread.sleep();?
no
schedule a task in a task
what?
doesn't mean it gets its very own thread
It uses a thread pool
there could be other tasks on the same thread
ye that works
players might be able to break stuff while stuff gets processed (there is disk io going on) if they spam stuff, so i need to put the thread to sleep until stuff gets processed.
if you say it works, does sleep just suspend the thread from the pool for that long?
while (true) Thread.yield() :)
cant you use a lock then?
it just sleeps the thread lol
Why do you want to do that?
was mojang smoking some kind of crack when they came up with the way these display entities rotate?
if the thread is in a pool too bad
private HashSet<Player> playersBeingProcessed = new HashSet<Player>();
while (playersBeingProcessed.contains(player)) {
Thread.sleep(50);
}```
I mean it would only be a problem if you sleep every thread in the pool, no?
this is how i am trying to do it.
Dont do that
I think it's just JOML
why not?
that's ehm not a good design
its a problem if you have other tasks that are part of that thread
smile tell em
i need to stop the player from spamming stuff.
Do tasks get assigned to a thread for their entire lifetime
So check it when they try to spam
maybe use a cyclicbarrier or semaphore
a what?
You are burning valuable processing power. This is just a glorified room heater in code form.
Use a CountdownLatch or Mutex to notify when the processing is done.
Or does a thread just get picked from the pool whenever a tasks executed
a worker thread can process multiple tasks
its async?
why require the initial rotation at all? Why do we have to calculate it ourselves?
why does it matter? stuff just runs asynchronously, right?
when the thread sleeps, the cpu processes other stuff though, right?
oh is it because it doesn't strictly have to be its actual starting point? I think I see what's going on
ok
why?
does not that mean it is blocking or something like that?
what do you mean why?
nvm.
alright now I get why this is like this
Are you writing a wrapper for it?
not sure if I will use it at all, I was going to just implement my own thing
threads are not created for every task that gets scheduled this isn't feasible. Hence there being a thread pool
smooth animation is cool but I don't know what will happen when things start getting desynced
If someone's doing a wrapper for doing easy transformation and such without needing to do complex math ops I will star their project 🦾
private HashSet<Player> playersBeingProcessed = new HashSet<Player>();
if (playersBeingProcessed.contains(player)) {
return;
}```
is this okay?
what are you even doing
the only wrapper you need is for the singular value decomposition
Bukkit.getScheduler().runTaskAsynchronously(ChunkClaimsPlugin.getThisPlugin(), () -> {
Player player = (Player) event.getWhoClicked();
if (playersBeingProcessed.contains(player)) {
return;
}
playersBeingProcessed.add(player);
// some code runs here probably.
playersBeingProcessed.remove(player);
});```
is that okay?
What would be better to do, would simply make your code just exit the code block if a condition hasn't been met for it to run
public class AsyncPlayerProcessor {
public AsyncPlayerProcessor() {
playerQueue = new ArrayDeque<>();
notification = new CompletableFuture<>();
}
private Queue<Player> playerQueue = new ArrayDeque<>();
private final CompletableFuture<Void> notification;
// Is called from one thread
public void processNext() {
Player nextPlayer = playerQueue.poll();
if(nextPlayer == null) {
notification.complete(null);
}
}
// Anyone can get this and wait for the process to finish
public CompletableFuture<Void> getNotification() {
return notification;
}
}
Example one
i am implementing a spam protection.
while stuff gets processed.
spamming the command might break stuff.
you could just implement a command delay based off how long ago they used it
is this not just that?
public class AsyncPlayerProcessor {
public AsyncPlayerProcessor(Collection<Player> players) {
playerQueue = new ArrayDeque<>(players);
notification = new CountDownLatch(players.size());
}
private final Queue<Player> playerQueue;
private final CountDownLatch notification;
// Is called from one thread
public void processNext() {
Player nextPlayer = playerQueue.poll();
if(nextPlayer != null) {
notification.countDown();
}
}
// Anyone can get this and wait for the process to finish
public CountDownLatch getNotification() {
return notification;
}
}
With this you even have a counter on how many players are left for processing
mapping timestamps :o
plus, i cant just have an arbitrary delay, i need the task to finish first.
you don't need to iterate anything if you are only dealing with timestamps
what task might that be?
there is disk io going on, i am fetching stuff from a database and it takes a while and between delays, if the thing is triggered again, it seems to be causing issues.
fyi I just checked and apache commons 3 does that for you
your DB is consuming disk IO? o.O
Then use a CompletableFuture. Its the easiest way to wait for one task to finish and work with the result
what are you doing using sqlite?
yep, sqlite.
Every DB uses Disk IO...
oh yeah, right, most dbs use network io, if they are not on the same machine probably.
use mysql or mariadb if you are having this much of an issue with IO
sqlite is not scalable
cool kids put their db on ram
nor was it meant to be
sqlite for me is just a fallback DB for when someone doesnt have a proper DB installed
this is true, but I am fairly certain mysql uses less then sqlite does
yep, those can also be probably, probably can just use the same sqlite code for mysql/mariadb.
how do I give a player a permission?
just have to change the jdbc url to do that perhaps?
most of the sql stuff is the same with only some minor differences for a few things
problem for later probably.
jdbc url would indeed need to be changed
I believe there are DBs (such as hazelcast) that are meant to minimise the impact of Disk I/O to be a non-issue
but sqlite is not designed to be used on a large scale or storing massive amounts of information
i would probably just have compatibility for sqlite and mysql, that is probably it.
somebody told me sqlite can handle like 2 million transactions or something.
Hazelcast is just memory clustering really... Wouldnt even call it a DB
its probably not meant for multiple connections.
But yeah there are in memory DBs
Wasn't too aware of what it is
its not possible to have multiple connections for sqlite
since you may not be able to use more than one application to access the file.
I just know that maven can use it for file locking for whatever reason
yep.
the reason its not possible is because sqlite requires a file handle
🤨 I didnt
how large is your sqlite DB?
so i just queue players to be processed, but how do i check if the player triggers the event again, they are being processed currently or not?
size on disk that is
probably a few thousand records in some tables, idk.
no I mean actual file size
probably not that bad.
its not deployed yet.
i mean it might have a few thousand rows.
if you want to make IO on disk a non-issue mount the file into a ramdisk
same the ramdisk periodically to hard disk every so often
i feel like this xy problem.
disk io is not my problem.
i need to prevent players from spamming sutff, which seems to be no longer a problem nvm.
you are the one using a system not designed to be scaled in this way, all I am doing is providing you a bandaide solution that will work for the time being
uh...?????
ramdisk is in memory only, and having the file in memory at all times means fast access and virtually no IO on the hard drive except every so often to save it back to hard drive
since your sqlite file is most likely going to be small, odds are you only need at most like 100-200mb ramdisk
i am probably going to providing mysql compatibility.
Add a PermissionAttachment
Or hook the vault api
but i still dont have disk io problems, at least none i have discerned yet.
How that?
But that‘d require vault :p
When using a latch: Check if the latch is at 0
When using a CF: Check if the CF is done
you are the one that said you needed to pause stuff because of IO
so...now IO is not an issue?
if IO is not an issue, I don't see a reason to pause stuff since that was the premise of the whole problem
Yeah sure, i thought they wanted to do a permissions plugin or sth
ok it seems to be working fine now for the most part.
java should probably consider some functional programming like some of the web development libraries like react.

java has done it significantly lol
CF, Stream, Optional, lambda
^
And if you like react that much then go and get Reactor.
Create your Monos and Fluxs
Java created Java
lies and deception
like sure java os oop at core but it has functional aspects
Very descriptive jdocs. Amirite?
How can i open guis like loom and stuff usually available in paper?
Btw, nice performance guide
I found it pretty helpful
javadocs for people who completed and remember their math classes in uni
lol
i sometimes i wonder why some of you seem so knowledgeable despite only really being in a discord server for minecraft coding.
I am almost done and i have never heard half of those words in my life.
half? Look at mr fancypants over here
how's your college debt doing
What a burn
it would be a sick burn if I didn't also live in such a country
where?
does the country have a name?
What have you tried so far?
Germany
OH.
I'm not in the latest version
What version are you on?
inb4 a version that doesn't have looms
do you even pay for college in germany? is it free like healthcare despite being so much better than america perhaps?
Yes but I might switch to 1.16.5 or smt
Well step one would be to update. Not many people remember how to do stuff for legacy versions.
I might update to 1.16.5
Tbf I will
How do I open looms and stuff in 1.16.5?
that sounds like quitter talk
fr
its seems like you haven't tried anything yet so I would recommend you start with step 0 by trying to visualize the loom for the next 10 hours with your eyes closed and away from discord
I am very tempted to go try out this whole visual entity thing right now
which is unfortunate because I really have some other stuff to finish first
lmao
iirc if you create an inventory you can say of what but i dont recall if workstations are inventories
will this do the job?
Yes this will create a combat system with adapted cooldowns
This segment does nothing. We have no idea what you are doing.
turning long into timestamp
Yes, looks ok. But make SimpleDateFormat a field
Wait does DateFormat also format time?
¯_(ツ)_/¯
You might need a DataTimeFormatter
String timeColonPattern = "HH:mm:ss";
DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern);
so if u store info in a player entity PDC and the player leaves the server afterwards and rejoins, does the data get wiped or does it stay?
Wouldnt be a very persistent PersistentDataContainer if it would just vanish, would it
how do i delete a world?
since world.getWorldFolder().delete() just gives me an error
Sarcasm?
yea
Ok
- First unload the world
- What error
Just saying, your performance guide is nice
thats a very good question what error it is
thanks
Just because we are here in this discord doesn't mean we don't have jobs and other things
some are going to school in regards to programming as well
also
not everyone is young either lol
ok so no error it just doesnt delete the folder, it does unload it but no delete

I do wonder if ultimately it is feasible to use the new transformations to interpolate points
Who you talking abouit
I'm a spry young lad so certainly not me
Same
MagmaGuy for instance
true dat
get away from me grandpa
lol
dab
How can i replace something in a string in a string builder?
by using replace
You need to wait for some time after unloading. Spigot doesnt notify when world unloading is done.
Frostalf is the old one
int start, int end, string?
i can't understand
aight tysm
do i just wait like 100 ticks
Yeah should be fine
the main issue I see with the client-side interpolation is that I have no clue of how I'm going to reconcile it with what is at its basis a moving entity
Im trying making a gui with an Open and Close system, for updating the gui when someone runs the command and update it for everyone in the server, but only the people who have open it how can i do that?
Bukkit.unloadWorld(world, true);
Bukkit.getScheduler().runTaskLater(plugin, () -> {
world.getWorldFolder().delete();
}, 100);
is this the correct way to delete a world?
inventory.getViewers?
cus i couldnt find anything else on it
and loop them and reopen the inventory
Your gui system should have a Map<Inventory, InventoryHandler> or something similar for your GUIs.
So iterate over all players, get their open inventory, check if its your GUI through the map and update it.
There is sadly no callback for when a world successfully unloads
Does everyone have the same Inventory instance open?
Well... then just change the content of the inventory.
this implies that there can be an unsuccessful unload
Probably
for (HumanEntity entity : inventory.getViewers) {
}
Hm? A Future<Void> would be enough
No need to reopen anything imo
Just edit the Inventory
^
they were saying there is no callback for a successful unload, was just stating that would mean there is a such thing as an unsuccessful unload as something being normal
I mean the current method returns a boolean already
why the heck is this not enabled by default ><
makes it easier to do some action after it unloads
How does the current method even return a boolean instantly
If unloading isn't instant
doesnt seem to work
StringBuilders aren't really meant to replace things. If you really absolutely need to do it, you can call indexOf("the string you want to replace"), then replace(index, sizeOfString, "the thing you want to replace with")
because it will unload, we don't need to wait till it is done doing that to return the boolean. As I said what you are implying is that it would be normal to have an unsuccessful unload lol
i was doing that wrongly, i was replacing the builder not the String inside it
StringBuilder builder = new StringBuilder("foo bar baz");
int index = builder.indexOf("bar");
builder.replace(index, index + 3, "blah");```
You'd get a builder that contains "foo blah baz"
gotcha
thanks for help
public boolean unloadWorld(World world, boolean save) {
if (world == null) {
return false;
}
WorldServer handle = ((CraftWorld) world).getHandle();
if (console.getLevel(handle.dimension()) == null) {
return false;
}
if (handle.dimension() == net.minecraft.world.level.World.OVERWORLD) {
return false;
}
if (handle.players().size() > 0) {
return false;
}
WorldUnloadEvent e = new WorldUnloadEvent(handle.getWorld());
pluginManager.callEvent(e);
if (e.isCancelled()) {
return false;
}
try {
if (save) {
handle.save(null, true, true);
}
handle.getChunkSource().close(save);
handle.entityManager.close(save); // SPIGOT-6722: close entityManager
handle.convertable.close();
} catch (Exception ex) {
getLogger().log(Level.SEVERE, null, ex);
}
worlds.remove(world.getName().toLowerCase(java.util.Locale.ENGLISH));
console.removeLevel(handle);
return true;
}
I see
did mojang mess with ServerGamePacketListenerImpl?
Arrays.asList("hello", "world")
If you want to keep the current stuff you need to get it and then append
List<String> current = config.getStringList(key)
current.add("poop")
config.set(key, current)
List<String> message = getConfig().getStringList("message");
message.add("test");
getConfig().set("message", message);
Coming back to this...
Thats a list of lists
Coderino pls
Arrays.asList now creates a List<List<String>>
just pass nicknames
nicknames is already an array
List<String> nicknames = configuration.getStringList("message.nicknames");
nicknames.add(player);
configuration.set("message.nicknames", nicknames);
since you obtained it as a stringlist
can someone help me
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/NoGoalSpecifiedException
i've been trying since yesterday
Show your lifecycles
huh?
intellij run button
First press clean and then package
where do I find this
private static final FieldAccess NF_PLAYER_NETWORK_MANAGER_FIELD;
private static final List<RawPacketListener> packetListeners = new ArrayList<>();
static {
Field playerNetworkManagerField;
try {
playerNetworkManagerField = PlayerConnection.class.getDeclaredField("h");
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
playerNetworkManagerField.setAccessible(true);
NF_PLAYER_NETWORK_MANAGER_FIELD = NoReflection.shared().get(playerNetworkManagerField);
}
Any ideas why this error occurs?
This code does not relate to your error.
Also: What are you doing? What are you tinkering with the PlayerConnection?
you need to recursively loop over the file structure and delete files first, then folders from the bottom up
ahh okay
PlayerConnection#NetworkManager is private in 1.19.4, and there is no getter for it
public void deleteFolder(File folder) {
for(File file : folder.listFiles()) {
if(file.isDirectory()) {
deleteFolder(file);
return;
}
file.delete();
}
}
``` @quaint mantle Something like this (really simple code, you should do error checking, and safety checks if the files are null)
No idea what those classes are supposed to be. Are you using Spigot mappings?
no
Show your project setup
u mean the project structure?
I just wanted to see if you have a pom and where its located
i do have a pom
Just realised. If you click on package then your error cant be the same.
Show your new error pls.
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/NoGoalSpecifiedException
Process finished with exit code 1```
i mean it throws the same error after i press run again
You have done something to massively break something
i've done nothing
Well never press run again
I don't think he's actually using the maven panel.
huh?
Your run configuration is botched
ok thx
To fix your "run" button your would need to edit this:
yea nvm i'll just use package
Why not just set a default goal in your pom and use the maven run button?
I have problem with spigot can someone help me
?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. Make sure you use the right channel regarding the topic of your question. Create a thread in case the channel is already in use!
I need to send photo to explain my problem better
You'll need to verify yourself before you can send images. Otherwise you'll have to use imgur, liteshot, or some other image sharing site.
?image
Not verified? Upload screenshots here: https://prnt.sc/
Polygon regions. Take that, WorldGuard.
great good god what have i done
Ayo that's actually kinda sick.
@kind hatch come prv
Tf is prv?
dm probably
@kind hatch dm
can you stop calling everyone into dm and just post your issue ?
@hazy parrot I can't send photo
?img
Not verified? Upload screenshots here: https://prnt.sc/
if you cant use that use imgur or smth
Alternatively, !verify yourself.
update protocol lib and or via version
old spigot web?
Idk about you, but this sure doesn't look old to me.
^^
so is it possible in theory for fireworks to get stuck inside of blocks?
it seems like someone reported to me that they have over 1k lingering fireworks
see that's what I thought
it's like I'm spawning them in unloaded chunks or something but that doesn't make any sense
oh
do you spawn them with a velocity?
are they getting shot into unloaded chunks maybe?
that could do it
yeah some of these are angled
that could do it
so fun question
if I set it to not be persistent, will it be smart enough to remove itself if it goes into an unloaded chunk?
I've been up for way too long, that's good enough for me
@remote swallow @kind hatch I get the same problem
WorldGuard does polygon regions though, doesn't it?
It doesn't look nearly as cool but I'm fairly certain it's capable of them
Since when
At least 1.12, but I don't think it was capable of triangle regions.
Not sure if it is even now
Maybe not, but if you make a polygon selection with WorldEdit and just define a region with that, it works (iirc anyways)
They are a pain in the ass to setup though.
They absolutely are yes
Oh yeah you can do elipsoids etc. But can you define N points and an arbitrary polygon within that?
Yes
There was some command that you could bind to the selection tool that would set the points.
Eh mine is still cooler 🤷
Solve my problem What is the use of you if you can not solve a simple problem like this problem
AAAHAHAHA XD
Yeah I don't remember the command but you definitely can do it. It takes forever though and afaik there's no way to have a visual aspect to it.
Damn, he's coming on to me.
So... still really epic looks cool af👍
Update your server and plugin versions and then come back if it still doesnt work.
I've already done everything but it keeps giving me the same problem
What server version?
Have you tried a different client?
@lost matrix
1.19.4 spigot
Yes
Keep in mind that 1.19.4 only came out like 2 days ago. It'll take time for plugins to update. ProtocolLib might still be usable up to 1.19.3
good thank you
Then go to ProtocolLib and ViaVersion and look at the supported versions.
1.19.4 is not production ready and should only be used for test versions.
Many plugins dont have updated their code for that version.
A bit clownish calling us useless when he simply refuses to read plugin descriptions
how i can calculate this (i know i described badly)
50 / 10 = 5
51 / 10 = 6
59 / 10 = 6
60 / 10 = 6
61 / 10 = 7
flooring the number
Modulus?
what is that
I need a solution to the problem. I have a Minecraft server, and now it does not work, and it must be on the latest version, because the members of the Minecraft server have a new version.
So 5.1 - 5.4 would floor to 5
but my numbers are Integer
Math.ceil(number / 10.0D)
thanks
Make sure to have either double or float division
That being said beware of floating point shenanigans
public static void main(String[] args) {
for(int i = 0; i < 50; i++) {
int floored = (int) Math.ceil(i / 10.0);
System.out.println("Number: " + i + " Floored / 10: " + floored);
}
}
Number: 26 Floored / 10: 3
Number: 27 Floored / 10: 3
Number: 28 Floored / 10: 3
Number: 29 Floored / 10: 3
Number: 30 Floored / 10: 3
Number: 31 Floored / 10: 4
Number: 32 Floored / 10: 4
Number: 33 Floored / 10: 4
Number: 34 Floored / 10: 4
Number: 35 Floored / 10: 4
Number: 36 Floored / 10: 4
Number: 37 Floored / 10: 4
Number: 38 Floored / 10: 4
Number: 39 Floored / 10: 4
Why must it be on the latest version? Again, it only came out 2 days ago, so updating immediately is kinda foolish since not everything has updated.
If you want a solution, just use ViaVersion on 1.19.3 so 1.19.4 clients can connect.
one can't really call that flooring if you are ceiling
Well thats not floored its ceiled...
Yeah language barrier kicks in
ceiling is up, floor is down ^^
Shoutout to worldguard for having a nice easy API for what I need
What's the process for setting the points? Curious to see if it's similar to how worldedit handles it or if it's simpler.
Most protection plugins don't let you query an entire area easily :c
One moment
For me its just
public AbstractRegion getRegionWithHighestPriorityAt(Location location) { ... }
Nah I want to query a cube
Without iterating every single location ideally
Worldguard lets me do
public boolean canBuild(Player player, BoundingBox bounds) {
LocalPlayer localPlayer = worldguard.wrapPlayer(player);
if (WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, localPlayer.getWorld())) {
return true;
}
RegionManager regions = CONTAINER.get(BukkitAdapter.adapt(player.getWorld()));
BlockVector3 min = BlockVector3.at(bounds.getMinX(), bounds.getMinY(), bounds.getMinZ());
BlockVector3 max = BlockVector3.at(bounds.getMaxX(), bounds.getMaxY(), bounds.getMaxZ());
ProtectedRegion dummy = new ProtectedCuboidRegion("dummy", min, max);
ApplicableRegionSet set = regions.getApplicableRegions(dummy);
return set.testState(localPlayer, Flags.BUILD);
}
Is there a way to disable this warning (in the serverlog)?
Loaded class <classpath> from <Plugin> v1.0.0 which is not a depend or softdepend of this plugin.
I'm trying to dynamically (based on a config) load classes from other plugins so I can not depend or softdepend on those plugins.
public Set<AbstractRegion> getIntersectingRegions(AbstractShape shape) {}
😄
I approve
Why cant you softdepend on them then?
Because I will not know all of the plugins.
Basically I want to enable other developers to create plugins based on an interface that my plugin can use
RegisteredServiceProvider
Wait...
Why do you need to load their classes then?
Its their responsibility to add your plugin to their dependencies in this case.
Ok lets take a step back. To understand this correctly:
- You are defining an Interface
- Another plugin can implement this Interface
- You will use their implementation
I'm working on a Plugin to configure and run "Events" (basically just code) at certain times, in certain areas etc.
So basically any developer will be able to create an own event while depending on my plugin. But my plugin will have to instatiate those events with the right values (from it's configuration)
Therefore I need the classes of the other plugin. And I might need to have multiple instances of a class so handing me one instance would not be enough (unless I keep deepcopying it)
Oh, I think you have the same issue that PlaceholderAPI had.
Sounds about right that they would run into that aswell
This is commonly solved by using Factory classes.
And you need a system for others to register their factories.
This means you should not load anything from their plugin
but rather provide an API for registering their Factories.
They need to depend on your plugin.
So your plugin loads first.
Then their plugins load and register their factories.
Yeah that sounds possible. Might be able to create those Factories via Reflection aswell in order to keep the API as simple as possible.
Thanks, I'll figure something out based on the factory pattern
you wouldnt need reflection though
No reflections. You just let them create one instance of those Factories
But they'd have to implement an extra factory for each event (sure it wouldn't be much code) but the fields to configure in each event are already filled using annotations. So might aswell use those annotations for an automatically created factory
Sounds dirty and slow
Well that's what a lot of frameworks are based on. Spring Framework also adds Beans to classes via annotations
Therefore the implementation of an event is extremely simple
Spring... hehe
You cant compare that because of multiple reasons.
First of all Spring is used in web environments where a few millis more or less dont matter.
In Spigot it does matter a lot. 10 Events á 2ms and you got almost 50% of your ticks time wasted with reflections.
Also Spring is a contained Framework. You have no idea what they do during compile time.
I hope you at least use a CDI framework like guice then
Well I can collect all the annotated variables during startup time and then I just set the values via reflection and don't have to fetch them each time.
I might think about skipping on reflection but the Factory-Method implementation increases the complexity for other devs
I'm not injecting depencies as in complex objects. I only inject simple values like Strings, ints that are read from a config
Meta programming via annotations is much more complicated and implicit than actually implementing a simple class
and calling registry.register(new CoolFactory())
But ok. You will find your way
Is that more complicated than creating a Factory for those 3 values?
I mean sure you have to know what an annotation is but besides that?
i would rather just implement an interface because its clear in what it does
but this seems just as good though
You would not create factories for those. This looks nothing like what you described...
Ok lets deep dive a bit then
And also: What if someone just wants to have other objects in there?
Do you have a dedicated Codec where they can register context resolvers?
They will get complex objects as configurationSections
Or MemorySection to be exact
Isn't it the same? Either I do the conversion by calling a context resolver or they do it themselves
But yeah to keep the "Eventpack" Plugins cleaner I might add that in aswell. Good point
If you are working with ConfigurationSections then you can just utilize
ConfigurationSerializable from Spigot
?paste those please
So to kinda explain what I want to achieve:
We have this abstract class
https://paste.md-5.net/revacimisa.java
And for a command Block event I'd plan to implement it like this:
https://paste.md-5.net/peyeyagosa.java
The config would look kinda like this:
Events:
commandblocker:
engine_classpath: me.fabsi23.basicEventPack.events.restricting.BlockCommand
engine_name: '&bCommand blocker'
engine_description: 'Blocks commands'
commandBlockedMessage: 'Command not allowed in this region'
blockedCommands:
- /tp
👀
That's the reason someone was added to the event, not a placeholder name
exposing players hehe
Because of the public getter or because Player objects can change?
Public getter
Also why are those abstract? Arent they supposed to mutate the participatingPlayers?
Also player objects can change
No those are called and based on the return value it either adds the player to the event or does not
If the player relogs
Players are removed from all events on logout
weak hashset kek
💪
Is there a StrongHashSet or maybe an AlphaHashSet
SigmaHashSet
im more of an OmegaSet user myself
This is incredibly fragile design
So basically the event can decide whether a player can be added by entering a region while event is running.
The engine would try to add him but if the event says no it won't.
This is especially useful if you have to meet a goal before a timed event ends and the timer is about to run out
I can assure you that other devs will introduce massive problems here
I'm open for feedback since this is supposed to end up as an open api.
- I love to learn
And yes I will document all those methods and write guides obviously. It's just not done yet
Ok so step one would be: Rename your enums
Alright what names would recommend?
yes
AddReason RemoveReason etc
what
Next up: Find a way to strongly encapsulate your participatingPlayers.
No getter no setter
Wish it was kotlin and I could use internal lol
i saw students in my class not using access modifiers for collections at all 🥵
To be honest. I dont think this collection should be inside your event
Or at least not together with your abstract methods
Wdym? If you want to access a variable in another class, make a getter method. Doesn't matter if it's primitive or a "normal" object.
hi
Well I want it to be accessible inside the event. I might add it to the EventController where it's still accessible from inside the event
In what context do you use "Event" here?
why cant i check this? it worked on another project on a dif java version. this one is java 8
?nohello
What do you mean?
It's basically all kinds of things.
Can be "spawn mobs" "tp player" "block command", "kick player" - any code, really
Wasn't sure what fits better/is more generic than "event"
show the declaration
i know why nvm
And why does every event have participants?
Because it is regionbased. Not in the region = not participating.
Regions can be worlds, cuboids or spheres
How can I make my while statement loop every 4 ticks until the statement inside is true? ```public class DialogueCommand implements CommandExecutor{
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String [] args) {
if (args.length == 0 || args[0].length() > 0 && args[1].length() == 0) {
sender.sendMessage(ChatColor.RED.toString() + "You need to provide both a selector and text.");
return false;
} else {
Player player = Bukkit.getPlayerExact(args[0]);
int idx = 1;
String word = "";
int counter = 0;
while (counter < args[1].length()) {
word = word + args[1].charAt(idx);
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(word));
idx = idx + 1;
counter = counter + 1;
}
}
return true;
}
}```
Use the bukkit scheduler.
?scheduling
Ok but then those players should be inside the regions and not inside the events.
Or can one event be present in multiple regions?
This honestly looks like an implementation detail which should not be in the abstract class.
A region can have multiple events running but one event (instance) can only be in one region
But by being in the region you aren't forced to be in every event in that region
Could be that you reached the goal (e.g. find a certain block) and therefore you are removed from one event but are still in another (e.g. one that gives you a slowness effect or whatever)
It has 4 methods lol
everything else is up to the actual implementation of that class
i lied, 1s
It tracks its participants, it listens to bukkit events, it provides registrations for itself
it contains all mutators and accessors.
This is an uber class
the currentStats thing is:
public HashMap<StatType, Double> currentStats = new HashMap<>();
thats it
but for some reason i cant check .containsKey since it wants an object and not StatType
Hmm. I can move the participants to the controller but I feel like the Listeners should be registered inside the event that is consuming them, no?
?paste
The reason I put the players in there is that nothing would break if someone (for whatever reason) called removePlayer themselfes/actually removed a player. And to have one abstract "Api-Class". Basically to keep it as simple and quick to implement as possible.
to clarify:
Here im checking some stuff etc.
for (ItemStack itemStack : stacksToCheck) {
ItemBase.getStatsOfStack(itemStack).forEach((statType, aDouble) -> {
if(currentStats.containsKey(statType)) {
currentStats.merge(statType, aDouble, Double::sum);
} else {
currentStats.put(statType, baseStats.get(statType) + aDouble);
}
});
}
but it gives me this error
I can see where you are going with this. As in reusable configurations for multiple events
the currentStats map is this
public HashMap<StatType, Double> currentStats = new HashMap<>();
If you are trying to simplify the API usage then you can not use those classes within your internals.
You might need to generate or create new Objects which can handle those simple implementations
in a more general and robust way.
Something like a "RunningEvent"-Class that holds an instance of "Event" and keeps the players within?
This would be something i could get behind.
When an event starts then you create an ActiveEvent which holds your general description of the Event functionality
and the participants.
I could delegate all calls from RunningEvent to the internal event.
Just like I did for the CompositeEvent.
https://paste.md-5.net/sududowawo.java
The only problem would be delegating or exposing participants to your Event implementations
Dont tell me EventController is a Singleton you use to manage your Events
I could create a copy of the list each time they query them. Or I just copy it once and if they mess with it in the wrong way it's their fault 😅
It's not a singleton but there is only one instance
Actually wait a sec let me push the whole project to a git repo. But it's not done yet so there's some things I still have to clean up
Im hungry and this system looks like it is written to mock SOLID in every way possible.
Well each region does have it's own Handler
But the EventController creates the regions and handlers (on startup) and keeps track of them (cleanup on shutdown etc)
Give the S and D a good look
I always forget what solid is I just kinda code lmao
I'll do that and rethink the current structure I guess
Its a cool idea with the annotations and all but this will wreak havoc on devs and servers
Also make sure you stick with naming conventions too this may have already been said thougj
Ok so this is my code: ```public class DialogueCommand implements CommandExecutor{
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String [] args) {
if (args.length == 0 || args[0].length() > 0 && args[1].length() == 0) {
sender.sendMessage(ChatColor.RED.toString() + "You need to provide both a selector and text.");
return false;
} else {
Player player = Bukkit.getPlayerExact(args[0]);
final int[] idx = {1};
final String[] word = {""};
final int[] counter = {0};
BukkitScheduler scheduler = Bukkit.getScheduler();
scheduler.runTaskTimer(plugin, () -> {
while (counter[0] != args[1].length()) {
word[0] = word[0] + args[1].charAt(idx[0]);
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(word[0]));
idx[0] = idx[0] + 1;
counter[0]++;
}
}, 4l, 4L
}
return true;
}
}
class Other {
private final Dialogue plugin = Dialogue.getPlugin(Dialogue.class);
}```
And here are my errors:
Yeah I like the concept which is why I got behind this project.
I will definitly do some improvements before publishing it tho
u forgot a )
at the end of the run task tmer
Especially chunk based region activation (for now all regions are active at once).
But I'll start with improving what you already mentioned!
Thanks a lot ❤️
we cant really help you from just that
well does the variable get edited at some point? where do you use it?
Guys I'm at my wits end. What am I doing wrong ?
Are you trying to connect the torch to the block?
Yeah. First to place cobble and then the torch and connect it to previous block.
facingDirection?
Use a WALL_TORCH and set the orientation using the BlockState
Oh ! I'll play with that now ! Thank you for pointing me in the right direction ! 🙂
These are the problems again:
Yeah there is still an error
Here are some links to get you started on learning Java:
- https://www.codecademy.com/learn/learn-java
- https://www.sololearn.com/learning/1068
- https://www.learnjavaonline.org/
- https://programmingbydoing.com/
- https://docs.oracle.com/javase/tutorial/java/index.html
The last one is the only official one, however some of those concepts assume that you already know a bit about programming.
What about the red plugin word?
can anyone please help me with displaying hex colors in chat?
ChatColor#of()
§x§f§f§f§f§f§f for white
nope
Yes?
That maps it to the nearest chat color
well then fuck me
But the bungee one doesn't.
Nty
How does Gson#fromJson() inernally does to assign values to fields without having any empty constructor on the "type class"?
Reflection probably
Hmn, elaborate more please
Because so far im using, to get the packet id while being registered, but what if i dont to oblise you to have an empty constructor. Cuz right now, if none default empty constructor while throw an InstantiationException
int id = (int) packet.getDeclaredMethod("getUniqueId").invoke(packet.newInstance());
Why is the word plugin red in this line? scheduler.runTaskTimer(plugin, () -> {
?paste
I need full code to help
maybe the plugin var doesnt exists, so your IDE puts in red meaning smth its wrong
Hey, I want to create a plugin that can alternate how ores are spawning, does anyone have an idea how would I maybe extend the normal world generator and change it like that? Anything is appreciated
Unsafe
Gson can use unsafe to create an object from a class nullary constructor regardless if it exists or not
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
Could be something related to "Java instrospection" ?
oh ok
How can I do this? I read the article over and I can't really make sense of it
First if you want to learn how to code plugins, you should learn the lang where you coding
Not wondering to be rude ofc, just a recommendations of someone who have had bad experiences with it
Hi there are plenty of great youtube channels out there to help
https://www.youtube.com/watch?v=eJkwnS5ZkAI This guys entire channel
What can make Java so tough for beginners to learn? If you're a Java beginner, getting started with programming, these are a few things that can make Java hard to learn compared to other languages.
Complete Java course: https://codingwithjohn.thinkific.com/courses/java-for-beginners
That doesn't mean it's not TOTALLY worth it. Java is now my c...
Totally agree with you
Its just people that just want things easy, and they expecting to code a bigger plugins in weeks without even knowing the lang where they coding
shrugs
English please? I dont know those weird words, they never explain them to me
It’s english
Thats are slangs, thats not plain english for sure
Not at home to test the code so I just want to ask for later. Can you use a textured player head on the new block display and item displays?
yes
Hello
That skin 🥴🥴
Why is your head an old tv-screen
it's because I migrated to the US and now I only have NTSC resolution
He’s flirting with you Alex
i got a bf >.<
Alex when are you upgrading to this?
🤣🤣
Magic
It only has nbt to store states
my 16 inch laptop's screen's resolution is 44 times larger than the resolution of that pic lol
what's the res
I mean that was kinda the point
3456x2234
Ah okay
bet you paid like 5 grand for it
yeah but, 44 times is much more than I would have expected
Item display not block display
roughly 4k€ for the m2 max, yes
Is there a way to prevent a entity Villager from moving?
remove their AI goals
no, that's why we remove the goals 😛
Cheers
requires NMS though
setAi false
villagers are more complex than that
Well gravity is moving
I thought with moving, they meant the villager moving itself
declaration: package: org.bukkit.entity, interface: Mob
Sets whether this mob is aware of its surroundings. Unaware mobs will still move if pushed, attacked, etc. but will not move or perform any actions on their own. Unaware mobs may also have other unspecified behaviours disabled, such as drowning.
That will work thank you
ah nice, that looks useful
didnt know that existed
Yes
how
Don't send a block update.
Set the type
place without physics
public void fill() {
System.out.println("asd");
Block block = startBlock;
for (int y = 1; y < height - 1; y++) {
for (int x = 1; x < width - 1; x++) {
System.out.println(block.getX() + x + " " + block.getY() + y + " " + block.getZ());
block.getWorld().setType(block.getX() + x, block.getY() + y, block.getZ(), Material.NETHER_PORTAL);
}
}
}```
declaration: package: org.bukkit.block, interface: Block
mb guys
Alright idk how interpolation on these things works
The display entities?
Alright I got it
Does this require any special Mods the end player has to install? It looks like a new Subclass of entity called Mob
Gotcha thank you. Was trying to find examples of spawning it. Found it on YouTube.
Hey @young knoll, do you know if the text display entities still use the ARGB color space for the background color?
I already have this line in my onEnable() in Dialogue.jar. DialogueCommand.jar contains the files for the command: getCommand("dialogue").setExecutor(new DialogueCommand());
yes
,
put them in different files misread
Class X implements A, B
You can implement two interfaces, also there is TabExecutor which implements both
?
Oh it's Listener
only in case you have
I trough its CommandExecutor lol
extends JavaPlugin implements Listener, CommandExecutor {}
Forget about TabExecutor thingy then
JavaPlugin already implements CommandExecutor
It grow
Cute
The annoying part would be keeping track of them all, and ticking them
You could be jank about it and recreate vanilla ticking
that too
Pick 3 ranom blocks per loaded chunk every tick, and see if there is a itemdisplay with a certain tag on that block
Then grow it
I have already, these are just the parts I don't know.
its an entity? so grab all entities in the chunk on chunk load
Yeah
Yeah I did this and it didn't work. I don't know if you would like me to put it in the Dialogue.jar or the DialogueCommand.jar.
Grab them on load and load them into a map of some kind
entities will not be loaded when the chunk loads, so delay your search
Dialogue.jar: https://paste.md-5.net/obecefopuv.java
DialogueCommand.jar: https://paste.md-5.net/wafemutada.java
Is this the right way to spawn a mob?
try {
this.entity = this.location.getWorld().spawn(this.location, Mob.class);
} catch( IllegalArgumentException e ) {
LOG(LogType.Info, e.getMessage());
}
I keep getting
IllegalArgumentException: Cannot spawn an entity for org.bukkit.entity.Mob
This is almost similar to the spawnEntity command which worked for a regular villager.
Guys am I doing this directional wrong. Could you point me in the right direction please ?
You can't spawn a mob, you need to spawn a subclass of mob that actually represents a specific entity in-game
U can cast directly in the if statement
Gotcha thank you
Hmm no luck there
before state.update
haven't worked with the bukkit api in so long 
Like I got the torch rotation done through setRawData but thats deprecated and I wanted to work the proper way out 😄
It's directional for sure
Torch is always on the ground
Rotating one torch got me stuck for couple of hours lol 😄
Wall torch is the one that can be rotated
Did you get it?
Well nvm I'll just set the direction through setRawData.
plugin is still red, but now getCommand is
is this null check on inv good? if (e.getClickedInventory().getItem(21).equals(null) || e.getClickedInventory().getItem(23).equals(null)){
idk if its cool
bcause im getting error
at that line
== null
Using .equals for null doesn't make sense
If it's null, using .equals with throw a NPE
Otherwise it will always be false
Okay
Thanks
appreciate it
Is there a way to listen that player holds left mouse button?
?paste
this is my code for my InventoryClickListener https://paste.md-5.net/igegudociv.java
The problem is that i cant interact with my inventory even when i close the mainMenu or the next inventory, why?
For me it is okay
nvm
just found
i had a ; in my if statement
How can I make a sort of /execute as @p run my_plugin_command in a command block for one of my plugins command ?
Does execute not just work with plugin commands
It look like it don't :c
You mean to make the player execute a command?
like /menu lets say?
yes
declaration: package: org.bukkit.entity, interface: Player
I want it in a command block (and I am using 1.18.2, for this plugin)
Oh
I mean /execute should work
my command don't appear in the tab completer, and when I write it, it says wring argument
Why i cant interact with stuff in my inventory? https://paste.md-5.net/basozidohi.cs
Ah I’ve taken a look at jira
Commands registered through spigot are not available for /execute
But if you use a command framework that supports brigadier they would be
Find my way by making another command that executes a command for the player
e.setCancelled(true)
i have it in the second line
cancelling the inventory event outright prevents you from moving any items in the whole inventory
you need to only cancel it if the player tries to move items that shouldnt be able to be picked up
damn
but if (inventoryView.getTitle().equals("Main Menu"))
isnt preventing cancelling the normal inventory?
Hmm
you need to check the slot numbers
so can i change it so i can move in my inv but not in the artificial inv
Wdym
You can check if the clicked inventory equals the top inventory
Or the bottom inventory
How to?
if (e.getClickedInventory().equals(inventoryView.getTopInventory()))
okay
ill try
Thanks, it worked.
Is there any other type of passing enchants from a book to a item other than: ```java
ItemStack sword = e.getClickedInventory().getItem(21);
ItemStack book = e.getClickedInventory().getItem(23);
ItemMeta swordMeta = sword.getItemMeta();
ItemMeta bookMeta = book.getItemMeta();
Map< Enchantment, Integer> enchants = bookMeta.getEnchants();
for (Map.Entry<Enchantment, Integer> entry : enchants.entrySet()){
Enchantment enchantment = entry.getKey();
int level = entry.getValue();
swordMeta.addEnchant(enchantment, level, false);
}
sword.setItemMeta(swordMeta);```
epic
You have to check only for top inventory, because if you use getClickedInventory() will return the inventory you are clicking
Anyone knows how I could get the Virtual host a player connected through (Not in join event or whatever but in general)?
Player#getAddress() returns an inet socket address object
I think you can obtain the virtual host from it, but im not sure currently
Nope.
Already checked it
Unless the getAddress() provided there would be the host, but I doubt that.
Could anybody provide an example of how to set the transition of a block display so that the block is just rotated 45 degrees or standing on one corner? I've been goofing off with the numbers in the setTransformation method the entity goes somewhere in my world and I've tried teleporting to it but I don't see the entity. Heres the code I'm currently using.
public void omPlace(BlockPlaceEvent event) {
event.setCancelled(true);
BlockDisplay nameTag = (BlockDisplay) event.getPlayer().getWorld().spawnEntity(event.getBlock().getLocation(), EntityType.BLOCK_DISPLAY);
nameTag.setBlock(event.getBlock().getBlockData());
nameTag.setDisplayWidth(1);
nameTag.setDisplayHeight(1);
nameTag.setTransformation(new Transformation(new Vector3f(0, 2, 0), new AxisAngle4f(45, 0, 2, 0), new Vector3f(0, 1, 0), new AxisAngle4f(12, 9, 3, 4)));
nameTag.setInterpolationDelay(0);
}```
Idk what AxisAngle4f or Vector3f really is either so the numbers I'm using are just to fill the requirements
I figured I'd learn what they are once I filled them in and saw the effect but my effect is no entity display lmao
Yeah I noticed that
The other one is a quaternion
Its optionally AxisAngle4f I think
Thats why I have it
I can try Quaternion but idk what that is either
?jd
don't use titles
Then?
instances
okay
Use the inventory instance itself
Or the view from openInventory
Or if you must, inventory holder
hello i'm a little bit new to java and minecraft developement, but not to dev
i have 2 plugin
1 that is a lib, this plugin can speak to an Rest API
2 and the other that i want to be able to use the plugin 1
i know that its possible but idk how i'm using VScode
so there is a public class named api in my plugin 1
that i want to be able to use in my plugin 2 how can i do that ?
thanks you for helping !
ping me :)
ho btw i use maven
Publish it to your maven local with the maven publish plugin, then you can add it like any other dependency
?di
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
is ItemStack immutable?
No
hmmm
it's not immutable but you can't get a mutable copy of an item in an inventory
you make a copy of it, modify the copy, and set it back into the slot
Items in hand are mutable tho
