#help-development
1 messages ยท Page 2287 of 1
but things like chests still won't have, for instance, items in the block inventory
and containers also use NBT to lock
ohh nbt for tile entities
yeah sorry that's what I meant
thought you meant like stone
was like huh lmao
You should just be able to get the NBT block on generation no?
you can set NBT data through NMS or even worldedit's API but you're not supposed to directly set blocks through the world during generation
what I currently tried was telling a scheduler to set the block's NBT a tick later and it technically works but it haults the whole server until the chunk is generated
which is really bad
idea
keep a referance to those locations
generate al lour chunks, and when a player goes nearby you generate chest contents
this is how vanilla mc does it
Go in spectator, try and open a chest far away
"Loot not generated" will show up
well chests have loottables, they generated once you open them
but afaik the loot tables are also stored in NBT
thing is these chunks only really generated when the player is near
Indeed but as far as this goes there not a lot of ther ways to handle it
i guess I could wait till they're really near but I still feel like there'd be a way to slow down the server if you're using, say, an elytra and travelling really fast
Dont exactly see an issue doing it that way unless its hindering performance on your generate code
I mean i would assume vanilla mc applied the nbt loot tables on chest generate
Theres a command to give you a placeable dungeon chest, and i know you directly apply NB directly when giving that item
Wouldnt see why it would be different for chunk generation, set nbtdata on generate
lol tell me about it, I wasn't thinking, I forgot I could totatly use a runnable inside the interact of the item.
in fact i think a plugin i worked on in the past did it like this
one sec
lemme look
Yep it did that but its oooold code
back when the chunk populator method was populate()
but its still same principle, on generation of the block apply the data or fill container
issue is it does
every time a chunk generates where NBT needs to be set and I run the code to set it, the server stalls for a good 5-10 seconds
I think the reason is that when running it on the main thread, I have to get an instance of the chunk and that means it has to wait until the chunk generates since worldgen is on another thread
Hello, I have this code in a command: https://paste.gg/p/anonymous/f0f4320a9a884daba10b9309059faee1
Then I have this code as a fill: https://paste.gg/p/anonymous/37824ea968ec45698c93194b709d44bf
What should I do at line 37 to make it work?
I'm trying to make all the logs spawn at the same chance... this system previously used HashMap
A lot of stuff is probably wrong, so any guidance would help so, so much!
What event are you using by chance
I can't even manually set the block inventories either if I wanted to just handle containers
I'm not using an event, this is a chunkgenerator
in generateSurface()
meaning I have to set block types with the ChunkData object it gives me instead of directly going through the world
hmm
this should work in onEnabled right?
Player player = (Player) Bukkit.getOnlinePlayers();
new BukkitRunnable() {
@Override
public void run() {
Player.Spigot spigot = player.spigot();
spigot.sendMessage(ChatMessageType.ACTION_BAR,
new TextComponent("โค" + ChatColor.RED + "" + ChatColor.BOLD + Math.round(player.getHealth()) + " " +
ChatColor.AQUA + "\uD83E\uDDEA" + ChatColor.BOLD + Mana.getPlayerMana(player)));
}
}.runTaskTimer(Wired.getPlugin(), 0,5);
you may have better luck using the chunk populate event (Might not be called that)
Since those give you direct access to Block
What does it do at line 37?
sadly yes
oh wait thats a timer
nvm
yeah itll work
Well, using HashMap entrySet did this: https://fwoostyhub.com/๐ ๐๐ป๐
but now I'm just using a list so I'm dumbfounded
ores is a list?
you mean use a blockpopulator?
Yes, one of those events
It should be really lightweight all your doing is setting block data
oh you mean literally hook onto the event
yee
hmmm
it gives you direct access to block
This is the HashMap system which works fine: java int x1 = -114, y1 = 62, z1 = -55; Location loc1 = new Location(Bukkit.getWorld("world"), x1, y1, z1); int x2 = -102, y2 = 52, z2 = -67; Location loc2 = new Location(Bukkit.getWorld("world"), x2, y2, z2); Map<BlockData, Double> ores = new HashMap<>(); ores.put(Bukkit.createBlockData(Material.COAL_BLOCK), 0.15); // 15% ores.put(Bukkit.createBlockData(Material.IRON_ORE), 0.15); // 15% ores.put(Bukkit.createBlockData(Material.GOLD_ORE), 0.05); // 5% ores.put(Bukkit.createBlockData(Material.REDSTONE_ORE), 0.04); // 5% ores.put(Bukkit.createBlockData(Material.DIAMOND_ORE), 0.03); // 3% Cuboid.fillCuboid(loc1, loc2, Bukkit.createBlockData(Material.STONE), ores);
and your rly not making a world gen
that seems kinda gross but that may work
indeed it is slightly gross
I just need to make basically the same system to work with a normal list so they have all the same chance of spawning
But its fine since your only doing one thing
if you were generating blocks in that event like a mountain
then oof
yeah no I can just save in a list the blocks that need their NBT saved and handle it in the event later
so you basically are removing chances
that should theoretically work
Yes, exactly
I have really no clue what else to do and I've been guided on this journey :P
for (Something something : thatList) {
}
you can just set it in there directly
unless thats not exactly what your asking
i assume your just asking how to iterate through it
It may be, but by chance could you give me an example of how I would use it in my instance? I'm so lost with this :P
I mean its relatively simple
you change ores to a List of BlockData
From there you change your put(BlockData, float) method to add(Bukkit.createBlockData(. . .));
And then you iterate over it like so
for (BlockData blockData : ores) {
}
I currently have this with my fill: java if (woods != null && woods.size() > 0) { // picking random ore BlockData blockData = woods.get(random.nextInt(woods.size())); int i = 0; for (BlockData blockdata : woods) { if (random.nextDouble() <= entry.getValue()) { loc1.getWorld().getBlockAt(x, y, z).setBlockData(entry.getKey()); } // guess failed. Use base. else { loc1.getWorld().getBlockAt(x, y, z).setBlockData(base); } // break loop, we've done our work. break; } }
int x1 = -89, y1 = 62, z1 = -81;
Location loc1 = new Location(Bukkit.getWorld("world"), x1, y1, z1);
int x2 = -77, y2 = 52, z2 = -93;
Location loc2 = new Location(Bukkit.getWorld("world"), x2, y2, z2);
List<BlockData> woods = new ArrayList<>();
woods.add(Bukkit.createBlockData(Material.SPRUCE_LOG)); // 12.5%
woods.add(Bukkit.createBlockData(Material.BIRCH_LOG)); // 12.5%
woods.add(Bukkit.createBlockData(Material.JUNGLE_LOG)); // 12.5%
woods.add(Bukkit.createBlockData(Material.ACACIA_LOG)); // 12.5%
woods.add(Bukkit.createBlockData(Material.DARK_OAK_LOG)); // 12.5%
woods.add(Bukkit.createBlockData(Material.CRIMSON_STEM)); // 12.5%
woods.add(Bukkit.createBlockData(Material.WARPED_STEM)); // 12.5%
Cuboid.woodfill(loc1, loc2, Bukkit.createBlockData(Material.OAK_LOG), woods);``` and this in the command
Now, what would I do in these two lines? ๐
java if (random.nextDouble() <= entry.getValue()) { loc1.getWorld().getBlockAt(x, y, z).setBlockData(entry.getKey());
oooops
sec
for (int x = 0; x <= (ores.size() - 1); x++) {
ores.get(x);
}
you can use x as the iteration count/index getting for the List
all lists start at 0 (I assume you know that, and hence why you -1 from size())
if you dont you get a IOB error (indexoutofbounds)
I replace this from the previous for loop you gave?
yep!
also
make sure you do a isEmpty() check before-hand if the values ever bcome non-hardocded
not that it will rly matter but its decent to catch that
https://paste.gg/p/anonymous/5dcd8face1b640d3887a28387b2c55c9 I current have this, does it look kinda right?
Line 37 is what I changed
yes but your still using entry.getKey() which is prolly screaming red in your ide
How did you manage to write all this without knowing how to do this lmao
Heh, lots and lots of help n googling, so now I need to remove java if (random.nextDouble() <= woods.getValue()) { loc1.getWorld().getBlockAt(x, y, z).setBlockData(entry.getKey()); and throw ores.get(x); in the place?
yep just remove the if, keep the body of the if and replace with List#get
Also is there any reason for you using block data to set blocks?
I feel like Material may suit you better unless you do plan on setting block data later on, then disreguard that part
Nope, besides that's what I've used in the past :P
I'll try it on the server now! :D
How can I power a piston with code?
((Piston) block).setExtended(true);
no way its that easy
Ok
you're talking garbage
Check again
I have this now: https://paste.gg/p/anonymous/98ac9b03acc54b08a16b88da23c408e0 and it replaced the whole mine with Spruce :P
its not going to be any different?
.
yeah that doesnt work
How so
Did you set the new block data
He means did you update the state
not necesarily
I believe we have to incorporate BlockData blockData = woods.get(random.nextInt(woods.size())); somehow to get a random block.
final Piston piston = (Piston) block.getBlockData();
piston.setExtended(true);
block.setBlockData(piston);
//For piston
if (data instanceof org.bukkit.block.data.type.Piston piston) {
//extend piston
if (cachedData.cachedRedstoneActivity.get(block) > 0) {
piston.setExtended(true);
block.setBlockData(piston);
continue;
}
continue;
}```
yeah like that, your code you sent above didnt have it
that was an example showing setpowered doesnt exist
I dont think that will do anything
I dont think it would return a clone of getBlockData
he didnt say setPowered
setExtended
Piston inherits BlockData
Doesnt change anything
@shadow zinc try this https://hub.spigotmc.org/javadocs/spigot/org/bukkit/block/BlockState.html#update(boolean,boolean) after making it extended
declaration: package: org.bukkit.block, interface: BlockState
Wtf
tf
Shitty client
sure
Stupid fabric
unless your textures are corrupted
doesnt push the block
oh thats fabric?
thats not client right?
Try using the block state update for players in radius
shouldnt even have to
i didnt mean to say that
but maybe his client is doing some sort of optimization
idk why idid
i mean to say just block state in world lol
however
he may need to do that too
just for that client
nah I don't think it's the client
I'm pretty sure setExtended just sets an NBT value
that's my best guess
and that makes the block look proper when the block for the piston stem gets created
https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/block/data/type/Piston.html#setExtended(boolean)
declaration: package: org.bukkit.block.data.type, interface: Piston
Shit game
the actual logic for creating the extension block and moving it is not there
an API request could maybe be made but idk it just kinda is what it is
bruh am I going to have to remove the block and set it one forwards
speaking of NBT though I really wish there was an API in bukkit to set NBT
I would personally take a look at how minecraft does it
declaration: package: org.bukkit.block.data, interface: Powerable
there you go ๐
yeah that probably works
I get why there's not, making the API consistent and shit between versions
Might as well try it
but man things like this make Bukkit in general pain to use sometimes
https://www.spigotmc.org/threads/make-piston-move.417551/#post-3689731
If not then you need to do this
thats the most recent thread i can find
from 2020
so hopefully it still works
^^ keeping in mind though you don't have to suffer with obfuscated names anymore
as long as your using maven at least
so if you are using mojang mappings (which you really should be, they're great) it will not be called .a
spigot dont care for gradle users :((
no one has converted special source plugin from maven to gradle and it suuucks
cause me like gradle
everyones favourite error
java.lang.RuntimeException: java.lang.ClassCastException: class org.bukkit.craftbukkit.v1_19_R1.block.impl.CraftPiston cannot be cast to class org.bukkit.block.data.AnaloguePowerable (org.bukkit.craftbukkit.v1_19_R1.block.impl.CraftPiston and org.bukkit.block.data.AnaloguePowerable are in unnamed module of loader java.net.URLClassLoader @5c29bfd)
yeah anytime i wanna do mappings i typically convert my project back to maven lmao
@shadow zinc read article i sent
ik
fun too to see what the community guessed right with their mappings and what is completely different
like tile entities actually being called block entities by mojang is very jarring
but makes more sense of course
i dont get why mojang just doesnt publicize theyre API
are they scared cause its so shit?
wdym API
even tho I have read it
IE the API mojang themselves use to make the game
i doubt that
If you did you would of told us you tried NMS
oh yeah, I've tried NMS
I mean as far as I know there's no API, just the source code
which we basically have access to now except not really
Minecraft is probably the closest thing to actually being open source right now but not quite
we have names for everything, just not the actual original .java files
well they would basically have theyre source code as the API,
But instead they decide to obfuscate and make nms users cry
What exactly did you try for NMS?
thats gonna be your only option now i beileve
obfuscating in this case was really just not saving names of stuff when compiling
idk some weird article I found, problem is all of these things are for no remapped
so a or b meaning nothing to me
the logic is still all the same, we still have to decompile everything
well look at the args
those are update methods
it's just that now when we do decompile minecraft we can get the names of everything back
Yeah i dont get why they dont just make an API jar
that mirrors methods from the server jar
it would make alllll this server shit so much easier
and the mirror jar is just empty code methods
and set scope to provided
I mean mojang doesn't really have an API like bukkit, there's no reason to
they very frequently change the structure of lots of parts of Minecraft
This really means nothing to me, its outdated
which is a good thing, Minecraft has far exceeded its original planned scope and was designed by a swedish dude in his off time originally
I would assume they have a basic event system and NBT handler though
and those would likely not change very often
cause its like core minecraft for those
they have NBT handling shit in NMS
@shadow zinc
and they don't necessarily need an event system but they do have sorts of events systems in minecraft's code
the reason we don't use any of that shit though is because it's not meant to be used as an API as it's just the game's code
so they change stuff around often
i knowww but i hate building all the shit myself ๐ฆ
the point of Bukkit is to have one uniform API that wraps around minecraft and deals with what changes in the background without the developer having to know or really care
mojang could just like
write good code
so they dont need rewrites every week
:))
Sorry, I don't know what you are referring to
You need to get a NMS BlockPiston
and call its update methods
all I will say is I do not envy Mojang developing a voxel game in Java
Java would be my absolute last choice for something so memory intensive
it might be named differently than BlockPiston in remapped tho
of ffs why isnt it remapped
If handled right its fine
a b c die
sure but the core structure of java is lacking for memory intensive applications
its 10x harder to try and avoid mem leaks
like afaik you can't allocate complex structures to the stack... like what
if I'm wrong on that correct me but I could never fucking find out how
basically being able to put objects on the stack
why isn't it remapped?
C# has structs which are like objects but immutable
is this something I did?
and you can lay out a struct using other value types like primitives and other custom structs
Did you follow the remapping guide?
and they are automatically put on the stack instead of having to go on the heap and be managed and eventually garbage collected
yeah youll need maven for remapped
theres prolly a way in gradle
but im not that good
so basically what I'm getting is: you cannot directly create something on the stack, but the JVM will try to analyze how you create objects and put them on the stack if it's safe to do so
Yeah in a sense
I far prefer C#'s way of handling this still but that's at least better than not being able to put anything other than primitives on the stack at all
Yeah im sure long running things are added to the stack more than likely
like socket instances and theyre values likely get shoved to stack while short lived things like threads and what not run through heap
Just my best editmate tho
I just hate how much is delegated to be part of the magic internals of the JVM instead of up to the developer to control
especially since how the JVM behaves is not necessarily always guaranteed depending on what JVM you're using
Seems like the comunity has a few different answers for this ngl
i wonder if its possible to create your own JVM
sure it is
and make java stack based instead of heap based
prolly a lot of work
too much
ide rather write a mc server jar from scratch
probably a waste of time but sure you can, all the JVM does is interpret the byte code and tell the computer how to run it
yep, imma google that now i wonder if its been done
you wouldn't want to put everything on the stack though, there's a heap for a reason
but the stack should be delegated for smaller objects that aren't necessarily supposed to change
no need to create a thousand small objects a second that only get used immediately just for them to all clog the garbage collector
Hmm so make global scope finals, statics, and long running objects on the stack
im boutta make my own programming language
actually usually you want long running objects to go on the heap
the stack only has so much space
it's usually short lived stuff you want to go on the stack
so stack wouldnt work for large complex voxels then no?
cause typically those voxels could be long lived
eg loaded chunks
usually you put stuff on the stack while, say, doing a ton of calculations in a loop
if you're trying to store data in some sort of structure while iterating over every block in a chunk you don't need to make an object
that structure you put on the stack is automatically freed as soon as the current iteration ends
instead of having to go through the GC
ahh i see was just about to say doesnt the gc replicate that haha
TBF the GC has gotten rly good over the years
compared to when mc first came out
could also be useful when, say, sending information to the GPU in a certain way
yeah no modern java versions are much better at it
i actually dont think MC interacts with gpu much
well it does, minecraft just doesn't do many intensive graphical calculations
because it's a simple block game
it would still be stupid to render on the CPU
it's moreso that Minecraft just spends way more time per frame on actual calculation instead of graphical calculation
and thats a full fledged AAA 3d game
basically your cpu is doing more work comparatively to your GPU
multithreading when
: ' |
someone should shoot notch for not making the code async ngl
multithreading is used very frequently throughout Minecraft's code, I think vanilla even does world gen on another thread
but you can't make everything on another thread
yeah it does but theres still a bunch of stuff handled on main
IIRC entities and stuff is all on main
sounds like a fun time to deal with race conditions and making the code look horrible because you now have to synchronize every thread when passing data between threads
multithreading also has diminishing returns to a point, CPUs only have so many cores/threads
thread pools
been playing with that lately
rly fun
the issue is that when running something on another thread there is zero guarantee as to what the main thread is doing
so to exchange any sort of data you have to basically pause both threads at a point that is appropriate and exchange information like a hand shake
public static int playerBalance;
CompletableFuture.runAsync(() -> playerBalance++);
ez

now access that from two threads at once
redis could possible work maybe as a middle man
I don't even think it's necessarily guaranteed what actually happens when you just access an int that is being written to currently
TIL the search bar in the creative inventory in 1.8 only fits 15 chars, so i cant search for items such as "heavy_weighted_pressure_plate" :(
latest running thread typically sets the value
last*
in java you use an AtomicInt
in C# you use a lock
or C# may have types like the Atomic types, not sure
in java u have the oh so wonderful synchronized keyword
(i have never used that in my life)
i have
its pretty useful
Object#wait
and Object#notify make use of it
you can make makeshift callback functions with all those methods
useful for multithreading too but i stoped using it
too annoying
but basically synchronized (object) just locks the object to the main thread when calling and allows you to execute things on main inside the block
ah so synchronized is basically like the lock keyword in C#
and can be used pretty much exactly like it
yes
makes sense
Would be useful if you handle data management on main thread
I am a little more familiar with C#'s threading systems over java's as usually I don't have to do much fucky shit in minecraft plugins
i actually need to make a async storage access system and thats gonna suck ngl
for as different as Java and C# are, theyre basically the same language when it comes to writing code
yeah they're pretty similar
except ones PascalCase and ones camelCase
I am far far more familiar with the internal workings of C# over java though
as I have just made more projects with it
like audio shit pretty much guarantees you will be doing some threading
but audio programming is fun
usually need to thread audio in java too iirc
well yeah you need to thread audio in every language, you simply have to feed to much data to do audio along with everything else
audio is fucking crazy
like imagine if we had to generated 44.1 thousand frames a second for a game
obviously there is far more calculation to be done in a game but still
a small price to pay for high FPS gameplay
or like 1000hz
smh
imagine
useless as shit
now i gotta make a whole different workaround for my multithreaded for loop counters
Wait so could you use volatile to say save player data accross threads?
https://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html
Actually this seems more viable
Oh thats right i pinged you lmao
Ye
i think the guys gone now
but whats the name of the protocol thingy minecraft uses?
Like the actual data type transferred
i remember you telling me one time
TCP?
Not TCP, i was talking about how i handle my socket data in JSON, and you mentioned something else that MC uses
someone else was doing the same thing
anyone got an idea how to remap gradle
I mean they just write their data in raw bytes if thats what you mean
Been asking myself for a while
Isnt there a special name for it?
My recipe is being shown in the recipe book, But I cant actually craft the item, the result shows the correct as well as all of the items, what could be causing something like this? I get no errors either.
it just wont happen
Hmm no not really as far as I know
I mean you have their abstraction on top of netty
With a buncch of utility methods for encoding and decoding data types to raw bytes
I know paper has a remapper plugin
But thatโd add the paper api to your classpath
Which you might not want
why not?
Because paper isnt spigot
so?
read through all your messages of the past 3 days and couldnt find it weird
does it break anything?
also conclure i learned the hard ware not calling join() with runAsync + work stealing
Yes
If you use paper methods on a spigot server youll get errors
Idk if you meant this @noble lantern #help-development message
nah it was like one word
it was a rly weird word too
maybe someone else said it hmm
Uhmm
you could use spigot remapping website to display version specific method names for mojang
Theres a website that does it
How are you saving?
Baboonery
can I get the link to that?
ah sandals
Im gonna have a class on main thread that has just a basic data handler class with calls to MongoDB
As well as a hashmap ofc to cash PlayerData POJO classes
I think the queue thing likely would work better for me maybe
such a fancy name lmao
screamingscandals would sound a bit dubious
i was even thinking in my head i bet smile knows the site
But anyway burchard you only want to yse volatile when absolutely necessary since any volatile write ensures a flush of local registries
Well
volatile prevents caching on the cpu layer caches.
^
Hold one let me write out my data handler rq and come back with my question
gimme like 5 mins
It also does not ensure atomicity
You could if you wanna be very optimized use a varhandle or atomic field updater
just gonna psueodo code
let me double check on that...
It has methods to do so
But on its own it doesnt
Well
What the fuck am I saying
I mean AtomicReference and AtomicFieldUpdater for instance
Not volatile itself
But volatile is a crucial part if you want to actually perform atomicity correctly
Or well memory fences as well with var handles work just as good
Ok so it doesnt. It just makes sure that all threads have the same representation and nobody uses a locally cached version
But you need the memory ordering effect guarantee to avoid indeterminacy
This class would be on the main thread, except for the Optional<PlayerData> which will be async get from MongoDB: https://paste.md-5.net/gozuwitela.cs
Don't roast me its just pseudo code lmao
And the POJO player data class would be like this: https://paste.md-5.net/akaxaligut.cpp
And when a processing thread wants player data they would get the instance of PlayerDataFactory and call get(uuid) (Like said pseudo code don't roast me for the current design pls)
my current method of handling it would just be calling synchroniced on the PlayerDataFactory instance and handling data get/insert there
Wait
ffs should I just use maven?
but for some reason it feels wrong
I want to die ngl
yes
gradle aint worth it
unless smile knows how to do special source for gradle
PlayerDataFactory is used across multiple threads for both reads and writes?
PlayerDataFactory is intialized on the main thread
hmm
and runs on main
Yes but?
but mongodb requests (First data load) are on a work stealing thread
Is it used over more threads than that?
Well it would be used by threads from the work stealing pool
The threads would get a static instance (Or DI instance) of that class and call get()
sec
Cause usually
You have some sort of repository class
Which is basically a map, sometimes responsible for instantiating the underlying objects as well
So factory + map
And that class might often very well be used across multiple threads
Could you send him a message so when he is available he can talk to me?
if thats alright, I don't want to ping anyone
It would get used like this in a sense
my code is more abstracted than that
runAsync is a CompletableFuture wrapper
only change variables inside PlayerData value retrieved from get, so i think yes?
No actual mongodb writing
just cache write
like playerMoney += 500; or some shit like that
It writes to mongodb every 5 mins on a diff future for cached PlayerData in the map
and onStop
So how do you put the player DTOs in the map in the first place?
When the player logs in, validated with oauth2, and sends theyre JWT with UUID it will be loaded on first login
ie onConnect
Isnt that on another thread?
But yeah I dont understand why you need that blocking queue as well?
Hey does anyone know how to add effects on Monsters?
well i assumed it was needed for data to be safe accross threads
like what if on thread does playerData.money += 50
i dont think it gets updated without the volatile keyword
Normally we have whats called plain read and write
kk
What type of effects
Which is normals reads and writes to variables
But when we do multi threaded stuff we need certain guarantees
speed and resistance type
Look into Attribute
https://hub.spigotmc.org/javadocs/spigot/org/bukkit/entity/Zombie.html
Certain mobs like this one implement Attributeable
From there you can call say zombie.getAttribute(Attribute.GENERIC_ARMOR);
declaration: package: org.bukkit.attribute, interface: Attributable
//one thread
var i = 3;
var j = 1;
//other thread
var a = i;
var b = j;
what are the possible values after both threads have executed?
And use these methods to edit it: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/attribute/AttributeInstance.html
declaration: package: org.bukkit.attribute, interface: AttributeInstance
Assuming they run concurrently
hmmm
thread 2 would generate an exception wouldnt it no
unless it runs after thread 1?
Can I use maven and gradle simultaneously?
The minecraft intellij plugin does it
Ok thanks
ooo
wtf
im having a hard time thinking of one LMAO
if theyre both ran at the same time at least
so basically no consistency between threads
Yes
Because
var i = 3
var j = 1
can be re ordered to
var j = 1
var i = 3
And same guess for a and b
That wont alter the behaviour of the program as you can see (assuming its a single thread)
Yeah but it would lead to values you dont really want in a sense
Yep
Like i dont want one thread spending a players money, while another thread also does it
so build is gradle, package is maven?
We are coming to that part soon burchard
okay okay x)
So basically we use volatile as by the means of preventing this type of reordering
Honestly have no idea how youd run the 2 in unison
Like you can have the 2 in your IDE but i dont think theylle work in unison like your expecting them to
If you want remapped maven is likely easiest way to go about it
so I need to create a plugin.yml now?
no just a pom.xml
but there are no generators?
convert your gradle to pom (Striaghtforward process) and then add special source
Its pretty easy
gradle imports are
groupId:artifact:version
dw im stilll listening
just multitasking
when we prevent re ordering we get somewhat of a determinacy we can safely rely on
how tf do you convert gradle to pom?
This is crucial when you want to read and write concurrently
Now assume we do have some ordering constraints
Then we can apply whats called atomicity
Manually I can give you an empty pom tho
Yeah i saw a lot about AtomicIntegers and stuff
Yes
DIdnt fully understand them though
So youd just take your gradle dependencies and format them to mavens xml format
So you know how incrementing a variable is multiple operations right?
yeah I just need to figure out how to shadow my kyori stuff
IE how it pushes the values to heap right, in that case yes
like you gotta load the variable, perform the incrementation and then put the result back into the variable
yep
necessarily just the thread local staxk
use maven shade plugin
here ill get you it
Anywa
?paste
https://paste.md-5.net/pezasurewu.xml
use scope compile for shading
your properties tags needs a java.version variable
When variables can guarantee visibility we can perform a compare and swap when we want to perform operations that base themselves on old values
basically when we have performed the incrementation you check whether or not the old value was changed
Ah so thats what atomics do?
Just constantly checking for new values?
Yes in principle
If the value was changed
Then we perform the incrementation again
And so on
If it wasnt
Then put the result into the variable
For this to work across multiple threads we need volatility
Since we want up to date and accurate reads and writes
AtomicInteger, AtomicReference provide methods that allow you to do this
updateAndGet, getAndUpdate
for AtomicInteger you have incrementAndGet, getAndIncrement
etc
So you dont havr to implement that shit
And for maps
You have ConcurrentHashMap
I dont think ill be doing any Incrementing on values
mainly division, multiplution, some addtion but not incrementals and substractions
Yeah
Always wondered wtf that was for
always thought it was for something else
Lol well it performs atomicity on a map
Would the atomicity also carry over to the objects inside said map?
assuming you use for instance putIfAbsent, computeIfAbsent, compute etc
Yeah i always use putIfAbsent on my regular maps
Ugh wym
lol sorry xD
it guarantees atomicity on the map, not the variables of the values in the map
yep thats what i was asking :p
oh fr
But in simple terms, you go woth AtomicReference etc
and provide some convenience methods with your DTO maybe
void add(int delta){
moneyReference.getAndUpdate(old -> old+delta)
}
would create a wrapper method called setAndUpdate around a ConcurrentHashMap work?
Ie where you get object from hashmap, edit that object and then update/re-insert it into the map?
I see under the hood, this is similar to what things like AtomicInteger does
ohh
yeah
and i wouldnt need any transforms to my actual pojo class? I can still just use raw BigInteger?
and other keywords instead of atomics
For the map
You probably dont need to do anything special
Like
If you just putIfAbsent or use put
To populate DTOs that are yet not contained
But remember
You only need atomicity when multiple threads reads and writes to a variable
Yeah theyres gonna be lots
Every request is handled async
and players can send a bunch of diffeerent requests that would alter theyre player data significantly
and some things take heavy math calculations
so sometimes a request could hang for a few seconds
What I recommend you to do is sth like
and if a player sends a request like spend money before that one finishes it would cause an issue
That was mainly my main concern and main thought worry when kaing the async socket system
onSomeThread(()->{
result = heavyCalculation() //if you are not dependent on old values
dto.add(result);
}
rather than dto.update(old -> heavyCalculation()+old);
But the latter might be necessary if u r dependent on old values
But yeah
You also need to add some checks
Then
To make sure the money cant go negative when performing an update
i would prefer to depend on the most latest updated value of that number
Yeah ill have those checks in my core logic
sec stil writing this out
No burchard
Sometimes youโre not dependent
Like lets say all you do is adding a number
Then you dont care
But if you wanna square the old value and take the second derivative of the old value or sth weird then you need to perform an explicit update
Anywah theres much more to it if you wanna get real, but this should be enough for you to create a model that is scalable enough
Id thoโฆ recommend unit testing
Especially the multi threaded stuff
Can I get some help shadowing minimessages?
To make sure you got it right
their docs don't supply any examples
hey I got a question is there a way to show the crafting recipe in a GUI without it being clickable? I tried to disable the clicks that a player does when they are in the GUI I made, however all this does it stop them from clicking in the crafting inventory I made.
They are still able to take out any items that are in the crafting gird by double clicking with a similar item, and can add to that item by right clicking the item onto the similar item in the GUI
think im mostly done
(:
https://paste.md-5.net/ukexepuxej.java - new player data handler my socket library handles those methods async, pretend that class isnt nested inside this class i was just lazy to make a new file
POJO Data class: https://paste.md-5.net/berepumemo.cpp
the subclass there would just be shown how its used
ik im prolly doing a lot of uncesary gets im not using
but its just psuedo code mainly
ill abstractify it once i get it work
Ill have to learn how to unit test lmfao
Got any code?
?paste
sorry bout that, forgot to turn off the reply
In this case ๐
Its just a basic check if the inventory is correct and if it is cancel the event.
https://paste.md-5.net/kuwojijixi.java
How I'm going to fix it though is just add a attribute to the item stack to make it different from any other possible item.
But overall atomicity is very scenario specific
now the main issue is just seeing how these parse against gson
Idk this does seems pretty good and looks like itll work
it will be easy to test once its stup
So you only want the actual 4 or 9 crafting slots to be non clickable?
the 9 crafting slots and the outcome to be not clickable, or editable in any way.
oh wow
that lots complex asf, ill definatly look into it haha
idk why unit tests always scary to me
I forgot theyre exact slot counts but
its 0 - 9 with 0 being the outcome for the crafting table
so can you just if clickSlot == those cancel?
Cya! And thanks a bunch for explaining so well for me
prolly would of never figured it out and i prolly would of went to like redis or something ๐
the code I sent works for stopping the items from getting left clicked or right clicked out, however, if you shift right click a item into the crafting gird it will remove the item and if you double click the item it will give you all of that item.
for shift clicking and canceling destination slot someone asked that earlier
youll need packets to get destination slot of shift clicks sadly, and then cancel upon those
As for double clicking
thats a thing?
i know shift double click is
yeah just clicking fast inside of a gui should stack all similar items up to their max stacking point
hmm
i wonder if an event for that exists
oh also you wanna cancel inventory drag event btw
cause i bet dragging breaks your gui too
I solved that issue by just adding in extra attributes to the items that are in the fake crafting menu I make. but the shift clicking items from your inventory will still make them disappear :/
suprisingly no, just the shift clicking item removal, and the items being able to be pull out with double clicking
Odd question
but after you cancel double clicks
do you cann player#updateInventory?
call****
I do not, do I need to?
"do you can" lmao
sometimes you might need to
bukkit api sucks for that
try and see if it fixes it
lmk if it doesnt
alright let me remove my fix and test that out, that may fix the shfit clicking too, who knows ๐
shift clicking sadly needs the weird work around
unless your shifting clicking directly on the disallowed slot
idk why theres no getTargetSlot method
didn't seem to do anything
one more thing
Bukkit.getSchedular().runTask(() -> p.updateInventroy());
sorry
forgot to mention run it one tick later
the work around only works for double clicking not shift clicking :/ unless your talking about another weird work around and not adding custom data to the item in the gird to make no items stack to it
well shift clicking and getting destination slot needs NMS/Packets
sec lemme find the article
hot link ^
running it later doesn't seem to do anything about it either, guess im stuck with the added data. ill look into the shfit clicking thing hope to fix that.
sadness, was worth a shot
Its weird that when shift clicking the item just disappears though.
sometimes that method can fix some weird behavious with inventories
Its likely just because its a custom inventory
so the functionalities fucked a little
ah yeah prob
I found a non NMS work around, in my inventory click event I have this code:
if (e.getClickedInventory().getType() == InventoryType.PLAYER) {
if (e.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY) {
e.setCancelled(true);
}
return;
}
basically what it does it check if the player shift clicks an item and if they do, it stops them, if they don't then they don't care about that inventory. However, I do wish that spigot had a InventoryAction.Double_Click since it doesn't seem to exist anywhere
EDIT:
๐คฆโโ๏ธ I think its called "COLLECT_TO_CURSOR"
I need help, why am I getting this for maven ```[ERROR] Failed to parse plugin descriptor for net.kyori:adventure-api:4.11.0 (/home/user
/.m2/repository/net/kyori/adventure-api/4.11.0/adventure-api-4.11.0.jar): No plugin descriptor found at META-INF/maven/plugin.xml -> [Help 1]
this is my shadow part
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.11.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>```
Since when is there an adventure maven plugin??
I see
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.11.0</version>
</dependency>
Nope thats a maven plugin. When using gradle ill always go for the userdev plugin from paper.
It does for everyone else... I'd bet on user error.
yeah maybe, but fixing isnt really an option now
So that fixes the two issues with, shift clicking and double clicking.
However, I also ran into an issue where you can right click the item into the slot if you right click the slot enough times it will bypass the event being cancelled
Video of the event running even though its clearly cancelled
Both maven and gradle have their caveats. They are both equally painful to use.
For recipe editing i always use a dropper or hopper inventory.
Ill let the user do whatever they want and simply read the matrix when the inventory closes.
its not supposed to be editable, its just another way for people to view the recipe other than in the recipe book. Because sometimes it glitches out
Then simply cancel the InventoryClickEvent when they have a view open.
All of them
Thats what I have right now https://paste.md-5.net/eqepawotul.cs
Dont use the title as an identity...
Is it not good practice? whats a better way to determine its the right view?
This can be done in way fewer lines. All you should need:
@EventHandler
public void onClick(InventoryClickEvent event) {
if(viewManager.isRecipeView(event.getInventory())) {
event.setCancelled(true);
}
}
Use a Set<Inventory>
Create a RecipeViewManager that contains a Set<Inventory>
When you open a view for a player you simply add it to the manager.
Then on the close event you remove it from the manager.
RecipeViewManager is a singleton like every other manager class
Write if you want an example
https://youtu.be/AVVQAU3lWZo?t=341
How can I code this thing (@5:41)
It makes it look like you are about to fall into the void but its just a trap
I Became a literal god on the Lifesteal Minecraft 1.18 SMP by exploiting its plugin...
Keep up with me on social media
โ
join the community on discord - https://discord.gg/SQqkenRwx4
โ
stalk me on twitter โฃใ @ashswagin ใ
โ
follow my twitch โฃใ https://www.twitch.tv/ashswagin ใ
THANKS TO THE PLUGIN DEVS FOR HELPING ME do this :- Abyss Development ...
come on, stop it
why
Thats just a bug
What exactly are you referring to?
no, I got that to work. However, it still bypasses the cancel event if you right click fast enough
Making it so player thinks he is about to fall into the void but its just a hole in the ground
Doesnt happen. What version are you on?
the way spigot fakes its ores for anti xray
1.18.1
Inventories are fully server authoritative. If you properly cancel the event then nothing can happen.
Send Chunk packets
I wonder why its happening then, cuz I can check if the event is cancelled after but the item still appears
Neve had that happen after 1.12
Its a fake ItemStack or your code is not solid.
ProtocolLib will do
Burchard you lied to me
Maven doesnt generate plugin.ymls
why would it?
sfsdfdsgdrf
so I send a chunk packet, thats all?
i never said maven did
i said the intellij plugin did
i didnt?
even then
why is plugin.yml a big deal
that shouldnt change when switching to mappings
I never had a plugin.yml
it was generated by minecrell
do I need to make it manually now?
.......
this is why we dont use libraries like that
are there any generators?
That way we know how to make a barebone plugin
I've done it before for my neosurvival
https://www.spigotmc.org/wiki/plugin-yml/
You can view how to make one here
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
it goes in /resources
I feel like a teenage girl that just got cut off her allowance
yes, theres a intelliJ plugin that will set you up with a basic plugin structure
Hes meaning just plugin.yml generator lol
oh
I suggested that plugin to him earlier
your right, im stupid, my code had old testing code from when I was trying to fix the other issues I had.
if (e.getCursor() == null) {
return;
}
if (e.getCurrentItem() == null) {
return;
}
this broke it which makes sense, Its all fixed now
why do u need a gen for that
because
i love when debugging code manages to keep itself in the codebase
happens alot when i go to bed after debugging a bunch of shiz and i start up the next day forgetting any leftover debug shiz
worst feeling, I have spent countless hours doing that
I once wrote something for an answer here into one of my resources and pushed it. Only noticed it a month later.
oh god
i do that a lot
ill write out some code in a random project to show to someone
and i forget its there lmfao
in fact there code in one of my projects doing that rn
forgot which one tho
enjoy smiles


He actually does a good job at explaining tbh
Lol
looks like me too
anyways
why cant I find my plugin.yml in the decompiled classes?
should be right when you unzip it
just a bad decompiler?
im literally the dumbest person in this channel, but thank you
-100 self confidence
How do i do this again version: {{ neoPerformance.version }}
for version:
again, I've always had my allowance, the real world is a bitch
I remember you could put some tag in the plugin.yml to grab the version
neoperformance is just the name of my crappy plugin
ahh
uhm
${version}
but thats maven
nvm u on maven
make sure you use the plugins i sent earlier
or that placeholder wont work iirc
is that minecraft development?
no its called filtering
just as long as thats true for your resources dir it should parse fine
which it should be cause i sent you that entire chunk earlier
just - the binary-resources dir bc that for my own plugin
It's saying my plugin.yml is invalid
send the plugin.yml you have
name: NeoPerformance
version: '${version}'
main: com.neomechanical.neoperformance.NeoPerformance
load: STARTUP
authors:
- NeoDevs
prefix: NeoPerformance
commands:
neoperformance:
description: Show server performance
aliases:
- np
- performance
permission: neoperformance.admin
usage: /neoperformance
api-version: 1.13
default-permission: op```
root
have a feeling this isnt ur project right?
